hyperframes 0.7.33 → 0.7.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -50,7 +50,7 @@ var VERSION;
50
50
  var init_version = __esm({
51
51
  "src/version.ts"() {
52
52
  "use strict";
53
- VERSION = true ? "0.7.33" : "0.0.0-dev";
53
+ VERSION = true ? "0.7.35" : "0.0.0-dev";
54
54
  }
55
55
  });
56
56
 
@@ -4891,7 +4891,7 @@ var require_util = __commonJS({
4891
4891
  return path2;
4892
4892
  }
4893
4893
  exports.normalize = normalize;
4894
- function join113(aRoot, aPath) {
4894
+ function join114(aRoot, aPath) {
4895
4895
  if (aRoot === "") {
4896
4896
  aRoot = ".";
4897
4897
  }
@@ -4923,7 +4923,7 @@ var require_util = __commonJS({
4923
4923
  }
4924
4924
  return joined;
4925
4925
  }
4926
- exports.join = join113;
4926
+ exports.join = join114;
4927
4927
  exports.isAbsolute = function(aPath) {
4928
4928
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
4929
4929
  };
@@ -5096,7 +5096,7 @@ var require_util = __commonJS({
5096
5096
  parsed.path = parsed.path.substring(0, index + 1);
5097
5097
  }
5098
5098
  }
5099
- sourceURL = join113(urlGenerate(parsed), sourceURL);
5099
+ sourceURL = join114(urlGenerate(parsed), sourceURL);
5100
5100
  }
5101
5101
  return normalize(sourceURL);
5102
5102
  }
@@ -60667,7 +60667,7 @@ async function applyDomLayerMask(page, showIds, extraHideIds) {
60667
60667
  (args) => {
60668
60668
  const existing = document.getElementById(args.styleId);
60669
60669
  if (existing) existing.remove();
60670
- const restoreMaskedTimedDescendants = () => {
60670
+ const restoreMaskedElements = () => {
60671
60671
  const masked = document.querySelectorAll(`[${args.hiddenAttr}="1"]`);
60672
60672
  for (const node of masked) {
60673
60673
  if (!(node instanceof HTMLElement)) continue;
@@ -60683,7 +60683,25 @@ async function applyDomLayerMask(page, showIds, extraHideIds) {
60683
60683
  node.removeAttribute(args.prevPriorityAttr);
60684
60684
  }
60685
60685
  };
60686
- restoreMaskedTimedDescendants();
60686
+ restoreMaskedElements();
60687
+ const rememberAndHideElement = (el) => {
60688
+ if (el.getAttribute(args.hiddenAttr) !== "1") {
60689
+ const prevVisibility = el.style.getPropertyValue("visibility");
60690
+ const prevPriority = typeof el.style.getPropertyPriority === "function" ? el.style.getPropertyPriority("visibility") : "";
60691
+ if (prevVisibility) {
60692
+ el.setAttribute(args.prevVisibilityAttr, prevVisibility);
60693
+ } else {
60694
+ el.removeAttribute(args.prevVisibilityAttr);
60695
+ }
60696
+ if (prevPriority) {
60697
+ el.setAttribute(args.prevPriorityAttr, prevPriority);
60698
+ } else {
60699
+ el.removeAttribute(args.prevPriorityAttr);
60700
+ }
60701
+ el.setAttribute(args.hiddenAttr, "1");
60702
+ }
60703
+ el.style.setProperty("visibility", "hidden", "important");
60704
+ };
60687
60705
  const hiddenTimedDescendants = [];
60688
60706
  const rememberHiddenTimedDescendants = (root) => {
60689
60707
  for (const node of root.querySelectorAll("[data-start]")) {
@@ -60710,30 +60728,16 @@ async function applyDomLayerMask(page, showIds, extraHideIds) {
60710
60728
  ${showRule}`;
60711
60729
  document.head.appendChild(style);
60712
60730
  for (const el of hiddenTimedDescendants) {
60713
- if (el.getAttribute(args.hiddenAttr) === "1") continue;
60714
- const prevVisibility = el.style.getPropertyValue("visibility");
60715
- const prevPriority = typeof el.style.getPropertyPriority === "function" ? el.style.getPropertyPriority("visibility") : "";
60716
- if (prevVisibility) {
60717
- el.setAttribute(args.prevVisibilityAttr, prevVisibility);
60718
- } else {
60719
- el.removeAttribute(args.prevVisibilityAttr);
60720
- }
60721
- if (prevPriority) {
60722
- el.setAttribute(args.prevPriorityAttr, prevPriority);
60723
- } else {
60724
- el.removeAttribute(args.prevPriorityAttr);
60725
- }
60726
- el.setAttribute(args.hiddenAttr, "1");
60727
- el.style.setProperty("visibility", "hidden", "important");
60731
+ rememberAndHideElement(el);
60728
60732
  }
60729
60733
  for (const id of args.hide) {
60730
60734
  const el = document.getElementById(id);
60731
60735
  if (el) {
60732
- el.style.setProperty("visibility", "hidden", "important");
60736
+ rememberAndHideElement(el);
60733
60737
  }
60734
60738
  const img = document.getElementById(`__render_frame_${id}__`);
60735
60739
  if (img) {
60736
- img.style.setProperty("visibility", "hidden", "important");
60740
+ rememberAndHideElement(img);
60737
60741
  }
60738
60742
  }
60739
60743
  },
@@ -60747,7 +60751,7 @@ ${showRule}`;
60747
60751
  }
60748
60752
  );
60749
60753
  }
60750
- async function removeDomLayerMask(page, extraHideIds) {
60754
+ async function removeDomLayerMask(page, _extraHideIds) {
60751
60755
  await page.evaluate(
60752
60756
  (args) => {
60753
60757
  const style = document.getElementById(args.styleId);
@@ -60766,17 +60770,8 @@ async function removeDomLayerMask(page, extraHideIds) {
60766
60770
  node.removeAttribute(args.prevVisibilityAttr);
60767
60771
  node.removeAttribute(args.prevPriorityAttr);
60768
60772
  }
60769
- for (const id of args.hide) {
60770
- const el = document.getElementById(id);
60771
- if (el) {
60772
- el.style.removeProperty("visibility");
60773
- }
60774
- const img = document.getElementById(`__render_frame_${id}__`);
60775
- if (img) img.style.removeProperty("visibility");
60776
- }
60777
60773
  },
60778
60774
  {
60779
- hide: extraHideIds,
60780
60775
  styleId: DOM_LAYER_MASK_STYLE_ID,
60781
60776
  hiddenAttr: DOM_LAYER_MASK_HIDDEN_ATTR,
60782
60777
  prevVisibilityAttr: DOM_LAYER_MASK_PREV_VISIBILITY_ATTR,
@@ -62131,10 +62126,47 @@ var init_processTracker = __esm({
62131
62126
 
62132
62127
  // ../engine/src/utils/ffmpegBinaries.ts
62133
62128
  import { execFileSync } from "child_process";
62134
- import { existsSync as existsSync5 } from "fs";
62135
- import { resolve as resolve5 } from "path";
62129
+ import { accessSync, constants, existsSync as existsSync5 } from "fs";
62130
+ import { delimiter, join as join7, resolve as resolve5 } from "path";
62131
+ function candidateFileName(candidate) {
62132
+ return candidate.split(/[\\/]/).at(-1)?.toLowerCase() ?? candidate.toLowerCase();
62133
+ }
62134
+ function chooseBestPathCandidate(name, candidates) {
62135
+ const normalized = candidates.map((candidate) => candidate.trim()).filter(Boolean);
62136
+ return normalized.find((candidate) => candidateFileName(candidate) === `${name}.exe`) ?? normalized.find((candidate) => candidateFileName(candidate) === name) ?? normalized.find((candidate) => !candidateFileName(candidate).match(/\.(cmd|bat)$/i)) ?? normalized[0];
62137
+ }
62138
+ function scanPath(name) {
62139
+ const pathValue = process.env.PATH;
62140
+ if (!pathValue) return void 0;
62141
+ const extensions = process.platform === "win32" ? [
62142
+ ".exe",
62143
+ ...new Set(
62144
+ (process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").map((ext) => ext.trim().toLowerCase()).filter(Boolean)
62145
+ ),
62146
+ ""
62147
+ ] : [""];
62148
+ const candidates = [];
62149
+ for (const dir of pathValue.split(delimiter)) {
62150
+ if (!dir) continue;
62151
+ for (const ext of extensions) {
62152
+ const candidate = join7(dir, `${name}${ext}`);
62153
+ if (isExecutablePathCandidate(candidate)) candidates.push(candidate);
62154
+ }
62155
+ }
62156
+ return chooseBestPathCandidate(name, candidates);
62157
+ }
62158
+ function isExecutablePathCandidate(candidate) {
62159
+ if (process.platform === "win32") return existsSync5(candidate);
62160
+ try {
62161
+ accessSync(candidate, constants.X_OK);
62162
+ return true;
62163
+ } catch {
62164
+ return false;
62165
+ }
62166
+ }
62136
62167
  function findOnPath(name) {
62137
62168
  if (pathCache.has(name)) return pathCache.get(name);
62169
+ let found;
62138
62170
  try {
62139
62171
  const command2 = process.platform === "win32" ? "where" : "which";
62140
62172
  const output = execFileSync(command2, [name], {
@@ -62142,14 +62174,13 @@ function findOnPath(name) {
62142
62174
  stdio: ["pipe", "pipe", "pipe"],
62143
62175
  timeout: 5e3
62144
62176
  });
62145
- const first = output.split(/\r?\n/).map((s2) => s2.trim()).find(Boolean);
62146
- const resolved = first ? resolve5(first) : void 0;
62147
- pathCache.set(name, resolved);
62148
- return resolved;
62177
+ found = chooseBestPathCandidate(name, output.split(/\r?\n/));
62149
62178
  } catch {
62150
- pathCache.set(name, void 0);
62151
- return void 0;
62179
+ found = scanPath(name);
62152
62180
  }
62181
+ const resolved = found ? resolve5(found) : void 0;
62182
+ pathCache.set(name, resolved);
62183
+ return resolved;
62153
62184
  }
62154
62185
  function getConfiguredBinary(envName, binaryName) {
62155
62186
  const configured = process.env[envName]?.trim();
@@ -62166,16 +62197,20 @@ function assertConfiguredFfmpegBinariesExist() {
62166
62197
  const ffmpegPath = process.env[FFMPEG_PATH_ENV]?.trim();
62167
62198
  if (ffmpegPath && !existsSync5(ffmpegPath)) {
62168
62199
  throw new Error(
62169
- `[FFmpeg] FFmpeg binary not found at ${FFMPEG_PATH_ENV}="${ffmpegPath}". Install FFmpeg or unset the override.`
62200
+ `[FFmpeg] FFmpeg binary not found at ${FFMPEG_PATH_ENV}="${ffmpegPath}". Install FFmpeg or unset the override.${pathEncodingHint(ffmpegPath)}`
62170
62201
  );
62171
62202
  }
62172
62203
  const ffprobePath = process.env[FFPROBE_PATH_ENV]?.trim();
62173
62204
  if (ffprobePath && !existsSync5(ffprobePath)) {
62174
62205
  throw new Error(
62175
- `[FFmpeg] FFprobe binary not found at ${FFPROBE_PATH_ENV}="${ffprobePath}". Install FFmpeg or unset the override.`
62206
+ `[FFmpeg] FFprobe binary not found at ${FFPROBE_PATH_ENV}="${ffprobePath}". Install FFmpeg or unset the override.${pathEncodingHint(ffprobePath)}`
62176
62207
  );
62177
62208
  }
62178
62209
  }
62210
+ function pathEncodingHint(configuredPath) {
62211
+ if (!configuredPath.includes("\uFFFD")) return "";
62212
+ return " The path contains a Unicode replacement character, which usually means it was mangled while being copied or decoded.";
62213
+ }
62179
62214
  var FFMPEG_PATH_ENV, FFPROBE_PATH_ENV, pathCache;
62180
62215
  var init_ffmpegBinaries = __esm({
62181
62216
  "../engine/src/utils/ffmpegBinaries.ts"() {
@@ -62825,7 +62860,7 @@ var init_ffprobe = __esm({
62825
62860
  // ../engine/src/services/chunkEncoder.ts
62826
62861
  import { spawn as spawn4 } from "child_process";
62827
62862
  import { copyFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync3 } from "fs";
62828
- import { join as join7, dirname as dirname4, extname as extname2 } from "path";
62863
+ import { join as join8, dirname as dirname4, extname as extname2 } from "path";
62829
62864
  function appendEncodeTimeoutMessage(error, timedOut, timeoutMs) {
62830
62865
  if (!timedOut) return error;
62831
62866
  return `${error}
@@ -63072,7 +63107,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
63072
63107
  if (options.useGpu) {
63073
63108
  gpuEncoder = await getCachedGpuEncoder();
63074
63109
  }
63075
- const inputPath = join7(framesDir, framePattern);
63110
+ const inputPath = join8(framesDir, framePattern);
63076
63111
  const inputArgs = ["-framerate", fpsToFfmpegArg(options.fps), "-i", inputPath];
63077
63112
  const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
63078
63113
  return new Promise((resolve62) => {
@@ -63160,7 +63195,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63160
63195
  }
63161
63196
  const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
63162
63197
  const chunkCount = Math.ceil(files.length / chunkSize);
63163
- const chunkDir = join7(dirname4(outputPath), "chunk-encode");
63198
+ const chunkDir = join8(dirname4(outputPath), "chunk-encode");
63164
63199
  if (!existsSync6(chunkDir)) mkdirSync3(chunkDir, { recursive: true });
63165
63200
  const chunkPaths = [];
63166
63201
  for (let i2 = 0; i2 < chunkCount; i2++) {
@@ -63177,8 +63212,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63177
63212
  const startNumber = i2 * chunkSize;
63178
63213
  const framesInChunk = Math.min(chunkSize, files.length - startNumber);
63179
63214
  const ext = outputPath.endsWith(".webm") ? ".webm" : outputPath.endsWith(".mov") ? ".mov" : ".mp4";
63180
- const chunkPath = join7(chunkDir, `chunk_${String(i2).padStart(4, "0")}${ext}`);
63181
- const inputPath = join7(framesDir, framePattern);
63215
+ const chunkPath = join8(chunkDir, `chunk_${String(i2).padStart(4, "0")}${ext}`);
63216
+ const inputPath = join8(framesDir, framePattern);
63182
63217
  const inputArgs = [
63183
63218
  "-framerate",
63184
63219
  fpsToFfmpegArg(options.fps),
@@ -63243,7 +63278,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
63243
63278
  }
63244
63279
  chunkPaths.push(chunkPath);
63245
63280
  }
63246
- const concatListPath = join7(chunkDir, "concat-list.txt");
63281
+ const concatListPath = join8(chunkDir, "concat-list.txt");
63247
63282
  const concatInput = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
63248
63283
  writeFileSync3(concatListPath, concatInput, "utf-8");
63249
63284
  const concatArgs = [
@@ -63791,7 +63826,7 @@ var init_streamingEncoder = __esm({
63791
63826
  // ../engine/src/utils/urlDownloader.ts
63792
63827
  import { createWriteStream, existsSync as existsSync8, mkdirSync as mkdirSync5 } from "fs";
63793
63828
  import { createHash } from "crypto";
63794
- import { join as join8, extname as extname3 } from "path";
63829
+ import { join as join9, extname as extname3 } from "path";
63795
63830
  import { Readable } from "stream";
63796
63831
  import { finished } from "stream/promises";
63797
63832
  function isBlockedHost(hostname) {
@@ -63843,7 +63878,7 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
63843
63878
  mkdirSync5(destDir, { recursive: true });
63844
63879
  }
63845
63880
  const filename = getFilenameFromUrl(url);
63846
- const localPath = join8(destDir, filename);
63881
+ const localPath = join9(destDir, filename);
63847
63882
  if (existsSync8(localPath)) {
63848
63883
  downloadPathCache.set(url, localPath);
63849
63884
  return localPath;
@@ -66363,7 +66398,7 @@ __export(dist_exports2, {
66363
66398
  import postcss2 from "postcss";
66364
66399
  import postcss22 from "postcss";
66365
66400
  import { existsSync as existsSync9, readFileSync as readFileSync4, readdirSync as readdirSync3 } from "fs";
66366
- import { dirname as dirname6, extname as extname4, isAbsolute as isAbsolute2, join as join9, posix as posix2, relative as relative2, resolve as resolve7 } from "path";
66401
+ import { dirname as dirname6, extname as extname4, isAbsolute as isAbsolute2, join as join10, posix as posix2, relative as relative2, resolve as resolve7 } from "path";
66367
66402
  function extractOpenTags(source) {
66368
66403
  const tags = [];
66369
66404
  let match;
@@ -67674,7 +67709,7 @@ function collectExternalStyles(projectDir, html, compSrcPath) {
67674
67709
  if (!rel.split(/\s+/).some((part) => part.toLowerCase() === "stylesheet")) continue;
67675
67710
  const href = tag.match(/\bhref\s*=\s*["']([^"']+)["']/i)?.[1] ?? "";
67676
67711
  if (!isLocalStylesheetHref(href)) continue;
67677
- const rootRelative = compSrcPath ? join9(dirname6(compSrcPath), href) : href;
67712
+ const rootRelative = compSrcPath ? join10(dirname6(compSrcPath), href) : href;
67678
67713
  const stylesheet = resolveExistingLocalAsset(projectDir, rootRelative);
67679
67714
  if (!stylesheet) continue;
67680
67715
  styles.push({ href, content: readFileSync4(stylesheet.resolved, "utf-8") });
@@ -67696,7 +67731,7 @@ function collectCssSources(projectDir, html, compSrcPath) {
67696
67731
  if (!rel.split(/\s+/).some((part) => part.toLowerCase() === "stylesheet")) continue;
67697
67732
  const href = readHtmlAttr(tag, "href") ?? "";
67698
67733
  if (!isLocalStylesheetHref(href)) continue;
67699
- const rootRelativePath = compSrcPath ? join9(dirname6(compSrcPath), href) : href;
67734
+ const rootRelativePath = compSrcPath ? join10(dirname6(compSrcPath), href) : href;
67700
67735
  const stylesheet = resolveExistingLocalAsset(projectDir, rootRelativePath);
67701
67736
  if (!stylesheet) continue;
67702
67737
  sources.push({
@@ -67756,7 +67791,7 @@ function resolveExistingLocalAsset(projectDir, url) {
67756
67791
  function resolveCssAssetCandidates(projectDir, url, htmlCompSrcPath, cssRootRelativePath) {
67757
67792
  if (url.startsWith("/")) return resolveLocalAssetCandidates(projectDir, url);
67758
67793
  if (cssRootRelativePath) {
67759
- return resolveLocalAssetCandidates(projectDir, join9(dirname6(cssRootRelativePath), url));
67794
+ return resolveLocalAssetCandidates(projectDir, join10(dirname6(cssRootRelativePath), url));
67760
67795
  }
67761
67796
  if (htmlCompSrcPath) {
67762
67797
  return resolveLocalAssetCandidates(projectDir, rewriteAssetPath(htmlCompSrcPath, url));
@@ -67785,14 +67820,14 @@ async function lintProject(projectDir) {
67785
67820
  const out = [];
67786
67821
  for (const entry of readdirSync3(dir, { withFileTypes: true })) {
67787
67822
  const relPath = rel ? `${rel}/${entry.name}` : entry.name;
67788
- if (entry.isDirectory()) out.push(...collectHtmlFiles(join9(dir, entry.name), relPath));
67823
+ if (entry.isDirectory()) out.push(...collectHtmlFiles(join10(dir, entry.name), relPath));
67789
67824
  else if (entry.isFile() && entry.name.endsWith(".html")) out.push(relPath);
67790
67825
  }
67791
67826
  return out;
67792
67827
  };
67793
67828
  const files = collectHtmlFiles(compositionsDir, "").sort();
67794
67829
  for (const file of files) {
67795
- const filePath = join9(compositionsDir, file);
67830
+ const filePath = join10(compositionsDir, file);
67796
67831
  const html = readFileSync4(filePath, "utf-8");
67797
67832
  const compSrcPath = `compositions/${file}`;
67798
67833
  allHtmlSources.push({ html, compSrcPath });
@@ -67970,7 +68005,7 @@ function lintMultipleRootCompositions(projectDir) {
67970
68005
  const rootCompositions = [];
67971
68006
  for (const file of rootHtmlFiles) {
67972
68007
  if (file === "caption-skin.html") continue;
67973
- const content = readFileSync4(join9(projectDir, file), "utf-8");
68008
+ const content = readFileSync4(join10(projectDir, file), "utf-8");
67974
68009
  if (/data-composition-id/i.test(content)) {
67975
68010
  rootCompositions.push(file);
67976
68011
  }
@@ -70469,7 +70504,7 @@ var init_inlineSubCompositions = __esm({
70469
70504
 
70470
70505
  // ../core/dist/compiler/htmlBundler.js
70471
70506
  import { readFileSync as readFileSync5, existsSync as existsSync10 } from "fs";
70472
- import { join as join10, resolve as resolve8, relative as relative3, dirname as dirname7, isAbsolute as isAbsolute3, sep as sep2 } from "path";
70507
+ import { join as join11, resolve as resolve8, relative as relative3, dirname as dirname7, isAbsolute as isAbsolute3, sep as sep2 } from "path";
70473
70508
  import { transformSync } from "esbuild";
70474
70509
  function getRuntimeScriptUrl() {
70475
70510
  const configured = (process.env.HYPERFRAME_RUNTIME_URL || "").trim();
@@ -70983,7 +71018,7 @@ function hoistCompositionScripts(container, opts) {
70983
71018
  }
70984
71019
  }
70985
71020
  async function bundleToSingleHtml(projectDir, options) {
70986
- const indexPath2 = join10(projectDir, "index.html");
71021
+ const indexPath2 = join11(projectDir, "index.html");
70987
71022
  if (!existsSync10(indexPath2))
70988
71023
  throw new Error("index.html not found in project directory");
70989
71024
  const rawHtml = readFileSync5(indexPath2, "utf-8");
@@ -71371,7 +71406,7 @@ import {
71371
71406
  utimesSync,
71372
71407
  writeFileSync as writeFileSync4
71373
71408
  } from "fs";
71374
- import { join as join11 } from "path";
71409
+ import { join as join12 } from "path";
71375
71410
  function readKeyStat(videoPath) {
71376
71411
  try {
71377
71412
  const stat3 = statSync3(videoPath);
@@ -71402,8 +71437,8 @@ function cacheEntryDirName(keyHash) {
71402
71437
  }
71403
71438
  function lookupCacheEntry(rootDir, input2) {
71404
71439
  const keyHash = computeCacheKey(input2);
71405
- const dir = join11(rootDir, cacheEntryDirName(keyHash));
71406
- const complete = existsSync11(join11(dir, COMPLETE_SENTINEL));
71440
+ const dir = join12(rootDir, cacheEntryDirName(keyHash));
71441
+ const complete = existsSync11(join12(dir, COMPLETE_SENTINEL));
71407
71442
  return { entry: { dir, keyHash }, hit: complete };
71408
71443
  }
71409
71444
  function partialCacheEntryDir(entry) {
@@ -71414,13 +71449,13 @@ function isTargetExistsRenameError(err) {
71414
71449
  return code === "EEXIST" || code === "ENOTEMPTY" || code === "EPERM";
71415
71450
  }
71416
71451
  function adoptPublishedWinner(entry, partialDir) {
71417
- if (!existsSync11(join11(entry.dir, COMPLETE_SENTINEL))) return null;
71452
+ if (!existsSync11(join12(entry.dir, COMPLETE_SENTINEL))) return null;
71418
71453
  removeDir(partialDir);
71419
71454
  return { dir: entry.dir, published: true };
71420
71455
  }
71421
71456
  function publishCacheEntry(entry, partialDir) {
71422
71457
  try {
71423
- writeFileSync4(join11(partialDir, COMPLETE_SENTINEL), "", "utf-8");
71458
+ writeFileSync4(join12(partialDir, COMPLETE_SENTINEL), "", "utf-8");
71424
71459
  } catch {
71425
71460
  return { dir: partialDir, published: false };
71426
71461
  }
@@ -71447,7 +71482,7 @@ function publishCacheEntry(entry, partialDir) {
71447
71482
  function touchCacheEntry(entry) {
71448
71483
  try {
71449
71484
  const now = /* @__PURE__ */ new Date();
71450
- utimesSync(join11(entry.dir, COMPLETE_SENTINEL), now, now);
71485
+ utimesSync(join12(entry.dir, COMPLETE_SENTINEL), now, now);
71451
71486
  } catch {
71452
71487
  }
71453
71488
  }
@@ -71472,7 +71507,7 @@ function directorySizeBytes(path2) {
71472
71507
  return 0;
71473
71508
  }
71474
71509
  for (const child of children) {
71475
- const childPath = join11(path2, child);
71510
+ const childPath = join12(path2, child);
71476
71511
  try {
71477
71512
  const stat3 = lstatSync(childPath);
71478
71513
  if (stat3.isDirectory()) {
@@ -71501,7 +71536,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
71501
71536
  }
71502
71537
  let lastUseMs = dirStat.mtimeMs;
71503
71538
  try {
71504
- lastUseMs = statSync3(join11(dir, COMPLETE_SENTINEL)).mtimeMs;
71539
+ lastUseMs = statSync3(join12(dir, COMPLETE_SENTINEL)).mtimeMs;
71505
71540
  } catch {
71506
71541
  }
71507
71542
  return { dir, size: directorySizeBytes(dir), lastUseMs, ageMs: now - lastUseMs };
@@ -71511,7 +71546,7 @@ function collectGcEntry(dir, name, now, minAgeMs, stats) {
71511
71546
  }
71512
71547
  function gcSweepDue(rootDir, maxAgeMs) {
71513
71548
  try {
71514
- return Date.now() - statSync3(join11(rootDir, GC_MARKER)).mtimeMs > maxAgeMs;
71549
+ return Date.now() - statSync3(join12(rootDir, GC_MARKER)).mtimeMs > maxAgeMs;
71515
71550
  } catch {
71516
71551
  return true;
71517
71552
  }
@@ -71519,7 +71554,7 @@ function gcSweepDue(rootDir, maxAgeMs) {
71519
71554
  function gcExtractionCache(rootDir, opts) {
71520
71555
  const stats = { evictedEntries: 0, evictedBytes: 0, agedPartialsRemoved: 0 };
71521
71556
  try {
71522
- writeFileSync4(join11(rootDir, GC_MARKER), "", "utf-8");
71557
+ writeFileSync4(join12(rootDir, GC_MARKER), "", "utf-8");
71523
71558
  } catch {
71524
71559
  }
71525
71560
  try {
@@ -71528,7 +71563,7 @@ function gcExtractionCache(rootDir, opts) {
71528
71563
  for (const child of readdirSync4(rootDir, { withFileTypes: true })) {
71529
71564
  if (!child.isDirectory() || !isCacheLikeChild(child.name)) continue;
71530
71565
  const entry = collectGcEntry(
71531
- join11(rootDir, child.name),
71566
+ join12(rootDir, child.name),
71532
71567
  child.name,
71533
71568
  now,
71534
71569
  opts.minAgeMs,
@@ -71557,7 +71592,7 @@ function rehydrateCacheEntry(entry, options) {
71557
71592
  const suffix = `.${options.format}`;
71558
71593
  const files = readdirSync4(entry.dir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(suffix)).sort();
71559
71594
  files.forEach((file, idx) => {
71560
- framePaths.set(idx, join11(entry.dir, file));
71595
+ framePaths.set(idx, join12(entry.dir, file));
71561
71596
  });
71562
71597
  return {
71563
71598
  videoId: options.videoId,
@@ -71586,7 +71621,7 @@ var init_extractionCache = __esm({
71586
71621
  // ../engine/src/services/videoFrameExtractor.ts
71587
71622
  import { spawn as spawn6 } from "child_process";
71588
71623
  import { copyFileSync as copyFileSync2, existsSync as existsSync12, linkSync, mkdirSync as mkdirSync7, readdirSync as readdirSync5, rmSync as rmSync2 } from "fs";
71589
- import { isAbsolute as isAbsolute4, join as join12, posix as posix3, resolve as resolve9, sep as sep3 } from "path";
71624
+ import { isAbsolute as isAbsolute4, join as join13, posix as posix3, resolve as resolve9, sep as sep3 } from "path";
71590
71625
  function isVideoFrameFormat(value) {
71591
71626
  return typeof value === "string" && VIDEO_FRAME_FORMATS.includes(value);
71592
71627
  }
@@ -71662,12 +71697,12 @@ function parseImageElements(html) {
71662
71697
  async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config, outputDirOverride) {
71663
71698
  const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
71664
71699
  const { fps, outputDir, quality = 95 } = options;
71665
- const videoOutputDir = outputDirOverride ?? join12(outputDir, videoId);
71700
+ const videoOutputDir = outputDirOverride ?? join13(outputDir, videoId);
71666
71701
  if (!existsSync12(videoOutputDir)) mkdirSync7(videoOutputDir, { recursive: true });
71667
71702
  const metadata = await extractMediaMetadata(videoPath);
71668
71703
  const format = resolveFrameFormat(metadata, options.format);
71669
71704
  const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
71670
- const outputPattern = join12(videoOutputDir, framePattern);
71705
+ const outputPattern = join13(videoOutputDir, framePattern);
71671
71706
  const isHdr = isHdrColorSpace(metadata.colorSpace);
71672
71707
  const isMacOS = process.platform === "darwin";
71673
71708
  const args = [];
@@ -71728,7 +71763,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
71728
71763
  const framePaths = /* @__PURE__ */ new Map();
71729
71764
  const files = readdirSync5(videoOutputDir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(`.${format}`)).sort();
71730
71765
  files.forEach((file, index) => {
71731
- framePaths.set(index, join12(videoOutputDir, file));
71766
+ framePaths.set(index, join13(videoOutputDir, file));
71732
71767
  });
71733
71768
  resolve62({
71734
71769
  videoId,
@@ -71779,7 +71814,7 @@ function extractedFramesFromDirectory(work, outputDir, srcPath, fps) {
71779
71814
  const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${work.format}`;
71780
71815
  const framePaths = /* @__PURE__ */ new Map();
71781
71816
  extractedFrameFileNames(outputDir, work.format).forEach((file, index) => {
71782
- framePaths.set(index, join12(outputDir, file));
71817
+ framePaths.set(index, join13(outputDir, file));
71783
71818
  });
71784
71819
  return {
71785
71820
  videoId: work.video.id,
@@ -71888,7 +71923,7 @@ function sliceSupersetMember(member, superset, outputDir, fps) {
71888
71923
  for (let i2 = 0; i2 < frameCount; i2 += 1) {
71889
71924
  const sourceFrame = superset.framePaths.get(member.offsetFrames + i2);
71890
71925
  if (!sourceFrame) throw new Error(`superset frame ${member.offsetFrames + i2} missing`);
71891
- linkOrCopyFrame(sourceFrame, join12(outputDir, frameFileName(i2 + 1, work.format)));
71926
+ linkOrCopyFrame(sourceFrame, join13(outputDir, frameFileName(i2 + 1, work.format)));
71892
71927
  }
71893
71928
  return extractedFramesFromDirectory(work, outputDir, work.videoPath, fps);
71894
71929
  }
@@ -71900,22 +71935,22 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
71900
71935
  if (!candidates.includes(candidate)) candidates.push(candidate);
71901
71936
  };
71902
71937
  for (const variant of decodeUrlPathVariants(cleanSrc)) {
71903
- const fromCompiled = compiledDir ? join12(compiledDir, variant) : null;
71904
- const fromBase = join12(baseDir, variant);
71938
+ const fromCompiled = compiledDir ? join13(compiledDir, variant) : null;
71939
+ const fromBase = join13(baseDir, variant);
71905
71940
  const baseAbs = resolve9(baseDir);
71906
71941
  const fromBaseAbs = resolve9(fromBase);
71907
71942
  if (!fromBaseAbs.startsWith(baseAbs + sep3) && fromBaseAbs !== baseAbs) {
71908
71943
  const normalized = posix3.normalize(variant.replace(/\\/g, "/"));
71909
71944
  const stripped = normalized.replace(/^(\.\.\/)+/, "");
71910
71945
  if (stripped && stripped !== variant && !stripped.startsWith("..")) {
71911
- if (compiledDir) addCandidate2(join12(compiledDir, stripped));
71912
- addCandidate2(join12(baseDir, stripped));
71946
+ if (compiledDir) addCandidate2(join13(compiledDir, stripped));
71947
+ addCandidate2(join13(baseDir, stripped));
71913
71948
  }
71914
71949
  }
71915
71950
  if (fromCompiled) addCandidate2(fromCompiled);
71916
71951
  addCandidate2(fromBase);
71917
71952
  }
71918
- return candidates.find(existsSync12) ?? join12(baseDir, cleanSrc);
71953
+ return candidates.find(existsSync12) ?? join13(baseDir, cleanSrc);
71919
71954
  }
71920
71955
  async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
71921
71956
  const startTime = Date.now();
@@ -71949,7 +71984,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
71949
71984
  videoPath = resolveProjectRelativeSrc(video.src, baseDir, compiledDir);
71950
71985
  }
71951
71986
  if (isHttpUrl(videoPath)) {
71952
- const downloadDir = join12(options.outputDir, "_downloads");
71987
+ const downloadDir = join13(options.outputDir, "_downloads");
71953
71988
  mkdirSync7(downloadDir, { recursive: true });
71954
71989
  videoPath = await downloadToTemp(videoPath, downloadDir);
71955
71990
  }
@@ -72143,7 +72178,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
72143
72178
  return sliceSupersetMember(
72144
72179
  member,
72145
72180
  superset,
72146
- join12(options.outputDir, work.video.id),
72181
+ join13(options.outputDir, work.video.id),
72147
72182
  options.fps
72148
72183
  );
72149
72184
  }
@@ -72159,7 +72194,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
72159
72194
  async function executeSupersetGroup(group) {
72160
72195
  const first = group.members[0]?.miss.work;
72161
72196
  if (!first) return [];
72162
- const tempDir = cacheRootDir ? join12(cacheRootDir, `${group.groupId}.partial-${process.pid}`) : join12(options.outputDir, group.groupId);
72197
+ const tempDir = cacheRootDir ? join13(cacheRootDir, `${group.groupId}.partial-${process.pid}`) : join13(options.outputDir, group.groupId);
72163
72198
  try {
72164
72199
  rmSync2(tempDir, { recursive: true, force: true });
72165
72200
  const superset = await extractVideoFramesRange(
@@ -73002,7 +73037,7 @@ var init_audioVolumeEnvelope = __esm({
73002
73037
 
73003
73038
  // ../engine/src/services/audioMixer.ts
73004
73039
  import { closeSync, existsSync as existsSync13, mkdirSync as mkdirSync8, mkdtempSync, openSync, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
73005
- import { isAbsolute as isAbsolute5, join as join13, dirname as dirname8 } from "path";
73040
+ import { isAbsolute as isAbsolute5, join as join14, dirname as dirname8 } from "path";
73006
73041
  function clampVolume(volume) {
73007
73042
  if (!Number.isFinite(volume)) return 1;
73008
73043
  return Math.max(0, Math.min(1, volume));
@@ -73264,8 +73299,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
73264
73299
  const runMix = (ignoreAutomation) => {
73265
73300
  const inputs = [];
73266
73301
  tracks.forEach((track) => inputs.push("-i", track.srcPath));
73267
- const scriptDir = mkdtempSync(join13(outputDir, ".filter-complex-"));
73268
- const scriptPath = join13(scriptDir, "graph.txt");
73302
+ const scriptDir = mkdtempSync(join14(outputDir, ".filter-complex-"));
73303
+ const scriptPath = join14(scriptDir, "graph.txt");
73269
73304
  const fd = openSync(scriptPath, "wx", 384);
73270
73305
  try {
73271
73306
  writeFileSync6(fd, buildFilterComplex(ignoreAutomation));
@@ -73364,7 +73399,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
73364
73399
  }
73365
73400
  let audioSrcPath = srcPath;
73366
73401
  if (element.type === "video") {
73367
- const extractedPath = join13(workDir, `${element.id}-extracted.wav`);
73402
+ const extractedPath = join14(workDir, `${element.id}-extracted.wav`);
73368
73403
  const extractResult = await extractAudioFromVideo(
73369
73404
  srcPath,
73370
73405
  extractedPath,
@@ -73381,7 +73416,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
73381
73416
  }
73382
73417
  audioSrcPath = extractedPath;
73383
73418
  } else {
73384
- const trimmedPath = join13(workDir, `${element.id}-trimmed.wav`);
73419
+ const trimmedPath = join14(workDir, `${element.id}-trimmed.wav`);
73385
73420
  const prepResult = await prepareAudioTrack(
73386
73421
  srcPath,
73387
73422
  trimmedPath,
@@ -73534,7 +73569,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
73534
73569
  import { cpus, freemem } from "os";
73535
73570
  import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync6 } from "fs";
73536
73571
  import { copyFile, rename } from "fs/promises";
73537
- import { join as join14 } from "path";
73572
+ import { join as join15 } from "path";
73538
73573
  function defaultSafeMaxWorkers() {
73539
73574
  return Math.max(6, Math.min(16, Math.floor(cpus().length / 8)));
73540
73575
  }
@@ -73613,7 +73648,7 @@ function distributeFrames(totalFrames, workerCount, workDir, rangeStart = 0) {
73613
73648
  workerId: i2,
73614
73649
  startFrame,
73615
73650
  endFrame,
73616
- outputDir: join14(workDir, `worker-${i2}`),
73651
+ outputDir: join15(workDir, `worker-${i2}`),
73617
73652
  outputFrameOffset: rangeStart
73618
73653
  });
73619
73654
  }
@@ -73751,8 +73786,8 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
73751
73786
  }
73752
73787
  const files = readdirSync6(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
73753
73788
  const copyTasks = files.map(async (file) => {
73754
- const sourcePath = join14(task.outputDir, file);
73755
- const targetPath = join14(outputDir, file);
73789
+ const sourcePath = join15(task.outputDir, file);
73790
+ const targetPath = join15(outputDir, file);
73756
73791
  try {
73757
73792
  await rename(sourcePath, targetPath);
73758
73793
  } catch {
@@ -73794,7 +73829,7 @@ var init_parallelCoordinator = __esm({
73794
73829
  import { Hono } from "hono";
73795
73830
  import { serve } from "@hono/node-server";
73796
73831
  import { readFileSync as readFileSync7, existsSync as existsSync15, statSync as statSync4 } from "fs";
73797
- import { join as join15, extname as extname5 } from "path";
73832
+ import { join as join16, extname as extname5 } from "path";
73798
73833
  function createFileServer(options) {
73799
73834
  const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
73800
73835
  const headScripts = options.headScripts ?? [];
@@ -73804,11 +73839,11 @@ function createFileServer(options) {
73804
73839
  let requestPath = c3.req.path;
73805
73840
  if (requestPath === "/") requestPath = "/index.html";
73806
73841
  const relativePath = requestPath.replace(/^\//, "");
73807
- const compiledPath = compiledDir ? join15(compiledDir, relativePath) : null;
73842
+ const compiledPath = compiledDir ? join16(compiledDir, relativePath) : null;
73808
73843
  const hasCompiledFile = Boolean(
73809
73844
  compiledPath && existsSync15(compiledPath) && statSync4(compiledPath).isFile()
73810
73845
  );
73811
- const filePath = hasCompiledFile ? compiledPath : join15(projectDir, relativePath);
73846
+ const filePath = hasCompiledFile ? compiledPath : join16(projectDir, relativePath);
73812
73847
  if (!existsSync15(filePath) || !statSync4(filePath).isFile()) {
73813
73848
  return c3.text("Not found", 404);
73814
73849
  }
@@ -75123,7 +75158,7 @@ var init_shaderTransitions = __esm({
75123
75158
 
75124
75159
  // ../engine/src/services/hdrCapture.ts
75125
75160
  import { existsSync as existsSync16, readdirSync as readdirSync7 } from "fs";
75126
- import { join as join16 } from "path";
75161
+ import { join as join17 } from "path";
75127
75162
  import { homedir as homedir3 } from "os";
75128
75163
  function linearToPQ(L2) {
75129
75164
  const Lp = Math.max(0, L2 * SDR_NITS / PQ_MAX_NITS);
@@ -75239,12 +75274,12 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
75239
75274
  return output;
75240
75275
  }
75241
75276
  function resolveHeadedChromePath() {
75242
- const baseDir = join16(homedir3(), ".cache", "puppeteer", "chrome");
75277
+ const baseDir = join17(homedir3(), ".cache", "puppeteer", "chrome");
75243
75278
  if (!existsSync16(baseDir)) return void 0;
75244
75279
  const versions = readdirSync7(baseDir).sort().reverse();
75245
75280
  for (const version2 of versions) {
75246
75281
  const candidates = [
75247
- join16(
75282
+ join17(
75248
75283
  baseDir,
75249
75284
  version2,
75250
75285
  "chrome-mac-arm64",
@@ -75253,7 +75288,7 @@ function resolveHeadedChromePath() {
75253
75288
  "MacOS",
75254
75289
  "Google Chrome for Testing"
75255
75290
  ),
75256
- join16(
75291
+ join17(
75257
75292
  baseDir,
75258
75293
  version2,
75259
75294
  "chrome-mac-x64",
@@ -75262,8 +75297,8 @@ function resolveHeadedChromePath() {
75262
75297
  "MacOS",
75263
75298
  "Google Chrome for Testing"
75264
75299
  ),
75265
- join16(baseDir, version2, "chrome-linux64", "chrome"),
75266
- join16(baseDir, version2, "chrome-win64", "chrome.exe")
75300
+ join17(baseDir, version2, "chrome-linux64", "chrome"),
75301
+ join17(baseDir, version2, "chrome-win64", "chrome.exe")
75267
75302
  ];
75268
75303
  for (const binary of candidates) {
75269
75304
  if (existsSync16(binary)) return binary;
@@ -78349,11 +78384,11 @@ var init_banner = __esm({
78349
78384
 
78350
78385
  // src/registry/remote.ts
78351
78386
  import { mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
78352
- import { join as join17, dirname as dirname9 } from "path";
78387
+ import { join as join18, dirname as dirname9 } from "path";
78353
78388
  import { homedir as homedir4 } from "os";
78354
78389
  function cachePath(baseUrl, key2) {
78355
78390
  const slug = baseUrl.replace(/[^a-zA-Z0-9]/g, "_");
78356
- return join17(CACHE_DIR, `${slug}__${key2}.json`);
78391
+ return join18(CACHE_DIR, `${slug}__${key2}.json`);
78357
78392
  }
78358
78393
  function readCache(path2) {
78359
78394
  try {
@@ -78424,7 +78459,7 @@ var init_remote = __esm({
78424
78459
  init_dist3();
78425
78460
  DEFAULT_REGISTRY_URL = "https://raw.githubusercontent.com/heygen-com/hyperframes/main/registry";
78426
78461
  FETCH_TIMEOUT_MS = 1e4;
78427
- CACHE_DIR = join17(homedir4(), ".hyperframes", "cache");
78462
+ CACHE_DIR = join18(homedir4(), ".hyperframes", "cache");
78428
78463
  CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
78429
78464
  }
78430
78465
  });
@@ -78702,7 +78737,7 @@ var init_compatibility = __esm({
78702
78737
 
78703
78738
  // src/templates/remote.ts
78704
78739
  import { existsSync as existsSync19 } from "fs";
78705
- import { join as join18 } from "path";
78740
+ import { join as join19 } from "path";
78706
78741
  async function fetchRemoteTemplate(templateId, destDir) {
78707
78742
  const items = await resolveItemWithDependencies(templateId);
78708
78743
  const warnings = gateRegistryItemsCompatibility(items);
@@ -78713,7 +78748,7 @@ async function fetchRemoteTemplate(templateId, destDir) {
78713
78748
  for (const item of items) {
78714
78749
  await installItem(item, { destDir });
78715
78750
  }
78716
- if (!existsSync19(join18(destDir, "index.html"))) {
78751
+ if (!existsSync19(join19(destDir, "index.html"))) {
78717
78752
  throw new Error(
78718
78753
  `Example "${templateId}" installed but missing index.html. The registry item may be malformed.`
78719
78754
  );
@@ -79072,7 +79107,7 @@ __export(manager_exports, {
79072
79107
  import { execFileSync as execFileSync3 } from "child_process";
79073
79108
  import { existsSync as existsSync22, mkdirSync as mkdirSync11, rmSync as rmSync4 } from "fs";
79074
79109
  import { homedir as homedir5, platform as platform4 } from "os";
79075
- import { join as join19 } from "path";
79110
+ import { join as join20 } from "path";
79076
79111
  function isWhisperUnavailable(err) {
79077
79112
  if (err instanceof WhisperUnavailableError) return true;
79078
79113
  return err instanceof Error && "code" in err && err.code === "WHISPER_UNAVAILABLE";
@@ -79115,8 +79150,8 @@ function findFromSystem() {
79115
79150
  }
79116
79151
  function findBuiltBinary() {
79117
79152
  for (const p2 of [
79118
- join19(BUILD_DIR, "build", "bin", "whisper-cli"),
79119
- join19(BUILD_DIR, "build", "whisper-cli")
79153
+ join20(BUILD_DIR, "build", "bin", "whisper-cli"),
79154
+ join20(BUILD_DIR, "build", "whisper-cli")
79120
79155
  ]) {
79121
79156
  if (existsSync22(p2)) return { executablePath: p2, source: "build" };
79122
79157
  }
@@ -79128,7 +79163,7 @@ function buildFromSource(onProgress) {
79128
79163
  }
79129
79164
  if (!existsSync22(BUILD_DIR)) {
79130
79165
  onProgress?.("Downloading whisper.cpp...");
79131
- mkdirSync11(join19(homedir5(), ".cache", "hyperframes", "whisper"), {
79166
+ mkdirSync11(join20(homedir5(), ".cache", "hyperframes", "whisper"), {
79132
79167
  recursive: true
79133
79168
  });
79134
79169
  execFileSync3("git", ["clone", "--depth", "1", WHISPER_REPO, BUILD_DIR], {
@@ -79213,7 +79248,7 @@ async function ensureWhisper(options) {
79213
79248
  throw new WhisperUnavailableError(`whisper-cpp not found. Install: ${getInstallInstructions()}`);
79214
79249
  }
79215
79250
  async function ensureModel(model = DEFAULT_MODEL, options) {
79216
- const modelPath2 = join19(MODELS_DIR, `ggml-${model}.bin`);
79251
+ const modelPath2 = join20(MODELS_DIR, `ggml-${model}.bin`);
79217
79252
  if (existsSync22(modelPath2)) return modelPath2;
79218
79253
  mkdirSync11(MODELS_DIR, { recursive: true });
79219
79254
  options?.onProgress?.(`Downloading model ${model}...`);
@@ -79232,7 +79267,7 @@ var init_manager = __esm({
79232
79267
  "use strict";
79233
79268
  init_ffmpeg();
79234
79269
  init_download();
79235
- MODELS_DIR = join19(homedir5(), ".cache", "hyperframes", "whisper", "models");
79270
+ MODELS_DIR = join20(homedir5(), ".cache", "hyperframes", "whisper", "models");
79236
79271
  DEFAULT_MODEL = "small.en";
79237
79272
  WhisperUnavailableError = class extends Error {
79238
79273
  code = "WHISPER_UNAVAILABLE";
@@ -79241,7 +79276,7 @@ var init_manager = __esm({
79241
79276
  this.name = "WhisperUnavailableError";
79242
79277
  }
79243
79278
  };
79244
- BUILD_DIR = join19(homedir5(), ".cache", "hyperframes", "whisper", "whisper.cpp");
79279
+ BUILD_DIR = join20(homedir5(), ".cache", "hyperframes", "whisper", "whisper.cpp");
79245
79280
  WHISPER_REPO = "https://github.com/ggml-org/whisper.cpp.git";
79246
79281
  }
79247
79282
  });
@@ -79258,7 +79293,7 @@ __export(normalize_exports, {
79258
79293
  wordsToCues: () => wordsToCues
79259
79294
  });
79260
79295
  import { readFileSync as readFileSync14, readdirSync as readdirSync8, writeFileSync as writeFileSync9 } from "fs";
79261
- import { extname as extname6, join as join20 } from "path";
79296
+ import { extname as extname6, join as join21 } from "path";
79262
79297
  function detectFormat(filePath) {
79263
79298
  const ext = extname6(filePath).toLowerCase();
79264
79299
  if (ext === ".srt") return "srt";
@@ -79535,7 +79570,7 @@ function patchCaptionHtml(dir, words) {
79535
79570
  const wordsJson = JSON.stringify(words, null, 2).replace(/\n/g, "\n ");
79536
79571
  let htmlFiles;
79537
79572
  try {
79538
- htmlFiles = readdirSync8(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join20(e3.parentPath, e3.name));
79573
+ htmlFiles = readdirSync8(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join21(e3.parentPath, e3.name));
79539
79574
  } catch {
79540
79575
  return;
79541
79576
  }
@@ -79576,9 +79611,9 @@ __export(projectConfig_exports, {
79576
79611
  writeProjectConfig: () => writeProjectConfig
79577
79612
  });
79578
79613
  import { readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "fs";
79579
- import { join as join21, resolve as resolve12 } from "path";
79614
+ import { join as join22, resolve as resolve12 } from "path";
79580
79615
  function projectConfigPath(projectDir) {
79581
- return join21(resolve12(projectDir), PROJECT_CONFIG_FILENAME);
79616
+ return join22(resolve12(projectDir), PROJECT_CONFIG_FILENAME);
79582
79617
  }
79583
79618
  function readProjectConfig(projectDir) {
79584
79619
  const path2 = projectConfigPath(projectDir);
@@ -79754,14 +79789,14 @@ import { execFile } from "child_process";
79754
79789
  import { createHash as createHash3 } from "crypto";
79755
79790
  import { existsSync as existsSync23, readdirSync as readdirSync9, readFileSync as readFileSync16, statSync as statSync6 } from "fs";
79756
79791
  import { homedir as homedir6 } from "os";
79757
- import { isAbsolute as isAbsolute7, join as join22, relative as relative5, resolve as resolve13, sep as sep4 } from "path";
79792
+ import { isAbsolute as isAbsolute7, join as join23, relative as relative5, resolve as resolve13, sep as sep4 } from "path";
79758
79793
  import { promisify } from "util";
79759
79794
  function listFilesSorted(dir) {
79760
79795
  const out = [];
79761
79796
  const walk = (d2) => {
79762
79797
  for (const name of readdirSync9(d2)) {
79763
79798
  if (name === ".DS_Store") continue;
79764
- const p2 = join22(d2, name);
79799
+ const p2 = join23(d2, name);
79765
79800
  if (statSync6(p2).isDirectory()) walk(p2);
79766
79801
  else out.push(p2);
79767
79802
  }
@@ -79785,9 +79820,9 @@ function hashSkillBundle(skillDir) {
79785
79820
  return { hash: h3.digest("hex").slice(0, 16), files: files.length };
79786
79821
  }
79787
79822
  function buildManifest(skillsRoot, meta) {
79788
- const names = readdirSync9(skillsRoot).filter((n2) => existsSync23(join22(skillsRoot, n2, "SKILL.md"))).sort();
79823
+ const names = readdirSync9(skillsRoot).filter((n2) => existsSync23(join23(skillsRoot, n2, "SKILL.md"))).sort();
79789
79824
  const skills = {};
79790
- for (const name of names) skills[name] = hashSkillBundle(join22(skillsRoot, name));
79825
+ for (const name of names) skills[name] = hashSkillBundle(join23(skillsRoot, name));
79791
79826
  return { source: meta.source, skills };
79792
79827
  }
79793
79828
  function agentLabel(hostDir) {
@@ -79809,12 +79844,12 @@ function listSubdirs(dir) {
79809
79844
  function discoverSkillRoots(base2, scope) {
79810
79845
  const candidates = [];
79811
79846
  const add2 = (hostBase, host) => {
79812
- const dir = join22(hostBase, host, "skills");
79847
+ const dir = join23(hostBase, host, "skills");
79813
79848
  if (existsSync23(dir) && statSync6(dir).isDirectory())
79814
79849
  candidates.push({ dir, agent: agentLabel(host), scope });
79815
79850
  };
79816
79851
  for (const host of listSubdirs(base2)) add2(base2, host);
79817
- const xdg = join22(base2, ".config");
79852
+ const xdg = join23(base2, ".config");
79818
79853
  for (const host of listSubdirs(xdg)) add2(xdg, host);
79819
79854
  return candidates.sort((a, b2) => {
79820
79855
  if (a.agent !== b2.agent) {
@@ -79848,15 +79883,15 @@ function locateInstall(skillNames, opts = {}) {
79848
79883
  ...discoverSkillRoots(opts.cwd ?? process.cwd(), "project")
79849
79884
  ];
79850
79885
  for (const root of roots) {
79851
- if (skillNames.some((n2) => existsSync23(join22(root.dir, n2, "SKILL.md")))) return root;
79886
+ if (skillNames.some((n2) => existsSync23(join23(root.dir, n2, "SKILL.md")))) return root;
79852
79887
  }
79853
79888
  return null;
79854
79889
  }
79855
79890
  function hashInstalled(root, skillNames) {
79856
79891
  const out = {};
79857
79892
  for (const name of skillNames) {
79858
- const skillDir = join22(root.dir, name);
79859
- if (existsSync23(join22(skillDir, "SKILL.md"))) out[name] = hashSkillBundle(skillDir);
79893
+ const skillDir = join23(root.dir, name);
79894
+ if (existsSync23(join23(skillDir, "SKILL.md"))) out[name] = hashSkillBundle(skillDir);
79860
79895
  }
79861
79896
  return out;
79862
79897
  }
@@ -79897,10 +79932,10 @@ function skillsAttributedToSource(lock, source) {
79897
79932
  return Object.entries(lock.skills).filter(([, e3]) => repoSlug(e3.source) === want || repoSlug(e3.sourceUrl) === want).map(([name]) => name);
79898
79933
  }
79899
79934
  function lockPathForScope(scope, opts) {
79900
- if (scope === "project") return join22(opts.cwd ?? process.cwd(), "skills-lock.json");
79935
+ if (scope === "project") return join23(opts.cwd ?? process.cwd(), "skills-lock.json");
79901
79936
  const xdgStateHome = process.env.XDG_STATE_HOME;
79902
- if (xdgStateHome) return join22(xdgStateHome, "skills", ".skill-lock.json");
79903
- return join22(opts.home ?? homedir6(), ".agents", ".skill-lock.json");
79937
+ if (xdgStateHome) return join23(xdgStateHome, "skills", ".skill-lock.json");
79938
+ return join23(opts.home ?? homedir6(), ".agents", ".skill-lock.json");
79904
79939
  }
79905
79940
  function readSkillLock(path2) {
79906
79941
  try {
@@ -79921,9 +79956,9 @@ function detectRemoved(root, latest, opts) {
79921
79956
  function findRepoManifest(cwd = process.cwd()) {
79922
79957
  let dir = cwd;
79923
79958
  for (let i2 = 0; i2 < 16; i2++) {
79924
- const p2 = join22(dir, MANIFEST_FILE);
79959
+ const p2 = join23(dir, MANIFEST_FILE);
79925
79960
  if (existsSync23(p2)) return p2;
79926
- const parent = join22(dir, "..");
79961
+ const parent = join23(dir, "..");
79927
79962
  if (parent === dir) break;
79928
79963
  dir = parent;
79929
79964
  }
@@ -79961,9 +79996,9 @@ async function remoteHeadSha(repoSlug2) {
79961
79996
  }
79962
79997
  }
79963
79998
  function resolveLocalManifest(source) {
79964
- const direct = source.endsWith(".json") ? source : join22(source, MANIFEST_FILE);
79999
+ const direct = source.endsWith(".json") ? source : join23(source, MANIFEST_FILE);
79965
80000
  if (existsSync23(direct)) return JSON.parse(readFileSync16(direct, "utf8"));
79966
- const skillsRoot = source.endsWith("skills") ? source : join22(source, "skills");
80001
+ const skillsRoot = source.endsWith("skills") ? source : join23(source, "skills");
79967
80002
  if (existsSync23(skillsRoot)) return buildManifest(skillsRoot, { source: skillsRoot });
79968
80003
  throw new Error(`No skills manifest found at: ${source}`);
79969
80004
  }
@@ -80122,22 +80157,22 @@ var init_agentDirs_generated = __esm({
80122
80157
  // src/utils/skillsMirror.ts
80123
80158
  import { cpSync, existsSync as existsSync24, mkdirSync as mkdirSync12, readdirSync as readdirSync10, rmSync as rmSync5, symlinkSync } from "fs";
80124
80159
  import { homedir as homedir7 } from "os";
80125
- import { dirname as dirname10, isAbsolute as isAbsolute8, join as join23, relative as relative6 } from "path";
80160
+ import { dirname as dirname10, isAbsolute as isAbsolute8, join as join24, relative as relative6 } from "path";
80126
80161
  function resolveBases(home, env) {
80127
80162
  const xdg = env["XDG_CONFIG_HOME"]?.trim();
80128
80163
  return {
80129
80164
  home,
80130
- configHome: xdg && isAbsolute8(xdg) ? xdg : join23(home, ".config"),
80131
- codexHome: env["CODEX_HOME"]?.trim() || join23(home, ".codex"),
80132
- claudeHome: env["CLAUDE_CONFIG_DIR"]?.trim() || join23(home, ".claude"),
80133
- vibeHome: env["VIBE_HOME"]?.trim() || join23(home, ".vibe"),
80134
- hermesHome: env["HERMES_HOME"]?.trim() || join23(home, ".hermes"),
80135
- autohandHome: env["AUTOHAND_HOME"]?.trim() || join23(home, ".autohand")
80165
+ configHome: xdg && isAbsolute8(xdg) ? xdg : join24(home, ".config"),
80166
+ codexHome: env["CODEX_HOME"]?.trim() || join24(home, ".codex"),
80167
+ claudeHome: env["CLAUDE_CONFIG_DIR"]?.trim() || join24(home, ".claude"),
80168
+ vibeHome: env["VIBE_HOME"]?.trim() || join24(home, ".vibe"),
80169
+ hermesHome: env["HERMES_HOME"]?.trim() || join24(home, ".hermes"),
80170
+ autohandHome: env["AUTOHAND_HOME"]?.trim() || join24(home, ".autohand")
80136
80171
  };
80137
80172
  }
80138
80173
  function listSkillDirs(store) {
80139
80174
  return readdirSync10(store, { withFileTypes: true }).filter(
80140
- (e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync24(join23(store, e3.name, "SKILL.md"))
80175
+ (e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync24(join24(store, e3.name, "SKILL.md"))
80141
80176
  ).map((e3) => e3.name);
80142
80177
  }
80143
80178
  function linkOrCopy(sourceSkill, targetSkill, platform10) {
@@ -80156,7 +80191,7 @@ function mirrorInto(targetDir, source, skills, platform10) {
80156
80191
  }
80157
80192
  for (const skill of skills) {
80158
80193
  try {
80159
- linkOrCopy(join23(source, skill), join23(targetDir, skill), platform10);
80194
+ linkOrCopy(join24(source, skill), join24(targetDir, skill), platform10);
80160
80195
  } catch {
80161
80196
  }
80162
80197
  }
@@ -80166,15 +80201,15 @@ function mirrorGlobalSkills(opts) {
80166
80201
  const home = opts.home ?? homedir7();
80167
80202
  const platform10 = opts.platform ?? process.platform;
80168
80203
  const bases = resolveBases(home, opts.env ?? process.env);
80169
- const source = join23(bases.claudeHome, "skills");
80170
- const universalStore = join23(home, ".agents", "skills");
80204
+ const source = join24(bases.claudeHome, "skills");
80205
+ const universalStore = join24(home, ".agents", "skills");
80171
80206
  if (!existsSync24(source)) return { source: null, mirrored: [] };
80172
80207
  const allowed = new Set(opts.skills);
80173
80208
  const skills = listSkillDirs(source).filter((name) => allowed.has(name));
80174
80209
  if (skills.length === 0) return { source, mirrored: [] };
80175
80210
  const mirrored = [];
80176
80211
  for (const { agent, base: base2, sub } of AGENT_GLOBAL_DIRS) {
80177
- const targetDir = join23(bases[base2], ...sub.split("/").filter(Boolean));
80212
+ const targetDir = join24(bases[base2], ...sub.split("/").filter(Boolean));
80178
80213
  if (targetDir === source || targetDir === universalStore) continue;
80179
80214
  if (!existsSync24(dirname10(targetDir))) continue;
80180
80215
  if (mirrorInto(targetDir, source, skills, platform10)) mirrored.push({ agent, dir: targetDir });
@@ -80484,7 +80519,7 @@ __export(transcribe_exports, {
80484
80519
  });
80485
80520
  import { execFileSync as execFileSync5 } from "child_process";
80486
80521
  import { existsSync as existsSync25, readFileSync as readFileSync17, mkdirSync as mkdirSync13, unlinkSync as unlinkSync2 } from "fs";
80487
- import { join as join24, extname as extname7 } from "path";
80522
+ import { join as join25, extname as extname7 } from "path";
80488
80523
  import { tmpdir as tmpdir2 } from "os";
80489
80524
  import { randomUUID as randomUUID3 } from "crypto";
80490
80525
  function detectLanguage(whisperPath, modelPath2, wavPath) {
@@ -80564,7 +80599,7 @@ function isVideoFile(filePath) {
80564
80599
  return VIDEO_EXTENSIONS.has(extname7(filePath).toLowerCase());
80565
80600
  }
80566
80601
  function tempWavPath() {
80567
- return join24(tmpdir2(), `hyperframes-audio-${process.pid}-${randomUUID3()}.wav`);
80602
+ return join25(tmpdir2(), `hyperframes-audio-${process.pid}-${randomUUID3()}.wav`);
80568
80603
  }
80569
80604
  function extractAudio(videoPath) {
80570
80605
  const ffmpegPath = findFFmpeg();
@@ -80655,7 +80690,7 @@ async function transcribe(inputPath, outputDir, options) {
80655
80690
  effectiveModel = multilingualModel;
80656
80691
  }
80657
80692
  options?.onProgress?.("Transcribing...");
80658
- const outputBase = join24(outputDir, "transcript");
80693
+ const outputBase = join25(outputDir, "transcript");
80659
80694
  mkdirSync13(outputDir, { recursive: true });
80660
80695
  const whisperArgs = [
80661
80696
  "--model",
@@ -88351,7 +88386,7 @@ var init_hfIds = __esm({
88351
88386
  import { execFileSync as execFileSync6 } from "child_process";
88352
88387
  import { existsSync as existsSync29, lstatSync as lstatSync2, readdirSync as readdirSync11, realpathSync as realpathSync3 } from "fs";
88353
88388
  import { homedir as homedir8, platform as platform5 } from "os";
88354
- import { join as join25, resolve as resolve18 } from "path";
88389
+ import { join as join26, resolve as resolve18 } from "path";
88355
88390
  function getAllowedFontDirs() {
88356
88391
  if (allowedDirsCache)
88357
88392
  return allowedDirsCache;
@@ -88420,7 +88455,7 @@ function fontDirectories() {
88420
88455
  const home = homedir8();
88421
88456
  if (platform5() === "darwin") {
88422
88457
  return [
88423
- join25(home, "Library", "Fonts"),
88458
+ join26(home, "Library", "Fonts"),
88424
88459
  "/Library/Fonts",
88425
88460
  "/System/Library/Fonts",
88426
88461
  "/System/Library/Fonts/Supplemental"
@@ -88428,13 +88463,13 @@ function fontDirectories() {
88428
88463
  }
88429
88464
  if (platform5() === "win32") {
88430
88465
  return [
88431
- join25(process.env.WINDIR || "C:\\Windows", "Fonts"),
88432
- join25(process.env.LOCALAPPDATA || join25(homedir8(), "AppData", "Local"), "Microsoft", "Windows", "Fonts")
88466
+ join26(process.env.WINDIR || "C:\\Windows", "Fonts"),
88467
+ join26(process.env.LOCALAPPDATA || join26(homedir8(), "AppData", "Local"), "Microsoft", "Windows", "Fonts")
88433
88468
  ];
88434
88469
  }
88435
88470
  return [
88436
- join25(home, ".fonts"),
88437
- join25(home, ".local", "share", "fonts"),
88471
+ join26(home, ".fonts"),
88472
+ join26(home, ".local", "share", "fonts"),
88438
88473
  "/usr/local/share/fonts",
88439
88474
  "/usr/share/fonts"
88440
88475
  ];
@@ -88445,7 +88480,7 @@ function collectFontFileEntries(dir, depth = 0) {
88445
88480
  const entries2 = [];
88446
88481
  try {
88447
88482
  for (const entry of readdirSync11(dir, { withFileTypes: true })) {
88448
- const fullPath = join25(dir, entry.name);
88483
+ const fullPath = join26(dir, entry.name);
88449
88484
  if (entry.isDirectory()) {
88450
88485
  entries2.push(...collectFontFileEntries(fullPath, depth + 1));
88451
88486
  continue;
@@ -91256,8 +91291,8 @@ var init_gsapParser = __esm({
91256
91291
  // ../studio-server/dist/index.js
91257
91292
  import { Hono as Hono2 } from "hono";
91258
91293
  import { readFile } from "fs/promises";
91259
- import { join as join26 } from "path";
91260
91294
  import { join as join27 } from "path";
91295
+ import { join as join28 } from "path";
91261
91296
  import { readdirSync as readdirSync12 } from "fs";
91262
91297
  import { existsSync as existsSync30, readFileSync as readFileSync19 } from "fs";
91263
91298
  import { bodyLimit } from "hono/body-limit";
@@ -91302,7 +91337,7 @@ import { join as join112 } from "path";
91302
91337
  import { createHash as createHash22 } from "crypto";
91303
91338
  import { existsSync as existsSync82, readFileSync as readFileSync112, writeFileSync as writeFileSync72, mkdirSync as mkdirSync62 } from "fs";
91304
91339
  import { join as join122 } from "path";
91305
- import { closeSync as closeSync2, constants, fstatSync, openSync as openSync2, readSync } from "fs";
91340
+ import { closeSync as closeSync2, constants as constants2, fstatSync, openSync as openSync2, readSync } from "fs";
91306
91341
  function shouldIgnoreDir(rel) {
91307
91342
  return rel === ".hyperframes/backup";
91308
91343
  }
@@ -91316,7 +91351,7 @@ function walkDir(dir, prefix = "") {
91316
91351
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
91317
91352
  if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel)) continue;
91318
91353
  if (entry.isDirectory()) {
91319
- files.push(...walkDir(join27(dir, entry.name), rel));
91354
+ files.push(...walkDir(join28(dir, entry.name), rel));
91320
91355
  } else {
91321
91356
  files.push(rel);
91322
91357
  }
@@ -91328,7 +91363,7 @@ async function filterCompositionFiles(projectDir, files) {
91328
91363
  const checks = await Promise.all(
91329
91364
  htmlFiles.map(async (f3) => {
91330
91365
  try {
91331
- const content = await readFile(join26(projectDir, f3), "utf-8");
91366
+ const content = await readFile(join27(projectDir, f3), "utf-8");
91332
91367
  return COMPOSITION_ID_RE.test(content);
91333
91368
  } catch {
91334
91369
  return false;
@@ -95121,7 +95156,7 @@ function registerFontRoutes(api) {
95121
95156
  if (!located) return c3.json({ error: "font not found" }, 404);
95122
95157
  let fd;
95123
95158
  try {
95124
- fd = openSync2(located.path, constants.O_RDONLY | constants.O_NOFOLLOW);
95159
+ fd = openSync2(located.path, constants2.O_RDONLY | constants2.O_NOFOLLOW);
95125
95160
  } catch {
95126
95161
  return c3.json({ error: "font file not accessible" }, 404);
95127
95162
  }
@@ -95535,7 +95570,7 @@ import { execSync as execSync5, spawnSync as spawnSync2 } from "child_process";
95535
95570
  import { existsSync as existsSync31, mkdirSync as mkdirSync15, readdirSync as readdirSync13, rmSync as rmSync7, statSync as statSync9 } from "fs";
95536
95571
  import { basename as basename4 } from "path";
95537
95572
  import { homedir as homedir9 } from "os";
95538
- import { join as join28 } from "path";
95573
+ import { join as join29 } from "path";
95539
95574
  async function loadPuppeteerBrowsers() {
95540
95575
  try {
95541
95576
  return await import("@puppeteer/browsers");
@@ -95690,15 +95725,15 @@ function findFromPuppeteerCache() {
95690
95725
  }
95691
95726
  for (const version2 of versions) {
95692
95727
  const candidates = [
95693
- join28(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-linux64", "chrome-headless-shell"),
95694
- join28(
95728
+ join29(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-linux64", "chrome-headless-shell"),
95729
+ join29(
95695
95730
  PUPPETEER_CACHE_DIR,
95696
95731
  version2,
95697
95732
  "chrome-headless-shell-mac-arm64",
95698
95733
  "chrome-headless-shell"
95699
95734
  ),
95700
- join28(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-mac-x64", "chrome-headless-shell"),
95701
- join28(
95735
+ join29(PUPPETEER_CACHE_DIR, version2, "chrome-headless-shell-mac-x64", "chrome-headless-shell"),
95736
+ join29(
95702
95737
  PUPPETEER_CACHE_DIR,
95703
95738
  version2,
95704
95739
  "chrome-headless-shell-win64",
@@ -95877,11 +95912,11 @@ var init_manager2 = __esm({
95877
95912
  "use strict";
95878
95913
  init_errorMessage();
95879
95914
  CHROME_VERSION = "131.0.6778.85";
95880
- CACHE_ROOT_DIR = join28(homedir9(), ".cache", "hyperframes");
95881
- CACHE_DIR2 = join28(homedir9(), ".cache", "hyperframes", "chrome");
95882
- PUPPETEER_CACHE_DIR = join28(homedir9(), ".cache", "puppeteer", "chrome-headless-shell");
95883
- INSTALL_LOCK_DIR = join28(CACHE_ROOT_DIR, ".chrome.install.lock");
95884
- INSTALL_RECLAIM_LOCK_DIR = join28(CACHE_ROOT_DIR, ".chrome.install.reclaim.lock");
95915
+ CACHE_ROOT_DIR = join29(homedir9(), ".cache", "hyperframes");
95916
+ CACHE_DIR2 = join29(homedir9(), ".cache", "hyperframes", "chrome");
95917
+ PUPPETEER_CACHE_DIR = join29(homedir9(), ".cache", "puppeteer", "chrome-headless-shell");
95918
+ INSTALL_LOCK_DIR = join29(CACHE_ROOT_DIR, ".chrome.install.lock");
95919
+ INSTALL_RECLAIM_LOCK_DIR = join29(CACHE_ROOT_DIR, ".chrome.install.reclaim.lock");
95885
95920
  INSTALL_LOCK_TIMEOUT_MS = 12e4;
95886
95921
  INSTALL_LOCK_POLL_MS = 200;
95887
95922
  SYSTEM_CHROME_PATHS = process.platform === "darwin" ? ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"] : [
@@ -99166,7 +99201,7 @@ __export(deterministicFonts_exports, {
99166
99201
  import { createHash as createHash6 } from "crypto";
99167
99202
  import { existsSync as existsSync33, mkdirSync as mkdirSync16, readFileSync as readFileSync20, writeFileSync as writeFileSync12 } from "fs";
99168
99203
  import { homedir as homedir10, tmpdir as tmpdir4 } from "os";
99169
- import { join as join29 } from "path";
99204
+ import { join as join30 } from "path";
99170
99205
  import postcss4 from "postcss";
99171
99206
  function parseFontFamilyValue(value) {
99172
99207
  return value.split(",").map((piece) => piece.trim().replace(/^['"]/, "").replace(/['"]$/, "").trim()).filter((piece) => piece.length > 0);
@@ -99483,13 +99518,13 @@ function warnUnresolvedFonts(unresolved) {
99483
99518
  );
99484
99519
  }
99485
99520
  function resolveFontCacheRoot() {
99486
- return process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ? join29(tmpdir4(), "hyperframes", "fonts") : join29(homedir10(), ".cache", "hyperframes", "fonts"));
99521
+ return process.env.HYPERFRAMES_FONT_CACHE_DIR ?? (process.env.AWS_LAMBDA_FUNCTION_NAME ? join30(tmpdir4(), "hyperframes", "fonts") : join30(homedir10(), ".cache", "hyperframes", "fonts"));
99487
99522
  }
99488
99523
  function fontSlug(familyName) {
99489
99524
  return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
99490
99525
  }
99491
99526
  function fontCacheDir(slug) {
99492
- const dir = join29(GOOGLE_FONTS_CACHE_DIR, slug);
99527
+ const dir = join30(GOOGLE_FONTS_CACHE_DIR, slug);
99493
99528
  if (!existsSync33(dir)) {
99494
99529
  mkdirSync16(dir, { recursive: true });
99495
99530
  }
@@ -99499,7 +99534,7 @@ function subsetToken(woff2Url) {
99499
99534
  return createHash6("sha1").update(woff2Url).digest("hex").slice(0, 12);
99500
99535
  }
99501
99536
  function cachedWoff2Path(slug, weight, style, subset) {
99502
- return join29(fontCacheDir(slug), `${weight}-${style}-${subset}.woff2`);
99537
+ return join30(fontCacheDir(slug), `${weight}-${style}-${subset}.woff2`);
99503
99538
  }
99504
99539
  function fontFetchError(familyName, url, what, cause) {
99505
99540
  const reason = "status" in cause ? `returned HTTP ${cause.status}` : `failed: ${cause.error.message}`;
@@ -99784,7 +99819,7 @@ import {
99784
99819
  rmSync as rmSync8,
99785
99820
  statSync as statSync10
99786
99821
  } from "fs";
99787
- import { dirname as dirname13, isAbsolute as isAbsolute10, join as join30, resolve as resolve20 } from "path";
99822
+ import { dirname as dirname13, isAbsolute as isAbsolute10, join as join31, resolve as resolve20 } from "path";
99788
99823
  function splitUrlSuffix2(src) {
99789
99824
  const queryIdx = src.indexOf("?");
99790
99825
  const hashIdx = src.indexOf("#");
@@ -100031,7 +100066,7 @@ function replaceImageWithVideo(input2) {
100031
100066
  return video;
100032
100067
  }
100033
100068
  async function prepareAnimatedGifInputs(html, options) {
100034
- const outputDir = options.outputDir ?? join30(options.downloadDir, PREPARED_GIF_SUBDIR);
100069
+ const outputDir = options.outputDir ?? join31(options.downloadDir, PREPARED_GIF_SUBDIR);
100035
100070
  const outputSrcPrefix = normalizeRelPath(options.outputSrcPrefix ?? PREPARED_GIF_SUBDIR);
100036
100071
  const cacheDir = options.cacheDir ?? outputDir;
100037
100072
  const { document: document2 } = parseHTML(html);
@@ -100053,8 +100088,8 @@ async function prepareAnimatedGifInputs(html, options) {
100053
100088
  const { loopIterations, padSeconds } = resolvePreparedPlayback(metadata, loop, windowSeconds);
100054
100089
  const hash2 = computePreparedGifHash(bytes, loopIterations, padSeconds);
100055
100090
  const filename = `${CACHE_SCHEMA}-${hash2.slice(0, 24)}.webm`;
100056
- const cachePath2 = join30(cacheDir, filename);
100057
- const outputPath = join30(outputDir, filename);
100091
+ const cachePath2 = join31(cacheDir, filename);
100092
+ const outputPath = join31(outputDir, filename);
100058
100093
  const outputSrc = `${outputSrcPrefix}/${filename}`;
100059
100094
  await ensurePreparedWebm({
100060
100095
  sourcePath,
@@ -100197,7 +100232,7 @@ import { serve as serve2 } from "@hono/node-server";
100197
100232
  import { existsSync as existsSync36, realpathSync as realpathSync4, statSync as statSync11, createReadStream } from "fs";
100198
100233
  import { readFile as readFile2 } from "fs/promises";
100199
100234
  import { Readable as Readable2 } from "stream";
100200
- import { join as join31, extname as extname9, resolve as resolve23, sep as sep5 } from "path";
100235
+ import { join as join33, extname as extname9, resolve as resolve23, sep as sep5 } from "path";
100201
100236
  function isPathInside2(child, parent, options = {}) {
100202
100237
  const { resolveSymlinks = false, pathModule } = options;
100203
100238
  const resolveFn = pathModule?.resolve ?? resolve23;
@@ -100541,13 +100576,13 @@ function createFileServer2(options) {
100541
100576
  }).join("/");
100542
100577
  let filePath = null;
100543
100578
  if (compiledDir) {
100544
- const candidate = join31(compiledDir, relativePath);
100579
+ const candidate = join33(compiledDir, relativePath);
100545
100580
  if (existsSync36(candidate) && isPathInside2(candidate, compiledDir) && statSync11(candidate).isFile()) {
100546
100581
  filePath = candidate;
100547
100582
  }
100548
100583
  }
100549
100584
  if (!filePath) {
100550
- const candidate = join31(projectDir, relativePath);
100585
+ const candidate = join33(projectDir, relativePath);
100551
100586
  if (existsSync36(candidate) && isPathInside2(candidate, projectDir) && statSync11(candidate).isFile()) {
100552
100587
  filePath = candidate;
100553
100588
  }
@@ -100772,7 +100807,7 @@ var init_fileServer2 = __esm({
100772
100807
  // ../producer/src/utils/paths.ts
100773
100808
  import {
100774
100809
  basename as basename5,
100775
- join as join33,
100810
+ join as join34,
100776
100811
  resolve as nodeResolve,
100777
100812
  relative as nodeRelative,
100778
100813
  isAbsolute as nodeIsAbsolute
@@ -100807,7 +100842,7 @@ function formatExportFrameName(index, ext) {
100807
100842
  function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
100808
100843
  const absoluteProjectDir = nodeResolve(projectDir);
100809
100844
  const projectName = basename5(absoluteProjectDir);
100810
- const resolvedOutputPath = outputPath ?? join33(rendersDir, `${projectName}.mp4`);
100845
+ const resolvedOutputPath = outputPath ?? join34(rendersDir, `${projectName}.mp4`);
100811
100846
  const absoluteOutputPath = nodeResolve(resolvedOutputPath);
100812
100847
  return { absoluteProjectDir, absoluteOutputPath };
100813
100848
  }
@@ -100823,7 +100858,7 @@ var init_paths = __esm({
100823
100858
 
100824
100859
  // ../producer/src/services/render/shared.ts
100825
100860
  import { copyFileSync as copyFileSync4, cpSync as cpSync2, existsSync as existsSync37, mkdirSync as mkdirSync18, symlinkSync as symlinkSync2, writeFileSync as writeFileSync13 } from "fs";
100826
- import { basename as basename6, dirname as dirname15, isAbsolute as isAbsolute11, join as join34, relative as relative8, resolve as resolve24 } from "path";
100861
+ import { basename as basename6, dirname as dirname15, isAbsolute as isAbsolute11, join as join35, relative as relative8, resolve as resolve24 } from "path";
100827
100862
  function writeFileExclusiveSync(path2, data2) {
100828
100863
  try {
100829
100864
  writeFileSync13(path2, data2, { flag: "wx", mode: 384 });
@@ -100851,16 +100886,16 @@ function resolveDeviceScaleFactor(input2) {
100851
100886
  return target.width / input2.compositionWidth;
100852
100887
  }
100853
100888
  function writeCompiledArtifacts(compiled, workDir, includeSummary) {
100854
- const compileDir = join34(workDir, "compiled");
100889
+ const compileDir = join35(workDir, "compiled");
100855
100890
  mkdirSync18(compileDir, { recursive: true });
100856
- writeFileSync13(join34(compileDir, "index.html"), compiled.html, "utf-8");
100891
+ writeFileSync13(join35(compileDir, "index.html"), compiled.html, "utf-8");
100857
100892
  for (const [srcPath, html] of compiled.subCompositions) {
100858
- const outPath = join34(compileDir, srcPath);
100893
+ const outPath = join35(compileDir, srcPath);
100859
100894
  mkdirSync18(dirname15(outPath), { recursive: true });
100860
100895
  writeFileSync13(outPath, html, "utf-8");
100861
100896
  }
100862
100897
  for (const [relativePath, absolutePath] of compiled.externalAssets) {
100863
- const outPath = resolve24(join34(compileDir, relativePath));
100898
+ const outPath = resolve24(join35(compileDir, relativePath));
100864
100899
  if (!isPathInside3(outPath, compileDir)) {
100865
100900
  console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
100866
100901
  continue;
@@ -100891,7 +100926,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
100891
100926
  renderModeHints: compiled.renderModeHints,
100892
100927
  hasShaderTransitions: compiled.hasShaderTransitions
100893
100928
  };
100894
- writeFileSync13(join34(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
100929
+ writeFileSync13(join35(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
100895
100930
  }
100896
100931
  }
100897
100932
  function applyRenderModeHints(alreadyForced, compiled, log2 = defaultLogger) {
@@ -100982,7 +101017,7 @@ var init_shared = __esm({
100982
101017
  BROWSER_MEDIA_EPSILON = 1e-4;
100983
101018
  materializePathModule = {
100984
101019
  resolve: resolve24,
100985
- join: join34,
101020
+ join: join35,
100986
101021
  dirname: dirname15,
100987
101022
  basename: basename6,
100988
101023
  relative: relative8,
@@ -101356,7 +101391,7 @@ var init_captureBeyondViewport = __esm({
101356
101391
  });
101357
101392
 
101358
101393
  // ../producer/src/services/render/captureCost.ts
101359
- import { join as join35 } from "path";
101394
+ import { join as join36 } from "path";
101360
101395
  function estimateCaptureCostMultiplier(compiled) {
101361
101396
  let multiplier = 1;
101362
101397
  const reasons = [];
@@ -101583,7 +101618,7 @@ async function runCaptureCalibration(input2) {
101583
101618
  });
101584
101619
  let calibration;
101585
101620
  try {
101586
- calibration = await runOneCalibration(join35(workDir, "capture-calibration"), calibrationCfg);
101621
+ calibration = await runOneCalibration(join36(workDir, "capture-calibration"), calibrationCfg);
101587
101622
  } catch (error) {
101588
101623
  const shouldFallback = !forceScreenshot && shouldFallbackToScreenshotAfterCalibrationError(error);
101589
101624
  if (!shouldFallback) {
@@ -101616,7 +101651,7 @@ async function runCaptureCalibration(input2) {
101616
101651
  const screenshotCfg = createCaptureCalibrationConfig({ ...cfg, forceScreenshot: true });
101617
101652
  try {
101618
101653
  calibration = await runOneCalibration(
101619
- join35(workDir, "capture-calibration-screenshot"),
101654
+ join36(workDir, "capture-calibration-screenshot"),
101620
101655
  screenshotCfg
101621
101656
  );
101622
101657
  } catch (fallbackError) {
@@ -102183,7 +102218,7 @@ var init_manualEditsRenderScript = __esm({
102183
102218
 
102184
102219
  // ../producer/src/services/htmlCompiler.ts
102185
102220
  import { readFileSync as readFileSync24, existsSync as existsSync38, mkdirSync as mkdirSync19 } from "fs";
102186
- import { join as join36, dirname as dirname16, resolve as resolve25, basename as basename7 } from "path";
102221
+ import { join as join37, dirname as dirname16, resolve as resolve25, basename as basename7 } from "path";
102187
102222
  function parseSubCompHtmlForValidity(html) {
102188
102223
  return parseHTML(html).document;
102189
102224
  }
@@ -102299,7 +102334,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
102299
102334
  return { duration: 0, resolvedPath: src };
102300
102335
  }
102301
102336
  } else if (!filePath.startsWith("/")) {
102302
- filePath = join36(baseDir, filePath);
102337
+ filePath = join37(baseDir, filePath);
102303
102338
  }
102304
102339
  if (!existsSync38(filePath)) {
102305
102340
  return { duration: 0, resolvedPath: filePath };
@@ -102820,7 +102855,7 @@ async function localizeRemoteMediaSources(html, downloadDir) {
102820
102855
  return downloadAndRewriteUrls(
102821
102856
  urlSet,
102822
102857
  html,
102823
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
102858
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102824
102859
  "Remote media download failed for",
102825
102860
  "Localized remote media source(s)"
102826
102861
  );
@@ -102835,7 +102870,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
102835
102870
  return downloadAndRewriteUrls(
102836
102871
  urlSet,
102837
102872
  html,
102838
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
102873
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102839
102874
  "Remote image download failed for",
102840
102875
  "Localized remote image source(s)"
102841
102876
  );
@@ -102984,7 +103019,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
102984
103019
  return downloadAndRewriteUrls(
102985
103020
  urlSet,
102986
103021
  processed,
102987
- join36(downloadDir, REMOTE_MEDIA_SUBDIR),
103022
+ join37(downloadDir, REMOTE_MEDIA_SUBDIR),
102988
103023
  "Remote font download failed for",
102989
103024
  "Localized remote font face(s)",
102990
103025
  (h3, url, relPath) => h3.replaceAll(`url(${url})`, `url("${relPath}")`)
@@ -103446,7 +103481,7 @@ Check that each file referenced by data-composition-src contains valid HTML with
103446
103481
  });
103447
103482
 
103448
103483
  // ../producer/src/services/render/stages/compileStage.ts
103449
- import { join as join37 } from "path";
103484
+ import { join as join38 } from "path";
103450
103485
  async function runCompileStage(input2) {
103451
103486
  const {
103452
103487
  projectDir,
@@ -103462,11 +103497,11 @@ async function runCompileStage(input2) {
103462
103497
  allowSystemFontCapture
103463
103498
  } = input2;
103464
103499
  const compileStart = Date.now();
103465
- const compiled = await compileForRender(projectDir, htmlPath, join37(workDir, "downloads"), {
103500
+ const compiled = await compileForRender(projectDir, htmlPath, join38(workDir, "downloads"), {
103466
103501
  log: log2,
103467
103502
  failClosedFontFetch: failClosedFontFetch === true,
103468
103503
  allowSystemFontCapture,
103469
- animatedGifCacheDir: cfg.extractCacheDir ? join37(cfg.extractCacheDir, "animated-gif") : void 0,
103504
+ animatedGifCacheDir: cfg.extractCacheDir ? join38(cfg.extractCacheDir, "animated-gif") : void 0,
103470
103505
  ffmpegProcessTimeout: cfg.ffmpegProcessTimeout
103471
103506
  });
103472
103507
  assertNotAborted();
@@ -103531,7 +103566,7 @@ var init_compileStage = __esm({
103531
103566
  });
103532
103567
 
103533
103568
  // ../producer/src/services/render/stages/probeStage.ts
103534
- import { join as join38 } from "path";
103569
+ import { join as join39 } from "path";
103535
103570
  function hasScriptedAudioVolumeAutomation(html, audioCount) {
103536
103571
  if (audioCount <= 0) return false;
103537
103572
  const { document: document2 } = parseHTML(html);
@@ -103579,7 +103614,7 @@ async function runProbeStage(input2) {
103579
103614
  });
103580
103615
  fileServer = await createFileServer2({
103581
103616
  projectDir,
103582
- compiledDir: join38(workDir, "compiled"),
103617
+ compiledDir: join39(workDir, "compiled"),
103583
103618
  port: 0,
103584
103619
  preHeadScripts: [VIRTUAL_TIME_SHIM],
103585
103620
  fps: job.config.fps
@@ -103600,7 +103635,7 @@ async function runProbeStage(input2) {
103600
103635
  log2.info("Creating capture session...", { attempt, maxAttempts: PROBE_MAX_ATTEMPTS });
103601
103636
  probeSession = await createCaptureSession(
103602
103637
  fileServer.url,
103603
- join38(workDir, "probe"),
103638
+ join39(workDir, "probe"),
103604
103639
  captureOpts,
103605
103640
  null,
103606
103641
  probeCfg
@@ -103680,7 +103715,7 @@ async function runProbeStage(input2) {
103680
103715
  compiled,
103681
103716
  resolutions,
103682
103717
  projectDir,
103683
- join38(workDir, "downloads")
103718
+ join39(workDir, "downloads")
103684
103719
  );
103685
103720
  assertNotAborted();
103686
103721
  composition.videos = compiled.videos;
@@ -103898,7 +103933,7 @@ var init_probeStage = __esm({
103898
103933
 
103899
103934
  // ../producer/src/services/render/stages/extractVideosStage.ts
103900
103935
  import { existsSync as existsSync39 } from "fs";
103901
- import { isAbsolute as isAbsolute12, join as join39 } from "path";
103936
+ import { isAbsolute as isAbsolute12, join as join40 } from "path";
103902
103937
  async function runExtractVideosStage(input2) {
103903
103938
  const {
103904
103939
  projectDir,
@@ -103941,7 +103976,7 @@ async function runExtractVideosStage(input2) {
103941
103976
  composition.images.map(async (img) => {
103942
103977
  let imgPath = img.src;
103943
103978
  if (!imgPath.startsWith("/")) {
103944
- const fromCompiled = existsSync39(join39(compiledDir, imgPath)) ? join39(compiledDir, imgPath) : join39(projectDir, imgPath);
103979
+ const fromCompiled = existsSync39(join40(compiledDir, imgPath)) ? join40(compiledDir, imgPath) : join40(projectDir, imgPath);
103945
103980
  imgPath = fromCompiled;
103946
103981
  }
103947
103982
  if (!existsSync39(imgPath)) return null;
@@ -103971,7 +104006,7 @@ async function runExtractVideosStage(input2) {
103971
104006
  // output framerate exact.
103972
104007
  {
103973
104008
  fps: fpsToNumber(job.config.fps),
103974
- outputDir: join39(compiledDir, "__hyperframes_video_frames"),
104009
+ outputDir: join40(compiledDir, "__hyperframes_video_frames"),
103975
104010
  format: job.config.videoFrameFormat ?? "auto"
103976
104011
  },
103977
104012
  abortSignal,
@@ -104037,18 +104072,18 @@ var init_extractVideosStage = __esm({
104037
104072
  });
104038
104073
 
104039
104074
  // ../producer/src/services/render/stages/audioStage.ts
104040
- import { join as join40 } from "path";
104075
+ import { join as join41 } from "path";
104041
104076
  async function runAudioStage(input2) {
104042
104077
  const { projectDir, workDir, compiledDir, duration, audios, abortSignal, assertNotAborted } = input2;
104043
104078
  const stage3Start = Date.now();
104044
- const audioOutputPath = join40(workDir, "audio.aac");
104079
+ const audioOutputPath = join41(workDir, "audio.aac");
104045
104080
  let hasAudio = false;
104046
104081
  let audioError;
104047
104082
  if (audios.length > 0) {
104048
104083
  const audioResult = await processCompositionAudio(
104049
104084
  audios,
104050
104085
  projectDir,
104051
- join40(workDir, "audio-work"),
104086
+ join41(workDir, "audio-work"),
104052
104087
  audioOutputPath,
104053
104088
  duration,
104054
104089
  abortSignal,
@@ -104211,7 +104246,7 @@ var init_captureStage = __esm({
104211
104246
 
104212
104247
  // ../producer/src/services/hdrCompositor.ts
104213
104248
  import { readSync as readSync2, closeSync as closeSync3 } from "fs";
104214
- import { join as join41 } from "path";
104249
+ import { join as join43 } from "path";
104215
104250
  function countNonZeroAlpha(rgba) {
104216
104251
  let n2 = 0;
104217
104252
  for (let p2 = 3; p2 < rgba.length; p2 += 4) {
@@ -104605,7 +104640,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
104605
104640
  if (shouldLog && debugDumpDir) {
104606
104641
  const after2 = countNonZeroRgb48(canvas);
104607
104642
  const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
104608
- const dumpPath = join41(debugDumpDir, dumpName);
104643
+ const dumpPath = join43(debugDumpDir, dumpName);
104609
104644
  writeFileExclusiveSync(dumpPath, domPng);
104610
104645
  log2.info("[diag] dom layer blit", {
104611
104646
  frame: debugFrameIndex,
@@ -105149,14 +105184,14 @@ var init_hdrImageTransferCache = __esm({
105149
105184
  // ../producer/src/services/render/stages/captureHdrResources.ts
105150
105185
  import {
105151
105186
  closeSync as closeSync4,
105152
- constants as constants2,
105187
+ constants as constants3,
105153
105188
  fstatSync as fstatSync2,
105154
105189
  mkdirSync as mkdirSync20,
105155
105190
  mkdtempSync as mkdtempSync3,
105156
105191
  openSync as openSync3,
105157
105192
  readFileSync as readFileSync25
105158
105193
  } from "fs";
105159
- import { join as join43 } from "path";
105194
+ import { join as join44 } from "path";
105160
105195
  function tempDirSafePrefix(id) {
105161
105196
  const safe = id.replace(/[^A-Za-z0-9_.-]/g, "_").slice(0, 80);
105162
105197
  return safe || "video";
@@ -105169,8 +105204,8 @@ function planHdrResources(args) {
105169
105204
  if (!hdrVideoIds.includes(v2.id)) continue;
105170
105205
  let srcPath = v2.src;
105171
105206
  if (!srcPath.startsWith("/")) {
105172
- const fromCompiled = join43(compiledDir, srcPath);
105173
- srcPath = args.existsSync(fromCompiled) ? fromCompiled : join43(projectDir, srcPath);
105207
+ const fromCompiled = join44(compiledDir, srcPath);
105208
+ srcPath = args.existsSync(fromCompiled) ? fromCompiled : join44(projectDir, srcPath);
105174
105209
  }
105175
105210
  hdrVideoSrcPaths.set(v2.id, srcPath);
105176
105211
  }
@@ -105244,10 +105279,10 @@ async function extractHdrVideoFrames(args) {
105244
105279
  const video = composition.videos.find((v2) => v2.id === videoId);
105245
105280
  if (!video) continue;
105246
105281
  mkdirSync20(framesDir, { recursive: true });
105247
- const frameDir = mkdtempSync3(join43(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
105282
+ const frameDir = mkdtempSync3(join44(framesDir, `hdr_${tempDirSafePrefix(videoId)}-`));
105248
105283
  const duration = video.end - video.start;
105249
105284
  const dims = prep.hdrExtractionDims.get(videoId) ?? { width, height };
105250
- const rawPath = join43(frameDir, "frames.rgb48le");
105285
+ const rawPath = join44(frameDir, "frames.rgb48le");
105251
105286
  const ffmpegArgs = [
105252
105287
  "-ss",
105253
105288
  String(video.mediaStart),
@@ -105279,7 +105314,7 @@ async function extractHdrVideoFrames(args) {
105279
105314
  );
105280
105315
  }
105281
105316
  const frameSize = dims.width * dims.height * 6;
105282
- const fd = openSync3(rawPath, constants2.O_RDONLY | NO_FOLLOW_FLAG);
105317
+ const fd = openSync3(rawPath, constants3.O_RDONLY | NO_FOLLOW_FLAG);
105283
105318
  let handedOff = false;
105284
105319
  try {
105285
105320
  const frameCount = Math.floor(fstatSync2(fd).size / frameSize);
@@ -105353,12 +105388,12 @@ var init_captureHdrResources = __esm({
105353
105388
  "use strict";
105354
105389
  init_src();
105355
105390
  init_dist3();
105356
- NO_FOLLOW_FLAG = constants2.O_NOFOLLOW ?? 0;
105391
+ NO_FOLLOW_FLAG = constants3.O_NOFOLLOW ?? 0;
105357
105392
  }
105358
105393
  });
105359
105394
 
105360
105395
  // ../producer/src/services/render/stages/captureHdrSequentialLoop.ts
105361
- import { join as join44 } from "path";
105396
+ import { join as join45 } from "path";
105362
105397
  async function runSequentialLayeredFrameLoop(input2) {
105363
105398
  const {
105364
105399
  job,
@@ -105479,7 +105514,7 @@ async function runSequentialLayeredFrameLoop(input2) {
105479
105514
  );
105480
105515
  if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
105481
105516
  writeFileExclusiveSync(
105482
- join44(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105517
+ join45(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105483
105518
  normalCanvas
105484
105519
  );
105485
105520
  }
@@ -105526,7 +105561,7 @@ var init_captureHdrSequentialLoop = __esm({
105526
105561
  // ../producer/src/services/shaderTransitionWorkerPool.ts
105527
105562
  import { Worker } from "worker_threads";
105528
105563
  import { fileURLToPath as fileURLToPath4, pathToFileURL } from "url";
105529
- import { dirname as dirname17, join as join45 } from "path";
105564
+ import { dirname as dirname17, join as join46 } from "path";
105530
105565
  import { createRequire } from "module";
105531
105566
  import { existsSync as existsSync40 } from "fs";
105532
105567
  import { cpus as cpus3 } from "os";
@@ -105540,9 +105575,9 @@ function resolveWorkerEntry(explicit) {
105540
105575
  return { path: override, isTs };
105541
105576
  }
105542
105577
  const moduleDir = dirname17(fileURLToPath4(import.meta.url));
105543
- const jsPath = join45(moduleDir, "shaderTransitionWorker.js");
105578
+ const jsPath = join46(moduleDir, "shaderTransitionWorker.js");
105544
105579
  if (existsSync40(jsPath)) return { path: jsPath, isTs: false };
105545
- const tsPath = join45(moduleDir, "shaderTransitionWorker.ts");
105580
+ const tsPath = join46(moduleDir, "shaderTransitionWorker.ts");
105546
105581
  return { path: tsPath, isTs: true };
105547
105582
  }
105548
105583
  function buildExecArgv(entryIsTs) {
@@ -105725,7 +105760,7 @@ var init_shaderTransitionWorkerPool = __esm({
105725
105760
  });
105726
105761
 
105727
105762
  // ../producer/src/services/render/stages/captureHdrHybridLoop.ts
105728
- import { join as join46 } from "path";
105763
+ import { join as join47 } from "path";
105729
105764
  async function runHybridLayeredFrameLoop(input2) {
105730
105765
  const {
105731
105766
  job,
@@ -105918,7 +105953,7 @@ async function runHybridLayeredFrameLoop(input2) {
105918
105953
  );
105919
105954
  if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
105920
105955
  writeFileExclusiveSync(
105921
- join46(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105956
+ join47(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
105922
105957
  canvas
105923
105958
  );
105924
105959
  }
@@ -105963,7 +105998,7 @@ var init_captureHdrHybridLoop = __esm({
105963
105998
 
105964
105999
  // ../producer/src/services/render/stages/captureHdrStage.ts
105965
106000
  import { existsSync as existsSync41, mkdirSync as mkdirSync21 } from "fs";
105966
- import { join as join47 } from "path";
106001
+ import { join as join48 } from "path";
105967
106002
  async function runCaptureHdrStage(input2) {
105968
106003
  const {
105969
106004
  job,
@@ -106122,7 +106157,7 @@ async function runCaptureHdrStage(input2) {
106122
106157
  if (hdrVideoFrameSources.has(v2.id)) hdrVideoEndTimes.set(v2.id, v2.end);
106123
106158
  }
106124
106159
  const debugDumpEnabled = process.env.KEEP_TEMP === "1";
106125
- const debugDumpDir = debugDumpEnabled ? join47(framesDir, "debug-composite") : null;
106160
+ const debugDumpDir = debugDumpEnabled ? join48(framesDir, "debug-composite") : null;
106126
106161
  if (debugDumpDir && !existsSync41(debugDumpDir)) {
106127
106162
  mkdirSync21(debugDumpDir, { recursive: true });
106128
106163
  }
@@ -106284,7 +106319,7 @@ var init_captureHdrStage = __esm({
106284
106319
  });
106285
106320
 
106286
106321
  // ../producer/src/services/render/stages/gifEncodeArgs.ts
106287
- import { join as join48 } from "path";
106322
+ import { join as join49 } from "path";
106288
106323
  function fpsToFfmpegArg2(fps) {
106289
106324
  return fps.den === 1 ? String(fps.num) : `${fps.num}/${fps.den}`;
106290
106325
  }
@@ -106295,7 +106330,7 @@ function buildGifPalettegenArgs(input2) {
106295
106330
  "-framerate",
106296
106331
  fpsArg,
106297
106332
  "-i",
106298
- join48(input2.framesDir, input2.framePattern),
106333
+ join49(input2.framesDir, input2.framePattern),
106299
106334
  "-vf",
106300
106335
  `fps=${fpsArg},palettegen=stats_mode=diff`,
106301
106336
  input2.palettePath
@@ -106308,7 +106343,7 @@ function buildGifPaletteuseArgs(input2) {
106308
106343
  "-framerate",
106309
106344
  fpsArg,
106310
106345
  "-i",
106311
- join48(input2.framesDir, input2.framePattern),
106346
+ join49(input2.framesDir, input2.framePattern),
106312
106347
  "-i",
106313
106348
  input2.palettePath,
106314
106349
  "-lavfi",
@@ -106326,7 +106361,7 @@ var init_gifEncodeArgs = __esm({
106326
106361
 
106327
106362
  // ../producer/src/services/render/stages/encodeStage.ts
106328
106363
  import { copyFileSync as copyFileSync5, existsSync as existsSync43, mkdirSync as mkdirSync23, readdirSync as readdirSync14, rmSync as rmSync11, statSync as statSync12 } from "fs";
106329
- import { dirname as dirname18, join as join49 } from "path";
106364
+ import { dirname as dirname18, join as join50 } from "path";
106330
106365
  function resolveGifLoop(loop) {
106331
106366
  const resolved = loop ?? 0;
106332
106367
  if (!Number.isInteger(resolved) || resolved < 0 || resolved > 65535) {
@@ -106431,11 +106466,11 @@ async function runEncodeStage(input2) {
106431
106466
  );
106432
106467
  }
106433
106468
  captured.forEach((name, i2) => {
106434
- const dst = join49(outputPath, formatExportFrameName(i2, "png"));
106435
- copyFileSync5(join49(framesDir, name), dst);
106469
+ const dst = join50(outputPath, formatExportFrameName(i2, "png"));
106470
+ copyFileSync5(join50(framesDir, name), dst);
106436
106471
  });
106437
106472
  if (hasAudio && audioOutputPath && existsSync43(audioOutputPath)) {
106438
- copyFileSync5(audioOutputPath, join49(outputPath, "audio.aac"));
106473
+ copyFileSync5(audioOutputPath, join50(outputPath, "audio.aac"));
106439
106474
  log2.info(`[Render] png-sequence: audio.aac sidecar written to ${outputPath}/audio.aac`);
106440
106475
  }
106441
106476
  return { encodeMs: Date.now() - stage5Start };
@@ -106451,7 +106486,7 @@ async function runEncodeStage(input2) {
106451
106486
  const encodeResult2 = await encodeGifFromDir(framesDir, framePattern2, outputPath, {
106452
106487
  fps: job.config.fps,
106453
106488
  loop,
106454
- palettePath: join49(dirname18(videoOnlyPath), "gif-palette.png"),
106489
+ palettePath: join50(dirname18(videoOnlyPath), "gif-palette.png"),
106455
106490
  signal: abortSignal,
106456
106491
  timeout: engineCfg.ffmpegEncodeTimeout
106457
106492
  });
@@ -106577,7 +106612,7 @@ import {
106577
106612
  copyFileSync as copyFileSync6,
106578
106613
  appendFileSync
106579
106614
  } from "fs";
106580
- import { join as join50, dirname as dirname19, resolve as resolve26 } from "path";
106615
+ import { join as join51, dirname as dirname19, resolve as resolve26 } from "path";
106581
106616
  import { randomUUID as randomUUID4 } from "crypto";
106582
106617
  import { fileURLToPath as fileURLToPath5 } from "url";
106583
106618
  function sampleDirectoryBytes(dir) {
@@ -106593,7 +106628,7 @@ function sampleDirectoryBytes(dir) {
106593
106628
  continue;
106594
106629
  }
106595
106630
  for (const name of entries2) {
106596
- const full2 = join50(current2, name);
106631
+ const full2 = join51(current2, name);
106597
106632
  try {
106598
106633
  const st3 = statSync13(full2);
106599
106634
  if (st3.isDirectory()) {
@@ -106682,7 +106717,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
106682
106717
  const ranges = [];
106683
106718
  let rangeStart = null;
106684
106719
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
106685
- const framePath = join50(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106720
+ const framePath = join51(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106686
106721
  const missing = !existsSync44(framePath);
106687
106722
  if (missing && rangeStart === null) {
106688
106723
  rangeStart = frameIndex;
@@ -106705,7 +106740,7 @@ function buildMissingFrameRetryBatches(ranges, maxWorkers, workDir, attempt, ran
106705
106740
  workerId,
106706
106741
  startFrame: rangeStart + range.startFrame,
106707
106742
  endFrame: rangeStart + range.endFrame,
106708
- outputDir: join50(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
106743
+ outputDir: join51(workDir, `retry-${attempt}-batch-${batchIndex}-worker-${workerId}`),
106709
106744
  outputFrameOffset: rangeStart
106710
106745
  }));
106711
106746
  batches.push(batch);
@@ -106738,7 +106773,7 @@ The composition is too large for the available memory. To reduce memory pressure
106738
106773
  function countCapturedFrames(totalFrames, framesDir, frameExt) {
106739
106774
  let captured = 0;
106740
106775
  for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
106741
- const framePath = join50(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106776
+ const framePath = join51(framesDir, formatCaptureFrameName(frameIndex, frameExt));
106742
106777
  if (existsSync44(framePath)) captured++;
106743
106778
  }
106744
106779
  return captured;
@@ -106763,7 +106798,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
106763
106798
  reason: attempt === 0 ? "initial" : pendingTransientRetry ? "transient-retry" : "retry"
106764
106799
  });
106765
106800
  pendingTransientRetry = false;
106766
- const attemptWorkDir = join50(options.workDir, `capture-attempt-${attempt}`);
106801
+ const attemptWorkDir = join51(options.workDir, `capture-attempt-${attempt}`);
106767
106802
  const batches = missingRanges ? buildMissingFrameRetryBatches(
106768
106803
  missingRanges,
106769
106804
  currentWorkers,
@@ -106948,10 +106983,10 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
106948
106983
  async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
106949
106984
  const moduleDir = dirname19(fileURLToPath5(import.meta.url));
106950
106985
  const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve26(process.env.PRODUCER_RENDERS_DIR, "..") : resolve26(moduleDir, "../..");
106951
- const debugDir = join50(producerRoot, ".debug");
106986
+ const debugDir = join51(producerRoot, ".debug");
106952
106987
  const outputDir = dirname19(outputPath);
106953
106988
  if (!existsSync44(outputDir)) mkdirSync24(outputDir, { recursive: true });
106954
- const workDir = job.config.debug ? join50(debugDir, job.id) : mkdtempSync4(join50(outputDir, `work-${job.id}-`));
106989
+ const workDir = job.config.debug ? join51(debugDir, job.id) : mkdtempSync4(join51(outputDir, `work-${job.id}-`));
106955
106990
  const pipelineStart = Date.now();
106956
106991
  const log2 = job.config.logger ?? defaultLogger;
106957
106992
  let fileServer = null;
@@ -106967,7 +107002,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
106967
107002
  imageDecodeFailures: 0
106968
107003
  };
106969
107004
  let hdrPerf;
106970
- const perfOutputPath = join50(workDir, "perf-summary.json");
107005
+ const perfOutputPath = join51(workDir, "perf-summary.json");
106971
107006
  const cfg = { ...job.config.producerConfig ?? resolveConfig() };
106972
107007
  const observability = new RenderObservabilityRecorder({
106973
107008
  pipelineStartMs: pipelineStart,
@@ -107014,7 +107049,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107014
107049
  assertConfiguredFfmpegBinariesExist();
107015
107050
  if (!existsSync44(workDir)) mkdirSync24(workDir, { recursive: true });
107016
107051
  if (job.config.debug) {
107017
- const logPath = join50(workDir, "render.log");
107052
+ const logPath = join51(workDir, "render.log");
107018
107053
  restoreLogger = installDebugLogger(logPath, log2);
107019
107054
  log2.info("[Render] Debug artifacts enabled", { workDir, logPath });
107020
107055
  }
@@ -107043,15 +107078,15 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107043
107078
  requestedWorkers: job.config.workers ?? "auto"
107044
107079
  });
107045
107080
  const entryFile = job.config.entryFile || "index.html";
107046
- let htmlPath = join50(projectDir, entryFile);
107081
+ let htmlPath = join51(projectDir, entryFile);
107047
107082
  if (!existsSync44(htmlPath)) {
107048
107083
  throw new Error(`Entry file not found: ${htmlPath}`);
107049
107084
  }
107050
107085
  assertNotAborted();
107051
107086
  const rawEntry = readFileSync26(htmlPath, "utf-8");
107052
107087
  if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
107053
- const wrapperPath = join50(workDir, "standalone-entry.html");
107054
- const projectIndexPath = join50(projectDir, "index.html");
107088
+ const wrapperPath = join51(workDir, "standalone-entry.html");
107089
+ const projectIndexPath = join51(projectDir, "index.html");
107055
107090
  if (!existsSync44(projectIndexPath)) {
107056
107091
  throw new Error(
107057
107092
  `Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
@@ -107174,7 +107209,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107174
107209
  compositionHash
107175
107210
  });
107176
107211
  updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
107177
- const compiledDir = join50(workDir, "compiled");
107212
+ const compiledDir = join51(workDir, "compiled");
107178
107213
  const extractResult = await observeRenderStage(
107179
107214
  observability,
107180
107215
  "video_extract",
@@ -107258,7 +107293,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107258
107293
  try {
107259
107294
  fileServer = await createFileServer2({
107260
107295
  projectDir,
107261
- compiledDir: join50(workDir, "compiled"),
107296
+ compiledDir: join51(workDir, "compiled"),
107262
107297
  port: 0,
107263
107298
  preHeadScripts: [VIRTUAL_TIME_SHIM],
107264
107299
  fps: job.config.fps
@@ -107276,7 +107311,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107276
107311
  if (!activeFileServer) {
107277
107312
  throw new Error("File server failed to initialize before frame capture");
107278
107313
  }
107279
- const framesDir = join50(workDir, "captured-frames");
107314
+ const framesDir = join51(workDir, "captured-frames");
107280
107315
  if (!existsSync44(framesDir)) mkdirSync24(framesDir, { recursive: true });
107281
107316
  const resolvedBrowserGpuMode = await resolveBrowserGpuMode(cfg.browserGpuMode, {
107282
107317
  chromePath: resolveHeadlessShellPath(cfg),
@@ -107386,7 +107421,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107386
107421
  gif: ".gif"
107387
107422
  };
107388
107423
  const videoExt = FORMAT_EXT3[outputFormat] ?? ".mp4";
107389
- const videoOnlyPath = join50(workDir, `video-only${videoExt}`);
107424
+ const videoOnlyPath = join51(workDir, `video-only${videoExt}`);
107390
107425
  const nativeHdrIds = /* @__PURE__ */ new Set([...nativeHdrVideoIds, ...nativeHdrImageIds]);
107391
107426
  const hasHdrContent = Boolean(effectiveHdr && nativeHdrIds.size > 0);
107392
107427
  const usePageSideCompositingForTransitions = (cfg.enablePageSideCompositing || isGif) && compiled.hasShaderTransitions && !hasHdrContent && !isPngSequence && !needsAlpha;
@@ -107706,7 +107741,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
107706
107741
  }
107707
107742
  if (job.config.debug) {
107708
107743
  if (!isPngSequence && existsSync44(outputPath)) {
107709
- const debugOutput = join50(workDir, `output${videoExt}`);
107744
+ const debugOutput = join51(workDir, `output${videoExt}`);
107710
107745
  copyFileSync6(outputPath, debugOutput);
107711
107746
  }
107712
107747
  } else if (process.env.KEEP_TEMP === "1") {
@@ -107868,7 +107903,7 @@ var init_config3 = __esm({
107868
107903
 
107869
107904
  // ../producer/src/services/hyperframeLint.ts
107870
107905
  import { existsSync as existsSync45, readFileSync as readFileSync27, statSync as statSync14 } from "fs";
107871
- import { resolve as resolve27, join as join51 } from "path";
107906
+ import { resolve as resolve27, join as join53 } from "path";
107872
107907
  function isStringRecord2(value) {
107873
107908
  if (!value || typeof value !== "object" || Array.isArray(value)) {
107874
107909
  return false;
@@ -107916,7 +107951,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
107916
107951
  }
107917
107952
  }
107918
107953
  return {
107919
- error: `No HTML entry file found in project directory: ${join51(absProjectDir, preferredEntryFile || "index.html")}`
107954
+ error: `No HTML entry file found in project directory: ${join53(absProjectDir, preferredEntryFile || "index.html")}`
107920
107955
  };
107921
107956
  }
107922
107957
  function prepareHyperframeLintBody(body) {
@@ -107965,7 +108000,7 @@ var init_hyperframeLint = __esm({
107965
108000
  // ../producer/src/services/healthWorker.ts
107966
108001
  import { Worker as Worker2 } from "worker_threads";
107967
108002
  import { fileURLToPath as fileURLToPath6 } from "url";
107968
- import { dirname as dirname20, join as join53 } from "path";
108003
+ import { dirname as dirname20, join as join54 } from "path";
107969
108004
  import { existsSync as existsSync46 } from "fs";
107970
108005
  async function startHealthWorker(options = {}) {
107971
108006
  const log2 = options.logger ?? defaultLogger2();
@@ -108040,7 +108075,7 @@ function defaultLogger2() {
108040
108075
  }
108041
108076
  function resolveWorkerEntry2() {
108042
108077
  const here = dirname20(fileURLToPath6(import.meta.url));
108043
- const candidates = [join53(here, "healthWorkerThread.js"), join53(here, "healthWorkerThread.ts")];
108078
+ const candidates = [join54(here, "healthWorkerThread.js"), join54(here, "healthWorkerThread.ts")];
108044
108079
  for (const candidate of candidates) {
108045
108080
  if (existsSync46(candidate)) return candidate;
108046
108081
  }
@@ -108105,7 +108140,7 @@ import {
108105
108140
  rmSync as rmSync13,
108106
108141
  createReadStream as createReadStream2
108107
108142
  } from "fs";
108108
- import { resolve as resolve28, dirname as dirname21, join as join54 } from "path";
108143
+ import { resolve as resolve28, dirname as dirname21, join as join55 } from "path";
108109
108144
  import { tmpdir as tmpdir5 } from "os";
108110
108145
  import { parseArgs as parseArgs2 } from "util";
108111
108146
  import crypto2 from "crypto";
@@ -108225,8 +108260,8 @@ async function prepareRenderBody(body) {
108225
108260
  }
108226
108261
  }
108227
108262
  const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir5();
108228
- const tempProjectDir = mkdtempSync5(join54(tempRoot, "producer-project-"));
108229
- writeFileSync15(join54(tempProjectDir, "index.html"), htmlContent, "utf-8");
108263
+ const tempProjectDir = mkdtempSync5(join55(tempRoot, "producer-project-"));
108264
+ writeFileSync15(join55(tempProjectDir, "index.html"), htmlContent, "utf-8");
108230
108265
  return {
108231
108266
  prepared: {
108232
108267
  input: {
@@ -108707,7 +108742,7 @@ var init_planHash = __esm({
108707
108742
 
108708
108743
  // ../producer/src/services/render/stages/freezePlan.ts
108709
108744
  import { existsSync as existsSync48, mkdirSync as mkdirSync26, readFileSync as readFileSync28, readdirSync as readdirSync16, writeFileSync as writeFileSync16 } from "fs";
108710
- import { join as join55, relative as relative9, resolve as resolve29 } from "path";
108745
+ import { join as join56, relative as relative9, resolve as resolve29 } from "path";
108711
108746
  function stripUndefined(value) {
108712
108747
  if (Array.isArray(value)) return value.map(stripUndefined);
108713
108748
  if (value !== null && typeof value === "object") {
@@ -108728,7 +108763,7 @@ function listPlanFiles(planDir) {
108728
108763
  function walk(dir) {
108729
108764
  const entries2 = readdirSync16(dir, { withFileTypes: true });
108730
108765
  for (const entry of entries2) {
108731
- const full2 = join55(dir, entry.name);
108766
+ const full2 = join56(dir, entry.name);
108732
108767
  if (entry.isDirectory()) {
108733
108768
  walk(full2);
108734
108769
  } else if (entry.isFile()) {
@@ -108764,8 +108799,8 @@ function collectPlanAssetShas(planDir) {
108764
108799
  return { compositionHtml, assets };
108765
108800
  }
108766
108801
  function recomputePlanHashFromPlanDir(planDir) {
108767
- const planJsonPath = join55(planDir, "plan.json");
108768
- const encoderJsonPath = join55(planDir, "meta", "encoder.json");
108802
+ const planJsonPath = join56(planDir, "plan.json");
108803
+ const encoderJsonPath = join56(planDir, "meta", "encoder.json");
108769
108804
  if (!existsSync48(planJsonPath)) {
108770
108805
  throw new Error(`[freezePlan] plan.json missing: ${planJsonPath}`);
108771
108806
  }
@@ -108801,18 +108836,18 @@ async function freezePlan(input2) {
108801
108836
  if (!existsSync48(planDir)) {
108802
108837
  throw new Error(`[freezePlan] planDir does not exist: ${planDir}`);
108803
108838
  }
108804
- const metaDir = join55(planDir, "meta");
108839
+ const metaDir = join56(planDir, "meta");
108805
108840
  if (!existsSync48(metaDir)) mkdirSync26(metaDir, { recursive: true });
108806
108841
  writeFileSync16(
108807
- join55(metaDir, "composition.json"),
108842
+ join56(metaDir, "composition.json"),
108808
108843
  `${JSON.stringify(composition, null, 2)}
108809
108844
  `,
108810
108845
  "utf-8"
108811
108846
  );
108812
108847
  const encoderForCanonical = stripUndefined(encoder);
108813
108848
  const encoderConfigCanonicalJson = canonicalJsonStringify(encoderForCanonical);
108814
- writeFileSync16(join55(metaDir, "encoder.json"), encoderConfigCanonicalJson, "utf-8");
108815
- writeFileSync16(join55(metaDir, "chunks.json"), `${JSON.stringify(chunks, null, 2)}
108849
+ writeFileSync16(join56(metaDir, "encoder.json"), encoderConfigCanonicalJson, "utf-8");
108850
+ writeFileSync16(join56(metaDir, "chunks.json"), `${JSON.stringify(chunks, null, 2)}
108816
108851
  `, "utf-8");
108817
108852
  const { compositionHtml, assets } = collectPlanAssetShas(planDir);
108818
108853
  const planHash = computePlanHash({
@@ -108835,7 +108870,7 @@ async function freezePlan(input2) {
108835
108870
  duration: durationSeconds,
108836
108871
  hasAudio
108837
108872
  };
108838
- const planJsonPath = join55(planDir, "plan.json");
108873
+ const planJsonPath = join56(planDir, "plan.json");
108839
108874
  writeFileSync16(planJsonPath, `${JSON.stringify(planJson, null, 2)}
108840
108875
  `, "utf-8");
108841
108876
  return { planJsonPath, planHash };
@@ -108958,7 +108993,7 @@ var init_runtimeEnvSnapshot = __esm({
108958
108993
 
108959
108994
  // ../producer/src/services/distributed/shared.ts
108960
108995
  import { execFile as execFileCallback } from "child_process";
108961
- import { dirname as dirname22, join as join56 } from "path";
108996
+ import { dirname as dirname22, join as join57 } from "path";
108962
108997
  import { existsSync as existsSync49, readFileSync as readFileSync29 } from "fs";
108963
108998
  import { fileURLToPath as fileURLToPath7 } from "url";
108964
108999
  import { promisify as promisify3 } from "util";
@@ -108997,7 +109032,7 @@ function readProducerVersion() {
108997
109032
  const startDir = dirname22(fileURLToPath7(import.meta.url));
108998
109033
  let current2 = startDir;
108999
109034
  for (let i2 = 0; i2 < 10; i2++) {
109000
- const candidate = join56(current2, "package.json");
109035
+ const candidate = join57(current2, "package.json");
109001
109036
  if (existsSync49(candidate)) {
109002
109037
  try {
109003
109038
  const pkg = JSON.parse(readFileSync29(candidate, "utf-8"));
@@ -109039,7 +109074,7 @@ import {
109039
109074
  statSync as statSync16,
109040
109075
  writeFileSync as writeFileSync17
109041
109076
  } from "fs";
109042
- import { join as join57, relative as relative10, sep as sep6 } from "path";
109077
+ import { join as join58, relative as relative10, sep as sep6 } from "path";
109043
109078
  function formatBytes2(bytes) {
109044
109079
  if (bytes < 1024) return `${bytes} B`;
109045
109080
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;
@@ -109064,7 +109099,7 @@ function measurePlanDirBytes(planDir) {
109064
109099
  return;
109065
109100
  }
109066
109101
  for (const entry of entries2) {
109067
- const full2 = join57(dir, entry.name);
109102
+ const full2 = join58(dir, entry.name);
109068
109103
  if (entry.isDirectory()) {
109069
109104
  walk(full2);
109070
109105
  } else if (entry.isFile()) {
@@ -109232,13 +109267,13 @@ async function plan(projectDir, config, planDir) {
109232
109267
  producerConfig: config.producerConfig
109233
109268
  });
109234
109269
  const entryFile = config.entryFile ?? "index.html";
109235
- const htmlPath = join57(projectDir, entryFile);
109270
+ const htmlPath = join58(projectDir, entryFile);
109236
109271
  if (!existsSync50(htmlPath)) {
109237
109272
  throw new Error(`[plan] entry file not found: ${htmlPath}`);
109238
109273
  }
109239
- const workDir = join57(planDir, ".plan-work");
109274
+ const workDir = join58(planDir, ".plan-work");
109240
109275
  if (!existsSync50(workDir)) mkdirSync27(workDir, { recursive: true });
109241
- const compiledDir = join57(workDir, "compiled");
109276
+ const compiledDir = join58(workDir, "compiled");
109242
109277
  mkdirSync27(compiledDir, { recursive: true });
109243
109278
  cpSync3(projectDir, compiledDir, {
109244
109279
  recursive: true,
@@ -109250,7 +109285,7 @@ async function plan(projectDir, config, planDir) {
109250
109285
  return firstSegment === void 0 || !PLAN_PROJECT_DIR_SKIP_SEGMENTS.has(firstSegment);
109251
109286
  }
109252
109287
  });
109253
- const finalCompiledDir = join57(planDir, "compiled");
109288
+ const finalCompiledDir = join58(planDir, "compiled");
109254
109289
  const needsAlpha = config.format === "png-sequence" || config.format === "mov" || config.format === "webm";
109255
109290
  const compileResult = await runCompileStage({
109256
109291
  projectDir,
@@ -109335,8 +109370,8 @@ async function plan(projectDir, config, planDir) {
109335
109370
  if (audioResult.audioError) {
109336
109371
  log2.warn(`[Render] Audio mix failed \u2014 output will be video-only: ${audioResult.audioError}`);
109337
109372
  }
109338
- const stagedVideoFrames = join57(compiledDir, "__hyperframes_video_frames");
109339
- const videoFramesDst = join57(planDir, "video-frames");
109373
+ const stagedVideoFrames = join58(compiledDir, "__hyperframes_video_frames");
109374
+ const videoFramesDst = join58(planDir, "video-frames");
109340
109375
  if (existsSync50(videoFramesDst)) rmSync14(videoFramesDst, { recursive: true, force: true });
109341
109376
  if (existsSync50(stagedVideoFrames)) {
109342
109377
  renameSync6(stagedVideoFrames, videoFramesDst);
@@ -109356,13 +109391,13 @@ async function plan(projectDir, config, planDir) {
109356
109391
  metadata: ext.metadata
109357
109392
  }))
109358
109393
  };
109359
- mkdirSync27(join57(planDir, "meta"), { recursive: true });
109394
+ mkdirSync27(join58(planDir, "meta"), { recursive: true });
109360
109395
  writeFileSync17(
109361
- join57(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
109396
+ join58(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
109362
109397
  JSON.stringify(planVideosJson, null, 2),
109363
109398
  "utf-8"
109364
109399
  );
109365
- const planAudioPath = join57(planDir, "audio.aac");
109400
+ const planAudioPath = join58(planDir, "audio.aac");
109366
109401
  if (audioResult.hasAudio && existsSync50(audioResult.audioOutputPath)) {
109367
109402
  renameSync6(audioResult.audioOutputPath, planAudioPath);
109368
109403
  }
@@ -109507,11 +109542,11 @@ var init_plan = __esm({
109507
109542
  // ../producer/src/services/distributed/renderChunk.ts
109508
109543
  import { randomBytes as randomBytes2 } from "crypto";
109509
109544
  import { existsSync as existsSync51, mkdirSync as mkdirSync28, readFileSync as readFileSync30, readdirSync as readdirSync18, rmSync as rmSync15, writeFileSync as writeFileSync18 } from "fs";
109510
- import { extname as extname10, join as join58 } from "path";
109545
+ import { extname as extname10, join as join59 } from "path";
109511
109546
  function rebuildExtractedFramesFromPlanDir(planDir, videos) {
109512
109547
  const result = [];
109513
109548
  for (const v2 of videos) {
109514
- const outputDir = join58(planDir, "video-frames", v2.videoId);
109549
+ const outputDir = join59(planDir, "video-frames", v2.videoId);
109515
109550
  if (!existsSync51(outputDir)) {
109516
109551
  throw new Error(
109517
109552
  `[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v2.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
@@ -109523,7 +109558,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
109523
109558
  for (let i2 = 0; i2 < frames.length; i2++) {
109524
109559
  const frameName = frames[i2];
109525
109560
  if (!frameName) continue;
109526
- framePaths.set(i2, join58(outputDir, frameName));
109561
+ framePaths.set(i2, join59(outputDir, frameName));
109527
109562
  }
109528
109563
  result.push({
109529
109564
  videoId: v2.videoId,
@@ -109548,7 +109583,7 @@ function hashChunkOutput(outputPath, kind) {
109548
109583
  if (kind === "file") return sha256Hex(readFileSync30(outputPath));
109549
109584
  const entries2 = readdirSync18(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
109550
109585
  const lines = entries2.map(
109551
- (name) => `${name}\0${sha256Hex(readFileSync30(join58(outputPath, name)))}`
109586
+ (name) => `${name}\0${sha256Hex(readFileSync30(join59(outputPath, name)))}`
109552
109587
  );
109553
109588
  return sha256Hex(lines.join("\0"));
109554
109589
  }
@@ -109565,9 +109600,9 @@ function resolveLockedVp9CpuUsed(lockedEncoder) {
109565
109600
  async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109566
109601
  const start = Date.now();
109567
109602
  const log2 = defaultLogger;
109568
- const planJsonPath = join58(planDir, "plan.json");
109569
- const encoderJsonPath = join58(planDir, "meta", "encoder.json");
109570
- const chunksJsonPath = join58(planDir, "meta", "chunks.json");
109603
+ const planJsonPath = join59(planDir, "plan.json");
109604
+ const encoderJsonPath = join59(planDir, "meta", "encoder.json");
109605
+ const chunksJsonPath = join59(planDir, "meta", "chunks.json");
109571
109606
  for (const required of [planJsonPath, encoderJsonPath, chunksJsonPath]) {
109572
109607
  if (!existsSync51(required)) {
109573
109608
  throw new RenderChunkValidationError(
@@ -109579,7 +109614,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109579
109614
  const plan2 = JSON.parse(readFileSync30(planJsonPath, "utf-8"));
109580
109615
  const encoder = JSON.parse(readFileSync30(encoderJsonPath, "utf-8"));
109581
109616
  const chunks = JSON.parse(readFileSync30(chunksJsonPath, "utf-8"));
109582
- const videosJsonPath = join58(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
109617
+ const videosJsonPath = join59(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
109583
109618
  let planVideos = null;
109584
109619
  if (existsSync51(videosJsonPath)) {
109585
109620
  try {
@@ -109608,7 +109643,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109608
109643
  `[renderChunk] chunk ${chunkIndex} has non-positive frame count: ${framesInChunk}`
109609
109644
  );
109610
109645
  }
109611
- const compiledDir = join58(planDir, "compiled");
109646
+ const compiledDir = join59(planDir, "compiled");
109612
109647
  if (!existsSync51(compiledDir)) {
109613
109648
  throw new RenderChunkValidationError(
109614
109649
  MISSING_PLAN_ARTIFACT,
@@ -109673,7 +109708,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109673
109708
  );
109674
109709
  const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes2(4).toString("hex")}`;
109675
109710
  mkdirSync28(workDir, { recursive: true });
109676
- const framesDir = join58(workDir, "captured-frames");
109711
+ const framesDir = join59(workDir, "captured-frames");
109677
109712
  mkdirSync28(framesDir, { recursive: true });
109678
109713
  const fileServer = await createFileServer2({
109679
109714
  projectDir: compiledDir,
@@ -109755,7 +109790,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
109755
109790
  if (isPngSequence) {
109756
109791
  if (!existsSync51(outputChunkPath)) mkdirSync28(outputChunkPath, { recursive: true });
109757
109792
  } else {
109758
- const outDir = join58(outputChunkPath, "..");
109793
+ const outDir = join59(outputChunkPath, "..");
109759
109794
  if (!existsSync51(outDir)) mkdirSync28(outDir, { recursive: true });
109760
109795
  }
109761
109796
  const encodeStarted = Date.now();
@@ -110202,14 +110237,14 @@ import {
110202
110237
  statSync as statSync17,
110203
110238
  writeFileSync as writeFileSync19
110204
110239
  } from "fs";
110205
- import { dirname as dirname23, join as join59 } from "path";
110240
+ import { dirname as dirname23, join as join60 } from "path";
110206
110241
  async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110207
110242
  const start = Date.now();
110208
110243
  const log2 = options?.logger ?? defaultLogger;
110209
110244
  const abortSignal = options?.abortSignal;
110210
110245
  const cfr = options?.cfr === true;
110211
- const planJsonPath = join59(planDir, "plan.json");
110212
- const chunksJsonPath = join59(planDir, "meta", "chunks.json");
110246
+ const planJsonPath = join60(planDir, "plan.json");
110247
+ const chunksJsonPath = join60(planDir, "meta", "chunks.json");
110213
110248
  if (!existsSync53(planJsonPath)) {
110214
110249
  throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
110215
110250
  }
@@ -110238,7 +110273,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110238
110273
  if (existsSync53(workDir)) rmSync17(workDir, { recursive: true, force: true });
110239
110274
  mkdirSync29(workDir, { recursive: true });
110240
110275
  try {
110241
- const concatOutputPath = join59(workDir, `concat.${plan2.dimensions.format}`);
110276
+ const concatOutputPath = join60(workDir, `concat.${plan2.dimensions.format}`);
110242
110277
  const fpsArg = fpsToFfmpegArg({
110243
110278
  num: plan2.dimensions.fpsNum,
110244
110279
  den: plan2.dimensions.fpsDen
@@ -110252,7 +110287,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110252
110287
  );
110253
110288
  }
110254
110289
  } else {
110255
- const concatListPath = join59(workDir, "concat-list.txt");
110290
+ const concatListPath = join60(workDir, "concat-list.txt");
110256
110291
  const concatBody = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
110257
110292
  writeFileSync19(concatListPath, `${concatBody}
110258
110293
  `, "utf-8");
@@ -110284,7 +110319,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110284
110319
  `[assemble] cfr=true is only supported for format="mp4" (got "${plan2.dimensions.format}"). Stream-copy paths for webm and mov already produce exact avg_frame_rate; cfr re-encode is not needed.`
110285
110320
  );
110286
110321
  }
110287
- const encoderJsonPath = join59(planDir, "meta", "encoder.json");
110322
+ const encoderJsonPath = join60(planDir, "meta", "encoder.json");
110288
110323
  if (!existsSync53(encoderJsonPath)) {
110289
110324
  throw new Error(`[assemble] planDir missing meta/encoder.json: ${encoderJsonPath}`);
110290
110325
  }
@@ -110294,7 +110329,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110294
110329
  `[assemble] cfr=true is not yet supported with codec: "h265". The cfr re-encode pass uses libx264 and would silently transcode the h265 chunks. Either disable cfr or render with codec: "h264".`
110295
110330
  );
110296
110331
  }
110297
- const cfrOutputPath = join59(workDir, `cfr.${plan2.dimensions.format}`);
110332
+ const cfrOutputPath = join60(workDir, `cfr.${plan2.dimensions.format}`);
110298
110333
  const cfrArgs = [
110299
110334
  "-i",
110300
110335
  concatOutputPath,
@@ -110328,7 +110363,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110328
110363
  }
110329
110364
  let audioForMux = null;
110330
110365
  if (audioPath !== null && existsSync53(audioPath)) {
110331
- const paddedAudioPath = join59(workDir, "audio-padded.aac");
110366
+ const paddedAudioPath = join60(workDir, "audio-padded.aac");
110332
110367
  const padTrimResult = await padOrTrimAudioToVideoFrameCount({
110333
110368
  videoPath: postConcatPath,
110334
110369
  audioPath,
@@ -110344,7 +110379,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
110344
110379
  sourceDurationSeconds: padTrimResult.sourceDurationSeconds
110345
110380
  });
110346
110381
  }
110347
- const muxOutputPath = audioForMux !== null ? join59(workDir, `mux.${plan2.dimensions.format}`) : postConcatPath;
110382
+ const muxOutputPath = audioForMux !== null ? join60(workDir, `mux.${plan2.dimensions.format}`) : postConcatPath;
110348
110383
  if (audioForMux !== null) {
110349
110384
  const muxResult = await muxVideoWithAudio(
110350
110385
  postConcatPath,
@@ -110404,8 +110439,8 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
110404
110439
  throw new Error(`[assemble] png-sequence chunk has no frames: ${chunkDir}`);
110405
110440
  }
110406
110441
  for (const frame of frames) {
110407
- const dst = join59(outputPath, formatExportFrameName(globalIdx, "png"));
110408
- cpSync4(join59(chunkDir, frame), dst);
110442
+ const dst = join60(outputPath, formatExportFrameName(globalIdx, "png"));
110443
+ cpSync4(join60(chunkDir, frame), dst);
110409
110444
  globalIdx += 1;
110410
110445
  }
110411
110446
  }
@@ -110415,13 +110450,13 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
110415
110450
  );
110416
110451
  }
110417
110452
  if (audioPath !== null && existsSync53(audioPath)) {
110418
- const sidecar = join59(outputPath, "audio.aac");
110453
+ const sidecar = join60(outputPath, "audio.aac");
110419
110454
  cpSync4(audioPath, sidecar);
110420
110455
  }
110421
110456
  let fileSize = 0;
110422
110457
  for (const name of readdirSync19(outputPath)) {
110423
110458
  try {
110424
- fileSize += statSync17(join59(outputPath, name)).size;
110459
+ fileSize += statSync17(join60(outputPath, name)).size;
110425
110460
  } catch {
110426
110461
  }
110427
110462
  }
@@ -110454,7 +110489,7 @@ var init_renderConfigValidation = __esm({
110454
110489
  // ../producer/src/services/distributed/projectHash.ts
110455
110490
  import { readdirSync as readdirSync20, readFileSync as readFileSync33 } from "fs";
110456
110491
  import { createHash as createHash11 } from "crypto";
110457
- import { join as join60, relative as relative11 } from "path";
110492
+ import { join as join61, relative as relative11 } from "path";
110458
110493
  var init_projectHash = __esm({
110459
110494
  "../producer/src/services/distributed/projectHash.ts"() {
110460
110495
  "use strict";
@@ -110536,7 +110571,7 @@ __export(studioServer_exports, {
110536
110571
  import { Hono as Hono5 } from "hono";
110537
110572
  import { streamSSE as streamSSE3 } from "hono/streaming";
110538
110573
  import { existsSync as existsSync54, readFileSync as readFileSync34, writeFileSync as writeFileSync20, statSync as statSync18 } from "fs";
110539
- import { resolve as resolve30, join as join61, basename as basename8 } from "path";
110574
+ import { resolve as resolve30, join as join63, basename as basename8 } from "path";
110540
110575
  function resolveDistDir() {
110541
110576
  return resolveStudioBundle().dir;
110542
110577
  }
@@ -110581,7 +110616,7 @@ function resolveRuntimePath() {
110581
110616
  return builtPath;
110582
110617
  }
110583
110618
  function readStudioManualEditManifestContent(projectDir) {
110584
- const manifestPath2 = join61(projectDir, STUDIO_MANUAL_EDITS_PATH2);
110619
+ const manifestPath2 = join63(projectDir, STUDIO_MANUAL_EDITS_PATH2);
110585
110620
  if (!existsSync54(manifestPath2)) return "";
110586
110621
  try {
110587
110622
  return readFileSync34(manifestPath2, "utf-8");
@@ -110687,7 +110722,7 @@ async function loadPreviewServerBuildSignature() {
110687
110722
  ]);
110688
110723
  }
110689
110724
  function rewriteWrittenToHostViewport(projectDir, written) {
110690
- const indexPath2 = join61(projectDir, "index.html");
110725
+ const indexPath2 = join63(projectDir, "index.html");
110691
110726
  if (!existsSync54(indexPath2)) return;
110692
110727
  const indexHtml = readFileSync34(indexPath2, "utf-8");
110693
110728
  const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
@@ -110744,8 +110779,8 @@ function createStudioServer(options) {
110744
110779
  const { injectDeterministicFontFaces: injectDeterministicFontFaces2 } = await Promise.resolve().then(() => (init_deterministicFonts(), deterministicFonts_exports));
110745
110780
  const { prepareAnimatedGifInputs: prepareAnimatedGifInputs2 } = await Promise.resolve().then(() => (init_animatedGifPrep(), animatedGifPrep_exports));
110746
110781
  const { downloadToTemp: downloadToTemp2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
110747
- const gifOutputDir = join61(project2.dir, ".hyperframes", "prepared-assets", "gif");
110748
- const gifDownloadDir = join61(project2.dir, ".hyperframes", "prepared-assets", "downloads");
110782
+ const gifOutputDir = join63(project2.dir, ".hyperframes", "prepared-assets", "gif");
110783
+ const gifDownloadDir = join63(project2.dir, ".hyperframes", "prepared-assets", "downloads");
110749
110784
  const prepared = await prepareAnimatedGifInputs2(html, {
110750
110785
  projectDir: project2.dir,
110751
110786
  downloadDir: gifDownloadDir,
@@ -110766,7 +110801,7 @@ function createStudioServer(options) {
110766
110801
  return await lintHyperframeHtml2(html, opts);
110767
110802
  },
110768
110803
  runtimeUrl: "/api/runtime.js",
110769
- rendersDir: () => join61(projectDir, "renders"),
110804
+ rendersDir: () => join63(projectDir, "renders"),
110770
110805
  startRender(opts) {
110771
110806
  const state = {
110772
110807
  id: opts.jobId,
@@ -111103,7 +111138,7 @@ __export(preview_exports, {
111103
111138
  });
111104
111139
  import { spawn as spawn12 } from "child_process";
111105
111140
  import { existsSync as existsSync55, lstatSync as lstatSync4, symlinkSync as symlinkSync3, unlinkSync as unlinkSync4, readlinkSync, mkdirSync as mkdirSync30 } from "fs";
111106
- import { resolve as resolve31, dirname as dirname24, basename as basename9, join as join63 } from "path";
111141
+ import { resolve as resolve31, dirname as dirname24, basename as basename9, join as join64 } from "path";
111107
111142
  import { fileURLToPath as fileURLToPath8 } from "url";
111108
111143
  import { createRequire as createRequire2 } from "module";
111109
111144
  function previewBaseUrl(port, host = "127.0.0.1") {
@@ -111409,7 +111444,7 @@ function printStudioSummary(projectName, url, opts = {}) {
111409
111444
  console.log();
111410
111445
  }
111411
111446
  function linkProjectIntoStudioData(dir, projectsDir, projectName) {
111412
- const symlinkPath = join63(projectsDir, projectName);
111447
+ const symlinkPath = join64(projectsDir, projectName);
111413
111448
  mkdirSync30(projectsDir, { recursive: true });
111414
111449
  let createdSymlink = false;
111415
111450
  if (dir !== symlinkPath) {
@@ -111472,13 +111507,13 @@ function attachStudioReadyHandler(child, spinner, projectName, options) {
111472
111507
  async function runDevMode(dir, options) {
111473
111508
  const thisFile = fileURLToPath8(import.meta.url);
111474
111509
  const repoRoot2 = resolve31(dirname24(thisFile), "..", "..", "..", "..");
111475
- const projectsDir = join63(repoRoot2, "packages", "studio", "data", "projects");
111510
+ const projectsDir = join64(repoRoot2, "packages", "studio", "data", "projects");
111476
111511
  const pName = options?.projectName ?? basename9(dir);
111477
111512
  const { symlinkPath, createdSymlink } = linkProjectIntoStudioData(dir, projectsDir, pName);
111478
111513
  ge(c.bold("hyperframes preview"));
111479
111514
  const s2 = ft();
111480
111515
  s2.start("Starting studio...");
111481
- const studioPkgDir = join63(repoRoot2, "packages", "studio");
111516
+ const studioPkgDir = join64(repoRoot2, "packages", "studio");
111482
111517
  const child = spawn12("bun", ["run", "dev"], {
111483
111518
  cwd: studioPkgDir,
111484
111519
  stdio: ["ignore", "pipe", "pipe"]
@@ -111490,7 +111525,7 @@ async function runDevMode(dir, options) {
111490
111525
  }
111491
111526
  function hasLocalStudio(dir) {
111492
111527
  try {
111493
- const req = createRequire2(join63(dir, "package.json"));
111528
+ const req = createRequire2(join64(dir, "package.json"));
111494
111529
  req.resolve("@hyperframes/studio/package.json");
111495
111530
  return true;
111496
111531
  } catch {
@@ -111498,10 +111533,10 @@ function hasLocalStudio(dir) {
111498
111533
  }
111499
111534
  }
111500
111535
  async function runLocalStudioMode(dir, options) {
111501
- const req = createRequire2(join63(dir, "package.json"));
111536
+ const req = createRequire2(join64(dir, "package.json"));
111502
111537
  const studioPkgPath = dirname24(req.resolve("@hyperframes/studio/package.json"));
111503
111538
  const pName = options?.projectName ?? basename9(dir);
111504
- const projectsDir = join63(studioPkgPath, "data", "projects");
111539
+ const projectsDir = join64(studioPkgPath, "data", "projects");
111505
111540
  const { symlinkPath, createdSymlink } = linkProjectIntoStudioData(dir, projectsDir, pName);
111506
111541
  ge(c.bold("hyperframes preview") + c.dim(" (local studio)"));
111507
111542
  const s2 = ft();
@@ -111864,7 +111899,7 @@ import {
111864
111899
  readFileSync as readFileSync35,
111865
111900
  readdirSync as readdirSync21
111866
111901
  } from "fs";
111867
- import { resolve as resolve33, basename as basename10, join as join64, dirname as dirname25 } from "path";
111902
+ import { resolve as resolve33, basename as basename10, join as join65, dirname as dirname25 } from "path";
111868
111903
  import { fileURLToPath as fileURLToPath9 } from "url";
111869
111904
  import { execFileSync as execFileSync7, spawn as spawn13 } from "child_process";
111870
111905
  function probeVideo(filePath) {
@@ -111998,7 +112033,7 @@ function listHtmlFiles(dir) {
111998
112033
  const ignoredDirs = /* @__PURE__ */ new Set([".git", "dist", "node_modules"]);
111999
112034
  function walk(currentDir) {
112000
112035
  for (const entry of readdirSync21(currentDir, { withFileTypes: true })) {
112001
- const entryPath = join64(currentDir, entry.name);
112036
+ const entryPath = join65(currentDir, entry.name);
112002
112037
  if (entry.isDirectory()) {
112003
112038
  if (!ignoredDirs.has(entry.name)) walk(entryPath);
112004
112039
  continue;
@@ -112043,7 +112078,7 @@ function writeTailwindSupport(destDir) {
112043
112078
  }
112044
112079
  }
112045
112080
  function patchVideoSrc(dir, videoFilename, durationSeconds) {
112046
- const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join64(e3.parentPath, e3.name));
112081
+ const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join65(e3.parentPath, e3.name));
112047
112082
  for (const file of htmlFiles) {
112048
112083
  let content = readFileSync35(file, "utf-8");
112049
112084
  if (videoFilename) {
@@ -112198,7 +112233,7 @@ function applyResolutionPreset(destDir, resolution) {
112198
112233
  async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
112199
112234
  mkdirSync31(destDir, { recursive: true });
112200
112235
  const templateDir = getStaticTemplateDir(templateId);
112201
- if (existsSync56(join64(templateDir, "index.html"))) {
112236
+ if (existsSync56(join65(templateDir, "index.html"))) {
112202
112237
  cpSync5(templateDir, destDir, { recursive: true });
112203
112238
  } else {
112204
112239
  await fetchRemoteTemplate(templateId, destDir);
@@ -112227,7 +112262,7 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
112227
112262
  const sharedDir = getSharedTemplateDir();
112228
112263
  if (existsSync56(sharedDir)) {
112229
112264
  for (const entry of readdirSync21(sharedDir, { withFileTypes: true })) {
112230
- const src = join64(sharedDir, entry.name);
112265
+ const src = join65(sharedDir, entry.name);
112231
112266
  const dest = resolve33(destDir, entry.name);
112232
112267
  if (entry.isFile() || entry.isSymbolicLink()) {
112233
112268
  copyFileSync7(src, dest);
@@ -113731,7 +113766,7 @@ var init_present = __esm({
113731
113766
  });
113732
113767
 
113733
113768
  // src/utils/publishProject.ts
113734
- import { basename as basename11, dirname as dirname27, join as join65, posix as posix4, relative as relative13, resolve as resolve39 } from "path";
113769
+ import { basename as basename11, dirname as dirname27, join as join66, posix as posix4, relative as relative13, resolve as resolve39 } from "path";
113735
113770
  import { existsSync as existsSync61, readdirSync as readdirSync23, readFileSync as readFileSync38, statSync as statSync19 } from "fs";
113736
113771
  import AdmZip from "adm-zip";
113737
113772
  function isRecord3(value) {
@@ -113832,7 +113867,7 @@ function shouldIgnoreSegment(segment) {
113832
113867
  function collectProjectFiles(rootDir, currentDir, paths) {
113833
113868
  for (const entry of readdirSync23(currentDir, { withFileTypes: true })) {
113834
113869
  if (shouldIgnoreSegment(entry.name)) continue;
113835
- const absolutePath = join65(currentDir, entry.name);
113870
+ const absolutePath = join66(currentDir, entry.name);
113836
113871
  const relativePath = relative13(rootDir, absolutePath).replaceAll("\\", "/");
113837
113872
  if (!relativePath) continue;
113838
113873
  if (entry.isDirectory()) {
@@ -113962,7 +113997,7 @@ function createPublishArchive(projectDir) {
113962
113997
  }
113963
113998
  const fileContents = /* @__PURE__ */ new Map();
113964
113999
  for (const filePath of filePaths) {
113965
- fileContents.set(filePath, readFileSync38(join65(absProjectDir, filePath)));
114000
+ fileContents.set(filePath, readFileSync38(join66(absProjectDir, filePath)));
113966
114001
  }
113967
114002
  localizeExternalAssets(absProjectDir, fileContents);
113968
114003
  const archive = new AdmZip();
@@ -114095,7 +114130,7 @@ __export(publish_exports, {
114095
114130
  });
114096
114131
  import { resolve as resolve40 } from "path";
114097
114132
  import { existsSync as existsSync63 } from "fs";
114098
- import { join as join66 } from "path";
114133
+ import { join as join67 } from "path";
114099
114134
  var examples8, publish_default;
114100
114135
  var init_publish = __esm({
114101
114136
  "src/commands/publish.ts"() {
@@ -114134,7 +114169,7 @@ var init_publish = __esm({
114134
114169
  async run({ args }) {
114135
114170
  const rawArg = args.dir;
114136
114171
  const dir = resolve40(rawArg ?? ".");
114137
- const indexPath2 = join66(dir, "index.html");
114172
+ const indexPath2 = join67(dir, "index.html");
114138
114173
  if (existsSync63(indexPath2)) {
114139
114174
  const lintResult = await lintProject(dir);
114140
114175
  if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
@@ -114896,7 +114931,7 @@ __export(batchRender_exports, {
114896
114931
  runBatchRender: () => runBatchRender
114897
114932
  });
114898
114933
  import { mkdirSync as mkdirSync33, readFileSync as readFileSync40, writeFileSync as writeFileSync23 } from "fs";
114899
- import { dirname as dirname28, join as join67, resolve as resolve43, sep as sep8 } from "path";
114934
+ import { dirname as dirname28, join as join68, resolve as resolve43, sep as sep8 } from "path";
114900
114935
  function isRecord4(value) {
114901
114936
  return value !== null && typeof value === "object" && !Array.isArray(value);
114902
114937
  }
@@ -115032,7 +115067,7 @@ function prepareBatchRender(options) {
115032
115067
  variables,
115033
115068
  outputPath: resolve43(resolveOutputTemplate(options.outputTemplate, variables, index))
115034
115069
  }));
115035
- const manifestPath2 = join67(
115070
+ const manifestPath2 = join68(
115036
115071
  commonOutputDirectory(rows.map((row) => row.outputPath)),
115037
115072
  "manifest.json"
115038
115073
  );
@@ -115245,7 +115280,7 @@ __export(render_exports, {
115245
115280
  });
115246
115281
  import { mkdirSync as mkdirSync34, readdirSync as readdirSync24, readFileSync as readFileSync41, statSync as statSync20, writeFileSync as writeFileSync24, rmSync as rmSync18 } from "fs";
115247
115282
  import { cpus as cpus4, freemem as freemem5, tmpdir as tmpdir6 } from "os";
115248
- import { resolve as resolve44, dirname as dirname29, join as join68, basename as basename12 } from "path";
115283
+ import { resolve as resolve44, dirname as dirname29, join as join69, basename as basename12 } from "path";
115249
115284
  import { execFileSync as execFileSync9, spawn as spawn14 } from "child_process";
115250
115285
  function formatFpsParseError(input2, reason) {
115251
115286
  switch (reason) {
@@ -115337,9 +115372,9 @@ function ensureDockerImage(version2, platform10, quiet) {
115337
115372
  }
115338
115373
  if (!quiet) console.log(c.dim(` Building Docker image: ${tag} (${platform10})...`));
115339
115374
  const dockerfilePath = resolveDockerfilePath();
115340
- const tmpDir = join68(tmpdir6(), `hyperframes-docker-${Date.now()}`);
115375
+ const tmpDir = join69(tmpdir6(), `hyperframes-docker-${Date.now()}`);
115341
115376
  mkdirSync34(tmpDir, { recursive: true });
115342
- writeFileSync24(join68(tmpDir, "Dockerfile"), readFileSync41(dockerfilePath));
115377
+ writeFileSync24(join69(tmpDir, "Dockerfile"), readFileSync41(dockerfilePath));
115343
115378
  const targetArch = platform10 === "linux/arm64" ? "arm64" : "amd64";
115344
115379
  try {
115345
115380
  execFileSync9(
@@ -115743,7 +115778,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds
115743
115778
  for (const entry of readdirSync24(outputPath, { withFileTypes: true })) {
115744
115779
  if (!entry.isFile()) continue;
115745
115780
  try {
115746
- total += statSync20(join68(outputPath, entry.name)).size;
115781
+ total += statSync20(join69(outputPath, entry.name)).size;
115747
115782
  } catch {
115748
115783
  }
115749
115784
  }
@@ -116161,8 +116196,8 @@ var init_render = __esm({
116161
116196
  const now = /* @__PURE__ */ new Date();
116162
116197
  const datePart = now.toISOString().slice(0, 10);
116163
116198
  const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
116164
- const batchOutputTemplate = args.output ? args.output : join68(rendersDir, `${project.name}_${datePart}_${timePart}_{index}${ext}`);
116165
- const outputPath = args.output ? resolve44(args.output) : join68(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
116199
+ const batchOutputTemplate = args.output ? args.output : join69(rendersDir, `${project.name}_${datePart}_${timePart}_{index}${ext}`);
116200
+ const outputPath = args.output ? resolve44(args.output) : join69(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
116166
116201
  if (!batchPath) mkdirSync34(dirname29(outputPath), { recursive: true });
116167
116202
  const useDocker = args.docker ?? false;
116168
116203
  const useGpu = args.gpu ?? false;
@@ -116655,16 +116690,16 @@ var init_beats = __esm({
116655
116690
  // src/beats/headlessAnalyzer.ts
116656
116691
  import { existsSync as existsSync65, readFileSync as readFileSync43 } from "fs";
116657
116692
  import { createRequire as createRequire3 } from "module";
116658
- import { dirname as dirname30, join as join69 } from "path";
116693
+ import { dirname as dirname30, join as join70 } from "path";
116659
116694
  import { fileURLToPath as fileURLToPath11 } from "url";
116660
116695
  function findPrebuiltBundle() {
116661
116696
  const here = dirname30(fileURLToPath11(import.meta.url));
116662
116697
  const candidates = [
116663
- join69(here, "beat-analyzer.global.js"),
116698
+ join70(here, "beat-analyzer.global.js"),
116664
116699
  // dist root (tsup-bundled cli)
116665
- join69(here, "../beat-analyzer.global.js"),
116700
+ join70(here, "../beat-analyzer.global.js"),
116666
116701
  // dist/beats → dist
116667
- join69(here, "../dist/beat-analyzer.global.js")
116702
+ join70(here, "../dist/beat-analyzer.global.js")
116668
116703
  ];
116669
116704
  for (const p2 of candidates) {
116670
116705
  if (existsSync65(p2)) return p2;
@@ -116674,7 +116709,7 @@ function findPrebuiltBundle() {
116674
116709
  async function buildFromCoreSource() {
116675
116710
  const esbuild = await import("esbuild");
116676
116711
  const coreRoot = dirname30(require2.resolve("@hyperframes/core/package.json"));
116677
- const entry = join69(coreRoot, "src/beats/beatDetection.ts");
116712
+ const entry = join70(coreRoot, "src/beats/beatDetection.ts");
116678
116713
  const result = await esbuild.build({
116679
116714
  stdin: {
116680
116715
  contents: `import { analyzeMusicFromBuffer } from ${JSON.stringify(entry)};
@@ -116775,7 +116810,7 @@ __export(beats_exports, {
116775
116810
  examples: () => examples11
116776
116811
  });
116777
116812
  import { existsSync as existsSync66, readFileSync as readFileSync44, mkdirSync as mkdirSync35, writeFileSync as writeFileSync25 } from "fs";
116778
- import { resolve as resolve45, join as join70, dirname as dirname31 } from "path";
116813
+ import { resolve as resolve45, join as join71, dirname as dirname31 } from "path";
116779
116814
  function fail(message) {
116780
116815
  console.error(c.error(message));
116781
116816
  process.exit(1);
@@ -116845,7 +116880,7 @@ var init_beats2 = __esm({
116845
116880
  if (result.beatTimes.length === 0) {
116846
116881
  fail(`No beats detected in ${rel} \u2014 nothing written. (Track may be silent/ambient.)`);
116847
116882
  }
116848
- const outPath = join70(project.dir, "beats", `${rel}.json`);
116883
+ const outPath = join71(project.dir, "beats", `${rel}.json`);
116849
116884
  mkdirSync35(dirname31(outPath), { recursive: true });
116850
116885
  writeFileSync25(outPath, serializeBeats(result.beatTimes, result.beatStrengths, rel));
116851
116886
  report(`beats/${rel}.json`, result, Boolean(args.json));
@@ -117306,7 +117341,7 @@ var init_motionAudit = __esm({
117306
117341
 
117307
117342
  // src/utils/motionSpec.ts
117308
117343
  import { existsSync as existsSync68, readFileSync as readFileSync45, readdirSync as readdirSync25 } from "fs";
117309
- import { basename as basename13, join as join71 } from "path";
117344
+ import { basename as basename13, join as join73 } from "path";
117310
117345
  function isObject2(value) {
117311
117346
  return typeof value === "object" && value !== null && !Array.isArray(value);
117312
117347
  }
@@ -117352,7 +117387,7 @@ function findMotionSpec(projectDir) {
117352
117387
  const entries2 = readdirSync25(projectDir);
117353
117388
  const sidecars = entries2.filter((name) => name.endsWith(".motion.json")).sort();
117354
117389
  if (!sidecars[0]) return null;
117355
- if (sidecars.length === 1) return join71(projectDir, sidecars[0]);
117390
+ if (sidecars.length === 1) return join73(projectDir, sidecars[0]);
117356
117391
  const htmlBases = new Set(
117357
117392
  entries2.filter((name) => name.endsWith(".html")).map((name) => basename13(name, ".html"))
117358
117393
  );
@@ -117362,7 +117397,7 @@ function findMotionSpec(projectDir) {
117362
117397
  `ambiguous motion sidecars in ${projectDir}: ${matched.join(", ")} each match a composition \u2014 remove the sidecars you do not need, or use one composition per project`
117363
117398
  );
117364
117399
  }
117365
- return join71(projectDir, matched[0] ?? sidecars[0]);
117400
+ return join73(projectDir, matched[0] ?? sidecars[0]);
117366
117401
  }
117367
117402
  function readMotionSpec(path2) {
117368
117403
  let raw;
@@ -117419,7 +117454,7 @@ __export(layout_exports, {
117419
117454
  examples: () => examples12
117420
117455
  });
117421
117456
  import { existsSync as existsSync69, readFileSync as readFileSync46 } from "fs";
117422
- import { dirname as dirname32, join as join73 } from "path";
117457
+ import { dirname as dirname32, join as join74 } from "path";
117423
117458
  import { fileURLToPath as fileURLToPath12 } from "url";
117424
117459
  function buildMotionSampleTimes(duration) {
117425
117460
  if (!Number.isFinite(duration) || duration <= 0) return [];
@@ -117604,7 +117639,7 @@ async function runLayoutAudit(projectDir, opts) {
117604
117639
  }
117605
117640
  }
117606
117641
  function loadBrowserScript(name) {
117607
- const candidates = [join73(__dirname2, name), join73(__dirname2, "commands", name)];
117642
+ const candidates = [join74(__dirname2, name), join74(__dirname2, "commands", name)];
117608
117643
  for (const candidate of candidates) {
117609
117644
  if (existsSync69(candidate)) return readFileSync46(candidate, "utf-8");
117610
117645
  }
@@ -120755,7 +120790,7 @@ __export(info_exports, {
120755
120790
  orientation: () => orientation
120756
120791
  });
120757
120792
  import { readFileSync as readFileSync48, readdirSync as readdirSync26, statSync as statSync24 } from "fs";
120758
- import { join as join74 } from "path";
120793
+ import { join as join75 } from "path";
120759
120794
  function orientation(width, height) {
120760
120795
  if (width > height) return "landscape";
120761
120796
  if (height > width) return "portrait";
@@ -120769,7 +120804,7 @@ function durationFromHtml(html, fallback) {
120769
120804
  function totalSize(dir) {
120770
120805
  let total = 0;
120771
120806
  for (const entry of readdirSync26(dir, { withFileTypes: true })) {
120772
- const path2 = join74(dir, entry.name);
120807
+ const path2 = join75(dir, entry.name);
120773
120808
  if (entry.isDirectory()) {
120774
120809
  total += totalSize(path2);
120775
120810
  } else {
@@ -121037,7 +121072,7 @@ __export(benchmark_exports, {
121037
121072
  examples: () => examples17
121038
121073
  });
121039
121074
  import { existsSync as existsSync73, statSync as statSync25 } from "fs";
121040
- import { resolve as resolve49, join as join75 } from "path";
121075
+ import { resolve as resolve49, join as join76 } from "path";
121041
121076
  var examples17, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
121042
121077
  var init_benchmark = __esm({
121043
121078
  "src/commands/benchmark.ts"() {
@@ -121115,7 +121150,7 @@ var init_benchmark = __esm({
121115
121150
  s2?.start(`Benchmarking ${config.label}...`);
121116
121151
  for (let i2 = 0; i2 < runsPerConfig; i2++) {
121117
121152
  s2?.message(`${config.label} \u2014 run ${i2 + 1}/${runsPerConfig}`);
121118
- const outputPath = join75(
121153
+ const outputPath = join76(
121119
121154
  benchDir,
121120
121155
  `${config.label.replace(/[^a-zA-Z0-9]/g, "_")}_run${i2}.mp4`
121121
121156
  );
@@ -121401,7 +121436,7 @@ __export(manager_exports3, {
121401
121436
  });
121402
121437
  import { existsSync as existsSync74, mkdirSync as mkdirSync36 } from "fs";
121403
121438
  import { homedir as homedir11, platform as platform8, arch } from "os";
121404
- import { join as join76 } from "path";
121439
+ import { join as join77 } from "path";
121405
121440
  function isDevice(value) {
121406
121441
  return typeof value === "string" && DEVICES.includes(value);
121407
121442
  }
@@ -121441,7 +121476,7 @@ function listAvailableProviders() {
121441
121476
  return out;
121442
121477
  }
121443
121478
  function modelPath(model = DEFAULT_MODEL2) {
121444
- return join76(MODELS_DIR2, `${model}.onnx`);
121479
+ return join77(MODELS_DIR2, `${model}.onnx`);
121445
121480
  }
121446
121481
  async function ensureModel2(model = DEFAULT_MODEL2, options) {
121447
121482
  const dest = modelPath(model);
@@ -121459,7 +121494,7 @@ var init_manager3 = __esm({
121459
121494
  "src/background-removal/manager.ts"() {
121460
121495
  "use strict";
121461
121496
  init_download();
121462
- MODELS_DIR2 = join76(homedir11(), ".cache", "hyperframes", "background-removal", "models");
121497
+ MODELS_DIR2 = join77(homedir11(), ".cache", "hyperframes", "background-removal", "models");
121463
121498
  DEFAULT_MODEL2 = "u2net_human_seg";
121464
121499
  MODEL_URLS = {
121465
121500
  u2net_human_seg: "https://github.com/danielgatis/rembg/releases/download/v0.0.0/u2net_human_seg.onnx"
@@ -122170,7 +122205,7 @@ __export(transcribe_exports2, {
122170
122205
  examples: () => examples20
122171
122206
  });
122172
122207
  import { existsSync as existsSync76, writeFileSync as writeFileSync27 } from "fs";
122173
- import { resolve as resolve51, join as join77, extname as extname12, dirname as dirname35 } from "path";
122208
+ import { resolve as resolve51, join as join78, extname as extname12, dirname as dirname35 } from "path";
122174
122209
  function failWith(message, json) {
122175
122210
  trackCommandFailure("transcribe", message);
122176
122211
  if (json) {
@@ -122193,7 +122228,7 @@ async function importTranscript(inputPath, dir, json) {
122193
122228
  const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
122194
122229
  const { words, format } = loadTranscript2(inputPath);
122195
122230
  if (words.length === 0) exitNoWords(json);
122196
- const outPath = join77(dir, "transcript.json");
122231
+ const outPath = join78(dir, "transcript.json");
122197
122232
  writeFileSync27(outPath, JSON.stringify(words, null, 2));
122198
122233
  patchCaptionHtml2(dir, words);
122199
122234
  if (json) {
@@ -122211,7 +122246,7 @@ async function exportTranscript(inputPath, dir, to, output, json, preserveCues)
122211
122246
  const { words, format } = loadTranscript2(inputPath);
122212
122247
  if (words.length === 0) exitNoWords(json);
122213
122248
  const preGrouped = preserveCues || format === "srt" || format === "vtt" || void 0;
122214
- const outPath = resolve51(output ?? join77(dir, `transcript.${to}`));
122249
+ const outPath = resolve51(output ?? join78(dir, `transcript.${to}`));
122215
122250
  const content = to === "srt" ? formatSrt2(words, { preGrouped }) : formatVtt2(words, { preGrouped });
122216
122251
  writeFileSync27(outPath, content);
122217
122252
  if (json) {
@@ -122400,7 +122435,7 @@ var init_transcribe2 = __esm({
122400
122435
  // src/tts/manager.ts
122401
122436
  import { existsSync as existsSync77, mkdirSync as mkdirSync37 } from "fs";
122402
122437
  import { homedir as homedir12 } from "os";
122403
- import { join as join78 } from "path";
122438
+ import { join as join79 } from "path";
122404
122439
  function inferLangFromVoiceId(voiceId) {
122405
122440
  const first = voiceId.charAt(0).toLowerCase();
122406
122441
  return VOICE_PREFIX_LANG[first] ?? "en-us";
@@ -122409,7 +122444,7 @@ function isSupportedLang(value) {
122409
122444
  return SUPPORTED_LANGS.includes(value);
122410
122445
  }
122411
122446
  async function ensureModel3(model = DEFAULT_MODEL3, options) {
122412
- const modelPath2 = join78(MODELS_DIR3, `${model}.onnx`);
122447
+ const modelPath2 = join79(MODELS_DIR3, `${model}.onnx`);
122413
122448
  if (existsSync77(modelPath2)) return modelPath2;
122414
122449
  const url = MODEL_URLS2[model];
122415
122450
  if (!url) {
@@ -122426,7 +122461,7 @@ async function ensureModel3(model = DEFAULT_MODEL3, options) {
122426
122461
  return modelPath2;
122427
122462
  }
122428
122463
  async function ensureVoices(options) {
122429
- const voicesPath = join78(VOICES_DIR, "voices-v1.0.bin");
122464
+ const voicesPath = join79(VOICES_DIR, "voices-v1.0.bin");
122430
122465
  if (existsSync77(voicesPath)) return voicesPath;
122431
122466
  mkdirSync37(VOICES_DIR, { recursive: true });
122432
122467
  options?.onProgress?.("Downloading voice data (~27 MB)...");
@@ -122441,9 +122476,9 @@ var init_manager4 = __esm({
122441
122476
  "src/tts/manager.ts"() {
122442
122477
  "use strict";
122443
122478
  init_download();
122444
- CACHE_DIR3 = join78(homedir12(), ".cache", "hyperframes", "tts");
122445
- MODELS_DIR3 = join78(CACHE_DIR3, "models");
122446
- VOICES_DIR = join78(CACHE_DIR3, "voices");
122479
+ CACHE_DIR3 = join79(homedir12(), ".cache", "hyperframes", "tts");
122480
+ MODELS_DIR3 = join79(CACHE_DIR3, "models");
122481
+ VOICES_DIR = join79(CACHE_DIR3, "voices");
122447
122482
  DEFAULT_MODEL3 = "kokoro-v1.0";
122448
122483
  MODEL_URLS2 = {
122449
122484
  "kokoro-v1.0": "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx"
@@ -122561,7 +122596,7 @@ __export(synthesize_exports, {
122561
122596
  });
122562
122597
  import { execFileSync as execFileSync11 } from "child_process";
122563
122598
  import { existsSync as existsSync78, writeFileSync as writeFileSync28, mkdirSync as mkdirSync38, readdirSync as readdirSync27, unlinkSync as unlinkSync5 } from "fs";
122564
- import { join as join79, dirname as dirname36, basename as basename15 } from "path";
122599
+ import { join as join80, dirname as dirname36, basename as basename15 } from "path";
122565
122600
  import { homedir as homedir13 } from "os";
122566
122601
  function ensureSynthScript() {
122567
122602
  if (!existsSync78(SCRIPT_PATH)) {
@@ -122572,7 +122607,7 @@ function ensureSynthScript() {
122572
122607
  for (const entry of readdirSync27(SCRIPT_DIR)) {
122573
122608
  if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
122574
122609
  try {
122575
- unlinkSync5(join79(SCRIPT_DIR, entry));
122610
+ unlinkSync5(join80(SCRIPT_DIR, entry));
122576
122611
  } catch {
122577
122612
  }
122578
122613
  }
@@ -122683,8 +122718,8 @@ print(json.dumps({
122683
122718
  "langApplied": bool(lang and supports_lang),
122684
122719
  }))
122685
122720
  `;
122686
- SCRIPT_DIR = join79(homedir13(), ".cache", "hyperframes", "tts");
122687
- SCRIPT_PATH = join79(SCRIPT_DIR, "synth-v2.py");
122721
+ SCRIPT_DIR = join80(homedir13(), ".cache", "hyperframes", "tts");
122722
+ SCRIPT_PATH = join80(SCRIPT_DIR, "synth-v2.py");
122688
122723
  }
122689
122724
  });
122690
122725
 
@@ -122898,7 +122933,7 @@ __export(docs_exports, {
122898
122933
  examples: () => examples22
122899
122934
  });
122900
122935
  import { readFileSync as readFileSync51, existsSync as existsSync80 } from "fs";
122901
- import { resolve as resolve53, dirname as dirname37, join as join80 } from "path";
122936
+ import { resolve as resolve53, dirname as dirname37, join as join81 } from "path";
122902
122937
  import { fileURLToPath as fileURLToPath13 } from "url";
122903
122938
  function docsDir() {
122904
122939
  const thisFile = fileURLToPath13(import.meta.url);
@@ -123002,7 +123037,7 @@ var init_docs = __esm({
123002
123037
  }
123003
123038
  process.exit(1);
123004
123039
  }
123005
- const filePath = join80(docsDir(), entry.file);
123040
+ const filePath = join81(docsDir(), entry.file);
123006
123041
  if (!existsSync80(filePath)) {
123007
123042
  console.error(c.error(`Doc file not found: ${filePath}`));
123008
123043
  process.exit(1);
@@ -123833,7 +123868,7 @@ __export(validate_exports, {
123833
123868
  waitForPreferredSeekTarget: () => waitForPreferredSeekTarget
123834
123869
  });
123835
123870
  import { existsSync as existsSync81, readFileSync as readFileSync53 } from "fs";
123836
- import { join as join81, dirname as dirname38 } from "path";
123871
+ import { join as join83, dirname as dirname38 } from "path";
123837
123872
  import { fileURLToPath as fileURLToPath14 } from "url";
123838
123873
  function resolveNavigationTimeoutMs(optTimeout) {
123839
123874
  return Math.max(NAV_TIMEOUT_FLOOR_MS, optTimeout ?? 0);
@@ -123991,8 +124026,8 @@ async function runContrastAudit(page) {
123991
124026
  }
123992
124027
  function loadContrastAuditScript() {
123993
124028
  const candidates = [
123994
- join81(__dirname3, "contrast-audit.browser.js"),
123995
- join81(__dirname3, "commands", "contrast-audit.browser.js")
124029
+ join83(__dirname3, "contrast-audit.browser.js"),
124030
+ join83(__dirname3, "commands", "contrast-audit.browser.js")
123996
124031
  ];
123997
124032
  for (const candidate of candidates) {
123998
124033
  if (existsSync81(candidate)) return readFileSync53(candidate, "utf-8");
@@ -124227,7 +124262,7 @@ __export(contactSheet_exports, {
124227
124262
  });
124228
124263
  import sharp from "sharp";
124229
124264
  import { readdirSync as readdirSync28, readFileSync as readFileSync54, writeFileSync as writeFileSync29, unlinkSync as unlinkSync6, existsSync as existsSync83 } from "fs";
124230
- import { join as join83, extname as extname14, basename as basename16, dirname as dirname39 } from "path";
124265
+ import { join as join84, extname as extname14, basename as basename16, dirname as dirname39 } from "path";
124231
124266
  async function createContactSheet(imagePaths, outputPath, opts = {}) {
124232
124267
  const {
124233
124268
  cols = 3,
@@ -124309,7 +124344,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath) {
124309
124344
  if (!existsSync83(screenshotsDir)) return [];
124310
124345
  const scrollFiles = readdirSync28(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
124311
124346
  if (scrollFiles.length === 0) return [];
124312
- const paths = scrollFiles.map((f3) => join83(screenshotsDir, f3));
124347
+ const paths = scrollFiles.map((f3) => join84(screenshotsDir, f3));
124313
124348
  const labels = scrollFiles.map((f3) => {
124314
124349
  const m2 = f3.match(/scroll-(\d+)\.png/);
124315
124350
  return m2 ? `${m2[1]}% scroll` : f3;
@@ -124326,7 +124361,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath) {
124326
124361
  if (!existsSync83(snapshotsDir)) return [];
124327
124362
  const snapshotFiles = readdirSync28(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
124328
124363
  if (snapshotFiles.length === 0) return [];
124329
- const paths = snapshotFiles.map((f3) => join83(snapshotsDir, f3));
124364
+ const paths = snapshotFiles.map((f3) => join84(snapshotsDir, f3));
124330
124365
  const labels = snapshotFiles.map((f3) => {
124331
124366
  const m2 = f3.match(/at-([\d.]+)s/);
124332
124367
  return m2 ? `${m2[1]}s` : f3;
@@ -124344,7 +124379,7 @@ async function createAssetContactSheet(assetsDir, outputPath) {
124344
124379
  const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
124345
124380
  const assetFiles = readdirSync28(assetsDir).filter((f3) => imageExts.has(extname14(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
124346
124381
  if (assetFiles.length === 0) return [];
124347
- const paths = assetFiles.map((f3) => join83(assetsDir, f3));
124382
+ const paths = assetFiles.map((f3) => join84(assetsDir, f3));
124348
124383
  return createContactSheetPages(paths, outputPath, {
124349
124384
  cols: 4,
124350
124385
  cellWidth: 480,
@@ -124363,7 +124398,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
124363
124398
  for (const f3 of readdirSync28(dir).filter((f4) => f4.endsWith(".svg")).sort()) {
124364
124399
  if (!seen.has(f3)) {
124365
124400
  seen.add(f3);
124366
- svgPaths.push(join83(dir, f3));
124401
+ svgPaths.push(join84(dir, f3));
124367
124402
  }
124368
124403
  }
124369
124404
  }
@@ -124375,7 +124410,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
124375
124410
  const labels = [];
124376
124411
  for (let i2 = 0; i2 < svgPaths.length; i2++) {
124377
124412
  const svgPath = svgPaths[i2];
124378
- const tmpPath = join83(tmpDir, `.thumb-${i2}.png`);
124413
+ const tmpPath = join84(tmpDir, `.thumb-${i2}.png`);
124379
124414
  try {
124380
124415
  const svgBuf = readFileSync54(svgPath);
124381
124416
  const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
@@ -155733,10 +155768,10 @@ function iterBinaryChunks(iterator) {
155733
155768
  }
155734
155769
  });
155735
155770
  }
155736
- function partition(str, delimiter) {
155737
- const index = str.indexOf(delimiter);
155771
+ function partition(str, delimiter2) {
155772
+ const index = str.indexOf(delimiter2);
155738
155773
  if (index !== -1) {
155739
- return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
155774
+ return [str.substring(0, index), delimiter2, str.substring(index + delimiter2.length)];
155740
155775
  }
155741
155776
  return [str, "", ""];
155742
155777
  }
@@ -159537,11 +159572,11 @@ var init_node4 = __esm({
159537
159572
  while (true) {
159538
159573
  delimiterIndex = -1;
159539
159574
  delimiterLength = 0;
159540
- for (const delimiter of delimiters) {
159541
- const index = buffer.indexOf(delimiter);
159575
+ for (const delimiter2 of delimiters) {
159576
+ const index = buffer.indexOf(delimiter2);
159542
159577
  if (index !== -1 && (delimiterIndex === -1 || index < delimiterIndex)) {
159543
159578
  delimiterIndex = index;
159544
- delimiterLength = delimiter.length;
159579
+ delimiterLength = delimiter2.length;
159545
159580
  }
159546
159581
  }
159547
159582
  if (delimiterIndex === -1) {
@@ -164159,7 +164194,7 @@ __export(snapshot_exports, {
164159
164194
  import { spawn as spawn16 } from "child_process";
164160
164195
  import { existsSync as existsSync84, mkdtempSync as mkdtempSync6, readFileSync as readFileSync55, mkdirSync as mkdirSync39, rmSync as rmSync19, writeFileSync as writeFileSync30 } from "fs";
164161
164196
  import { tmpdir as tmpdir7 } from "os";
164162
- import { resolve as resolve55, join as join84, relative as relative15, isAbsolute as isAbsolute14, basename as basename19 } from "path";
164197
+ import { resolve as resolve55, join as join85, relative as relative15, isAbsolute as isAbsolute14, basename as basename19 } from "path";
164163
164198
  function orbitStageSource() {
164164
164199
  return `function(cam) {
164165
164200
  var root = document.querySelector("[data-composition-id]")
@@ -164182,8 +164217,8 @@ function orbitStageSource() {
164182
164217
  }`;
164183
164218
  }
164184
164219
  async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
164185
- const tmp = mkdtempSync6(join84(tmpdir7(), "hf-snapshot-frame-"));
164186
- const outPath = join84(tmp, "frame.png");
164220
+ const tmp = mkdtempSync6(join85(tmpdir7(), "hf-snapshot-frame-"));
164221
+ const outPath = join85(tmp, "frame.png");
164187
164222
  try {
164188
164223
  const ffmpegPath = findFFmpeg();
164189
164224
  if (!ffmpegPath) return null;
@@ -164358,13 +164393,13 @@ async function captureSnapshots(projectDir, opts) {
164358
164393
  );
164359
164394
  }
164360
164395
  const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
164361
- const snapshotDir = opts.outputDir ?? join84(projectDir, "snapshots");
164396
+ const snapshotDir = opts.outputDir ?? join85(projectDir, "snapshots");
164362
164397
  mkdirSync39(snapshotDir, { recursive: true });
164363
164398
  try {
164364
164399
  const { readdirSync: readdirSync35 } = await import("fs");
164365
164400
  for (const file of readdirSync35(snapshotDir)) {
164366
164401
  if (/\.(png|jpg|jpeg)$/i.test(file)) {
164367
- rmSync19(join84(snapshotDir, file), { force: true });
164402
+ rmSync19(join85(snapshotDir, file), { force: true });
164368
164403
  }
164369
164404
  }
164370
164405
  } catch {
@@ -164481,7 +164516,7 @@ async function captureSnapshots(projectDir, opts) {
164481
164516
  }
164482
164517
  const timeLabel = `${time.toFixed(1)}s`;
164483
164518
  const filename = `frame-${String(i2).padStart(2, "0")}-at-${timeLabel}.png`;
164484
- const framePath = join84(snapshotDir, filename);
164519
+ const framePath = join85(snapshotDir, filename);
164485
164520
  await page.screenshot({ path: framePath, type: "png" });
164486
164521
  const rel = relative15(projectDir, framePath);
164487
164522
  savedPaths.push(rel.startsWith("..") || isAbsolute14(rel) ? framePath : rel);
@@ -164567,7 +164602,7 @@ var init_snapshot = __esm({
164567
164602
  const angleLabel = camera && (camera.yaw !== 0 || camera.pitch !== 0) ? ` ${c.dim(`(angle yaw ${camera.yaw}\xB0 pitch ${camera.pitch}\xB0)`)}` : "";
164568
164603
  console.log(`${c.accent("\u25C6")} Capturing ${label2} from ${c.accent(project.name)}${angleLabel}`);
164569
164604
  try {
164570
- const snapshotDir = args.output ? resolve55(String(args.output)) : join84(project.dir, "snapshots");
164605
+ const snapshotDir = args.output ? resolve55(String(args.output)) : join85(project.dir, "snapshots");
164571
164606
  const paths = await captureSnapshots(project.dir, {
164572
164607
  frames,
164573
164608
  timeout,
@@ -164594,7 +164629,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164594
164629
  const { createSnapshotContactSheet: createSnapshotContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
164595
164630
  const sheets = await createSnapshotContactSheet2(
164596
164631
  snapshotDir,
164597
- join84(snapshotDir, "contact-sheet.jpg")
164632
+ join85(snapshotDir, "contact-sheet.jpg")
164598
164633
  );
164599
164634
  if (sheets.length > 0) {
164600
164635
  const label3 = sheets.length === 1 ? "contact-sheet.jpg" : `contact-sheet-1..${sheets.length}.jpg`;
@@ -164630,7 +164665,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164630
164665
  const results = await Promise.allSettled(
164631
164666
  paths.map(async (p2) => {
164632
164667
  const filename = basename19(p2);
164633
- const filePath = join84(snapshotDir, filename);
164668
+ const filePath = join85(snapshotDir, filename);
164634
164669
  if (!existsSync84(filePath)) return { filename, desc: "file not found" };
164635
164670
  const raw = readFileSync55(filePath);
164636
164671
  let imageData;
@@ -164668,7 +164703,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
164668
164703
  descriptions.push(`## (error)`, `Gemini call failed: ${errMsg.slice(0, 120)}`, ``);
164669
164704
  }
164670
164705
  }
164671
- const descPath = join84(snapshotDir, "descriptions.md");
164706
+ const descPath = join85(snapshotDir, "descriptions.md");
164672
164707
  writeFileSync30(descPath, descriptions.join("\n"));
164673
164708
  console.log(` ${c.dim("descriptions.md")} (Gemini frame analysis)`);
164674
164709
  }
@@ -164690,18 +164725,18 @@ ${c.error("\u2717")} Snapshot failed: ${msg}`);
164690
164725
 
164691
164726
  // src/capture/assetDownloader.ts
164692
164727
  import { writeFileSync as writeFileSync31, mkdirSync as mkdirSync40 } from "fs";
164693
- import { join as join85, extname as extname15 } from "path";
164728
+ import { join as join86, extname as extname15 } from "path";
164694
164729
  import { createHash as createHash12 } from "crypto";
164695
164730
  function svgContentHashSlug(svgSource, isLogo) {
164696
164731
  const hash2 = createHash12("sha1").update(svgSource).digest("hex").slice(0, 8);
164697
164732
  return isLogo ? `logo-${hash2}` : `svg-${hash2}`;
164698
164733
  }
164699
164734
  async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks) {
164700
- const assetsDir = join85(outputDir, "assets");
164735
+ const assetsDir = join86(outputDir, "assets");
164701
164736
  mkdirSync40(assetsDir, { recursive: true });
164702
164737
  const assets = [];
164703
164738
  const downloadedUrls = /* @__PURE__ */ new Set();
164704
- mkdirSync40(join85(outputDir, "assets", "svgs"), { recursive: true });
164739
+ mkdirSync40(join86(outputDir, "assets", "svgs"), { recursive: true });
164705
164740
  const usedSvgNames = /* @__PURE__ */ new Set();
164706
164741
  for (let i2 = 0; i2 < tokens.svgs.length && i2 < 30; i2++) {
164707
164742
  const svg = tokens.svgs[i2];
@@ -164717,7 +164752,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164717
164752
  const name = `${finalSlug}.svg`;
164718
164753
  const localPath = `assets/svgs/${name}`;
164719
164754
  try {
164720
- writeFileSync31(join85(outputDir, localPath), svg.outerHTML, "utf-8");
164755
+ writeFileSync31(join86(outputDir, localPath), svg.outerHTML, "utf-8");
164721
164756
  assets.push({ url: "", localPath, type: "svg" });
164722
164757
  } catch {
164723
164758
  }
@@ -164730,7 +164765,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164730
164765
  const localPath = `assets/${name}`;
164731
164766
  const buffer = await fetchBuffer(icon.href);
164732
164767
  if (buffer) {
164733
- writeFileSync31(join85(outputDir, localPath), buffer);
164768
+ writeFileSync31(join86(outputDir, localPath), buffer);
164734
164769
  assets.push({ url: icon.href, localPath, type: "favicon" });
164735
164770
  break;
164736
164771
  }
@@ -164795,7 +164830,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164795
164830
  const name = `${slug}${ext}`;
164796
164831
  usedNames.add(slug);
164797
164832
  const localPath = `assets/${name}`;
164798
- writeFileSync31(join85(outputDir, localPath), buffer);
164833
+ writeFileSync31(join86(outputDir, localPath), buffer);
164799
164834
  assets.push({ url, localPath, type: "image" });
164800
164835
  imgIdx++;
164801
164836
  } catch {
@@ -164808,7 +164843,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
164808
164843
  const localPath = `assets/og-image${ext}`;
164809
164844
  const buffer = await fetchBuffer(tokens.ogImage);
164810
164845
  if (buffer && buffer.length > 5e3) {
164811
- writeFileSync31(join85(outputDir, localPath), buffer);
164846
+ writeFileSync31(join86(outputDir, localPath), buffer);
164812
164847
  assets.push({ url: tokens.ogImage, localPath, type: "image" });
164813
164848
  }
164814
164849
  } catch {
@@ -164831,7 +164866,7 @@ function normalizeUrl(u) {
164831
164866
  }
164832
164867
  }
164833
164868
  async function downloadAndRewriteFonts(css, outputDir) {
164834
- const assetsDir = join85(outputDir, "assets", "fonts");
164869
+ const assetsDir = join86(outputDir, "assets", "fonts");
164835
164870
  mkdirSync40(assetsDir, { recursive: true });
164836
164871
  const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
164837
164872
  const fontUrls = /* @__PURE__ */ new Set();
@@ -164867,7 +164902,7 @@ async function downloadAndRewriteFonts(css, outputDir) {
164867
164902
  try {
164868
164903
  const urlObj = new URL(fontUrl);
164869
164904
  const filename = urlObj.pathname.split("/").pop() || `font-${count}.woff2`;
164870
- const localPath = join85(assetsDir, filename);
164905
+ const localPath = join86(assetsDir, filename);
164871
164906
  const relativePath = `assets/fonts/${filename}`;
164872
164907
  const buffer = await fetchBuffer(fontUrl);
164873
164908
  if (buffer) {
@@ -165026,7 +165061,7 @@ __export(video_exports, {
165026
165061
  safeFilename: () => safeFilename
165027
165062
  });
165028
165063
  import { createWriteStream as createWriteStream4, existsSync as existsSync85, mkdirSync as mkdirSync41, readFileSync as readFileSync56, unlinkSync as unlinkSync7 } from "fs";
165029
- import { resolve as resolve56, join as join86, basename as basename20 } from "path";
165064
+ import { resolve as resolve56, join as join87, basename as basename20 } from "path";
165030
165065
  async function streamToFile(url, destPath) {
165031
165066
  const r2 = await safeFetch(url, {
165032
165067
  signal: AbortSignal.timeout(12e4),
@@ -165145,8 +165180,8 @@ function pickManifestEntry(manifest, args) {
165145
165180
  }
165146
165181
  async function runVideoMode(args) {
165147
165182
  const projectDir = resolve56(args.project);
165148
- const directPath = join86(projectDir, "extracted", "video-manifest.json");
165149
- const w2hPath = join86(projectDir, "capture", "extracted", "video-manifest.json");
165183
+ const directPath = join87(projectDir, "extracted", "video-manifest.json");
165184
+ const w2hPath = join87(projectDir, "capture", "extracted", "video-manifest.json");
165150
165185
  const manifestPath2 = existsSync85(directPath) ? directPath : w2hPath;
165151
165186
  const isW2hLayout = manifestPath2 === w2hPath;
165152
165187
  if (!existsSync85(manifestPath2)) {
@@ -165200,10 +165235,10 @@ async function runVideoMode(args) {
165200
165235
  process.exitCode = 1;
165201
165236
  return;
165202
165237
  }
165203
- const outDir = isW2hLayout ? join86(projectDir, "capture", "assets", "videos") : join86(projectDir, "assets", "videos");
165238
+ const outDir = isW2hLayout ? join87(projectDir, "capture", "assets", "videos") : join87(projectDir, "assets", "videos");
165204
165239
  mkdirSync41(outDir, { recursive: true });
165205
165240
  const fname = safeFilename(entry.filename || basename20(entry.url));
165206
- const outPath = join86(outDir, fname);
165241
+ const outPath = join87(outDir, fname);
165207
165242
  const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
165208
165243
  console.log(
165209
165244
  `${c.accent("\u25B8")} downloading [${entry.index}] ${entry.filename} (${entry.sourceWidth || entry.width}\xD7${entry.sourceHeight || entry.height})`
@@ -166447,7 +166482,7 @@ var init_designStyleExtractor = __esm({
166447
166482
 
166448
166483
  // src/capture/fontMetadataExtractor.ts
166449
166484
  import { readdirSync as readdirSync29, readFileSync as readFileSync57, writeFileSync as writeFileSync33, existsSync as existsSync86 } from "fs";
166450
- import { join as join87 } from "path";
166485
+ import { join as join88 } from "path";
166451
166486
  import * as fontkit from "fontkit";
166452
166487
  function isFontCollection(value) {
166453
166488
  return value.type === "TTC" || value.type === "DFont";
@@ -166458,7 +166493,7 @@ function extractFontMetadata(fontsDir, outputPath) {
166458
166493
  if (existsSync86(fontsDir)) {
166459
166494
  const fontFiles = readdirSync29(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
166460
166495
  for (const filename of fontFiles) {
166461
- const fullPath = join87(fontsDir, filename);
166496
+ const fullPath = join88(fontsDir, filename);
166462
166497
  const meta = readSingleFont(fullPath, filename);
166463
166498
  if (meta.identified) {
166464
166499
  files.push(meta);
@@ -166770,7 +166805,7 @@ var init_animationCataloger = __esm({
166770
166805
 
166771
166806
  // src/capture/mediaCapture.ts
166772
166807
  import { mkdirSync as mkdirSync43, writeFileSync as writeFileSync34, readdirSync as readdirSync30, readFileSync as readFileSync58, statSync as statSync27 } from "fs";
166773
- import { join as join88, extname as extname16 } from "path";
166808
+ import { join as join89, extname as extname16 } from "path";
166774
166809
  async function saveLottieAnimations(discoveredLotties, lottieDir) {
166775
166810
  let savedCount = 0;
166776
166811
  const savedHashes = /* @__PURE__ */ new Set();
@@ -166802,7 +166837,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166802
166837
  const hash2 = buf.toString("base64").slice(0, 100);
166803
166838
  if (savedHashes.has(hash2)) continue;
166804
166839
  savedHashes.add(hash2);
166805
- writeFileSync34(join88(lottieDir, `animation-${savedCount}.lottie`), buf);
166840
+ writeFileSync34(join89(lottieDir, `animation-${savedCount}.lottie`), buf);
166806
166841
  savedCount++;
166807
166842
  continue;
166808
166843
  }
@@ -166820,7 +166855,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166820
166855
  } catch {
166821
166856
  continue;
166822
166857
  }
166823
- writeFileSync34(join88(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
166858
+ writeFileSync34(join89(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
166824
166859
  savedCount++;
166825
166860
  }
166826
166861
  } catch {
@@ -166830,22 +166865,22 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
166830
166865
  }
166831
166866
  async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166832
166867
  const manifest = [];
166833
- const previewDir = join88(lottieDir, "previews");
166868
+ const previewDir = join89(lottieDir, "previews");
166834
166869
  mkdirSync43(previewDir, { recursive: true });
166835
166870
  for (const file of readdirSync30(lottieDir)) {
166836
166871
  if (!file.endsWith(".json")) continue;
166837
166872
  try {
166838
- const raw = JSON.parse(readFileSync58(join88(lottieDir, file), "utf-8"));
166873
+ const raw = JSON.parse(readFileSync58(join89(lottieDir, file), "utf-8"));
166839
166874
  const fr = raw.fr || 30;
166840
166875
  const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
166841
166876
  const previewName = file.replace(".json", "-preview.png");
166842
- const fileSize = statSync27(join88(lottieDir, file)).size;
166877
+ const fileSize = statSync27(join89(lottieDir, file)).size;
166843
166878
  if (fileSize > 2e6) continue;
166844
166879
  let previewPage;
166845
166880
  try {
166846
166881
  previewPage = await chromeBrowser.newPage();
166847
166882
  await previewPage.setViewport({ width: 400, height: 400 });
166848
- const animData = JSON.parse(readFileSync58(join88(lottieDir, file), "utf-8"));
166883
+ const animData = JSON.parse(readFileSync58(join89(lottieDir, file), "utf-8"));
166849
166884
  const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
166850
166885
  await previewPage.setContent(
166851
166886
  `<!DOCTYPE html>
@@ -166875,7 +166910,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166875
166910
  await previewPage.waitForFunction(() => window.__READY === true, { timeout: 5e3 }).catch(() => {
166876
166911
  });
166877
166912
  await previewPage.screenshot({
166878
- path: join88(previewDir, previewName),
166913
+ path: join89(previewDir, previewName),
166879
166914
  type: "png",
166880
166915
  omitBackground: true
166881
166916
  });
@@ -166899,7 +166934,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
166899
166934
  }
166900
166935
  if (manifest.length > 0) {
166901
166936
  writeFileSync34(
166902
- join88(outputDir, "extracted", "lottie-manifest.json"),
166937
+ join89(outputDir, "extracted", "lottie-manifest.json"),
166903
166938
  JSON.stringify(manifest, null, 2),
166904
166939
  "utf-8"
166905
166940
  );
@@ -166934,7 +166969,7 @@ async function downloadVideoBody(srcUrl, filename, videosDir) {
166934
166969
  }
166935
166970
  if (total < 1024) return null;
166936
166971
  const safe = /\.[a-z0-9]+$/i.test(filename) ? filename.replace(/[^\w.-]/g, "_") : `video${ext}`;
166937
- writeFileSync34(join88(videosDir, safe), Buffer.concat(chunks));
166972
+ writeFileSync34(join89(videosDir, safe), Buffer.concat(chunks));
166938
166973
  return `assets/videos/${safe}`;
166939
166974
  } catch {
166940
166975
  return null;
@@ -166996,9 +167031,9 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
166996
167031
  }
166997
167032
  const merged = [...byKey.values()];
166998
167033
  if (merged.length === 0) return;
166999
- const videoManifestDir = join88(outputDir, "assets", "videos");
167034
+ const videoManifestDir = join89(outputDir, "assets", "videos");
167000
167035
  mkdirSync43(videoManifestDir, { recursive: true });
167001
- const previewDir = join88(videoManifestDir, "previews");
167036
+ const previewDir = join89(videoManifestDir, "previews");
167002
167037
  mkdirSync43(previewDir, { recursive: true });
167003
167038
  const videoManifest = [];
167004
167039
  const dlStart = Date.now();
@@ -167021,7 +167056,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
167021
167056
  if (rect && rect.width >= 10) {
167022
167057
  await new Promise((r2) => setTimeout(r2, 200));
167023
167058
  await page.screenshot({
167024
- path: join88(previewDir, previewName),
167059
+ path: join89(previewDir, previewName),
167025
167060
  clip: {
167026
167061
  x: Math.max(0, rect.x),
167027
167062
  y: Math.max(0, rect.y),
@@ -167053,7 +167088,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
167053
167088
  }
167054
167089
  if (videoManifest.length > 0) {
167055
167090
  writeFileSync34(
167056
- join88(outputDir, "extracted", "video-manifest.json"),
167091
+ join89(outputDir, "extracted", "video-manifest.json"),
167057
167092
  JSON.stringify(videoManifest, null, 2),
167058
167093
  "utf-8"
167059
167094
  );
@@ -167122,7 +167157,7 @@ var init_mediaCapture = __esm({
167122
167157
 
167123
167158
  // src/capture/contentExtractor.ts
167124
167159
  import { existsSync as existsSync87, readdirSync as readdirSync31, statSync as statSync28, readFileSync as readFileSync59 } from "fs";
167125
- import { basename as basename21, join as join89 } from "path";
167160
+ import { basename as basename21, join as join90 } from "path";
167126
167161
  async function detectLibraries(page, capturedShaders) {
167127
167162
  let detectedLibraries = [];
167128
167163
  try {
@@ -167289,7 +167324,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167289
167324
  return response.text?.trim() || "";
167290
167325
  };
167291
167326
  }
167292
- const imageFiles = readdirSync31(join89(outputDir, "assets")).filter(
167327
+ const imageFiles = readdirSync31(join90(outputDir, "assets")).filter(
167293
167328
  (f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
167294
167329
  );
167295
167330
  const BATCH_SIZE = 20;
@@ -167297,7 +167332,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167297
167332
  const batch = imageFiles.slice(i2, i2 + BATCH_SIZE);
167298
167333
  const results = await Promise.allSettled(
167299
167334
  batch.map(async (file) => {
167300
- const filePath = join89(outputDir, "assets", file);
167335
+ const filePath = join90(outputDir, "assets", file);
167301
167336
  const stat3 = statSync28(filePath);
167302
167337
  if (stat3.size > 4e6) return { file, caption: "" };
167303
167338
  const buffer = readFileSync59(filePath);
@@ -167331,11 +167366,11 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167331
167366
  `${Object.keys(geminiCaptions).length} images captioned with ${providerName}`
167332
167367
  );
167333
167368
  const svgFiles = [];
167334
- const assetsDir = join89(outputDir, "assets");
167369
+ const assetsDir = join90(outputDir, "assets");
167335
167370
  for (const f3 of readdirSync31(assetsDir)) {
167336
167371
  if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
167337
167372
  }
167338
- const svgsSubdir = join89(assetsDir, "svgs");
167373
+ const svgsSubdir = join90(assetsDir, "svgs");
167339
167374
  if (existsSync87(svgsSubdir)) {
167340
167375
  for (const f3 of readdirSync31(svgsSubdir)) {
167341
167376
  if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
@@ -167359,7 +167394,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
167359
167394
  const batch = svgFiles.slice(i2, i2 + SVG_BATCH);
167360
167395
  const results = await Promise.allSettled(
167361
167396
  batch.map(async ({ relPath }) => {
167362
- const filePath = join89(assetsDir, relPath);
167397
+ const filePath = join90(assetsDir, relPath);
167363
167398
  let pngBase64;
167364
167399
  try {
167365
167400
  const svgSource = readFileSync59(filePath, "utf-8");
@@ -167417,11 +167452,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167417
167452
  const uncaptionedLines = [];
167418
167453
  const svgLines = [];
167419
167454
  const fontLines = [];
167420
- const assetsPath = join89(outputDir, "assets");
167455
+ const assetsPath = join90(outputDir, "assets");
167421
167456
  try {
167422
167457
  for (const file of readdirSync31(assetsPath)) {
167423
167458
  if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
167424
- const filePath = join89(assetsPath, file);
167459
+ const filePath = join90(assetsPath, file);
167425
167460
  const stat3 = statSync28(filePath);
167426
167461
  if (!stat3.isFile()) continue;
167427
167462
  const sizeKb = Math.round(stat3.size / 1024);
@@ -167450,7 +167485,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167450
167485
  } catch {
167451
167486
  }
167452
167487
  try {
167453
- const svgsPath = join89(assetsPath, "svgs");
167488
+ const svgsPath = join90(assetsPath, "svgs");
167454
167489
  for (const file of readdirSync31(svgsPath)) {
167455
167490
  if (!file.endsWith(".svg")) continue;
167456
167491
  const svgMatch = tokens.svgs.find(
@@ -167469,7 +167504,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167469
167504
  } catch {
167470
167505
  }
167471
167506
  try {
167472
- const fontsPath = join89(assetsPath, "fonts");
167507
+ const fontsPath = join90(assetsPath, "fonts");
167473
167508
  for (const file of readdirSync31(fontsPath)) {
167474
167509
  fontLines.push(`fonts/${file} \u2014 font file`);
167475
167510
  }
@@ -167478,7 +167513,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
167478
167513
  const videoLines = [];
167479
167514
  try {
167480
167515
  const manifest = JSON.parse(
167481
- readFileSync59(join89(outputDir, "extracted", "video-manifest.json"), "utf-8")
167516
+ readFileSync59(join90(outputDir, "extracted", "video-manifest.json"), "utf-8")
167482
167517
  );
167483
167518
  for (const v2 of manifest) {
167484
167519
  if (!v2.localPath) continue;
@@ -167506,7 +167541,7 @@ __export(agentPromptGenerator_exports, {
167506
167541
  generateAgentPrompt: () => generateAgentPrompt
167507
167542
  });
167508
167543
  import { writeFileSync as writeFileSync35, readdirSync as readdirSync33, existsSync as existsSync88 } from "fs";
167509
- import { join as join90 } from "path";
167544
+ import { join as join91 } from "path";
167510
167545
  function inferColorRole(hex) {
167511
167546
  const r2 = parseInt(hex.slice(1, 3), 16) / 255;
167512
167547
  const g = parseInt(hex.slice(3, 5), 16) / 255;
@@ -167525,9 +167560,9 @@ function inferColorRole(hex) {
167525
167560
  }
167526
167561
  function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
167527
167562
  const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
167528
- writeFileSync35(join90(outputDir, "AGENTS.md"), prompt, "utf-8");
167529
- writeFileSync35(join90(outputDir, "CLAUDE.md"), prompt, "utf-8");
167530
- writeFileSync35(join90(outputDir, ".cursorrules"), prompt, "utf-8");
167563
+ writeFileSync35(join91(outputDir, "AGENTS.md"), prompt, "utf-8");
167564
+ writeFileSync35(join91(outputDir, "CLAUDE.md"), prompt, "utf-8");
167565
+ writeFileSync35(join91(outputDir, ".cursorrules"), prompt, "utf-8");
167531
167566
  }
167532
167567
  function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
167533
167568
  const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
@@ -167536,7 +167571,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
167536
167571
  (f3) => f3.family + (f3.variable && f3.weightRange ? ` (${f3.weightRange[0]}-${f3.weightRange[1]} variable)` : f3.weights.length > 0 ? ` (${f3.weights.join(",")})` : "")
167537
167572
  ).join(", ") || "none detected";
167538
167573
  function contactSheetRows(dir, baseFile, label2) {
167539
- const fullDir = join90(outputDir, dir);
167574
+ const fullDir = join91(outputDir, dir);
167540
167575
  if (!existsSync88(fullDir)) return [];
167541
167576
  const baseName = baseFile.replace(/\.jpg$/, "");
167542
167577
  const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -167569,7 +167604,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
167569
167604
  tableRows.push(
167570
167605
  `| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
167571
167606
  );
167572
- if (existsSync88(join90(outputDir, "extracted", "design-styles.json"))) {
167607
+ if (existsSync88(join91(outputDir, "extracted", "design-styles.json"))) {
167573
167608
  tableRows.push(
167574
167609
  "| `extracted/design-styles.json` | Computed styles from live DOM: typography hierarchy, button/card/nav styles, spacing scale, border-radius, box shadows. Primary data source for DESIGN.md. |"
167575
167610
  );
@@ -167641,7 +167676,7 @@ var init_agentPromptGenerator = __esm({
167641
167676
 
167642
167677
  // src/capture/scaffolding.ts
167643
167678
  import { existsSync as existsSync89, writeFileSync as writeFileSync36, readFileSync as readFileSync60 } from "fs";
167644
- import { join as join91, resolve as resolve57 } from "path";
167679
+ import { join as join93, resolve as resolve57 } from "path";
167645
167680
  function loadEnvFile(startDir) {
167646
167681
  try {
167647
167682
  let dir = resolve57(startDir);
@@ -167667,7 +167702,7 @@ function loadEnvFile(startDir) {
167667
167702
  }
167668
167703
  }
167669
167704
  async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
167670
- const metaPath = join91(outputDir, "meta.json");
167705
+ const metaPath = join93(outputDir, "meta.json");
167671
167706
  if (!existsSync89(metaPath)) {
167672
167707
  const hostname = new URL(url).hostname.replace(/^www\./, "");
167673
167708
  writeFileSync36(
@@ -167706,9 +167741,9 @@ __export(screenshotCapture_exports, {
167706
167741
  captureScrollScreenshots: () => captureScrollScreenshots
167707
167742
  });
167708
167743
  import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync44 } from "fs";
167709
- import { join as join93 } from "path";
167744
+ import { join as join94 } from "path";
167710
167745
  async function captureScrollScreenshots(page, outputDir) {
167711
- const screenshotsDir = join93(outputDir, "screenshots");
167746
+ const screenshotsDir = join94(outputDir, "screenshots");
167712
167747
  mkdirSync44(screenshotsDir, { recursive: true });
167713
167748
  const MAX_SCREENSHOTS = 20;
167714
167749
  const filePaths = [];
@@ -167800,7 +167835,7 @@ async function captureScrollScreenshots(page, outputDir) {
167800
167835
  finalPositions[i2] / Math.max(1, scrollHeight - viewportHeight) * 100
167801
167836
  );
167802
167837
  const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
167803
- const filePath = join93(screenshotsDir, filename);
167838
+ const filePath = join94(screenshotsDir, filename);
167804
167839
  const buffer = await page.screenshot({ type: "png" });
167805
167840
  writeFileSync37(filePath, buffer);
167806
167841
  filePaths.push(`screenshots/${filename}`);
@@ -168150,7 +168185,7 @@ __export(capture_exports, {
168150
168185
  captureWebsite: () => captureWebsite
168151
168186
  });
168152
168187
  import { mkdirSync as mkdirSync45, writeFileSync as writeFileSync38, existsSync as existsSync90 } from "fs";
168153
- import { join as join94 } from "path";
168188
+ import { join as join95 } from "path";
168154
168189
  async function captureWebsite(opts, onProgress) {
168155
168190
  const {
168156
168191
  url,
@@ -168167,9 +168202,9 @@ async function captureWebsite(opts, onProgress) {
168167
168202
  onProgress?.(stage, detail);
168168
168203
  };
168169
168204
  loadEnvFile(outputDir);
168170
- mkdirSync45(join94(outputDir, "extracted"), { recursive: true });
168171
- mkdirSync45(join94(outputDir, "screenshots"), { recursive: true });
168172
- mkdirSync45(join94(outputDir, "assets"), { recursive: true });
168205
+ mkdirSync45(join95(outputDir, "extracted"), { recursive: true });
168206
+ mkdirSync45(join95(outputDir, "screenshots"), { recursive: true });
168207
+ mkdirSync45(join95(outputDir, "assets"), { recursive: true });
168173
168208
  progress("browser", "Launching headless Chrome...");
168174
168209
  const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
168175
168210
  const browser = await ensureBrowser2();
@@ -168329,7 +168364,7 @@ async function captureWebsite(opts, onProgress) {
168329
168364
  } catch {
168330
168365
  }
168331
168366
  if (discoveredLotties.length > 0) {
168332
- const lottieDir = join94(outputDir, "assets", "lottie");
168367
+ const lottieDir = join95(outputDir, "assets", "lottie");
168333
168368
  mkdirSync45(lottieDir, { recursive: true });
168334
168369
  const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir);
168335
168370
  if (savedCount > 0) {
@@ -168349,7 +168384,7 @@ async function captureWebsite(opts, onProgress) {
168349
168384
  });
168350
168385
  capturedShaders = unique;
168351
168386
  writeFileSync38(
168352
- join94(outputDir, "extracted", "shaders.json"),
168387
+ join95(outputDir, "extracted", "shaders.json"),
168353
168388
  JSON.stringify(unique, null, 2),
168354
168389
  "utf-8"
168355
168390
  );
@@ -168364,7 +168399,7 @@ async function captureWebsite(opts, onProgress) {
168364
168399
  svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
168365
168400
  };
168366
168401
  writeFileSync38(
168367
- join94(outputDir, "extracted", "tokens.json"),
168402
+ join95(outputDir, "extracted", "tokens.json"),
168368
168403
  JSON.stringify(tokensForDisk, null, 2),
168369
168404
  "utf-8"
168370
168405
  );
@@ -168372,7 +168407,7 @@ async function captureWebsite(opts, onProgress) {
168372
168407
  try {
168373
168408
  const designStyles = await extractDesignStyles(page1);
168374
168409
  writeFileSync38(
168375
- join94(outputDir, "extracted", "design-styles.json"),
168410
+ join95(outputDir, "extracted", "design-styles.json"),
168376
168411
  JSON.stringify(designStyles, null, 2),
168377
168412
  "utf-8"
168378
168413
  );
@@ -168451,8 +168486,8 @@ ${err.stack}` : normalizeErrorMessage(err);
168451
168486
  extracted.headHtml = await downloadAndRewriteFonts(extracted.headHtml, outputDir);
168452
168487
  try {
168453
168488
  const fontsManifest = extractFontMetadata(
168454
- join94(outputDir, "assets", "fonts"),
168455
- join94(outputDir, "extracted", "fonts-manifest.json")
168489
+ join95(outputDir, "assets", "fonts"),
168490
+ join95(outputDir, "extracted", "fonts-manifest.json")
168456
168491
  );
168457
168492
  if (fontsManifest.families.length > 0) {
168458
168493
  const summary = fontsManifest.families.map((f3) => `${f3.family}${f3.variable ? " (variable)" : ""} \xD7 ${f3.fileCount}`).join(", ");
@@ -168479,7 +168514,7 @@ ${err.stack}` : normalizeErrorMessage(err);
168479
168514
  representativeAnimations: representativeAnims
168480
168515
  };
168481
168516
  writeFileSync38(
168482
- join94(outputDir, "extracted", "animations.json"),
168517
+ join95(outputDir, "extracted", "animations.json"),
168483
168518
  JSON.stringify(leanCatalog, null, 2),
168484
168519
  "utf-8"
168485
168520
  );
@@ -168510,7 +168545,7 @@ ${err.stack}` : normalizeErrorMessage(err);
168510
168545
  svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
168511
168546
  };
168512
168547
  writeFileSync38(
168513
- join94(outputDir, "extracted", "tokens.json"),
168548
+ join95(outputDir, "extracted", "tokens.json"),
168514
168549
  JSON.stringify(tokensForDisk2, null, 2),
168515
168550
  "utf-8"
168516
168551
  );
@@ -168526,12 +168561,12 @@ ${extracted.bodyHtml}
168526
168561
  </body>
168527
168562
  </html>
168528
168563
  `;
168529
- writeFileSync38(join94(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
168564
+ writeFileSync38(join95(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
168530
168565
  } catch (err) {
168531
168566
  warnings.push(`page.html write failed: ${err}`);
168532
168567
  }
168533
168568
  if (visibleTextContent) {
168534
- writeFileSync38(join94(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
168569
+ writeFileSync38(join95(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
168535
168570
  }
168536
168571
  const geminiCaptions = await captionImagesWithGemini(outputDir, progress, warnings);
168537
168572
  progress("design", "Generating asset descriptions...");
@@ -168541,7 +168576,7 @@ ${extracted.bodyHtml}
168541
168576
  const hasGeminiKey = !!(process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY);
168542
168577
  const header = hasGeminiKey ? "# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\nTo find a specific brand or icon, **grep this file for the brand name in the description text** (e.g. `grep -i 'autodesk' asset-descriptions.md`). The Gemini Vision captions identify what's actually in each file \u2014 that's the agent's selector.\n\nThe `logo-<hash>.svg` filename prefix is a cheap structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). It is NOT a content claim \u2014 many `logo-*` files are nav icons or decorative shapes. Trust the captions, not the filename prefix.\n\n" : "# Asset Descriptions\n\n\u26A0\uFE0F GEMINI_API_KEY not set \u2014 descriptions below are catalog-derived (alt text, headings, section context, filename) instead of Vision-generated. To get richer Vision descriptions on the next capture, set GEMINI_API_KEY (or GOOGLE_API_KEY) and re-run.\n\nThe `logo-<hash>.svg` filename prefix is a structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). To pick the actual brand logo without Vision, open the `logo-*` candidates in a previewer or rasterize them with `sharp` before referencing \u2014 composing a fake logo ships off-brand in the final video.\n\n";
168543
168578
  writeFileSync38(
168544
- join94(outputDir, "extracted", "asset-descriptions.md"),
168579
+ join95(outputDir, "extracted", "asset-descriptions.md"),
168545
168580
  header + lines.map((l) => "- " + l).join("\n") + "\n",
168546
168581
  "utf-8"
168547
168582
  );
@@ -168556,19 +168591,19 @@ ${extracted.bodyHtml}
168556
168591
  try {
168557
168592
  const { createScrollContactSheet: createScrollContactSheet2, createAssetContactSheet: createAssetContactSheet2, createSvgContactSheet: createSvgContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
168558
168593
  const scrollSheets = await createScrollContactSheet2(
168559
- join94(outputDir, "screenshots"),
168560
- join94(outputDir, "screenshots", "contact-sheet.jpg")
168594
+ join95(outputDir, "screenshots"),
168595
+ join95(outputDir, "screenshots", "contact-sheet.jpg")
168561
168596
  );
168562
168597
  if (scrollSheets.length > 0)
168563
168598
  progress(
168564
168599
  "design",
168565
168600
  `Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
168566
168601
  );
168567
- const assetsImgDir = join94(outputDir, "assets");
168602
+ const assetsImgDir = join95(outputDir, "assets");
168568
168603
  if (existsSync90(assetsImgDir)) {
168569
168604
  const assetSheets = await createAssetContactSheet2(
168570
168605
  assetsImgDir,
168571
- join94(outputDir, "assets", "contact-sheet.jpg")
168606
+ join95(outputDir, "assets", "contact-sheet.jpg")
168572
168607
  );
168573
168608
  if (assetSheets.length > 0)
168574
168609
  progress(
@@ -168576,9 +168611,9 @@ ${extracted.bodyHtml}
168576
168611
  `Asset contact sheet generated (${assetSheets.length} page${assetSheets.length > 1 ? "s" : ""})`
168577
168612
  );
168578
168613
  }
168579
- const svgsDir = join94(outputDir, "assets", "svgs");
168580
- const assetsRootDir = join94(outputDir, "assets");
168581
- const svgOutputPath = existsSync90(svgsDir) ? join94(outputDir, "assets", "svgs", "contact-sheet.jpg") : join94(outputDir, "assets", "contact-sheet-svgs.jpg");
168614
+ const svgsDir = join95(outputDir, "assets", "svgs");
168615
+ const assetsRootDir = join95(outputDir, "assets");
168616
+ const svgOutputPath = existsSync90(svgsDir) ? join95(outputDir, "assets", "svgs", "contact-sheet.jpg") : join95(outputDir, "assets", "contact-sheet-svgs.jpg");
168582
168617
  const svgSheets = await createSvgContactSheet2(svgsDir, svgOutputPath, assetsRootDir);
168583
168618
  if (svgSheets.length > 0)
168584
168619
  progress(
@@ -168594,7 +168629,7 @@ ${extracted.bodyHtml}
168594
168629
  animationCatalog,
168595
168630
  screenshots.length > 0,
168596
168631
  discoveredLotties.length > 0,
168597
- existsSync90(join94(outputDir, "extracted", "shaders.json")),
168632
+ existsSync90(join95(outputDir, "extracted", "shaders.json")),
168598
168633
  catalogedAssets,
168599
168634
  progress,
168600
168635
  warnings,
@@ -168880,9 +168915,9 @@ __export(state_exports, {
168880
168915
  writeStackOutputs: () => writeStackOutputs
168881
168916
  });
168882
168917
  import { existsSync as existsSync91, mkdirSync as mkdirSync46, readdirSync as readdirSync34, readFileSync as readFileSync61, rmSync as rmSync20, writeFileSync as writeFileSync39 } from "fs";
168883
- import { dirname as dirname40, join as join95 } from "path";
168918
+ import { dirname as dirname40, join as join96 } from "path";
168884
168919
  function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
168885
- return join95(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
168920
+ return join96(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
168886
168921
  }
168887
168922
  function writeStackOutputs(outputs, cwd = process.cwd()) {
168888
168923
  const path2 = stateFilePath(outputs.stackName, cwd);
@@ -168904,7 +168939,7 @@ function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd())
168904
168939
  if (existsSync91(path2)) rmSync20(path2);
168905
168940
  }
168906
168941
  function listStackNames(cwd = process.cwd()) {
168907
- const dir = join95(cwd, STATE_DIR_NAME);
168942
+ const dir = join96(cwd, STATE_DIR_NAME);
168908
168943
  if (!existsSync91(dir)) return [];
168909
168944
  return readdirSync34(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
168910
168945
  }
@@ -168936,7 +168971,7 @@ var init_state = __esm({
168936
168971
  // src/commands/lambda/sam.ts
168937
168972
  import { execFileSync as execFileSync13, spawnSync as spawnSync4 } from "child_process";
168938
168973
  import { existsSync as existsSync92 } from "fs";
168939
- import { join as join96 } from "path";
168974
+ import { join as join97 } from "path";
168940
168975
  function assertSamAvailable() {
168941
168976
  try {
168942
168977
  execFileSync13("sam", ["--version"], { stdio: "ignore" });
@@ -168956,7 +168991,7 @@ function assertAwsCliAvailable() {
168956
168991
  }
168957
168992
  }
168958
168993
  function locateSamTemplate(repoRoot2) {
168959
- const candidate = join96(repoRoot2, "examples", "aws-lambda", "template.yaml");
168994
+ const candidate = join97(repoRoot2, "examples", "aws-lambda", "template.yaml");
168960
168995
  if (!existsSync92(candidate)) {
168961
168996
  throw new Error(
168962
168997
  `[lambda] SAM template not found at ${candidate}. If you're running from an installed package, point --sam-template at your local copy of examples/aws-lambda/template.yaml.`
@@ -168990,7 +169025,7 @@ function samDeploy(opts) {
168990
169025
  if (opts.awsProfile) {
168991
169026
  args.push("--profile", opts.awsProfile);
168992
169027
  }
168993
- const samDir = join96(opts.repoRoot, "examples", "aws-lambda");
169028
+ const samDir = join97(opts.repoRoot, "examples", "aws-lambda");
168994
169029
  const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
168995
169030
  if (result.status !== 0) {
168996
169031
  throw new Error(`[lambda] sam deploy exited with code ${result.status ?? "unknown"}`);
@@ -169002,7 +169037,7 @@ function samDelete(opts) {
169002
169037
  if (opts.awsProfile) {
169003
169038
  args.push("--profile", opts.awsProfile);
169004
169039
  }
169005
- const samDir = join96(opts.repoRoot, "examples", "aws-lambda");
169040
+ const samDir = join97(opts.repoRoot, "examples", "aws-lambda");
169006
169041
  const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
169007
169042
  if (result.status !== 0) {
169008
169043
  throw new Error(`[lambda] sam delete exited with code ${result.status ?? "unknown"}`);
@@ -169086,7 +169121,7 @@ __export(deploy_exports, {
169086
169121
  });
169087
169122
  import { spawnSync as spawnSync5 } from "child_process";
169088
169123
  import { existsSync as existsSync94 } from "fs";
169089
- import { join as join97, resolve as resolve60 } from "path";
169124
+ import { join as join98, resolve as resolve60 } from "path";
169090
169125
  async function runDeploy(args = {}) {
169091
169126
  const resolved = {
169092
169127
  stackName: args.stackName ?? DEFAULT_STACK_NAME,
@@ -169103,7 +169138,7 @@ async function runDeploy(args = {}) {
169103
169138
  console.log(c.dim("\u2192 Building handler ZIP"));
169104
169139
  buildHandlerZip(root);
169105
169140
  } else {
169106
- const zip = join97(root, "packages", "aws-lambda", "dist", "handler.zip");
169141
+ const zip = join98(root, "packages", "aws-lambda", "dist", "handler.zip");
169107
169142
  if (!existsSync94(zip)) {
169108
169143
  throw new Error(
169109
169144
  `--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
@@ -169147,7 +169182,7 @@ async function runDeploy(args = {}) {
169147
169182
  function buildHandlerZip(root) {
169148
169183
  const result = spawnSync5(
169149
169184
  "bun",
169150
- ["run", "--cwd", join97(root, "packages", "aws-lambda"), "build:zip"],
169185
+ ["run", "--cwd", join98(root, "packages", "aws-lambda"), "build:zip"],
169151
169186
  { stdio: "inherit" }
169152
169187
  );
169153
169188
  if (result.status !== 0) {
@@ -169217,13 +169252,13 @@ var init_sites = __esm({
169217
169252
 
169218
169253
  // src/commands/lambda/_dimensions.ts
169219
169254
  import { readFileSync as readFileSync63 } from "fs";
169220
- import { join as join98 } from "path";
169255
+ import { join as join99 } from "path";
169221
169256
  function warnOnDimensionMismatch(args) {
169222
169257
  if (args.quiet) return;
169223
169258
  if (args.outputResolution) return;
169224
169259
  let html;
169225
169260
  try {
169226
- html = readFileSync63(join98(args.projectDir, "index.html"), "utf-8");
169261
+ html = readFileSync63(join99(args.projectDir, "index.html"), "utf-8");
169227
169262
  } catch {
169228
169263
  return;
169229
169264
  }
@@ -169252,7 +169287,7 @@ __export(render_exports2, {
169252
169287
  runRender: () => runRender
169253
169288
  });
169254
169289
  import { existsSync as existsSync95 } from "fs";
169255
- import { join as join99, resolve as resolvePath2 } from "path";
169290
+ import { join as join100, resolve as resolvePath2 } from "path";
169256
169291
  async function loadSDK2() {
169257
169292
  return import("@hyperframes/aws-lambda/sdk");
169258
169293
  }
@@ -169268,7 +169303,7 @@ async function runRender(args) {
169268
169303
  });
169269
169304
  const variables = resolveVariablesArg(args.variables, args.variablesFile);
169270
169305
  if (variables && Object.keys(variables).length > 0) {
169271
- const indexPath2 = join99(projectDir, "index.html");
169306
+ const indexPath2 = join100(projectDir, "index.html");
169272
169307
  if (existsSync95(indexPath2)) {
169273
169308
  const issues = validateVariablesAgainstProject(indexPath2, variables);
169274
169309
  reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
@@ -169394,7 +169429,7 @@ __export(render_batch_exports, {
169394
169429
  runWithConcurrencyLimit: () => runWithConcurrencyLimit
169395
169430
  });
169396
169431
  import { existsSync as existsSync96, readFileSync as readFileSync64 } from "fs";
169397
- import { join as join100, resolve as resolvePath3 } from "path";
169432
+ import { join as join101, resolve as resolvePath3 } from "path";
169398
169433
  async function loadSDK3() {
169399
169434
  return import("@hyperframes/aws-lambda/sdk");
169400
169435
  }
@@ -169418,7 +169453,7 @@ async function runRenderBatch(args) {
169418
169453
  outputResolution: args.outputResolution,
169419
169454
  quiet: args.json
169420
169455
  });
169421
- const schema = loadProjectVariableSchema(join100(projectDir, "index.html"));
169456
+ const schema = loadProjectVariableSchema(join101(projectDir, "index.html"));
169422
169457
  const strict = args.strictVariables ?? false;
169423
169458
  let hadStrictIssue = false;
169424
169459
  for (const { entry, lineNumber } of entries2) {
@@ -170441,12 +170476,12 @@ import { spawnSync as spawnSync6 } from "child_process";
170441
170476
  import { createRequire as createRequire4 } from "module";
170442
170477
  import { existsSync as existsSync97, mkdirSync as mkdirSync47, readFileSync as readFileSync66, writeFileSync as writeFileSync40 } from "fs";
170443
170478
  import { homedir as homedir14 } from "os";
170444
- import { dirname as dirname42, join as join101, resolve as resolve61 } from "path";
170479
+ import { dirname as dirname42, join as join103, resolve as resolve61 } from "path";
170445
170480
  function stateDir() {
170446
- return join101(homedir14(), ".hyperframes");
170481
+ return join103(homedir14(), ".hyperframes");
170447
170482
  }
170448
170483
  function statePath() {
170449
- return join101(stateDir(), "cloudrun-state.json");
170484
+ return join103(stateDir(), "cloudrun-state.json");
170450
170485
  }
170451
170486
  function writeState(state) {
170452
170487
  mkdirSync47(stateDir(), { recursive: true });
@@ -170480,7 +170515,7 @@ function stripUndefined2(o) {
170480
170515
  function terraformDir() {
170481
170516
  const require3 = createRequire4(import.meta.url);
170482
170517
  const pkgJson = require3.resolve("@hyperframes/gcp-cloud-run/package.json");
170483
- return join101(dirname42(pkgJson), "terraform");
170518
+ return join103(dirname42(pkgJson), "terraform");
170484
170519
  }
170485
170520
  function run(cmd, cmdArgs, opts = {}) {
170486
170521
  const res = spawnSync6(cmd, cmdArgs, { stdio: "inherit", cwd: opts.cwd });
@@ -170607,11 +170642,11 @@ function machineVars(args, project, region, image) {
170607
170642
  }
170608
170643
  function findRepoRoot(tfDir) {
170609
170644
  const candidate = resolve61(tfDir, "..", "..", "..");
170610
- if (existsSync97(join101(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
170645
+ if (existsSync97(join103(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
170611
170646
  return null;
170612
170647
  }
170613
170648
  function writeCloudBuildConfig(image) {
170614
- const cfgPath = join101(stateDir(), "cloudrun-cloudbuild.yaml");
170649
+ const cfgPath = join103(stateDir(), "cloudrun-cloudbuild.yaml");
170615
170650
  mkdirSync47(stateDir(), { recursive: true });
170616
170651
  writeFileSync40(
170617
170652
  cfgPath,
@@ -170897,7 +170932,7 @@ function resolveAndValidateVariables(args, projectDir) {
170897
170932
  args["variables-file"]
170898
170933
  );
170899
170934
  if (variables && Object.keys(variables).length > 0) {
170900
- const indexPath2 = join101(projectDir, "index.html");
170935
+ const indexPath2 = join103(projectDir, "index.html");
170901
170936
  if (existsSync97(indexPath2)) {
170902
170937
  const issues = validateVariablesAgainstProject(indexPath2, variables);
170903
170938
  reportVariableIssues(issues, {
@@ -171912,14 +171947,14 @@ var init_browser2 = __esm({
171912
171947
 
171913
171948
  // src/auth/paths.ts
171914
171949
  import { homedir as homedir15 } from "os";
171915
- import { join as join103 } from "path";
171950
+ import { join as join104 } from "path";
171916
171951
  function configDir() {
171917
171952
  const override = process.env["HEYGEN_CONFIG_DIR"];
171918
171953
  if (override && override.length > 0) return override;
171919
- return join103(homedir15(), ".heygen");
171954
+ return join104(homedir15(), ".heygen");
171920
171955
  }
171921
171956
  function credentialPath() {
171922
- return join103(configDir(), CREDENTIAL_FILENAME);
171957
+ return join104(configDir(), CREDENTIAL_FILENAME);
171923
171958
  }
171924
171959
  var CREDENTIAL_FILENAME;
171925
171960
  var init_paths2 = __esm({
@@ -174618,15 +174653,15 @@ var init_jsonl = __esm({
174618
174653
 
174619
174654
  // ../core/dist/figma/manifest.js
174620
174655
  import { appendFileSync as appendFileSync2, existsSync as existsSync100, mkdirSync as mkdirSync50, readFileSync as readFileSync69, writeFileSync as writeFileSync43 } from "fs";
174621
- import { join as join104 } from "path";
174656
+ import { join as join105 } from "path";
174622
174657
  function mediaDir(projectDir) {
174623
- return join104(projectDir, ".media");
174658
+ return join105(projectDir, ".media");
174624
174659
  }
174625
174660
  function manifestPath(projectDir) {
174626
- return join104(mediaDir(projectDir), MANIFEST_FILE2);
174661
+ return join105(mediaDir(projectDir), MANIFEST_FILE2);
174627
174662
  }
174628
174663
  function typeDirPath(projectDir, type) {
174629
- return join104(mediaDir(projectDir), TYPE_DIRS[type]);
174664
+ return join105(mediaDir(projectDir), TYPE_DIRS[type]);
174630
174665
  }
174631
174666
  function isFigmaManifestRecord(value) {
174632
174667
  if (typeof value !== "object" || value === null)
@@ -174713,12 +174748,12 @@ var init_manifest = __esm({
174713
174748
 
174714
174749
  // ../core/dist/figma/mediaIndex.js
174715
174750
  import { mkdirSync as mkdirSync51, writeFileSync as writeFileSync44 } from "fs";
174716
- import { dirname as dirname46, join as join105 } from "path";
174751
+ import { dirname as dirname46, join as join106 } from "path";
174717
174752
  function isRow(value) {
174718
174753
  return typeof value === "object" && value !== null;
174719
174754
  }
174720
174755
  function indexPath(projectDir) {
174721
- return join105(mediaDir(projectDir), "index.md");
174756
+ return join106(mediaDir(projectDir), "index.md");
174722
174757
  }
174723
174758
  function pad(str, len2) {
174724
174759
  return String(str ?? "").padEnd(len2);
@@ -174830,9 +174865,9 @@ var init_sanitizeSvg = __esm({
174830
174865
 
174831
174866
  // ../core/dist/figma/bindings.js
174832
174867
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync53, writeFileSync as writeFileSync45 } from "fs";
174833
- import { join as join106 } from "path";
174868
+ import { join as join107 } from "path";
174834
174869
  function bindingsPath(projectDir) {
174835
- return join106(mediaDir(projectDir), BINDINGS_FILE);
174870
+ return join107(mediaDir(projectDir), BINDINGS_FILE);
174836
174871
  }
174837
174872
  function isRecord6(value) {
174838
174873
  return typeof value === "object" && value !== null;
@@ -175387,7 +175422,7 @@ __export(asset_exports, {
175387
175422
  runAssetImport: () => runAssetImport
175388
175423
  });
175389
175424
  import { existsSync as existsSync101 } from "fs";
175390
- import { join as join107, relative as relative16 } from "path";
175425
+ import { join as join108, relative as relative16 } from "path";
175391
175426
  async function runAssetImport(refInput, opts, deps) {
175392
175427
  const ref2 = parseFigmaRef(refInput);
175393
175428
  if (!ref2.nodeId)
@@ -175398,7 +175433,7 @@ async function runAssetImport(refInput, opts, deps) {
175398
175433
  const description = normalizeMeta(opts.description);
175399
175434
  const entity = normalizeMeta(opts.entity);
175400
175435
  const existing = findAllByFigmaNode(deps.projectDir, ref2.fileKey, ref2.nodeId).find(
175401
- (r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 && existsSync101(join107(deps.projectDir, r2.path))
175436
+ (r2) => r2.provenance.format === opts.format && (r2.provenance.scale ?? 1) === (opts.scale ?? 1) && r2.provenance.version === version2 && existsSync101(join108(deps.projectDir, r2.path))
175402
175437
  );
175403
175438
  if (existing) {
175404
175439
  let record2 = existing;
@@ -175422,7 +175457,7 @@ async function runAssetImport(refInput, opts, deps) {
175422
175457
  bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
175423
175458
  }
175424
175459
  const id = nextId(deps.projectDir, "image");
175425
- const destAbs = join107(typeDirPath(deps.projectDir, "image"), `${id}.${rendered.ext}`);
175460
+ const destAbs = join108(typeDirPath(deps.projectDir, "image"), `${id}.${rendered.ext}`);
175426
175461
  freezeBytes(bytes, destAbs);
175427
175462
  const record = {
175428
175463
  id,
@@ -175519,11 +175554,11 @@ __export(tokens_exports, {
175519
175554
  runTokensImport: () => runTokensImport
175520
175555
  });
175521
175556
  import { writeFileSync as writeFileSync46 } from "fs";
175522
- import { join as join108 } from "path";
175557
+ import { join as join109 } from "path";
175523
175558
  async function runTokensImport(refInput, deps) {
175524
175559
  const { fileKey } = parseFigmaRef(refInput);
175525
175560
  const { version: version2 } = await deps.client.fileVersion(fileKey);
175526
- const sidecarPath = join108(deps.projectDir, "figma-tokens.json");
175561
+ const sidecarPath = join109(deps.projectDir, "figma-tokens.json");
175527
175562
  let vars = null;
175528
175563
  try {
175529
175564
  vars = await deps.client.variables(fileKey);
@@ -175590,7 +175625,7 @@ __export(component_exports, {
175590
175625
  runComponentImport: () => runComponentImport
175591
175626
  });
175592
175627
  import { existsSync as existsSync102, mkdirSync as mkdirSync54, writeFileSync as writeFileSync47 } from "fs";
175593
- import { join as join109, relative as relative17 } from "path";
175628
+ import { join as join110, relative as relative17 } from "path";
175594
175629
  function escapeAttr2(value) {
175595
175630
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
175596
175631
  }
@@ -175601,7 +175636,7 @@ async function runComponentImport(refInput, deps) {
175601
175636
  const bindings = resolveBindings(tree, readBindings(deps.projectDir));
175602
175637
  const mapped = nodeToHtml(tree, bindings);
175603
175638
  const name = slugify2(tree.name);
175604
- const componentDir = join109(deps.projectDir, "compositions", "components", name);
175639
+ const componentDir = join110(deps.projectDir, "compositions", "components", name);
175605
175640
  if (existsSync102(componentDir))
175606
175641
  console.warn(
175607
175642
  `component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
@@ -175616,7 +175651,7 @@ async function runComponentImport(refInput, deps) {
175616
175651
  { projectDir: deps.projectDir, client: deps.client, download: deps.download }
175617
175652
  );
175618
175653
  frozenAssets.push(asset.record.path);
175619
- const srcRel = relative17(componentDir, join109(deps.projectDir, asset.record.path)).replaceAll(
175654
+ const srcRel = relative17(componentDir, join110(deps.projectDir, asset.record.path)).replaceAll(
175620
175655
  "\\",
175621
175656
  "/"
175622
175657
  );
@@ -175626,7 +175661,7 @@ async function runComponentImport(refInput, deps) {
175626
175661
  `data-figma-rasterize="${emittedId}" src="${escapeAttr2(srcRel)}" `
175627
175662
  );
175628
175663
  }
175629
- const htmlFile = join109(componentDir, `${name}.html`);
175664
+ const htmlFile = join110(componentDir, `${name}.html`);
175630
175665
  writeFileSync47(htmlFile, html + "\n");
175631
175666
  const registryItem = {
175632
175667
  name,
@@ -175648,7 +175683,7 @@ async function runComponentImport(refInput, deps) {
175648
175683
  ]
175649
175684
  };
175650
175685
  writeFileSync47(
175651
- join109(componentDir, "registry-item.json"),
175686
+ join110(componentDir, "registry-item.json"),
175652
175687
  JSON.stringify(registryItem, null, 2) + "\n"
175653
175688
  );
175654
175689
  return {
@@ -175890,7 +175925,7 @@ __export(autoUpdate_exports, {
175890
175925
  import { spawn as spawn17 } from "child_process";
175891
175926
  import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync55, openSync as openSync4 } from "fs";
175892
175927
  import { homedir as homedir16 } from "os";
175893
- import { join as join110 } from "path";
175928
+ import { join as join111 } from "path";
175894
175929
  import { compareVersions as compareVersions3 } from "compare-versions";
175895
175930
  function isAutoInstallDisabled() {
175896
175931
  if (isDevMode()) return true;
@@ -175913,7 +175948,7 @@ function log(line2) {
175913
175948
  }
175914
175949
  function launchDetachedInstall(installCommand, version2) {
175915
175950
  mkdirSync55(CONFIG_DIR2, { recursive: true, mode: 448 });
175916
- const configFile = join110(CONFIG_DIR2, "config.json");
175951
+ const configFile = join111(CONFIG_DIR2, "config.json");
175917
175952
  const nodeScript = `
175918
175953
  const { exec } = require("node:child_process");
175919
175954
  const { readFileSync, renameSync, writeFileSync } = require("node:fs");
@@ -176032,8 +176067,8 @@ var init_autoUpdate = __esm({
176032
176067
  init_config();
176033
176068
  init_env();
176034
176069
  init_installerDetection();
176035
- CONFIG_DIR2 = join110(homedir16(), ".hyperframes");
176036
- LOG_FILE = join110(CONFIG_DIR2, "auto-update.log");
176070
+ CONFIG_DIR2 = join111(homedir16(), ".hyperframes");
176071
+ LOG_FILE = join111(CONFIG_DIR2, "auto-update.log");
176037
176072
  PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
176038
176073
  }
176039
176074
  });
@@ -176281,7 +176316,7 @@ var init_help = __esm({
176281
176316
  // src/cli.ts
176282
176317
  init_version();
176283
176318
  init_dist();
176284
- import { dirname as dirname47, join as join111 } from "path";
176319
+ import { dirname as dirname47, join as join113 } from "path";
176285
176320
  import { fileURLToPath as fileURLToPath16 } from "url";
176286
176321
  import { existsSync as existsSync103 } from "fs";
176287
176322
 
@@ -176326,7 +176361,7 @@ for (const stream of [process.stdout, process.stderr]) {
176326
176361
  }
176327
176362
  (() => {
176328
176363
  const here = dirname47(fileURLToPath16(import.meta.url));
176329
- const shader = join111(here, "shaderTransitionWorker.js");
176364
+ const shader = join113(here, "shaderTransitionWorker.js");
176330
176365
  if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync103(shader)) {
176331
176366
  process.env.HF_SHADER_WORKER_ENTRY = shader;
176332
176367
  }