@hyperframes/producer 0.4.14 → 0.4.15

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.
@@ -1357,12 +1357,12 @@ var require_CSSValueExpression = __commonJS({
1357
1357
  return false;
1358
1358
  }
1359
1359
  };
1360
- CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
1361
- var endIdx = this._findMatchedIdx(token, idx, sep), text;
1360
+ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep2) {
1361
+ var endIdx = this._findMatchedIdx(token, idx, sep2), text;
1362
1362
  if (endIdx === -1) {
1363
1363
  return false;
1364
1364
  } else {
1365
- text = token.substring(idx, endIdx + sep.length);
1365
+ text = token.substring(idx, endIdx + sep2.length);
1366
1366
  return {
1367
1367
  idx: endIdx,
1368
1368
  text
@@ -1402,15 +1402,15 @@ var require_CSSValueExpression = __commonJS({
1402
1402
  if (!isLegal) {
1403
1403
  return false;
1404
1404
  } else {
1405
- var sep = "/";
1406
- return this._parseJSString(token, idx, sep);
1405
+ var sep2 = "/";
1406
+ return this._parseJSString(token, idx, sep2);
1407
1407
  }
1408
1408
  };
1409
- CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
1409
+ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep2) {
1410
1410
  var startIdx = idx, endIdx;
1411
1411
  var NOT_FOUND = -1;
1412
1412
  while (true) {
1413
- endIdx = token.indexOf(sep, startIdx + 1);
1413
+ endIdx = token.indexOf(sep2, startIdx + 1);
1414
1414
  if (endIdx === -1) {
1415
1415
  endIdx = NOT_FOUND;
1416
1416
  break;
@@ -2149,11 +2149,11 @@ function __extends(d, b) {
2149
2149
  }
2150
2150
  function __awaiter(thisArg, _arguments, P, generator) {
2151
2151
  function adopt(value) {
2152
- return value instanceof P ? value : new P(function(resolve13) {
2153
- resolve13(value);
2152
+ return value instanceof P ? value : new P(function(resolve14) {
2153
+ resolve14(value);
2154
2154
  });
2155
2155
  }
2156
- return new (P || (P = Promise))(function(resolve13, reject) {
2156
+ return new (P || (P = Promise))(function(resolve14, reject) {
2157
2157
  function fulfilled(value) {
2158
2158
  try {
2159
2159
  step(generator.next(value));
@@ -2169,7 +2169,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
2169
2169
  }
2170
2170
  }
2171
2171
  function step(result) {
2172
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
2172
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
2173
2173
  }
2174
2174
  step((generator = generator.apply(thisArg, _arguments || [])).next());
2175
2175
  });
@@ -2332,14 +2332,14 @@ function __asyncValues(o) {
2332
2332
  }, i);
2333
2333
  function verb(n) {
2334
2334
  i[n] = o[n] && function(v) {
2335
- return new Promise(function(resolve13, reject) {
2336
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
2335
+ return new Promise(function(resolve14, reject) {
2336
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
2337
2337
  });
2338
2338
  };
2339
2339
  }
2340
- function settle(resolve13, reject, d, v) {
2340
+ function settle(resolve14, reject, d, v) {
2341
2341
  Promise.resolve(v).then(function(v2) {
2342
- resolve13({ value: v2, done: d });
2342
+ resolve14({ value: v2, done: d });
2343
2343
  }, reject);
2344
2344
  }
2345
2345
  }
@@ -2864,7 +2864,7 @@ function of() {
2864
2864
  }
2865
2865
  function lastValueFrom(source2, config2) {
2866
2866
  var hasConfig = typeof config2 === "object";
2867
- return new Promise(function(resolve13, reject) {
2867
+ return new Promise(function(resolve14, reject) {
2868
2868
  var _hasValue = false;
2869
2869
  var _value;
2870
2870
  source2.subscribe({
@@ -2875,9 +2875,9 @@ function lastValueFrom(source2, config2) {
2875
2875
  error: reject,
2876
2876
  complete: function() {
2877
2877
  if (_hasValue) {
2878
- resolve13(_value);
2878
+ resolve14(_value);
2879
2879
  } else if (hasConfig) {
2880
- resolve13(config2.defaultValue);
2880
+ resolve14(config2.defaultValue);
2881
2881
  } else {
2882
2882
  reject(new EmptyError());
2883
2883
  }
@@ -2887,16 +2887,16 @@ function lastValueFrom(source2, config2) {
2887
2887
  }
2888
2888
  function firstValueFrom(source2, config2) {
2889
2889
  var hasConfig = typeof config2 === "object";
2890
- return new Promise(function(resolve13, reject) {
2890
+ return new Promise(function(resolve14, reject) {
2891
2891
  var subscriber = new SafeSubscriber({
2892
2892
  next: function(value) {
2893
- resolve13(value);
2893
+ resolve14(value);
2894
2894
  subscriber.unsubscribe();
2895
2895
  },
2896
2896
  error: reject,
2897
2897
  complete: function() {
2898
2898
  if (hasConfig) {
2899
- resolve13(config2.defaultValue);
2899
+ resolve14(config2.defaultValue);
2900
2900
  } else {
2901
2901
  reject(new EmptyError());
2902
2902
  }
@@ -3935,7 +3935,7 @@ var init_rxjs = __esm({
3935
3935
  Observable2.prototype.forEach = function(next, promiseCtor) {
3936
3936
  var _this = this;
3937
3937
  promiseCtor = getPromiseCtor(promiseCtor);
3938
- return new promiseCtor(function(resolve13, reject) {
3938
+ return new promiseCtor(function(resolve14, reject) {
3939
3939
  var subscriber = new SafeSubscriber({
3940
3940
  next: function(value) {
3941
3941
  try {
@@ -3946,7 +3946,7 @@ var init_rxjs = __esm({
3946
3946
  }
3947
3947
  },
3948
3948
  error: reject,
3949
- complete: resolve13
3949
+ complete: resolve14
3950
3950
  });
3951
3951
  _this.subscribe(subscriber);
3952
3952
  });
@@ -3968,14 +3968,14 @@ var init_rxjs = __esm({
3968
3968
  Observable2.prototype.toPromise = function(promiseCtor) {
3969
3969
  var _this = this;
3970
3970
  promiseCtor = getPromiseCtor(promiseCtor);
3971
- return new promiseCtor(function(resolve13, reject) {
3971
+ return new promiseCtor(function(resolve14, reject) {
3972
3972
  var value;
3973
3973
  _this.subscribe(function(x) {
3974
3974
  return value = x;
3975
3975
  }, function(err) {
3976
3976
  return reject(err);
3977
3977
  }, function() {
3978
- return resolve13(value);
3978
+ return resolve14(value);
3979
3979
  });
3980
3980
  });
3981
3981
  };
@@ -6405,8 +6405,8 @@ var init_Deferred = __esm({
6405
6405
  // SAFETY: This is ensured by #taskPromise.
6406
6406
  #resolve;
6407
6407
  // TODO: Switch to Promise.withResolvers with Node 22
6408
- #taskPromise = new Promise((resolve13) => {
6409
- this.#resolve = resolve13;
6408
+ #taskPromise = new Promise((resolve14) => {
6409
+ this.#resolve = resolve14;
6410
6410
  });
6411
6411
  #timeoutId;
6412
6412
  #timeoutError;
@@ -6496,12 +6496,12 @@ var init_Mutex = __esm({
6496
6496
  return new _Mutex.Guard(this, onRelease);
6497
6497
  }
6498
6498
  release() {
6499
- const resolve13 = this.#acquirers.shift();
6500
- if (!resolve13) {
6499
+ const resolve14 = this.#acquirers.shift();
6500
+ if (!resolve14) {
6501
6501
  this.#locked = false;
6502
6502
  return;
6503
6503
  }
6504
- resolve13();
6504
+ resolve14();
6505
6505
  }
6506
6506
  };
6507
6507
  }
@@ -8516,12 +8516,12 @@ var init_locators = __esm({
8516
8516
  }
8517
8517
  return defer(() => {
8518
8518
  return from(handle.evaluate((element) => {
8519
- return new Promise((resolve13) => {
8519
+ return new Promise((resolve14) => {
8520
8520
  window.requestAnimationFrame(() => {
8521
8521
  const rect1 = element.getBoundingClientRect();
8522
8522
  window.requestAnimationFrame(() => {
8523
8523
  const rect2 = element.getBoundingClientRect();
8524
- resolve13([
8524
+ resolve14([
8525
8525
  {
8526
8526
  x: rect1.x,
8527
8527
  y: rect1.y,
@@ -10260,9 +10260,9 @@ var init_ElementHandle = __esm({
10260
10260
  const handle = await this.#asSVGElementHandle();
10261
10261
  const target = __addDisposableResource6(env_5, handle && await handle.#getOwnerSVGElement(), false);
10262
10262
  return await (target ?? this).evaluate(async (element, threshold) => {
10263
- const visibleRatio = await new Promise((resolve13) => {
10263
+ const visibleRatio = await new Promise((resolve14) => {
10264
10264
  const observer = new IntersectionObserver((entries2) => {
10265
- resolve13(entries2[0].intersectionRatio);
10265
+ resolve14(entries2[0].intersectionRatio);
10266
10266
  observer.disconnect();
10267
10267
  });
10268
10268
  observer.observe(element);
@@ -10908,7 +10908,7 @@ var init_Frame = __esm({
10908
10908
  }
10909
10909
  type = type ?? "text/javascript";
10910
10910
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, id, type: type2, content: content2 }) => {
10911
- return await new Promise((resolve13, reject) => {
10911
+ return await new Promise((resolve14, reject) => {
10912
10912
  const script = document.createElement("script");
10913
10913
  script.type = type2;
10914
10914
  script.text = content2;
@@ -10921,12 +10921,12 @@ var init_Frame = __esm({
10921
10921
  if (url) {
10922
10922
  script.src = url;
10923
10923
  script.addEventListener("load", () => {
10924
- resolve13(script);
10924
+ resolve14(script);
10925
10925
  }, { once: true });
10926
10926
  document.head.appendChild(script);
10927
10927
  } else {
10928
10928
  document.head.appendChild(script);
10929
- resolve13(script);
10929
+ resolve14(script);
10930
10930
  }
10931
10931
  });
10932
10932
  }, { ...options, type, content }));
@@ -10946,7 +10946,7 @@ var init_Frame = __esm({
10946
10946
  options.content = content;
10947
10947
  }
10948
10948
  return await this.mainRealm().transferHandle(await this.isolatedRealm().evaluateHandle(async ({ url, content: content2 }) => {
10949
- return await new Promise((resolve13, reject) => {
10949
+ return await new Promise((resolve14, reject) => {
10950
10950
  let element;
10951
10951
  if (!url) {
10952
10952
  element = document.createElement("style");
@@ -10958,7 +10958,7 @@ var init_Frame = __esm({
10958
10958
  element = link;
10959
10959
  }
10960
10960
  element.addEventListener("load", () => {
10961
- resolve13(element);
10961
+ resolve14(element);
10962
10962
  }, { once: true });
10963
10963
  element.addEventListener("error", (event) => {
10964
10964
  reject(new Error(event.message ?? "Could not load style"));
@@ -12697,9 +12697,9 @@ var init_Page = __esm({
12697
12697
  ++this.#screencastSessionCount;
12698
12698
  if (!this.#startScreencastPromise) {
12699
12699
  this.#startScreencastPromise = this.mainFrame().client.send("Page.startScreencast", { format: "png" }).then(() => {
12700
- return new Promise((resolve13) => {
12700
+ return new Promise((resolve14) => {
12701
12701
  return this.mainFrame().client.once("Page.screencastFrame", () => {
12702
- return resolve13();
12702
+ return resolve14();
12703
12703
  });
12704
12704
  });
12705
12705
  });
@@ -16017,11 +16017,11 @@ function addPageBinding(type, name, prefix) {
16017
16017
  return value instanceof Node;
16018
16018
  })
16019
16019
  }));
16020
- return new Promise((resolve13, reject) => {
16020
+ return new Promise((resolve14, reject) => {
16021
16021
  callPuppeteer.callbacks.set(seq, {
16022
16022
  resolve(value) {
16023
16023
  callPuppeteer.args.delete(seq);
16024
- resolve13(value);
16024
+ resolve14(value);
16025
16025
  },
16026
16026
  reject(value) {
16027
16027
  callPuppeteer.args.delete(seq);
@@ -19684,8 +19684,8 @@ var init_Input2 = __esm({
19684
19684
  if (typeof delay === "number") {
19685
19685
  await Promise.all(actions);
19686
19686
  actions.length = 0;
19687
- await new Promise((resolve13) => {
19688
- setTimeout(resolve13, delay);
19687
+ await new Promise((resolve14) => {
19688
+ setTimeout(resolve14, delay);
19689
19689
  });
19690
19690
  }
19691
19691
  actions.push(this.up({ ...options, clickCount }));
@@ -19705,9 +19705,9 @@ var init_Input2 = __esm({
19705
19705
  });
19706
19706
  }
19707
19707
  async drag(start, target) {
19708
- const promise = new Promise((resolve13) => {
19708
+ const promise = new Promise((resolve14) => {
19709
19709
  this.#client.once("Input.dragIntercepted", (event) => {
19710
- return resolve13(event.data);
19710
+ return resolve14(event.data);
19711
19711
  });
19712
19712
  });
19713
19713
  await this.move(start.x, start.y);
@@ -19748,8 +19748,8 @@ var init_Input2 = __esm({
19748
19748
  await this.dragEnter(target, data);
19749
19749
  await this.dragOver(target, data);
19750
19750
  if (delay) {
19751
- await new Promise((resolve13) => {
19752
- return setTimeout(resolve13, delay);
19751
+ await new Promise((resolve14) => {
19752
+ return setTimeout(resolve14, delay);
19753
19753
  });
19754
19754
  }
19755
19755
  await this.drop(target, data);
@@ -20633,9 +20633,9 @@ var init_Page2 = __esm({
20633
20633
  async captureHeapSnapshot(options) {
20634
20634
  const { createWriteStream: createWriteStream3 } = environment.value.fs;
20635
20635
  const stream2 = createWriteStream3(options.path);
20636
- const streamPromise = new Promise((resolve13, reject) => {
20636
+ const streamPromise = new Promise((resolve14, reject) => {
20637
20637
  stream2.on("error", reject);
20638
- stream2.on("finish", resolve13);
20638
+ stream2.on("finish", resolve14);
20639
20639
  });
20640
20640
  const client = this.#primaryTargetClient;
20641
20641
  await client.send("HeapProfiler.enable");
@@ -22277,10 +22277,10 @@ var init_BrowserWebSocketTransport = __esm({
22277
22277
  "../../node_modules/.bun/puppeteer-core@24.40.0/node_modules/puppeteer-core/lib/esm/puppeteer/common/BrowserWebSocketTransport.js"() {
22278
22278
  BrowserWebSocketTransport = class _BrowserWebSocketTransport {
22279
22279
  static create(url) {
22280
- return new Promise((resolve13, reject) => {
22280
+ return new Promise((resolve14, reject) => {
22281
22281
  const ws = new WebSocket(url);
22282
22282
  ws.addEventListener("open", () => {
22283
- return resolve13(new _BrowserWebSocketTransport(ws));
22283
+ return resolve14(new _BrowserWebSocketTransport(ws));
22284
22284
  });
22285
22285
  ws.addEventListener("error", reject);
22286
22286
  });
@@ -25202,11 +25202,11 @@ var require_BrowsingContextProcessor = __commonJS({
25202
25202
  }
25203
25203
  const parentCdpClient = context2.cdpTarget.parentCdpClient;
25204
25204
  try {
25205
- const detachedFromTargetPromise = new Promise((resolve13) => {
25205
+ const detachedFromTargetPromise = new Promise((resolve14) => {
25206
25206
  const onContextDestroyed = (event) => {
25207
25207
  if (event.targetId === params.context) {
25208
25208
  parentCdpClient.off("Target.detachedFromTarget", onContextDestroyed);
25209
- resolve13();
25209
+ resolve14();
25210
25210
  }
25211
25211
  };
25212
25212
  parentCdpClient.on("Target.detachedFromTarget", onContextDestroyed);
@@ -26569,7 +26569,7 @@ var require_ActionDispatcher = __commonJS({
26569
26569
  }
26570
26570
  }
26571
26571
  const promises = [
26572
- new Promise((resolve13) => setTimeout(resolve13, this.#tickDuration))
26572
+ new Promise((resolve14) => setTimeout(resolve14, this.#tickDuration))
26573
26573
  ];
26574
26574
  for (const option of options) {
26575
26575
  promises.push(this.#dispatchAction(option));
@@ -27170,8 +27170,8 @@ var require_Mutex = __commonJS({
27170
27170
  acquire() {
27171
27171
  const state = { resolved: false };
27172
27172
  if (this.#locked) {
27173
- return new Promise((resolve13) => {
27174
- this.#acquirers.push(() => resolve13(this.#release.bind(this, state)));
27173
+ return new Promise((resolve14) => {
27174
+ this.#acquirers.push(() => resolve14(this.#release.bind(this, state)));
27175
27175
  });
27176
27176
  }
27177
27177
  this.#locked = true;
@@ -27182,12 +27182,12 @@ var require_Mutex = __commonJS({
27182
27182
  throw new Error("Cannot release more than once.");
27183
27183
  }
27184
27184
  state.resolved = true;
27185
- const resolve13 = this.#acquirers.shift();
27186
- if (!resolve13) {
27185
+ const resolve14 = this.#acquirers.shift();
27186
+ if (!resolve14) {
27187
27187
  this.#locked = false;
27188
27188
  return;
27189
27189
  }
27190
- resolve13();
27190
+ resolve14();
27191
27191
  }
27192
27192
  async run(action) {
27193
27193
  const release = await this.acquire();
@@ -28369,8 +28369,8 @@ var require_ChannelProxy = __commonJS({
28369
28369
  * in the queue.
28370
28370
  */
28371
28371
  async getMessage() {
28372
- const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve13) => {
28373
- queueNonEmptyResolver = resolve13;
28372
+ const onMessage = queue.length > 0 ? Promise.resolve() : new Promise((resolve14) => {
28373
+ queueNonEmptyResolver = resolve14;
28374
28374
  });
28375
28375
  await onMessage;
28376
28376
  return queue.shift();
@@ -28475,7 +28475,7 @@ var require_ChannelProxy = __commonJS({
28475
28475
  functionDeclaration: String((id) => {
28476
28476
  const w = window;
28477
28477
  if (w[id] === void 0) {
28478
- return new Promise((resolve13) => w[id] = resolve13);
28478
+ return new Promise((resolve14) => w[id] = resolve14);
28479
28479
  }
28480
28480
  const channelProxy = w[id];
28481
28481
  delete w[id];
@@ -29976,8 +29976,8 @@ var require_Deferred = __commonJS({
29976
29976
  return this.#result;
29977
29977
  }
29978
29978
  constructor() {
29979
- this.#promise = new Promise((resolve13, reject) => {
29980
- this.#resolve = resolve13;
29979
+ this.#promise = new Promise((resolve14, reject) => {
29980
+ this.#resolve = resolve14;
29981
29981
  this.#reject = reject;
29982
29982
  });
29983
29983
  this.#promise.catch((_error) => {
@@ -34821,11 +34821,11 @@ var require_BrowsingContextStorage = __commonJS({
34821
34821
  if (this.#contexts.has(browsingContextId)) {
34822
34822
  return Promise.resolve(this.getContext(browsingContextId));
34823
34823
  }
34824
- return new Promise((resolve13) => {
34824
+ return new Promise((resolve14) => {
34825
34825
  const listener = (event) => {
34826
34826
  if (event.browsingContext.id === browsingContextId) {
34827
34827
  this.#eventEmitter.off("added", listener);
34828
- resolve13(event.browsingContext);
34828
+ resolve14(event.browsingContext);
34829
34829
  }
34830
34830
  };
34831
34831
  this.#eventEmitter.on("added", listener);
@@ -38407,8 +38407,8 @@ var init_ExposedFunction = __esm({
38407
38407
  const functionDeclaration = stringifyFunction(interpolateFunction((callback) => {
38408
38408
  Object.assign(globalThis, {
38409
38409
  [PLACEHOLDER("name")]: function(...args) {
38410
- return new Promise((resolve13, reject) => {
38411
- callback([resolve13, reject, args]);
38410
+ return new Promise((resolve14, reject) => {
38411
+ callback([resolve14, reject, args]);
38412
38412
  });
38413
38413
  }
38414
38414
  });
@@ -38496,8 +38496,8 @@ var init_ExposedFunction = __esm({
38496
38496
  return;
38497
38497
  }
38498
38498
  try {
38499
- await dataHandle.evaluate(([resolve13], result2) => {
38500
- resolve13(result2);
38499
+ await dataHandle.evaluate(([resolve14], result2) => {
38500
+ resolve14(result2);
38501
38501
  }, result);
38502
38502
  } catch (error) {
38503
38503
  debugError(error);
@@ -46578,7 +46578,7 @@ var init_NodeWebSocketTransport = __esm({
46578
46578
  init_version();
46579
46579
  NodeWebSocketTransport = class _NodeWebSocketTransport {
46580
46580
  static create(url, headers) {
46581
- return new Promise((resolve13, reject) => {
46581
+ return new Promise((resolve14, reject) => {
46582
46582
  const ws = new wrapper_default(url, [], {
46583
46583
  followRedirects: true,
46584
46584
  perMessageDeflate: false,
@@ -46591,7 +46591,7 @@ var init_NodeWebSocketTransport = __esm({
46591
46591
  }
46592
46592
  });
46593
46593
  ws.addEventListener("open", () => {
46594
- return resolve13(new _NodeWebSocketTransport(ws));
46594
+ return resolve14(new _NodeWebSocketTransport(ws));
46595
46595
  });
46596
46596
  ws.addEventListener("error", reject);
46597
46597
  });
@@ -49652,8 +49652,8 @@ var require_helpers = __commonJS({
49652
49652
  function req(url, opts = {}) {
49653
49653
  const href = typeof url === "string" ? url : url.href;
49654
49654
  const req2 = (href.startsWith("https:") ? https2 : http2).request(url, opts);
49655
- const promise = new Promise((resolve13, reject) => {
49656
- req2.once("response", resolve13).once("error", reject).end();
49655
+ const promise = new Promise((resolve14, reject) => {
49656
+ req2.once("response", resolve14).once("error", reject).end();
49657
49657
  });
49658
49658
  req2.then = promise.then.bind(promise);
49659
49659
  return req2;
@@ -50030,7 +50030,7 @@ var require_parse_proxy_response = __commonJS({
50030
50030
  var debug_1 = __importDefault2(require_src());
50031
50031
  var debug6 = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
50032
50032
  function parseProxyResponse(socket) {
50033
- return new Promise((resolve13, reject) => {
50033
+ return new Promise((resolve14, reject) => {
50034
50034
  let buffersLength = 0;
50035
50035
  const buffers = [];
50036
50036
  function read() {
@@ -50096,7 +50096,7 @@ var require_parse_proxy_response = __commonJS({
50096
50096
  }
50097
50097
  debug6("got proxy server response: %o %o", firstLine, headers);
50098
50098
  cleanup();
50099
- resolve13({
50099
+ resolve14({
50100
50100
  connect: {
50101
50101
  statusCode,
50102
50102
  statusText,
@@ -53354,11 +53354,11 @@ var require_socksclient = __commonJS({
53354
53354
  "use strict";
53355
53355
  var __awaiter3 = exports && exports.__awaiter || function(thisArg, _arguments, P, generator) {
53356
53356
  function adopt(value) {
53357
- return value instanceof P ? value : new P(function(resolve13) {
53358
- resolve13(value);
53357
+ return value instanceof P ? value : new P(function(resolve14) {
53358
+ resolve14(value);
53359
53359
  });
53360
53360
  }
53361
- return new (P || (P = Promise))(function(resolve13, reject) {
53361
+ return new (P || (P = Promise))(function(resolve14, reject) {
53362
53362
  function fulfilled(value) {
53363
53363
  try {
53364
53364
  step(generator.next(value));
@@ -53374,7 +53374,7 @@ var require_socksclient = __commonJS({
53374
53374
  }
53375
53375
  }
53376
53376
  function step(result) {
53377
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
53377
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
53378
53378
  }
53379
53379
  step((generator = generator.apply(thisArg, _arguments || [])).next());
53380
53380
  });
@@ -53408,13 +53408,13 @@ var require_socksclient = __commonJS({
53408
53408
  * @returns { Promise }
53409
53409
  */
53410
53410
  static createConnection(options, callback) {
53411
- return new Promise((resolve13, reject) => {
53411
+ return new Promise((resolve14, reject) => {
53412
53412
  try {
53413
53413
  (0, helpers_1.validateSocksClientOptions)(options, ["connect"]);
53414
53414
  } catch (err) {
53415
53415
  if (typeof callback === "function") {
53416
53416
  callback(err);
53417
- return resolve13(err);
53417
+ return resolve14(err);
53418
53418
  } else {
53419
53419
  return reject(err);
53420
53420
  }
@@ -53425,16 +53425,16 @@ var require_socksclient = __commonJS({
53425
53425
  client.removeAllListeners();
53426
53426
  if (typeof callback === "function") {
53427
53427
  callback(null, info);
53428
- resolve13(info);
53428
+ resolve14(info);
53429
53429
  } else {
53430
- resolve13(info);
53430
+ resolve14(info);
53431
53431
  }
53432
53432
  });
53433
53433
  client.once("error", (err) => {
53434
53434
  client.removeAllListeners();
53435
53435
  if (typeof callback === "function") {
53436
53436
  callback(err);
53437
- resolve13(err);
53437
+ resolve14(err);
53438
53438
  } else {
53439
53439
  reject(err);
53440
53440
  }
@@ -53451,13 +53451,13 @@ var require_socksclient = __commonJS({
53451
53451
  * @returns { Promise }
53452
53452
  */
53453
53453
  static createConnectionChain(options, callback) {
53454
- return new Promise((resolve13, reject) => __awaiter3(this, void 0, void 0, function* () {
53454
+ return new Promise((resolve14, reject) => __awaiter3(this, void 0, void 0, function* () {
53455
53455
  try {
53456
53456
  (0, helpers_1.validateSocksClientChainOptions)(options);
53457
53457
  } catch (err) {
53458
53458
  if (typeof callback === "function") {
53459
53459
  callback(err);
53460
- return resolve13(err);
53460
+ return resolve14(err);
53461
53461
  } else {
53462
53462
  return reject(err);
53463
53463
  }
@@ -53483,14 +53483,14 @@ var require_socksclient = __commonJS({
53483
53483
  }
53484
53484
  if (typeof callback === "function") {
53485
53485
  callback(null, { socket: sock });
53486
- resolve13({ socket: sock });
53486
+ resolve14({ socket: sock });
53487
53487
  } else {
53488
- resolve13({ socket: sock });
53488
+ resolve14({ socket: sock });
53489
53489
  }
53490
53490
  } catch (err) {
53491
53491
  if (typeof callback === "function") {
53492
53492
  callback(err);
53493
- resolve13(err);
53493
+ resolve14(err);
53494
53494
  } else {
53495
53495
  reject(err);
53496
53496
  }
@@ -54174,12 +54174,12 @@ var require_dist4 = __commonJS({
54174
54174
  let { host } = opts;
54175
54175
  const { port, lookup: lookupFn = dns.lookup } = opts;
54176
54176
  if (shouldLookup) {
54177
- host = await new Promise((resolve13, reject) => {
54177
+ host = await new Promise((resolve14, reject) => {
54178
54178
  lookupFn(host, {}, (err, res) => {
54179
54179
  if (err) {
54180
54180
  reject(err);
54181
54181
  } else {
54182
- resolve13(res);
54182
+ resolve14(res);
54183
54183
  }
54184
54184
  });
54185
54185
  });
@@ -55364,7 +55364,7 @@ var require_netUtils = __commonJS({
55364
55364
  return `${socket.remoteAddress}:${socket.remotePort}`;
55365
55365
  }
55366
55366
  function upgradeSocket(socket, options) {
55367
- return new Promise((resolve13, reject) => {
55367
+ return new Promise((resolve14, reject) => {
55368
55368
  const tlsOptions = Object.assign({}, options, {
55369
55369
  socket
55370
55370
  });
@@ -55374,7 +55374,7 @@ var require_netUtils = __commonJS({
55374
55374
  reject(tlsSocket.authorizationError);
55375
55375
  } else {
55376
55376
  tlsSocket.removeAllListeners("error");
55377
- resolve13(tlsSocket);
55377
+ resolve14(tlsSocket);
55378
55378
  }
55379
55379
  }).once("error", (error) => {
55380
55380
  reject(error);
@@ -55469,7 +55469,7 @@ var require_transfer = __commonJS({
55469
55469
  };
55470
55470
  }
55471
55471
  function connectForPassiveTransfer(host, port, ftp) {
55472
- return new Promise((resolve13, reject) => {
55472
+ return new Promise((resolve14, reject) => {
55473
55473
  let socket = ftp._newSocket();
55474
55474
  const handleConnErr = function(err) {
55475
55475
  err.message = "Can't open data connection in passive mode: " + err.message;
@@ -55497,7 +55497,7 @@ var require_transfer = __commonJS({
55497
55497
  socket.removeListener("error", handleConnErr);
55498
55498
  socket.removeListener("timeout", handleTimeout);
55499
55499
  ftp.dataSocket = socket;
55500
- resolve13();
55500
+ resolve14();
55501
55501
  });
55502
55502
  });
55503
55503
  }
@@ -67966,11 +67966,11 @@ function __metadata(metadataKey, metadataValue) {
67966
67966
  }
67967
67967
  function __awaiter2(thisArg, _arguments, P, generator) {
67968
67968
  function adopt(value) {
67969
- return value instanceof P ? value : new P(function(resolve13) {
67970
- resolve13(value);
67969
+ return value instanceof P ? value : new P(function(resolve14) {
67970
+ resolve14(value);
67971
67971
  });
67972
67972
  }
67973
- return new (P || (P = Promise))(function(resolve13, reject) {
67973
+ return new (P || (P = Promise))(function(resolve14, reject) {
67974
67974
  function fulfilled(value) {
67975
67975
  try {
67976
67976
  step(generator.next(value));
@@ -67986,7 +67986,7 @@ function __awaiter2(thisArg, _arguments, P, generator) {
67986
67986
  }
67987
67987
  }
67988
67988
  function step(result) {
67989
- result.done ? resolve13(result.value) : adopt(result.value).then(fulfilled, rejected);
67989
+ result.done ? resolve14(result.value) : adopt(result.value).then(fulfilled, rejected);
67990
67990
  }
67991
67991
  step((generator = generator.apply(thisArg, _arguments || [])).next());
67992
67992
  });
@@ -68177,14 +68177,14 @@ function __asyncValues2(o) {
68177
68177
  }, i);
68178
68178
  function verb(n) {
68179
68179
  i[n] = o[n] && function(v) {
68180
- return new Promise(function(resolve13, reject) {
68181
- v = o[n](v), settle(resolve13, reject, v.done, v.value);
68180
+ return new Promise(function(resolve14, reject) {
68181
+ v = o[n](v), settle(resolve14, reject, v.done, v.value);
68182
68182
  });
68183
68183
  };
68184
68184
  }
68185
- function settle(resolve13, reject, d, v) {
68185
+ function settle(resolve14, reject, d, v) {
68186
68186
  Promise.resolve(v).then(function(v2) {
68187
- resolve13({ value: v2, done: d });
68187
+ resolve14({ value: v2, done: d });
68188
68188
  }, reject);
68189
68189
  }
68190
68190
  }
@@ -71737,12 +71737,12 @@ var require_util3 = __commonJS({
71737
71737
  exports.isGMT = exports.dnsLookup = void 0;
71738
71738
  var dns_1 = __require("dns");
71739
71739
  function dnsLookup(host, opts) {
71740
- return new Promise((resolve13, reject) => {
71740
+ return new Promise((resolve14, reject) => {
71741
71741
  (0, dns_1.lookup)(host, opts, (err, res) => {
71742
71742
  if (err) {
71743
71743
  reject(err);
71744
71744
  } else {
71745
- resolve13(res);
71745
+ resolve14(res);
71746
71746
  }
71747
71747
  });
71748
71748
  });
@@ -72107,10 +72107,10 @@ var require_myIpAddress = __commonJS({
72107
72107
  var ip_1 = require_ip();
72108
72108
  var net_1 = __importDefault2(__require("net"));
72109
72109
  async function myIpAddress() {
72110
- return new Promise((resolve13, reject) => {
72110
+ return new Promise((resolve14, reject) => {
72111
72111
  const socket = net_1.default.connect({ host: "8.8.8.8", port: 53 });
72112
72112
  const onError = () => {
72113
- resolve13(ip_1.ip.address());
72113
+ resolve14(ip_1.ip.address());
72114
72114
  };
72115
72115
  socket.once("error", onError);
72116
72116
  socket.once("connect", () => {
@@ -72118,9 +72118,9 @@ var require_myIpAddress = __commonJS({
72118
72118
  const addr = socket.address();
72119
72119
  socket.destroy();
72120
72120
  if (typeof addr === "string") {
72121
- resolve13(addr);
72121
+ resolve14(addr);
72122
72122
  } else if (addr.address) {
72123
- resolve13(addr.address);
72123
+ resolve14(addr.address);
72124
72124
  } else {
72125
72125
  reject(new Error("Expected a `string`"));
72126
72126
  }
@@ -72698,8 +72698,8 @@ var require_deferred_promise = __commonJS({
72698
72698
  this.context = args.context;
72699
72699
  this.owner = args.context.runtime;
72700
72700
  this.handle = args.promiseHandle;
72701
- this.settled = new Promise((resolve13) => {
72702
- this.onSettled = resolve13;
72701
+ this.settled = new Promise((resolve14) => {
72702
+ this.onSettled = resolve14;
72703
72703
  });
72704
72704
  this.resolveHandle = args.resolveHandle;
72705
72705
  this.rejectHandle = args.rejectHandle;
@@ -73220,13 +73220,13 @@ var require_context = __commonJS({
73220
73220
  if (vmResolveResult.error) {
73221
73221
  return Promise.resolve(vmResolveResult);
73222
73222
  }
73223
- return new Promise((resolve13) => {
73223
+ return new Promise((resolve14) => {
73224
73224
  lifetime_1.Scope.withScope((scope) => {
73225
73225
  const resolveHandle = scope.manage(this.newFunction("resolve", (value) => {
73226
- resolve13({ value: value && value.dup() });
73226
+ resolve14({ value: value && value.dup() });
73227
73227
  }));
73228
73228
  const rejectHandle = scope.manage(this.newFunction("reject", (error) => {
73229
- resolve13({ error: error && error.dup() });
73229
+ resolve14({ error: error && error.dup() });
73230
73230
  }));
73231
73231
  const promiseHandle = scope.manage(vmResolveResult.value);
73232
73232
  const promiseThenHandle = scope.manage(this.getProp(promiseHandle, "then"));
@@ -75601,13 +75601,13 @@ import * as http from "node:http";
75601
75601
  import * as https from "node:https";
75602
75602
  import { URL as URL2, urlToHttpOptions } from "node:url";
75603
75603
  function headHttpRequest(url) {
75604
- return new Promise((resolve13) => {
75604
+ return new Promise((resolve14) => {
75605
75605
  const request3 = httpRequest(url, "HEAD", (response) => {
75606
75606
  response.resume();
75607
- resolve13(response.statusCode === 200);
75607
+ resolve14(response.statusCode === 200);
75608
75608
  }, false);
75609
75609
  request3.on("error", () => {
75610
- resolve13(false);
75610
+ resolve14(false);
75611
75611
  });
75612
75612
  });
75613
75613
  }
@@ -75635,7 +75635,7 @@ function httpRequest(url, method, response, keepAlive = true) {
75635
75635
  return request3;
75636
75636
  }
75637
75637
  function downloadFile(url, destinationPath, progressCallback) {
75638
- return new Promise((resolve13, reject) => {
75638
+ return new Promise((resolve14, reject) => {
75639
75639
  let downloadedBytes = 0;
75640
75640
  let totalBytes = 0;
75641
75641
  function onData(chunk) {
@@ -75651,7 +75651,7 @@ function downloadFile(url, destinationPath, progressCallback) {
75651
75651
  }
75652
75652
  const file = createWriteStream(destinationPath);
75653
75653
  file.on("close", () => {
75654
- return resolve13();
75654
+ return resolve14();
75655
75655
  });
75656
75656
  file.on("error", (error) => {
75657
75657
  return reject(error);
@@ -75676,7 +75676,7 @@ async function getJSON(url) {
75676
75676
  }
75677
75677
  }
75678
75678
  function getText3(url) {
75679
- return new Promise((resolve13, reject) => {
75679
+ return new Promise((resolve14, reject) => {
75680
75680
  const request3 = httpRequest(url, "GET", (response) => {
75681
75681
  let data = "";
75682
75682
  if (response.statusCode && response.statusCode >= 400) {
@@ -75687,7 +75687,7 @@ function getText3(url) {
75687
75687
  });
75688
75688
  response.on("end", () => {
75689
75689
  try {
75690
- return resolve13(String(data));
75690
+ return resolve14(String(data));
75691
75691
  } catch {
75692
75692
  return reject(new Error(`Failed to read text response from ${url}`));
75693
75693
  }
@@ -77079,7 +77079,7 @@ var init_launch = __esm({
77079
77079
  if (opts.onExit) {
77080
77080
  this.#onExitHook = opts.onExit;
77081
77081
  }
77082
- this.#browserProcessExiting = new Promise((resolve13, reject) => {
77082
+ this.#browserProcessExiting = new Promise((resolve14, reject) => {
77083
77083
  this.#browserProcess.once("exit", async () => {
77084
77084
  debugLaunch(`Browser process ${this.#browserProcess.pid} onExit`);
77085
77085
  this.#clearListeners();
@@ -77090,7 +77090,7 @@ var init_launch = __esm({
77090
77090
  reject(err);
77091
77091
  return;
77092
77092
  }
77093
- resolve13();
77093
+ resolve14();
77094
77094
  });
77095
77095
  });
77096
77096
  }
@@ -77206,7 +77206,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77206
77206
  return [...this.#logs];
77207
77207
  }
77208
77208
  waitForLineOutput(regex, timeout2 = 0) {
77209
- return new Promise((resolve13, reject) => {
77209
+ return new Promise((resolve14, reject) => {
77210
77210
  const onClose = (errorOrCode) => {
77211
77211
  cleanup();
77212
77212
  reject(new Error([
@@ -77242,7 +77242,7 @@ Error cause: ${isErrorLike2(error) ? error.stack : error}`);
77242
77242
  return;
77243
77243
  }
77244
77244
  cleanup();
77245
- resolve13(match2[1]);
77245
+ resolve14(match2[1]);
77246
77246
  }
77247
77247
  });
77248
77248
  }
@@ -77711,7 +77711,7 @@ var require_get_stream = __commonJS({
77711
77711
  };
77712
77712
  const { maxBuffer } = options;
77713
77713
  let stream2;
77714
- await new Promise((resolve13, reject) => {
77714
+ await new Promise((resolve14, reject) => {
77715
77715
  const rejectPromise = (error) => {
77716
77716
  if (error && stream2.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
77717
77717
  error.bufferedData = stream2.getBufferedValue();
@@ -77723,7 +77723,7 @@ var require_get_stream = __commonJS({
77723
77723
  rejectPromise(error);
77724
77724
  return;
77725
77725
  }
77726
- resolve13();
77726
+ resolve14();
77727
77727
  });
77728
77728
  stream2.on("data", () => {
77729
77729
  if (stream2.getBufferedLength() > maxBuffer) {
@@ -79012,7 +79012,7 @@ var require_extract_zip = __commonJS({
79012
79012
  debug6("opening", this.zipPath, "with opts", this.opts);
79013
79013
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
79014
79014
  this.canceled = false;
79015
- return new Promise((resolve13, reject) => {
79015
+ return new Promise((resolve14, reject) => {
79016
79016
  this.zipfile.on("error", (err) => {
79017
79017
  this.canceled = true;
79018
79018
  reject(err);
@@ -79021,7 +79021,7 @@ var require_extract_zip = __commonJS({
79021
79021
  this.zipfile.on("close", () => {
79022
79022
  if (!this.canceled) {
79023
79023
  debug6("zip extraction complete");
79024
- resolve13();
79024
+ resolve14();
79025
79025
  }
79026
79026
  });
79027
79027
  this.zipfile.on("entry", async (entry) => {
@@ -80278,8 +80278,8 @@ var require_streamx = __commonJS({
80278
80278
  return this;
80279
80279
  },
80280
80280
  next() {
80281
- return new Promise(function(resolve13, reject) {
80282
- promiseResolve = resolve13;
80281
+ return new Promise(function(resolve14, reject) {
80282
+ promiseResolve = resolve14;
80283
80283
  promiseReject = reject;
80284
80284
  const data = stream2.read();
80285
80285
  if (data !== null) ondata(data);
@@ -80309,11 +80309,11 @@ var require_streamx = __commonJS({
80309
80309
  }
80310
80310
  function destroy(err) {
80311
80311
  stream2.destroy(err);
80312
- return new Promise((resolve13, reject) => {
80313
- if (stream2._duplexState & DESTROYED) return resolve13({ value: void 0, done: true });
80312
+ return new Promise((resolve14, reject) => {
80313
+ if (stream2._duplexState & DESTROYED) return resolve14({ value: void 0, done: true });
80314
80314
  stream2.once("close", function() {
80315
80315
  if (err) reject(err);
80316
- else resolve13({ value: void 0, done: true });
80316
+ else resolve14({ value: void 0, done: true });
80317
80317
  });
80318
80318
  });
80319
80319
  }
@@ -80357,8 +80357,8 @@ var require_streamx = __commonJS({
80357
80357
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
80358
80358
  if (writes === 0) return Promise.resolve(true);
80359
80359
  if (state.drains === null) state.drains = [];
80360
- return new Promise((resolve13) => {
80361
- state.drains.push({ writes, resolve: resolve13 });
80360
+ return new Promise((resolve14) => {
80361
+ state.drains.push({ writes, resolve: resolve14 });
80362
80362
  });
80363
80363
  }
80364
80364
  write(data) {
@@ -80463,10 +80463,10 @@ var require_streamx = __commonJS({
80463
80463
  cb(null);
80464
80464
  }
80465
80465
  function pipelinePromise(...streams) {
80466
- return new Promise((resolve13, reject) => {
80466
+ return new Promise((resolve14, reject) => {
80467
80467
  return pipeline(...streams, (err) => {
80468
80468
  if (err) return reject(err);
80469
- resolve13();
80469
+ resolve14();
80470
80470
  });
80471
80471
  });
80472
80472
  }
@@ -81121,16 +81121,16 @@ var require_extract = __commonJS({
81121
81121
  entryCallback = null;
81122
81122
  cb(err);
81123
81123
  }
81124
- function onnext(resolve13, reject) {
81124
+ function onnext(resolve14, reject) {
81125
81125
  if (error) {
81126
81126
  return reject(error);
81127
81127
  }
81128
81128
  if (entryStream) {
81129
- resolve13({ value: entryStream, done: false });
81129
+ resolve14({ value: entryStream, done: false });
81130
81130
  entryStream = null;
81131
81131
  return;
81132
81132
  }
81133
- promiseResolve = resolve13;
81133
+ promiseResolve = resolve14;
81134
81134
  promiseReject = reject;
81135
81135
  consumeCallback(null);
81136
81136
  if (extract._finished && promiseResolve) {
@@ -81158,11 +81158,11 @@ var require_extract = __commonJS({
81158
81158
  function destroy(err) {
81159
81159
  extract.destroy(err);
81160
81160
  consumeCallback(err);
81161
- return new Promise((resolve13, reject) => {
81162
- if (extract.destroyed) return resolve13({ value: void 0, done: true });
81161
+ return new Promise((resolve14, reject) => {
81162
+ if (extract.destroyed) return resolve14({ value: void 0, done: true });
81163
81163
  extract.once("close", function() {
81164
81164
  if (err) reject(err);
81165
- else resolve13({ value: void 0, done: true });
81165
+ else resolve14({ value: void 0, done: true });
81166
81166
  });
81167
81167
  });
81168
81168
  }
@@ -84931,13 +84931,13 @@ function usage(yargs, shim3) {
84931
84931
  };
84932
84932
  self2.stringifiedValues = function stringifiedValues(values, separator) {
84933
84933
  let string = "";
84934
- const sep = separator || ", ";
84934
+ const sep2 = separator || ", ";
84935
84935
  const array = [].concat(values);
84936
84936
  if (!values || !array.length)
84937
84937
  return string;
84938
84938
  array.forEach((value) => {
84939
84939
  if (string.length)
84940
- string += sep;
84940
+ string += sep2;
84941
84941
  string += JSON.stringify(value);
84942
84942
  });
84943
84943
  return string;
@@ -86138,12 +86138,12 @@ var init_yargs_factory = __esm({
86138
86138
  async getCompletion(args, done) {
86139
86139
  argsert("<array> [function]", [args, done], arguments.length);
86140
86140
  if (!done) {
86141
- return new Promise((resolve13, reject) => {
86141
+ return new Promise((resolve14, reject) => {
86142
86142
  __classPrivateFieldGet2(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
86143
86143
  if (err)
86144
86144
  reject(err);
86145
86145
  else
86146
- resolve13(completions);
86146
+ resolve14(completions);
86147
86147
  });
86148
86148
  });
86149
86149
  } else {
@@ -88944,8 +88944,8 @@ var init_ScreenRecorder = __esm({
88944
88944
  static {
88945
88945
  const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
88946
88946
  __esDecorate23(this, _private_writeFrame_descriptor = { value: __setFunctionName6(async function(buffer) {
88947
- const error = await new Promise((resolve13) => {
88948
- this.#process.stdin.write(buffer, resolve13);
88947
+ const error = await new Promise((resolve14) => {
88948
+ this.#process.stdin.write(buffer, resolve14);
88949
88949
  });
88950
88950
  if (error) {
88951
88951
  console.log(`ffmpeg failed to write: ${error.message}.`);
@@ -89135,8 +89135,8 @@ var init_ScreenRecorder = __esm({
89135
89135
  const [buffer, timestamp] = await this.#lastFrame;
89136
89136
  await Promise.all(Array(Math.max(1, Math.round(this.#fps * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
89137
89137
  this.#process.stdin.end();
89138
- await new Promise((resolve13) => {
89139
- this.#process.once("close", resolve13);
89138
+ await new Promise((resolve14) => {
89139
+ this.#process.once("close", resolve14);
89140
89140
  });
89141
89141
  }
89142
89142
  /**
@@ -89426,7 +89426,7 @@ import {
89426
89426
  rmSync as rmSync4,
89427
89427
  createReadStream as createReadStream2
89428
89428
  } from "node:fs";
89429
- import { resolve as resolve12, dirname as dirname11, join as join17 } from "node:path";
89429
+ import { resolve as resolve13, dirname as dirname11, join as join17 } from "node:path";
89430
89430
  import { tmpdir as tmpdir2 } from "node:os";
89431
89431
  import { parseArgs } from "node:util";
89432
89432
  import crypto2 from "node:crypto";
@@ -92061,7 +92061,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
92061
92061
  });
92062
92062
  if (!chunk) {
92063
92063
  if (i === 1) {
92064
- await new Promise((resolve13) => setTimeout(resolve13));
92064
+ await new Promise((resolve14) => setTimeout(resolve14));
92065
92065
  maxReadCount = 3;
92066
92066
  continue;
92067
92067
  }
@@ -95822,8 +95822,8 @@ var CustomElementRegistry = class {
95822
95822
  } : (element) => element.localName === localName;
95823
95823
  registry.set(localName, { Class, check });
95824
95824
  if (waiting.has(localName)) {
95825
- for (const resolve13 of waiting.get(localName))
95826
- resolve13(Class);
95825
+ for (const resolve14 of waiting.get(localName))
95826
+ resolve14(Class);
95827
95827
  waiting.delete(localName);
95828
95828
  }
95829
95829
  ownerDocument.querySelectorAll(
@@ -95863,13 +95863,13 @@ var CustomElementRegistry = class {
95863
95863
  */
95864
95864
  whenDefined(localName) {
95865
95865
  const { registry, waiting } = this;
95866
- return new Promise((resolve13) => {
95866
+ return new Promise((resolve14) => {
95867
95867
  if (registry.has(localName))
95868
- resolve13(registry.get(localName).Class);
95868
+ resolve14(registry.get(localName).Class);
95869
95869
  else {
95870
95870
  if (!waiting.has(localName))
95871
95871
  waiting.set(localName, []);
95872
- waiting.get(localName).push(resolve13);
95872
+ waiting.get(localName).push(resolve14);
95873
95873
  }
95874
95874
  });
95875
95875
  }
@@ -101519,7 +101519,7 @@ function resolveConfig(overrides) {
101519
101519
  hdr: (() => {
101520
101520
  const raw2 = env2("PRODUCER_HDR_TRANSFER");
101521
101521
  if (raw2 === "hlg" || raw2 === "pq") return { transfer: raw2 };
101522
- return void 0;
101522
+ return false;
101523
101523
  })(),
101524
101524
  hdrAutoDetect: envBool("PRODUCER_HDR_AUTO_DETECT", DEFAULT_CONFIG.hdrAutoDetect),
101525
101525
  audioGain: envNum("PRODUCER_AUDIO_GAIN", DEFAULT_CONFIG.audioGain),
@@ -103921,7 +103921,8 @@ async function injectVideoFramesBatch(page, updates) {
103921
103921
  let img = video.nextElementSibling;
103922
103922
  const isNewImage = !img || !img.classList.contains("__render_frame__");
103923
103923
  const computedStyle = window.getComputedStyle(video);
103924
- const computedOpacity = parseFloat(computedStyle.opacity) || 1;
103924
+ const opacityParsed = parseFloat(computedStyle.opacity);
103925
+ const computedOpacity = Number.isNaN(opacityParsed) ? 1 : opacityParsed;
103925
103926
  const sourceIsStatic = !computedStyle.position || computedStyle.position === "static";
103926
103927
  if (isNewImage) {
103927
103928
  img = document.createElement("img");
@@ -103967,7 +103968,6 @@ async function injectVideoFramesBatch(page, updates) {
103967
103968
  img.style.opacity = String(computedOpacity);
103968
103969
  img.style.visibility = "visible";
103969
103970
  video.style.setProperty("visibility", "hidden", "important");
103970
- video.style.setProperty("opacity", "0", "important");
103971
103971
  video.style.setProperty("pointer-events", "none", "important");
103972
103972
  }
103973
103973
  if (pendingDecodes.length > 0) {
@@ -103994,7 +103994,6 @@ async function syncVideoFrameVisibility(page, activeVideoIds) {
103994
103994
  } else {
103995
103995
  video.style.removeProperty("display");
103996
103996
  video.style.setProperty("visibility", "hidden", "important");
103997
- video.style.setProperty("opacity", "0", "important");
103998
103997
  video.style.setProperty("pointer-events", "none", "important");
103999
103998
  if (hasImg) {
104000
103999
  img.style.visibility = "hidden";
@@ -104085,7 +104084,7 @@ async function pollPageExpression(page, expression, timeoutMs, intervalMs = 100)
104085
104084
  while (Date.now() < deadline) {
104086
104085
  const ready = Boolean(await page.evaluate(expression));
104087
104086
  if (ready) return true;
104088
- await new Promise((resolve13) => setTimeout(resolve13, intervalMs));
104087
+ await new Promise((resolve14) => setTimeout(resolve14, intervalMs));
104089
104088
  }
104090
104089
  return Boolean(await page.evaluate(expression));
104091
104090
  }
@@ -104316,9 +104315,15 @@ async function captureFrameToBuffer(session, frameIndex, time) {
104316
104315
  return { buffer, captureTimeMs };
104317
104316
  }
104318
104317
  async function closeCaptureSession(session) {
104319
- if (session.page) await session.page.close().catch(() => {
104320
- });
104321
- if (session.browser) await releaseBrowser(session.browser, session.config);
104318
+ if (!session.pageReleased && session.page) {
104319
+ await session.page.close().catch(() => {
104320
+ });
104321
+ session.pageReleased = true;
104322
+ }
104323
+ if (!session.browserReleased && session.browser) {
104324
+ await releaseBrowser(session.browser, session.config);
104325
+ session.browserReleased = true;
104326
+ }
104322
104327
  session.isInitialized = false;
104323
104328
  }
104324
104329
  function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
@@ -104362,7 +104367,7 @@ import { join as join6, dirname as dirname5 } from "path";
104362
104367
  // ../engine/src/utils/gpuEncoder.ts
104363
104368
  import { spawn as spawn3 } from "child_process";
104364
104369
  async function detectGpuEncoder() {
104365
- return new Promise((resolve13) => {
104370
+ return new Promise((resolve14) => {
104366
104371
  const ffmpeg = spawn3("ffmpeg", ["-encoders"], {
104367
104372
  stdio: ["pipe", "pipe", "pipe"]
104368
104373
  });
@@ -104371,13 +104376,13 @@ async function detectGpuEncoder() {
104371
104376
  stdout += data.toString();
104372
104377
  });
104373
104378
  ffmpeg.on("close", () => {
104374
- if (stdout.includes("h264_nvenc")) resolve13("nvenc");
104375
- else if (stdout.includes("h264_videotoolbox")) resolve13("videotoolbox");
104376
- else if (stdout.includes("h264_vaapi")) resolve13("vaapi");
104377
- else if (stdout.includes("h264_qsv")) resolve13("qsv");
104378
- else resolve13(null);
104379
+ if (stdout.includes("h264_nvenc")) resolve14("nvenc");
104380
+ else if (stdout.includes("h264_videotoolbox")) resolve14("videotoolbox");
104381
+ else if (stdout.includes("h264_vaapi")) resolve14("vaapi");
104382
+ else if (stdout.includes("h264_qsv")) resolve14("qsv");
104383
+ else resolve14(null);
104379
104384
  });
104380
- ffmpeg.on("error", () => resolve13(null));
104385
+ ffmpeg.on("error", () => resolve14(null));
104381
104386
  });
104382
104387
  }
104383
104388
  var cachedGpuEncoder = void 0;
@@ -104403,6 +104408,45 @@ function getGpuEncoderName(encoder, codec) {
104403
104408
  }
104404
104409
  }
104405
104410
 
104411
+ // ../engine/src/utils/hdr.ts
104412
+ function isHdrColorSpace(cs) {
104413
+ if (!cs) return false;
104414
+ return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
104415
+ }
104416
+ function detectTransfer(cs) {
104417
+ if (cs?.colorTransfer === "smpte2084") return "pq";
104418
+ return "hlg";
104419
+ }
104420
+ var DEFAULT_HDR10_MASTERING = {
104421
+ masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
104422
+ maxCll: "1000,400"
104423
+ };
104424
+ function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
104425
+ const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
104426
+ const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
104427
+ const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
104428
+ return {
104429
+ colorPrimaries: "bt2020",
104430
+ colorTrc,
104431
+ colorspace: "bt2020nc",
104432
+ pixelFormat: "yuv420p10le",
104433
+ x265ColorParams: `${tagging}:${metadata}`,
104434
+ mastering
104435
+ };
104436
+ }
104437
+ function analyzeCompositionHdr(colorSpaces) {
104438
+ let hasPq = false;
104439
+ let hasHdr = false;
104440
+ for (const cs of colorSpaces) {
104441
+ if (!isHdrColorSpace(cs)) continue;
104442
+ hasHdr = true;
104443
+ if (cs?.colorTransfer === "smpte2084") hasPq = true;
104444
+ }
104445
+ if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
104446
+ const dominantTransfer = hasPq ? "pq" : "hlg";
104447
+ return { hasHdr: true, dominantTransfer };
104448
+ }
104449
+
104406
104450
  // ../engine/src/utils/runFfmpeg.ts
104407
104451
  import { spawn as spawn4 } from "child_process";
104408
104452
  var DEFAULT_TIMEOUT2 = 3e5;
@@ -104411,7 +104455,7 @@ async function runFfmpeg(args, opts) {
104411
104455
  const signal = opts?.signal;
104412
104456
  const timeout2 = opts?.timeout ?? DEFAULT_TIMEOUT2;
104413
104457
  const onStderr = opts?.onStderr;
104414
- return new Promise((resolve13) => {
104458
+ return new Promise((resolve14) => {
104415
104459
  const ffmpeg = spawn4("ffmpeg", args);
104416
104460
  let stderr = "";
104417
104461
  const onAbort = () => {
@@ -104437,7 +104481,7 @@ async function runFfmpeg(args, opts) {
104437
104481
  ffmpeg.on("close", (code) => {
104438
104482
  clearTimeout(timer2);
104439
104483
  if (signal) signal.removeEventListener("abort", onAbort);
104440
- resolve13({
104484
+ resolve14({
104441
104485
  success: !signal?.aborted && code === 0,
104442
104486
  exitCode: code,
104443
104487
  stderr,
@@ -104447,7 +104491,7 @@ async function runFfmpeg(args, opts) {
104447
104491
  ffmpeg.on("error", (err) => {
104448
104492
  clearTimeout(timer2);
104449
104493
  if (signal) signal.removeEventListener("abort", onAbort);
104450
- resolve13({
104494
+ resolve14({
104451
104495
  success: false,
104452
104496
  exitCode: null,
104453
104497
  stderr: err.message,
@@ -104502,6 +104546,12 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104502
104546
  pixelFormat = "yuv420p",
104503
104547
  useGpu = false
104504
104548
  } = options;
104549
+ if (options.hdr && codec === "h264") {
104550
+ console.warn(
104551
+ "[chunkEncoder] HDR is not supported with codec=h264 (libx264 has no HDR support). Stripping HDR metadata and tagging output as SDR/BT.709. Use codec=h265 for HDR output."
104552
+ );
104553
+ options = { ...options, hdr: void 0 };
104554
+ }
104505
104555
  const args = [...inputArgs, "-r", String(fps)];
104506
104556
  const shouldUseGpu = useGpu && gpuEncoder !== null;
104507
104557
  if (codec === "h264" || codec === "h265") {
@@ -104540,7 +104590,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104540
104590
  if (bitrate) args.push("-b:v", bitrate);
104541
104591
  else args.push("-crf", String(quality));
104542
104592
  const xParamsFlag = codec === "h264" ? "-x264-params" : "-x265-params";
104543
- const colorParams = "colorprim=bt709:transfer=bt709:colormatrix=bt709";
104593
+ const colorParams = codec === "h265" && options.hdr ? getHdrEncoderColorParams(options.hdr.transfer).x265ColorParams : "colorprim=bt709:transfer=bt709:colormatrix=bt709";
104544
104594
  if (preset === "ultrafast") {
104545
104595
  args.push(xParamsFlag, `aq-mode=3:${colorParams}`);
104546
104596
  } else {
@@ -104564,16 +104614,30 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
104564
104614
  return [...args, "-y", outputPath];
104565
104615
  }
104566
104616
  if (codec === "h264" || codec === "h265") {
104567
- args.push(
104568
- "-colorspace:v",
104569
- "bt709",
104570
- "-color_primaries:v",
104571
- "bt709",
104572
- "-color_trc:v",
104573
- "bt709",
104574
- "-color_range",
104575
- "tv"
104576
- );
104617
+ if (options.hdr) {
104618
+ const transferTag = options.hdr.transfer === "pq" ? "smpte2084" : "arib-std-b67";
104619
+ args.push(
104620
+ "-colorspace:v",
104621
+ "bt2020nc",
104622
+ "-color_primaries:v",
104623
+ "bt2020",
104624
+ "-color_trc:v",
104625
+ transferTag,
104626
+ "-color_range",
104627
+ "tv"
104628
+ );
104629
+ } else {
104630
+ args.push(
104631
+ "-colorspace:v",
104632
+ "bt709",
104633
+ "-color_primaries:v",
104634
+ "bt709",
104635
+ "-color_trc:v",
104636
+ "bt709",
104637
+ "-color_range",
104638
+ "tv"
104639
+ );
104640
+ }
104577
104641
  if (gpuEncoder === "vaapi") {
104578
104642
  const vfIdx = args.indexOf("-vf");
104579
104643
  if (vfIdx !== -1) {
@@ -104613,7 +104677,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104613
104677
  const inputPath = join6(framesDir, framePattern);
104614
104678
  const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
104615
104679
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
104616
- return new Promise((resolve13) => {
104680
+ return new Promise((resolve14) => {
104617
104681
  const ffmpeg = spawn5("ffmpeg", args);
104618
104682
  let stderr = "";
104619
104683
  const onAbort = () => {
@@ -104638,7 +104702,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104638
104702
  if (signal) signal.removeEventListener("abort", onAbort);
104639
104703
  const durationMs = Date.now() - startTime;
104640
104704
  if (signal?.aborted) {
104641
- resolve13({
104705
+ resolve14({
104642
104706
  success: false,
104643
104707
  outputPath,
104644
104708
  durationMs,
@@ -104649,7 +104713,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104649
104713
  return;
104650
104714
  }
104651
104715
  if (code !== 0) {
104652
- resolve13({
104716
+ resolve14({
104653
104717
  success: false,
104654
104718
  outputPath,
104655
104719
  durationMs,
@@ -104660,12 +104724,12 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
104660
104724
  return;
104661
104725
  }
104662
104726
  const fileSize = existsSync5(outputPath) ? statSync3(outputPath).size : 0;
104663
- resolve13({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
104727
+ resolve14({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
104664
104728
  });
104665
104729
  ffmpeg.on("error", (err) => {
104666
104730
  clearTimeout(timer2);
104667
104731
  if (signal) signal.removeEventListener("abort", onAbort);
104668
- resolve13({
104732
+ resolve14({
104669
104733
  success: false,
104670
104734
  outputPath,
104671
104735
  durationMs: Date.now() - startTime,
@@ -104723,18 +104787,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
104723
104787
  let gpuEncoder = null;
104724
104788
  if (options.useGpu) gpuEncoder = await getCachedGpuEncoder();
104725
104789
  const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
104726
- const chunkResult = await new Promise((resolve13) => {
104790
+ const chunkResult = await new Promise((resolve14) => {
104727
104791
  const ffmpeg = spawn5("ffmpeg", args);
104728
104792
  let stderr = "";
104729
104793
  ffmpeg.stderr.on("data", (d) => {
104730
104794
  stderr += d.toString();
104731
104795
  });
104732
104796
  ffmpeg.on("close", (code) => {
104733
- if (code === 0) resolve13({ success: true });
104734
- else resolve13({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
104797
+ if (code === 0) resolve14({ success: true });
104798
+ else resolve14({ success: false, error: `Chunk ${i} encode failed: ${stderr.slice(-400)}` });
104735
104799
  });
104736
104800
  ffmpeg.on("error", (err) => {
104737
- resolve13({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
104801
+ resolve14({ success: false, error: `Chunk ${i} encode error: ${err.message}` });
104738
104802
  });
104739
104803
  });
104740
104804
  if (!chunkResult.success) {
@@ -104764,18 +104828,18 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
104764
104828
  "-y",
104765
104829
  outputPath
104766
104830
  ];
104767
- const concatResult = await new Promise((resolve13) => {
104831
+ const concatResult = await new Promise((resolve14) => {
104768
104832
  const ffmpeg = spawn5("ffmpeg", concatArgs);
104769
104833
  let stderr = "";
104770
104834
  ffmpeg.stderr.on("data", (d) => {
104771
104835
  stderr += d.toString();
104772
104836
  });
104773
104837
  ffmpeg.on("close", (code) => {
104774
- if (code === 0) resolve13({ success: true });
104775
- else resolve13({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
104838
+ if (code === 0) resolve14({ success: true });
104839
+ else resolve14({ success: false, error: `Chunk concat failed: ${stderr.slice(-400)}` });
104776
104840
  });
104777
104841
  ffmpeg.on("error", (err) => {
104778
- resolve13({ success: false, error: `Chunk concat error: ${err.message}` });
104842
+ resolve14({ success: false, error: `Chunk concat error: ${err.message}` });
104779
104843
  });
104780
104844
  });
104781
104845
  if (!concatResult.success) {
@@ -104856,81 +104920,40 @@ async function applyFaststart(inputPath, outputPath, signal, config2) {
104856
104920
  import { spawn as spawn6 } from "child_process";
104857
104921
  import { existsSync as existsSync6, mkdirSync as mkdirSync3, statSync as statSync4 } from "fs";
104858
104922
  import { dirname as dirname6 } from "path";
104859
-
104860
- // ../engine/src/utils/hdr.ts
104861
- function isHdrColorSpace(cs) {
104862
- if (!cs) return false;
104863
- return cs.colorPrimaries.includes("bt2020") || cs.colorSpace.includes("bt2020") || cs.colorTransfer === "smpte2084" || cs.colorTransfer === "arib-std-b67";
104864
- }
104865
- function detectTransfer(cs) {
104866
- if (cs?.colorTransfer === "smpte2084") return "pq";
104867
- return "hlg";
104868
- }
104869
- var DEFAULT_HDR10_MASTERING = {
104870
- masterDisplay: "G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)",
104871
- maxCll: "1000,400"
104872
- };
104873
- function getHdrEncoderColorParams(transfer, mastering = DEFAULT_HDR10_MASTERING) {
104874
- const colorTrc = transfer === "pq" ? "smpte2084" : "arib-std-b67";
104875
- const tagging = `colorprim=bt2020:transfer=${colorTrc}:colormatrix=bt2020nc`;
104876
- const metadata = `master-display=${mastering.masterDisplay}:max-cll=${mastering.maxCll}`;
104877
- return {
104878
- colorPrimaries: "bt2020",
104879
- colorTrc,
104880
- colorspace: "bt2020nc",
104881
- pixelFormat: "yuv420p10le",
104882
- x265ColorParams: `${tagging}:${metadata}`,
104883
- mastering
104884
- };
104885
- }
104886
- function analyzeCompositionHdr(colorSpaces) {
104887
- let hasPq = false;
104888
- let hasHdr = false;
104889
- for (const cs of colorSpaces) {
104890
- if (!isHdrColorSpace(cs)) continue;
104891
- hasHdr = true;
104892
- if (cs?.colorTransfer === "smpte2084") hasPq = true;
104893
- }
104894
- if (!hasHdr) return { hasHdr: false, dominantTransfer: null };
104895
- const dominantTransfer = hasPq ? "pq" : "hlg";
104896
- return { hasHdr: true, dominantTransfer };
104897
- }
104898
-
104899
- // ../engine/src/services/streamingEncoder.ts
104900
104923
  function createFrameReorderBuffer(startFrame, endFrame) {
104901
104924
  let cursor = startFrame;
104902
104925
  const pending = /* @__PURE__ */ new Map();
104903
- const enqueueAt = (frame, resolve13) => {
104926
+ const enqueueAt = (frame, resolve14) => {
104904
104927
  const list = pending.get(frame);
104905
104928
  if (list === void 0) {
104906
- pending.set(frame, [resolve13]);
104929
+ pending.set(frame, [resolve14]);
104907
104930
  } else {
104908
- list.push(resolve13);
104931
+ list.push(resolve14);
104909
104932
  }
104910
104933
  };
104911
104934
  const flushAt = (frame) => {
104912
104935
  const list = pending.get(frame);
104913
104936
  if (list === void 0) return;
104914
104937
  pending.delete(frame);
104915
- for (const resolve13 of list) resolve13();
104938
+ for (const resolve14 of list) resolve14();
104916
104939
  };
104917
- const waitForFrame = (frame) => new Promise((resolve13) => {
104940
+ const waitForFrame = (frame) => new Promise((resolve14) => {
104918
104941
  if (frame === cursor) {
104919
- resolve13();
104942
+ resolve14();
104920
104943
  return;
104921
104944
  }
104922
- enqueueAt(frame, resolve13);
104945
+ enqueueAt(frame, resolve14);
104923
104946
  });
104924
104947
  const advanceTo = (frame) => {
104925
104948
  cursor = frame;
104926
104949
  flushAt(frame);
104927
104950
  };
104928
- const waitForAllDone = () => new Promise((resolve13) => {
104951
+ const waitForAllDone = () => new Promise((resolve14) => {
104929
104952
  if (cursor >= endFrame) {
104930
- resolve13();
104953
+ resolve14();
104931
104954
  return;
104932
104955
  }
104933
- enqueueAt(endFrame, resolve13);
104956
+ enqueueAt(endFrame, resolve14);
104934
104957
  });
104935
104958
  return { waitForFrame, advanceTo, waitForAllDone };
104936
104959
  }
@@ -105092,7 +105115,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config2) {
105092
105115
  let stderr = "";
105093
105116
  let exitCode = null;
105094
105117
  let exitPromiseResolve = null;
105095
- const exitPromise = new Promise((resolve13) => exitPromiseResolve = resolve13);
105118
+ const exitPromise = new Promise((resolve14) => exitPromiseResolve = resolve14);
105096
105119
  ffmpeg.stderr?.on("data", (data) => {
105097
105120
  stderr += data.toString();
105098
105121
  });
@@ -105138,8 +105161,8 @@ Process error: ${err.message}`;
105138
105161
  if (signal) signal.removeEventListener("abort", onAbort);
105139
105162
  const stdin = ffmpeg.stdin;
105140
105163
  if (stdin && !stdin.destroyed) {
105141
- await new Promise((resolve13) => {
105142
- stdin.end(() => resolve13());
105164
+ await new Promise((resolve14) => {
105165
+ stdin.end(() => resolve14());
105143
105166
  });
105144
105167
  }
105145
105168
  await exitPromise;
@@ -105178,7 +105201,7 @@ import { spawn as spawn7 } from "child_process";
105178
105201
  import { readFileSync as readFileSync5 } from "fs";
105179
105202
  import { extname as extname2 } from "path";
105180
105203
  function runFfprobe(args) {
105181
- return new Promise((resolve13, reject) => {
105204
+ return new Promise((resolve14, reject) => {
105182
105205
  const proc = spawn7("ffprobe", args);
105183
105206
  let stdout = "";
105184
105207
  let stderr = "";
@@ -105192,7 +105215,7 @@ function runFfprobe(args) {
105192
105215
  if (code !== 0) {
105193
105216
  reject(new Error(`[FFmpeg] ffprobe exited with code ${code}: ${stderr}`));
105194
105217
  } else {
105195
- resolve13(stdout);
105218
+ resolve14(stdout);
105196
105219
  }
105197
105220
  });
105198
105221
  proc.on("error", (err) => {
@@ -105591,7 +105614,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105591
105614
  args.push("-q:v", format3 === "jpg" ? String(Math.ceil((100 - quality) / 3)) : "0");
105592
105615
  if (format3 === "png") args.push("-compression_level", "6");
105593
105616
  args.push("-y", outputPattern);
105594
- return new Promise((resolve13, reject) => {
105617
+ return new Promise((resolve14, reject) => {
105595
105618
  const ffmpeg = spawn8("ffmpeg", args);
105596
105619
  let stderr = "";
105597
105620
  const onAbort = () => {
@@ -105626,7 +105649,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105626
105649
  files.forEach((file, index) => {
105627
105650
  framePaths.set(index, join8(videoOutputDir, file));
105628
105651
  });
105629
- resolve13({
105652
+ resolve14({
105630
105653
  videoId,
105631
105654
  srcPath: videoPath,
105632
105655
  outputDir: videoOutputDir,
@@ -105648,8 +105671,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
105648
105671
  });
105649
105672
  });
105650
105673
  }
105651
- async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
105674
+ async function convertSdrToHdr(inputPath, outputPath, targetTransfer, signal, config2) {
105652
105675
  const timeout2 = config2?.ffmpegProcessTimeout ?? DEFAULT_CONFIG.ffmpegProcessTimeout;
105676
+ const colorTrc = targetTransfer === "pq" ? "smpte2084" : "arib-std-b67";
105653
105677
  const args = [
105654
105678
  "-i",
105655
105679
  inputPath,
@@ -105658,7 +105682,7 @@ async function convertSdrToHdr(inputPath, outputPath, signal, config2) {
105658
105682
  "-color_primaries",
105659
105683
  "bt2020",
105660
105684
  "-color_trc",
105661
- "arib-std-b67",
105685
+ colorTrc,
105662
105686
  "-colorspace",
105663
105687
  "bt2020nc",
105664
105688
  "-c:v",
@@ -105744,8 +105768,9 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105744
105768
  return metadata.colorSpace;
105745
105769
  })
105746
105770
  );
105747
- const hasAnyHdr = videoColorSpaces.some(isHdrColorSpace);
105748
- if (hasAnyHdr) {
105771
+ const hdrInfo = analyzeCompositionHdr(videoColorSpaces);
105772
+ if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
105773
+ const targetTransfer = hdrInfo.dominantTransfer;
105749
105774
  const convertDir = join8(options.outputDir, "_hdr_normalized");
105750
105775
  mkdirSync5(convertDir, { recursive: true });
105751
105776
  for (let i = 0; i < resolvedVideos.length; i++) {
@@ -105756,7 +105781,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config2,
105756
105781
  if (!entry) continue;
105757
105782
  const convertedPath = join8(convertDir, `${entry.video.id}_hdr.mp4`);
105758
105783
  try {
105759
- await convertSdrToHdr(entry.videoPath, convertedPath, signal, config2);
105784
+ await convertSdrToHdr(entry.videoPath, convertedPath, targetTransfer, signal, config2);
105760
105785
  entry.videoPath = convertedPath;
105761
105786
  } catch (err) {
105762
105787
  errors.push({
@@ -106061,12 +106086,12 @@ async function queryElementStacking(page, nativeHdrIds) {
106061
106086
  function resolveRadius(value, el) {
106062
106087
  if (value.includes("%")) {
106063
106088
  const pct = parseFloat(value) / 100;
106064
- const htmlEl = el;
106065
- const w = htmlEl.offsetWidth || 0;
106066
- const h = htmlEl.offsetHeight || 0;
106089
+ const w = el instanceof HTMLElement ? el.offsetWidth : 0;
106090
+ const h = el instanceof HTMLElement ? el.offsetHeight : 0;
106067
106091
  return pct * Math.min(w, h);
106068
106092
  }
106069
- return parseFloat(value) || 0;
106093
+ const parsed = parseFloat(value);
106094
+ return Number.isNaN(parsed) ? 0 : parsed;
106070
106095
  }
106071
106096
  const selfCs = window.getComputedStyle(node);
106072
106097
  const selfRadii = [
@@ -106150,8 +106175,7 @@ async function queryElementStacking(page, nativeHdrIds) {
106150
106175
  const style = window.getComputedStyle(el);
106151
106176
  const zIndex = getEffectiveZIndex(el);
106152
106177
  const isHdrEl = hdrSet.has(id);
106153
- const opacityStartNode = isHdrEl ? el.parentElement : el;
106154
- const opacity = opacityStartNode ? getEffectiveOpacity(opacityStartNode) : 1;
106178
+ const opacity = getEffectiveOpacity(el);
106155
106179
  const visible = style.visibility !== "hidden" && style.display !== "none" && rect.width > 0 && rect.height > 0;
106156
106180
  const htmlEl = el instanceof HTMLElement ? el : null;
106157
106181
  results.push({
@@ -107797,14 +107821,14 @@ var ridgedBurn = (from2, to, out, w, h, p) => {
107797
107821
  TRANSITIONS["ridged-burn"] = ridgedBurn;
107798
107822
 
107799
107823
  // src/services/renderOrchestrator.ts
107800
- import { join as join15, dirname as dirname10, resolve as resolve10 } from "path";
107824
+ import { join as join15, dirname as dirname10, resolve as resolve11 } from "path";
107801
107825
  import { randomUUID } from "crypto";
107802
107826
  import { freemem as freemem2 } from "os";
107803
107827
  import { fileURLToPath as fileURLToPath3 } from "url";
107804
107828
 
107805
107829
  // src/services/fileServer.ts
107806
- import { readFileSync as readFileSync7, existsSync as existsSync12, statSync as statSync5 } from "node:fs";
107807
- import { join as join11, extname as extname4 } from "node:path";
107830
+ import { readFileSync as readFileSync7, existsSync as existsSync12, realpathSync, statSync as statSync5 } from "node:fs";
107831
+ import { join as join11, extname as extname4, resolve as resolve8, sep } from "node:path";
107808
107832
 
107809
107833
  // src/services/hyperframeRuntimeLoader.ts
107810
107834
  import { createHash as createHash2 } from "node:crypto";
@@ -107880,6 +107904,18 @@ function resolveVerifiedHyperframeRuntime() {
107880
107904
  }
107881
107905
 
107882
107906
  // src/services/fileServer.ts
107907
+ function isPathInside(child, parent, options = {}) {
107908
+ const { resolveSymlinks = false, pathModule } = options;
107909
+ const resolveFn = pathModule?.resolve ?? resolve8;
107910
+ const separator = pathModule?.sep ?? sep;
107911
+ const resolvedChild = resolveFn(child);
107912
+ const resolvedParent = resolveFn(parent);
107913
+ const normalizedChild = resolveSymlinks && existsSync12(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
107914
+ const normalizedParent = resolveSymlinks && existsSync12(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
107915
+ if (normalizedChild === normalizedParent) return true;
107916
+ const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
107917
+ return normalizedChild.startsWith(parentWithSep);
107918
+ }
107883
107919
  var MIME_TYPES = {
107884
107920
  ".html": "text/html; charset=utf-8",
107885
107921
  ".css": "text/css; charset=utf-8",
@@ -108272,12 +108308,20 @@ function createFileServer2(options) {
108272
108308
  let requestPath = c.req.path;
108273
108309
  if (requestPath === "/") requestPath = "/index.html";
108274
108310
  const relativePath = requestPath.replace(/^\//, "");
108275
- const compiledPath = compiledDir ? join11(compiledDir, relativePath) : null;
108276
- const hasCompiledFile = Boolean(
108277
- compiledPath && existsSync12(compiledPath) && statSync5(compiledPath).isFile()
108278
- );
108279
- const filePath = hasCompiledFile ? compiledPath : join11(projectDir, relativePath);
108280
- if (!existsSync12(filePath) || !statSync5(filePath).isFile()) {
108311
+ let filePath = null;
108312
+ if (compiledDir) {
108313
+ const candidate = join11(compiledDir, relativePath);
108314
+ if (existsSync12(candidate) && isPathInside(candidate, compiledDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108315
+ filePath = candidate;
108316
+ }
108317
+ }
108318
+ if (!filePath) {
108319
+ const candidate = join11(projectDir, relativePath);
108320
+ if (existsSync12(candidate) && isPathInside(candidate, projectDir, { resolveSymlinks: true }) && statSync5(candidate).isFile()) {
108321
+ filePath = candidate;
108322
+ }
108323
+ }
108324
+ if (!filePath) {
108281
108325
  if (!/favicon\.ico$/i.test(requestPath)) {
108282
108326
  console.warn(`[FileServer] 404 Not Found: ${requestPath}`);
108283
108327
  }
@@ -108301,10 +108345,10 @@ function createFileServer2(options) {
108301
108345
  headers: { "Content-Type": contentType }
108302
108346
  });
108303
108347
  });
108304
- return new Promise((resolve13) => {
108348
+ return new Promise((resolve14) => {
108305
108349
  const connections = /* @__PURE__ */ new Set();
108306
108350
  const server = serve({ fetch: app.fetch, port }, (info) => {
108307
- resolve13({
108351
+ resolve14({
108308
108352
  url: `http://localhost:${info.port}`,
108309
108353
  port: info.port,
108310
108354
  close: () => {
@@ -108323,15 +108367,15 @@ function createFileServer2(options) {
108323
108367
 
108324
108368
  // src/services/htmlCompiler.ts
108325
108369
  import { readFileSync as readFileSync9, existsSync as existsSync14, mkdirSync as mkdirSync9 } from "fs";
108326
- import { join as join14, dirname as dirname9, resolve as resolve9 } from "path";
108370
+ import { join as join14, dirname as dirname9, resolve as resolve10 } from "path";
108327
108371
  import postcss from "postcss";
108328
108372
 
108329
108373
  // src/utils/paths.ts
108330
- import { resolve as resolve8, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
108331
- var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve8(new URL(import.meta.url).pathname, "../../..", "renders");
108332
- function isPathInside(childPath, parentPath) {
108333
- const absChild = resolve8(childPath);
108334
- const absParent = resolve8(parentPath);
108374
+ import { resolve as resolve9, basename as basename2, join as join12, relative as relative2, isAbsolute as isAbsolute2 } from "node:path";
108375
+ var DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve9(new URL(import.meta.url).pathname, "../../..", "renders");
108376
+ function isPathInside2(childPath, parentPath) {
108377
+ const absChild = resolve9(childPath);
108378
+ const absParent = resolve9(parentPath);
108335
108379
  if (absChild === absParent) return true;
108336
108380
  const rel = relative2(absParent, absChild);
108337
108381
  return rel !== "" && !rel.startsWith("..") && !isAbsolute2(rel);
@@ -108347,10 +108391,10 @@ function toExternalAssetKey(absPath) {
108347
108391
  return "hf-ext/" + normalised;
108348
108392
  }
108349
108393
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
108350
- const absoluteProjectDir = resolve8(projectDir);
108394
+ const absoluteProjectDir = resolve9(projectDir);
108351
108395
  const projectName = basename2(absoluteProjectDir);
108352
108396
  const resolvedOutputPath = outputPath ?? join12(rendersDir, `${projectName}.mp4`);
108353
- const absoluteOutputPath = resolve8(resolvedOutputPath);
108397
+ const absoluteOutputPath = resolve9(resolvedOutputPath);
108354
108398
  return { absoluteProjectDir, absoluteOutputPath };
108355
108399
  }
108356
108400
 
@@ -108859,7 +108903,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
108859
108903
  const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
108860
108904
  const absoluteStart = parentOffset + elStart;
108861
108905
  const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
108862
- const filePath = resolve9(projectDir, srcPath);
108906
+ const filePath = resolve10(projectDir, srcPath);
108863
108907
  if (visited.has(filePath)) {
108864
108908
  continue;
108865
108909
  }
@@ -109072,7 +109116,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
109072
109116
  if (!srcPath) continue;
109073
109117
  let compHtml = subCompositions.get(srcPath) || null;
109074
109118
  if (!compHtml) {
109075
- const filePath = resolve9(projectDir, srcPath);
109119
+ const filePath = resolve10(projectDir, srcPath);
109076
109120
  if (existsSync14(filePath)) {
109077
109121
  compHtml = readFileSync9(filePath, "utf-8");
109078
109122
  }
@@ -109289,7 +109333,7 @@ ${safeText}
109289
109333
  return wrappedFragment ? document2.body.innerHTML || "" : document2.toString();
109290
109334
  }
109291
109335
  function collectExternalAssets(html, projectDir) {
109292
- const absProjectDir = resolve9(projectDir);
109336
+ const absProjectDir = resolve10(projectDir);
109293
109337
  const externalAssets = /* @__PURE__ */ new Map();
109294
109338
  const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
109295
109339
  function processPath(rawPath) {
@@ -109297,8 +109341,8 @@ function collectExternalAssets(html, projectDir) {
109297
109341
  if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
109298
109342
  return null;
109299
109343
  }
109300
- const absPath = resolve9(absProjectDir, trimmed);
109301
- if (isPathInside(absPath, absProjectDir)) {
109344
+ const absPath = resolve10(absProjectDir, trimmed);
109345
+ if (isPathInside2(absPath, absProjectDir)) {
109302
109346
  return null;
109303
109347
  }
109304
109348
  if (!existsSync14(absPath)) return null;
@@ -109378,7 +109422,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
109378
109422
  const images = dedupeElementsById([...mainImages, ...subImages]);
109379
109423
  for (const video of videos) {
109380
109424
  if (isHttpUrl(video.src)) continue;
109381
- const videoPath = resolve9(projectDir, video.src);
109425
+ const videoPath = resolve10(projectDir, video.src);
109382
109426
  const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
109383
109427
  Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
109384
109428
  if (analysis.isProblematic) {
@@ -109639,8 +109683,8 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
109639
109683
  writeFileSync4(outPath, html, "utf-8");
109640
109684
  }
109641
109685
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
109642
- const outPath = resolve10(join15(compileDir, relativePath));
109643
- if (!isPathInside(outPath, compileDir)) {
109686
+ const outPath = resolve11(join15(compileDir, relativePath));
109687
+ if (!isPathInside2(outPath, compileDir)) {
109644
109688
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
109645
109689
  continue;
109646
109690
  }
@@ -109827,7 +109871,7 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
109827
109871
  }
109828
109872
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
109829
109873
  const moduleDir = dirname10(fileURLToPath3(import.meta.url));
109830
- const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve10(process.env.PRODUCER_RENDERS_DIR, "..") : resolve10(moduleDir, "../..");
109874
+ const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve11(process.env.PRODUCER_RENDERS_DIR, "..") : resolve11(moduleDir, "../..");
109831
109875
  const debugDir = join15(producerRoot, ".debug");
109832
109876
  const workDir = job.config.debug ? join15(debugDir, job.id) : join15(dirname10(outputPath), `work-${job.id}`);
109833
109877
  const pipelineStart = Date.now();
@@ -110271,6 +110315,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110271
110315
  const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
110272
110316
  const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
110273
110317
  const preset = getEncoderPreset(job.config.quality, outputFormat, encoderHdr);
110318
+ if (job.config.crf != null && job.config.videoBitrate) {
110319
+ log.warn(
110320
+ `[Render] Both crf=${job.config.crf} and videoBitrate=${job.config.videoBitrate} were set. These are mutually exclusive; honoring crf and ignoring videoBitrate. Set only one to silence this warning.`
110321
+ );
110322
+ }
110323
+ const effectiveQuality = job.config.crf ?? preset.quality;
110324
+ const effectiveBitrate = job.config.crf != null ? void 0 : job.config.videoBitrate;
110274
110325
  job.framesRendered = 0;
110275
110326
  if (hasHdrContent) {
110276
110327
  log.info("[Render] HDR layered composite: z-ordered DOM + native HLG video layers");
@@ -110294,411 +110345,251 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110294
110345
  createVideoFrameInjector(frameLookup),
110295
110346
  cfg
110296
110347
  );
110297
- await initializeSession(domSession);
110298
- assertNotAborted();
110299
- lastBrowserConsole = domSession.browserConsoleBuffer;
110300
- await initTransparentBackground(domSession.page);
110301
- const transitionMeta = await domSession.page.evaluate(() => {
110302
- return window.__hf?.transitions ?? [];
110303
- });
110304
- const sceneElements = await domSession.page.evaluate(() => {
110305
- const scenes = document.querySelectorAll(".scene");
110306
- const map2 = {};
110307
- for (const scene of scenes) {
110308
- const els = scene.querySelectorAll("[data-start]");
110309
- map2[scene.id] = Array.from(els).map((e) => e.id);
110310
- }
110311
- return map2;
110312
- });
110313
- const transitionRanges = transitionMeta.map((t) => ({
110314
- ...t,
110315
- startFrame: Math.floor(t.time * job.config.fps),
110316
- endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110317
- }));
110318
- if (transitionRanges.length > 0) {
110319
- log.info("[Render] Detected shader transitions for HDR compositing", {
110320
- count: transitionRanges.length,
110321
- transitions: transitionRanges.map((t) => ({
110322
- shader: t.shader,
110323
- from: t.fromScene,
110324
- to: t.toScene,
110325
- frames: `${t.startFrame}-${t.endFrame}`
110326
- }))
110327
- });
110328
- }
110329
- const hdrEncoder = await spawnStreamingEncoder(
110330
- videoOnlyPath,
110331
- {
110332
- fps: job.config.fps,
110333
- width,
110334
- height,
110335
- codec: preset.codec,
110336
- preset: preset.preset,
110337
- quality: preset.quality,
110338
- pixelFormat: preset.pixelFormat,
110339
- hdr: preset.hdr,
110340
- rawInputFormat: "rgb48le"
110341
- },
110342
- abortSignal,
110343
- { ffmpegStreamingTimeout: 36e5 }
110344
- );
110345
- assertNotAborted();
110346
- const hdrExtractionDims = /* @__PURE__ */ new Map();
110347
- const hdrImageFitInfo = /* @__PURE__ */ new Map();
110348
- const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110349
- for (const v of composition.videos) {
110350
- if (hdrVideoIds.includes(v.id)) {
110351
- hdrVideoStartTimes.set(v.id, v.start);
110352
- }
110353
- }
110354
- const hdrImageStartTimes = /* @__PURE__ */ new Map();
110355
- for (const img of composition.images) {
110356
- if (nativeHdrImageIds.has(img.id)) {
110357
- hdrImageStartTimes.set(img.id, img.start);
110358
- }
110359
- }
110360
- const uniqueStartTimes = [
110361
- .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110362
- ].sort((a, b) => a - b);
110363
- for (const seekTime of uniqueStartTimes) {
110364
- await domSession.page.evaluate((t) => {
110365
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110366
- }, seekTime);
110367
- if (domSession.onBeforeCapture) {
110368
- await domSession.onBeforeCapture(domSession.page, seekTime);
110369
- }
110370
- const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110371
- for (const el of stacking) {
110372
- if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110373
- hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110374
- }
110375
- if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110376
- hdrImageFitInfo.set(el.id, {
110377
- fit: el.objectFit,
110378
- position: el.objectPosition
110379
- });
110380
- }
110381
- }
110382
- }
110348
+ let hdrEncoder = null;
110349
+ let hdrEncoderClosed = false;
110350
+ let domSessionClosed = false;
110383
110351
  const hdrFrameDirs = /* @__PURE__ */ new Map();
110384
- for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110385
- const video = composition.videos.find((v) => v.id === videoId);
110386
- if (!video) continue;
110387
- const frameDir = join15(framesDir, `hdr_${videoId}`);
110388
- mkdirSync10(frameDir, { recursive: true });
110389
- const duration = video.end - video.start;
110390
- const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110391
- const ffmpegArgs = [
110392
- "-ss",
110393
- String(video.mediaStart),
110394
- "-i",
110395
- srcPath,
110396
- "-t",
110397
- String(duration),
110398
- "-r",
110399
- String(job.config.fps),
110400
- "-vf",
110401
- `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110402
- "-pix_fmt",
110403
- "rgb48le",
110404
- "-c:v",
110405
- "png",
110406
- "-y",
110407
- join15(frameDir, "frame_%04d.png")
110408
- ];
110409
- const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110410
- if (!result.success) {
110411
- hdrDiagnostics.videoExtractionFailures += 1;
110412
- log.error("HDR frame pre-extraction failed; aborting render", {
110413
- videoId,
110414
- srcPath,
110415
- stderr: result.stderr.slice(-400)
110352
+ try {
110353
+ await initializeSession(domSession);
110354
+ assertNotAborted();
110355
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110356
+ await initTransparentBackground(domSession.page);
110357
+ const transitionMeta = await domSession.page.evaluate(() => {
110358
+ return window.__hf?.transitions ?? [];
110359
+ });
110360
+ const sceneElements = await domSession.page.evaluate(() => {
110361
+ const scenes = document.querySelectorAll(".scene");
110362
+ const map2 = {};
110363
+ for (const scene of scenes) {
110364
+ const els = scene.querySelectorAll("[data-start]");
110365
+ map2[scene.id] = Array.from(els).map((e) => e.id);
110366
+ }
110367
+ return map2;
110368
+ });
110369
+ const transitionRanges = transitionMeta.map((t) => ({
110370
+ ...t,
110371
+ startFrame: Math.floor(t.time * job.config.fps),
110372
+ endFrame: Math.ceil((t.time + t.duration) * job.config.fps)
110373
+ }));
110374
+ if (transitionRanges.length > 0) {
110375
+ log.info("[Render] Detected shader transitions for HDR compositing", {
110376
+ count: transitionRanges.length,
110377
+ transitions: transitionRanges.map((t) => ({
110378
+ shader: t.shader,
110379
+ from: t.fromScene,
110380
+ to: t.toScene,
110381
+ frames: `${t.startFrame}-${t.endFrame}`
110382
+ }))
110416
110383
  });
110417
- throw new Error(
110418
- `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110419
- );
110420
110384
  }
110421
- hdrFrameDirs.set(videoId, frameDir);
110422
- }
110423
- const hdrImageBuffers = /* @__PURE__ */ new Map();
110424
- for (const [imageId, srcPath] of hdrImageSrcPaths) {
110425
- try {
110426
- const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110427
- const layout2 = hdrExtractionDims.get(imageId);
110428
- const fitInfo = hdrImageFitInfo.get(imageId);
110429
- if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110430
- const fit = normalizeObjectFit(fitInfo?.fit);
110431
- const resampled = resampleRgb48leObjectFit(
110432
- decoded.data,
110433
- decoded.width,
110434
- decoded.height,
110435
- layout2.width,
110436
- layout2.height,
110437
- fit,
110438
- fitInfo?.position
110439
- );
110440
- hdrImageBuffers.set(imageId, {
110441
- data: resampled,
110442
- width: layout2.width,
110443
- height: layout2.height
110444
- });
110445
- } else {
110446
- hdrImageBuffers.set(imageId, {
110447
- data: Buffer.from(decoded.data),
110448
- width: decoded.width,
110449
- height: decoded.height
110450
- });
110385
+ hdrEncoder = await spawnStreamingEncoder(
110386
+ videoOnlyPath,
110387
+ {
110388
+ fps: job.config.fps,
110389
+ width,
110390
+ height,
110391
+ codec: preset.codec,
110392
+ preset: preset.preset,
110393
+ quality: effectiveQuality,
110394
+ bitrate: effectiveBitrate,
110395
+ pixelFormat: preset.pixelFormat,
110396
+ hdr: preset.hdr,
110397
+ rawInputFormat: "rgb48le"
110398
+ },
110399
+ abortSignal,
110400
+ { ffmpegStreamingTimeout: 36e5 }
110401
+ );
110402
+ assertNotAborted();
110403
+ const hdrExtractionDims = /* @__PURE__ */ new Map();
110404
+ const hdrImageFitInfo = /* @__PURE__ */ new Map();
110405
+ const hdrVideoStartTimes = /* @__PURE__ */ new Map();
110406
+ for (const v of composition.videos) {
110407
+ if (hdrVideoIds.includes(v.id)) {
110408
+ hdrVideoStartTimes.set(v.id, v.start);
110451
110409
  }
110452
- } catch (err) {
110453
- hdrDiagnostics.imageDecodeFailures += 1;
110454
- log.error("HDR image decode failed; aborting render", {
110455
- imageId,
110456
- srcPath,
110457
- error: err instanceof Error ? err.message : String(err)
110458
- });
110459
- throw new Error(
110460
- `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110461
- );
110462
110410
  }
110463
- }
110464
- assertNotAborted();
110465
- try {
110466
- let countNonZeroAlpha2 = function(rgba) {
110467
- let n = 0;
110468
- for (let p = 3; p < rgba.length; p += 4) {
110469
- if (rgba[p] !== 0) n++;
110411
+ const hdrImageStartTimes = /* @__PURE__ */ new Map();
110412
+ for (const img of composition.images) {
110413
+ if (nativeHdrImageIds.has(img.id)) {
110414
+ hdrImageStartTimes.set(img.id, img.start);
110470
110415
  }
110471
- return n;
110472
- }, countNonZeroRgb482 = function(buf) {
110473
- let n = 0;
110474
- for (let p = 0; p < buf.length; p += 6) {
110475
- if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0) n++;
110416
+ }
110417
+ const uniqueStartTimes = [
110418
+ .../* @__PURE__ */ new Set([...hdrVideoStartTimes.values(), ...hdrImageStartTimes.values()])
110419
+ ].sort((a, b) => a - b);
110420
+ for (const seekTime of uniqueStartTimes) {
110421
+ await domSession.page.evaluate((t) => {
110422
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110423
+ }, seekTime);
110424
+ if (domSession.onBeforeCapture) {
110425
+ await domSession.onBeforeCapture(domSession.page, seekTime);
110426
+ }
110427
+ const stacking = await queryElementStacking(domSession.page, nativeHdrIds);
110428
+ for (const el of stacking) {
110429
+ if (el.isHdr && el.layoutWidth > 0 && el.layoutHeight > 0 && !hdrExtractionDims.has(el.id)) {
110430
+ hdrExtractionDims.set(el.id, { width: el.layoutWidth, height: el.layoutHeight });
110431
+ }
110432
+ if (el.isHdr && nativeHdrImageIds.has(el.id) && !hdrImageFitInfo.has(el.id)) {
110433
+ hdrImageFitInfo.set(el.id, {
110434
+ fit: el.objectFit,
110435
+ position: el.objectPosition
110436
+ });
110437
+ }
110476
110438
  }
110477
- return n;
110478
- };
110479
- var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
110480
- const beforeCaptureHook = domSession.onBeforeCapture;
110481
- const cleanedUpVideos = /* @__PURE__ */ new Set();
110482
- const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110483
- for (const v of composition.videos) {
110484
- if (hdrFrameDirs.has(v.id)) {
110485
- hdrVideoEndTimes.set(v.id, v.end);
110486
- }
110487
- }
110488
- const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110489
- const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110490
- if (debugDumpDir && !existsSync15(debugDumpDir)) {
110491
- mkdirSync10(debugDumpDir, { recursive: true });
110492
- }
110493
- async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
110494
- const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
110495
- const layers = groupIntoLayers(filteredStacking);
110496
- const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
110497
- if (shouldLog) {
110498
- log.info("[diag] compositeToBuffer plan", {
110499
- frame: debugFrameIndex,
110500
- time: time.toFixed(3),
110501
- filterSize: elementFilter?.size,
110502
- fullStackingCount: fullStacking.length,
110503
- filteredCount: filteredStacking.length,
110504
- layerCount: layers.length,
110505
- layers: layers.map(
110506
- (l) => l.type === "hdr" ? {
110507
- type: "hdr",
110508
- id: l.element.id,
110509
- z: l.element.zIndex,
110510
- visible: l.element.visible,
110511
- opacity: l.element.opacity,
110512
- bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
110513
- } : { type: "dom", ids: l.elementIds }
110514
- )
110439
+ }
110440
+ for (const [videoId, srcPath] of hdrVideoSrcPaths) {
110441
+ const video = composition.videos.find((v) => v.id === videoId);
110442
+ if (!video) continue;
110443
+ const frameDir = join15(framesDir, `hdr_${videoId}`);
110444
+ mkdirSync10(frameDir, { recursive: true });
110445
+ const duration = video.end - video.start;
110446
+ const dims = hdrExtractionDims.get(videoId) ?? { width, height };
110447
+ const ffmpegArgs = [
110448
+ "-ss",
110449
+ String(video.mediaStart),
110450
+ "-i",
110451
+ srcPath,
110452
+ "-t",
110453
+ String(duration),
110454
+ "-r",
110455
+ String(job.config.fps),
110456
+ "-vf",
110457
+ `scale=${dims.width}:${dims.height}:force_original_aspect_ratio=increase,crop=${dims.width}:${dims.height}`,
110458
+ "-pix_fmt",
110459
+ "rgb48le",
110460
+ "-c:v",
110461
+ "png",
110462
+ "-y",
110463
+ join15(frameDir, "frame_%04d.png")
110464
+ ];
110465
+ const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
110466
+ if (!result.success) {
110467
+ hdrDiagnostics.videoExtractionFailures += 1;
110468
+ log.error("HDR frame pre-extraction failed; aborting render", {
110469
+ videoId,
110470
+ srcPath,
110471
+ stderr: result.stderr.slice(-400)
110515
110472
  });
110473
+ throw new Error(
110474
+ `HDR frame extraction failed for video "${videoId}". Aborting render to avoid shipping black HDR layers.`
110475
+ );
110516
110476
  }
110517
- for (const [layerIdx, layer] of layers.entries()) {
110518
- if (layer.type === "hdr") {
110519
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110520
- const isHdrImage = nativeHdrImageIds.has(layer.element.id);
110521
- if (isHdrImage) {
110522
- blitHdrImageLayer(
110523
- canvas,
110524
- layer.element,
110525
- hdrImageBuffers,
110526
- width,
110527
- height,
110528
- log,
110529
- imageTransfers.get(layer.element.id),
110530
- effectiveHdr?.transfer
110531
- );
110532
- } else {
110533
- blitHdrVideoLayer(
110534
- canvas,
110535
- layer.element,
110536
- time,
110537
- job.config.fps,
110538
- hdrFrameDirs,
110539
- hdrVideoStartTimes,
110540
- width,
110541
- height,
110542
- log,
110543
- videoTransfers.get(layer.element.id),
110544
- effectiveHdr?.transfer
110545
- );
110546
- }
110547
- if (shouldLog) {
110548
- const after2 = countNonZeroRgb482(canvas);
110549
- if (isHdrImage) {
110550
- const buf = hdrImageBuffers.get(layer.element.id);
110551
- log.info("[diag] hdr layer blit", {
110552
- frame: debugFrameIndex,
110553
- layerIdx,
110554
- id: layer.element.id,
110555
- kind: "image",
110556
- pixelsAdded: after2 - before2,
110557
- totalNonZero: after2,
110558
- bufferDecoded: !!buf,
110559
- bufferDims: buf ? `${buf.width}x${buf.height}` : null
110560
- });
110561
- } else {
110562
- const frameDir = hdrFrameDirs.get(layer.element.id);
110563
- const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110564
- const localTime = time - startTime;
110565
- const frameNum = Math.floor(localTime * job.config.fps) + 1;
110566
- const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110567
- log.info("[diag] hdr layer blit", {
110568
- frame: debugFrameIndex,
110569
- layerIdx,
110570
- id: layer.element.id,
110571
- kind: "video",
110572
- pixelsAdded: after2 - before2,
110573
- totalNonZero: after2,
110574
- startTime,
110575
- localTime: localTime.toFixed(3),
110576
- hdrFrameNum: frameNum,
110577
- expectedFrame,
110578
- expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110579
- });
110580
- }
110581
- }
110477
+ hdrFrameDirs.set(videoId, frameDir);
110478
+ }
110479
+ const hdrImageBuffers = /* @__PURE__ */ new Map();
110480
+ for (const [imageId, srcPath] of hdrImageSrcPaths) {
110481
+ try {
110482
+ const decoded = decodePngToRgb48le(readFileSync10(srcPath));
110483
+ const layout2 = hdrExtractionDims.get(imageId);
110484
+ const fitInfo = hdrImageFitInfo.get(imageId);
110485
+ if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
110486
+ const fit = normalizeObjectFit(fitInfo?.fit);
110487
+ const resampled = resampleRgb48leObjectFit(
110488
+ decoded.data,
110489
+ decoded.width,
110490
+ decoded.height,
110491
+ layout2.width,
110492
+ layout2.height,
110493
+ fit,
110494
+ fitInfo?.position
110495
+ );
110496
+ hdrImageBuffers.set(imageId, {
110497
+ data: resampled,
110498
+ width: layout2.width,
110499
+ height: layout2.height
110500
+ });
110582
110501
  } else {
110583
- const allElementIds = fullStacking.map((e) => e.id);
110584
- const layerIds = new Set(layer.elementIds);
110585
- const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110586
- await domSession.page.evaluate((t) => {
110587
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110588
- }, time);
110589
- if (beforeCaptureHook) {
110590
- await beforeCaptureHook(domSession.page, time);
110591
- }
110592
- await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110593
- const domPng = await captureAlphaPng(domSession.page, width, height);
110594
- await removeDomLayerMask(domSession.page, hideIds);
110595
- try {
110596
- const { data: domRgba } = decodePng(domPng);
110597
- if (!effectiveHdr) {
110598
- throw new Error(
110599
- "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
110600
- );
110601
- }
110602
- const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110603
- const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
110604
- blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110605
- if (shouldLog && debugDumpDir) {
110606
- const after2 = countNonZeroRgb482(canvas);
110607
- const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110608
- const dumpPath = join15(debugDumpDir, dumpName);
110609
- writeFileSync4(dumpPath, domPng);
110610
- log.info("[diag] dom layer blit", {
110611
- frame: debugFrameIndex,
110612
- layerIdx,
110613
- layerIds: layer.elementIds,
110614
- hideCount: hideIds.length,
110615
- pngBytes: domPng.length,
110616
- alphaPixels,
110617
- pixelsAdded: after2 - before2,
110618
- totalNonZero: after2,
110619
- dumpPath
110620
- });
110621
- }
110622
- } catch (err) {
110623
- log.warn("DOM layer decode/blit failed; skipping overlay", {
110624
- layerIds: layer.elementIds,
110625
- error: err instanceof Error ? err.message : String(err)
110626
- });
110627
- }
110502
+ hdrImageBuffers.set(imageId, {
110503
+ data: Buffer.from(decoded.data),
110504
+ width: decoded.width,
110505
+ height: decoded.height
110506
+ });
110628
110507
  }
110629
- }
110630
- if (shouldLog && debugDumpDir) {
110631
- const finalNonZero = countNonZeroRgb482(canvas);
110632
- log.info("[diag] compositeToBuffer end", {
110633
- frame: debugFrameIndex,
110634
- finalNonZeroPixels: finalNonZero,
110635
- totalPixels: width * height,
110636
- coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110508
+ } catch (err) {
110509
+ hdrDiagnostics.imageDecodeFailures += 1;
110510
+ log.error("HDR image decode failed; aborting render", {
110511
+ imageId,
110512
+ srcPath,
110513
+ error: err instanceof Error ? err.message : String(err)
110637
110514
  });
110515
+ throw new Error(
110516
+ `HDR image decode failed for image "${imageId}". Aborting render to avoid shipping missing HDR image layers.`
110517
+ );
110638
110518
  }
110639
110519
  }
110640
- const bufSize = width * height * 6;
110641
- const hasTransitions = transitionRanges.length > 0;
110642
- const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110643
- const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110644
- const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110645
- const normalCanvas = Buffer.alloc(bufSize);
110646
- for (let i = 0; i < totalFrames; i++) {
110647
- assertNotAborted();
110648
- const time = i / job.config.fps;
110649
- await domSession.page.evaluate((t) => {
110650
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110651
- }, time);
110652
- if (beforeCaptureHook) {
110653
- await beforeCaptureHook(domSession.page, time);
110654
- }
110655
- const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110656
- const activeTransition = transitionRanges.find(
110657
- (t) => i >= t.startFrame && i <= t.endFrame
110658
- );
110659
- if (i % 30 === 0) {
110660
- const hdrEl = stackingInfo.find((e) => e.isHdr);
110661
- log.debug("[Render] HDR layer composite frame", {
110662
- frame: i,
110663
- time: time.toFixed(2),
110664
- hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110665
- stackingCount: stackingInfo.length,
110666
- activeTransition: activeTransition?.shader
110667
- });
110668
- }
110669
- if (activeTransition && transBufferA && transBufferB && transOutput) {
110670
- const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110671
- const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110672
- const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110673
- transBufferA.fill(0);
110674
- transBufferB.fill(0);
110675
- for (const [sceneBuf, sceneIds] of [
110676
- [transBufferA, sceneAIds],
110677
- [transBufferB, sceneBIds]
110678
- ]) {
110679
- await domSession.page.evaluate((t) => {
110680
- if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110681
- }, time);
110682
- if (beforeCaptureHook) {
110683
- await beforeCaptureHook(domSession.page, time);
110684
- }
110685
- for (const el of stackingInfo) {
110686
- if (!el.isHdr || !sceneIds.has(el.id)) continue;
110687
- if (nativeHdrImageIds.has(el.id)) {
110520
+ assertNotAborted();
110521
+ try {
110522
+ let countNonZeroAlpha2 = function(rgba) {
110523
+ let n = 0;
110524
+ for (let p = 3; p < rgba.length; p += 4) {
110525
+ if (rgba[p] !== 0) n++;
110526
+ }
110527
+ return n;
110528
+ }, countNonZeroRgb482 = function(buf) {
110529
+ let n = 0;
110530
+ for (let p = 0; p < buf.length; p += 6) {
110531
+ if (buf[p] !== 0 || buf[p + 1] !== 0 || buf[p + 2] !== 0 || buf[p + 3] !== 0 || buf[p + 4] !== 0 || buf[p + 5] !== 0)
110532
+ n++;
110533
+ }
110534
+ return n;
110535
+ };
110536
+ var countNonZeroAlpha = countNonZeroAlpha2, countNonZeroRgb48 = countNonZeroRgb482;
110537
+ const beforeCaptureHook = domSession.onBeforeCapture;
110538
+ const cleanedUpVideos = /* @__PURE__ */ new Set();
110539
+ const hdrVideoEndTimes = /* @__PURE__ */ new Map();
110540
+ for (const v of composition.videos) {
110541
+ if (hdrFrameDirs.has(v.id)) {
110542
+ hdrVideoEndTimes.set(v.id, v.end);
110543
+ }
110544
+ }
110545
+ const debugDumpEnabled = process.env.KEEP_TEMP === "1";
110546
+ const debugDumpDir = debugDumpEnabled ? join15(framesDir, "debug-composite") : null;
110547
+ if (debugDumpDir && !existsSync15(debugDumpDir)) {
110548
+ mkdirSync10(debugDumpDir, { recursive: true });
110549
+ }
110550
+ async function compositeToBuffer(canvas, time, fullStacking, elementFilter, debugFrameIndex = -1) {
110551
+ const filteredStacking = elementFilter ? fullStacking.filter((e) => elementFilter.has(e.id)) : fullStacking;
110552
+ const layers = groupIntoLayers(filteredStacking);
110553
+ const shouldLog = debugDumpEnabled && debugFrameIndex >= 0;
110554
+ if (shouldLog) {
110555
+ log.info("[diag] compositeToBuffer plan", {
110556
+ frame: debugFrameIndex,
110557
+ time: time.toFixed(3),
110558
+ filterSize: elementFilter?.size,
110559
+ fullStackingCount: fullStacking.length,
110560
+ filteredCount: filteredStacking.length,
110561
+ layerCount: layers.length,
110562
+ layers: layers.map(
110563
+ (l) => l.type === "hdr" ? {
110564
+ type: "hdr",
110565
+ id: l.element.id,
110566
+ z: l.element.zIndex,
110567
+ visible: l.element.visible,
110568
+ opacity: l.element.opacity,
110569
+ bounds: `${Math.round(l.element.x)},${Math.round(l.element.y)} ${Math.round(l.element.width)}x${Math.round(l.element.height)}`
110570
+ } : { type: "dom", ids: l.elementIds }
110571
+ )
110572
+ });
110573
+ }
110574
+ for (const [layerIdx, layer] of layers.entries()) {
110575
+ if (layer.type === "hdr") {
110576
+ const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110577
+ const isHdrImage = nativeHdrImageIds.has(layer.element.id);
110578
+ if (isHdrImage) {
110688
110579
  blitHdrImageLayer(
110689
- sceneBuf,
110690
- el,
110580
+ canvas,
110581
+ layer.element,
110691
110582
  hdrImageBuffers,
110692
110583
  width,
110693
110584
  height,
110694
110585
  log,
110695
- imageTransfers.get(el.id),
110586
+ imageTransfers.get(layer.element.id),
110696
110587
  effectiveHdr?.transfer
110697
110588
  );
110698
110589
  } else {
110699
110590
  blitHdrVideoLayer(
110700
- sceneBuf,
110701
- el,
110591
+ canvas,
110592
+ layer.element,
110702
110593
  time,
110703
110594
  job.config.fps,
110704
110595
  hdrFrameDirs,
@@ -110706,100 +110597,294 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110706
110597
  width,
110707
110598
  height,
110708
110599
  log,
110709
- videoTransfers.get(el.id),
110600
+ videoTransfers.get(layer.element.id),
110710
110601
  effectiveHdr?.transfer
110711
110602
  );
110712
110603
  }
110604
+ if (shouldLog) {
110605
+ const after2 = countNonZeroRgb482(canvas);
110606
+ if (isHdrImage) {
110607
+ const buf = hdrImageBuffers.get(layer.element.id);
110608
+ log.info("[diag] hdr layer blit", {
110609
+ frame: debugFrameIndex,
110610
+ layerIdx,
110611
+ id: layer.element.id,
110612
+ kind: "image",
110613
+ pixelsAdded: after2 - before2,
110614
+ totalNonZero: after2,
110615
+ bufferDecoded: !!buf,
110616
+ bufferDims: buf ? `${buf.width}x${buf.height}` : null
110617
+ });
110618
+ } else {
110619
+ const frameDir = hdrFrameDirs.get(layer.element.id);
110620
+ const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
110621
+ const localTime = time - startTime;
110622
+ const frameNum = Math.floor(localTime * job.config.fps) + 1;
110623
+ const expectedFrame = frameDir ? join15(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
110624
+ log.info("[diag] hdr layer blit", {
110625
+ frame: debugFrameIndex,
110626
+ layerIdx,
110627
+ id: layer.element.id,
110628
+ kind: "video",
110629
+ pixelsAdded: after2 - before2,
110630
+ totalNonZero: after2,
110631
+ startTime,
110632
+ localTime: localTime.toFixed(3),
110633
+ hdrFrameNum: frameNum,
110634
+ expectedFrame,
110635
+ expectedFrameExists: expectedFrame ? existsSync15(expectedFrame) : false
110636
+ });
110637
+ }
110638
+ }
110639
+ } else {
110640
+ const allElementIds = fullStacking.map((e) => e.id);
110641
+ const layerIds = new Set(layer.elementIds);
110642
+ const hideIds = allElementIds.filter((id) => !layerIds.has(id));
110643
+ await domSession.page.evaluate((t) => {
110644
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110645
+ }, time);
110646
+ if (beforeCaptureHook) {
110647
+ await beforeCaptureHook(domSession.page, time);
110648
+ }
110649
+ await applyDomLayerMask(domSession.page, layer.elementIds, hideIds);
110650
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110651
+ await removeDomLayerMask(domSession.page, hideIds);
110652
+ try {
110653
+ const { data: domRgba } = decodePng(domPng);
110654
+ if (!effectiveHdr) {
110655
+ throw new Error(
110656
+ "Invariant violation: effectiveHdr is undefined inside HDR layer branch"
110657
+ );
110658
+ }
110659
+ const before2 = shouldLog ? countNonZeroRgb482(canvas) : 0;
110660
+ const alphaPixels = shouldLog ? countNonZeroAlpha2(domRgba) : 0;
110661
+ blitRgba8OverRgb48le(domRgba, canvas, width, height, effectiveHdr.transfer);
110662
+ if (shouldLog && debugDumpDir) {
110663
+ const after2 = countNonZeroRgb482(canvas);
110664
+ const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
110665
+ const dumpPath = join15(debugDumpDir, dumpName);
110666
+ writeFileSync4(dumpPath, domPng);
110667
+ log.info("[diag] dom layer blit", {
110668
+ frame: debugFrameIndex,
110669
+ layerIdx,
110670
+ layerIds: layer.elementIds,
110671
+ hideCount: hideIds.length,
110672
+ pngBytes: domPng.length,
110673
+ alphaPixels,
110674
+ pixelsAdded: after2 - before2,
110675
+ totalNonZero: after2,
110676
+ dumpPath
110677
+ });
110678
+ }
110679
+ } catch (err) {
110680
+ log.warn("DOM layer decode/blit failed; skipping overlay", {
110681
+ layerIds: layer.elementIds,
110682
+ error: err instanceof Error ? err.message : String(err)
110683
+ });
110684
+ }
110713
110685
  }
110714
- const showIds = Array.from(sceneIds);
110715
- const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110716
- await applyDomLayerMask(domSession.page, showIds, hideIds);
110717
- const domPng = await captureAlphaPng(domSession.page, width, height);
110718
- await removeDomLayerMask(domSession.page, hideIds);
110719
- try {
110720
- const { data: domRgba } = decodePng(domPng);
110721
- if (!effectiveHdr) {
110722
- throw new Error(
110723
- "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110686
+ }
110687
+ if (shouldLog && debugDumpDir) {
110688
+ const finalNonZero = countNonZeroRgb482(canvas);
110689
+ log.info("[diag] compositeToBuffer end", {
110690
+ frame: debugFrameIndex,
110691
+ finalNonZeroPixels: finalNonZero,
110692
+ totalPixels: width * height,
110693
+ coverage: (finalNonZero / (width * height) * 100).toFixed(1) + "%"
110694
+ });
110695
+ }
110696
+ }
110697
+ const bufSize = width * height * 6;
110698
+ const hasTransitions = transitionRanges.length > 0;
110699
+ const transBufferA = hasTransitions ? Buffer.alloc(bufSize) : null;
110700
+ const transBufferB = hasTransitions ? Buffer.alloc(bufSize) : null;
110701
+ const transOutput = hasTransitions ? Buffer.alloc(bufSize) : null;
110702
+ const normalCanvas = Buffer.alloc(bufSize);
110703
+ for (let i = 0; i < totalFrames; i++) {
110704
+ assertNotAborted();
110705
+ const time = i / job.config.fps;
110706
+ await domSession.page.evaluate((t) => {
110707
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110708
+ }, time);
110709
+ if (beforeCaptureHook) {
110710
+ await beforeCaptureHook(domSession.page, time);
110711
+ }
110712
+ const stackingInfo = await queryElementStacking(domSession.page, nativeHdrIds);
110713
+ const activeTransition = transitionRanges.find(
110714
+ (t) => i >= t.startFrame && i <= t.endFrame
110715
+ );
110716
+ if (i % 30 === 0) {
110717
+ const hdrEl = stackingInfo.find((e) => e.isHdr);
110718
+ log.debug("[Render] HDR layer composite frame", {
110719
+ frame: i,
110720
+ time: time.toFixed(2),
110721
+ hdrElement: hdrEl ? { z: hdrEl.zIndex, visible: hdrEl.visible, width: hdrEl.width } : null,
110722
+ stackingCount: stackingInfo.length,
110723
+ activeTransition: activeTransition?.shader
110724
+ });
110725
+ }
110726
+ if (activeTransition && transBufferA && transBufferB && transOutput) {
110727
+ const progress = activeTransition.endFrame === activeTransition.startFrame ? 1 : (i - activeTransition.startFrame) / (activeTransition.endFrame - activeTransition.startFrame);
110728
+ const sceneAIds = new Set(sceneElements[activeTransition.fromScene] ?? []);
110729
+ const sceneBIds = new Set(sceneElements[activeTransition.toScene] ?? []);
110730
+ transBufferA.fill(0);
110731
+ transBufferB.fill(0);
110732
+ for (const [sceneBuf, sceneIds] of [
110733
+ [transBufferA, sceneAIds],
110734
+ [transBufferB, sceneBIds]
110735
+ ]) {
110736
+ assertNotAborted();
110737
+ await domSession.page.evaluate((t) => {
110738
+ if (window.__hf && typeof window.__hf.seek === "function") window.__hf.seek(t);
110739
+ }, time);
110740
+ if (beforeCaptureHook) {
110741
+ await beforeCaptureHook(domSession.page, time);
110742
+ }
110743
+ for (const el of stackingInfo) {
110744
+ if (!el.isHdr || !sceneIds.has(el.id)) continue;
110745
+ if (nativeHdrImageIds.has(el.id)) {
110746
+ blitHdrImageLayer(
110747
+ sceneBuf,
110748
+ el,
110749
+ hdrImageBuffers,
110750
+ width,
110751
+ height,
110752
+ log,
110753
+ imageTransfers.get(el.id),
110754
+ effectiveHdr?.transfer
110755
+ );
110756
+ } else {
110757
+ blitHdrVideoLayer(
110758
+ sceneBuf,
110759
+ el,
110760
+ time,
110761
+ job.config.fps,
110762
+ hdrFrameDirs,
110763
+ hdrVideoStartTimes,
110764
+ width,
110765
+ height,
110766
+ log,
110767
+ videoTransfers.get(el.id),
110768
+ effectiveHdr?.transfer
110769
+ );
110770
+ }
110771
+ }
110772
+ const showIds = Array.from(sceneIds);
110773
+ const hideIds = stackingInfo.map((e) => e.id).filter((id) => !sceneIds.has(id) || nativeHdrIds.has(id));
110774
+ await applyDomLayerMask(domSession.page, showIds, hideIds);
110775
+ const domPng = await captureAlphaPng(domSession.page, width, height);
110776
+ await removeDomLayerMask(domSession.page, hideIds);
110777
+ try {
110778
+ const { data: domRgba } = decodePng(domPng);
110779
+ if (!effectiveHdr) {
110780
+ throw new Error(
110781
+ "Invariant violation: effectiveHdr is undefined inside hasHdrVideo branch"
110782
+ );
110783
+ }
110784
+ blitRgba8OverRgb48le(
110785
+ domRgba,
110786
+ sceneBuf,
110787
+ width,
110788
+ height,
110789
+ effectiveHdr.transfer
110724
110790
  );
110791
+ } catch (err) {
110792
+ log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110793
+ frameIndex: i,
110794
+ sceneIds: Array.from(sceneIds),
110795
+ error: err instanceof Error ? err.message : String(err)
110796
+ });
110725
110797
  }
110726
- blitRgba8OverRgb48le(
110727
- domRgba,
110728
- sceneBuf,
110729
- width,
110730
- height,
110731
- effectiveHdr.transfer
110798
+ }
110799
+ const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110800
+ transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110801
+ hdrEncoder.writeFrame(transOutput);
110802
+ } else {
110803
+ normalCanvas.fill(0);
110804
+ await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i);
110805
+ if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110806
+ const previewPath = join15(
110807
+ debugDumpDir,
110808
+ `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110732
110809
  );
110733
- } catch (err) {
110734
- log.warn("DOM layer decode/blit failed; skipping overlay for transition scene", {
110735
- frameIndex: i,
110736
- sceneIds: Array.from(sceneIds),
110737
- error: err instanceof Error ? err.message : String(err)
110738
- });
110810
+ writeFileSync4(previewPath, normalCanvas);
110739
110811
  }
110740
- }
110741
- const transitionFn = TRANSITIONS[activeTransition.shader] ?? crossfade;
110742
- transitionFn(transBufferA, transBufferB, transOutput, width, height, progress);
110743
- hdrEncoder.writeFrame(transOutput);
110744
- } else {
110745
- normalCanvas.fill(0);
110746
- await compositeToBuffer(normalCanvas, time, stackingInfo, void 0, i);
110747
- if (debugDumpEnabled && debugDumpDir && i % 30 === 0) {
110748
- const previewPath = join15(
110749
- debugDumpDir,
110750
- `frame_${String(i).padStart(4, "0")}_final_rgb48le.bin`
110751
- );
110752
- writeFileSync4(previewPath, normalCanvas);
110753
- }
110754
- hdrEncoder.writeFrame(normalCanvas);
110755
- }
110756
- if (process.env.KEEP_TEMP !== "1") {
110757
- for (const [videoId, endTime] of hdrVideoEndTimes) {
110758
- if (time > endTime && !cleanedUpVideos.has(videoId)) {
110759
- const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110760
- if (!stillNeeded) {
110761
- const frameDir = hdrFrameDirs.get(videoId);
110762
- if (frameDir) {
110763
- try {
110764
- rmSync3(frameDir, { recursive: true, force: true });
110765
- } catch (err) {
110766
- log.warn("Failed to clean up HDR frame directory", {
110767
- videoId,
110768
- frameDir,
110769
- error: err instanceof Error ? err.message : String(err)
110770
- });
110812
+ hdrEncoder.writeFrame(normalCanvas);
110813
+ }
110814
+ if (process.env.KEEP_TEMP !== "1") {
110815
+ for (const [videoId, endTime] of hdrVideoEndTimes) {
110816
+ if (time > endTime && !cleanedUpVideos.has(videoId)) {
110817
+ const stillNeeded = activeTransition && (sceneElements[activeTransition.fromScene]?.includes(videoId) || sceneElements[activeTransition.toScene]?.includes(videoId));
110818
+ if (!stillNeeded) {
110819
+ const frameDir = hdrFrameDirs.get(videoId);
110820
+ if (frameDir) {
110821
+ try {
110822
+ rmSync3(frameDir, { recursive: true, force: true });
110823
+ } catch (err) {
110824
+ log.warn("Failed to clean up HDR frame directory", {
110825
+ videoId,
110826
+ frameDir,
110827
+ error: err instanceof Error ? err.message : String(err)
110828
+ });
110829
+ }
110830
+ frameDirMaxIndexCache.delete(frameDir);
110831
+ hdrFrameDirs.delete(videoId);
110771
110832
  }
110833
+ cleanedUpVideos.add(videoId);
110772
110834
  }
110773
- cleanedUpVideos.add(videoId);
110774
110835
  }
110775
110836
  }
110776
110837
  }
110838
+ job.framesRendered = i + 1;
110839
+ if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110840
+ const frameProgress = (i + 1) / totalFrames;
110841
+ updateJobStatus(
110842
+ job,
110843
+ "rendering",
110844
+ `HDR composite frame ${i + 1}/${job.totalFrames}`,
110845
+ Math.round(25 + frameProgress * 55),
110846
+ onProgress
110847
+ );
110848
+ }
110777
110849
  }
110778
- job.framesRendered = i + 1;
110779
- if ((i + 1) % 10 === 0 || i + 1 === totalFrames) {
110780
- const frameProgress = (i + 1) / totalFrames;
110781
- updateJobStatus(
110782
- job,
110783
- "rendering",
110784
- `HDR composite frame ${i + 1}/${job.totalFrames}`,
110785
- Math.round(25 + frameProgress * 55),
110786
- onProgress
110787
- );
110788
- }
110850
+ } finally {
110851
+ lastBrowserConsole = domSession.browserConsoleBuffer;
110852
+ await closeCaptureSession(domSession);
110853
+ domSessionClosed = true;
110854
+ }
110855
+ const hdrEncodeResult = await hdrEncoder.close();
110856
+ hdrEncoderClosed = true;
110857
+ assertNotAborted();
110858
+ if (!hdrEncodeResult.success) {
110859
+ throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
110789
110860
  }
110861
+ perfStages.captureMs = Date.now() - stage4Start;
110862
+ perfStages.encodeMs = hdrEncodeResult.durationMs;
110790
110863
  } finally {
110791
- lastBrowserConsole = domSession.browserConsoleBuffer;
110792
- await closeCaptureSession(domSession);
110793
- }
110794
- const hdrEncodeResult = await hdrEncoder.close();
110795
- assertNotAborted();
110796
- if (!hdrEncodeResult.success) {
110797
- throw new Error(`HDR encode failed: ${hdrEncodeResult.error}`);
110864
+ if (hdrEncoder && !hdrEncoderClosed) {
110865
+ try {
110866
+ await hdrEncoder.close();
110867
+ } catch (err) {
110868
+ log.warn("hdrEncoder defensive close failed", {
110869
+ err: err instanceof Error ? err.message : String(err)
110870
+ });
110871
+ }
110872
+ }
110873
+ if (!domSessionClosed) {
110874
+ await closeCaptureSession(domSession).catch((err) => {
110875
+ log.warn("closeCaptureSession defensive close failed", {
110876
+ err: err instanceof Error ? err.message : String(err)
110877
+ });
110878
+ });
110879
+ }
110880
+ for (const frameDir of hdrFrameDirs.values()) {
110881
+ frameDirMaxIndexCache.delete(frameDir);
110882
+ }
110883
+ hdrFrameDirs.clear();
110798
110884
  }
110799
- perfStages.captureMs = Date.now() - stage4Start;
110800
- perfStages.encodeMs = hdrEncodeResult.durationMs;
110801
110885
  } else {
110802
110886
  let streamingEncoder = null;
110887
+ let streamingEncoderClosed = false;
110803
110888
  if (enableStreamingEncode) {
110804
110889
  streamingEncoder = await spawnStreamingEncoder(
110805
110890
  videoOnlyPath,
@@ -110809,7 +110894,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110809
110894
  height,
110810
110895
  codec: preset.codec,
110811
110896
  preset: preset.preset,
110812
- quality: preset.quality,
110897
+ quality: effectiveQuality,
110898
+ bitrate: effectiveBitrate,
110813
110899
  pixelFormat: preset.pixelFormat,
110814
110900
  useGpu: job.config.useGpu,
110815
110901
  imageFormat: captureOptions.format || "jpeg",
@@ -110819,201 +110905,215 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
110819
110905
  );
110820
110906
  assertNotAborted();
110821
110907
  }
110822
- if (enableStreamingEncode && streamingEncoder) {
110823
- const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
110824
- const currentEncoder = streamingEncoder;
110825
- if (workerCount > 1) {
110826
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110827
- const onFrameBuffer = async (frameIndex, buffer) => {
110828
- await reorderBuffer.waitForFrame(frameIndex);
110829
- currentEncoder.writeFrame(buffer);
110830
- reorderBuffer.advanceTo(frameIndex + 1);
110831
- };
110832
- await executeParallelCapture(
110833
- fileServer.url,
110834
- workDir,
110835
- tasks,
110836
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110837
- () => createVideoFrameInjector(frameLookup),
110838
- abortSignal,
110839
- (progress) => {
110840
- job.framesRendered = progress.capturedFrames;
110841
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110842
- const progressPct = 25 + frameProgress * 55;
110843
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110908
+ try {
110909
+ if (enableStreamingEncode && streamingEncoder) {
110910
+ const reorderBuffer = createFrameReorderBuffer(0, totalFrames);
110911
+ const currentEncoder = streamingEncoder;
110912
+ if (workerCount > 1) {
110913
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110914
+ const onFrameBuffer = async (frameIndex, buffer) => {
110915
+ await reorderBuffer.waitForFrame(frameIndex);
110916
+ currentEncoder.writeFrame(buffer);
110917
+ reorderBuffer.advanceTo(frameIndex + 1);
110918
+ };
110919
+ await executeParallelCapture(
110920
+ fileServer.url,
110921
+ workDir,
110922
+ tasks,
110923
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110924
+ () => createVideoFrameInjector(frameLookup),
110925
+ abortSignal,
110926
+ (progress) => {
110927
+ job.framesRendered = progress.capturedFrames;
110928
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
110929
+ const progressPct = 25 + frameProgress * 55;
110930
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
110931
+ updateJobStatus(
110932
+ job,
110933
+ "rendering",
110934
+ `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110935
+ Math.round(progressPct),
110936
+ onProgress
110937
+ );
110938
+ }
110939
+ },
110940
+ onFrameBuffer,
110941
+ cfg
110942
+ );
110943
+ if (probeSession) {
110944
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
110945
+ await closeCaptureSession(probeSession);
110946
+ probeSession = null;
110947
+ }
110948
+ } else {
110949
+ const videoInjector = createVideoFrameInjector(frameLookup);
110950
+ const session = probeSession ?? await createCaptureSession(
110951
+ fileServer.url,
110952
+ framesDir,
110953
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110954
+ videoInjector,
110955
+ cfg
110956
+ );
110957
+ if (probeSession) {
110958
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110959
+ probeSession = null;
110960
+ }
110961
+ try {
110962
+ if (!session.isInitialized) {
110963
+ await initializeSession(session);
110964
+ }
110965
+ assertNotAborted();
110966
+ lastBrowserConsole = session.browserConsoleBuffer;
110967
+ for (let i = 0; i < totalFrames; i++) {
110968
+ assertNotAborted();
110969
+ const time = i / job.config.fps;
110970
+ const { buffer } = await captureFrameToBuffer(session, i, time);
110971
+ await reorderBuffer.waitForFrame(i);
110972
+ currentEncoder.writeFrame(buffer);
110973
+ reorderBuffer.advanceTo(i + 1);
110974
+ job.framesRendered = i + 1;
110975
+ const frameProgress = (i + 1) / totalFrames;
110976
+ const progress = 25 + frameProgress * 55;
110844
110977
  updateJobStatus(
110845
110978
  job,
110846
110979
  "rendering",
110847
- `Streaming frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110848
- Math.round(progressPct),
110980
+ `Streaming frame ${i + 1}/${job.totalFrames}`,
110981
+ Math.round(progress),
110849
110982
  onProgress
110850
110983
  );
110851
110984
  }
110852
- },
110853
- onFrameBuffer,
110854
- cfg
110855
- );
110856
- if (probeSession) {
110857
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110858
- await closeCaptureSession(probeSession);
110859
- probeSession = null;
110985
+ } finally {
110986
+ lastBrowserConsole = session.browserConsoleBuffer;
110987
+ await closeCaptureSession(session);
110988
+ }
110860
110989
  }
110861
- } else {
110862
- const videoInjector = createVideoFrameInjector(frameLookup);
110863
- const session = probeSession ?? await createCaptureSession(
110864
- fileServer.url,
110865
- framesDir,
110866
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110867
- videoInjector,
110868
- cfg
110869
- );
110870
- if (probeSession) {
110871
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110872
- probeSession = null;
110990
+ const encodeResult = await currentEncoder.close();
110991
+ streamingEncoderClosed = true;
110992
+ assertNotAborted();
110993
+ if (!encodeResult.success) {
110994
+ throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110873
110995
  }
110874
- try {
110875
- if (!session.isInitialized) {
110876
- await initializeSession(session);
110996
+ perfStages.captureMs = Date.now() - stage4Start;
110997
+ perfStages.encodeMs = encodeResult.durationMs;
110998
+ } else {
110999
+ if (workerCount > 1) {
111000
+ const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
111001
+ await executeParallelCapture(
111002
+ fileServer.url,
111003
+ workDir,
111004
+ tasks,
111005
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
111006
+ () => createVideoFrameInjector(frameLookup),
111007
+ abortSignal,
111008
+ (progress) => {
111009
+ job.framesRendered = progress.capturedFrames;
111010
+ const frameProgress = progress.capturedFrames / progress.totalFrames;
111011
+ const progressPct = 25 + frameProgress * 45;
111012
+ if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111013
+ updateJobStatus(
111014
+ job,
111015
+ "rendering",
111016
+ `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
111017
+ Math.round(progressPct),
111018
+ onProgress
111019
+ );
111020
+ }
111021
+ },
111022
+ void 0,
111023
+ cfg
111024
+ );
111025
+ await mergeWorkerFrames(workDir, tasks, framesDir);
111026
+ if (probeSession) {
111027
+ lastBrowserConsole = probeSession.browserConsoleBuffer;
111028
+ await closeCaptureSession(probeSession);
111029
+ probeSession = null;
110877
111030
  }
110878
- assertNotAborted();
110879
- lastBrowserConsole = session.browserConsoleBuffer;
110880
- for (let i = 0; i < totalFrames; i++) {
110881
- assertNotAborted();
110882
- const time = i / job.config.fps;
110883
- const { buffer } = await captureFrameToBuffer(session, i, time);
110884
- await reorderBuffer.waitForFrame(i);
110885
- currentEncoder.writeFrame(buffer);
110886
- reorderBuffer.advanceTo(i + 1);
110887
- job.framesRendered = i + 1;
110888
- const frameProgress = (i + 1) / totalFrames;
110889
- const progress = 25 + frameProgress * 55;
110890
- updateJobStatus(
110891
- job,
110892
- "rendering",
110893
- `Streaming frame ${i + 1}/${job.totalFrames}`,
110894
- Math.round(progress),
110895
- onProgress
110896
- );
111031
+ } else {
111032
+ const videoInjector = createVideoFrameInjector(frameLookup);
111033
+ const session = probeSession ?? await createCaptureSession(
111034
+ fileServer.url,
111035
+ framesDir,
111036
+ { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
111037
+ videoInjector,
111038
+ cfg
111039
+ );
111040
+ if (probeSession) {
111041
+ prepareCaptureSessionForReuse(session, framesDir, videoInjector);
111042
+ probeSession = null;
110897
111043
  }
110898
- } finally {
110899
- lastBrowserConsole = session.browserConsoleBuffer;
110900
- await closeCaptureSession(session);
110901
- }
110902
- }
110903
- const encodeResult = await currentEncoder.close();
110904
- assertNotAborted();
110905
- if (!encodeResult.success) {
110906
- throw new Error(`Streaming encode failed: ${encodeResult.error}`);
110907
- }
110908
- perfStages.captureMs = Date.now() - stage4Start;
110909
- perfStages.encodeMs = encodeResult.durationMs;
110910
- } else {
110911
- if (workerCount > 1) {
110912
- const tasks = distributeFrames(job.totalFrames, workerCount, workDir);
110913
- await executeParallelCapture(
110914
- fileServer.url,
110915
- workDir,
110916
- tasks,
110917
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110918
- () => createVideoFrameInjector(frameLookup),
110919
- abortSignal,
110920
- (progress) => {
110921
- job.framesRendered = progress.capturedFrames;
110922
- const frameProgress = progress.capturedFrames / progress.totalFrames;
110923
- const progressPct = 25 + frameProgress * 45;
110924
- if (progress.capturedFrames % 30 === 0 || progress.capturedFrames === progress.totalFrames) {
111044
+ try {
111045
+ if (!session.isInitialized) {
111046
+ await initializeSession(session);
111047
+ }
111048
+ assertNotAborted();
111049
+ lastBrowserConsole = session.browserConsoleBuffer;
111050
+ for (let i = 0; i < job.totalFrames; i++) {
111051
+ assertNotAborted();
111052
+ const time = i / job.config.fps;
111053
+ await captureFrame(session, i, time);
111054
+ job.framesRendered = i + 1;
111055
+ const frameProgress = (i + 1) / job.totalFrames;
111056
+ const progress = 25 + frameProgress * 45;
110925
111057
  updateJobStatus(
110926
111058
  job,
110927
111059
  "rendering",
110928
- `Capturing frame ${progress.capturedFrames}/${progress.totalFrames} (${workerCount} workers)`,
110929
- Math.round(progressPct),
111060
+ `Capturing frame ${i + 1}/${job.totalFrames}`,
111061
+ Math.round(progress),
110930
111062
  onProgress
110931
111063
  );
110932
111064
  }
110933
- },
110934
- void 0,
110935
- cfg
110936
- );
110937
- await mergeWorkerFrames(workDir, tasks, framesDir);
110938
- if (probeSession) {
110939
- lastBrowserConsole = probeSession.browserConsoleBuffer;
110940
- await closeCaptureSession(probeSession);
110941
- probeSession = null;
111065
+ } finally {
111066
+ lastBrowserConsole = session.browserConsoleBuffer;
111067
+ await closeCaptureSession(session);
111068
+ }
110942
111069
  }
110943
- } else {
110944
- const videoInjector = createVideoFrameInjector(frameLookup);
110945
- const session = probeSession ?? await createCaptureSession(
110946
- fileServer.url,
111070
+ perfStages.captureMs = Date.now() - stage4Start;
111071
+ const stage5Start = Date.now();
111072
+ updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
111073
+ const frameExt = needsAlpha ? "png" : "jpg";
111074
+ const framePattern = `frame_%06d.${frameExt}`;
111075
+ const encoderOpts = {
111076
+ fps: job.config.fps,
111077
+ width,
111078
+ height,
111079
+ codec: preset.codec,
111080
+ preset: preset.preset,
111081
+ quality: effectiveQuality,
111082
+ bitrate: effectiveBitrate,
111083
+ pixelFormat: preset.pixelFormat,
111084
+ useGpu: job.config.useGpu,
111085
+ hdr: preset.hdr
111086
+ };
111087
+ const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
111088
+ framesDir,
111089
+ framePattern,
111090
+ videoOnlyPath,
111091
+ encoderOpts,
111092
+ chunkedEncodeSize,
111093
+ abortSignal
111094
+ ) : await encodeFramesFromDir(
110947
111095
  framesDir,
110948
- { ...captureOptions, skipReadinessVideoIds: Array.from(nativeHdrVideoIds) },
110949
- videoInjector,
110950
- cfg
111096
+ framePattern,
111097
+ videoOnlyPath,
111098
+ encoderOpts,
111099
+ abortSignal
110951
111100
  );
110952
- if (probeSession) {
110953
- prepareCaptureSessionForReuse(session, framesDir, videoInjector);
110954
- probeSession = null;
111101
+ assertNotAborted();
111102
+ if (!encodeResult.success) {
111103
+ throw new Error(`Encoding failed: ${encodeResult.error}`);
110955
111104
  }
111105
+ perfStages.encodeMs = Date.now() - stage5Start;
111106
+ }
111107
+ } finally {
111108
+ if (streamingEncoder && !streamingEncoderClosed) {
110956
111109
  try {
110957
- if (!session.isInitialized) {
110958
- await initializeSession(session);
110959
- }
110960
- assertNotAborted();
110961
- lastBrowserConsole = session.browserConsoleBuffer;
110962
- for (let i = 0; i < job.totalFrames; i++) {
110963
- assertNotAborted();
110964
- const time = i / job.config.fps;
110965
- await captureFrame(session, i, time);
110966
- job.framesRendered = i + 1;
110967
- const frameProgress = (i + 1) / job.totalFrames;
110968
- const progress = 25 + frameProgress * 45;
110969
- updateJobStatus(
110970
- job,
110971
- "rendering",
110972
- `Capturing frame ${i + 1}/${job.totalFrames}`,
110973
- Math.round(progress),
110974
- onProgress
110975
- );
110976
- }
110977
- } finally {
110978
- lastBrowserConsole = session.browserConsoleBuffer;
110979
- await closeCaptureSession(session);
111110
+ await streamingEncoder.close();
111111
+ } catch (err) {
111112
+ log.warn("streamingEncoder defensive close failed", {
111113
+ err: err instanceof Error ? err.message : String(err)
111114
+ });
110980
111115
  }
110981
111116
  }
110982
- perfStages.captureMs = Date.now() - stage4Start;
110983
- const stage5Start = Date.now();
110984
- updateJobStatus(job, "encoding", "Encoding video", 75, onProgress);
110985
- const frameExt = needsAlpha ? "png" : "jpg";
110986
- const framePattern = `frame_%06d.${frameExt}`;
110987
- const encoderOpts = {
110988
- fps: job.config.fps,
110989
- width,
110990
- height,
110991
- codec: preset.codec,
110992
- preset: preset.preset,
110993
- quality: preset.quality,
110994
- pixelFormat: preset.pixelFormat,
110995
- useGpu: job.config.useGpu,
110996
- hdr: preset.hdr
110997
- };
110998
- const encodeResult = enableChunkedEncode ? await encodeFramesChunkedConcat(
110999
- framesDir,
111000
- framePattern,
111001
- videoOnlyPath,
111002
- encoderOpts,
111003
- chunkedEncodeSize,
111004
- abortSignal
111005
- ) : await encodeFramesFromDir(
111006
- framesDir,
111007
- framePattern,
111008
- videoOnlyPath,
111009
- encoderOpts,
111010
- abortSignal
111011
- );
111012
- assertNotAborted();
111013
- if (!encodeResult.success) {
111014
- throw new Error(`Encoding failed: ${encodeResult.error}`);
111015
- }
111016
- perfStages.encodeMs = Date.now() - stage5Start;
111017
111117
  }
111018
111118
  }
111019
111119
  if (probeSession !== null) {
@@ -111177,7 +111277,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
111177
111277
 
111178
111278
  // src/services/hyperframeLint.ts
111179
111279
  import { existsSync as existsSync16, readFileSync as readFileSync11, statSync as statSync6 } from "node:fs";
111180
- import { resolve as resolve11, join as join16 } from "node:path";
111280
+ import { resolve as resolve12, join as join16 } from "node:path";
111181
111281
  function isStringRecord(value) {
111182
111282
  if (!value || typeof value !== "object" || Array.isArray(value)) {
111183
111283
  return false;
@@ -111204,7 +111304,7 @@ function pickEntryFile(files, preferredEntryFile) {
111204
111304
  return null;
111205
111305
  }
111206
111306
  function readProjectEntryFile(projectDir, preferredEntryFile) {
111207
- const absProjectDir = resolve11(projectDir);
111307
+ const absProjectDir = resolve12(projectDir);
111208
111308
  if (!existsSync16(absProjectDir) || !statSync6(absProjectDir).isDirectory()) {
111209
111309
  return { error: `Project directory not found: ${absProjectDir}` };
111210
111310
  }
@@ -111212,7 +111312,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
111212
111312
  (value) => typeof value === "string" && value.trim().length > 0
111213
111313
  );
111214
111314
  for (const entryFile of entryCandidates) {
111215
- const absoluteEntryPath = resolve11(absProjectDir, entryFile);
111315
+ const absoluteEntryPath = resolve12(absProjectDir, entryFile);
111216
111316
  if (!absoluteEntryPath.startsWith(absProjectDir)) {
111217
111317
  return { error: `Entry file must stay inside project directory: ${entryFile}` };
111218
111318
  }
@@ -111277,10 +111377,10 @@ var Semaphore = class {
111277
111377
  this.active++;
111278
111378
  return () => this.release();
111279
111379
  }
111280
- return new Promise((resolve13) => {
111380
+ return new Promise((resolve14) => {
111281
111381
  this.queue.push(() => {
111282
111382
  this.active++;
111283
- resolve13(() => this.release());
111383
+ resolve14(() => this.release());
111284
111384
  });
111285
111385
  });
111286
111386
  }
@@ -111315,12 +111415,12 @@ async function prepareRenderBody(body) {
111315
111415
  const options = parseRenderOptions(body);
111316
111416
  const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
111317
111417
  if (projectDir) {
111318
- const absProjectDir = resolve12(projectDir);
111418
+ const absProjectDir = resolve13(projectDir);
111319
111419
  if (!existsSync17(absProjectDir) || !statSync7(absProjectDir).isDirectory()) {
111320
111420
  return { error: `Project directory not found: ${absProjectDir}` };
111321
111421
  }
111322
111422
  const entry = options.entryFile || "index.html";
111323
- if (!existsSync17(resolve12(absProjectDir, entry))) {
111423
+ if (!existsSync17(resolve13(absProjectDir, entry))) {
111324
111424
  return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
111325
111425
  }
111326
111426
  return { prepared: { input: { projectDir: absProjectDir, ...options } } };
@@ -111361,7 +111461,7 @@ function resolveOutputPath(projectDir, outputCandidate, rendersDir, log) {
111361
111461
  try {
111362
111462
  return resolveRenderPaths(projectDir, outputCandidate, rendersDir).absoluteOutputPath;
111363
111463
  } catch (error) {
111364
- const fallbackPath = resolve12(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111464
+ const fallbackPath = resolve13(rendersDir, `producer-fallback-${Date.now()}.mp4`);
111365
111465
  log.warn("Failed to resolve output path, using fallback", {
111366
111466
  fallback: fallbackPath,
111367
111467
  error: error instanceof Error ? error.message : String(error)
@@ -111740,7 +111840,7 @@ function startServer(options = {}) {
111740
111840
  process.on("SIGINT", () => shutdown("SIGINT"));
111741
111841
  return server;
111742
111842
  }
111743
- var entryScript = process.argv[1] ? resolve12(process.argv[1]) : "";
111843
+ var entryScript = process.argv[1] ? resolve13(process.argv[1]) : "";
111744
111844
  var isPublicServerEntry = entryScript.endsWith("/public-server.js") || entryScript.endsWith("/src/server.ts");
111745
111845
  if (isPublicServerEntry) {
111746
111846
  const { values } = parseArgs({