hyperframes 0.4.24 → 0.5.0-alpha.2
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 +707 -460
- package/dist/studio/assets/index-BExHzIDS.js +105 -0
- package/dist/studio/assets/index-BpcIkyVP.css +1 -0
- package/dist/studio/index.html +2 -2
- package/package.json +1 -1
- package/dist/studio/assets/index-CAscydDF.js +0 -115
- package/dist/studio/assets/index-dpgHnQGg.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.
|
|
57
|
+
VERSION = true ? "0.5.0-alpha.2" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -5994,6 +5994,18 @@ function rewriteAssetPaths(elements, compSrcPath, getAttr2, setAttr) {
|
|
|
5994
5994
|
}
|
|
5995
5995
|
}
|
|
5996
5996
|
}
|
|
5997
|
+
function rewriteInlineStyleAssetUrls(elements, compSrcPath, getStyle, setStyle) {
|
|
5998
|
+
const compDir = dirname(compSrcPath);
|
|
5999
|
+
if (!compDir || compDir === ".") return;
|
|
6000
|
+
for (const el of elements) {
|
|
6001
|
+
const style = getStyle(el);
|
|
6002
|
+
if (!style) continue;
|
|
6003
|
+
const rewritten = rewriteCssAssetUrls(style, compSrcPath);
|
|
6004
|
+
if (rewritten !== style) {
|
|
6005
|
+
setStyle(el, rewritten);
|
|
6006
|
+
}
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
5997
6009
|
function rewriteCssAssetUrls(cssText, compSrcPath) {
|
|
5998
6010
|
if (!cssText) return cssText;
|
|
5999
6011
|
return cssText.replace(CSS_URL_RE, (full, quote, rawUrl) => {
|
|
@@ -24416,6 +24428,14 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
|
24416
24428
|
el.setAttribute(attr, value);
|
|
24417
24429
|
}
|
|
24418
24430
|
);
|
|
24431
|
+
rewriteInlineStyleAssetUrls(
|
|
24432
|
+
contentDoc.querySelectorAll("[style]"),
|
|
24433
|
+
compPath,
|
|
24434
|
+
(el) => el.getAttribute("style"),
|
|
24435
|
+
(el, value) => {
|
|
24436
|
+
el.setAttribute("style", value);
|
|
24437
|
+
}
|
|
24438
|
+
);
|
|
24419
24439
|
for (const styleEl of contentDoc.querySelectorAll("style")) {
|
|
24420
24440
|
styleEl.textContent = rewriteCssAssetUrls(styleEl.textContent || "", compPath);
|
|
24421
24441
|
}
|
|
@@ -24810,7 +24830,7 @@ var init_render = __esm({
|
|
|
24810
24830
|
});
|
|
24811
24831
|
|
|
24812
24832
|
// ../core/src/studio-api/routes/thumbnail.ts
|
|
24813
|
-
import { existsSync as existsSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7 } from "fs";
|
|
24833
|
+
import { existsSync as existsSync13, readFileSync as readFileSync14, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, statSync as statSync4 } from "fs";
|
|
24814
24834
|
import { join as join16 } from "path";
|
|
24815
24835
|
function registerThumbnailRoutes(api, adapter2) {
|
|
24816
24836
|
api.get("/projects/:id/thumbnail/*", async (c2) => {
|
|
@@ -24828,11 +24848,14 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
24828
24848
|
const vpWidth = parseInt(url.searchParams.get("w") || "0") || 0;
|
|
24829
24849
|
const vpHeight = parseInt(url.searchParams.get("h") || "0") || 0;
|
|
24830
24850
|
const selector = url.searchParams.get("selector") || void 0;
|
|
24851
|
+
const urlVersion = url.searchParams.get("v") || "";
|
|
24831
24852
|
let compW = vpWidth || 1920;
|
|
24832
24853
|
let compH = vpHeight || 1080;
|
|
24854
|
+
let sourceMtime = 0;
|
|
24833
24855
|
if (!vpWidth) {
|
|
24834
24856
|
const htmlFile = join16(project.dir, compPath);
|
|
24835
24857
|
if (existsSync13(htmlFile)) {
|
|
24858
|
+
sourceMtime = Math.round(statSync4(htmlFile).mtimeMs);
|
|
24836
24859
|
const html = readFileSync14(htmlFile, "utf-8");
|
|
24837
24860
|
const wMatch = html.match(/data-width=["'](\d+)["']/);
|
|
24838
24861
|
const hMatch = html.match(/data-height=["'](\d+)["']/);
|
|
@@ -24843,7 +24866,8 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
24843
24866
|
const previewUrl = compPath === "index.html" ? `http://${c2.req.header("host")}/api/projects/${project.id}/preview` : `http://${c2.req.header("host")}/api/projects/${project.id}/preview/comp/${compPath}`;
|
|
24844
24867
|
const cacheDir = join16(project.dir, ".thumbnails");
|
|
24845
24868
|
const selectorKey = selector ? `_${selector.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 80)}` : "";
|
|
24846
|
-
const
|
|
24869
|
+
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
24870
|
+
const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}_${compPath.replace(/\//g, "_")}_${compW}x${compH}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.jpg`;
|
|
24847
24871
|
const cachePath2 = join16(cacheDir, cacheKey);
|
|
24848
24872
|
if (existsSync13(cachePath2)) {
|
|
24849
24873
|
return new Response(new Uint8Array(readFileSync14(cachePath2)), {
|
|
@@ -24878,7 +24902,219 @@ var THUMBNAIL_CACHE_VERSION;
|
|
|
24878
24902
|
var init_thumbnail = __esm({
|
|
24879
24903
|
"../core/src/studio-api/routes/thumbnail.ts"() {
|
|
24880
24904
|
"use strict";
|
|
24881
|
-
THUMBNAIL_CACHE_VERSION = "
|
|
24905
|
+
THUMBNAIL_CACHE_VERSION = "v3";
|
|
24906
|
+
}
|
|
24907
|
+
});
|
|
24908
|
+
|
|
24909
|
+
// ../core/src/studio-api/routes/fonts.ts
|
|
24910
|
+
import { execFileSync as execFileSync4 } from "child_process";
|
|
24911
|
+
import { existsSync as existsSync14, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
|
|
24912
|
+
import { homedir as homedir4, platform as platform3 } from "os";
|
|
24913
|
+
import { join as join17 } from "path";
|
|
24914
|
+
function isRecord(value) {
|
|
24915
|
+
return typeof value === "object" && value !== null;
|
|
24916
|
+
}
|
|
24917
|
+
function fontDirectories() {
|
|
24918
|
+
const home = homedir4();
|
|
24919
|
+
if (platform3() === "darwin") {
|
|
24920
|
+
return [
|
|
24921
|
+
join17(home, "Library", "Fonts"),
|
|
24922
|
+
"/Library/Fonts",
|
|
24923
|
+
"/System/Library/Fonts",
|
|
24924
|
+
"/System/Library/Fonts/Supplemental"
|
|
24925
|
+
];
|
|
24926
|
+
}
|
|
24927
|
+
if (platform3() === "win32") {
|
|
24928
|
+
return [join17(process.env.WINDIR || "C:\\Windows", "Fonts")];
|
|
24929
|
+
}
|
|
24930
|
+
return [
|
|
24931
|
+
join17(home, ".fonts"),
|
|
24932
|
+
join17(home, ".local", "share", "fonts"),
|
|
24933
|
+
"/usr/local/share/fonts",
|
|
24934
|
+
"/usr/share/fonts"
|
|
24935
|
+
];
|
|
24936
|
+
}
|
|
24937
|
+
function toFamilyName(fileName) {
|
|
24938
|
+
const withoutExt = fileName.replace(FONT_EXT_RE, "");
|
|
24939
|
+
if (!withoutExt || withoutExt.startsWith(".")) return null;
|
|
24940
|
+
const spaced = withoutExt.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/\s+/g, " ").trim();
|
|
24941
|
+
const words = spaced.split(" ").filter(Boolean);
|
|
24942
|
+
while (words.length > 1 && STYLE_SUFFIXES.has((words.at(-1) ?? "").toLowerCase())) {
|
|
24943
|
+
words.pop();
|
|
24944
|
+
}
|
|
24945
|
+
const family = words.join(" ").trim();
|
|
24946
|
+
return family.length >= 2 ? family : null;
|
|
24947
|
+
}
|
|
24948
|
+
function collectMacSystemProfilerFonts() {
|
|
24949
|
+
if (platform3() !== "darwin") return [];
|
|
24950
|
+
let parsed;
|
|
24951
|
+
try {
|
|
24952
|
+
const raw = execFileSync4("system_profiler", ["SPFontsDataType", "-json"], {
|
|
24953
|
+
encoding: "utf8",
|
|
24954
|
+
maxBuffer: 12 * 1024 * 1024,
|
|
24955
|
+
timeout: 5e3
|
|
24956
|
+
});
|
|
24957
|
+
parsed = JSON.parse(raw);
|
|
24958
|
+
} catch {
|
|
24959
|
+
return [];
|
|
24960
|
+
}
|
|
24961
|
+
if (!isRecord(parsed) || !Array.isArray(parsed.SPFontsDataType)) return [];
|
|
24962
|
+
const fonts = [];
|
|
24963
|
+
for (const fontEntry of parsed.SPFontsDataType) {
|
|
24964
|
+
if (!isRecord(fontEntry)) continue;
|
|
24965
|
+
const typefaces = fontEntry.typefaces;
|
|
24966
|
+
if (!Array.isArray(typefaces)) continue;
|
|
24967
|
+
for (const typeface of typefaces) {
|
|
24968
|
+
if (!isRecord(typeface)) continue;
|
|
24969
|
+
const family = typeface.family;
|
|
24970
|
+
const fullName = typeface.fullname;
|
|
24971
|
+
const name = typeface._name;
|
|
24972
|
+
if (typeof family === "string" && family.trim()) {
|
|
24973
|
+
fonts.push(family.trim());
|
|
24974
|
+
} else if (typeof fullName === "string" && fullName.trim()) {
|
|
24975
|
+
fonts.push(fullName.trim());
|
|
24976
|
+
} else if (typeof name === "string" && name.trim()) {
|
|
24977
|
+
fonts.push(name.trim());
|
|
24978
|
+
}
|
|
24979
|
+
}
|
|
24980
|
+
}
|
|
24981
|
+
return fonts;
|
|
24982
|
+
}
|
|
24983
|
+
function collectFontsFromDir(dir, depth = 0) {
|
|
24984
|
+
if (!existsSync14(dir) || depth > 2) return [];
|
|
24985
|
+
const fonts = [];
|
|
24986
|
+
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
24987
|
+
const fullPath = join17(dir, entry.name);
|
|
24988
|
+
if (entry.isDirectory()) {
|
|
24989
|
+
fonts.push(...collectFontsFromDir(fullPath, depth + 1));
|
|
24990
|
+
continue;
|
|
24991
|
+
}
|
|
24992
|
+
if (!entry.isFile() || !FONT_EXT_RE.test(entry.name)) continue;
|
|
24993
|
+
try {
|
|
24994
|
+
if (!statSync5(fullPath).isFile()) continue;
|
|
24995
|
+
} catch {
|
|
24996
|
+
continue;
|
|
24997
|
+
}
|
|
24998
|
+
const family = toFamilyName(entry.name);
|
|
24999
|
+
if (family) fonts.push(family);
|
|
25000
|
+
}
|
|
25001
|
+
return fonts;
|
|
25002
|
+
}
|
|
25003
|
+
function listInstalledFontFamilies() {
|
|
25004
|
+
if (cachedFonts) return cachedFonts;
|
|
25005
|
+
const families = /* @__PURE__ */ new Set();
|
|
25006
|
+
for (const family of collectMacSystemProfilerFonts()) {
|
|
25007
|
+
families.add(family);
|
|
25008
|
+
if (families.size >= MAX_FONT_RESULTS) break;
|
|
25009
|
+
}
|
|
25010
|
+
for (const dir of fontDirectories()) {
|
|
25011
|
+
for (const family of collectFontsFromDir(dir)) {
|
|
25012
|
+
families.add(family);
|
|
25013
|
+
if (families.size >= MAX_FONT_RESULTS) break;
|
|
25014
|
+
}
|
|
25015
|
+
if (families.size >= MAX_FONT_RESULTS) break;
|
|
25016
|
+
}
|
|
25017
|
+
cachedFonts = Array.from(families).sort((a, b) => a.localeCompare(b));
|
|
25018
|
+
return cachedFonts;
|
|
25019
|
+
}
|
|
25020
|
+
function parseGoogleFontMetadata(value) {
|
|
25021
|
+
if (!isRecord(value) || !Array.isArray(value.familyMetadataList)) return [];
|
|
25022
|
+
const families = [];
|
|
25023
|
+
for (const entry of value.familyMetadataList) {
|
|
25024
|
+
if (!isRecord(entry) || typeof entry.family !== "string") continue;
|
|
25025
|
+
families.push(entry.family);
|
|
25026
|
+
}
|
|
25027
|
+
return families;
|
|
25028
|
+
}
|
|
25029
|
+
function stripGoogleJsonGuard(raw) {
|
|
25030
|
+
const prefix = ")]}'";
|
|
25031
|
+
if (!raw.startsWith(prefix)) return raw;
|
|
25032
|
+
let index = prefix.length;
|
|
25033
|
+
while (index < raw.length && (raw[index] === " " || raw[index] === "\n" || raw[index] === "\r" || raw[index] === " " || raw[index] === "\f")) {
|
|
25034
|
+
index += 1;
|
|
25035
|
+
}
|
|
25036
|
+
return raw.slice(index);
|
|
25037
|
+
}
|
|
25038
|
+
async function listGoogleFontFamilies() {
|
|
25039
|
+
if (cachedGoogleFonts) return cachedGoogleFonts;
|
|
25040
|
+
const controller = new AbortController();
|
|
25041
|
+
const timer = setTimeout(() => controller.abort(), GOOGLE_FONTS_FETCH_TIMEOUT_MS);
|
|
25042
|
+
try {
|
|
25043
|
+
const response = await fetch(GOOGLE_FONTS_METADATA_URL, { signal: controller.signal });
|
|
25044
|
+
if (!response.ok) {
|
|
25045
|
+
cachedGoogleFonts = GOOGLE_FONT_FALLBACKS;
|
|
25046
|
+
return cachedGoogleFonts;
|
|
25047
|
+
}
|
|
25048
|
+
const raw = await response.text();
|
|
25049
|
+
const jsonText = stripGoogleJsonGuard(raw);
|
|
25050
|
+
const families = parseGoogleFontMetadata(JSON.parse(jsonText));
|
|
25051
|
+
cachedGoogleFonts = families.length > 0 ? families : GOOGLE_FONT_FALLBACKS;
|
|
25052
|
+
} catch {
|
|
25053
|
+
cachedGoogleFonts = GOOGLE_FONT_FALLBACKS;
|
|
25054
|
+
} finally {
|
|
25055
|
+
clearTimeout(timer);
|
|
25056
|
+
}
|
|
25057
|
+
return cachedGoogleFonts;
|
|
25058
|
+
}
|
|
25059
|
+
function registerFontRoutes(api) {
|
|
25060
|
+
api.get("/fonts", (c2) => c2.json({ fonts: listInstalledFontFamilies() }));
|
|
25061
|
+
api.get("/fonts/google", async (c2) => c2.json({ fonts: await listGoogleFontFamilies() }));
|
|
25062
|
+
}
|
|
25063
|
+
var FONT_EXT_RE, MAX_FONT_RESULTS, GOOGLE_FONTS_METADATA_URL, GOOGLE_FONTS_FETCH_TIMEOUT_MS, cachedFonts, cachedGoogleFonts, STYLE_SUFFIXES, GOOGLE_FONT_FALLBACKS;
|
|
25064
|
+
var init_fonts = __esm({
|
|
25065
|
+
"../core/src/studio-api/routes/fonts.ts"() {
|
|
25066
|
+
"use strict";
|
|
25067
|
+
FONT_EXT_RE = /\.(otf|ttf|ttc|woff2?)$/i;
|
|
25068
|
+
MAX_FONT_RESULTS = 2e3;
|
|
25069
|
+
GOOGLE_FONTS_METADATA_URL = "https://fonts.google.com/metadata/fonts";
|
|
25070
|
+
GOOGLE_FONTS_FETCH_TIMEOUT_MS = 3e3;
|
|
25071
|
+
cachedFonts = null;
|
|
25072
|
+
cachedGoogleFonts = null;
|
|
25073
|
+
STYLE_SUFFIXES = /* @__PURE__ */ new Set([
|
|
25074
|
+
"black",
|
|
25075
|
+
"bold",
|
|
25076
|
+
"book",
|
|
25077
|
+
"condensed",
|
|
25078
|
+
"demi",
|
|
25079
|
+
"demibold",
|
|
25080
|
+
"display",
|
|
25081
|
+
"extra",
|
|
25082
|
+
"extrabold",
|
|
25083
|
+
"hairline",
|
|
25084
|
+
"heavy",
|
|
25085
|
+
"italic",
|
|
25086
|
+
"light",
|
|
25087
|
+
"medium",
|
|
25088
|
+
"normal",
|
|
25089
|
+
"regular",
|
|
25090
|
+
"roman",
|
|
25091
|
+
"semibold",
|
|
25092
|
+
"thin",
|
|
25093
|
+
"ultra",
|
|
25094
|
+
"ultralight"
|
|
25095
|
+
]);
|
|
25096
|
+
GOOGLE_FONT_FALLBACKS = [
|
|
25097
|
+
"Inter",
|
|
25098
|
+
"Roboto",
|
|
25099
|
+
"Open Sans",
|
|
25100
|
+
"Montserrat",
|
|
25101
|
+
"Poppins",
|
|
25102
|
+
"Lato",
|
|
25103
|
+
"Oswald",
|
|
25104
|
+
"Raleway",
|
|
25105
|
+
"Nunito",
|
|
25106
|
+
"Playfair Display",
|
|
25107
|
+
"Merriweather",
|
|
25108
|
+
"Source Sans 3",
|
|
25109
|
+
"Source Serif 4",
|
|
25110
|
+
"Source Code Pro",
|
|
25111
|
+
"DM Sans",
|
|
25112
|
+
"Space Grotesk",
|
|
25113
|
+
"Space Mono",
|
|
25114
|
+
"Bebas Neue",
|
|
25115
|
+
"Outfit",
|
|
25116
|
+
"JetBrains Mono"
|
|
25117
|
+
];
|
|
24882
25118
|
}
|
|
24883
25119
|
});
|
|
24884
25120
|
|
|
@@ -24892,6 +25128,7 @@ function createStudioApi(adapter2) {
|
|
|
24892
25128
|
registerLintRoutes(api, adapter2);
|
|
24893
25129
|
registerRenderRoutes(api, adapter2);
|
|
24894
25130
|
registerThumbnailRoutes(api, adapter2);
|
|
25131
|
+
registerFontRoutes(api);
|
|
24895
25132
|
return api;
|
|
24896
25133
|
}
|
|
24897
25134
|
var init_createStudioApi = __esm({
|
|
@@ -24903,6 +25140,7 @@ var init_createStudioApi = __esm({
|
|
|
24903
25140
|
init_lint2();
|
|
24904
25141
|
init_render();
|
|
24905
25142
|
init_thumbnail();
|
|
25143
|
+
init_fonts();
|
|
24906
25144
|
}
|
|
24907
25145
|
});
|
|
24908
25146
|
|
|
@@ -24937,9 +25175,9 @@ __export(manager_exports2, {
|
|
|
24937
25175
|
setBrowserPath: () => setBrowserPath
|
|
24938
25176
|
});
|
|
24939
25177
|
import { execSync } from "child_process";
|
|
24940
|
-
import { existsSync as
|
|
24941
|
-
import { homedir as
|
|
24942
|
-
import { join as
|
|
25178
|
+
import { existsSync as existsSync15, rmSync as rmSync4 } from "fs";
|
|
25179
|
+
import { homedir as homedir5 } from "os";
|
|
25180
|
+
import { join as join18 } from "path";
|
|
24943
25181
|
import { Browser, detectBrowserPlatform, getInstalledBrowsers, install } from "@puppeteer/browsers";
|
|
24944
25182
|
function setBrowserPath(path2) {
|
|
24945
25183
|
_browserPathOverride = path2;
|
|
@@ -24959,17 +25197,17 @@ function whichBinary2(name) {
|
|
|
24959
25197
|
}
|
|
24960
25198
|
}
|
|
24961
25199
|
function findFromEnv2() {
|
|
24962
|
-
if (_browserPathOverride &&
|
|
25200
|
+
if (_browserPathOverride && existsSync15(_browserPathOverride)) {
|
|
24963
25201
|
return { executablePath: _browserPathOverride, source: "env" };
|
|
24964
25202
|
}
|
|
24965
25203
|
const envPath = process.env["HYPERFRAMES_BROWSER_PATH"];
|
|
24966
|
-
if (envPath &&
|
|
25204
|
+
if (envPath && existsSync15(envPath)) {
|
|
24967
25205
|
return { executablePath: envPath, source: "env" };
|
|
24968
25206
|
}
|
|
24969
25207
|
return void 0;
|
|
24970
25208
|
}
|
|
24971
25209
|
async function findFromCache() {
|
|
24972
|
-
if (!
|
|
25210
|
+
if (!existsSync15(CACHE_DIR2)) {
|
|
24973
25211
|
return void 0;
|
|
24974
25212
|
}
|
|
24975
25213
|
const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR2 });
|
|
@@ -24981,7 +25219,7 @@ async function findFromCache() {
|
|
|
24981
25219
|
}
|
|
24982
25220
|
function findFromSystem2() {
|
|
24983
25221
|
for (const p of SYSTEM_CHROME_PATHS) {
|
|
24984
|
-
if (
|
|
25222
|
+
if (existsSync15(p)) {
|
|
24985
25223
|
return { executablePath: p, source: "system" };
|
|
24986
25224
|
}
|
|
24987
25225
|
}
|
|
@@ -25001,21 +25239,21 @@ async function findBrowser() {
|
|
|
25001
25239
|
async function ensureBrowser(options) {
|
|
25002
25240
|
const existing = await findBrowser();
|
|
25003
25241
|
if (existing) return existing;
|
|
25004
|
-
const
|
|
25005
|
-
if (!
|
|
25242
|
+
const platform6 = detectBrowserPlatform();
|
|
25243
|
+
if (!platform6) {
|
|
25006
25244
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
|
25007
25245
|
}
|
|
25008
25246
|
const installed = await install({
|
|
25009
25247
|
cacheDir: CACHE_DIR2,
|
|
25010
25248
|
browser: Browser.CHROMEHEADLESSSHELL,
|
|
25011
25249
|
buildId: CHROME_VERSION,
|
|
25012
|
-
platform:
|
|
25250
|
+
platform: platform6,
|
|
25013
25251
|
downloadProgressCallback: options?.onProgress
|
|
25014
25252
|
});
|
|
25015
25253
|
return { executablePath: installed.executablePath, source: "download" };
|
|
25016
25254
|
}
|
|
25017
25255
|
function clearBrowser() {
|
|
25018
|
-
if (!
|
|
25256
|
+
if (!existsSync15(CACHE_DIR2)) {
|
|
25019
25257
|
return false;
|
|
25020
25258
|
}
|
|
25021
25259
|
rmSync4(CACHE_DIR2, { recursive: true, force: true });
|
|
@@ -25026,7 +25264,7 @@ var init_manager2 = __esm({
|
|
|
25026
25264
|
"src/browser/manager.ts"() {
|
|
25027
25265
|
"use strict";
|
|
25028
25266
|
CHROME_VERSION = "131.0.6778.85";
|
|
25029
|
-
CACHE_DIR2 =
|
|
25267
|
+
CACHE_DIR2 = join18(homedir5(), ".cache", "hyperframes", "chrome");
|
|
25030
25268
|
SYSTEM_CHROME_PATHS = process.platform === "darwin" ? ["/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"] : [
|
|
25031
25269
|
"/usr/bin/google-chrome",
|
|
25032
25270
|
"/usr/bin/google-chrome-stable",
|
|
@@ -25153,9 +25391,9 @@ var init_config2 = __esm({
|
|
|
25153
25391
|
});
|
|
25154
25392
|
|
|
25155
25393
|
// ../engine/src/services/browserManager.ts
|
|
25156
|
-
import { existsSync as
|
|
25157
|
-
import { join as
|
|
25158
|
-
import { homedir as
|
|
25394
|
+
import { existsSync as existsSync16, readdirSync as readdirSync7 } from "fs";
|
|
25395
|
+
import { join as join19 } from "path";
|
|
25396
|
+
import { homedir as homedir6 } from "os";
|
|
25159
25397
|
async function getPuppeteer() {
|
|
25160
25398
|
if (_puppeteer) return _puppeteer;
|
|
25161
25399
|
try {
|
|
@@ -25175,19 +25413,19 @@ function resolveHeadlessShellPath(config) {
|
|
|
25175
25413
|
if (process.env.PRODUCER_HEADLESS_SHELL_PATH) {
|
|
25176
25414
|
return process.env.PRODUCER_HEADLESS_SHELL_PATH;
|
|
25177
25415
|
}
|
|
25178
|
-
const baseDir =
|
|
25179
|
-
if (!
|
|
25416
|
+
const baseDir = join19(homedir6(), ".cache", "puppeteer", "chrome-headless-shell");
|
|
25417
|
+
if (!existsSync16(baseDir)) return void 0;
|
|
25180
25418
|
try {
|
|
25181
|
-
const versions =
|
|
25419
|
+
const versions = readdirSync7(baseDir).sort().reverse();
|
|
25182
25420
|
for (const version of versions) {
|
|
25183
25421
|
const candidates = [
|
|
25184
|
-
|
|
25185
|
-
|
|
25186
|
-
|
|
25187
|
-
|
|
25422
|
+
join19(baseDir, version, "chrome-headless-shell-linux64", "chrome-headless-shell"),
|
|
25423
|
+
join19(baseDir, version, "chrome-headless-shell-mac-arm64", "chrome-headless-shell"),
|
|
25424
|
+
join19(baseDir, version, "chrome-headless-shell-mac-x64", "chrome-headless-shell"),
|
|
25425
|
+
join19(baseDir, version, "chrome-headless-shell-win64", "chrome-headless-shell.exe")
|
|
25188
25426
|
];
|
|
25189
25427
|
for (const binary of candidates) {
|
|
25190
|
-
if (
|
|
25428
|
+
if (existsSync16(binary)) return binary;
|
|
25191
25429
|
}
|
|
25192
25430
|
}
|
|
25193
25431
|
} catch {
|
|
@@ -25650,10 +25888,10 @@ var init_screenshotService = __esm({
|
|
|
25650
25888
|
});
|
|
25651
25889
|
|
|
25652
25890
|
// ../engine/src/services/frameCapture.ts
|
|
25653
|
-
import { existsSync as
|
|
25654
|
-
import { join as
|
|
25891
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
|
|
25892
|
+
import { join as join20 } from "path";
|
|
25655
25893
|
async function createCaptureSession(serverUrl, outputDir, options, onBeforeCapture = null, config) {
|
|
25656
|
-
if (!
|
|
25894
|
+
if (!existsSync17(outputDir)) mkdirSync8(outputDir, { recursive: true });
|
|
25657
25895
|
const headlessShell = resolveHeadlessShellPath(config);
|
|
25658
25896
|
const isLinux = process.platform === "linux";
|
|
25659
25897
|
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
|
|
@@ -25857,9 +26095,9 @@ async function initializeSession(session) {
|
|
|
25857
26095
|
}
|
|
25858
26096
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
25859
26097
|
try {
|
|
25860
|
-
const diagnosticsDir =
|
|
25861
|
-
if (!
|
|
25862
|
-
const base =
|
|
26098
|
+
const diagnosticsDir = join20(session.outputDir, "diagnostics");
|
|
26099
|
+
if (!existsSync17(diagnosticsDir)) mkdirSync8(diagnosticsDir, { recursive: true });
|
|
26100
|
+
const base = join20(diagnosticsDir, `frame-error-${frameIndex}`);
|
|
25863
26101
|
await session.page.screenshot({ path: `${base}.png`, type: "png", fullPage: true });
|
|
25864
26102
|
const html = await session.page.content();
|
|
25865
26103
|
writeFileSync8(`${base}.html`, html, "utf-8");
|
|
@@ -25957,7 +26195,7 @@ async function captureFrame(session, frameIndex, time) {
|
|
|
25957
26195
|
);
|
|
25958
26196
|
const ext = options.format === "png" ? "png" : "jpg";
|
|
25959
26197
|
const frameName = `frame_${String(frameIndex).padStart(6, "0")}.${ext}`;
|
|
25960
|
-
const framePath =
|
|
26198
|
+
const framePath = join20(outputDir, frameName);
|
|
25961
26199
|
writeFileSync8(framePath, buffer);
|
|
25962
26200
|
return { frameIndex, time: quantizedTime, path: framePath, captureTimeMs };
|
|
25963
26201
|
}
|
|
@@ -25978,7 +26216,7 @@ async function closeCaptureSession(session) {
|
|
|
25978
26216
|
session.isInitialized = false;
|
|
25979
26217
|
}
|
|
25980
26218
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
25981
|
-
if (!
|
|
26219
|
+
if (!existsSync17(outputDir)) {
|
|
25982
26220
|
mkdirSync8(outputDir, { recursive: true });
|
|
25983
26221
|
}
|
|
25984
26222
|
session.outputDir = outputDir;
|
|
@@ -26216,8 +26454,8 @@ var init_runFfmpeg = __esm({
|
|
|
26216
26454
|
|
|
26217
26455
|
// ../engine/src/services/chunkEncoder.ts
|
|
26218
26456
|
import { spawn as spawn4 } from "child_process";
|
|
26219
|
-
import { copyFileSync, existsSync as
|
|
26220
|
-
import { join as
|
|
26457
|
+
import { copyFileSync, existsSync as existsSync18, mkdirSync as mkdirSync9, readdirSync as readdirSync8, statSync as statSync6, writeFileSync as writeFileSync9 } from "fs";
|
|
26458
|
+
import { join as join21, dirname as dirname6 } from "path";
|
|
26221
26459
|
function getEncoderPreset(quality, format = "mp4", hdr) {
|
|
26222
26460
|
const base = ENCODER_PRESETS[quality];
|
|
26223
26461
|
if (format === "webm") {
|
|
@@ -26368,8 +26606,8 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
26368
26606
|
async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
|
|
26369
26607
|
const startTime = Date.now();
|
|
26370
26608
|
const outputDir = dirname6(outputPath);
|
|
26371
|
-
if (!
|
|
26372
|
-
const files =
|
|
26609
|
+
if (!existsSync18(outputDir)) mkdirSync9(outputDir, { recursive: true });
|
|
26610
|
+
const files = readdirSync8(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i));
|
|
26373
26611
|
const frameCount = files.length;
|
|
26374
26612
|
if (frameCount === 0) {
|
|
26375
26613
|
return {
|
|
@@ -26385,7 +26623,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
26385
26623
|
if (options.useGpu) {
|
|
26386
26624
|
gpuEncoder = await getCachedGpuEncoder();
|
|
26387
26625
|
}
|
|
26388
|
-
const inputPath =
|
|
26626
|
+
const inputPath = join21(framesDir, framePattern);
|
|
26389
26627
|
const inputArgs = ["-framerate", String(options.fps), "-i", inputPath];
|
|
26390
26628
|
const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
|
|
26391
26629
|
return new Promise((resolve39) => {
|
|
@@ -26434,7 +26672,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
26434
26672
|
});
|
|
26435
26673
|
return;
|
|
26436
26674
|
}
|
|
26437
|
-
const fileSize =
|
|
26675
|
+
const fileSize = existsSync18(outputPath) ? statSync6(outputPath).size : 0;
|
|
26438
26676
|
resolve39({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
26439
26677
|
});
|
|
26440
26678
|
ffmpeg.on("error", (err) => {
|
|
@@ -26453,7 +26691,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
26453
26691
|
}
|
|
26454
26692
|
async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, options, chunkSizeFrames, signal) {
|
|
26455
26693
|
const start = Date.now();
|
|
26456
|
-
const files =
|
|
26694
|
+
const files = readdirSync8(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i)).sort();
|
|
26457
26695
|
if (files.length === 0) {
|
|
26458
26696
|
return {
|
|
26459
26697
|
success: false,
|
|
@@ -26466,8 +26704,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
26466
26704
|
}
|
|
26467
26705
|
const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
|
|
26468
26706
|
const chunkCount = Math.ceil(files.length / chunkSize);
|
|
26469
|
-
const chunkDir =
|
|
26470
|
-
if (!
|
|
26707
|
+
const chunkDir = join21(dirname6(outputPath), "chunk-encode");
|
|
26708
|
+
if (!existsSync18(chunkDir)) mkdirSync9(chunkDir, { recursive: true });
|
|
26471
26709
|
const chunkPaths = [];
|
|
26472
26710
|
for (let i2 = 0; i2 < chunkCount; i2++) {
|
|
26473
26711
|
if (signal?.aborted) {
|
|
@@ -26483,8 +26721,8 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
26483
26721
|
const startNumber = i2 * chunkSize;
|
|
26484
26722
|
const framesInChunk = Math.min(chunkSize, files.length - startNumber);
|
|
26485
26723
|
const ext = outputPath.endsWith(".webm") ? ".webm" : outputPath.endsWith(".mov") ? ".mov" : ".mp4";
|
|
26486
|
-
const chunkPath =
|
|
26487
|
-
const inputPath =
|
|
26724
|
+
const chunkPath = join21(chunkDir, `chunk_${String(i2).padStart(4, "0")}${ext}`);
|
|
26725
|
+
const inputPath = join21(framesDir, framePattern);
|
|
26488
26726
|
const inputArgs = [
|
|
26489
26727
|
"-framerate",
|
|
26490
26728
|
String(options.fps),
|
|
@@ -26524,7 +26762,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
26524
26762
|
}
|
|
26525
26763
|
chunkPaths.push(chunkPath);
|
|
26526
26764
|
}
|
|
26527
|
-
const concatListPath =
|
|
26765
|
+
const concatListPath = join21(chunkDir, "concat-list.txt");
|
|
26528
26766
|
const concatInput = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
|
|
26529
26767
|
writeFileSync9(concatListPath, concatInput, "utf-8");
|
|
26530
26768
|
const concatArgs = [
|
|
@@ -26563,7 +26801,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
26563
26801
|
error: concatResult.error
|
|
26564
26802
|
};
|
|
26565
26803
|
}
|
|
26566
|
-
const fileSize =
|
|
26804
|
+
const fileSize = existsSync18(outputPath) ? statSync6(outputPath).size : 0;
|
|
26567
26805
|
return {
|
|
26568
26806
|
success: true,
|
|
26569
26807
|
outputPath,
|
|
@@ -26574,7 +26812,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
26574
26812
|
}
|
|
26575
26813
|
async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
|
|
26576
26814
|
const outputDir = dirname6(outputPath);
|
|
26577
|
-
if (!
|
|
26815
|
+
if (!existsSync18(outputDir)) mkdirSync9(outputDir, { recursive: true });
|
|
26578
26816
|
const isWebm = outputPath.endsWith(".webm");
|
|
26579
26817
|
const isMov = outputPath.endsWith(".mov");
|
|
26580
26818
|
const args = ["-i", videoPath, "-i", audioPath, "-c:v", "copy"];
|
|
@@ -26645,7 +26883,7 @@ var init_chunkEncoder = __esm({
|
|
|
26645
26883
|
|
|
26646
26884
|
// ../engine/src/services/streamingEncoder.ts
|
|
26647
26885
|
import { spawn as spawn5 } from "child_process";
|
|
26648
|
-
import { existsSync as
|
|
26886
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync10, statSync as statSync7 } from "fs";
|
|
26649
26887
|
import { dirname as dirname7 } from "path";
|
|
26650
26888
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
26651
26889
|
let cursor = startFrame;
|
|
@@ -26828,7 +27066,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
26828
27066
|
}
|
|
26829
27067
|
async function spawnStreamingEncoder(outputPath, options, signal, config) {
|
|
26830
27068
|
const outputDir = dirname7(outputPath);
|
|
26831
|
-
if (!
|
|
27069
|
+
if (!existsSync19(outputDir)) mkdirSync10(outputDir, { recursive: true });
|
|
26832
27070
|
let gpuEncoder = null;
|
|
26833
27071
|
if (options.useGpu) {
|
|
26834
27072
|
gpuEncoder = await getCachedGpuEncoder();
|
|
@@ -26910,7 +27148,7 @@ Process error: ${err.message}`;
|
|
|
26910
27148
|
error: formatFfmpegError(exitCode, stderr)
|
|
26911
27149
|
};
|
|
26912
27150
|
}
|
|
26913
|
-
const fileSize =
|
|
27151
|
+
const fileSize = existsSync19(outputPath) ? statSync7(outputPath).size : 0;
|
|
26914
27152
|
return { success: true, durationMs, fileSize };
|
|
26915
27153
|
},
|
|
26916
27154
|
getExitStatus: () => exitStatus
|
|
@@ -27202,9 +27440,9 @@ var init_ffprobe = __esm({
|
|
|
27202
27440
|
});
|
|
27203
27441
|
|
|
27204
27442
|
// ../engine/src/utils/urlDownloader.ts
|
|
27205
|
-
import { createWriteStream as createWriteStream2, existsSync as
|
|
27443
|
+
import { createWriteStream as createWriteStream2, existsSync as existsSync20, mkdirSync as mkdirSync11 } from "fs";
|
|
27206
27444
|
import { createHash } from "crypto";
|
|
27207
|
-
import { join as
|
|
27445
|
+
import { join as join22, extname as extname5 } from "path";
|
|
27208
27446
|
import { Readable } from "stream";
|
|
27209
27447
|
import { finished } from "stream/promises";
|
|
27210
27448
|
function getFilenameFromUrl(url) {
|
|
@@ -27215,19 +27453,19 @@ function getFilenameFromUrl(url) {
|
|
|
27215
27453
|
}
|
|
27216
27454
|
async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
|
|
27217
27455
|
const cachedPath = downloadPathCache.get(url);
|
|
27218
|
-
if (cachedPath &&
|
|
27456
|
+
if (cachedPath && existsSync20(cachedPath)) {
|
|
27219
27457
|
return cachedPath;
|
|
27220
27458
|
}
|
|
27221
27459
|
const inFlight = inFlightDownloads.get(url);
|
|
27222
27460
|
if (inFlight) {
|
|
27223
27461
|
return inFlight;
|
|
27224
27462
|
}
|
|
27225
|
-
if (!
|
|
27463
|
+
if (!existsSync20(destDir)) {
|
|
27226
27464
|
mkdirSync11(destDir, { recursive: true });
|
|
27227
27465
|
}
|
|
27228
27466
|
const filename = getFilenameFromUrl(url);
|
|
27229
|
-
const localPath =
|
|
27230
|
-
if (
|
|
27467
|
+
const localPath = join22(destDir, filename);
|
|
27468
|
+
if (existsSync20(localPath)) {
|
|
27231
27469
|
downloadPathCache.set(url, localPath);
|
|
27232
27470
|
return localPath;
|
|
27233
27471
|
}
|
|
@@ -27319,12 +27557,12 @@ var init_htmlTemplate = __esm({
|
|
|
27319
27557
|
|
|
27320
27558
|
// ../engine/src/services/extractionCache.ts
|
|
27321
27559
|
import { createHash as createHash2 } from "crypto";
|
|
27322
|
-
import { mkdirSync as mkdirSync12, readdirSync as
|
|
27323
|
-
import { existsSync as
|
|
27324
|
-
import { join as
|
|
27560
|
+
import { mkdirSync as mkdirSync12, readdirSync as readdirSync9, statSync as statSync8, writeFileSync as writeFileSync10 } from "fs";
|
|
27561
|
+
import { existsSync as existsSync21 } from "fs";
|
|
27562
|
+
import { join as join23 } from "path";
|
|
27325
27563
|
function readKeyStat(videoPath) {
|
|
27326
27564
|
try {
|
|
27327
|
-
const stat3 =
|
|
27565
|
+
const stat3 = statSync8(videoPath);
|
|
27328
27566
|
return { mtimeMs: Math.floor(stat3.mtimeMs), size: stat3.size };
|
|
27329
27567
|
} catch {
|
|
27330
27568
|
return null;
|
|
@@ -27350,23 +27588,23 @@ function cacheEntryDirName(keyHash) {
|
|
|
27350
27588
|
}
|
|
27351
27589
|
function lookupCacheEntry(rootDir, input) {
|
|
27352
27590
|
const keyHash = computeCacheKey(input);
|
|
27353
|
-
const dir =
|
|
27354
|
-
const complete =
|
|
27591
|
+
const dir = join23(rootDir, cacheEntryDirName(keyHash));
|
|
27592
|
+
const complete = existsSync21(join23(dir, COMPLETE_SENTINEL));
|
|
27355
27593
|
return { entry: { dir, keyHash }, hit: complete };
|
|
27356
27594
|
}
|
|
27357
27595
|
function ensureCacheEntryDir(entry) {
|
|
27358
27596
|
mkdirSync12(entry.dir, { recursive: true });
|
|
27359
27597
|
}
|
|
27360
27598
|
function markCacheEntryComplete(entry) {
|
|
27361
|
-
writeFileSync10(
|
|
27599
|
+
writeFileSync10(join23(entry.dir, COMPLETE_SENTINEL), "", "utf-8");
|
|
27362
27600
|
}
|
|
27363
27601
|
function rehydrateCacheEntry(entry, options) {
|
|
27364
27602
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
27365
27603
|
const framePaths = /* @__PURE__ */ new Map();
|
|
27366
27604
|
const suffix = `.${options.format}`;
|
|
27367
|
-
const files =
|
|
27605
|
+
const files = readdirSync9(entry.dir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(suffix)).sort();
|
|
27368
27606
|
files.forEach((file, idx) => {
|
|
27369
|
-
framePaths.set(idx,
|
|
27607
|
+
framePaths.set(idx, join23(entry.dir, file));
|
|
27370
27608
|
});
|
|
27371
27609
|
return {
|
|
27372
27610
|
videoId: options.videoId,
|
|
@@ -27392,8 +27630,8 @@ var init_extractionCache = __esm({
|
|
|
27392
27630
|
|
|
27393
27631
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
27394
27632
|
import { spawn as spawn7 } from "child_process";
|
|
27395
|
-
import { existsSync as
|
|
27396
|
-
import { isAbsolute as isAbsolute2, join as
|
|
27633
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync13, readdirSync as readdirSync10, rmSync as rmSync5 } from "fs";
|
|
27634
|
+
import { isAbsolute as isAbsolute2, join as join24 } from "path";
|
|
27397
27635
|
function parseVideoElements(html) {
|
|
27398
27636
|
const videos = [];
|
|
27399
27637
|
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
@@ -27463,12 +27701,12 @@ function parseImageElements(html) {
|
|
|
27463
27701
|
async function extractVideoFramesRange(videoPath, videoId, startTime, duration, options, signal, config, outputDirOverride) {
|
|
27464
27702
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
27465
27703
|
const { fps, outputDir, quality = 95 } = options;
|
|
27466
|
-
const videoOutputDir = outputDirOverride ??
|
|
27467
|
-
if (!
|
|
27704
|
+
const videoOutputDir = outputDirOverride ?? join24(outputDir, videoId);
|
|
27705
|
+
if (!existsSync22(videoOutputDir)) mkdirSync13(videoOutputDir, { recursive: true });
|
|
27468
27706
|
const metadata = await extractMediaMetadata(videoPath);
|
|
27469
27707
|
const format = resolveFrameFormat(metadata, options.format);
|
|
27470
27708
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
|
|
27471
|
-
const outputPattern =
|
|
27709
|
+
const outputPattern = join24(videoOutputDir, framePattern);
|
|
27472
27710
|
const isHdr = isHdrColorSpace(metadata.colorSpace);
|
|
27473
27711
|
const isMacOS = process.platform === "darwin";
|
|
27474
27712
|
const args = [];
|
|
@@ -27519,9 +27757,9 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
27519
27757
|
return;
|
|
27520
27758
|
}
|
|
27521
27759
|
const framePaths = /* @__PURE__ */ new Map();
|
|
27522
|
-
const files =
|
|
27760
|
+
const files = readdirSync10(videoOutputDir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(`.${format}`)).sort();
|
|
27523
27761
|
files.forEach((file, index) => {
|
|
27524
|
-
framePaths.set(index,
|
|
27762
|
+
framePaths.set(index, join24(videoOutputDir, file));
|
|
27525
27763
|
});
|
|
27526
27764
|
resolve39({
|
|
27527
27765
|
videoId,
|
|
@@ -27648,15 +27886,15 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
27648
27886
|
try {
|
|
27649
27887
|
let videoPath = video.src;
|
|
27650
27888
|
if (!isAbsolute2(videoPath) && !isHttpUrl(videoPath)) {
|
|
27651
|
-
const fromCompiled = compiledDir ?
|
|
27652
|
-
videoPath = fromCompiled &&
|
|
27889
|
+
const fromCompiled = compiledDir ? join24(compiledDir, videoPath) : null;
|
|
27890
|
+
videoPath = fromCompiled && existsSync22(fromCompiled) ? fromCompiled : join24(baseDir, videoPath);
|
|
27653
27891
|
}
|
|
27654
27892
|
if (isHttpUrl(videoPath)) {
|
|
27655
|
-
const downloadDir =
|
|
27893
|
+
const downloadDir = join24(options.outputDir, "_downloads");
|
|
27656
27894
|
mkdirSync13(downloadDir, { recursive: true });
|
|
27657
27895
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
27658
27896
|
}
|
|
27659
|
-
if (!
|
|
27897
|
+
if (!existsSync22(videoPath)) {
|
|
27660
27898
|
errors.push({ videoId: video.id, error: `Video file not found: ${videoPath}` });
|
|
27661
27899
|
continue;
|
|
27662
27900
|
}
|
|
@@ -27689,7 +27927,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
27689
27927
|
const hdrSkippedIndices = /* @__PURE__ */ new Set();
|
|
27690
27928
|
if (hdrInfo.hasHdr && hdrInfo.dominantTransfer) {
|
|
27691
27929
|
const targetTransfer = hdrInfo.dominantTransfer;
|
|
27692
|
-
const convertDir =
|
|
27930
|
+
const convertDir = join24(options.outputDir, "_hdr_normalized");
|
|
27693
27931
|
mkdirSync13(convertDir, { recursive: true });
|
|
27694
27932
|
for (let i2 = 0; i2 < resolvedVideos.length; i2++) {
|
|
27695
27933
|
if (signal?.aborted) break;
|
|
@@ -27711,7 +27949,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
27711
27949
|
const sourceRemaining = metadata.durationSeconds - entry.video.mediaStart;
|
|
27712
27950
|
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
27713
27951
|
}
|
|
27714
|
-
const convertedPath =
|
|
27952
|
+
const convertedPath = join24(convertDir, `${entry.video.id}_hdr.mp4`);
|
|
27715
27953
|
try {
|
|
27716
27954
|
await convertSdrToHdr(
|
|
27717
27955
|
entry.videoPath,
|
|
@@ -27746,7 +27984,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
27746
27984
|
}
|
|
27747
27985
|
}
|
|
27748
27986
|
const vfrPreflightStart = Date.now();
|
|
27749
|
-
const vfrNormDir =
|
|
27987
|
+
const vfrNormDir = join24(options.outputDir, "_vfr_normalized");
|
|
27750
27988
|
for (let i2 = 0; i2 < resolvedVideos.length; i2++) {
|
|
27751
27989
|
if (signal?.aborted) break;
|
|
27752
27990
|
const entry = resolvedVideos[i2];
|
|
@@ -27761,7 +27999,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
27761
27999
|
segDuration = sourceRemaining > 0 ? sourceRemaining : metadata.durationSeconds;
|
|
27762
28000
|
}
|
|
27763
28001
|
mkdirSync13(vfrNormDir, { recursive: true });
|
|
27764
|
-
const normalizedPath =
|
|
28002
|
+
const normalizedPath = join24(vfrNormDir, `${entry.video.id}_cfr.mp4`);
|
|
27765
28003
|
try {
|
|
27766
28004
|
await convertVfrToCfr(
|
|
27767
28005
|
entry.videoPath,
|
|
@@ -28017,7 +28255,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
28017
28255
|
cleanup() {
|
|
28018
28256
|
for (const video of this.videos.values()) {
|
|
28019
28257
|
if (video.extracted.ownedByLookup) continue;
|
|
28020
|
-
if (
|
|
28258
|
+
if (existsSync22(video.extracted.outputDir)) {
|
|
28021
28259
|
rmSync5(video.extracted.outputDir, { recursive: true, force: true });
|
|
28022
28260
|
}
|
|
28023
28261
|
}
|
|
@@ -28325,8 +28563,8 @@ var init_videoFrameInjector = __esm({
|
|
|
28325
28563
|
});
|
|
28326
28564
|
|
|
28327
28565
|
// ../engine/src/services/audioMixer.ts
|
|
28328
|
-
import { existsSync as
|
|
28329
|
-
import { isAbsolute as isAbsolute3, join as
|
|
28566
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync14, rmSync as rmSync6 } from "fs";
|
|
28567
|
+
import { isAbsolute as isAbsolute3, join as join25, dirname as dirname8 } from "path";
|
|
28330
28568
|
function parseAudioElements(html) {
|
|
28331
28569
|
const elements = [];
|
|
28332
28570
|
const { document: document2 } = parseHTML(unwrapTemplate(html));
|
|
@@ -28377,7 +28615,7 @@ function parseAudioElements(html) {
|
|
|
28377
28615
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
|
|
28378
28616
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
28379
28617
|
const outputDir = dirname8(outputPath);
|
|
28380
|
-
if (!
|
|
28618
|
+
if (!existsSync23(outputDir)) mkdirSync14(outputDir, { recursive: true });
|
|
28381
28619
|
const args = ["-i", videoPath];
|
|
28382
28620
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
28383
28621
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -28404,7 +28642,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
28404
28642
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config) {
|
|
28405
28643
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
28406
28644
|
const outputDir = dirname8(outputPath);
|
|
28407
|
-
if (!
|
|
28645
|
+
if (!existsSync23(outputDir)) mkdirSync14(outputDir, { recursive: true });
|
|
28408
28646
|
const args = [
|
|
28409
28647
|
"-ss",
|
|
28410
28648
|
String(mediaStart),
|
|
@@ -28440,7 +28678,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
28440
28678
|
async function generateSilence(outputPath, duration, signal, config) {
|
|
28441
28679
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
28442
28680
|
const outputDir = dirname8(outputPath);
|
|
28443
|
-
if (!
|
|
28681
|
+
if (!existsSync23(outputDir)) mkdirSync14(outputDir, { recursive: true });
|
|
28444
28682
|
const args = [
|
|
28445
28683
|
"-f",
|
|
28446
28684
|
"lavfi",
|
|
@@ -28483,7 +28721,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
28483
28721
|
};
|
|
28484
28722
|
}
|
|
28485
28723
|
const outputDir = dirname8(outputPath);
|
|
28486
|
-
if (!
|
|
28724
|
+
if (!existsSync23(outputDir)) mkdirSync14(outputDir, { recursive: true });
|
|
28487
28725
|
const inputs = [];
|
|
28488
28726
|
const filterParts = [];
|
|
28489
28727
|
tracks.forEach((track, i2) => {
|
|
@@ -28544,7 +28782,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
28544
28782
|
const startMs = Date.now();
|
|
28545
28783
|
const tracks = [];
|
|
28546
28784
|
const errors = [];
|
|
28547
|
-
if (!
|
|
28785
|
+
if (!existsSync23(workDir)) mkdirSync14(workDir, { recursive: true });
|
|
28548
28786
|
await Promise.all(
|
|
28549
28787
|
elements.map(async (element) => {
|
|
28550
28788
|
if (signal?.aborted) {
|
|
@@ -28554,8 +28792,8 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
28554
28792
|
try {
|
|
28555
28793
|
let srcPath = element.src;
|
|
28556
28794
|
if (!isAbsolute3(srcPath) && !isHttpUrl(srcPath)) {
|
|
28557
|
-
const fromCompiled = compiledDir ?
|
|
28558
|
-
srcPath = fromCompiled &&
|
|
28795
|
+
const fromCompiled = compiledDir ? join25(compiledDir, srcPath) : null;
|
|
28796
|
+
srcPath = fromCompiled && existsSync23(fromCompiled) ? fromCompiled : join25(baseDir, srcPath);
|
|
28559
28797
|
}
|
|
28560
28798
|
if (isHttpUrl(srcPath)) {
|
|
28561
28799
|
try {
|
|
@@ -28567,7 +28805,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
28567
28805
|
return;
|
|
28568
28806
|
}
|
|
28569
28807
|
}
|
|
28570
|
-
if (!
|
|
28808
|
+
if (!existsSync23(srcPath)) {
|
|
28571
28809
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
28572
28810
|
return;
|
|
28573
28811
|
}
|
|
@@ -28578,7 +28816,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
28578
28816
|
}
|
|
28579
28817
|
let audioSrcPath = srcPath;
|
|
28580
28818
|
if (element.type === "video") {
|
|
28581
|
-
const extractedPath =
|
|
28819
|
+
const extractedPath = join25(workDir, `${element.id}-extracted.wav`);
|
|
28582
28820
|
const extractResult = await extractAudioFromVideo(
|
|
28583
28821
|
srcPath,
|
|
28584
28822
|
extractedPath,
|
|
@@ -28595,7 +28833,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
28595
28833
|
}
|
|
28596
28834
|
audioSrcPath = extractedPath;
|
|
28597
28835
|
} else {
|
|
28598
|
-
const trimmedPath =
|
|
28836
|
+
const trimmedPath = join25(workDir, `${element.id}-trimmed.wav`);
|
|
28599
28837
|
const prepResult = await prepareAudioTrack(
|
|
28600
28838
|
srcPath,
|
|
28601
28839
|
trimmedPath,
|
|
@@ -28649,9 +28887,9 @@ var init_audioMixer = __esm({
|
|
|
28649
28887
|
|
|
28650
28888
|
// ../engine/src/services/parallelCoordinator.ts
|
|
28651
28889
|
import { cpus as cpus2, freemem, totalmem as totalmem2 } from "os";
|
|
28652
|
-
import { existsSync as
|
|
28890
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync15, readdirSync as readdirSync11 } from "fs";
|
|
28653
28891
|
import { copyFile, rename } from "fs/promises";
|
|
28654
|
-
import { join as
|
|
28892
|
+
import { join as join26 } from "path";
|
|
28655
28893
|
function calculateOptimalWorkers(totalFrames, requested, config) {
|
|
28656
28894
|
const effectiveMaxWorkers = (() => {
|
|
28657
28895
|
const concurrency = config?.concurrency ?? DEFAULT_CONFIG2.concurrency;
|
|
@@ -28694,7 +28932,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
28694
28932
|
workerId: i2,
|
|
28695
28933
|
startFrame,
|
|
28696
28934
|
endFrame,
|
|
28697
|
-
outputDir:
|
|
28935
|
+
outputDir: join26(workDir, `worker-${i2}`)
|
|
28698
28936
|
});
|
|
28699
28937
|
}
|
|
28700
28938
|
return tasks;
|
|
@@ -28702,7 +28940,7 @@ function distributeFrames(totalFrames, workerCount, workDir) {
|
|
|
28702
28940
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config) {
|
|
28703
28941
|
const startTime = Date.now();
|
|
28704
28942
|
let framesCaptured = 0;
|
|
28705
|
-
if (!
|
|
28943
|
+
if (!existsSync24(task.outputDir)) mkdirSync15(task.outputDir, { recursive: true });
|
|
28706
28944
|
let session = null;
|
|
28707
28945
|
let perf;
|
|
28708
28946
|
try {
|
|
@@ -28792,17 +29030,17 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
28792
29030
|
return results;
|
|
28793
29031
|
}
|
|
28794
29032
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
28795
|
-
if (!
|
|
29033
|
+
if (!existsSync24(outputDir)) mkdirSync15(outputDir, { recursive: true });
|
|
28796
29034
|
let totalFrames = 0;
|
|
28797
29035
|
const sortedTasks = [...tasks].sort((a, b) => a.startFrame - b.startFrame);
|
|
28798
29036
|
for (const task of sortedTasks) {
|
|
28799
|
-
if (!
|
|
29037
|
+
if (!existsSync24(task.outputDir)) {
|
|
28800
29038
|
continue;
|
|
28801
29039
|
}
|
|
28802
|
-
const files =
|
|
29040
|
+
const files = readdirSync11(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
28803
29041
|
const copyTasks = files.map(async (file) => {
|
|
28804
|
-
const sourcePath =
|
|
28805
|
-
const targetPath =
|
|
29042
|
+
const sourcePath = join26(task.outputDir, file);
|
|
29043
|
+
const targetPath = join26(outputDir, file);
|
|
28806
29044
|
try {
|
|
28807
29045
|
await rename(sourcePath, targetPath);
|
|
28808
29046
|
} catch {
|
|
@@ -28839,8 +29077,8 @@ var init_parallelCoordinator = __esm({
|
|
|
28839
29077
|
// ../engine/src/services/fileServer.ts
|
|
28840
29078
|
import { Hono as Hono2 } from "hono";
|
|
28841
29079
|
import { serve } from "@hono/node-server";
|
|
28842
|
-
import { readFileSync as readFileSync16, existsSync as
|
|
28843
|
-
import { join as
|
|
29080
|
+
import { readFileSync as readFileSync16, existsSync as existsSync25, statSync as statSync9 } from "fs";
|
|
29081
|
+
import { join as join27, extname as extname6 } from "path";
|
|
28844
29082
|
function stripEmbeddedRuntimeScripts(html) {
|
|
28845
29083
|
if (!html) return html;
|
|
28846
29084
|
const scriptRe = /<script\b[^>]*>[\s\S]*?<\/script>/gi;
|
|
@@ -28909,12 +29147,12 @@ function createFileServer(options) {
|
|
|
28909
29147
|
let requestPath = c2.req.path;
|
|
28910
29148
|
if (requestPath === "/") requestPath = "/index.html";
|
|
28911
29149
|
const relativePath = requestPath.replace(/^\//, "");
|
|
28912
|
-
const compiledPath = compiledDir ?
|
|
29150
|
+
const compiledPath = compiledDir ? join27(compiledDir, relativePath) : null;
|
|
28913
29151
|
const hasCompiledFile = Boolean(
|
|
28914
|
-
compiledPath &&
|
|
29152
|
+
compiledPath && existsSync25(compiledPath) && statSync9(compiledPath).isFile()
|
|
28915
29153
|
);
|
|
28916
|
-
const filePath = hasCompiledFile ? compiledPath :
|
|
28917
|
-
if (!
|
|
29154
|
+
const filePath = hasCompiledFile ? compiledPath : join27(projectDir, relativePath);
|
|
29155
|
+
if (!existsSync25(filePath) || !statSync9(filePath).isFile()) {
|
|
28918
29156
|
return c2.text("Not found", 404);
|
|
28919
29157
|
}
|
|
28920
29158
|
const ext = extname6(filePath).toLowerCase();
|
|
@@ -30192,9 +30430,9 @@ var init_shaderTransitions = __esm({
|
|
|
30192
30430
|
});
|
|
30193
30431
|
|
|
30194
30432
|
// ../engine/src/services/hdrCapture.ts
|
|
30195
|
-
import { existsSync as
|
|
30196
|
-
import { join as
|
|
30197
|
-
import { homedir as
|
|
30433
|
+
import { existsSync as existsSync26, readdirSync as readdirSync12 } from "fs";
|
|
30434
|
+
import { join as join28 } from "path";
|
|
30435
|
+
import { homedir as homedir7 } from "os";
|
|
30198
30436
|
function linearToPQ(L2) {
|
|
30199
30437
|
const Lp = Math.max(0, L2 * SDR_NITS / PQ_MAX_NITS);
|
|
30200
30438
|
const Lm1 = Math.pow(Lp, PQ_M12);
|
|
@@ -30309,12 +30547,12 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
30309
30547
|
return output;
|
|
30310
30548
|
}
|
|
30311
30549
|
function resolveHeadedChromePath() {
|
|
30312
|
-
const baseDir =
|
|
30313
|
-
if (!
|
|
30314
|
-
const versions =
|
|
30550
|
+
const baseDir = join28(homedir7(), ".cache", "puppeteer", "chrome");
|
|
30551
|
+
if (!existsSync26(baseDir)) return void 0;
|
|
30552
|
+
const versions = readdirSync12(baseDir).sort().reverse();
|
|
30315
30553
|
for (const version of versions) {
|
|
30316
30554
|
const candidates = [
|
|
30317
|
-
|
|
30555
|
+
join28(
|
|
30318
30556
|
baseDir,
|
|
30319
30557
|
version,
|
|
30320
30558
|
"chrome-mac-arm64",
|
|
@@ -30323,7 +30561,7 @@ function resolveHeadedChromePath() {
|
|
|
30323
30561
|
"MacOS",
|
|
30324
30562
|
"Google Chrome for Testing"
|
|
30325
30563
|
),
|
|
30326
|
-
|
|
30564
|
+
join28(
|
|
30327
30565
|
baseDir,
|
|
30328
30566
|
version,
|
|
30329
30567
|
"chrome-mac-x64",
|
|
@@ -30332,11 +30570,11 @@ function resolveHeadedChromePath() {
|
|
|
30332
30570
|
"MacOS",
|
|
30333
30571
|
"Google Chrome for Testing"
|
|
30334
30572
|
),
|
|
30335
|
-
|
|
30336
|
-
|
|
30573
|
+
join28(baseDir, version, "chrome-linux64", "chrome"),
|
|
30574
|
+
join28(baseDir, version, "chrome-win64", "chrome.exe")
|
|
30337
30575
|
];
|
|
30338
30576
|
for (const binary of candidates) {
|
|
30339
|
-
if (
|
|
30577
|
+
if (existsSync26(binary)) return binary;
|
|
30340
30578
|
}
|
|
30341
30579
|
}
|
|
30342
30580
|
return void 0;
|
|
@@ -30608,8 +30846,8 @@ var init_staticGuard = __esm({
|
|
|
30608
30846
|
});
|
|
30609
30847
|
|
|
30610
30848
|
// ../core/src/compiler/htmlBundler.ts
|
|
30611
|
-
import { readFileSync as readFileSync17, existsSync as
|
|
30612
|
-
import { join as
|
|
30849
|
+
import { readFileSync as readFileSync17, existsSync as existsSync27 } from "fs";
|
|
30850
|
+
import { join as join29, resolve as resolve12, isAbsolute as isAbsolute4, sep as sep2 } from "path";
|
|
30613
30851
|
import { transformSync } from "esbuild";
|
|
30614
30852
|
function parseHTMLContent2(html) {
|
|
30615
30853
|
const trimmed = html.trimStart().toLowerCase();
|
|
@@ -30677,7 +30915,7 @@ function isRelativeUrl(url) {
|
|
|
30677
30915
|
return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute4(url);
|
|
30678
30916
|
}
|
|
30679
30917
|
function safeReadFile(filePath) {
|
|
30680
|
-
if (!
|
|
30918
|
+
if (!existsSync27(filePath)) return null;
|
|
30681
30919
|
try {
|
|
30682
30920
|
return readFileSync17(filePath, "utf-8");
|
|
30683
30921
|
} catch {
|
|
@@ -30685,7 +30923,7 @@ function safeReadFile(filePath) {
|
|
|
30685
30923
|
}
|
|
30686
30924
|
}
|
|
30687
30925
|
function safeReadFileBuffer(filePath) {
|
|
30688
|
-
if (!
|
|
30926
|
+
if (!existsSync27(filePath)) return null;
|
|
30689
30927
|
try {
|
|
30690
30928
|
return readFileSync17(filePath);
|
|
30691
30929
|
} catch {
|
|
@@ -30878,8 +31116,8 @@ function stripJsCommentsParserSafe(source) {
|
|
|
30878
31116
|
}
|
|
30879
31117
|
}
|
|
30880
31118
|
async function bundleToSingleHtml(projectDir, options) {
|
|
30881
|
-
const indexPath =
|
|
30882
|
-
if (!
|
|
31119
|
+
const indexPath = join29(projectDir, "index.html");
|
|
31120
|
+
if (!existsSync27(indexPath)) throw new Error("index.html not found in project directory");
|
|
30883
31121
|
const rawHtml = readFileSync17(indexPath, "utf-8");
|
|
30884
31122
|
const compiled = await compileHtml(rawHtml, projectDir, options?.probeMediaDuration);
|
|
30885
31123
|
const staticGuard = validateHyperframeHtmlContract(compiled);
|
|
@@ -31003,6 +31241,15 @@ async function bundleToSingleHtml(projectDir, options) {
|
|
|
31003
31241
|
el.setAttribute(attr, val);
|
|
31004
31242
|
}
|
|
31005
31243
|
);
|
|
31244
|
+
const styledEls = innerRoot ? innerRoot.querySelectorAll("[style]") : contentDoc.querySelectorAll("[style]");
|
|
31245
|
+
rewriteInlineStyleAssetUrls(
|
|
31246
|
+
styledEls,
|
|
31247
|
+
src,
|
|
31248
|
+
(el) => el.getAttribute("style"),
|
|
31249
|
+
(el, val) => {
|
|
31250
|
+
el.setAttribute("style", val);
|
|
31251
|
+
}
|
|
31252
|
+
);
|
|
31006
31253
|
if (innerRoot) {
|
|
31007
31254
|
const innerCompId = innerRoot.getAttribute("data-composition-id");
|
|
31008
31255
|
const innerW = innerRoot.getAttribute("data-width");
|
|
@@ -31155,7 +31402,7 @@ var init_compiler = __esm({
|
|
|
31155
31402
|
|
|
31156
31403
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
31157
31404
|
import { createHash as createHash3 } from "crypto";
|
|
31158
|
-
import { existsSync as
|
|
31405
|
+
import { existsSync as existsSync28, readFileSync as readFileSync18 } from "fs";
|
|
31159
31406
|
import { dirname as dirname9, resolve as resolve13 } from "path";
|
|
31160
31407
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
31161
31408
|
function resolveHyperframeManifestPath() {
|
|
@@ -31168,7 +31415,7 @@ function resolveHyperframeManifestPath() {
|
|
|
31168
31415
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
31169
31416
|
];
|
|
31170
31417
|
for (const candidate of candidates) {
|
|
31171
|
-
if (
|
|
31418
|
+
if (existsSync28(candidate)) {
|
|
31172
31419
|
return candidate;
|
|
31173
31420
|
}
|
|
31174
31421
|
}
|
|
@@ -31179,7 +31426,7 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
31179
31426
|
}
|
|
31180
31427
|
function resolveVerifiedHyperframeRuntime() {
|
|
31181
31428
|
const manifestPath = resolveHyperframeManifestPath();
|
|
31182
|
-
if (!
|
|
31429
|
+
if (!existsSync28(manifestPath)) {
|
|
31183
31430
|
throw new Error(
|
|
31184
31431
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
31185
31432
|
);
|
|
@@ -31193,7 +31440,7 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
31193
31440
|
);
|
|
31194
31441
|
}
|
|
31195
31442
|
const runtimePath = resolve13(dirname9(manifestPath), runtimeFileName);
|
|
31196
|
-
if (!
|
|
31443
|
+
if (!existsSync28(runtimePath)) {
|
|
31197
31444
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
31198
31445
|
}
|
|
31199
31446
|
const runtimeSource = readFileSync18(runtimePath, "utf8");
|
|
@@ -31235,16 +31482,16 @@ var init_hyperframeRuntimeLoader = __esm({
|
|
|
31235
31482
|
// ../producer/src/services/fileServer.ts
|
|
31236
31483
|
import { Hono as Hono3 } from "hono";
|
|
31237
31484
|
import { serve as serve2 } from "@hono/node-server";
|
|
31238
|
-
import { readFileSync as readFileSync19, existsSync as
|
|
31239
|
-
import { join as
|
|
31485
|
+
import { readFileSync as readFileSync19, existsSync as existsSync29, realpathSync, statSync as statSync10 } from "fs";
|
|
31486
|
+
import { join as join30, extname as extname7, resolve as resolve14, sep as sep3 } from "path";
|
|
31240
31487
|
function isPathInside(child, parent, options = {}) {
|
|
31241
31488
|
const { resolveSymlinks = false, pathModule } = options;
|
|
31242
31489
|
const resolveFn = pathModule?.resolve ?? resolve14;
|
|
31243
31490
|
const separator = pathModule?.sep ?? sep3;
|
|
31244
31491
|
const resolvedChild = resolveFn(child);
|
|
31245
31492
|
const resolvedParent = resolveFn(parent);
|
|
31246
|
-
const normalizedChild = resolveSymlinks &&
|
|
31247
|
-
const normalizedParent = resolveSymlinks &&
|
|
31493
|
+
const normalizedChild = resolveSymlinks && existsSync29(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
31494
|
+
const normalizedParent = resolveSymlinks && existsSync29(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
31248
31495
|
if (normalizedChild === normalizedParent) return true;
|
|
31249
31496
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
31250
31497
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -31333,14 +31580,14 @@ function createFileServer2(options) {
|
|
|
31333
31580
|
const relativePath = requestPath.replace(/^\//, "");
|
|
31334
31581
|
let filePath = null;
|
|
31335
31582
|
if (compiledDir) {
|
|
31336
|
-
const candidate =
|
|
31337
|
-
if (
|
|
31583
|
+
const candidate = join30(compiledDir, relativePath);
|
|
31584
|
+
if (existsSync29(candidate) && isPathInside(candidate, compiledDir) && statSync10(candidate).isFile()) {
|
|
31338
31585
|
filePath = candidate;
|
|
31339
31586
|
}
|
|
31340
31587
|
}
|
|
31341
31588
|
if (!filePath) {
|
|
31342
|
-
const candidate =
|
|
31343
|
-
if (
|
|
31589
|
+
const candidate = join30(projectDir, relativePath);
|
|
31590
|
+
if (existsSync29(candidate) && isPathInside(candidate, projectDir) && statSync10(candidate).isFile()) {
|
|
31344
31591
|
filePath = candidate;
|
|
31345
31592
|
}
|
|
31346
31593
|
}
|
|
@@ -31714,7 +31961,7 @@ var init_ffprobe2 = __esm({
|
|
|
31714
31961
|
});
|
|
31715
31962
|
|
|
31716
31963
|
// ../producer/src/utils/paths.ts
|
|
31717
|
-
import { resolve as resolve15, basename as basename2, join as
|
|
31964
|
+
import { resolve as resolve15, basename as basename2, join as join31, relative as relative2, isAbsolute as isAbsolute5 } from "path";
|
|
31718
31965
|
function isPathInside2(childPath, parentPath) {
|
|
31719
31966
|
const absChild = resolve15(childPath);
|
|
31720
31967
|
const absParent = resolve15(parentPath);
|
|
@@ -31735,7 +31982,7 @@ function toExternalAssetKey(absPath) {
|
|
|
31735
31982
|
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
31736
31983
|
const absoluteProjectDir = resolve15(projectDir);
|
|
31737
31984
|
const projectName = basename2(absoluteProjectDir);
|
|
31738
|
-
const resolvedOutputPath = outputPath ??
|
|
31985
|
+
const resolvedOutputPath = outputPath ?? join31(rendersDir, `${projectName}.mp4`);
|
|
31739
31986
|
const absoluteOutputPath = resolve15(resolvedOutputPath);
|
|
31740
31987
|
return { absoluteProjectDir, absoluteOutputPath };
|
|
31741
31988
|
}
|
|
@@ -31808,9 +32055,9 @@ var init_fontData_generated = __esm({
|
|
|
31808
32055
|
});
|
|
31809
32056
|
|
|
31810
32057
|
// ../producer/src/services/deterministicFonts.ts
|
|
31811
|
-
import { existsSync as
|
|
31812
|
-
import { homedir as
|
|
31813
|
-
import { join as
|
|
32058
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync16, readFileSync as readFileSync20, writeFileSync as writeFileSync11 } from "fs";
|
|
32059
|
+
import { homedir as homedir8 } from "os";
|
|
32060
|
+
import { join as join32 } from "path";
|
|
31814
32061
|
function normalizeFamilyName(family) {
|
|
31815
32062
|
return family.trim().replace(/^['"]|['"]$/g, "").trim().toLowerCase();
|
|
31816
32063
|
}
|
|
@@ -31921,14 +32168,14 @@ function fontSlug(familyName) {
|
|
|
31921
32168
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
31922
32169
|
}
|
|
31923
32170
|
function fontCacheDir(slug) {
|
|
31924
|
-
const dir =
|
|
31925
|
-
if (!
|
|
32171
|
+
const dir = join32(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
32172
|
+
if (!existsSync30(dir)) {
|
|
31926
32173
|
mkdirSync16(dir, { recursive: true });
|
|
31927
32174
|
}
|
|
31928
32175
|
return dir;
|
|
31929
32176
|
}
|
|
31930
32177
|
function cachedWoff2Path(slug, weight, style) {
|
|
31931
|
-
return
|
|
32178
|
+
return join32(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
31932
32179
|
}
|
|
31933
32180
|
async function fetchGoogleFont(familyName) {
|
|
31934
32181
|
const slug = fontSlug(familyName);
|
|
@@ -31954,7 +32201,7 @@ async function fetchGoogleFont(familyName) {
|
|
|
31954
32201
|
const woff2Url = match[3] || "";
|
|
31955
32202
|
if (!woff2Url) continue;
|
|
31956
32203
|
const cachePath2 = cachedWoff2Path(slug, weight, style);
|
|
31957
|
-
if (!
|
|
32204
|
+
if (!existsSync30(cachePath2)) {
|
|
31958
32205
|
try {
|
|
31959
32206
|
const fontRes = await fetch(woff2Url);
|
|
31960
32207
|
if (!fontRes.ok) continue;
|
|
@@ -32140,14 +32387,14 @@ var init_deterministicFonts = __esm({
|
|
|
32140
32387
|
poppins: "poppins",
|
|
32141
32388
|
"segoe ui": "roboto"
|
|
32142
32389
|
};
|
|
32143
|
-
GOOGLE_FONTS_CACHE_DIR =
|
|
32390
|
+
GOOGLE_FONTS_CACHE_DIR = join32(homedir8(), ".cache", "hyperframes", "fonts");
|
|
32144
32391
|
WOFF2_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
32145
32392
|
}
|
|
32146
32393
|
});
|
|
32147
32394
|
|
|
32148
32395
|
// ../producer/src/services/htmlCompiler.ts
|
|
32149
|
-
import { readFileSync as readFileSync21, existsSync as
|
|
32150
|
-
import { join as
|
|
32396
|
+
import { readFileSync as readFileSync21, existsSync as existsSync31, mkdirSync as mkdirSync17 } from "fs";
|
|
32397
|
+
import { join as join33, dirname as dirname10, resolve as resolve16 } from "path";
|
|
32151
32398
|
import postcss from "postcss";
|
|
32152
32399
|
function dedupeElementsById(elements) {
|
|
32153
32400
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -32198,16 +32445,16 @@ function detectRenderModeHints(html) {
|
|
|
32198
32445
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
32199
32446
|
let filePath = src;
|
|
32200
32447
|
if (isHttpUrl(src)) {
|
|
32201
|
-
if (!
|
|
32448
|
+
if (!existsSync31(downloadDir)) mkdirSync17(downloadDir, { recursive: true });
|
|
32202
32449
|
try {
|
|
32203
32450
|
filePath = await downloadToTemp(src, downloadDir);
|
|
32204
32451
|
} catch {
|
|
32205
32452
|
return { duration: 0, resolvedPath: src };
|
|
32206
32453
|
}
|
|
32207
32454
|
} else if (!filePath.startsWith("/")) {
|
|
32208
|
-
filePath =
|
|
32455
|
+
filePath = join33(baseDir, filePath);
|
|
32209
32456
|
}
|
|
32210
|
-
if (!
|
|
32457
|
+
if (!existsSync31(filePath)) {
|
|
32211
32458
|
return { duration: 0, resolvedPath: filePath };
|
|
32212
32459
|
}
|
|
32213
32460
|
const metadata = tagName19 === "video" ? await extractMediaMetadata(filePath) : await extractAudioMetadata(filePath);
|
|
@@ -32276,7 +32523,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
32276
32523
|
if (visited.has(filePath)) {
|
|
32277
32524
|
continue;
|
|
32278
32525
|
}
|
|
32279
|
-
if (!
|
|
32526
|
+
if (!existsSync31(filePath)) {
|
|
32280
32527
|
continue;
|
|
32281
32528
|
}
|
|
32282
32529
|
const rawSubHtml = readFileSync21(filePath, "utf-8");
|
|
@@ -32486,7 +32733,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
32486
32733
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
32487
32734
|
if (!compHtml) {
|
|
32488
32735
|
const filePath = resolve16(projectDir, srcPath);
|
|
32489
|
-
if (
|
|
32736
|
+
if (existsSync31(filePath)) {
|
|
32490
32737
|
compHtml = readFileSync21(filePath, "utf-8");
|
|
32491
32738
|
}
|
|
32492
32739
|
}
|
|
@@ -32714,7 +32961,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
32714
32961
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
32715
32962
|
return null;
|
|
32716
32963
|
}
|
|
32717
|
-
if (!
|
|
32964
|
+
if (!existsSync31(absPath)) return null;
|
|
32718
32965
|
const safeKey = toExternalAssetKey(absPath);
|
|
32719
32966
|
externalAssets.set(safeKey, absPath);
|
|
32720
32967
|
return safeKey;
|
|
@@ -32993,7 +33240,7 @@ var init_logger = __esm({
|
|
|
32993
33240
|
});
|
|
32994
33241
|
|
|
32995
33242
|
// ../producer/src/services/frameDirCache.ts
|
|
32996
|
-
import { readdirSync as
|
|
33243
|
+
import { readdirSync as readdirSync13 } from "fs";
|
|
32997
33244
|
function getMaxFrameIndex(frameDir) {
|
|
32998
33245
|
const cached2 = cache.get(frameDir);
|
|
32999
33246
|
if (cached2 !== void 0) {
|
|
@@ -33003,7 +33250,7 @@ function getMaxFrameIndex(frameDir) {
|
|
|
33003
33250
|
}
|
|
33004
33251
|
let max = 0;
|
|
33005
33252
|
try {
|
|
33006
|
-
for (const name of
|
|
33253
|
+
for (const name of readdirSync13(frameDir)) {
|
|
33007
33254
|
const m2 = FRAME_FILENAME_RE.exec(name);
|
|
33008
33255
|
if (!m2) continue;
|
|
33009
33256
|
const n = Number(m2[1]);
|
|
@@ -33099,17 +33346,17 @@ var init_hdrImageTransferCache = __esm({
|
|
|
33099
33346
|
|
|
33100
33347
|
// ../producer/src/services/renderOrchestrator.ts
|
|
33101
33348
|
import {
|
|
33102
|
-
existsSync as
|
|
33349
|
+
existsSync as existsSync32,
|
|
33103
33350
|
mkdirSync as mkdirSync18,
|
|
33104
33351
|
rmSync as rmSync7,
|
|
33105
33352
|
readFileSync as readFileSync22,
|
|
33106
|
-
readdirSync as
|
|
33107
|
-
statSync as
|
|
33353
|
+
readdirSync as readdirSync14,
|
|
33354
|
+
statSync as statSync11,
|
|
33108
33355
|
writeFileSync as writeFileSync12,
|
|
33109
33356
|
copyFileSync as copyFileSync2,
|
|
33110
33357
|
appendFileSync
|
|
33111
33358
|
} from "fs";
|
|
33112
|
-
import { join as
|
|
33359
|
+
import { join as join34, dirname as dirname11, resolve as resolve17 } from "path";
|
|
33113
33360
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
33114
33361
|
import { freemem as freemem2 } from "os";
|
|
33115
33362
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -33130,14 +33377,14 @@ function sampleDirectoryBytes(dir) {
|
|
|
33130
33377
|
if (!current) continue;
|
|
33131
33378
|
let entries2 = [];
|
|
33132
33379
|
try {
|
|
33133
|
-
entries2 =
|
|
33380
|
+
entries2 = readdirSync14(current);
|
|
33134
33381
|
} catch {
|
|
33135
33382
|
continue;
|
|
33136
33383
|
}
|
|
33137
33384
|
for (const name of entries2) {
|
|
33138
|
-
const full =
|
|
33385
|
+
const full = join34(current, name);
|
|
33139
33386
|
try {
|
|
33140
|
-
const st2 =
|
|
33387
|
+
const st2 = statSync11(full);
|
|
33141
33388
|
if (st2.isDirectory()) {
|
|
33142
33389
|
stack.push(full);
|
|
33143
33390
|
} else if (st2.isFile()) {
|
|
@@ -33210,16 +33457,16 @@ function installDebugLogger(logPath, log2 = defaultLogger) {
|
|
|
33210
33457
|
};
|
|
33211
33458
|
}
|
|
33212
33459
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
33213
|
-
const compileDir =
|
|
33460
|
+
const compileDir = join34(workDir, "compiled");
|
|
33214
33461
|
mkdirSync18(compileDir, { recursive: true });
|
|
33215
|
-
writeFileSync12(
|
|
33462
|
+
writeFileSync12(join34(compileDir, "index.html"), compiled.html, "utf-8");
|
|
33216
33463
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
33217
|
-
const outPath =
|
|
33464
|
+
const outPath = join34(compileDir, srcPath);
|
|
33218
33465
|
mkdirSync18(dirname11(outPath), { recursive: true });
|
|
33219
33466
|
writeFileSync12(outPath, html, "utf-8");
|
|
33220
33467
|
}
|
|
33221
33468
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
33222
|
-
const outPath = resolve17(
|
|
33469
|
+
const outPath = resolve17(join34(compileDir, relativePath));
|
|
33223
33470
|
if (!isPathInside2(outPath, compileDir)) {
|
|
33224
33471
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
33225
33472
|
continue;
|
|
@@ -33249,7 +33496,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
33249
33496
|
subCompositions: Array.from(compiled.subCompositions.keys()),
|
|
33250
33497
|
renderModeHints: compiled.renderModeHints
|
|
33251
33498
|
};
|
|
33252
|
-
writeFileSync12(
|
|
33499
|
+
writeFileSync12(join34(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
33253
33500
|
}
|
|
33254
33501
|
}
|
|
33255
33502
|
function applyRenderModeHints(cfg, compiled, log2 = defaultLogger) {
|
|
@@ -33270,8 +33517,8 @@ function blitHdrVideoLayer(canvas, el, time, fps, hdrFrameDirs, hdrStartTimes, w
|
|
|
33270
33517
|
if (videoFrameIndex < 1) return;
|
|
33271
33518
|
const maxIndex = getMaxFrameIndex(frameDir);
|
|
33272
33519
|
const effectiveIndex = maxIndex > 0 ? Math.min(videoFrameIndex, maxIndex) : videoFrameIndex;
|
|
33273
|
-
const framePath =
|
|
33274
|
-
if (!
|
|
33520
|
+
const framePath = join34(frameDir, `frame_${String(effectiveIndex).padStart(4, "0")}.png`);
|
|
33521
|
+
if (!existsSync32(framePath)) {
|
|
33275
33522
|
return;
|
|
33276
33523
|
}
|
|
33277
33524
|
try {
|
|
@@ -33454,7 +33701,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
33454
33701
|
const startTime = hdrVideoStartTimes.get(layer.element.id) ?? 0;
|
|
33455
33702
|
const localTime = time - startTime;
|
|
33456
33703
|
const frameNum = Math.floor(localTime * fps) + 1;
|
|
33457
|
-
const expectedFrame = frameDir ?
|
|
33704
|
+
const expectedFrame = frameDir ? join34(frameDir, `frame_${String(frameNum).padStart(4, "0")}.png`) : null;
|
|
33458
33705
|
log2.info("[diag] hdr layer blit", {
|
|
33459
33706
|
frame: debugFrameIndex,
|
|
33460
33707
|
layerIdx,
|
|
@@ -33466,7 +33713,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
33466
33713
|
localTime: localTime.toFixed(3),
|
|
33467
33714
|
hdrFrameNum: frameNum,
|
|
33468
33715
|
expectedFrame,
|
|
33469
|
-
expectedFrameExists: expectedFrame ?
|
|
33716
|
+
expectedFrameExists: expectedFrame ? existsSync32(expectedFrame) : false
|
|
33470
33717
|
});
|
|
33471
33718
|
}
|
|
33472
33719
|
}
|
|
@@ -33491,7 +33738,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
33491
33738
|
if (shouldLog && debugDumpDir) {
|
|
33492
33739
|
const after2 = countNonZeroRgb48(canvas);
|
|
33493
33740
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
33494
|
-
const dumpPath =
|
|
33741
|
+
const dumpPath = join34(debugDumpDir, dumpName);
|
|
33495
33742
|
writeFileSync12(dumpPath, domPng);
|
|
33496
33743
|
log2.info("[diag] dom layer blit", {
|
|
33497
33744
|
frame: debugFrameIndex,
|
|
@@ -33565,8 +33812,8 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
33565
33812
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
33566
33813
|
const moduleDir = dirname11(fileURLToPath3(import.meta.url));
|
|
33567
33814
|
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve17(process.env.PRODUCER_RENDERS_DIR, "..") : resolve17(moduleDir, "../..");
|
|
33568
|
-
const debugDir =
|
|
33569
|
-
const workDir = job.config.debug ?
|
|
33815
|
+
const debugDir = join34(producerRoot, ".debug");
|
|
33816
|
+
const workDir = job.config.debug ? join34(debugDir, job.id) : join34(dirname11(outputPath), `work-${job.id}`);
|
|
33570
33817
|
const pipelineStart = Date.now();
|
|
33571
33818
|
const log2 = job.config.logger ?? defaultLogger;
|
|
33572
33819
|
let fileServer = null;
|
|
@@ -33578,7 +33825,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33578
33825
|
videoExtractionFailures: 0,
|
|
33579
33826
|
imageDecodeFailures: 0
|
|
33580
33827
|
};
|
|
33581
|
-
const perfOutputPath =
|
|
33828
|
+
const perfOutputPath = join34(workDir, "perf-summary.json");
|
|
33582
33829
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
33583
33830
|
const outputFormat = job.config.format ?? "mp4";
|
|
33584
33831
|
const isWebm = outputFormat === "webm";
|
|
@@ -33611,22 +33858,22 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33611
33858
|
};
|
|
33612
33859
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
33613
33860
|
assertNotAborted();
|
|
33614
|
-
if (!
|
|
33861
|
+
if (!existsSync32(workDir)) mkdirSync18(workDir, { recursive: true });
|
|
33615
33862
|
if (job.config.debug) {
|
|
33616
|
-
const logPath =
|
|
33863
|
+
const logPath = join34(workDir, "render.log");
|
|
33617
33864
|
restoreLogger = installDebugLogger(logPath, log2);
|
|
33618
33865
|
}
|
|
33619
33866
|
const entryFile = job.config.entryFile || "index.html";
|
|
33620
|
-
let htmlPath =
|
|
33621
|
-
if (!
|
|
33867
|
+
let htmlPath = join34(projectDir, entryFile);
|
|
33868
|
+
if (!existsSync32(htmlPath)) {
|
|
33622
33869
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
33623
33870
|
}
|
|
33624
33871
|
assertNotAborted();
|
|
33625
33872
|
const rawEntry = readFileSync22(htmlPath, "utf-8");
|
|
33626
33873
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
33627
|
-
const wrapperPath =
|
|
33628
|
-
const projectIndexPath =
|
|
33629
|
-
if (!
|
|
33874
|
+
const wrapperPath = join34(workDir, "standalone-entry.html");
|
|
33875
|
+
const projectIndexPath = join34(projectDir, "index.html");
|
|
33876
|
+
if (!existsSync32(projectIndexPath)) {
|
|
33630
33877
|
throw new Error(
|
|
33631
33878
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
33632
33879
|
);
|
|
@@ -33649,7 +33896,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33649
33896
|
const stage1Start = Date.now();
|
|
33650
33897
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
33651
33898
|
const compileStart = Date.now();
|
|
33652
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
33899
|
+
let compiled = await compileForRender(projectDir, htmlPath, join34(workDir, "downloads"));
|
|
33653
33900
|
assertNotAborted();
|
|
33654
33901
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
33655
33902
|
applyRenderModeHints(cfg, compiled, log2);
|
|
@@ -33681,7 +33928,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33681
33928
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
33682
33929
|
fileServer = await createFileServer2({
|
|
33683
33930
|
projectDir,
|
|
33684
|
-
compiledDir:
|
|
33931
|
+
compiledDir: join34(workDir, "compiled"),
|
|
33685
33932
|
port: 0,
|
|
33686
33933
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
33687
33934
|
});
|
|
@@ -33695,7 +33942,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33695
33942
|
};
|
|
33696
33943
|
probeSession = await createCaptureSession(
|
|
33697
33944
|
fileServer.url,
|
|
33698
|
-
|
|
33945
|
+
join34(workDir, "probe"),
|
|
33699
33946
|
captureOpts,
|
|
33700
33947
|
null,
|
|
33701
33948
|
cfg
|
|
@@ -33727,7 +33974,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33727
33974
|
compiled,
|
|
33728
33975
|
resolutions,
|
|
33729
33976
|
projectDir,
|
|
33730
|
-
|
|
33977
|
+
join34(workDir, "downloads")
|
|
33731
33978
|
);
|
|
33732
33979
|
assertNotAborted();
|
|
33733
33980
|
composition.videos = compiled.videos;
|
|
@@ -33881,7 +34128,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33881
34128
|
const stage2Start = Date.now();
|
|
33882
34129
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
33883
34130
|
let frameLookup = null;
|
|
33884
|
-
const compiledDir =
|
|
34131
|
+
const compiledDir = join34(workDir, "compiled");
|
|
33885
34132
|
let extractionResult = null;
|
|
33886
34133
|
const nativeHdrVideoIds = /* @__PURE__ */ new Set();
|
|
33887
34134
|
const videoTransfers = /* @__PURE__ */ new Map();
|
|
@@ -33890,10 +34137,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33890
34137
|
composition.videos.map(async (v) => {
|
|
33891
34138
|
let videoPath = v.src;
|
|
33892
34139
|
if (!videoPath.startsWith("/")) {
|
|
33893
|
-
const fromCompiled =
|
|
34140
|
+
const fromCompiled = existsSync32(join34(compiledDir, videoPath)) ? join34(compiledDir, videoPath) : join34(projectDir, videoPath);
|
|
33894
34141
|
videoPath = fromCompiled;
|
|
33895
34142
|
}
|
|
33896
|
-
if (!
|
|
34143
|
+
if (!existsSync32(videoPath)) return;
|
|
33897
34144
|
const meta = await extractMediaMetadata(videoPath);
|
|
33898
34145
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
33899
34146
|
nativeHdrVideoIds.add(v.id);
|
|
@@ -33911,10 +34158,10 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33911
34158
|
composition.images.map(async (img) => {
|
|
33912
34159
|
let imgPath = img.src;
|
|
33913
34160
|
if (!imgPath.startsWith("/")) {
|
|
33914
|
-
const fromCompiled =
|
|
34161
|
+
const fromCompiled = existsSync32(join34(compiledDir, imgPath)) ? join34(compiledDir, imgPath) : join34(projectDir, imgPath);
|
|
33915
34162
|
imgPath = fromCompiled;
|
|
33916
34163
|
}
|
|
33917
|
-
if (!
|
|
34164
|
+
if (!existsSync32(imgPath)) return null;
|
|
33918
34165
|
const meta = await extractMediaMetadata(imgPath);
|
|
33919
34166
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
33920
34167
|
nativeHdrImageIds.add(img.id);
|
|
@@ -33930,7 +34177,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33930
34177
|
extractionResult = await extractAllVideoFrames(
|
|
33931
34178
|
composition.videos,
|
|
33932
34179
|
projectDir,
|
|
33933
|
-
{ fps: job.config.fps, outputDir:
|
|
34180
|
+
{ fps: job.config.fps, outputDir: join34(workDir, "video-frames") },
|
|
33934
34181
|
abortSignal,
|
|
33935
34182
|
{ extractCacheDir: cfg.extractCacheDir },
|
|
33936
34183
|
compiledDir
|
|
@@ -33988,13 +34235,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
33988
34235
|
}
|
|
33989
34236
|
const stage3Start = Date.now();
|
|
33990
34237
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
33991
|
-
const audioOutputPath =
|
|
34238
|
+
const audioOutputPath = join34(workDir, "audio.aac");
|
|
33992
34239
|
let hasAudio = false;
|
|
33993
34240
|
if (composition.audios.length > 0) {
|
|
33994
34241
|
const audioResult = await processCompositionAudio(
|
|
33995
34242
|
composition.audios,
|
|
33996
34243
|
projectDir,
|
|
33997
|
-
|
|
34244
|
+
join34(workDir, "audio-work"),
|
|
33998
34245
|
audioOutputPath,
|
|
33999
34246
|
job.duration,
|
|
34000
34247
|
abortSignal,
|
|
@@ -34012,14 +34259,14 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34012
34259
|
if (!fileServer) {
|
|
34013
34260
|
fileServer = await createFileServer2({
|
|
34014
34261
|
projectDir,
|
|
34015
|
-
compiledDir:
|
|
34262
|
+
compiledDir: join34(workDir, "compiled"),
|
|
34016
34263
|
port: 0,
|
|
34017
34264
|
preHeadScripts: [VIRTUAL_TIME_SHIM]
|
|
34018
34265
|
});
|
|
34019
34266
|
assertNotAborted();
|
|
34020
34267
|
}
|
|
34021
|
-
const framesDir =
|
|
34022
|
-
if (!
|
|
34268
|
+
const framesDir = join34(workDir, "captured-frames");
|
|
34269
|
+
if (!existsSync32(framesDir)) mkdirSync18(framesDir, { recursive: true });
|
|
34023
34270
|
const captureOptions = {
|
|
34024
34271
|
width,
|
|
34025
34272
|
height,
|
|
@@ -34034,7 +34281,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34034
34281
|
const workerCount = calculateOptimalWorkers(totalFrames, job.config.workers, cfg);
|
|
34035
34282
|
const FORMAT_EXT2 = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
34036
34283
|
const videoExt = FORMAT_EXT2[outputFormat] ?? ".mp4";
|
|
34037
|
-
const videoOnlyPath =
|
|
34284
|
+
const videoOnlyPath = join34(workDir, `video-only${videoExt}`);
|
|
34038
34285
|
const nativeHdrIds = /* @__PURE__ */ new Set([...nativeHdrVideoIds, ...nativeHdrImageIds]);
|
|
34039
34286
|
const hasHdrContent = effectiveHdr && nativeHdrIds.size > 0;
|
|
34040
34287
|
const encoderHdr = hasHdrContent ? effectiveHdr : void 0;
|
|
@@ -34056,8 +34303,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34056
34303
|
if (!hdrVideoIds.includes(v.id)) continue;
|
|
34057
34304
|
let srcPath = v.src;
|
|
34058
34305
|
if (!srcPath.startsWith("/")) {
|
|
34059
|
-
const fromCompiled =
|
|
34060
|
-
srcPath =
|
|
34306
|
+
const fromCompiled = join34(compiledDir, srcPath);
|
|
34307
|
+
srcPath = existsSync32(fromCompiled) ? fromCompiled : join34(projectDir, srcPath);
|
|
34061
34308
|
}
|
|
34062
34309
|
hdrVideoSrcPaths.set(v.id, srcPath);
|
|
34063
34310
|
}
|
|
@@ -34187,7 +34434,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34187
34434
|
for (const [videoId, srcPath] of hdrVideoSrcPaths) {
|
|
34188
34435
|
const video = composition.videos.find((v) => v.id === videoId);
|
|
34189
34436
|
if (!video) continue;
|
|
34190
|
-
const frameDir =
|
|
34437
|
+
const frameDir = join34(framesDir, `hdr_${videoId}`);
|
|
34191
34438
|
mkdirSync18(frameDir, { recursive: true });
|
|
34192
34439
|
const duration = video.end - video.start;
|
|
34193
34440
|
const dims = hdrExtractionDims.get(videoId) ?? { width, height };
|
|
@@ -34207,7 +34454,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34207
34454
|
"-c:v",
|
|
34208
34455
|
"png",
|
|
34209
34456
|
"-y",
|
|
34210
|
-
|
|
34457
|
+
join34(frameDir, "frame_%04d.png")
|
|
34211
34458
|
];
|
|
34212
34459
|
const result = await runFfmpeg(ffmpegArgs, { signal: abortSignal });
|
|
34213
34460
|
if (!result.success) {
|
|
@@ -34275,8 +34522,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34275
34522
|
}
|
|
34276
34523
|
}
|
|
34277
34524
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
34278
|
-
const debugDumpDir = debugDumpEnabled ?
|
|
34279
|
-
if (debugDumpDir && !
|
|
34525
|
+
const debugDumpDir = debugDumpEnabled ? join34(framesDir, "debug-composite") : null;
|
|
34526
|
+
if (debugDumpDir && !existsSync32(debugDumpDir)) {
|
|
34280
34527
|
mkdirSync18(debugDumpDir, { recursive: true });
|
|
34281
34528
|
}
|
|
34282
34529
|
if (!effectiveHdr) {
|
|
@@ -34423,7 +34670,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34423
34670
|
i2
|
|
34424
34671
|
);
|
|
34425
34672
|
if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
|
|
34426
|
-
const previewPath =
|
|
34673
|
+
const previewPath = join34(
|
|
34427
34674
|
debugDumpDir,
|
|
34428
34675
|
`frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`
|
|
34429
34676
|
);
|
|
@@ -34770,7 +35017,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34770
35017
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
34771
35018
|
const totalElapsed = Date.now() - pipelineStart;
|
|
34772
35019
|
sampleMemory();
|
|
34773
|
-
const tmpPeakBytes =
|
|
35020
|
+
const tmpPeakBytes = existsSync32(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
34774
35021
|
const perfSummary = {
|
|
34775
35022
|
renderId: job.id,
|
|
34776
35023
|
totalElapsedMs: totalElapsed,
|
|
@@ -34804,8 +35051,8 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34804
35051
|
}
|
|
34805
35052
|
}
|
|
34806
35053
|
if (job.config.debug) {
|
|
34807
|
-
if (
|
|
34808
|
-
const debugOutput =
|
|
35054
|
+
if (existsSync32(outputPath)) {
|
|
35055
|
+
const debugOutput = join34(workDir, `output${videoExt}`);
|
|
34809
35056
|
copyFileSync2(outputPath, debugOutput);
|
|
34810
35057
|
}
|
|
34811
35058
|
} else if (process.env.KEEP_TEMP === "1") {
|
|
@@ -34891,7 +35138,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
34891
35138
|
await safeCleanup(
|
|
34892
35139
|
"remove workDir (error)",
|
|
34893
35140
|
() => {
|
|
34894
|
-
if (
|
|
35141
|
+
if (existsSync32(workDir)) rmSync7(workDir, { recursive: true, force: true });
|
|
34895
35142
|
},
|
|
34896
35143
|
log2
|
|
34897
35144
|
);
|
|
@@ -34951,8 +35198,8 @@ var init_config3 = __esm({
|
|
|
34951
35198
|
});
|
|
34952
35199
|
|
|
34953
35200
|
// ../producer/src/services/hyperframeLint.ts
|
|
34954
|
-
import { existsSync as
|
|
34955
|
-
import { resolve as resolve18, join as
|
|
35201
|
+
import { existsSync as existsSync33, readFileSync as readFileSync23, statSync as statSync12 } from "fs";
|
|
35202
|
+
import { resolve as resolve18, join as join35 } from "path";
|
|
34956
35203
|
function isStringRecord(value) {
|
|
34957
35204
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
34958
35205
|
return false;
|
|
@@ -34980,7 +35227,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
34980
35227
|
}
|
|
34981
35228
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
34982
35229
|
const absProjectDir = resolve18(projectDir);
|
|
34983
|
-
if (!
|
|
35230
|
+
if (!existsSync33(absProjectDir) || !statSync12(absProjectDir).isDirectory()) {
|
|
34984
35231
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
34985
35232
|
}
|
|
34986
35233
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -34991,7 +35238,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
34991
35238
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
34992
35239
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
34993
35240
|
}
|
|
34994
|
-
if (
|
|
35241
|
+
if (existsSync33(absoluteEntryPath) && statSync12(absoluteEntryPath).isFile()) {
|
|
34995
35242
|
return {
|
|
34996
35243
|
entryFile,
|
|
34997
35244
|
html: readFileSync23(absoluteEntryPath, "utf-8"),
|
|
@@ -35000,7 +35247,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
35000
35247
|
}
|
|
35001
35248
|
}
|
|
35002
35249
|
return {
|
|
35003
|
-
error: `No HTML entry file found in project directory: ${
|
|
35250
|
+
error: `No HTML entry file found in project directory: ${join35(absProjectDir, preferredEntryFile || "index.html")}`
|
|
35004
35251
|
};
|
|
35005
35252
|
}
|
|
35006
35253
|
function prepareHyperframeLintBody(body) {
|
|
@@ -35088,15 +35335,15 @@ var init_semaphore = __esm({
|
|
|
35088
35335
|
|
|
35089
35336
|
// ../producer/src/server.ts
|
|
35090
35337
|
import {
|
|
35091
|
-
existsSync as
|
|
35338
|
+
existsSync as existsSync34,
|
|
35092
35339
|
mkdirSync as mkdirSync19,
|
|
35093
|
-
statSync as
|
|
35340
|
+
statSync as statSync13,
|
|
35094
35341
|
mkdtempSync as mkdtempSync2,
|
|
35095
35342
|
writeFileSync as writeFileSync13,
|
|
35096
35343
|
rmSync as rmSync8,
|
|
35097
35344
|
createReadStream
|
|
35098
35345
|
} from "fs";
|
|
35099
|
-
import { resolve as resolve19, dirname as dirname12, join as
|
|
35346
|
+
import { resolve as resolve19, dirname as dirname12, join as join36 } from "path";
|
|
35100
35347
|
import { tmpdir as tmpdir3 } from "os";
|
|
35101
35348
|
import { parseArgs as parseArgs2 } from "util";
|
|
35102
35349
|
import crypto2 from "crypto";
|
|
@@ -35119,11 +35366,11 @@ async function prepareRenderBody(body) {
|
|
|
35119
35366
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
35120
35367
|
if (projectDir) {
|
|
35121
35368
|
const absProjectDir = resolve19(projectDir);
|
|
35122
|
-
if (!
|
|
35369
|
+
if (!existsSync34(absProjectDir) || !statSync13(absProjectDir).isDirectory()) {
|
|
35123
35370
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
35124
35371
|
}
|
|
35125
35372
|
const entry = options.entryFile || "index.html";
|
|
35126
|
-
if (!
|
|
35373
|
+
if (!existsSync34(resolve19(absProjectDir, entry))) {
|
|
35127
35374
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
35128
35375
|
}
|
|
35129
35376
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -35148,8 +35395,8 @@ async function prepareRenderBody(body) {
|
|
|
35148
35395
|
}
|
|
35149
35396
|
}
|
|
35150
35397
|
const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir3();
|
|
35151
|
-
const tempProjectDir = mkdtempSync2(
|
|
35152
|
-
writeFileSync13(
|
|
35398
|
+
const tempProjectDir = mkdtempSync2(join36(tempRoot, "producer-project-"));
|
|
35399
|
+
writeFileSync13(join36(tempProjectDir, "index.html"), htmlContent, "utf-8");
|
|
35153
35400
|
return {
|
|
35154
35401
|
prepared: {
|
|
35155
35402
|
input: {
|
|
@@ -35272,7 +35519,7 @@ function createRenderHandlers(options = {}) {
|
|
|
35272
35519
|
log2
|
|
35273
35520
|
);
|
|
35274
35521
|
const outputDir = dirname12(absoluteOutputPath);
|
|
35275
|
-
if (!
|
|
35522
|
+
if (!existsSync34(outputDir)) mkdirSync19(outputDir, { recursive: true });
|
|
35276
35523
|
const release2 = await renderSemaphore.acquire();
|
|
35277
35524
|
log2.info("render started", {
|
|
35278
35525
|
requestId,
|
|
@@ -35299,7 +35546,7 @@ function createRenderHandlers(options = {}) {
|
|
|
35299
35546
|
log2.info(`render progress ${pct}%`, { requestId, stage: j2.currentStage, message });
|
|
35300
35547
|
}
|
|
35301
35548
|
});
|
|
35302
|
-
const fileSize =
|
|
35549
|
+
const fileSize = existsSync34(absoluteOutputPath) ? statSync13(absoluteOutputPath).size : 0;
|
|
35303
35550
|
const durationMs = Date.now() - t0;
|
|
35304
35551
|
const outputToken = store.register(absoluteOutputPath);
|
|
35305
35552
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -35383,7 +35630,7 @@ function createRenderHandlers(options = {}) {
|
|
|
35383
35630
|
log2
|
|
35384
35631
|
);
|
|
35385
35632
|
const outputDir = dirname12(absoluteOutputPath);
|
|
35386
|
-
if (!
|
|
35633
|
+
if (!existsSync34(outputDir)) mkdirSync19(outputDir, { recursive: true });
|
|
35387
35634
|
log2.info("render-stream started", { requestId, projectDir: input.projectDir });
|
|
35388
35635
|
const job = createRenderJob({
|
|
35389
35636
|
fps: input.fps,
|
|
@@ -35428,7 +35675,7 @@ function createRenderHandlers(options = {}) {
|
|
|
35428
35675
|
},
|
|
35429
35676
|
abortController.signal
|
|
35430
35677
|
);
|
|
35431
|
-
const fileSize =
|
|
35678
|
+
const fileSize = existsSync34(absoluteOutputPath) ? statSync13(absoluteOutputPath).size : 0;
|
|
35432
35679
|
const outputToken = store.register(absoluteOutputPath);
|
|
35433
35680
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
35434
35681
|
log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -35487,11 +35734,11 @@ function createRenderHandlers(options = {}) {
|
|
|
35487
35734
|
if (!artifact) {
|
|
35488
35735
|
return c2.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
35489
35736
|
}
|
|
35490
|
-
if (!
|
|
35737
|
+
if (!existsSync34(artifact.path)) {
|
|
35491
35738
|
store.delete(token);
|
|
35492
35739
|
return c2.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
35493
35740
|
}
|
|
35494
|
-
const stats =
|
|
35741
|
+
const stats = statSync13(artifact.path);
|
|
35495
35742
|
return new Response(createReadStream(artifact.path), {
|
|
35496
35743
|
headers: {
|
|
35497
35744
|
"content-type": "video/mp4",
|
|
@@ -35625,20 +35872,20 @@ __export(studioServer_exports, {
|
|
|
35625
35872
|
});
|
|
35626
35873
|
import { Hono as Hono5 } from "hono";
|
|
35627
35874
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
35628
|
-
import { existsSync as
|
|
35629
|
-
import { resolve as resolve20, join as
|
|
35875
|
+
import { existsSync as existsSync35, readFileSync as readFileSync24, writeFileSync as writeFileSync14, statSync as statSync14 } from "fs";
|
|
35876
|
+
import { resolve as resolve20, join as join37, basename as basename3 } from "path";
|
|
35630
35877
|
function resolveDistDir() {
|
|
35631
35878
|
return resolveStudioBundle().dir;
|
|
35632
35879
|
}
|
|
35633
35880
|
function resolveStudioBundle() {
|
|
35634
35881
|
const builtPath = resolve20(__dirname, "studio");
|
|
35635
35882
|
const builtIndex = resolve20(builtPath, "index.html");
|
|
35636
|
-
if (
|
|
35883
|
+
if (existsSync35(builtIndex)) {
|
|
35637
35884
|
return { dir: builtPath, indexPath: builtIndex, available: true, checkedPaths: [builtIndex] };
|
|
35638
35885
|
}
|
|
35639
35886
|
const devPath = resolve20(__dirname, "..", "..", "..", "studio", "dist");
|
|
35640
35887
|
const devIndex = resolve20(devPath, "index.html");
|
|
35641
|
-
if (
|
|
35888
|
+
if (existsSync35(devIndex)) {
|
|
35642
35889
|
return {
|
|
35643
35890
|
dir: devPath,
|
|
35644
35891
|
indexPath: devIndex,
|
|
@@ -35655,9 +35902,9 @@ function resolveStudioBundle() {
|
|
|
35655
35902
|
}
|
|
35656
35903
|
function resolveRuntimePath() {
|
|
35657
35904
|
const builtPath = resolve20(__dirname, "hyperframe-runtime.js");
|
|
35658
|
-
if (
|
|
35905
|
+
if (existsSync35(builtPath)) return builtPath;
|
|
35659
35906
|
const iifePath = resolve20(__dirname, "hyperframe.runtime.iife.js");
|
|
35660
|
-
if (
|
|
35907
|
+
if (existsSync35(iifePath)) return iifePath;
|
|
35661
35908
|
const devPath = resolve20(
|
|
35662
35909
|
__dirname,
|
|
35663
35910
|
"..",
|
|
@@ -35667,7 +35914,7 @@ function resolveRuntimePath() {
|
|
|
35667
35914
|
"dist",
|
|
35668
35915
|
"hyperframe.runtime.iife.js"
|
|
35669
35916
|
);
|
|
35670
|
-
if (
|
|
35917
|
+
if (existsSync35(devPath)) return devPath;
|
|
35671
35918
|
return builtPath;
|
|
35672
35919
|
}
|
|
35673
35920
|
async function getThumbnailBrowser() {
|
|
@@ -35729,7 +35976,7 @@ function createStudioServer(options) {
|
|
|
35729
35976
|
return lintHyperframeHtml2(html, opts);
|
|
35730
35977
|
},
|
|
35731
35978
|
runtimeUrl: "/api/runtime.js",
|
|
35732
|
-
rendersDir: () =>
|
|
35979
|
+
rendersDir: () => join37(projectDir, "renders"),
|
|
35733
35980
|
startRender(opts) {
|
|
35734
35981
|
const state = {
|
|
35735
35982
|
id: opts.jobId,
|
|
@@ -35844,7 +36091,7 @@ function createStudioServer(options) {
|
|
|
35844
36091
|
});
|
|
35845
36092
|
app.get("/api/runtime.js", (c2) => {
|
|
35846
36093
|
const serve4 = async () => {
|
|
35847
|
-
const runtimeSource = await loadRuntimeSource() ?? (
|
|
36094
|
+
const runtimeSource = await loadRuntimeSource() ?? (existsSync35(runtimePath) ? readFileSync24(runtimePath, "utf-8") : null);
|
|
35848
36095
|
if (!runtimeSource) return c2.text("runtime not available", 404);
|
|
35849
36096
|
return c2.body(runtimeSource, 200, {
|
|
35850
36097
|
"Content-Type": "text/javascript",
|
|
@@ -35880,7 +36127,7 @@ function createStudioServer(options) {
|
|
|
35880
36127
|
});
|
|
35881
36128
|
app.get("/assets/*", (c2) => {
|
|
35882
36129
|
const filePath = resolve20(studioDir, c2.req.path.slice(1));
|
|
35883
|
-
if (!
|
|
36130
|
+
if (!existsSync35(filePath) || !statSync14(filePath).isFile()) return c2.text("not found", 404);
|
|
35884
36131
|
const content = readFileSync24(filePath);
|
|
35885
36132
|
return new Response(content, {
|
|
35886
36133
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
@@ -35888,7 +36135,7 @@ function createStudioServer(options) {
|
|
|
35888
36135
|
});
|
|
35889
36136
|
app.get("/icons/*", (c2) => {
|
|
35890
36137
|
const filePath = resolve20(studioDir, c2.req.path.slice(1));
|
|
35891
|
-
if (!
|
|
36138
|
+
if (!existsSync35(filePath) || !statSync14(filePath).isFile()) return c2.text("not found", 404);
|
|
35892
36139
|
const content = readFileSync24(filePath);
|
|
35893
36140
|
return new Response(content, {
|
|
35894
36141
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
@@ -35896,7 +36143,7 @@ function createStudioServer(options) {
|
|
|
35896
36143
|
});
|
|
35897
36144
|
app.get("*", (c2) => {
|
|
35898
36145
|
const indexPath = resolve20(studioDir, "index.html");
|
|
35899
|
-
if (!
|
|
36146
|
+
if (!existsSync35(indexPath)) {
|
|
35900
36147
|
return c2.html(
|
|
35901
36148
|
`<!doctype html>
|
|
35902
36149
|
<html>
|
|
@@ -35976,20 +36223,20 @@ __export(preview_exports, {
|
|
|
35976
36223
|
examples: () => examples
|
|
35977
36224
|
});
|
|
35978
36225
|
import { spawn as spawn8 } from "child_process";
|
|
35979
|
-
import { existsSync as
|
|
35980
|
-
import { resolve as resolve21, dirname as dirname13, basename as basename4, join as
|
|
36226
|
+
import { existsSync as existsSync36, lstatSync, symlinkSync, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync20 } from "fs";
|
|
36227
|
+
import { resolve as resolve21, dirname as dirname13, basename as basename4, join as join38 } from "path";
|
|
35981
36228
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
35982
36229
|
import { createRequire } from "module";
|
|
35983
36230
|
async function runDevMode(dir, projectName) {
|
|
35984
36231
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
35985
36232
|
const repoRoot = resolve21(dirname13(thisFile), "..", "..", "..", "..");
|
|
35986
|
-
const projectsDir =
|
|
36233
|
+
const projectsDir = join38(repoRoot, "packages", "studio", "data", "projects");
|
|
35987
36234
|
const pName = projectName ?? basename4(dir);
|
|
35988
|
-
const symlinkPath =
|
|
36235
|
+
const symlinkPath = join38(projectsDir, pName);
|
|
35989
36236
|
mkdirSync20(projectsDir, { recursive: true });
|
|
35990
36237
|
let createdSymlink = false;
|
|
35991
36238
|
if (dir !== symlinkPath) {
|
|
35992
|
-
if (
|
|
36239
|
+
if (existsSync36(symlinkPath)) {
|
|
35993
36240
|
try {
|
|
35994
36241
|
const stat3 = lstatSync(symlinkPath);
|
|
35995
36242
|
if (stat3.isSymbolicLink()) {
|
|
@@ -36001,7 +36248,7 @@ async function runDevMode(dir, projectName) {
|
|
|
36001
36248
|
} catch {
|
|
36002
36249
|
}
|
|
36003
36250
|
}
|
|
36004
|
-
if (!
|
|
36251
|
+
if (!existsSync36(symlinkPath)) {
|
|
36005
36252
|
symlinkSync(dir, symlinkPath, "dir");
|
|
36006
36253
|
createdSymlink = true;
|
|
36007
36254
|
}
|
|
@@ -36009,7 +36256,7 @@ async function runDevMode(dir, projectName) {
|
|
|
36009
36256
|
Wt2(c.bold("hyperframes preview"));
|
|
36010
36257
|
const s2 = be();
|
|
36011
36258
|
s2.start("Starting studio...");
|
|
36012
|
-
const studioPkgDir =
|
|
36259
|
+
const studioPkgDir = join38(repoRoot, "packages", "studio");
|
|
36013
36260
|
const child = spawn8("pnpm", ["exec", "vite"], {
|
|
36014
36261
|
cwd: studioPkgDir,
|
|
36015
36262
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -36043,7 +36290,7 @@ async function runDevMode(dir, projectName) {
|
|
|
36043
36290
|
if (createdSymlink) {
|
|
36044
36291
|
process.on("exit", () => {
|
|
36045
36292
|
try {
|
|
36046
|
-
if (
|
|
36293
|
+
if (existsSync36(symlinkPath)) unlinkSync5(symlinkPath);
|
|
36047
36294
|
} catch {
|
|
36048
36295
|
}
|
|
36049
36296
|
});
|
|
@@ -36054,7 +36301,7 @@ async function runDevMode(dir, projectName) {
|
|
|
36054
36301
|
}
|
|
36055
36302
|
function hasLocalStudio(dir) {
|
|
36056
36303
|
try {
|
|
36057
|
-
const req = createRequire(
|
|
36304
|
+
const req = createRequire(join38(dir, "package.json"));
|
|
36058
36305
|
req.resolve("@hyperframes/studio/package.json");
|
|
36059
36306
|
return true;
|
|
36060
36307
|
} catch {
|
|
@@ -36062,20 +36309,20 @@ function hasLocalStudio(dir) {
|
|
|
36062
36309
|
}
|
|
36063
36310
|
}
|
|
36064
36311
|
async function runLocalStudioMode(dir, projectName) {
|
|
36065
|
-
const req = createRequire(
|
|
36312
|
+
const req = createRequire(join38(dir, "package.json"));
|
|
36066
36313
|
const studioPkgPath = dirname13(req.resolve("@hyperframes/studio/package.json"));
|
|
36067
36314
|
const pName = projectName ?? basename4(dir);
|
|
36068
|
-
const projectsDir =
|
|
36069
|
-
const symlinkPath =
|
|
36315
|
+
const projectsDir = join38(studioPkgPath, "data", "projects");
|
|
36316
|
+
const symlinkPath = join38(projectsDir, pName);
|
|
36070
36317
|
mkdirSync20(projectsDir, { recursive: true });
|
|
36071
36318
|
let createdSymlink = false;
|
|
36072
36319
|
if (dir !== symlinkPath) {
|
|
36073
|
-
if (
|
|
36320
|
+
if (existsSync36(symlinkPath) && lstatSync(symlinkPath).isSymbolicLink()) {
|
|
36074
36321
|
if (resolve21(readlinkSync(symlinkPath)) !== resolve21(dir)) {
|
|
36075
36322
|
unlinkSync5(symlinkPath);
|
|
36076
36323
|
}
|
|
36077
36324
|
}
|
|
36078
|
-
if (!
|
|
36325
|
+
if (!existsSync36(symlinkPath)) {
|
|
36079
36326
|
symlinkSync(dir, symlinkPath, "dir");
|
|
36080
36327
|
createdSymlink = true;
|
|
36081
36328
|
}
|
|
@@ -36114,7 +36361,7 @@ async function runLocalStudioMode(dir, projectName) {
|
|
|
36114
36361
|
if (createdSymlink) {
|
|
36115
36362
|
process.on("exit", () => {
|
|
36116
36363
|
try {
|
|
36117
|
-
if (
|
|
36364
|
+
if (existsSync36(symlinkPath)) unlinkSync5(symlinkPath);
|
|
36118
36365
|
} catch {
|
|
36119
36366
|
}
|
|
36120
36367
|
});
|
|
@@ -36290,8 +36537,8 @@ var init_preview2 = __esm({
|
|
|
36290
36537
|
const dir = resolve21(rawArg ?? ".");
|
|
36291
36538
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
36292
36539
|
const projectName = isImplicitCwd ? basename4(process.env.PWD ?? dir) : basename4(dir);
|
|
36293
|
-
const indexPath =
|
|
36294
|
-
if (
|
|
36540
|
+
const indexPath = join38(dir, "index.html");
|
|
36541
|
+
if (existsSync36(indexPath)) {
|
|
36295
36542
|
const project = { dir, name: projectName, indexPath };
|
|
36296
36543
|
const lintResult = lintProject(project);
|
|
36297
36544
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
@@ -36320,20 +36567,20 @@ __export(init_exports, {
|
|
|
36320
36567
|
examples: () => examples2
|
|
36321
36568
|
});
|
|
36322
36569
|
import {
|
|
36323
|
-
existsSync as
|
|
36570
|
+
existsSync as existsSync37,
|
|
36324
36571
|
mkdirSync as mkdirSync21,
|
|
36325
36572
|
copyFileSync as copyFileSync3,
|
|
36326
36573
|
cpSync,
|
|
36327
36574
|
writeFileSync as writeFileSync15,
|
|
36328
36575
|
readFileSync as readFileSync25,
|
|
36329
|
-
readdirSync as
|
|
36576
|
+
readdirSync as readdirSync15
|
|
36330
36577
|
} from "fs";
|
|
36331
|
-
import { resolve as resolve22, basename as basename5, join as
|
|
36578
|
+
import { resolve as resolve22, basename as basename5, join as join39, dirname as dirname14 } from "path";
|
|
36332
36579
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
36333
|
-
import { execFileSync as
|
|
36580
|
+
import { execFileSync as execFileSync5, spawn as spawn9 } from "child_process";
|
|
36334
36581
|
function probeVideo(filePath) {
|
|
36335
36582
|
try {
|
|
36336
|
-
const raw =
|
|
36583
|
+
const raw = execFileSync5(
|
|
36337
36584
|
"ffprobe",
|
|
36338
36585
|
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filePath],
|
|
36339
36586
|
{ encoding: "utf-8", timeout: 15e3 }
|
|
@@ -36400,7 +36647,7 @@ function resolveAssetDir(devSegments, builtSegments) {
|
|
|
36400
36647
|
const base = dirname14(fileURLToPath5(import.meta.url));
|
|
36401
36648
|
const devPath = resolve22(base, ...devSegments);
|
|
36402
36649
|
const builtPath = resolve22(base, ...builtSegments);
|
|
36403
|
-
return
|
|
36650
|
+
return existsSync37(devPath) ? devPath : builtPath;
|
|
36404
36651
|
}
|
|
36405
36652
|
function getStaticTemplateDir(templateId) {
|
|
36406
36653
|
return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
|
|
@@ -36409,7 +36656,7 @@ function getSharedTemplateDir() {
|
|
|
36409
36656
|
return resolveAssetDir(["..", "templates", "_shared"], ["templates", "_shared"]);
|
|
36410
36657
|
}
|
|
36411
36658
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
36412
|
-
const htmlFiles =
|
|
36659
|
+
const htmlFiles = readdirSync15(dir, { withFileTypes: true, recursive: true }).filter((e2) => e2.isFile() && e2.name.endsWith(".html")).map((e2) => join39(e2.parentPath ?? e2.path, e2.name));
|
|
36413
36660
|
for (const file of htmlFiles) {
|
|
36414
36661
|
let content = readFileSync25(file, "utf-8");
|
|
36415
36662
|
if (videoFilename) {
|
|
@@ -36516,7 +36763,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
|
|
|
36516
36763
|
async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds) {
|
|
36517
36764
|
mkdirSync21(destDir, { recursive: true });
|
|
36518
36765
|
const templateDir = getStaticTemplateDir(templateId);
|
|
36519
|
-
if (
|
|
36766
|
+
if (existsSync37(templateDir)) {
|
|
36520
36767
|
cpSync(templateDir, destDir, { recursive: true });
|
|
36521
36768
|
} else {
|
|
36522
36769
|
await fetchRemoteTemplate(templateId, destDir);
|
|
@@ -36535,14 +36782,14 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
36535
36782
|
),
|
|
36536
36783
|
"utf-8"
|
|
36537
36784
|
);
|
|
36538
|
-
if (!
|
|
36785
|
+
if (!existsSync37(resolve22(destDir, "hyperframes.json"))) {
|
|
36539
36786
|
const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
|
|
36540
36787
|
writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
|
|
36541
36788
|
}
|
|
36542
36789
|
const sharedDir = getSharedTemplateDir();
|
|
36543
|
-
if (
|
|
36544
|
-
for (const entry of
|
|
36545
|
-
const src =
|
|
36790
|
+
if (existsSync37(sharedDir)) {
|
|
36791
|
+
for (const entry of readdirSync15(sharedDir, { withFileTypes: true })) {
|
|
36792
|
+
const src = join39(sharedDir, entry.name);
|
|
36546
36793
|
const dest = resolve22(destDir, entry.name);
|
|
36547
36794
|
if (entry.isFile() || entry.isSymbolicLink()) {
|
|
36548
36795
|
copyFileSync3(src, dest);
|
|
@@ -36656,7 +36903,7 @@ var init_init = __esm({
|
|
|
36656
36903
|
const templateId2 = exampleFlag ?? "blank";
|
|
36657
36904
|
const name2 = args.name ?? "my-video";
|
|
36658
36905
|
const destDir2 = resolve22(name2);
|
|
36659
|
-
if (
|
|
36906
|
+
if (existsSync37(destDir2) && readdirSync15(destDir2).length > 0) {
|
|
36660
36907
|
console.error(c.error(`Directory already exists and is not empty: ${name2}`));
|
|
36661
36908
|
process.exit(1);
|
|
36662
36909
|
}
|
|
@@ -36670,7 +36917,7 @@ var init_init = __esm({
|
|
|
36670
36917
|
}
|
|
36671
36918
|
if (videoFlag) {
|
|
36672
36919
|
const videoPath = resolve22(videoFlag);
|
|
36673
|
-
if (!
|
|
36920
|
+
if (!existsSync37(videoPath)) {
|
|
36674
36921
|
console.error(c.error(`Video file not found: ${videoFlag}`));
|
|
36675
36922
|
process.exit(1);
|
|
36676
36923
|
}
|
|
@@ -36684,7 +36931,7 @@ var init_init = __esm({
|
|
|
36684
36931
|
}
|
|
36685
36932
|
if (audioFlag) {
|
|
36686
36933
|
const audioPath = resolve22(audioFlag);
|
|
36687
|
-
if (!
|
|
36934
|
+
if (!existsSync37(audioPath)) {
|
|
36688
36935
|
console.error(c.error(`Audio file not found: ${audioFlag}`));
|
|
36689
36936
|
process.exit(1);
|
|
36690
36937
|
}
|
|
@@ -36730,11 +36977,11 @@ var init_init = __esm({
|
|
|
36730
36977
|
}
|
|
36731
36978
|
trackInitTemplate(templateId2);
|
|
36732
36979
|
const transcriptFile2 = resolve22(destDir2, "transcript.json");
|
|
36733
|
-
if (
|
|
36980
|
+
if (existsSync37(transcriptFile2)) {
|
|
36734
36981
|
await patchTranscript(destDir2, transcriptFile2);
|
|
36735
36982
|
}
|
|
36736
36983
|
console.log(c.success(`Created ${c.accent(name2 + "/")}`));
|
|
36737
|
-
for (const f3 of
|
|
36984
|
+
for (const f3 of readdirSync15(destDir2).filter((f4) => !f4.startsWith("."))) {
|
|
36738
36985
|
console.log(` ${c.accent(f3)}`);
|
|
36739
36986
|
}
|
|
36740
36987
|
console.log();
|
|
@@ -36782,7 +37029,7 @@ var init_init = __esm({
|
|
|
36782
37029
|
name = nameResult;
|
|
36783
37030
|
}
|
|
36784
37031
|
const destDir = resolve22(name);
|
|
36785
|
-
if (
|
|
37032
|
+
if (existsSync37(destDir) && readdirSync15(destDir).length > 0) {
|
|
36786
37033
|
const overwrite = await Rt({
|
|
36787
37034
|
message: `Directory ${c.accent(name)} already exists and is not empty. Overwrite?`,
|
|
36788
37035
|
initialValue: false
|
|
@@ -36797,7 +37044,7 @@ var init_init = __esm({
|
|
|
36797
37044
|
let videoDuration;
|
|
36798
37045
|
if (videoFlag) {
|
|
36799
37046
|
const videoPath = resolve22(videoFlag);
|
|
36800
|
-
if (!
|
|
37047
|
+
if (!existsSync37(videoPath)) {
|
|
36801
37048
|
R2.error(`File not found: ${videoFlag}`);
|
|
36802
37049
|
Nt("Setup cancelled.");
|
|
36803
37050
|
process.exit(1);
|
|
@@ -36809,7 +37056,7 @@ var init_init = __esm({
|
|
|
36809
37056
|
videoDuration = result.meta.durationSeconds;
|
|
36810
37057
|
} else if (audioFlag) {
|
|
36811
37058
|
const audioPath = resolve22(audioFlag);
|
|
36812
|
-
if (!
|
|
37059
|
+
if (!existsSync37(audioPath)) {
|
|
36813
37060
|
R2.error(`File not found: ${audioFlag}`);
|
|
36814
37061
|
Nt("Setup cancelled.");
|
|
36815
37062
|
process.exit(1);
|
|
@@ -36902,10 +37149,10 @@ ${c.dim("Use --example blank for offline use.")}`
|
|
|
36902
37149
|
}
|
|
36903
37150
|
trackInitTemplate(templateId);
|
|
36904
37151
|
const transcriptFile = resolve22(destDir, "transcript.json");
|
|
36905
|
-
if (
|
|
37152
|
+
if (existsSync37(transcriptFile)) {
|
|
36906
37153
|
await patchTranscript(destDir, transcriptFile);
|
|
36907
37154
|
}
|
|
36908
|
-
const files =
|
|
37155
|
+
const files = readdirSync15(destDir);
|
|
36909
37156
|
Vt2(files.map((f3) => c.accent(f3)).join("\n"), c.success(`Created ${name}/`));
|
|
36910
37157
|
if (!skipSkills) {
|
|
36911
37158
|
const installSkills = await Rt({
|
|
@@ -36934,9 +37181,9 @@ ${c.dim("Use --example blank for offline use.")}`
|
|
|
36934
37181
|
|
|
36935
37182
|
// src/utils/clipboard.ts
|
|
36936
37183
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
36937
|
-
import { platform as
|
|
37184
|
+
import { platform as platform4 } from "os";
|
|
36938
37185
|
function detectProvider() {
|
|
36939
|
-
const os =
|
|
37186
|
+
const os = platform4();
|
|
36940
37187
|
if (os === "darwin") {
|
|
36941
37188
|
return { cmd: "pbcopy", args: [] };
|
|
36942
37189
|
}
|
|
@@ -36988,7 +37235,7 @@ __export(add_exports, {
|
|
|
36988
37235
|
remapTarget: () => remapTarget,
|
|
36989
37236
|
runAdd: () => runAdd
|
|
36990
37237
|
});
|
|
36991
|
-
import { existsSync as
|
|
37238
|
+
import { existsSync as existsSync38 } from "fs";
|
|
36992
37239
|
import { resolve as resolve23, relative as relative3 } from "path";
|
|
36993
37240
|
function remapTarget(item, originalTarget, paths) {
|
|
36994
37241
|
if (item.type === "hyperframes:block") {
|
|
@@ -37014,8 +37261,8 @@ function buildSnippet(item, relativeTarget) {
|
|
|
37014
37261
|
async function runAdd(opts) {
|
|
37015
37262
|
const projectDir = resolve23(opts.projectDir);
|
|
37016
37263
|
let config = loadProjectConfig(projectDir);
|
|
37017
|
-
const hasConfig =
|
|
37018
|
-
if (!hasConfig &&
|
|
37264
|
+
const hasConfig = existsSync38(projectConfigPath(projectDir));
|
|
37265
|
+
if (!hasConfig && existsSync38(resolve23(projectDir, "index.html"))) {
|
|
37019
37266
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
37020
37267
|
config = DEFAULT_PROJECT_CONFIG;
|
|
37021
37268
|
}
|
|
@@ -37114,10 +37361,10 @@ var init_add = __esm({
|
|
|
37114
37361
|
const projectDir = resolve23(args.dir ?? process.cwd());
|
|
37115
37362
|
const json = args.json === true;
|
|
37116
37363
|
const skipClipboard = args["no-clipboard"] === true;
|
|
37117
|
-
const hasConfigBefore =
|
|
37364
|
+
const hasConfigBefore = existsSync38(projectConfigPath(projectDir));
|
|
37118
37365
|
try {
|
|
37119
37366
|
const result = await runAdd({ name: args.name, projectDir, skipClipboard });
|
|
37120
|
-
const wroteConfig = !hasConfigBefore &&
|
|
37367
|
+
const wroteConfig = !hasConfigBefore && existsSync38(projectConfigPath(projectDir));
|
|
37121
37368
|
if (json) {
|
|
37122
37369
|
console.log(JSON.stringify(result));
|
|
37123
37370
|
return;
|
|
@@ -37327,17 +37574,17 @@ var init_format = __esm({
|
|
|
37327
37574
|
});
|
|
37328
37575
|
|
|
37329
37576
|
// src/utils/project.ts
|
|
37330
|
-
import { existsSync as
|
|
37577
|
+
import { existsSync as existsSync39, statSync as statSync15 } from "fs";
|
|
37331
37578
|
import { resolve as resolve25, basename as basename6 } from "path";
|
|
37332
37579
|
function resolveProject(dirArg) {
|
|
37333
37580
|
const dir = resolve25(dirArg ?? ".");
|
|
37334
37581
|
const name = basename6(dir);
|
|
37335
37582
|
const indexPath = resolve25(dir, "index.html");
|
|
37336
|
-
if (!
|
|
37583
|
+
if (!existsSync39(dir) || !statSync15(dir).isDirectory()) {
|
|
37337
37584
|
errorBox("Not a directory: " + dir);
|
|
37338
37585
|
process.exit(1);
|
|
37339
37586
|
}
|
|
37340
|
-
if (!
|
|
37587
|
+
if (!existsSync39(indexPath)) {
|
|
37341
37588
|
errorBox(
|
|
37342
37589
|
"No composition found in " + dir,
|
|
37343
37590
|
"No index.html file found.",
|
|
@@ -37360,7 +37607,7 @@ __export(play_exports, {
|
|
|
37360
37607
|
default: () => play_default,
|
|
37361
37608
|
examples: () => examples5
|
|
37362
37609
|
});
|
|
37363
|
-
import { existsSync as
|
|
37610
|
+
import { existsSync as existsSync40, readFileSync as readFileSync26 } from "fs";
|
|
37364
37611
|
import { resolve as resolve26, dirname as dirname15 } from "path";
|
|
37365
37612
|
function commandDir() {
|
|
37366
37613
|
return dirname15(new URL(import.meta.url).pathname);
|
|
@@ -37375,7 +37622,7 @@ function resolveRuntimePath2() {
|
|
|
37375
37622
|
resolve26(d, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
|
|
37376
37623
|
];
|
|
37377
37624
|
for (const p of candidates) {
|
|
37378
|
-
if (
|
|
37625
|
+
if (existsSync40(p)) return p;
|
|
37379
37626
|
}
|
|
37380
37627
|
return null;
|
|
37381
37628
|
}
|
|
@@ -37389,7 +37636,7 @@ function resolvePlayerPath() {
|
|
|
37389
37636
|
resolve26(d, "..", "hyperframes-player.global.js")
|
|
37390
37637
|
];
|
|
37391
37638
|
for (const p of candidates) {
|
|
37392
|
-
if (
|
|
37639
|
+
if (existsSync40(p)) return p;
|
|
37393
37640
|
}
|
|
37394
37641
|
return null;
|
|
37395
37642
|
}
|
|
@@ -37491,7 +37738,7 @@ var init_play = __esm({
|
|
|
37491
37738
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
37492
37739
|
const filePath = resolve26(project.dir, reqPath);
|
|
37493
37740
|
if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
|
|
37494
|
-
if (!
|
|
37741
|
+
if (!existsSync40(filePath)) return ctx.text("Not found", 404);
|
|
37495
37742
|
const content = readFileSync26(filePath, "utf-8");
|
|
37496
37743
|
if (filePath.endsWith(".html")) {
|
|
37497
37744
|
const injected = injectRuntime(content);
|
|
@@ -37567,23 +37814,23 @@ var init_play = __esm({
|
|
|
37567
37814
|
});
|
|
37568
37815
|
|
|
37569
37816
|
// src/utils/publishProject.ts
|
|
37570
|
-
import { basename as basename7, join as
|
|
37571
|
-
import { readdirSync as
|
|
37817
|
+
import { basename as basename7, join as join40, relative as relative4 } from "path";
|
|
37818
|
+
import { readdirSync as readdirSync16, readFileSync as readFileSync27, statSync as statSync16 } from "fs";
|
|
37572
37819
|
import AdmZip from "adm-zip";
|
|
37573
37820
|
function shouldIgnoreSegment(segment) {
|
|
37574
37821
|
return segment.startsWith(".") || IGNORED_DIRS.has(segment) || IGNORED_FILES.has(segment);
|
|
37575
37822
|
}
|
|
37576
37823
|
function collectProjectFiles(rootDir, currentDir, paths) {
|
|
37577
|
-
for (const entry of
|
|
37824
|
+
for (const entry of readdirSync16(currentDir, { withFileTypes: true })) {
|
|
37578
37825
|
if (shouldIgnoreSegment(entry.name)) continue;
|
|
37579
|
-
const absolutePath =
|
|
37826
|
+
const absolutePath = join40(currentDir, entry.name);
|
|
37580
37827
|
const relativePath = relative4(rootDir, absolutePath).replaceAll("\\", "/");
|
|
37581
37828
|
if (!relativePath) continue;
|
|
37582
37829
|
if (entry.isDirectory()) {
|
|
37583
37830
|
collectProjectFiles(rootDir, absolutePath, paths);
|
|
37584
37831
|
continue;
|
|
37585
37832
|
}
|
|
37586
|
-
if (!
|
|
37833
|
+
if (!statSync16(absolutePath).isFile()) continue;
|
|
37587
37834
|
paths.push(relativePath);
|
|
37588
37835
|
}
|
|
37589
37836
|
}
|
|
@@ -37595,7 +37842,7 @@ function createPublishArchive(projectDir) {
|
|
|
37595
37842
|
}
|
|
37596
37843
|
const archive = new AdmZip();
|
|
37597
37844
|
for (const filePath of filePaths) {
|
|
37598
|
-
archive.addFile(filePath, readFileSync27(
|
|
37845
|
+
archive.addFile(filePath, readFileSync27(join40(projectDir, filePath)));
|
|
37599
37846
|
}
|
|
37600
37847
|
return {
|
|
37601
37848
|
buffer: archive.toBuffer(),
|
|
@@ -37651,8 +37898,8 @@ __export(publish_exports, {
|
|
|
37651
37898
|
examples: () => examples6
|
|
37652
37899
|
});
|
|
37653
37900
|
import { basename as basename8, resolve as resolve27 } from "path";
|
|
37654
|
-
import { existsSync as
|
|
37655
|
-
import { join as
|
|
37901
|
+
import { existsSync as existsSync41 } from "fs";
|
|
37902
|
+
import { join as join41 } from "path";
|
|
37656
37903
|
var examples6, publish_default;
|
|
37657
37904
|
var init_publish = __esm({
|
|
37658
37905
|
"src/commands/publish.ts"() {
|
|
@@ -37687,8 +37934,8 @@ var init_publish = __esm({
|
|
|
37687
37934
|
const dir = resolve27(rawArg ?? ".");
|
|
37688
37935
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
37689
37936
|
const projectName = isImplicitCwd ? basename8(process.env["PWD"] ?? dir) : basename8(dir);
|
|
37690
|
-
const indexPath =
|
|
37691
|
-
if (
|
|
37937
|
+
const indexPath = join41(dir, "index.html");
|
|
37938
|
+
if (existsSync41(indexPath)) {
|
|
37692
37939
|
const lintResult = lintProject({ dir, name: projectName, indexPath });
|
|
37693
37940
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
37694
37941
|
console.log();
|
|
@@ -37859,10 +38106,10 @@ __export(render_exports, {
|
|
|
37859
38106
|
default: () => render_default,
|
|
37860
38107
|
examples: () => examples7
|
|
37861
38108
|
});
|
|
37862
|
-
import { mkdirSync as mkdirSync22, readFileSync as readFileSync28, statSync as
|
|
38109
|
+
import { mkdirSync as mkdirSync22, readFileSync as readFileSync28, statSync as statSync17, writeFileSync as writeFileSync16, rmSync as rmSync9 } from "fs";
|
|
37863
38110
|
import { cpus as cpus3, freemem as freemem3, tmpdir as tmpdir4 } from "os";
|
|
37864
|
-
import { resolve as resolve28, dirname as dirname16, join as
|
|
37865
|
-
import { execFileSync as
|
|
38111
|
+
import { resolve as resolve28, dirname as dirname16, join as join42, basename as basename9 } from "path";
|
|
38112
|
+
import { execFileSync as execFileSync6, spawn as spawn10 } from "child_process";
|
|
37866
38113
|
function defaultWorkerCount() {
|
|
37867
38114
|
return Math.max(1, Math.min(Math.floor(CPU_CORE_COUNT * 3 / 4), 8));
|
|
37868
38115
|
}
|
|
@@ -37874,7 +38121,7 @@ function resolveDockerfilePath() {
|
|
|
37874
38121
|
const devPath = resolve28(__dirname, "..", "src", "docker", "Dockerfile.render");
|
|
37875
38122
|
for (const p of [builtPath, devPath]) {
|
|
37876
38123
|
try {
|
|
37877
|
-
|
|
38124
|
+
statSync17(p);
|
|
37878
38125
|
return p;
|
|
37879
38126
|
} catch {
|
|
37880
38127
|
continue;
|
|
@@ -37884,7 +38131,7 @@ function resolveDockerfilePath() {
|
|
|
37884
38131
|
}
|
|
37885
38132
|
function dockerImageExists(tag) {
|
|
37886
38133
|
try {
|
|
37887
|
-
|
|
38134
|
+
execFileSync6("docker", ["image", "inspect", tag], { stdio: "pipe", timeout: 1e4 });
|
|
37888
38135
|
return true;
|
|
37889
38136
|
} catch {
|
|
37890
38137
|
return false;
|
|
@@ -37898,11 +38145,11 @@ function ensureDockerImage(version, quiet) {
|
|
|
37898
38145
|
}
|
|
37899
38146
|
if (!quiet) console.log(c.dim(` Building Docker image: ${tag}...`));
|
|
37900
38147
|
const dockerfilePath = resolveDockerfilePath();
|
|
37901
|
-
const tmpDir =
|
|
38148
|
+
const tmpDir = join42(tmpdir4(), `hyperframes-docker-${Date.now()}`);
|
|
37902
38149
|
mkdirSync22(tmpDir, { recursive: true });
|
|
37903
|
-
writeFileSync16(
|
|
38150
|
+
writeFileSync16(join42(tmpDir, "Dockerfile"), readFileSync28(dockerfilePath));
|
|
37904
38151
|
try {
|
|
37905
|
-
|
|
38152
|
+
execFileSync6(
|
|
37906
38153
|
"docker",
|
|
37907
38154
|
[
|
|
37908
38155
|
"build",
|
|
@@ -38087,7 +38334,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet) {
|
|
|
38087
38334
|
if (quiet) return;
|
|
38088
38335
|
let fileSize = "unknown";
|
|
38089
38336
|
try {
|
|
38090
|
-
fileSize = formatBytes(
|
|
38337
|
+
fileSize = formatBytes(statSync17(outputPath).size);
|
|
38091
38338
|
} catch {
|
|
38092
38339
|
}
|
|
38093
38340
|
const duration = formatDuration(elapsedMs);
|
|
@@ -38248,7 +38495,7 @@ var init_render2 = __esm({
|
|
|
38248
38495
|
const now = /* @__PURE__ */ new Date();
|
|
38249
38496
|
const datePart = now.toISOString().slice(0, 10);
|
|
38250
38497
|
const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
|
|
38251
|
-
const outputPath = args.output ? resolve28(args.output) :
|
|
38498
|
+
const outputPath = args.output ? resolve28(args.output) : join42(rendersDir, `${project.name}_${datePart}_${timePart}${ext}`);
|
|
38252
38499
|
mkdirSync22(dirname16(outputPath), { recursive: true });
|
|
38253
38500
|
const useDocker = args.docker ?? false;
|
|
38254
38501
|
const useGpu = args.gpu ?? false;
|
|
@@ -38724,8 +38971,8 @@ __export(layout_exports, {
|
|
|
38724
38971
|
examples: () => examples9
|
|
38725
38972
|
});
|
|
38726
38973
|
import { createServer } from "http";
|
|
38727
|
-
import { existsSync as
|
|
38728
|
-
import { dirname as dirname17, isAbsolute as isAbsolute6, join as
|
|
38974
|
+
import { existsSync as existsSync42, readFileSync as readFileSync29 } from "fs";
|
|
38975
|
+
import { dirname as dirname17, isAbsolute as isAbsolute6, join as join43, relative as relative5, resolve as resolve29 } from "path";
|
|
38729
38976
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
38730
38977
|
async function getCompositionDuration2(page) {
|
|
38731
38978
|
return page.evaluate(() => {
|
|
@@ -38795,7 +39042,7 @@ async function bundleProjectHtml(projectDir) {
|
|
|
38795
39042
|
"dist",
|
|
38796
39043
|
"hyperframe.runtime.iife.js"
|
|
38797
39044
|
);
|
|
38798
|
-
if (
|
|
39045
|
+
if (existsSync42(runtimePath)) {
|
|
38799
39046
|
const runtimeSource = readFileSync29(runtimePath, "utf-8");
|
|
38800
39047
|
html = html.replace(
|
|
38801
39048
|
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
|
|
@@ -38820,7 +39067,7 @@ async function serveProject(projectDir, html) {
|
|
|
38820
39067
|
res.end();
|
|
38821
39068
|
return;
|
|
38822
39069
|
}
|
|
38823
|
-
if (
|
|
39070
|
+
if (existsSync42(filePath)) {
|
|
38824
39071
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
38825
39072
|
res.end(readFileSync29(filePath));
|
|
38826
39073
|
return;
|
|
@@ -38924,11 +39171,11 @@ async function runLayoutAudit(projectDir, opts) {
|
|
|
38924
39171
|
}
|
|
38925
39172
|
function loadLayoutAuditScript() {
|
|
38926
39173
|
const candidates = [
|
|
38927
|
-
|
|
38928
|
-
|
|
39174
|
+
join43(__dirname2, "layout-audit.browser.js"),
|
|
39175
|
+
join43(__dirname2, "commands", "layout-audit.browser.js")
|
|
38929
39176
|
];
|
|
38930
39177
|
for (const candidate of candidates) {
|
|
38931
|
-
if (
|
|
39178
|
+
if (existsSync42(candidate)) return readFileSync29(candidate, "utf-8");
|
|
38932
39179
|
}
|
|
38933
39180
|
throw new Error("Missing layout audit browser script");
|
|
38934
39181
|
}
|
|
@@ -39148,16 +39395,16 @@ __export(info_exports, {
|
|
|
39148
39395
|
default: () => info_default,
|
|
39149
39396
|
examples: () => examples11
|
|
39150
39397
|
});
|
|
39151
|
-
import { readFileSync as readFileSync30, readdirSync as
|
|
39152
|
-
import { join as
|
|
39398
|
+
import { readFileSync as readFileSync30, readdirSync as readdirSync17, statSync as statSync18 } from "fs";
|
|
39399
|
+
import { join as join44 } from "path";
|
|
39153
39400
|
function totalSize(dir) {
|
|
39154
39401
|
let total = 0;
|
|
39155
|
-
for (const entry of
|
|
39156
|
-
const path2 =
|
|
39402
|
+
for (const entry of readdirSync17(dir, { withFileTypes: true })) {
|
|
39403
|
+
const path2 = join44(dir, entry.name);
|
|
39157
39404
|
if (entry.isDirectory()) {
|
|
39158
39405
|
total += totalSize(path2);
|
|
39159
39406
|
} else {
|
|
39160
|
-
total +=
|
|
39407
|
+
total += statSync18(path2).size;
|
|
39161
39408
|
}
|
|
39162
39409
|
}
|
|
39163
39410
|
return total;
|
|
@@ -39241,7 +39488,7 @@ __export(compositions_exports, {
|
|
|
39241
39488
|
default: () => compositions_default,
|
|
39242
39489
|
examples: () => examples12
|
|
39243
39490
|
});
|
|
39244
|
-
import { existsSync as
|
|
39491
|
+
import { existsSync as existsSync43, readFileSync as readFileSync31 } from "fs";
|
|
39245
39492
|
import { resolve as resolve30, dirname as dirname18 } from "path";
|
|
39246
39493
|
function parseCompositions(html, baseDir) {
|
|
39247
39494
|
const parser = new DOMParser();
|
|
@@ -39255,7 +39502,7 @@ function parseCompositions(html, baseDir) {
|
|
|
39255
39502
|
const compositionSrc = div.getAttribute("data-composition-src");
|
|
39256
39503
|
if (compositionSrc) {
|
|
39257
39504
|
const subPath = resolve30(baseDir, compositionSrc);
|
|
39258
|
-
if (
|
|
39505
|
+
if (existsSync43(subPath)) {
|
|
39259
39506
|
const subHtml = readFileSync31(subPath, "utf-8");
|
|
39260
39507
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
39261
39508
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
@@ -39388,8 +39635,8 @@ __export(benchmark_exports, {
|
|
|
39388
39635
|
default: () => benchmark_default,
|
|
39389
39636
|
examples: () => examples13
|
|
39390
39637
|
});
|
|
39391
|
-
import { existsSync as
|
|
39392
|
-
import { resolve as resolve31, join as
|
|
39638
|
+
import { existsSync as existsSync44, statSync as statSync19 } from "fs";
|
|
39639
|
+
import { resolve as resolve31, join as join45 } from "path";
|
|
39393
39640
|
var examples13, DEFAULT_CONFIGS, benchmark_default;
|
|
39394
39641
|
var init_benchmark = __esm({
|
|
39395
39642
|
"src/commands/benchmark.ts"() {
|
|
@@ -39464,7 +39711,7 @@ var init_benchmark = __esm({
|
|
|
39464
39711
|
s2?.start(`Benchmarking ${config.label}...`);
|
|
39465
39712
|
for (let i2 = 0; i2 < runsPerConfig; i2++) {
|
|
39466
39713
|
s2?.message(`${config.label} \u2014 run ${i2 + 1}/${runsPerConfig}`);
|
|
39467
|
-
const outputPath =
|
|
39714
|
+
const outputPath = join45(
|
|
39468
39715
|
benchDir,
|
|
39469
39716
|
`${config.label.replace(/[^a-zA-Z0-9]/g, "_")}_run${i2}.mp4`
|
|
39470
39717
|
);
|
|
@@ -39478,8 +39725,8 @@ var init_benchmark = __esm({
|
|
|
39478
39725
|
await producer.executeRenderJob(job, project.dir, outputPath);
|
|
39479
39726
|
const elapsedMs = Date.now() - startTime;
|
|
39480
39727
|
let fileSize = null;
|
|
39481
|
-
if (
|
|
39482
|
-
const stat3 =
|
|
39728
|
+
if (existsSync44(outputPath)) {
|
|
39729
|
+
const stat3 = statSync19(outputPath);
|
|
39483
39730
|
fileSize = stat3.size;
|
|
39484
39731
|
}
|
|
39485
39732
|
runs.push({ elapsedMs, fileSize });
|
|
@@ -39694,8 +39941,8 @@ __export(transcribe_exports2, {
|
|
|
39694
39941
|
default: () => transcribe_default,
|
|
39695
39942
|
examples: () => examples15
|
|
39696
39943
|
});
|
|
39697
|
-
import { existsSync as
|
|
39698
|
-
import { resolve as resolve32, join as
|
|
39944
|
+
import { existsSync as existsSync45, writeFileSync as writeFileSync17 } from "fs";
|
|
39945
|
+
import { resolve as resolve32, join as join46, extname as extname8 } from "path";
|
|
39699
39946
|
async function importTranscript(inputPath, dir, json) {
|
|
39700
39947
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
39701
39948
|
const { words, format } = loadTranscript2(inputPath);
|
|
@@ -39703,7 +39950,7 @@ async function importTranscript(inputPath, dir, json) {
|
|
|
39703
39950
|
console.error(c.error("No words found in transcript."));
|
|
39704
39951
|
process.exit(1);
|
|
39705
39952
|
}
|
|
39706
|
-
const outPath =
|
|
39953
|
+
const outPath = join46(dir, "transcript.json");
|
|
39707
39954
|
writeFileSync17(outPath, JSON.stringify(words, null, 2));
|
|
39708
39955
|
patchCaptionHtml2(dir, words);
|
|
39709
39956
|
if (json) {
|
|
@@ -39820,7 +40067,7 @@ var init_transcribe2 = __esm({
|
|
|
39820
40067
|
},
|
|
39821
40068
|
async run({ args }) {
|
|
39822
40069
|
const inputPath = resolve32(args.input);
|
|
39823
|
-
if (!
|
|
40070
|
+
if (!existsSync45(inputPath)) {
|
|
39824
40071
|
console.error(c.error(`File not found: ${args.input}`));
|
|
39825
40072
|
process.exit(1);
|
|
39826
40073
|
}
|
|
@@ -39841,9 +40088,9 @@ var init_transcribe2 = __esm({
|
|
|
39841
40088
|
});
|
|
39842
40089
|
|
|
39843
40090
|
// src/tts/manager.ts
|
|
39844
|
-
import { existsSync as
|
|
39845
|
-
import { homedir as
|
|
39846
|
-
import { join as
|
|
40091
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync23 } from "fs";
|
|
40092
|
+
import { homedir as homedir9 } from "os";
|
|
40093
|
+
import { join as join47 } from "path";
|
|
39847
40094
|
function inferLangFromVoiceId(voiceId) {
|
|
39848
40095
|
const first = voiceId.charAt(0).toLowerCase();
|
|
39849
40096
|
return VOICE_PREFIX_LANG[first] ?? "en-us";
|
|
@@ -39852,8 +40099,8 @@ function isSupportedLang(value) {
|
|
|
39852
40099
|
return SUPPORTED_LANGS.includes(value);
|
|
39853
40100
|
}
|
|
39854
40101
|
async function ensureModel2(model = DEFAULT_MODEL2, options) {
|
|
39855
|
-
const modelPath =
|
|
39856
|
-
if (
|
|
40102
|
+
const modelPath = join47(MODELS_DIR2, `${model}.onnx`);
|
|
40103
|
+
if (existsSync46(modelPath)) return modelPath;
|
|
39857
40104
|
const url = MODEL_URLS[model];
|
|
39858
40105
|
if (!url) {
|
|
39859
40106
|
throw new Error(
|
|
@@ -39863,18 +40110,18 @@ async function ensureModel2(model = DEFAULT_MODEL2, options) {
|
|
|
39863
40110
|
mkdirSync23(MODELS_DIR2, { recursive: true });
|
|
39864
40111
|
options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
|
|
39865
40112
|
await downloadFile(url, modelPath);
|
|
39866
|
-
if (!
|
|
40113
|
+
if (!existsSync46(modelPath)) {
|
|
39867
40114
|
throw new Error(`Model download failed: ${model}`);
|
|
39868
40115
|
}
|
|
39869
40116
|
return modelPath;
|
|
39870
40117
|
}
|
|
39871
40118
|
async function ensureVoices(options) {
|
|
39872
|
-
const voicesPath =
|
|
39873
|
-
if (
|
|
40119
|
+
const voicesPath = join47(VOICES_DIR, "voices-v1.0.bin");
|
|
40120
|
+
if (existsSync46(voicesPath)) return voicesPath;
|
|
39874
40121
|
mkdirSync23(VOICES_DIR, { recursive: true });
|
|
39875
40122
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
39876
40123
|
await downloadFile(VOICES_URL, voicesPath);
|
|
39877
|
-
if (!
|
|
40124
|
+
if (!existsSync46(voicesPath)) {
|
|
39878
40125
|
throw new Error("Voice data download failed");
|
|
39879
40126
|
}
|
|
39880
40127
|
return voicesPath;
|
|
@@ -39884,9 +40131,9 @@ var init_manager3 = __esm({
|
|
|
39884
40131
|
"src/tts/manager.ts"() {
|
|
39885
40132
|
"use strict";
|
|
39886
40133
|
init_download();
|
|
39887
|
-
CACHE_DIR3 =
|
|
39888
|
-
MODELS_DIR2 =
|
|
39889
|
-
VOICES_DIR =
|
|
40134
|
+
CACHE_DIR3 = join47(homedir9(), ".cache", "hyperframes", "tts");
|
|
40135
|
+
MODELS_DIR2 = join47(CACHE_DIR3, "models");
|
|
40136
|
+
VOICES_DIR = join47(CACHE_DIR3, "voices");
|
|
39890
40137
|
DEFAULT_MODEL2 = "kokoro-v1.0";
|
|
39891
40138
|
MODEL_URLS = {
|
|
39892
40139
|
"kokoro-v1.0": "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx"
|
|
@@ -39946,22 +40193,22 @@ var synthesize_exports = {};
|
|
|
39946
40193
|
__export(synthesize_exports, {
|
|
39947
40194
|
synthesize: () => synthesize
|
|
39948
40195
|
});
|
|
39949
|
-
import { execFileSync as
|
|
39950
|
-
import { existsSync as
|
|
39951
|
-
import { join as
|
|
39952
|
-
import { homedir as
|
|
40196
|
+
import { execFileSync as execFileSync7 } from "child_process";
|
|
40197
|
+
import { existsSync as existsSync47, writeFileSync as writeFileSync18, mkdirSync as mkdirSync24, readdirSync as readdirSync18, unlinkSync as unlinkSync6 } from "fs";
|
|
40198
|
+
import { join as join48, dirname as dirname19, basename as basename10 } from "path";
|
|
40199
|
+
import { homedir as homedir10 } from "os";
|
|
39953
40200
|
function findPython() {
|
|
39954
40201
|
for (const name of ["python3", "python"]) {
|
|
39955
40202
|
try {
|
|
39956
40203
|
const cmd = process.platform === "win32" ? "where" : "which";
|
|
39957
|
-
const output =
|
|
40204
|
+
const output = execFileSync7(cmd, [name], {
|
|
39958
40205
|
encoding: "utf-8",
|
|
39959
40206
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39960
40207
|
timeout: 5e3
|
|
39961
40208
|
});
|
|
39962
40209
|
const first = output.split(/\r?\n/).map((s2) => s2.trim()).find(Boolean);
|
|
39963
40210
|
if (!first) continue;
|
|
39964
|
-
const version =
|
|
40211
|
+
const version = execFileSync7(first, ["--version"], {
|
|
39965
40212
|
encoding: "utf-8",
|
|
39966
40213
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39967
40214
|
timeout: 5e3
|
|
@@ -39974,7 +40221,7 @@ function findPython() {
|
|
|
39974
40221
|
}
|
|
39975
40222
|
function hasPythonPackage(python, pkg) {
|
|
39976
40223
|
try {
|
|
39977
|
-
|
|
40224
|
+
execFileSync7(python, ["-c", `import ${pkg}`], {
|
|
39978
40225
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39979
40226
|
timeout: 1e4
|
|
39980
40227
|
});
|
|
@@ -39984,15 +40231,15 @@ function hasPythonPackage(python, pkg) {
|
|
|
39984
40231
|
}
|
|
39985
40232
|
}
|
|
39986
40233
|
function ensureSynthScript() {
|
|
39987
|
-
if (!
|
|
40234
|
+
if (!existsSync47(SCRIPT_PATH)) {
|
|
39988
40235
|
mkdirSync24(SCRIPT_DIR, { recursive: true });
|
|
39989
40236
|
writeFileSync18(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
39990
40237
|
const currentName = basename10(SCRIPT_PATH);
|
|
39991
40238
|
try {
|
|
39992
|
-
for (const entry of
|
|
40239
|
+
for (const entry of readdirSync18(SCRIPT_DIR)) {
|
|
39993
40240
|
if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
|
|
39994
40241
|
try {
|
|
39995
|
-
unlinkSync6(
|
|
40242
|
+
unlinkSync6(join48(SCRIPT_DIR, entry));
|
|
39996
40243
|
} catch {
|
|
39997
40244
|
}
|
|
39998
40245
|
}
|
|
@@ -40029,7 +40276,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
40029
40276
|
mkdirSync24(dirname19(outputPath), { recursive: true });
|
|
40030
40277
|
options?.onProgress?.(`Generating speech with voice ${voice} (${lang})...`);
|
|
40031
40278
|
try {
|
|
40032
|
-
const stdout2 =
|
|
40279
|
+
const stdout2 = execFileSync7(
|
|
40033
40280
|
python,
|
|
40034
40281
|
[scriptPath, modelPath, voicesPath, text, voice, String(speed), outputPath, lang],
|
|
40035
40282
|
{
|
|
@@ -40038,7 +40285,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
40038
40285
|
stdio: ["pipe", "pipe", "pipe"]
|
|
40039
40286
|
}
|
|
40040
40287
|
);
|
|
40041
|
-
if (!
|
|
40288
|
+
if (!existsSync47(outputPath)) {
|
|
40042
40289
|
throw new Error("Synthesis completed but no output file was created");
|
|
40043
40290
|
}
|
|
40044
40291
|
const lines = stdout2.trim().split("\n");
|
|
@@ -40051,7 +40298,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
40051
40298
|
langApplied: result.langApplied
|
|
40052
40299
|
};
|
|
40053
40300
|
} catch (err) {
|
|
40054
|
-
if (err instanceof SyntaxError &&
|
|
40301
|
+
if (err instanceof SyntaxError && existsSync47(outputPath)) {
|
|
40055
40302
|
throw new Error(
|
|
40056
40303
|
"Speech was generated but metadata could not be read. Check the output file manually."
|
|
40057
40304
|
);
|
|
@@ -40102,8 +40349,8 @@ print(json.dumps({
|
|
|
40102
40349
|
"langApplied": bool(lang and supports_lang),
|
|
40103
40350
|
}))
|
|
40104
40351
|
`;
|
|
40105
|
-
SCRIPT_DIR =
|
|
40106
|
-
SCRIPT_PATH =
|
|
40352
|
+
SCRIPT_DIR = join48(homedir10(), ".cache", "hyperframes", "tts");
|
|
40353
|
+
SCRIPT_PATH = join48(SCRIPT_DIR, "synth-v2.py");
|
|
40107
40354
|
}
|
|
40108
40355
|
});
|
|
40109
40356
|
|
|
@@ -40113,7 +40360,7 @@ __export(tts_exports, {
|
|
|
40113
40360
|
default: () => tts_default,
|
|
40114
40361
|
examples: () => examples16
|
|
40115
40362
|
});
|
|
40116
|
-
import { existsSync as
|
|
40363
|
+
import { existsSync as existsSync48, readFileSync as readFileSync32 } from "fs";
|
|
40117
40364
|
import { resolve as resolve33, extname as extname9 } from "path";
|
|
40118
40365
|
function listVoices(json) {
|
|
40119
40366
|
const rows = BUNDLED_VOICES.map((v) => ({ ...v, defaultLang: inferLangFromVoiceId(v.id) }));
|
|
@@ -40223,7 +40470,7 @@ var init_tts = __esm({
|
|
|
40223
40470
|
}
|
|
40224
40471
|
let text;
|
|
40225
40472
|
const maybeFile = resolve33(args.input);
|
|
40226
|
-
if (
|
|
40473
|
+
if (existsSync48(maybeFile) && extname9(maybeFile).toLowerCase() === ".txt") {
|
|
40227
40474
|
text = readFileSync32(maybeFile, "utf-8").trim();
|
|
40228
40475
|
if (!text) {
|
|
40229
40476
|
console.error(c.error("File is empty."));
|
|
@@ -40316,15 +40563,15 @@ __export(docs_exports, {
|
|
|
40316
40563
|
default: () => docs_default,
|
|
40317
40564
|
examples: () => examples17
|
|
40318
40565
|
});
|
|
40319
|
-
import { readFileSync as readFileSync33, existsSync as
|
|
40320
|
-
import { resolve as resolve34, dirname as dirname20, join as
|
|
40566
|
+
import { readFileSync as readFileSync33, existsSync as existsSync49 } from "fs";
|
|
40567
|
+
import { resolve as resolve34, dirname as dirname20, join as join49 } from "path";
|
|
40321
40568
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
40322
40569
|
function docsDir() {
|
|
40323
40570
|
const thisFile = fileURLToPath7(import.meta.url);
|
|
40324
40571
|
const dir = dirname20(thisFile);
|
|
40325
40572
|
const devPath = resolve34(dir, "..", "docs");
|
|
40326
40573
|
const builtPath = resolve34(dir, "docs");
|
|
40327
|
-
return
|
|
40574
|
+
return existsSync49(devPath) ? devPath : builtPath;
|
|
40328
40575
|
}
|
|
40329
40576
|
function formatInlineCode(line) {
|
|
40330
40577
|
return line.replace(/`([^`]+)`/g, (_match, code) => c.accent(code));
|
|
@@ -40421,8 +40668,8 @@ var init_docs = __esm({
|
|
|
40421
40668
|
}
|
|
40422
40669
|
process.exit(1);
|
|
40423
40670
|
}
|
|
40424
|
-
const filePath =
|
|
40425
|
-
if (!
|
|
40671
|
+
const filePath = join49(docsDir(), entry.file);
|
|
40672
|
+
if (!existsSync49(filePath)) {
|
|
40426
40673
|
console.error(c.error(`Doc file not found: ${filePath}`));
|
|
40427
40674
|
process.exit(1);
|
|
40428
40675
|
}
|
|
@@ -40441,7 +40688,7 @@ __export(doctor_exports, {
|
|
|
40441
40688
|
examples: () => examples18
|
|
40442
40689
|
});
|
|
40443
40690
|
import { execSync as execSync3 } from "child_process";
|
|
40444
|
-
import { freemem as freemem4, platform as
|
|
40691
|
+
import { freemem as freemem4, platform as platform5 } from "os";
|
|
40445
40692
|
function checkFFmpeg() {
|
|
40446
40693
|
const path2 = findFFmpeg();
|
|
40447
40694
|
if (path2) {
|
|
@@ -40606,7 +40853,7 @@ var init_doctor = __esm({
|
|
|
40606
40853
|
{ name: "Memory", run: checkMemory },
|
|
40607
40854
|
{ name: "Disk", run: checkDisk }
|
|
40608
40855
|
];
|
|
40609
|
-
if (
|
|
40856
|
+
if (platform5() === "linux") {
|
|
40610
40857
|
checks.push({ name: "/dev/shm", run: checkShm });
|
|
40611
40858
|
}
|
|
40612
40859
|
checks.push(
|
|
@@ -40852,8 +41099,8 @@ var validate_exports = {};
|
|
|
40852
41099
|
__export(validate_exports, {
|
|
40853
41100
|
default: () => validate_default
|
|
40854
41101
|
});
|
|
40855
|
-
import { existsSync as
|
|
40856
|
-
import { resolve as resolve35, join as
|
|
41102
|
+
import { existsSync as existsSync50, readFileSync as readFileSync34 } from "fs";
|
|
41103
|
+
import { resolve as resolve35, join as join50, dirname as dirname21 } from "path";
|
|
40857
41104
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
40858
41105
|
async function getCompositionDuration3(page) {
|
|
40859
41106
|
return page.evaluate(() => {
|
|
@@ -40908,7 +41155,7 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
40908
41155
|
"dist",
|
|
40909
41156
|
"hyperframe.runtime.iife.js"
|
|
40910
41157
|
);
|
|
40911
|
-
if (
|
|
41158
|
+
if (existsSync50(runtimePath)) {
|
|
40912
41159
|
const runtimeSource = readFileSync34(runtimePath, "utf-8");
|
|
40913
41160
|
html = html.replace(
|
|
40914
41161
|
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
|
|
@@ -40924,8 +41171,8 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
40924
41171
|
res.end(html);
|
|
40925
41172
|
return;
|
|
40926
41173
|
}
|
|
40927
|
-
const filePath =
|
|
40928
|
-
if (
|
|
41174
|
+
const filePath = join50(projectDir, decodeURIComponent(url));
|
|
41175
|
+
if (existsSync50(filePath)) {
|
|
40929
41176
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
40930
41177
|
res.end(readFileSync34(filePath));
|
|
40931
41178
|
return;
|
|
@@ -41118,13 +41365,13 @@ __export(snapshot_exports, {
|
|
|
41118
41365
|
examples: () => examples21
|
|
41119
41366
|
});
|
|
41120
41367
|
import { spawn as spawn11 } from "child_process";
|
|
41121
|
-
import { existsSync as
|
|
41368
|
+
import { existsSync as existsSync51, mkdtempSync as mkdtempSync3, readFileSync as readFileSync35, mkdirSync as mkdirSync25, rmSync as rmSync10 } from "fs";
|
|
41122
41369
|
import { tmpdir as tmpdir5 } from "os";
|
|
41123
|
-
import { resolve as resolve36, join as
|
|
41370
|
+
import { resolve as resolve36, join as join51, dirname as dirname22, relative as relative6, isAbsolute as isAbsolute7 } from "path";
|
|
41124
41371
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
41125
41372
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
41126
|
-
const tmp = mkdtempSync3(
|
|
41127
|
-
const outPath =
|
|
41373
|
+
const tmp = mkdtempSync3(join51(tmpdir5(), "hf-snapshot-frame-"));
|
|
41374
|
+
const outPath = join51(tmp, "frame.png");
|
|
41128
41375
|
try {
|
|
41129
41376
|
const result = await new Promise(
|
|
41130
41377
|
(resolvePromise) => {
|
|
@@ -41164,7 +41411,7 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
41164
41411
|
});
|
|
41165
41412
|
}
|
|
41166
41413
|
);
|
|
41167
|
-
if (result.code !== 0 || result.timedOut || !
|
|
41414
|
+
if (result.code !== 0 || result.timedOut || !existsSync51(outPath)) return null;
|
|
41168
41415
|
return readFileSync35(outPath);
|
|
41169
41416
|
} finally {
|
|
41170
41417
|
try {
|
|
@@ -41187,7 +41434,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
41187
41434
|
"dist",
|
|
41188
41435
|
"hyperframe.runtime.iife.js"
|
|
41189
41436
|
);
|
|
41190
|
-
if (
|
|
41437
|
+
if (existsSync51(runtimePath)) {
|
|
41191
41438
|
const runtimeSource = readFileSync35(runtimePath, "utf-8");
|
|
41192
41439
|
html = html.replace(
|
|
41193
41440
|
/<script[^>]*data-hyperframes-preview-runtime[^>]*src="[^"]*"[^>]*><\/script>/,
|
|
@@ -41210,7 +41457,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
41210
41457
|
res.end();
|
|
41211
41458
|
return;
|
|
41212
41459
|
}
|
|
41213
|
-
if (
|
|
41460
|
+
if (existsSync51(filePath)) {
|
|
41214
41461
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
41215
41462
|
res.end(readFileSync35(filePath));
|
|
41216
41463
|
return;
|
|
@@ -41285,7 +41532,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
41285
41532
|
return [];
|
|
41286
41533
|
}
|
|
41287
41534
|
const positions = opts.at?.length ? opts.at : numFrames === 1 ? [duration / 2] : Array.from({ length: numFrames }, (_2, i2) => i2 / (numFrames - 1) * duration);
|
|
41288
|
-
const snapshotDir =
|
|
41535
|
+
const snapshotDir = join51(projectDir, "snapshots");
|
|
41289
41536
|
mkdirSync25(snapshotDir, { recursive: true });
|
|
41290
41537
|
let injectVideoFramesBatch2 = null;
|
|
41291
41538
|
let syncVideoFrameVisibility2 = null;
|
|
@@ -41360,7 +41607,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
41360
41607
|
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
|
41361
41608
|
const candidate = resolve36(projectDir, decodedPath);
|
|
41362
41609
|
const rel = relative6(projectDir, candidate);
|
|
41363
|
-
if (!rel.startsWith("..") && !isAbsolute7(rel) &&
|
|
41610
|
+
if (!rel.startsWith("..") && !isAbsolute7(rel) && existsSync51(candidate)) {
|
|
41364
41611
|
filePath = candidate;
|
|
41365
41612
|
}
|
|
41366
41613
|
} catch {
|
|
@@ -41390,7 +41637,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
41390
41637
|
}
|
|
41391
41638
|
const timeLabel = opts.at?.length ? `${time.toFixed(1)}s` : `${Math.round(time / duration * 100)}pct`;
|
|
41392
41639
|
const filename = `frame-${String(i2).padStart(2, "0")}-at-${timeLabel}.png`;
|
|
41393
|
-
const framePath =
|
|
41640
|
+
const framePath = join51(snapshotDir, filename);
|
|
41394
41641
|
await page.screenshot({ path: framePath, type: "png" });
|
|
41395
41642
|
savedPaths.push(`snapshots/${filename}`);
|
|
41396
41643
|
}
|
|
@@ -41476,13 +41723,13 @@ ${c.error("\u2717")} Snapshot failed: ${msg}`);
|
|
|
41476
41723
|
|
|
41477
41724
|
// src/capture/assetDownloader.ts
|
|
41478
41725
|
import { writeFileSync as writeFileSync19, mkdirSync as mkdirSync26 } from "fs";
|
|
41479
|
-
import { join as
|
|
41726
|
+
import { join as join52, extname as extname10 } from "path";
|
|
41480
41727
|
async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks) {
|
|
41481
|
-
const assetsDir =
|
|
41728
|
+
const assetsDir = join52(outputDir, "assets");
|
|
41482
41729
|
mkdirSync26(assetsDir, { recursive: true });
|
|
41483
41730
|
const assets = [];
|
|
41484
41731
|
const downloadedUrls = /* @__PURE__ */ new Set();
|
|
41485
|
-
mkdirSync26(
|
|
41732
|
+
mkdirSync26(join52(outputDir, "assets", "svgs"), { recursive: true });
|
|
41486
41733
|
for (let i2 = 0; i2 < tokens.svgs.length && i2 < 30; i2++) {
|
|
41487
41734
|
const svg = tokens.svgs[i2];
|
|
41488
41735
|
if (!svg.outerHTML || svg.outerHTML.length < 50) continue;
|
|
@@ -41490,7 +41737,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
41490
41737
|
const name = label2 ? slugify(label2) + ".svg" : svg.isLogo ? `logo-${i2}.svg` : `icon-${i2}.svg`;
|
|
41491
41738
|
const localPath = `assets/svgs/${name}`;
|
|
41492
41739
|
try {
|
|
41493
|
-
writeFileSync19(
|
|
41740
|
+
writeFileSync19(join52(outputDir, localPath), svg.outerHTML, "utf-8");
|
|
41494
41741
|
assets.push({ url: "", localPath, type: "svg" });
|
|
41495
41742
|
} catch {
|
|
41496
41743
|
}
|
|
@@ -41503,7 +41750,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
41503
41750
|
const localPath = `assets/${name}`;
|
|
41504
41751
|
const buffer = await fetchBuffer(icon.href);
|
|
41505
41752
|
if (buffer) {
|
|
41506
|
-
writeFileSync19(
|
|
41753
|
+
writeFileSync19(join52(outputDir, localPath), buffer);
|
|
41507
41754
|
assets.push({ url: icon.href, localPath, type: "favicon" });
|
|
41508
41755
|
break;
|
|
41509
41756
|
}
|
|
@@ -41560,7 +41807,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
41560
41807
|
const slug = isMeaningful ? slugify(rawName) : `${prefix}-${imgIdx}`;
|
|
41561
41808
|
const name = `${slug}${ext}`;
|
|
41562
41809
|
const localPath = `assets/${name}`;
|
|
41563
|
-
writeFileSync19(
|
|
41810
|
+
writeFileSync19(join52(outputDir, localPath), buffer);
|
|
41564
41811
|
assets.push({ url, localPath, type: "image" });
|
|
41565
41812
|
imgIdx++;
|
|
41566
41813
|
} catch {
|
|
@@ -41573,7 +41820,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
41573
41820
|
const localPath = `assets/og-image${ext}`;
|
|
41574
41821
|
const buffer = await fetchBuffer(tokens.ogImage);
|
|
41575
41822
|
if (buffer && buffer.length > 5e3) {
|
|
41576
|
-
writeFileSync19(
|
|
41823
|
+
writeFileSync19(join52(outputDir, localPath), buffer);
|
|
41577
41824
|
assets.push({ url: tokens.ogImage, localPath, type: "image" });
|
|
41578
41825
|
}
|
|
41579
41826
|
} catch {
|
|
@@ -41596,7 +41843,7 @@ function normalizeUrl(u) {
|
|
|
41596
41843
|
}
|
|
41597
41844
|
}
|
|
41598
41845
|
async function downloadAndRewriteFonts(css, outputDir) {
|
|
41599
|
-
const assetsDir =
|
|
41846
|
+
const assetsDir = join52(outputDir, "assets", "fonts");
|
|
41600
41847
|
mkdirSync26(assetsDir, { recursive: true });
|
|
41601
41848
|
const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
|
|
41602
41849
|
const fontUrls = /* @__PURE__ */ new Set();
|
|
@@ -41632,7 +41879,7 @@ async function downloadAndRewriteFonts(css, outputDir) {
|
|
|
41632
41879
|
try {
|
|
41633
41880
|
const urlObj = new URL(fontUrl);
|
|
41634
41881
|
const filename = urlObj.pathname.split("/").pop() || `font-${count}.woff2`;
|
|
41635
|
-
const localPath =
|
|
41882
|
+
const localPath = join52(assetsDir, filename);
|
|
41636
41883
|
const relativePath = `assets/fonts/${filename}`;
|
|
41637
41884
|
const buffer = await fetchBuffer(fontUrl);
|
|
41638
41885
|
if (buffer) {
|
|
@@ -42429,8 +42676,8 @@ var init_animationCataloger = __esm({
|
|
|
42429
42676
|
});
|
|
42430
42677
|
|
|
42431
42678
|
// src/capture/mediaCapture.ts
|
|
42432
|
-
import { mkdirSync as mkdirSync27, writeFileSync as writeFileSync20, readdirSync as
|
|
42433
|
-
import { join as
|
|
42679
|
+
import { mkdirSync as mkdirSync27, writeFileSync as writeFileSync20, readdirSync as readdirSync19, readFileSync as readFileSync36, statSync as statSync20 } from "fs";
|
|
42680
|
+
import { join as join53 } from "path";
|
|
42434
42681
|
async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
42435
42682
|
let savedCount = 0;
|
|
42436
42683
|
const savedHashes = /* @__PURE__ */ new Set();
|
|
@@ -42463,7 +42710,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
|
42463
42710
|
const hash2 = buf.toString("base64").slice(0, 100);
|
|
42464
42711
|
if (savedHashes.has(hash2)) continue;
|
|
42465
42712
|
savedHashes.add(hash2);
|
|
42466
|
-
writeFileSync20(
|
|
42713
|
+
writeFileSync20(join53(lottieDir, `animation-${savedCount}.lottie`), buf);
|
|
42467
42714
|
savedCount++;
|
|
42468
42715
|
continue;
|
|
42469
42716
|
}
|
|
@@ -42481,7 +42728,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
|
42481
42728
|
} catch {
|
|
42482
42729
|
continue;
|
|
42483
42730
|
}
|
|
42484
|
-
writeFileSync20(
|
|
42731
|
+
writeFileSync20(join53(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
|
|
42485
42732
|
savedCount++;
|
|
42486
42733
|
}
|
|
42487
42734
|
} catch {
|
|
@@ -42491,22 +42738,22 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
|
42491
42738
|
}
|
|
42492
42739
|
async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
42493
42740
|
const manifest = [];
|
|
42494
|
-
const previewDir =
|
|
42741
|
+
const previewDir = join53(lottieDir, "previews");
|
|
42495
42742
|
mkdirSync27(previewDir, { recursive: true });
|
|
42496
|
-
for (const file of
|
|
42743
|
+
for (const file of readdirSync19(lottieDir)) {
|
|
42497
42744
|
if (!file.endsWith(".json")) continue;
|
|
42498
42745
|
try {
|
|
42499
|
-
const raw = JSON.parse(readFileSync36(
|
|
42746
|
+
const raw = JSON.parse(readFileSync36(join53(lottieDir, file), "utf-8"));
|
|
42500
42747
|
const fr = raw.fr || 30;
|
|
42501
42748
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
42502
42749
|
const previewName = file.replace(".json", "-preview.png");
|
|
42503
|
-
const fileSize =
|
|
42750
|
+
const fileSize = statSync20(join53(lottieDir, file)).size;
|
|
42504
42751
|
if (fileSize > 2e6) continue;
|
|
42505
42752
|
let previewPage;
|
|
42506
42753
|
try {
|
|
42507
42754
|
previewPage = await chromeBrowser.newPage();
|
|
42508
42755
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
42509
|
-
const animData = JSON.parse(readFileSync36(
|
|
42756
|
+
const animData = JSON.parse(readFileSync36(join53(lottieDir, file), "utf-8"));
|
|
42510
42757
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
42511
42758
|
await previewPage.setContent(
|
|
42512
42759
|
`<!DOCTYPE html>
|
|
@@ -42536,7 +42783,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
42536
42783
|
await previewPage.waitForFunction(() => window.__READY === true, { timeout: 5e3 }).catch(() => {
|
|
42537
42784
|
});
|
|
42538
42785
|
await previewPage.screenshot({
|
|
42539
|
-
path:
|
|
42786
|
+
path: join53(previewDir, previewName),
|
|
42540
42787
|
type: "png",
|
|
42541
42788
|
omitBackground: true
|
|
42542
42789
|
});
|
|
@@ -42560,7 +42807,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
42560
42807
|
}
|
|
42561
42808
|
if (manifest.length > 0) {
|
|
42562
42809
|
writeFileSync20(
|
|
42563
|
-
|
|
42810
|
+
join53(outputDir, "extracted", "lottie-manifest.json"),
|
|
42564
42811
|
JSON.stringify(manifest, null, 2),
|
|
42565
42812
|
"utf-8"
|
|
42566
42813
|
);
|
|
@@ -42622,15 +42869,15 @@ async function captureVideoManifest(page, outputDir, progress) {
|
|
|
42622
42869
|
return true;
|
|
42623
42870
|
});
|
|
42624
42871
|
if (uniqueVideos.length > 0) {
|
|
42625
|
-
const videoManifestDir =
|
|
42872
|
+
const videoManifestDir = join53(outputDir, "assets", "videos");
|
|
42626
42873
|
mkdirSync27(videoManifestDir, { recursive: true });
|
|
42627
|
-
const previewDir =
|
|
42874
|
+
const previewDir = join53(videoManifestDir, "previews");
|
|
42628
42875
|
mkdirSync27(previewDir, { recursive: true });
|
|
42629
42876
|
const videoManifest = [];
|
|
42630
42877
|
for (let vi = 0; vi < uniqueVideos.length && vi < 20; vi++) {
|
|
42631
42878
|
const v = uniqueVideos[vi];
|
|
42632
42879
|
const previewName = `video-${vi}-preview.png`;
|
|
42633
|
-
const previewPath =
|
|
42880
|
+
const previewPath = join53(previewDir, previewName);
|
|
42634
42881
|
try {
|
|
42635
42882
|
await page.evaluate(`window.scrollTo(0, ${Math.max(0, v.top - 100)})`);
|
|
42636
42883
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
@@ -42669,7 +42916,7 @@ async function captureVideoManifest(page, outputDir, progress) {
|
|
|
42669
42916
|
}
|
|
42670
42917
|
if (videoManifest.length > 0) {
|
|
42671
42918
|
writeFileSync20(
|
|
42672
|
-
|
|
42919
|
+
join53(outputDir, "extracted", "video-manifest.json"),
|
|
42673
42920
|
JSON.stringify(videoManifest, null, 2),
|
|
42674
42921
|
"utf-8"
|
|
42675
42922
|
);
|
|
@@ -49623,7 +49870,7 @@ var require_node_domexception = __commonJS({
|
|
|
49623
49870
|
});
|
|
49624
49871
|
|
|
49625
49872
|
// ../../node_modules/.bun/fetch-blob@3.2.0/node_modules/fetch-blob/from.js
|
|
49626
|
-
import { statSync as
|
|
49873
|
+
import { statSync as statSync21, createReadStream as createReadStream2, promises as fs2 } from "fs";
|
|
49627
49874
|
import { basename as basename11 } from "path";
|
|
49628
49875
|
var import_node_domexception, stat, blobFromSync, blobFrom, fileFrom, fileFromSync, fromBlob, fromFile, BlobDataItem;
|
|
49629
49876
|
var init_from = __esm({
|
|
@@ -49633,10 +49880,10 @@ var init_from = __esm({
|
|
|
49633
49880
|
init_file();
|
|
49634
49881
|
init_fetch_blob();
|
|
49635
49882
|
({ stat } = fs2);
|
|
49636
|
-
blobFromSync = (path2, type) => fromBlob(
|
|
49883
|
+
blobFromSync = (path2, type) => fromBlob(statSync21(path2), path2, type);
|
|
49637
49884
|
blobFrom = (path2, type) => stat(path2).then((stat3) => fromBlob(stat3, path2, type));
|
|
49638
49885
|
fileFrom = (path2, type) => stat(path2).then((stat3) => fromFile(stat3, path2, type));
|
|
49639
|
-
fileFromSync = (path2, type) => fromFile(
|
|
49886
|
+
fileFromSync = (path2, type) => fromFile(statSync21(path2), path2, type);
|
|
49640
49887
|
fromBlob = (stat3, path2, type = "") => new fetch_blob_default([new BlobDataItem({
|
|
49641
49888
|
path: path2,
|
|
49642
49889
|
size: stat3.size,
|
|
@@ -83124,8 +83371,8 @@ ${underline2}`);
|
|
|
83124
83371
|
});
|
|
83125
83372
|
|
|
83126
83373
|
// src/capture/contentExtractor.ts
|
|
83127
|
-
import { readdirSync as
|
|
83128
|
-
import { join as
|
|
83374
|
+
import { readdirSync as readdirSync20, statSync as statSync22, readFileSync as readFileSync37 } from "fs";
|
|
83375
|
+
import { join as join54 } from "path";
|
|
83129
83376
|
async function detectLibraries(page, capturedShaders) {
|
|
83130
83377
|
let detectedLibraries = [];
|
|
83131
83378
|
try {
|
|
@@ -83245,7 +83492,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
83245
83492
|
try {
|
|
83246
83493
|
const { GoogleGenAI: GoogleGenAI2 } = await Promise.resolve().then(() => (init_node4(), node_exports));
|
|
83247
83494
|
const ai = new GoogleGenAI2({ apiKey: geminiKey });
|
|
83248
|
-
const imageFiles =
|
|
83495
|
+
const imageFiles = readdirSync20(join54(outputDir, "assets")).filter(
|
|
83249
83496
|
(f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
|
|
83250
83497
|
);
|
|
83251
83498
|
const model = process.env.HYPERFRAMES_GEMINI_MODEL || "gemini-3.1-flash-lite-preview";
|
|
@@ -83254,8 +83501,8 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
83254
83501
|
const batch = imageFiles.slice(i2, i2 + BATCH_SIZE);
|
|
83255
83502
|
const results = await Promise.allSettled(
|
|
83256
83503
|
batch.map(async (file) => {
|
|
83257
|
-
const filePath =
|
|
83258
|
-
const stat3 =
|
|
83504
|
+
const filePath = join54(outputDir, "assets", file);
|
|
83505
|
+
const stat3 = statSync22(filePath);
|
|
83259
83506
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
83260
83507
|
const buffer = readFileSync37(filePath);
|
|
83261
83508
|
const base64 = buffer.toString("base64");
|
|
@@ -83303,12 +83550,12 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
83303
83550
|
const uncaptionedLines = [];
|
|
83304
83551
|
const svgLines = [];
|
|
83305
83552
|
const fontLines = [];
|
|
83306
|
-
const assetsPath =
|
|
83553
|
+
const assetsPath = join54(outputDir, "assets");
|
|
83307
83554
|
try {
|
|
83308
|
-
for (const file of
|
|
83555
|
+
for (const file of readdirSync20(assetsPath)) {
|
|
83309
83556
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
83310
|
-
const filePath =
|
|
83311
|
-
const stat3 =
|
|
83557
|
+
const filePath = join54(assetsPath, file);
|
|
83558
|
+
const stat3 = statSync22(filePath);
|
|
83312
83559
|
if (!stat3.isFile()) continue;
|
|
83313
83560
|
const sizeKb = Math.round(stat3.size / 1024);
|
|
83314
83561
|
const catalogMatch = catalogedAssets.find(
|
|
@@ -83336,8 +83583,8 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
83336
83583
|
} catch {
|
|
83337
83584
|
}
|
|
83338
83585
|
try {
|
|
83339
|
-
const svgsPath =
|
|
83340
|
-
for (const file of
|
|
83586
|
+
const svgsPath = join54(assetsPath, "svgs");
|
|
83587
|
+
for (const file of readdirSync20(svgsPath)) {
|
|
83341
83588
|
if (!file.endsWith(".svg")) continue;
|
|
83342
83589
|
const svgMatch = tokens.svgs.find(
|
|
83343
83590
|
(s2) => s2.label && file.includes(
|
|
@@ -83351,8 +83598,8 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
83351
83598
|
} catch {
|
|
83352
83599
|
}
|
|
83353
83600
|
try {
|
|
83354
|
-
const fontsPath =
|
|
83355
|
-
for (const file of
|
|
83601
|
+
const fontsPath = join54(assetsPath, "fonts");
|
|
83602
|
+
for (const file of readdirSync20(fontsPath)) {
|
|
83356
83603
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
83357
83604
|
}
|
|
83358
83605
|
} catch {
|
|
@@ -83371,12 +83618,12 @@ __export(agentPromptGenerator_exports, {
|
|
|
83371
83618
|
generateAgentPrompt: () => generateAgentPrompt
|
|
83372
83619
|
});
|
|
83373
83620
|
import { writeFileSync as writeFileSync21 } from "fs";
|
|
83374
|
-
import { join as
|
|
83621
|
+
import { join as join55 } from "path";
|
|
83375
83622
|
function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, detectedLibraries) {
|
|
83376
83623
|
const prompt = buildPrompt(url, tokens, hasScreenshot, hasLottie, hasShaders, detectedLibraries);
|
|
83377
|
-
writeFileSync21(
|
|
83378
|
-
writeFileSync21(
|
|
83379
|
-
writeFileSync21(
|
|
83624
|
+
writeFileSync21(join55(outputDir, "AGENTS.md"), prompt, "utf-8");
|
|
83625
|
+
writeFileSync21(join55(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
|
83626
|
+
writeFileSync21(join55(outputDir, ".cursorrules"), prompt, "utf-8");
|
|
83380
83627
|
}
|
|
83381
83628
|
function buildPrompt(url, tokens, hasScreenshot, hasLottie, hasShaders, detectedLibraries) {
|
|
83382
83629
|
const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -83443,8 +83690,8 @@ var init_agentPromptGenerator = __esm({
|
|
|
83443
83690
|
});
|
|
83444
83691
|
|
|
83445
83692
|
// src/capture/scaffolding.ts
|
|
83446
|
-
import { existsSync as
|
|
83447
|
-
import { join as
|
|
83693
|
+
import { existsSync as existsSync52, writeFileSync as writeFileSync22, readFileSync as readFileSync38 } from "fs";
|
|
83694
|
+
import { join as join56, resolve as resolve37 } from "path";
|
|
83448
83695
|
function loadEnvFile(startDir) {
|
|
83449
83696
|
try {
|
|
83450
83697
|
let dir = resolve37(startDir);
|
|
@@ -83470,8 +83717,8 @@ function loadEnvFile(startDir) {
|
|
|
83470
83717
|
}
|
|
83471
83718
|
}
|
|
83472
83719
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
83473
|
-
const metaPath =
|
|
83474
|
-
if (!
|
|
83720
|
+
const metaPath = join56(outputDir, "meta.json");
|
|
83721
|
+
if (!existsSync52(metaPath)) {
|
|
83475
83722
|
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
83476
83723
|
writeFileSync22(
|
|
83477
83724
|
metaPath,
|
|
@@ -83509,9 +83756,9 @@ __export(screenshotCapture_exports, {
|
|
|
83509
83756
|
captureScrollScreenshots: () => captureScrollScreenshots
|
|
83510
83757
|
});
|
|
83511
83758
|
import { writeFileSync as writeFileSync23, mkdirSync as mkdirSync28 } from "fs";
|
|
83512
|
-
import { join as
|
|
83759
|
+
import { join as join57 } from "path";
|
|
83513
83760
|
async function captureScrollScreenshots(page, outputDir) {
|
|
83514
|
-
const screenshotsDir =
|
|
83761
|
+
const screenshotsDir = join57(outputDir, "screenshots");
|
|
83515
83762
|
mkdirSync28(screenshotsDir, { recursive: true });
|
|
83516
83763
|
const MAX_SCREENSHOTS = 20;
|
|
83517
83764
|
const filePaths = [];
|
|
@@ -83545,7 +83792,7 @@ async function captureScrollScreenshots(page, outputDir) {
|
|
|
83545
83792
|
finalPositions[i2] / Math.max(1, scrollHeight - viewportHeight) * 100
|
|
83546
83793
|
);
|
|
83547
83794
|
const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
|
|
83548
|
-
const filePath =
|
|
83795
|
+
const filePath = join57(screenshotsDir, filename);
|
|
83549
83796
|
const buffer = await page.screenshot({ type: "png" });
|
|
83550
83797
|
writeFileSync23(filePath, buffer);
|
|
83551
83798
|
filePaths.push(`screenshots/${filename}`);
|
|
@@ -83858,8 +84105,8 @@ var capture_exports = {};
|
|
|
83858
84105
|
__export(capture_exports, {
|
|
83859
84106
|
captureWebsite: () => captureWebsite
|
|
83860
84107
|
});
|
|
83861
|
-
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync24, existsSync as
|
|
83862
|
-
import { join as
|
|
84108
|
+
import { mkdirSync as mkdirSync29, writeFileSync as writeFileSync24, existsSync as existsSync53 } from "fs";
|
|
84109
|
+
import { join as join58 } from "path";
|
|
83863
84110
|
async function captureWebsite(opts, onProgress) {
|
|
83864
84111
|
const {
|
|
83865
84112
|
url,
|
|
@@ -83876,9 +84123,9 @@ async function captureWebsite(opts, onProgress) {
|
|
|
83876
84123
|
onProgress?.(stage, detail);
|
|
83877
84124
|
};
|
|
83878
84125
|
loadEnvFile(outputDir);
|
|
83879
|
-
mkdirSync29(
|
|
83880
|
-
mkdirSync29(
|
|
83881
|
-
mkdirSync29(
|
|
84126
|
+
mkdirSync29(join58(outputDir, "extracted"), { recursive: true });
|
|
84127
|
+
mkdirSync29(join58(outputDir, "screenshots"), { recursive: true });
|
|
84128
|
+
mkdirSync29(join58(outputDir, "assets"), { recursive: true });
|
|
83882
84129
|
progress("browser", "Launching headless Chrome...");
|
|
83883
84130
|
const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
|
|
83884
84131
|
const browser = await ensureBrowser2();
|
|
@@ -84034,7 +84281,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84034
84281
|
} catch {
|
|
84035
84282
|
}
|
|
84036
84283
|
if (discoveredLotties.length > 0) {
|
|
84037
|
-
const lottieDir =
|
|
84284
|
+
const lottieDir = join58(outputDir, "assets", "lottie");
|
|
84038
84285
|
mkdirSync29(lottieDir, { recursive: true });
|
|
84039
84286
|
const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir);
|
|
84040
84287
|
if (savedCount > 0) {
|
|
@@ -84054,7 +84301,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84054
84301
|
});
|
|
84055
84302
|
capturedShaders = unique;
|
|
84056
84303
|
writeFileSync24(
|
|
84057
|
-
|
|
84304
|
+
join58(outputDir, "extracted", "shaders.json"),
|
|
84058
84305
|
JSON.stringify(unique, null, 2),
|
|
84059
84306
|
"utf-8"
|
|
84060
84307
|
);
|
|
@@ -84065,7 +84312,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84065
84312
|
progress("tokens", "Extracting design tokens...");
|
|
84066
84313
|
const tokens = await extractTokens(page1);
|
|
84067
84314
|
writeFileSync24(
|
|
84068
|
-
|
|
84315
|
+
join58(outputDir, "extracted", "tokens.json"),
|
|
84069
84316
|
JSON.stringify(tokens, null, 2),
|
|
84070
84317
|
"utf-8"
|
|
84071
84318
|
);
|
|
@@ -84139,7 +84386,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84139
84386
|
representativeAnimations: representativeAnims
|
|
84140
84387
|
};
|
|
84141
84388
|
writeFileSync24(
|
|
84142
|
-
|
|
84389
|
+
join58(outputDir, "extracted", "animations.json"),
|
|
84143
84390
|
JSON.stringify(leanCatalog, null, 2),
|
|
84144
84391
|
"utf-8"
|
|
84145
84392
|
);
|
|
@@ -84150,18 +84397,18 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84150
84397
|
assets = await downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks);
|
|
84151
84398
|
}
|
|
84152
84399
|
if (visibleTextContent) {
|
|
84153
|
-
writeFileSync24(
|
|
84400
|
+
writeFileSync24(join58(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
|
|
84154
84401
|
}
|
|
84155
84402
|
if (catalogedAssets.length > 0) {
|
|
84156
84403
|
writeFileSync24(
|
|
84157
|
-
|
|
84404
|
+
join58(outputDir, "extracted", "assets-catalog.json"),
|
|
84158
84405
|
JSON.stringify(catalogedAssets, null, 2),
|
|
84159
84406
|
"utf-8"
|
|
84160
84407
|
);
|
|
84161
84408
|
}
|
|
84162
84409
|
if (detectedLibraries.length > 0) {
|
|
84163
84410
|
writeFileSync24(
|
|
84164
|
-
|
|
84411
|
+
join58(outputDir, "extracted", "detected-libraries.json"),
|
|
84165
84412
|
JSON.stringify(detectedLibraries, null, 2),
|
|
84166
84413
|
"utf-8"
|
|
84167
84414
|
);
|
|
@@ -84172,7 +84419,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84172
84419
|
const lines = generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCaptions);
|
|
84173
84420
|
if (lines.length > 0) {
|
|
84174
84421
|
writeFileSync24(
|
|
84175
|
-
|
|
84422
|
+
join58(outputDir, "extracted", "asset-descriptions.md"),
|
|
84176
84423
|
"# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\n" + lines.map((l) => "- " + l).join("\n") + "\n",
|
|
84177
84424
|
"utf-8"
|
|
84178
84425
|
);
|
|
@@ -84188,7 +84435,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
84188
84435
|
animationCatalog,
|
|
84189
84436
|
screenshots.length > 0,
|
|
84190
84437
|
discoveredLotties.length > 0,
|
|
84191
|
-
|
|
84438
|
+
existsSync53(join58(outputDir, "extracted", "shaders.json")),
|
|
84192
84439
|
catalogedAssets,
|
|
84193
84440
|
progress,
|
|
84194
84441
|
warnings,
|
|
@@ -84536,8 +84783,8 @@ __export(autoUpdate_exports, {
|
|
|
84536
84783
|
});
|
|
84537
84784
|
import { spawn as spawn12 } from "child_process";
|
|
84538
84785
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync30, openSync } from "fs";
|
|
84539
|
-
import { homedir as
|
|
84540
|
-
import { join as
|
|
84786
|
+
import { homedir as homedir11 } from "os";
|
|
84787
|
+
import { join as join59 } from "path";
|
|
84541
84788
|
import { compareVersions as compareVersions2 } from "compare-versions";
|
|
84542
84789
|
function isAutoInstallDisabled() {
|
|
84543
84790
|
if (isDevMode()) return true;
|
|
@@ -84560,7 +84807,7 @@ function log(line) {
|
|
|
84560
84807
|
}
|
|
84561
84808
|
function launchDetachedInstall(installCommand, version) {
|
|
84562
84809
|
mkdirSync30(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
84563
|
-
const configFile =
|
|
84810
|
+
const configFile = join59(CONFIG_DIR2, "config.json");
|
|
84564
84811
|
const nodeScript = `
|
|
84565
84812
|
const { exec } = require("node:child_process");
|
|
84566
84813
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -84679,8 +84926,8 @@ var init_autoUpdate = __esm({
|
|
|
84679
84926
|
init_config();
|
|
84680
84927
|
init_env();
|
|
84681
84928
|
init_installerDetection();
|
|
84682
|
-
CONFIG_DIR2 =
|
|
84683
|
-
LOG_FILE =
|
|
84929
|
+
CONFIG_DIR2 = join59(homedir11(), ".hyperframes");
|
|
84930
|
+
LOG_FILE = join59(CONFIG_DIR2, "auto-update.log");
|
|
84684
84931
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
84685
84932
|
}
|
|
84686
84933
|
});
|