hyperframes 0.6.36 → 0.6.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -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.6.
|
|
57
|
+
VERSION = true ? "0.6.38" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -11365,9 +11365,173 @@ var init_env = __esm({
|
|
|
11365
11365
|
}
|
|
11366
11366
|
});
|
|
11367
11367
|
|
|
11368
|
+
// src/telemetry/platform.ts
|
|
11369
|
+
import { platform, release } from "os";
|
|
11370
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
11371
|
+
function detectWSL() {
|
|
11372
|
+
if (platform() !== "linux") return false;
|
|
11373
|
+
try {
|
|
11374
|
+
const osRelease = release().toLowerCase();
|
|
11375
|
+
if (osRelease.includes("microsoft") || osRelease.includes("wsl")) return true;
|
|
11376
|
+
const procVersion = readFileSync4("/proc/version", "utf-8").toLowerCase();
|
|
11377
|
+
return procVersion.includes("microsoft") || procVersion.includes("wsl");
|
|
11378
|
+
} catch {
|
|
11379
|
+
return false;
|
|
11380
|
+
}
|
|
11381
|
+
}
|
|
11382
|
+
var init_platform = __esm({
|
|
11383
|
+
"src/telemetry/platform.ts"() {
|
|
11384
|
+
"use strict";
|
|
11385
|
+
}
|
|
11386
|
+
});
|
|
11387
|
+
|
|
11388
|
+
// src/telemetry/agent_runtime.ts
|
|
11389
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
|
|
11390
|
+
import { platform as platform2, release as release2 } from "os";
|
|
11391
|
+
function detectSandboxRuntime() {
|
|
11392
|
+
if (platform2() === "win32") return null;
|
|
11393
|
+
if (detectWSL()) return "wsl";
|
|
11394
|
+
if (isGVisor()) return "gvisor";
|
|
11395
|
+
if (isDocker()) return "docker";
|
|
11396
|
+
if (isFirecracker()) return "firecracker";
|
|
11397
|
+
if (isKVM()) return "kvm";
|
|
11398
|
+
return null;
|
|
11399
|
+
}
|
|
11400
|
+
function detectAgentRuntime() {
|
|
11401
|
+
for (const rule of VENDOR_RULES) {
|
|
11402
|
+
if (rule.check(process.env)) return rule.name;
|
|
11403
|
+
}
|
|
11404
|
+
return null;
|
|
11405
|
+
}
|
|
11406
|
+
function isGVisor() {
|
|
11407
|
+
const kernel = release2();
|
|
11408
|
+
if (kernel.includes("gvisor")) return true;
|
|
11409
|
+
if (platform2() !== "linux") return false;
|
|
11410
|
+
try {
|
|
11411
|
+
const procVersion = readFileSync5("/proc/version", "utf-8");
|
|
11412
|
+
return procVersion.includes("gVisor");
|
|
11413
|
+
} catch {
|
|
11414
|
+
return false;
|
|
11415
|
+
}
|
|
11416
|
+
}
|
|
11417
|
+
function isDocker() {
|
|
11418
|
+
if (existsSync4("/.dockerenv")) return true;
|
|
11419
|
+
if (platform2() !== "linux") return false;
|
|
11420
|
+
try {
|
|
11421
|
+
const cgroup = readFileSync5("/proc/1/cgroup", "utf-8");
|
|
11422
|
+
return cgroup.includes("docker") || cgroup.includes("containerd");
|
|
11423
|
+
} catch {
|
|
11424
|
+
return false;
|
|
11425
|
+
}
|
|
11426
|
+
}
|
|
11427
|
+
function isFirecracker() {
|
|
11428
|
+
if (platform2() !== "linux") return false;
|
|
11429
|
+
if (!existsSync4("/dev/vsock")) return false;
|
|
11430
|
+
try {
|
|
11431
|
+
const sysVendor = readFileSync5("/sys/class/dmi/id/sys_vendor", "utf-8").trim();
|
|
11432
|
+
if (sysVendor !== "Amazon EC2") return false;
|
|
11433
|
+
const productName = readFileSync5("/sys/class/dmi/id/product_name", "utf-8").trim();
|
|
11434
|
+
return productName.toLowerCase().includes("firecracker");
|
|
11435
|
+
} catch {
|
|
11436
|
+
return false;
|
|
11437
|
+
}
|
|
11438
|
+
}
|
|
11439
|
+
function isKVM() {
|
|
11440
|
+
if (platform2() !== "linux") return false;
|
|
11441
|
+
try {
|
|
11442
|
+
const sysVendor = readFileSync5("/sys/class/dmi/id/sys_vendor", "utf-8").trim();
|
|
11443
|
+
return sysVendor === "QEMU" || sysVendor.includes("KVM");
|
|
11444
|
+
} catch {
|
|
11445
|
+
return false;
|
|
11446
|
+
}
|
|
11447
|
+
}
|
|
11448
|
+
var VENDOR_RULES;
|
|
11449
|
+
var init_agent_runtime = __esm({
|
|
11450
|
+
"src/telemetry/agent_runtime.ts"() {
|
|
11451
|
+
"use strict";
|
|
11452
|
+
init_platform();
|
|
11453
|
+
VENDOR_RULES = [
|
|
11454
|
+
// Anthropic Claude Code — sets CLAUDECODE=1 on every Bash/PowerShell tool
|
|
11455
|
+
// spawn (Shell.ts:321) and CLAUDE_CODE_ENTRYPOINT at startup, inherited by
|
|
11456
|
+
// every child (main.tsx:527). Both propagate to spawned subprocesses.
|
|
11457
|
+
// Source: confirmed by @magi from Claude Code internal source.
|
|
11458
|
+
{
|
|
11459
|
+
name: "claude_code",
|
|
11460
|
+
check: (env) => typeof env["CLAUDECODE"] === "string" || typeof env["CLAUDE_CODE_ENTRYPOINT"] === "string"
|
|
11461
|
+
},
|
|
11462
|
+
// OpenAI Codex (https://github.com/openai/codex).
|
|
11463
|
+
// - CODEX_THREAD_ID — set unconditionally on every spawned shell command
|
|
11464
|
+
// (codex-rs/protocol/src/shell_environment.rs:6 constant, set by
|
|
11465
|
+
// codex-rs/core/src/unified_exec/process_manager.rs:1010 and
|
|
11466
|
+
// codex-rs/core/src/tools/runtimes/mod.rs:164).
|
|
11467
|
+
// - CODEX_CI — hardcoded in the UNIFIED_EXEC_ENV array, always set on
|
|
11468
|
+
// every unified-exec child (process_manager.rs:70).
|
|
11469
|
+
// - CODEX_SANDBOX_NETWORK_DISABLED — set when network sandbox is active
|
|
11470
|
+
// (codex-rs/core/src/sandboxing/mod.rs:135-138, default-on).
|
|
11471
|
+
// CODEX_HOME is deliberately NOT used — it's a config override read at
|
|
11472
|
+
// Codex startup, not propagated to spawned subprocesses.
|
|
11473
|
+
{
|
|
11474
|
+
name: "codex",
|
|
11475
|
+
check: (env) => typeof env["CODEX_THREAD_ID"] === "string" || typeof env["CODEX_CI"] === "string" || typeof env["CODEX_SANDBOX_NETWORK_DISABLED"] === "string"
|
|
11476
|
+
},
|
|
11477
|
+
// Cursor IDE integrated terminal — exports TERM_PROGRAM=cursor.
|
|
11478
|
+
// Cursor Background Agent env vars are not publicly documented; if a
|
|
11479
|
+
// canonical marker is identified later, add it here.
|
|
11480
|
+
{
|
|
11481
|
+
name: "cursor",
|
|
11482
|
+
check: (env) => env["TERM_PROGRAM"] === "cursor"
|
|
11483
|
+
},
|
|
11484
|
+
// GitHub Copilot Coding Agent — runs inside GitHub Actions and the
|
|
11485
|
+
// workflow injects an additional marker to distinguish from generic CI.
|
|
11486
|
+
// Not yet verified from a public-source citation in this audit; the var
|
|
11487
|
+
// names below match GitHub Copilot Coding Agent documentation but
|
|
11488
|
+
// should be confirmed before relying on attribution.
|
|
11489
|
+
{
|
|
11490
|
+
name: "copilot_agent",
|
|
11491
|
+
check: (env) => env["GITHUB_ACTIONS"] === "true" && (typeof env["COPILOT_AGENT_ID"] === "string" || env["RUNNER_NAME"] === "Copilot")
|
|
11492
|
+
},
|
|
11493
|
+
// Replit — REPL_ID and REPLIT_USER are long-documented environment
|
|
11494
|
+
// variables exposed inside every Replit workspace.
|
|
11495
|
+
// Source: https://docs.replit.com/replit-workspace/configuring-the-environment
|
|
11496
|
+
{
|
|
11497
|
+
name: "replit",
|
|
11498
|
+
check: (env) => typeof env["REPL_ID"] === "string" || typeof env["REPLIT_USER"] === "string"
|
|
11499
|
+
},
|
|
11500
|
+
// Nous Research Hermes Agent — cli.py:50 unconditionally executes
|
|
11501
|
+
// os.environ["HERMES_QUIET"] = "1"
|
|
11502
|
+
// at module load, so the marker propagates via os.environ to every
|
|
11503
|
+
// subprocess spawned by Hermes. Keying on existence (not the literal
|
|
11504
|
+
// "1") so we still match if Hermes ever changes the value.
|
|
11505
|
+
// Source: https://github.com/NousResearch/hermes-agent (cli.py:50)
|
|
11506
|
+
{
|
|
11507
|
+
name: "hermes",
|
|
11508
|
+
check: (env) => typeof env["HERMES_QUIET"] === "string"
|
|
11509
|
+
},
|
|
11510
|
+
// openclaw — multi-channel AI gateway. When openclaw spawns a CLI
|
|
11511
|
+
// subprocess it builds the child env with OPENCLAW_STATE_DIR /
|
|
11512
|
+
// OPENCLAW_CONFIG_PATH / OPENCLAW_DISABLE_AUTO_UPDATE set explicitly
|
|
11513
|
+
// (extensions/qa-matrix/src/runners/contract/scenario-runtime-cli.ts:344-351).
|
|
11514
|
+
// We key on OPENCLAW_STATE_DIR since it's a path scope-bound to openclaw.
|
|
11515
|
+
// Source: https://github.com/openclaw/openclaw
|
|
11516
|
+
{
|
|
11517
|
+
name: "openclaw",
|
|
11518
|
+
check: (env) => typeof env["OPENCLAW_STATE_DIR"] === "string" || typeof env["OPENCLAW_CONFIG_PATH"] === "string"
|
|
11519
|
+
},
|
|
11520
|
+
// Pi coding agent (https://pi.dev, https://github.com/earendil-works/pi).
|
|
11521
|
+
// packages/coding-agent/src/cli.ts:13 unconditionally executes
|
|
11522
|
+
// process.env.PI_CODING_AGENT = "true";
|
|
11523
|
+
// at module entry, so every subprocess Pi spawns sees this marker.
|
|
11524
|
+
{
|
|
11525
|
+
name: "pi",
|
|
11526
|
+
check: (env) => typeof env["PI_CODING_AGENT"] === "string"
|
|
11527
|
+
}
|
|
11528
|
+
];
|
|
11529
|
+
}
|
|
11530
|
+
});
|
|
11531
|
+
|
|
11368
11532
|
// src/telemetry/system.ts
|
|
11369
|
-
import { cpus, totalmem, platform, release } from "os";
|
|
11370
|
-
import { existsSync as
|
|
11533
|
+
import { cpus, totalmem, platform as platform3, release as release3 } from "os";
|
|
11534
|
+
import { existsSync as existsSync5, readFileSync as readFileSync6, statfsSync } from "fs";
|
|
11371
11535
|
function bytesToMb(bytes) {
|
|
11372
11536
|
return Math.trunc(bytes / (1024 * 1024));
|
|
11373
11537
|
}
|
|
@@ -11376,7 +11540,7 @@ function getSystemMeta() {
|
|
|
11376
11540
|
const cpuInfo = cpus();
|
|
11377
11541
|
const firstCpu = cpuInfo[0] ?? null;
|
|
11378
11542
|
cached = {
|
|
11379
|
-
os_release:
|
|
11543
|
+
os_release: release3(),
|
|
11380
11544
|
cpu_count: cpuInfo.length,
|
|
11381
11545
|
cpu_model: firstCpu?.model?.trim() ?? null,
|
|
11382
11546
|
cpu_speed: firstCpu?.speed ?? null,
|
|
@@ -11385,47 +11549,39 @@ function getSystemMeta() {
|
|
|
11385
11549
|
is_ci: detectCI(),
|
|
11386
11550
|
ci_name: getCIName(),
|
|
11387
11551
|
is_wsl: detectWSL(),
|
|
11388
|
-
is_tty: Boolean(process.stdout?.isTTY)
|
|
11552
|
+
is_tty: Boolean(process.stdout?.isTTY),
|
|
11553
|
+
sandbox_runtime: detectSandboxRuntime(),
|
|
11554
|
+
agent_runtime: detectAgentRuntime()
|
|
11389
11555
|
};
|
|
11390
11556
|
return cached;
|
|
11391
11557
|
}
|
|
11392
11558
|
function detectDocker() {
|
|
11393
11559
|
try {
|
|
11394
|
-
if (
|
|
11395
|
-
if (
|
|
11396
|
-
const cgroup =
|
|
11560
|
+
if (existsSync5("/.dockerenv")) return true;
|
|
11561
|
+
if (platform3() === "linux") {
|
|
11562
|
+
const cgroup = readFileSync6("/proc/1/cgroup", "utf-8");
|
|
11397
11563
|
if (cgroup.includes("docker") || cgroup.includes("containerd")) return true;
|
|
11398
11564
|
}
|
|
11399
11565
|
} catch {
|
|
11400
11566
|
}
|
|
11401
11567
|
return false;
|
|
11402
11568
|
}
|
|
11569
|
+
function matchesProvider(p2) {
|
|
11570
|
+
const v2 = process.env[p2.envVar];
|
|
11571
|
+
if (p2.mode === "presence") return v2 != null;
|
|
11572
|
+
return v2 === "true" || v2 === "1";
|
|
11573
|
+
}
|
|
11403
11574
|
function detectCI() {
|
|
11404
|
-
return
|
|
11575
|
+
return CI_PROVIDERS.some(matchesProvider);
|
|
11405
11576
|
}
|
|
11406
11577
|
function getCIName() {
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
if (process.env["CIRCLECI"] === "true") return "circleci";
|
|
11410
|
-
if (process.env["JENKINS_URL"] != null) return "jenkins";
|
|
11411
|
-
if (process.env["BUILDKITE"] === "true") return "buildkite";
|
|
11412
|
-
if (process.env["TRAVIS"] === "true") return "travis";
|
|
11413
|
-
if (detectCI()) return "unknown";
|
|
11414
|
-
return null;
|
|
11415
|
-
}
|
|
11416
|
-
function detectWSL() {
|
|
11417
|
-
if (platform() !== "linux") return false;
|
|
11418
|
-
try {
|
|
11419
|
-
const osRelease = release().toLowerCase();
|
|
11420
|
-
if (osRelease.includes("microsoft") || osRelease.includes("wsl")) return true;
|
|
11421
|
-
const procVersion = readFileSync4("/proc/version", "utf-8").toLowerCase();
|
|
11422
|
-
return procVersion.includes("microsoft") || procVersion.includes("wsl");
|
|
11423
|
-
} catch {
|
|
11424
|
-
return false;
|
|
11578
|
+
for (const provider of CI_PROVIDERS) {
|
|
11579
|
+
if (provider.name && matchesProvider(provider)) return provider.name;
|
|
11425
11580
|
}
|
|
11581
|
+
return detectCI() ? "unknown" : null;
|
|
11426
11582
|
}
|
|
11427
11583
|
function getShmSizeMb() {
|
|
11428
|
-
if (
|
|
11584
|
+
if (platform3() !== "linux") return null;
|
|
11429
11585
|
try {
|
|
11430
11586
|
const stats = statfsSync("/dev/shm");
|
|
11431
11587
|
return bytesToMb(stats.bsize * stats.blocks);
|
|
@@ -11441,11 +11597,23 @@ function getFreeDiskMb(path2 = ".") {
|
|
|
11441
11597
|
return null;
|
|
11442
11598
|
}
|
|
11443
11599
|
}
|
|
11444
|
-
var cached;
|
|
11600
|
+
var cached, CI_PROVIDERS;
|
|
11445
11601
|
var init_system = __esm({
|
|
11446
11602
|
"src/telemetry/system.ts"() {
|
|
11447
11603
|
"use strict";
|
|
11604
|
+
init_agent_runtime();
|
|
11605
|
+
init_platform();
|
|
11448
11606
|
cached = null;
|
|
11607
|
+
CI_PROVIDERS = [
|
|
11608
|
+
{ name: "github_actions", envVar: "GITHUB_ACTIONS", mode: "truthy" },
|
|
11609
|
+
{ name: "gitlab_ci", envVar: "GITLAB_CI", mode: "truthy" },
|
|
11610
|
+
{ name: "circleci", envVar: "CIRCLECI", mode: "truthy" },
|
|
11611
|
+
{ name: "jenkins", envVar: "JENKINS_URL", mode: "presence" },
|
|
11612
|
+
{ name: "buildkite", envVar: "BUILDKITE", mode: "truthy" },
|
|
11613
|
+
{ name: "travis", envVar: "TRAVIS", mode: "truthy" },
|
|
11614
|
+
{ name: null, envVar: "CONTINUOUS_INTEGRATION", mode: "truthy" },
|
|
11615
|
+
{ name: null, envVar: "CI", mode: "truthy" }
|
|
11616
|
+
];
|
|
11449
11617
|
}
|
|
11450
11618
|
});
|
|
11451
11619
|
|
|
@@ -11488,32 +11656,35 @@ function trackEvent(event, properties = {}) {
|
|
|
11488
11656
|
is_ci: sys.is_ci,
|
|
11489
11657
|
ci_name: sys.ci_name ?? void 0,
|
|
11490
11658
|
is_wsl: sys.is_wsl,
|
|
11491
|
-
is_tty: sys.is_tty
|
|
11659
|
+
is_tty: sys.is_tty,
|
|
11660
|
+
sandbox_runtime: sys.sandbox_runtime ?? void 0,
|
|
11661
|
+
agent_runtime: sys.agent_runtime ?? void 0
|
|
11492
11662
|
},
|
|
11493
11663
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
11494
11664
|
});
|
|
11495
11665
|
}
|
|
11496
|
-
|
|
11497
|
-
if (eventQueue.length === 0)
|
|
11498
|
-
return;
|
|
11499
|
-
}
|
|
11666
|
+
function drainQueueToPayload() {
|
|
11667
|
+
if (eventQueue.length === 0) return null;
|
|
11500
11668
|
const config = readConfig();
|
|
11501
11669
|
const batch = eventQueue.map((e3) => ({
|
|
11502
11670
|
event: e3.event,
|
|
11503
|
-
// $ip: null tells PostHog to not record the request IP for this event.
|
|
11504
|
-
// Server-side "Discard client IP data" is also enabled in project settings.
|
|
11505
11671
|
properties: { ...e3.properties, $ip: null },
|
|
11506
11672
|
distinct_id: config.anonymousId,
|
|
11507
11673
|
timestamp: e3.timestamp
|
|
11508
11674
|
}));
|
|
11509
11675
|
eventQueue = [];
|
|
11676
|
+
return JSON.stringify({ api_key: POSTHOG_API_KEY, batch });
|
|
11677
|
+
}
|
|
11678
|
+
async function flush() {
|
|
11679
|
+
const payload = drainQueueToPayload();
|
|
11680
|
+
if (payload == null) return;
|
|
11510
11681
|
const controller = new AbortController();
|
|
11511
11682
|
const timeout = setTimeout(() => controller.abort(), FLUSH_TIMEOUT_MS);
|
|
11512
11683
|
try {
|
|
11513
11684
|
await fetch(`${POSTHOG_HOST}/batch/`, {
|
|
11514
11685
|
method: "POST",
|
|
11515
11686
|
headers: { "Content-Type": "application/json", Connection: "close" },
|
|
11516
|
-
body:
|
|
11687
|
+
body: payload,
|
|
11517
11688
|
signal: controller.signal
|
|
11518
11689
|
});
|
|
11519
11690
|
} catch {
|
|
@@ -11522,18 +11693,8 @@ async function flush() {
|
|
|
11522
11693
|
}
|
|
11523
11694
|
}
|
|
11524
11695
|
function flushSync() {
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
}
|
|
11528
|
-
const config = readConfig();
|
|
11529
|
-
const batch = eventQueue.map((e3) => ({
|
|
11530
|
-
event: e3.event,
|
|
11531
|
-
properties: { ...e3.properties, $ip: null },
|
|
11532
|
-
distinct_id: config.anonymousId,
|
|
11533
|
-
timestamp: e3.timestamp
|
|
11534
|
-
}));
|
|
11535
|
-
eventQueue = [];
|
|
11536
|
-
const payload = JSON.stringify({ api_key: POSTHOG_API_KEY, batch });
|
|
11696
|
+
const payload = drainQueueToPayload();
|
|
11697
|
+
if (payload == null) return;
|
|
11537
11698
|
try {
|
|
11538
11699
|
const { spawn: spawn17 } = __require("child_process");
|
|
11539
11700
|
const child = spawn17(
|
|
@@ -11708,8 +11869,8 @@ __export(manager_exports, {
|
|
|
11708
11869
|
hasFFprobe: () => hasFFprobe
|
|
11709
11870
|
});
|
|
11710
11871
|
import { execFileSync } from "child_process";
|
|
11711
|
-
import { existsSync as
|
|
11712
|
-
import { homedir as homedir3, platform as
|
|
11872
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, rmSync } from "fs";
|
|
11873
|
+
import { homedir as homedir3, platform as platform4 } from "os";
|
|
11713
11874
|
import { join as join5 } from "path";
|
|
11714
11875
|
function getModelUrl(model) {
|
|
11715
11876
|
return `https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-${model}.bin`;
|
|
@@ -11730,7 +11891,7 @@ function whichBinary(name) {
|
|
|
11730
11891
|
}
|
|
11731
11892
|
function findFromEnv() {
|
|
11732
11893
|
const envPath = process.env["HYPERFRAMES_WHISPER_PATH"];
|
|
11733
|
-
if (envPath &&
|
|
11894
|
+
if (envPath && existsSync6(envPath)) {
|
|
11734
11895
|
return { executablePath: envPath, source: "env" };
|
|
11735
11896
|
}
|
|
11736
11897
|
return void 0;
|
|
@@ -11740,9 +11901,9 @@ function findFromSystem() {
|
|
|
11740
11901
|
const path2 = whichBinary(name);
|
|
11741
11902
|
if (path2) return { executablePath: path2, source: "system" };
|
|
11742
11903
|
}
|
|
11743
|
-
if (
|
|
11904
|
+
if (platform4() === "darwin") {
|
|
11744
11905
|
for (const p2 of ["/opt/homebrew/bin/whisper-cli", "/usr/local/bin/whisper-cli"]) {
|
|
11745
|
-
if (
|
|
11906
|
+
if (existsSync6(p2)) return { executablePath: p2, source: "system" };
|
|
11746
11907
|
}
|
|
11747
11908
|
}
|
|
11748
11909
|
return void 0;
|
|
@@ -11752,15 +11913,15 @@ function findBuiltBinary() {
|
|
|
11752
11913
|
join5(BUILD_DIR, "build", "bin", "whisper-cli"),
|
|
11753
11914
|
join5(BUILD_DIR, "build", "whisper-cli")
|
|
11754
11915
|
]) {
|
|
11755
|
-
if (
|
|
11916
|
+
if (existsSync6(p2)) return { executablePath: p2, source: "build" };
|
|
11756
11917
|
}
|
|
11757
11918
|
return void 0;
|
|
11758
11919
|
}
|
|
11759
11920
|
function buildFromSource(onProgress) {
|
|
11760
|
-
if (
|
|
11921
|
+
if (existsSync6(BUILD_DIR) && !findBuiltBinary()) {
|
|
11761
11922
|
rmSync(BUILD_DIR, { recursive: true, force: true });
|
|
11762
11923
|
}
|
|
11763
|
-
if (!
|
|
11924
|
+
if (!existsSync6(BUILD_DIR)) {
|
|
11764
11925
|
onProgress?.("Downloading whisper.cpp...");
|
|
11765
11926
|
mkdirSync3(join5(homedir3(), ".cache", "hyperframes", "whisper"), {
|
|
11766
11927
|
recursive: true
|
|
@@ -11803,7 +11964,7 @@ function findWhisper() {
|
|
|
11803
11964
|
return findFromEnv() ?? findFromSystem() ?? findBuiltBinary();
|
|
11804
11965
|
}
|
|
11805
11966
|
function getInstallInstructions() {
|
|
11806
|
-
if (
|
|
11967
|
+
if (platform4() === "darwin") {
|
|
11807
11968
|
return "brew install whisper-cpp";
|
|
11808
11969
|
}
|
|
11809
11970
|
return "See https://github.com/ggml-org/whisper.cpp#building";
|
|
@@ -11820,7 +11981,7 @@ function hasCmake() {
|
|
|
11820
11981
|
async function ensureWhisper(options) {
|
|
11821
11982
|
const existing = findWhisper();
|
|
11822
11983
|
if (existing) return existing;
|
|
11823
|
-
if (
|
|
11984
|
+
if (platform4() === "darwin" && hasBrew()) {
|
|
11824
11985
|
options?.onProgress?.("Installing whisper-cpp via Homebrew...");
|
|
11825
11986
|
try {
|
|
11826
11987
|
execFileSync("brew", ["install", "whisper-cpp"], {
|
|
@@ -11842,11 +12003,11 @@ async function ensureWhisper(options) {
|
|
|
11842
12003
|
}
|
|
11843
12004
|
async function ensureModel(model = DEFAULT_MODEL, options) {
|
|
11844
12005
|
const modelPath2 = join5(MODELS_DIR, `ggml-${model}.bin`);
|
|
11845
|
-
if (
|
|
12006
|
+
if (existsSync6(modelPath2)) return modelPath2;
|
|
11846
12007
|
mkdirSync3(MODELS_DIR, { recursive: true });
|
|
11847
12008
|
options?.onProgress?.(`Downloading model ${model}...`);
|
|
11848
12009
|
await downloadFile(getModelUrl(model), modelPath2);
|
|
11849
|
-
if (!
|
|
12010
|
+
if (!existsSync6(modelPath2)) {
|
|
11850
12011
|
throw new Error(`Model download failed: ${model}`);
|
|
11851
12012
|
}
|
|
11852
12013
|
return modelPath2;
|
|
@@ -11885,13 +12046,13 @@ __export(normalize_exports, {
|
|
|
11885
12046
|
patchCaptionHtml: () => patchCaptionHtml,
|
|
11886
12047
|
stripBeforeOnset: () => stripBeforeOnset
|
|
11887
12048
|
});
|
|
11888
|
-
import { readFileSync as
|
|
12049
|
+
import { readFileSync as readFileSync7, readdirSync, writeFileSync as writeFileSync4 } from "fs";
|
|
11889
12050
|
import { extname, join as join6 } from "path";
|
|
11890
12051
|
function detectFormat(filePath) {
|
|
11891
12052
|
const ext = extname(filePath).toLowerCase();
|
|
11892
12053
|
if (ext === ".srt") return "srt";
|
|
11893
12054
|
if (ext === ".vtt") return "vtt";
|
|
11894
|
-
if (ext === ".json") return detectJsonFormat(JSON.parse(
|
|
12055
|
+
if (ext === ".json") return detectJsonFormat(JSON.parse(readFileSync7(filePath, "utf-8")));
|
|
11895
12056
|
throw new Error(`Unsupported transcript file extension: ${ext}. Use .json, .srt, or .vtt`);
|
|
11896
12057
|
}
|
|
11897
12058
|
function detectJsonFormat(raw) {
|
|
@@ -12041,7 +12202,7 @@ function round3(n) {
|
|
|
12041
12202
|
}
|
|
12042
12203
|
function loadTranscript(filePath) {
|
|
12043
12204
|
const ext = extname(filePath).toLowerCase();
|
|
12044
|
-
const content =
|
|
12205
|
+
const content = readFileSync7(filePath, "utf-8");
|
|
12045
12206
|
if (ext === ".srt") {
|
|
12046
12207
|
const words2 = parseSrt(content).map((w3, i2) => ({ ...w3, id: w3.id ?? `w${i2}` }));
|
|
12047
12208
|
return { words: words2, format: "srt" };
|
|
@@ -12073,7 +12234,7 @@ function patchCaptionHtml(dir, words) {
|
|
|
12073
12234
|
return;
|
|
12074
12235
|
}
|
|
12075
12236
|
for (const file of htmlFiles) {
|
|
12076
|
-
let content =
|
|
12237
|
+
let content = readFileSync7(file, "utf-8");
|
|
12077
12238
|
const scriptBlocks = content.match(/<script>[\s\S]*?<\/script>/g) ?? [];
|
|
12078
12239
|
let scriptMatch = null;
|
|
12079
12240
|
let transcriptMatch = null;
|
|
@@ -12106,7 +12267,7 @@ __export(projectConfig_exports, {
|
|
|
12106
12267
|
readProjectConfig: () => readProjectConfig,
|
|
12107
12268
|
writeProjectConfig: () => writeProjectConfig
|
|
12108
12269
|
});
|
|
12109
|
-
import { readFileSync as
|
|
12270
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
12110
12271
|
import { join as join7, resolve as resolve4 } from "path";
|
|
12111
12272
|
function projectConfigPath(projectDir) {
|
|
12112
12273
|
return join7(resolve4(projectDir), PROJECT_CONFIG_FILENAME);
|
|
@@ -12114,7 +12275,7 @@ function projectConfigPath(projectDir) {
|
|
|
12114
12275
|
function readProjectConfig(projectDir) {
|
|
12115
12276
|
const path2 = projectConfigPath(projectDir);
|
|
12116
12277
|
try {
|
|
12117
|
-
const parsed = JSON.parse(
|
|
12278
|
+
const parsed = JSON.parse(readFileSync8(path2, "utf-8"));
|
|
12118
12279
|
return normalizeConfig(parsed);
|
|
12119
12280
|
} catch {
|
|
12120
12281
|
return void 0;
|
|
@@ -12164,7 +12325,7 @@ __export(transcribe_exports, {
|
|
|
12164
12325
|
transcribe: () => transcribe
|
|
12165
12326
|
});
|
|
12166
12327
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
12167
|
-
import { existsSync as
|
|
12328
|
+
import { existsSync as existsSync7, readFileSync as readFileSync9, mkdirSync as mkdirSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
12168
12329
|
import { join as join8, extname as extname2 } from "path";
|
|
12169
12330
|
import { tmpdir } from "os";
|
|
12170
12331
|
function detectLanguage(whisperPath, modelPath2, wavPath) {
|
|
@@ -12200,7 +12361,7 @@ function detectSpeechOnset(wavPath) {
|
|
|
12200
12361
|
const SILENCE_THRESHOLD_RATIO = 0.6;
|
|
12201
12362
|
const MIN_INTRO_SECONDS = 3;
|
|
12202
12363
|
try {
|
|
12203
|
-
const buf =
|
|
12364
|
+
const buf = readFileSync9(wavPath);
|
|
12204
12365
|
const dataChunk = findWavDataChunk(buf);
|
|
12205
12366
|
if (!dataChunk) return null;
|
|
12206
12367
|
const pcm = new Int16Array(buf.buffer, buf.byteOffset + dataChunk.offset, dataChunk.size / 2);
|
|
@@ -12338,10 +12499,10 @@ async function transcribe(inputPath, outputDir, options) {
|
|
|
12338
12499
|
whisperArgs.push(wavPath);
|
|
12339
12500
|
execFileSync2(whisper.executablePath, whisperArgs, { stdio: "ignore", timeout: 3e5 });
|
|
12340
12501
|
const transcriptPath = `${outputBase}.json`;
|
|
12341
|
-
if (!
|
|
12502
|
+
if (!existsSync7(transcriptPath)) {
|
|
12342
12503
|
throw new Error("Whisper did not produce output. Check the input file.");
|
|
12343
12504
|
}
|
|
12344
|
-
const transcript = JSON.parse(
|
|
12505
|
+
const transcript = JSON.parse(readFileSync9(transcriptPath, "utf-8"));
|
|
12345
12506
|
const segments = transcript.transcription ?? [];
|
|
12346
12507
|
let wordCount = 0;
|
|
12347
12508
|
let maxEnd = 0;
|
|
@@ -12492,7 +12653,7 @@ var init_lint = __esm({
|
|
|
12492
12653
|
});
|
|
12493
12654
|
|
|
12494
12655
|
// src/utils/lintProject.ts
|
|
12495
|
-
import { existsSync as
|
|
12656
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10, readdirSync as readdirSync2 } from "fs";
|
|
12496
12657
|
import { dirname as dirname4, join as join9, resolve as resolve5, extname as extname3 } from "path";
|
|
12497
12658
|
function readHtmlAttr(tag, name) {
|
|
12498
12659
|
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -12514,8 +12675,8 @@ function collectExternalStyles(projectDir, html, compSrcPath) {
|
|
|
12514
12675
|
if (!isLocalStylesheetHref(href)) continue;
|
|
12515
12676
|
const rootRelative = compSrcPath ? join9(dirname4(compSrcPath), href) : href;
|
|
12516
12677
|
const resolved = resolve5(projectDir, rootRelative);
|
|
12517
|
-
if (!
|
|
12518
|
-
styles.push({ href, content:
|
|
12678
|
+
if (!existsSync8(resolved)) continue;
|
|
12679
|
+
styles.push({ href, content: readFileSync10(resolved, "utf-8") });
|
|
12519
12680
|
}
|
|
12520
12681
|
return styles;
|
|
12521
12682
|
}
|
|
@@ -12536,8 +12697,8 @@ function collectCssSources(projectDir, html, compSrcPath) {
|
|
|
12536
12697
|
if (!isLocalStylesheetHref(href)) continue;
|
|
12537
12698
|
const rootRelativePath = compSrcPath ? join9(dirname4(compSrcPath), href) : href;
|
|
12538
12699
|
const resolved = resolve5(projectDir, rootRelativePath);
|
|
12539
|
-
if (!
|
|
12540
|
-
sources.push({ content:
|
|
12700
|
+
if (!existsSync8(resolved)) continue;
|
|
12701
|
+
sources.push({ content: readFileSync10(resolved, "utf-8"), rootRelativePath });
|
|
12541
12702
|
}
|
|
12542
12703
|
let tagMatch;
|
|
12543
12704
|
const tagPattern = new RegExp(OPEN_TAG_RE.source, OPEN_TAG_RE.flags);
|
|
@@ -12566,7 +12727,7 @@ function lintProject(project) {
|
|
|
12566
12727
|
let totalErrors = 0;
|
|
12567
12728
|
let totalWarnings = 0;
|
|
12568
12729
|
let totalInfos = 0;
|
|
12569
|
-
const rootHtml =
|
|
12730
|
+
const rootHtml = readFileSync10(project.indexPath, "utf-8");
|
|
12570
12731
|
const rootResult = lintHyperframeHtml(rootHtml, {
|
|
12571
12732
|
filePath: project.indexPath,
|
|
12572
12733
|
externalStyles: collectExternalStyles(project.dir, rootHtml)
|
|
@@ -12577,11 +12738,11 @@ function lintProject(project) {
|
|
|
12577
12738
|
totalInfos += rootResult.infoCount;
|
|
12578
12739
|
const allHtmlSources = [{ html: rootHtml }];
|
|
12579
12740
|
const compositionsDir = resolve5(project.dir, "compositions");
|
|
12580
|
-
if (
|
|
12741
|
+
if (existsSync8(compositionsDir)) {
|
|
12581
12742
|
const files = readdirSync2(compositionsDir).filter((f3) => f3.endsWith(".html"));
|
|
12582
12743
|
for (const file of files) {
|
|
12583
12744
|
const filePath = join9(compositionsDir, file);
|
|
12584
|
-
const html =
|
|
12745
|
+
const html = readFileSync10(filePath, "utf-8");
|
|
12585
12746
|
const compSrcPath = `compositions/${file}`;
|
|
12586
12747
|
allHtmlSources.push({ html, compSrcPath });
|
|
12587
12748
|
const result = lintHyperframeHtml(html, {
|
|
@@ -12654,7 +12815,7 @@ function lintAudioSrcNotFound(projectDir, htmlSources) {
|
|
|
12654
12815
|
if (/^__[A-Z_]+__$/.test(src)) continue;
|
|
12655
12816
|
const rootRelative = compSrcPath ? rewriteAssetPath(compSrcPath, src) : src;
|
|
12656
12817
|
const resolved = resolve5(projectDir, rootRelative);
|
|
12657
|
-
if (!
|
|
12818
|
+
if (!existsSync8(resolved)) {
|
|
12658
12819
|
missingSrcs.push(src);
|
|
12659
12820
|
}
|
|
12660
12821
|
}
|
|
@@ -12687,7 +12848,7 @@ function lintTextureMaskAssetNotFound(projectDir, htmlSources) {
|
|
|
12687
12848
|
compSrcPath,
|
|
12688
12849
|
cssSource.rootRelativePath
|
|
12689
12850
|
);
|
|
12690
|
-
if (
|
|
12851
|
+
if (existsSync8(resolved)) continue;
|
|
12691
12852
|
missing.set(url, resolved);
|
|
12692
12853
|
}
|
|
12693
12854
|
}
|
|
@@ -12709,7 +12870,7 @@ function lintMultipleRootCompositions(projectDir) {
|
|
|
12709
12870
|
const rootHtmlFiles = readdirSync2(projectDir).filter((f3) => f3.endsWith(".html"));
|
|
12710
12871
|
const rootCompositions = [];
|
|
12711
12872
|
for (const file of rootHtmlFiles) {
|
|
12712
|
-
const content =
|
|
12873
|
+
const content = readFileSync10(join9(projectDir, file), "utf-8");
|
|
12713
12874
|
if (/data-composition-id/i.test(content)) {
|
|
12714
12875
|
rootCompositions.push(file);
|
|
12715
12876
|
}
|
|
@@ -13071,6 +13232,103 @@ var init_portUtils = __esm({
|
|
|
13071
13232
|
}
|
|
13072
13233
|
});
|
|
13073
13234
|
|
|
13235
|
+
// src/utils/orphanCleanup.ts
|
|
13236
|
+
import { execSync } from "child_process";
|
|
13237
|
+
function killOrphanedProcesses() {
|
|
13238
|
+
if (process.platform === "win32") return 0;
|
|
13239
|
+
let killed = 0;
|
|
13240
|
+
for (const name of ["chrome-headless-shell", "chrome_headless_shell"]) {
|
|
13241
|
+
killed += killOrphansByName(name);
|
|
13242
|
+
}
|
|
13243
|
+
killed += killOrphansByName("puppeteer_dev_chrome_profile");
|
|
13244
|
+
return killed;
|
|
13245
|
+
}
|
|
13246
|
+
function killProcessTree(pid, signal = "SIGTERM") {
|
|
13247
|
+
if (process.platform === "win32") return;
|
|
13248
|
+
const descendants = getDescendants(pid);
|
|
13249
|
+
const allPids = [...descendants.reverse(), pid];
|
|
13250
|
+
for (const p2 of allPids) {
|
|
13251
|
+
try {
|
|
13252
|
+
process.kill(p2, signal);
|
|
13253
|
+
} catch {
|
|
13254
|
+
}
|
|
13255
|
+
}
|
|
13256
|
+
if (signal !== "SIGKILL") {
|
|
13257
|
+
setTimeout(() => {
|
|
13258
|
+
for (const p2 of allPids) {
|
|
13259
|
+
try {
|
|
13260
|
+
process.kill(p2, "SIGKILL");
|
|
13261
|
+
} catch {
|
|
13262
|
+
}
|
|
13263
|
+
}
|
|
13264
|
+
}, 500).unref();
|
|
13265
|
+
}
|
|
13266
|
+
}
|
|
13267
|
+
function getDescendants(pid) {
|
|
13268
|
+
let children;
|
|
13269
|
+
try {
|
|
13270
|
+
const raw = execSync(`pgrep -P ${pid}`, { encoding: "utf-8", timeout: 2e3 }).trim();
|
|
13271
|
+
if (!raw) return [];
|
|
13272
|
+
children = raw.split("\n").map((s2) => parseInt(s2, 10)).filter((n) => !isNaN(n) && n > 0);
|
|
13273
|
+
} catch {
|
|
13274
|
+
return [];
|
|
13275
|
+
}
|
|
13276
|
+
const all = [];
|
|
13277
|
+
for (const child of children) {
|
|
13278
|
+
all.push(child);
|
|
13279
|
+
all.push(...getDescendants(child));
|
|
13280
|
+
}
|
|
13281
|
+
return all;
|
|
13282
|
+
}
|
|
13283
|
+
function killOrphansByName(processName) {
|
|
13284
|
+
const uid = getUid();
|
|
13285
|
+
const userFlag = uid !== null ? `-u ${uid} ` : "";
|
|
13286
|
+
let pids;
|
|
13287
|
+
try {
|
|
13288
|
+
const raw = execSync(`pgrep ${userFlag}-f ${processName}`, {
|
|
13289
|
+
encoding: "utf-8",
|
|
13290
|
+
timeout: 3e3
|
|
13291
|
+
}).trim();
|
|
13292
|
+
if (!raw) return 0;
|
|
13293
|
+
pids = raw.split("\n").map((s2) => parseInt(s2, 10)).filter((n) => !isNaN(n) && n > 0);
|
|
13294
|
+
} catch {
|
|
13295
|
+
return 0;
|
|
13296
|
+
}
|
|
13297
|
+
let killed = 0;
|
|
13298
|
+
for (const pid of pids) {
|
|
13299
|
+
if (!isOrphan(pid)) continue;
|
|
13300
|
+
killProcessTree(pid);
|
|
13301
|
+
killed++;
|
|
13302
|
+
}
|
|
13303
|
+
return killed;
|
|
13304
|
+
}
|
|
13305
|
+
function getUid() {
|
|
13306
|
+
if (_cachedUid !== void 0) return _cachedUid;
|
|
13307
|
+
try {
|
|
13308
|
+
_cachedUid = execSync("id -u", { encoding: "utf-8", timeout: 1e3 }).trim();
|
|
13309
|
+
} catch {
|
|
13310
|
+
_cachedUid = null;
|
|
13311
|
+
}
|
|
13312
|
+
return _cachedUid;
|
|
13313
|
+
}
|
|
13314
|
+
function isOrphan(pid) {
|
|
13315
|
+
try {
|
|
13316
|
+
const ppid = execSync(`ps -p ${pid} -o ppid=`, {
|
|
13317
|
+
encoding: "utf-8",
|
|
13318
|
+
timeout: 2e3
|
|
13319
|
+
}).trim();
|
|
13320
|
+
return ppid === "1";
|
|
13321
|
+
} catch {
|
|
13322
|
+
return false;
|
|
13323
|
+
}
|
|
13324
|
+
}
|
|
13325
|
+
var _cachedUid;
|
|
13326
|
+
var init_orphanCleanup = __esm({
|
|
13327
|
+
"src/utils/orphanCleanup.ts"() {
|
|
13328
|
+
"use strict";
|
|
13329
|
+
}
|
|
13330
|
+
});
|
|
13331
|
+
|
|
13074
13332
|
// src/server/fileWatcher.ts
|
|
13075
13333
|
import { watch } from "fs";
|
|
13076
13334
|
function shouldWatchProjectFile(filename) {
|
|
@@ -13132,13 +13390,13 @@ var init_fileWatcher = __esm({
|
|
|
13132
13390
|
});
|
|
13133
13391
|
|
|
13134
13392
|
// src/server/runtimeSource.ts
|
|
13135
|
-
import { existsSync as
|
|
13393
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
|
|
13136
13394
|
import { resolve as resolve7, dirname as dirname5 } from "path";
|
|
13137
13395
|
async function loadRuntimeSource() {
|
|
13138
13396
|
return await buildFromSource2() ?? await getInlinedRuntime() ?? readPrebuiltArtifact();
|
|
13139
13397
|
}
|
|
13140
13398
|
async function buildFromSource2() {
|
|
13141
|
-
if (!
|
|
13399
|
+
if (!existsSync9(ENTRY_TS)) return null;
|
|
13142
13400
|
try {
|
|
13143
13401
|
const mod = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
13144
13402
|
if (typeof mod.loadHyperframeRuntimeSource === "function") {
|
|
@@ -13165,7 +13423,7 @@ function readPrebuiltArtifact() {
|
|
|
13165
13423
|
function readFromDir(dir) {
|
|
13166
13424
|
for (const name of ARTIFACT_NAMES) {
|
|
13167
13425
|
const path2 = resolve7(dir, name);
|
|
13168
|
-
if (
|
|
13426
|
+
if (existsSync9(path2)) return readFileSync11(path2, "utf-8");
|
|
13169
13427
|
}
|
|
13170
13428
|
return null;
|
|
13171
13429
|
}
|
|
@@ -13383,7 +13641,7 @@ var init_mime = __esm({
|
|
|
13383
13641
|
|
|
13384
13642
|
// ../core/src/studio-api/helpers/waveform.ts
|
|
13385
13643
|
import { spawn as spawn3 } from "child_process";
|
|
13386
|
-
import { existsSync as
|
|
13644
|
+
import { existsSync as existsSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5 } from "fs";
|
|
13387
13645
|
import { join as join11 } from "path";
|
|
13388
13646
|
function buildWaveformCacheKey(assetPath) {
|
|
13389
13647
|
return `${WAVEFORM_CACHE_VERSION}_${assetPath.replace(/[/\\]/g, "_")}.json`;
|
|
@@ -13445,10 +13703,10 @@ function decodeAudioPeaks(audioPath) {
|
|
|
13445
13703
|
}
|
|
13446
13704
|
async function generateWaveformCache(projectDir, assetPath) {
|
|
13447
13705
|
const audioPath = join11(projectDir, assetPath);
|
|
13448
|
-
if (!
|
|
13706
|
+
if (!existsSync10(audioPath)) return;
|
|
13449
13707
|
const cacheDir = join11(projectDir, ".waveform-cache");
|
|
13450
13708
|
const cachePath2 = join11(cacheDir, buildWaveformCacheKey(assetPath));
|
|
13451
|
-
if (
|
|
13709
|
+
if (existsSync10(cachePath2)) return;
|
|
13452
13710
|
const peaks = await decodeAudioPeaks(audioPath);
|
|
13453
13711
|
mkdirSync5(cacheDir, { recursive: true });
|
|
13454
13712
|
writeFileSync6(cachePath2, JSON.stringify(peaks));
|
|
@@ -26303,8 +26561,8 @@ var init_sourceMutation = __esm({
|
|
|
26303
26561
|
// ../core/src/studio-api/routes/files.ts
|
|
26304
26562
|
import { bodyLimit } from "hono/body-limit";
|
|
26305
26563
|
import {
|
|
26306
|
-
existsSync as
|
|
26307
|
-
readFileSync as
|
|
26564
|
+
existsSync as existsSync11,
|
|
26565
|
+
readFileSync as readFileSync12,
|
|
26308
26566
|
writeFileSync as writeFileSync8,
|
|
26309
26567
|
mkdirSync as mkdirSync6,
|
|
26310
26568
|
unlinkSync as unlinkSync3,
|
|
@@ -26328,14 +26586,14 @@ async function resolveProjectFile(c3, adapter2, opts) {
|
|
|
26328
26586
|
if (!isSafePath(project.dir, absPath)) {
|
|
26329
26587
|
return { error: c3.json({ error: "forbidden" }, 403) };
|
|
26330
26588
|
}
|
|
26331
|
-
if (opts?.mustExist && !
|
|
26589
|
+
if (opts?.mustExist && !existsSync11(absPath)) {
|
|
26332
26590
|
return { error: c3.json({ error: "not found" }, 404) };
|
|
26333
26591
|
}
|
|
26334
26592
|
return { project, filePath, absPath };
|
|
26335
26593
|
}
|
|
26336
26594
|
function ensureDir(filePath) {
|
|
26337
26595
|
const dir = dirname6(filePath);
|
|
26338
|
-
if (!
|
|
26596
|
+
if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
|
|
26339
26597
|
}
|
|
26340
26598
|
function generateCopyPath(projectDir, originalPath) {
|
|
26341
26599
|
const ext = originalPath.includes(".") ? "." + originalPath.split(".").pop() : "";
|
|
@@ -26344,7 +26602,7 @@ function generateCopyPath(projectDir, originalPath) {
|
|
|
26344
26602
|
const cleanBase = copyMatch ? base.slice(0, -copyMatch[0].length) : base;
|
|
26345
26603
|
let num = copyMatch ? copyMatch[1] ? parseInt(copyMatch[1]) + 1 : 2 : 1;
|
|
26346
26604
|
let candidate = num === 1 ? `${cleanBase} (copy)${ext}` : `${cleanBase} (copy ${num})${ext}`;
|
|
26347
|
-
while (
|
|
26605
|
+
while (existsSync11(resolve9(projectDir, candidate))) {
|
|
26348
26606
|
num++;
|
|
26349
26607
|
candidate = `${cleanBase} (copy ${num})${ext}`;
|
|
26350
26608
|
}
|
|
@@ -26371,7 +26629,7 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
26371
26629
|
);
|
|
26372
26630
|
let updatedCount = 0;
|
|
26373
26631
|
for (const file of textFiles) {
|
|
26374
|
-
const content =
|
|
26632
|
+
const content = readFileSync12(file, "utf-8");
|
|
26375
26633
|
if (!content.includes(oldPath)) continue;
|
|
26376
26634
|
const updated = content.split(oldPath).join(newPath);
|
|
26377
26635
|
if (updated !== content) {
|
|
@@ -26385,13 +26643,13 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26385
26643
|
api.get("/projects/:id/files/*", async (c3) => {
|
|
26386
26644
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26387
26645
|
if ("error" in res) return res.error;
|
|
26388
|
-
if (!
|
|
26646
|
+
if (!existsSync11(res.absPath)) {
|
|
26389
26647
|
if (c3.req.query("optional") === "1") {
|
|
26390
26648
|
return c3.json({ filename: res.filePath, content: "" });
|
|
26391
26649
|
}
|
|
26392
26650
|
return c3.json({ error: "not found" }, 404);
|
|
26393
26651
|
}
|
|
26394
|
-
const content =
|
|
26652
|
+
const content = readFileSync12(res.absPath, "utf-8");
|
|
26395
26653
|
return c3.json({ filename: res.filePath, content });
|
|
26396
26654
|
});
|
|
26397
26655
|
api.put("/projects/:id/files/*", async (c3) => {
|
|
@@ -26405,7 +26663,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26405
26663
|
api.post("/projects/:id/files/*", async (c3) => {
|
|
26406
26664
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26407
26665
|
if ("error" in res) return res.error;
|
|
26408
|
-
if (
|
|
26666
|
+
if (existsSync11(res.absPath)) {
|
|
26409
26667
|
return c3.json({ error: "already exists" }, 409);
|
|
26410
26668
|
}
|
|
26411
26669
|
ensureDir(res.absPath);
|
|
@@ -26438,14 +26696,14 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26438
26696
|
if (!isSafePath(project.dir, absPath)) {
|
|
26439
26697
|
return c3.json({ error: "forbidden" }, 403);
|
|
26440
26698
|
}
|
|
26441
|
-
if (!
|
|
26699
|
+
if (!existsSync11(absPath)) {
|
|
26442
26700
|
return c3.json({ error: "not found" }, 404);
|
|
26443
26701
|
}
|
|
26444
26702
|
const body = await c3.req.json().catch(() => null);
|
|
26445
26703
|
if (!body?.target) {
|
|
26446
26704
|
return c3.json({ error: "target required" }, 400);
|
|
26447
26705
|
}
|
|
26448
|
-
const originalContent =
|
|
26706
|
+
const originalContent = readFileSync12(absPath, "utf-8");
|
|
26449
26707
|
const patchedContent = removeElementFromHtml2(originalContent, body.target);
|
|
26450
26708
|
if (patchedContent === originalContent) {
|
|
26451
26709
|
return c3.json({ ok: true, changed: false, content: originalContent });
|
|
@@ -26473,7 +26731,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26473
26731
|
}
|
|
26474
26732
|
let originalContent;
|
|
26475
26733
|
try {
|
|
26476
|
-
originalContent =
|
|
26734
|
+
originalContent = readFileSync12(absPath, "utf-8");
|
|
26477
26735
|
} catch {
|
|
26478
26736
|
return c3.json({ error: "not found" }, 404);
|
|
26479
26737
|
}
|
|
@@ -26495,7 +26753,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26495
26753
|
if (!isSafePath(res.project.dir, newAbs)) {
|
|
26496
26754
|
return c3.json({ error: "forbidden" }, 403);
|
|
26497
26755
|
}
|
|
26498
|
-
if (
|
|
26756
|
+
if (existsSync11(newAbs)) {
|
|
26499
26757
|
return c3.json({ error: "already exists" }, 409);
|
|
26500
26758
|
}
|
|
26501
26759
|
ensureDir(newAbs);
|
|
@@ -26511,7 +26769,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26511
26769
|
return c3.json({ error: "path required" }, 400);
|
|
26512
26770
|
}
|
|
26513
26771
|
const srcAbs = resolve9(project.dir, body.path);
|
|
26514
|
-
if (!isSafePath(project.dir, srcAbs) || !
|
|
26772
|
+
if (!isSafePath(project.dir, srcAbs) || !existsSync11(srcAbs)) {
|
|
26515
26773
|
return c3.json({ error: "not found" }, 404);
|
|
26516
26774
|
}
|
|
26517
26775
|
const copyPath = generateCopyPath(project.dir, body.path);
|
|
@@ -26520,7 +26778,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26520
26778
|
return c3.json({ error: "forbidden" }, 403);
|
|
26521
26779
|
}
|
|
26522
26780
|
ensureDir(destAbs);
|
|
26523
|
-
writeFileSync8(destAbs,
|
|
26781
|
+
writeFileSync8(destAbs, readFileSync12(srcAbs));
|
|
26524
26782
|
return c3.json({ ok: true, path: copyPath }, 201);
|
|
26525
26783
|
});
|
|
26526
26784
|
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
@@ -26536,7 +26794,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26536
26794
|
const subDir = c3.req.query("dir") ?? "";
|
|
26537
26795
|
const targetDir = subDir ? resolve9(project.dir, subDir) : project.dir;
|
|
26538
26796
|
if (!isSafePath(project.dir, targetDir)) return c3.json({ error: "forbidden" }, 403);
|
|
26539
|
-
if (subDir && !
|
|
26797
|
+
if (subDir && !existsSync11(targetDir)) mkdirSync6(targetDir, { recursive: true });
|
|
26540
26798
|
const formData = await c3.req.formData();
|
|
26541
26799
|
const uploaded = [];
|
|
26542
26800
|
const skipped = [];
|
|
@@ -26554,12 +26812,12 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26554
26812
|
if (!isSafePath(project.dir, destPath)) continue;
|
|
26555
26813
|
let finalPath = destPath;
|
|
26556
26814
|
let finalName = name;
|
|
26557
|
-
if (
|
|
26815
|
+
if (existsSync11(finalPath)) {
|
|
26558
26816
|
const dotIdx = name.indexOf(".", name.startsWith(".") ? 1 : 0);
|
|
26559
26817
|
const ext = dotIdx > 0 ? name.slice(dotIdx) : "";
|
|
26560
26818
|
const base = dotIdx > 0 ? name.slice(0, dotIdx) : name;
|
|
26561
26819
|
let n = 2;
|
|
26562
|
-
while (n < 1e4 &&
|
|
26820
|
+
while (n < 1e4 && existsSync11(resolve9(targetDir, `${base} (${n})${ext}`))) n++;
|
|
26563
26821
|
if (n >= 1e4) {
|
|
26564
26822
|
skipped.push(name);
|
|
26565
26823
|
continue;
|
|
@@ -26781,7 +27039,7 @@ var init_htmlDocument = __esm({
|
|
|
26781
27039
|
});
|
|
26782
27040
|
|
|
26783
27041
|
// ../core/src/studio-api/helpers/subComposition.ts
|
|
26784
|
-
import { existsSync as
|
|
27042
|
+
import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
|
|
26785
27043
|
import { join as join14 } from "path";
|
|
26786
27044
|
function isFullHtmlDocument(html) {
|
|
26787
27045
|
return /^\s*(?:<!doctype\s|<html[\s>])/i.test(html);
|
|
@@ -26830,8 +27088,8 @@ function extractElementAttrs(el) {
|
|
|
26830
27088
|
}
|
|
26831
27089
|
function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
26832
27090
|
const compFile = join14(projectDir, compPath);
|
|
26833
|
-
if (!
|
|
26834
|
-
const rawComp =
|
|
27091
|
+
if (!existsSync12(compFile)) return null;
|
|
27092
|
+
const rawComp = readFileSync13(compFile, "utf-8");
|
|
26835
27093
|
let compHeadContent = "";
|
|
26836
27094
|
let rewrittenContent;
|
|
26837
27095
|
let htmlAttrs = "";
|
|
@@ -26859,8 +27117,8 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
|
26859
27117
|
}
|
|
26860
27118
|
const indexPath = join14(projectDir, "index.html");
|
|
26861
27119
|
let headContent = "";
|
|
26862
|
-
if (
|
|
26863
|
-
const indexHtml =
|
|
27120
|
+
if (existsSync12(indexPath)) {
|
|
27121
|
+
const indexHtml = readFileSync13(indexPath, "utf-8");
|
|
26864
27122
|
const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
26865
27123
|
headContent = headMatch?.[1] ?? "";
|
|
26866
27124
|
}
|
|
@@ -26901,7 +27159,7 @@ var init_subComposition = __esm({
|
|
|
26901
27159
|
|
|
26902
27160
|
// ../core/src/studio-api/helpers/projectSignature.ts
|
|
26903
27161
|
import { createHash } from "crypto";
|
|
26904
|
-
import { lstatSync, readFileSync as
|
|
27162
|
+
import { lstatSync, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "fs";
|
|
26905
27163
|
import { extname as extname4, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10 } from "path";
|
|
26906
27164
|
function isPathWithin(parentDir, childPath) {
|
|
26907
27165
|
const childRelativePath = relative2(parentDir, childPath);
|
|
@@ -26993,7 +27251,7 @@ function createProjectSignature(projectDir) {
|
|
|
26993
27251
|
hash2.update("\0");
|
|
26994
27252
|
if (entry.textContentEligible) {
|
|
26995
27253
|
try {
|
|
26996
|
-
hash2.update(
|
|
27254
|
+
hash2.update(readFileSync14(entry.file));
|
|
26997
27255
|
} catch {
|
|
26998
27256
|
hash2.update(String(entry.mtimeMs));
|
|
26999
27257
|
}
|
|
@@ -27238,7 +27496,7 @@ var init_studioMotionRenderScript = __esm({
|
|
|
27238
27496
|
});
|
|
27239
27497
|
|
|
27240
27498
|
// ../core/src/studio-api/routes/preview.ts
|
|
27241
|
-
import { existsSync as
|
|
27499
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15, statSync as statSync2 } from "fs";
|
|
27242
27500
|
import { join as join15, resolve as resolve11 } from "path";
|
|
27243
27501
|
function resolveProjectSignature(adapter2, projectDir) {
|
|
27244
27502
|
return adapter2.getProjectSignature?.(projectDir) ?? createProjectSignature(projectDir);
|
|
@@ -27258,9 +27516,9 @@ ${html}`;
|
|
|
27258
27516
|
}
|
|
27259
27517
|
function readStudioMotionManifestContent(projectDir) {
|
|
27260
27518
|
const manifestPath = join15(projectDir, STUDIO_MOTION_PATH);
|
|
27261
|
-
if (!
|
|
27519
|
+
if (!existsSync13(manifestPath)) return "";
|
|
27262
27520
|
try {
|
|
27263
|
-
return
|
|
27521
|
+
return readFileSync15(manifestPath, "utf-8");
|
|
27264
27522
|
} catch {
|
|
27265
27523
|
return "";
|
|
27266
27524
|
}
|
|
@@ -27341,12 +27599,12 @@ async function transformPreviewHtml(html, adapter2, project, activeCompositionPa
|
|
|
27341
27599
|
}
|
|
27342
27600
|
function resolveProjectMainHtml(projectDir, projectId) {
|
|
27343
27601
|
const indexPath = join15(projectDir, "index.html");
|
|
27344
|
-
if (
|
|
27345
|
-
return { html:
|
|
27602
|
+
if (existsSync13(indexPath)) {
|
|
27603
|
+
return { html: readFileSync15(indexPath, "utf-8"), compositionPath: "index.html" };
|
|
27346
27604
|
}
|
|
27347
27605
|
const blockHtmlPath = join15(projectDir, `${projectId}.html`);
|
|
27348
|
-
if (
|
|
27349
|
-
return { html:
|
|
27606
|
+
if (existsSync13(blockHtmlPath)) {
|
|
27607
|
+
return { html: readFileSync15(blockHtmlPath, "utf-8"), compositionPath: `${projectId}.html` };
|
|
27350
27608
|
}
|
|
27351
27609
|
return null;
|
|
27352
27610
|
}
|
|
@@ -27415,7 +27673,7 @@ ${runtimeTag}`;
|
|
|
27415
27673
|
c3.req.path.replace(`/projects/${project.id}/preview/comp/`, "").split("?")[0] ?? ""
|
|
27416
27674
|
);
|
|
27417
27675
|
const compFile = resolve11(project.dir, compPath);
|
|
27418
|
-
if (!isSafePath(project.dir, compFile) || !
|
|
27676
|
+
if (!isSafePath(project.dir, compFile) || !existsSync13(compFile) || !statSync2(compFile).isFile()) {
|
|
27419
27677
|
return c3.text("not found", 404);
|
|
27420
27678
|
}
|
|
27421
27679
|
const etag = `"comp:${compPath}:${signature}"`;
|
|
@@ -27440,7 +27698,7 @@ ${runtimeTag}`;
|
|
|
27440
27698
|
c3.req.path.replace(`/projects/${project.id}/preview/`, "").split("?")[0] ?? ""
|
|
27441
27699
|
);
|
|
27442
27700
|
const file = resolve11(project.dir, subPath);
|
|
27443
|
-
const stat3 =
|
|
27701
|
+
const stat3 = existsSync13(file) ? statSync2(file) : null;
|
|
27444
27702
|
if (!isSafePath(project.dir, file) || !stat3?.isFile()) {
|
|
27445
27703
|
return c3.text("not found", 404);
|
|
27446
27704
|
}
|
|
@@ -27454,7 +27712,7 @@ ${runtimeTag}`;
|
|
|
27454
27712
|
return new Response(null, { status: 304, headers: cacheHeaders });
|
|
27455
27713
|
}
|
|
27456
27714
|
}
|
|
27457
|
-
const buffer = isText2 ? Buffer.from(
|
|
27715
|
+
const buffer = isText2 ? Buffer.from(readFileSync15(file, "utf-8"), "utf-8") : readFileSync15(file);
|
|
27458
27716
|
const totalSize2 = buffer.length;
|
|
27459
27717
|
const rangeHeader = c3.req.header("Range");
|
|
27460
27718
|
if (rangeHeader) {
|
|
@@ -27524,7 +27782,7 @@ var init_preview = __esm({
|
|
|
27524
27782
|
});
|
|
27525
27783
|
|
|
27526
27784
|
// ../core/src/studio-api/routes/lint.ts
|
|
27527
|
-
import { readFileSync as
|
|
27785
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
27528
27786
|
import { join as join16 } from "path";
|
|
27529
27787
|
function registerLintRoutes(api, adapter2) {
|
|
27530
27788
|
api.get("/projects/:id/lint", async (c3) => {
|
|
@@ -27534,7 +27792,7 @@ function registerLintRoutes(api, adapter2) {
|
|
|
27534
27792
|
const htmlFiles = walkDir(project.dir).filter((f3) => f3.endsWith(".html"));
|
|
27535
27793
|
const allFindings = [];
|
|
27536
27794
|
for (const file of htmlFiles) {
|
|
27537
|
-
const content =
|
|
27795
|
+
const content = readFileSync16(join16(project.dir, file), "utf-8");
|
|
27538
27796
|
const result = await adapter2.lint(content, { filePath: file });
|
|
27539
27797
|
if (result?.findings) {
|
|
27540
27798
|
for (const f3 of result.findings) {
|
|
@@ -27558,7 +27816,7 @@ var init_lint2 = __esm({
|
|
|
27558
27816
|
|
|
27559
27817
|
// ../core/src/studio-api/routes/render.ts
|
|
27560
27818
|
import { streamSSE } from "hono/streaming";
|
|
27561
|
-
import { existsSync as
|
|
27819
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, mkdirSync as mkdirSync7, unlinkSync as unlinkSync4, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
27562
27820
|
import { join as join17, resolve as resolve12, sep as sep2 } from "path";
|
|
27563
27821
|
function registerRenderRoutes(api, adapter2) {
|
|
27564
27822
|
const renderJobs = /* @__PURE__ */ new Map();
|
|
@@ -27610,7 +27868,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27610
27868
|
const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
|
|
27611
27869
|
const jobId = `${project.id}_${datePart}_${timePart}`;
|
|
27612
27870
|
const rendersDir = adapter2.rendersDir(project);
|
|
27613
|
-
if (!
|
|
27871
|
+
if (!existsSync14(rendersDir)) mkdirSync7(rendersDir, { recursive: true });
|
|
27614
27872
|
const ext = FORMAT_EXT2[format] ?? ".mp4";
|
|
27615
27873
|
const outputPath = join17(rendersDir, `${jobId}${ext}`);
|
|
27616
27874
|
const jobState = adapter2.startRender({
|
|
@@ -27663,12 +27921,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27663
27921
|
api.get("/render/:jobId/view", (c3) => {
|
|
27664
27922
|
const { jobId } = c3.req.param();
|
|
27665
27923
|
const job = renderJobs.get(jobId);
|
|
27666
|
-
if (!job?.outputPath || !
|
|
27924
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27667
27925
|
return c3.json({ error: "not found" }, 404);
|
|
27668
27926
|
}
|
|
27669
27927
|
const contentType = renderContentType(job.outputPath);
|
|
27670
27928
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27671
|
-
const content =
|
|
27929
|
+
const content = readFileSync17(job.outputPath);
|
|
27672
27930
|
return new Response(content, {
|
|
27673
27931
|
headers: {
|
|
27674
27932
|
"Content-Type": contentType,
|
|
@@ -27681,12 +27939,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27681
27939
|
api.get("/render/:jobId/download", (c3) => {
|
|
27682
27940
|
const { jobId } = c3.req.param();
|
|
27683
27941
|
const job = renderJobs.get(jobId);
|
|
27684
|
-
if (!job?.outputPath || !
|
|
27942
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27685
27943
|
return c3.json({ error: "not found" }, 404);
|
|
27686
27944
|
}
|
|
27687
27945
|
const contentType = renderContentType(job.outputPath);
|
|
27688
27946
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27689
|
-
const content =
|
|
27947
|
+
const content = readFileSync17(job.outputPath);
|
|
27690
27948
|
return new Response(content, {
|
|
27691
27949
|
headers: {
|
|
27692
27950
|
"Content-Type": contentType,
|
|
@@ -27701,7 +27959,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27701
27959
|
const dir = state.outputPath.replace(/\/[^/]+$/, "");
|
|
27702
27960
|
for (const ext of [".mp4", ".webm", ".mov", ".meta.json"]) {
|
|
27703
27961
|
const fp = join17(dir, `${jobId}${ext}`);
|
|
27704
|
-
if (
|
|
27962
|
+
if (existsSync14(fp)) unlinkSync4(fp);
|
|
27705
27963
|
}
|
|
27706
27964
|
break;
|
|
27707
27965
|
}
|
|
@@ -27716,9 +27974,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27716
27974
|
if (!filename) return c3.json({ error: "missing filename" }, 400);
|
|
27717
27975
|
const rendersDir = adapter2.rendersDir(project);
|
|
27718
27976
|
const fp = join17(rendersDir, filename);
|
|
27719
|
-
if (!
|
|
27977
|
+
if (!existsSync14(fp)) return c3.json({ error: "not found" }, 404);
|
|
27720
27978
|
const contentType = renderContentType(fp);
|
|
27721
|
-
const content =
|
|
27979
|
+
const content = readFileSync17(fp);
|
|
27722
27980
|
return new Response(content, {
|
|
27723
27981
|
headers: {
|
|
27724
27982
|
"Content-Type": contentType,
|
|
@@ -27732,7 +27990,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27732
27990
|
const project = await adapter2.resolveProject(c3.req.param("id"));
|
|
27733
27991
|
if (!project) return c3.json({ error: "not found" }, 404);
|
|
27734
27992
|
const rendersDir = adapter2.rendersDir(project);
|
|
27735
|
-
if (!
|
|
27993
|
+
if (!existsSync14(rendersDir)) return c3.json({ renders: [] });
|
|
27736
27994
|
const files = readdirSync6(rendersDir).filter((f3) => f3.endsWith(".mp4") || f3.endsWith(".webm") || f3.endsWith(".mov")).map((f3) => {
|
|
27737
27995
|
const fp = join17(rendersDir, f3);
|
|
27738
27996
|
const stat3 = statSync3(fp);
|
|
@@ -27740,9 +27998,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27740
27998
|
const metaPath = join17(rendersDir, `${rid}.meta.json`);
|
|
27741
27999
|
let status = "complete";
|
|
27742
28000
|
let durationMs;
|
|
27743
|
-
if (
|
|
28001
|
+
if (existsSync14(metaPath)) {
|
|
27744
28002
|
try {
|
|
27745
|
-
const meta = JSON.parse(
|
|
28003
|
+
const meta = JSON.parse(readFileSync17(metaPath, "utf-8"));
|
|
27746
28004
|
if (meta.status === "failed") status = "failed";
|
|
27747
28005
|
if (meta.durationMs) durationMs = meta.durationMs;
|
|
27748
28006
|
} catch {
|
|
@@ -28365,7 +28623,7 @@ var init_manualEditsRenderScript = __esm({
|
|
|
28365
28623
|
});
|
|
28366
28624
|
|
|
28367
28625
|
// ../core/src/studio-api/routes/thumbnail.ts
|
|
28368
|
-
import { existsSync as
|
|
28626
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
|
|
28369
28627
|
import { join as join18 } from "path";
|
|
28370
28628
|
import { createHash as createHash2 } from "crypto";
|
|
28371
28629
|
function registerThumbnailRoutes(api, adapter2) {
|
|
@@ -28396,9 +28654,9 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28396
28654
|
let sourceMtime = 0;
|
|
28397
28655
|
if (!vpWidth) {
|
|
28398
28656
|
const htmlFile = join18(project.dir, compPath);
|
|
28399
|
-
if (
|
|
28657
|
+
if (existsSync15(htmlFile)) {
|
|
28400
28658
|
sourceMtime = Math.round(statSync4(htmlFile).mtimeMs);
|
|
28401
|
-
const html =
|
|
28659
|
+
const html = readFileSync18(htmlFile, "utf-8");
|
|
28402
28660
|
const wMatch = html.match(/data-width=["'](\d+)["']/);
|
|
28403
28661
|
const hMatch = html.match(/data-height=["'](\d+)["']/);
|
|
28404
28662
|
if (wMatch?.[1]) compW = parseInt(wMatch[1]);
|
|
@@ -28407,15 +28665,15 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28407
28665
|
}
|
|
28408
28666
|
const manualEditsFile = join18(project.dir, STUDIO_MANUAL_EDITS_PATH);
|
|
28409
28667
|
let manualEditsKey = "";
|
|
28410
|
-
if (
|
|
28411
|
-
const manualEditsContent =
|
|
28668
|
+
if (existsSync15(manualEditsFile)) {
|
|
28669
|
+
const manualEditsContent = readFileSync18(manualEditsFile, "utf-8");
|
|
28412
28670
|
manualEditsKey = `_${createHash2("sha1").update(manualEditsContent).digest("hex").slice(0, 16)}`;
|
|
28413
28671
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(manualEditsFile).mtimeMs));
|
|
28414
28672
|
}
|
|
28415
28673
|
const motionFile = join18(project.dir, STUDIO_MOTION_PATH);
|
|
28416
28674
|
let motionKey = "";
|
|
28417
|
-
if (
|
|
28418
|
-
const motionContent =
|
|
28675
|
+
if (existsSync15(motionFile)) {
|
|
28676
|
+
const motionContent = readFileSync18(motionFile, "utf-8");
|
|
28419
28677
|
motionKey = `_${createHash2("sha1").update(motionContent).digest("hex").slice(0, 16)}`;
|
|
28420
28678
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(motionFile).mtimeMs));
|
|
28421
28679
|
}
|
|
@@ -28425,8 +28683,8 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28425
28683
|
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
28426
28684
|
const cacheKey = `${THUMBNAIL_CACHE_VERSION}${urlVersionKey}${manualEditsKey}${motionKey}_${format}_${compPath.replace(/\//g, "_")}_${compW}x${compH}_${sourceMtime}_${seekTime.toFixed(2)}${selectorKey}.${format === "png" ? "png" : "jpg"}`;
|
|
28427
28685
|
const cachePath2 = join18(cacheDir, cacheKey);
|
|
28428
|
-
if (
|
|
28429
|
-
return new Response(new Uint8Array(
|
|
28686
|
+
if (existsSync15(cachePath2)) {
|
|
28687
|
+
return new Response(new Uint8Array(readFileSync18(cachePath2)), {
|
|
28430
28688
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
28431
28689
|
});
|
|
28432
28690
|
}
|
|
@@ -28448,7 +28706,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28448
28706
|
500
|
|
28449
28707
|
);
|
|
28450
28708
|
}
|
|
28451
|
-
if (!
|
|
28709
|
+
if (!existsSync15(cacheDir)) mkdirSync8(cacheDir, { recursive: true });
|
|
28452
28710
|
writeFileSync9(cachePath2, buffer);
|
|
28453
28711
|
return new Response(new Uint8Array(buffer), {
|
|
28454
28712
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
@@ -28470,7 +28728,7 @@ var init_thumbnail = __esm({
|
|
|
28470
28728
|
});
|
|
28471
28729
|
|
|
28472
28730
|
// ../core/src/studio-api/routes/waveform.ts
|
|
28473
|
-
import { existsSync as
|
|
28731
|
+
import { existsSync as existsSync16, readFileSync as readFileSync19, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9 } from "fs";
|
|
28474
28732
|
import { join as join19 } from "path";
|
|
28475
28733
|
function registerWaveformRoutes(api, adapter2) {
|
|
28476
28734
|
api.get("/projects/:id/waveform/*", async (c3) => {
|
|
@@ -28480,12 +28738,12 @@ function registerWaveformRoutes(api, adapter2) {
|
|
|
28480
28738
|
c3.req.path.replace(`/projects/${project.id}/waveform/`, "").split("?")[0] ?? ""
|
|
28481
28739
|
);
|
|
28482
28740
|
const audioPath = join19(project.dir, assetPath);
|
|
28483
|
-
if (!
|
|
28741
|
+
if (!existsSync16(audioPath)) return c3.json({ error: "file not found" }, 404);
|
|
28484
28742
|
const cacheDir = join19(project.dir, ".waveform-cache");
|
|
28485
28743
|
const cachePath2 = join19(cacheDir, buildWaveformCacheKey(assetPath));
|
|
28486
|
-
if (
|
|
28744
|
+
if (existsSync16(cachePath2)) {
|
|
28487
28745
|
try {
|
|
28488
|
-
const peaks2 = JSON.parse(
|
|
28746
|
+
const peaks2 = JSON.parse(readFileSync19(cachePath2, "utf-8"));
|
|
28489
28747
|
return c3.json({ peaks: peaks2 });
|
|
28490
28748
|
} catch {
|
|
28491
28749
|
}
|
|
@@ -28513,15 +28771,15 @@ var init_waveform2 = __esm({
|
|
|
28513
28771
|
|
|
28514
28772
|
// ../core/src/studio-api/routes/fonts.ts
|
|
28515
28773
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
28516
|
-
import { existsSync as
|
|
28517
|
-
import { homedir as homedir4, platform as
|
|
28774
|
+
import { existsSync as existsSync17, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
28775
|
+
import { homedir as homedir4, platform as platform5 } from "os";
|
|
28518
28776
|
import { join as join20 } from "path";
|
|
28519
28777
|
function isRecord(value) {
|
|
28520
28778
|
return typeof value === "object" && value !== null;
|
|
28521
28779
|
}
|
|
28522
28780
|
function fontDirectories() {
|
|
28523
28781
|
const home = homedir4();
|
|
28524
|
-
if (
|
|
28782
|
+
if (platform5() === "darwin") {
|
|
28525
28783
|
return [
|
|
28526
28784
|
join20(home, "Library", "Fonts"),
|
|
28527
28785
|
"/Library/Fonts",
|
|
@@ -28529,7 +28787,7 @@ function fontDirectories() {
|
|
|
28529
28787
|
"/System/Library/Fonts/Supplemental"
|
|
28530
28788
|
];
|
|
28531
28789
|
}
|
|
28532
|
-
if (
|
|
28790
|
+
if (platform5() === "win32") {
|
|
28533
28791
|
return [join20(process.env.WINDIR || "C:\\Windows", "Fonts")];
|
|
28534
28792
|
}
|
|
28535
28793
|
return [
|
|
@@ -28551,7 +28809,7 @@ function toFamilyName(fileName) {
|
|
|
28551
28809
|
return family.length >= 2 ? family : null;
|
|
28552
28810
|
}
|
|
28553
28811
|
function collectMacSystemProfilerFonts() {
|
|
28554
|
-
if (
|
|
28812
|
+
if (platform5() !== "darwin") return [];
|
|
28555
28813
|
let parsed;
|
|
28556
28814
|
try {
|
|
28557
28815
|
const raw = execFileSync4("system_profiler", ["SPFontsDataType", "-json"], {
|
|
@@ -28586,7 +28844,7 @@ function collectMacSystemProfilerFonts() {
|
|
|
28586
28844
|
return fonts;
|
|
28587
28845
|
}
|
|
28588
28846
|
function collectFontsFromDir(dir, depth = 0) {
|
|
28589
|
-
if (!
|
|
28847
|
+
if (!existsSync17(dir) || depth > 2) return [];
|
|
28590
28848
|
const fonts = [];
|
|
28591
28849
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
28592
28850
|
const fullPath = join20(dir, entry.name);
|
|
@@ -28857,8 +29115,8 @@ __export(manager_exports2, {
|
|
|
28857
29115
|
findBrowser: () => findBrowser,
|
|
28858
29116
|
isLinuxArm: () => isLinuxArm
|
|
28859
29117
|
});
|
|
28860
|
-
import { execSync, spawnSync as spawnSync2 } from "child_process";
|
|
28861
|
-
import { existsSync as
|
|
29118
|
+
import { execSync as execSync2, spawnSync as spawnSync2 } from "child_process";
|
|
29119
|
+
import { existsSync as existsSync18, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
|
|
28862
29120
|
import { basename as basename2 } from "path";
|
|
28863
29121
|
import { homedir as homedir5 } from "os";
|
|
28864
29122
|
import { join as join21 } from "path";
|
|
@@ -28866,7 +29124,7 @@ import { Browser, detectBrowserPlatform, getInstalledBrowsers, install } from "@
|
|
|
28866
29124
|
function whichBinary2(name) {
|
|
28867
29125
|
try {
|
|
28868
29126
|
const cmd = process.platform === "win32" ? `where ${name}` : `which ${name}`;
|
|
28869
|
-
const output =
|
|
29127
|
+
const output = execSync2(cmd, {
|
|
28870
29128
|
encoding: "utf-8",
|
|
28871
29129
|
stdio: ["pipe", "pipe", "pipe"],
|
|
28872
29130
|
timeout: 5e3
|
|
@@ -28879,7 +29137,7 @@ function whichBinary2(name) {
|
|
|
28879
29137
|
}
|
|
28880
29138
|
function findFromEnv2() {
|
|
28881
29139
|
const envPath = process.env["HYPERFRAMES_BROWSER_PATH"];
|
|
28882
|
-
if (envPath &&
|
|
29140
|
+
if (envPath && existsSync18(envPath)) {
|
|
28883
29141
|
return { executablePath: envPath, source: "env" };
|
|
28884
29142
|
}
|
|
28885
29143
|
return void 0;
|
|
@@ -28889,7 +29147,7 @@ async function findFromCache() {
|
|
|
28889
29147
|
if (fromPuppeteer) {
|
|
28890
29148
|
return fromPuppeteer;
|
|
28891
29149
|
}
|
|
28892
|
-
if (
|
|
29150
|
+
if (existsSync18(CACHE_DIR2)) {
|
|
28893
29151
|
const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR2 });
|
|
28894
29152
|
const match = installed.find((b2) => b2.browser === Browser.CHROMEHEADLESSSHELL);
|
|
28895
29153
|
if (match) {
|
|
@@ -28927,7 +29185,7 @@ function compareVersionDirsDescending(a, b2) {
|
|
|
28927
29185
|
return 0;
|
|
28928
29186
|
}
|
|
28929
29187
|
function findFromPuppeteerCache() {
|
|
28930
|
-
if (!
|
|
29188
|
+
if (!existsSync18(PUPPETEER_CACHE_DIR)) return void 0;
|
|
28931
29189
|
let versions;
|
|
28932
29190
|
try {
|
|
28933
29191
|
versions = [...readdirSync8(PUPPETEER_CACHE_DIR)].sort(compareVersionDirsDescending);
|
|
@@ -28952,7 +29210,7 @@ function findFromPuppeteerCache() {
|
|
|
28952
29210
|
)
|
|
28953
29211
|
];
|
|
28954
29212
|
for (const binary of candidates) {
|
|
28955
|
-
if (
|
|
29213
|
+
if (existsSync18(binary)) {
|
|
28956
29214
|
return { executablePath: binary, source: "cache" };
|
|
28957
29215
|
}
|
|
28958
29216
|
}
|
|
@@ -28979,7 +29237,7 @@ function _resetSystemFallbackWarnForTests() {
|
|
|
28979
29237
|
}
|
|
28980
29238
|
function findFromSystem2() {
|
|
28981
29239
|
for (const p2 of SYSTEM_CHROME_PATHS) {
|
|
28982
|
-
if (
|
|
29240
|
+
if (existsSync18(p2)) {
|
|
28983
29241
|
return { executablePath: p2, source: "system" };
|
|
28984
29242
|
}
|
|
28985
29243
|
}
|
|
@@ -29004,7 +29262,7 @@ async function ensureLinuxArmBrowser(options) {
|
|
|
29004
29262
|
void options;
|
|
29005
29263
|
const existing = await findBrowser();
|
|
29006
29264
|
if (existing) return existing;
|
|
29007
|
-
const hasApt =
|
|
29265
|
+
const hasApt = existsSync18("/usr/bin/apt-get");
|
|
29008
29266
|
if (hasApt) {
|
|
29009
29267
|
console.error(
|
|
29010
29268
|
"\n\u{1F50D} Linux ARM64 detected \u2014 Chrome Headless Shell is not available for this platform."
|
|
@@ -29042,8 +29300,8 @@ Then re-run your command. The HYPERFRAMES_BROWSER_PATH env var persists for the
|
|
|
29042
29300
|
async function ensureBrowser(options) {
|
|
29043
29301
|
const existing = await findBrowser();
|
|
29044
29302
|
if (existing) return existing;
|
|
29045
|
-
const
|
|
29046
|
-
if (!
|
|
29303
|
+
const platform9 = detectBrowserPlatform();
|
|
29304
|
+
if (!platform9) {
|
|
29047
29305
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
|
29048
29306
|
}
|
|
29049
29307
|
if (isLinuxArm()) {
|
|
@@ -29053,13 +29311,13 @@ async function ensureBrowser(options) {
|
|
|
29053
29311
|
cacheDir: CACHE_DIR2,
|
|
29054
29312
|
browser: Browser.CHROMEHEADLESSSHELL,
|
|
29055
29313
|
buildId: CHROME_VERSION,
|
|
29056
|
-
platform:
|
|
29314
|
+
platform: platform9,
|
|
29057
29315
|
downloadProgressCallback: options?.onProgress
|
|
29058
29316
|
});
|
|
29059
29317
|
return { executablePath: installed.executablePath, source: "download" };
|
|
29060
29318
|
}
|
|
29061
29319
|
function clearBrowser() {
|
|
29062
|
-
if (!
|
|
29320
|
+
if (!existsSync18(CACHE_DIR2)) {
|
|
29063
29321
|
return false;
|
|
29064
29322
|
}
|
|
29065
29323
|
rmSync4(CACHE_DIR2, { recursive: true, force: true });
|
|
@@ -29230,7 +29488,7 @@ var init_config2 = __esm({
|
|
|
29230
29488
|
});
|
|
29231
29489
|
|
|
29232
29490
|
// ../engine/src/services/browserManager.ts
|
|
29233
|
-
import { existsSync as
|
|
29491
|
+
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
29234
29492
|
import { join as join22 } from "path";
|
|
29235
29493
|
import { homedir as homedir6 } from "os";
|
|
29236
29494
|
async function getPuppeteer() {
|
|
@@ -29253,7 +29511,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29253
29511
|
return process.env.PRODUCER_HEADLESS_SHELL_PATH;
|
|
29254
29512
|
}
|
|
29255
29513
|
const baseDir = join22(homedir6(), ".cache", "puppeteer", "chrome-headless-shell");
|
|
29256
|
-
if (!
|
|
29514
|
+
if (!existsSync19(baseDir)) return void 0;
|
|
29257
29515
|
try {
|
|
29258
29516
|
const versions = readdirSync9(baseDir).sort().reverse();
|
|
29259
29517
|
for (const version of versions) {
|
|
@@ -29264,7 +29522,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29264
29522
|
join22(baseDir, version, "chrome-headless-shell-win64", "chrome-headless-shell.exe")
|
|
29265
29523
|
];
|
|
29266
29524
|
for (const binary of candidates) {
|
|
29267
|
-
if (
|
|
29525
|
+
if (existsSync19(binary)) return binary;
|
|
29268
29526
|
}
|
|
29269
29527
|
}
|
|
29270
29528
|
} catch {
|
|
@@ -29303,7 +29561,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29303
29561
|
if (mode !== "auto") return Promise.resolve(mode);
|
|
29304
29562
|
if (_autoBrowserGpuModeCache) return _autoBrowserGpuModeCache;
|
|
29305
29563
|
_autoBrowserGpuModeCache = (async () => {
|
|
29306
|
-
const
|
|
29564
|
+
const platform9 = options.platform ?? process.platform;
|
|
29307
29565
|
const browserTimeout = options.browserTimeout ?? DEFAULT_CONFIG2.browserTimeout;
|
|
29308
29566
|
const executablePath = options.chromePath ?? resolveHeadlessShellPath({});
|
|
29309
29567
|
const probeArgs = [
|
|
@@ -29312,7 +29570,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29312
29570
|
"--disable-dev-shm-usage",
|
|
29313
29571
|
"--enable-webgl",
|
|
29314
29572
|
"--ignore-gpu-blocklist",
|
|
29315
|
-
...getBrowserGpuArgs("hardware",
|
|
29573
|
+
...getBrowserGpuArgs("hardware", platform9)
|
|
29316
29574
|
];
|
|
29317
29575
|
const ppt = await getPuppeteer().catch(() => null);
|
|
29318
29576
|
if (!ppt) {
|
|
@@ -29505,7 +29763,7 @@ async function drainBrowserPool() {
|
|
|
29505
29763
|
}
|
|
29506
29764
|
}
|
|
29507
29765
|
function buildChromeArgs(options, config) {
|
|
29508
|
-
const
|
|
29766
|
+
const platform9 = options.platform ?? process.platform;
|
|
29509
29767
|
const gpuDisabled = config?.disableGpu ?? DEFAULT_CONFIG2.disableGpu;
|
|
29510
29768
|
const browserGpuMode = gpuDisabled ? "software" : config?.browserGpuMode ?? DEFAULT_CONFIG2.browserGpuMode;
|
|
29511
29769
|
const chromeArgs = [
|
|
@@ -29515,7 +29773,7 @@ function buildChromeArgs(options, config) {
|
|
|
29515
29773
|
CANVAS_DRAW_ELEMENT_FEATURE_FLAG,
|
|
29516
29774
|
"--enable-webgl",
|
|
29517
29775
|
"--ignore-gpu-blocklist",
|
|
29518
|
-
...getBrowserGpuArgs(browserGpuMode,
|
|
29776
|
+
...getBrowserGpuArgs(browserGpuMode, platform9),
|
|
29519
29777
|
"--font-render-hinting=none",
|
|
29520
29778
|
"--force-color-profile=srgb",
|
|
29521
29779
|
`--window-size=${options.width},${options.height}`,
|
|
@@ -29563,14 +29821,14 @@ function buildChromeArgs(options, config) {
|
|
|
29563
29821
|
}
|
|
29564
29822
|
return chromeArgs;
|
|
29565
29823
|
}
|
|
29566
|
-
function getBrowserGpuArgs(mode,
|
|
29824
|
+
function getBrowserGpuArgs(mode, platform9) {
|
|
29567
29825
|
if (mode === "software") {
|
|
29568
29826
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29569
29827
|
}
|
|
29570
29828
|
if (mode === "auto") {
|
|
29571
29829
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29572
29830
|
}
|
|
29573
|
-
switch (
|
|
29831
|
+
switch (platform9) {
|
|
29574
29832
|
case "darwin":
|
|
29575
29833
|
return ["--use-gl=angle", "--use-angle=metal", "--enable-gpu-rasterization"];
|
|
29576
29834
|
case "win32":
|
|
@@ -29893,7 +30151,7 @@ var init_screenshotService = __esm({
|
|
|
29893
30151
|
});
|
|
29894
30152
|
|
|
29895
30153
|
// ../engine/src/services/frameCapture.ts
|
|
29896
|
-
import { existsSync as
|
|
30154
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
29897
30155
|
import { join as join23 } from "path";
|
|
29898
30156
|
async function driveWarmupTicks(options, state) {
|
|
29899
30157
|
const sleep3 = options.sleep ?? realSleep;
|
|
@@ -29930,7 +30188,7 @@ async function waitForCloseWithTimeout(promise) {
|
|
|
29930
30188
|
return !timedOut;
|
|
29931
30189
|
}
|
|
29932
30190
|
async function createCaptureSession(serverUrl, outputDir, options, onBeforeCapture = null, config) {
|
|
29933
|
-
if (!
|
|
30191
|
+
if (!existsSync20(outputDir)) mkdirSync10(outputDir, { recursive: true });
|
|
29934
30192
|
const headlessShell = resolveHeadlessShellPath(config);
|
|
29935
30193
|
const isLinux = process.platform === "linux";
|
|
29936
30194
|
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
|
|
@@ -30276,7 +30534,7 @@ async function initializeSession(session) {
|
|
|
30276
30534
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
30277
30535
|
try {
|
|
30278
30536
|
const diagnosticsDir = join23(session.outputDir, "diagnostics");
|
|
30279
|
-
if (!
|
|
30537
|
+
if (!existsSync20(diagnosticsDir)) mkdirSync10(diagnosticsDir, { recursive: true });
|
|
30280
30538
|
const base = join23(diagnosticsDir, `frame-error-${frameIndex}`);
|
|
30281
30539
|
await session.page.screenshot({ path: `${base}.png`, type: "png", fullPage: true });
|
|
30282
30540
|
const html = await session.page.content();
|
|
@@ -30439,7 +30697,7 @@ async function closeCaptureSession(session) {
|
|
|
30439
30697
|
session.isInitialized = false;
|
|
30440
30698
|
}
|
|
30441
30699
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
30442
|
-
if (!
|
|
30700
|
+
if (!existsSync20(outputDir)) {
|
|
30443
30701
|
mkdirSync10(outputDir, { recursive: true });
|
|
30444
30702
|
}
|
|
30445
30703
|
session.outputDir = outputDir;
|
|
@@ -30485,6 +30743,43 @@ var init_frameCapture = __esm({
|
|
|
30485
30743
|
}
|
|
30486
30744
|
});
|
|
30487
30745
|
|
|
30746
|
+
// ../engine/src/utils/processTracker.ts
|
|
30747
|
+
function trackChildProcess(proc) {
|
|
30748
|
+
tracked.add(proc);
|
|
30749
|
+
const remove2 = () => tracked.delete(proc);
|
|
30750
|
+
proc.once("exit", remove2);
|
|
30751
|
+
proc.once("error", remove2);
|
|
30752
|
+
}
|
|
30753
|
+
function killTrackedProcesses() {
|
|
30754
|
+
const alive = [];
|
|
30755
|
+
for (const proc of tracked) {
|
|
30756
|
+
if (!proc.killed) {
|
|
30757
|
+
try {
|
|
30758
|
+
proc.kill("SIGTERM");
|
|
30759
|
+
alive.push(proc);
|
|
30760
|
+
} catch {
|
|
30761
|
+
}
|
|
30762
|
+
}
|
|
30763
|
+
}
|
|
30764
|
+
tracked.clear();
|
|
30765
|
+
if (alive.length === 0) return;
|
|
30766
|
+
setTimeout(() => {
|
|
30767
|
+
for (const proc of alive) {
|
|
30768
|
+
try {
|
|
30769
|
+
proc.kill("SIGKILL");
|
|
30770
|
+
} catch {
|
|
30771
|
+
}
|
|
30772
|
+
}
|
|
30773
|
+
}, 500).unref();
|
|
30774
|
+
}
|
|
30775
|
+
var tracked;
|
|
30776
|
+
var init_processTracker = __esm({
|
|
30777
|
+
"../engine/src/utils/processTracker.ts"() {
|
|
30778
|
+
"use strict";
|
|
30779
|
+
tracked = /* @__PURE__ */ new Set();
|
|
30780
|
+
}
|
|
30781
|
+
});
|
|
30782
|
+
|
|
30488
30783
|
// ../engine/src/utils/gpuEncoder.ts
|
|
30489
30784
|
import { spawn as spawn4 } from "child_process";
|
|
30490
30785
|
async function detectGpuEncoder() {
|
|
@@ -30626,6 +30921,7 @@ async function runFfmpeg(args, opts) {
|
|
|
30626
30921
|
const onStderr = opts?.onStderr;
|
|
30627
30922
|
return new Promise((resolve46) => {
|
|
30628
30923
|
const ffmpeg = spawn5("ffmpeg", args);
|
|
30924
|
+
trackChildProcess(ffmpeg);
|
|
30629
30925
|
let stderr = "";
|
|
30630
30926
|
const onAbort = () => {
|
|
30631
30927
|
ffmpeg.kill("SIGTERM");
|
|
@@ -30673,6 +30969,7 @@ var DEFAULT_TIMEOUT, DEFAULT_STDERR_TAIL_LINES;
|
|
|
30673
30969
|
var init_runFfmpeg = __esm({
|
|
30674
30970
|
"../engine/src/utils/runFfmpeg.ts"() {
|
|
30675
30971
|
"use strict";
|
|
30972
|
+
init_processTracker();
|
|
30676
30973
|
DEFAULT_TIMEOUT = 3e5;
|
|
30677
30974
|
DEFAULT_STDERR_TAIL_LINES = 15;
|
|
30678
30975
|
}
|
|
@@ -30680,7 +30977,7 @@ var init_runFfmpeg = __esm({
|
|
|
30680
30977
|
|
|
30681
30978
|
// ../engine/src/services/chunkEncoder.ts
|
|
30682
30979
|
import { spawn as spawn6 } from "child_process";
|
|
30683
|
-
import { copyFileSync, existsSync as
|
|
30980
|
+
import { copyFileSync, existsSync as existsSync21, mkdirSync as mkdirSync11, readdirSync as readdirSync10, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
30684
30981
|
import { join as join24, dirname as dirname7 } from "path";
|
|
30685
30982
|
function getEncoderPreset(quality, format = "mp4", hdr) {
|
|
30686
30983
|
const base = ENCODER_PRESETS[quality];
|
|
@@ -30892,7 +31189,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
30892
31189
|
async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
|
|
30893
31190
|
const startTime = Date.now();
|
|
30894
31191
|
const outputDir = dirname7(outputPath);
|
|
30895
|
-
if (!
|
|
31192
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
30896
31193
|
const files = readdirSync10(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i));
|
|
30897
31194
|
const frameCount = files.length;
|
|
30898
31195
|
if (frameCount === 0) {
|
|
@@ -30914,6 +31211,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
30914
31211
|
const args = buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder);
|
|
30915
31212
|
return new Promise((resolve46) => {
|
|
30916
31213
|
const ffmpeg = spawn6("ffmpeg", args);
|
|
31214
|
+
trackChildProcess(ffmpeg);
|
|
30917
31215
|
let stderr = "";
|
|
30918
31216
|
const onAbort = () => {
|
|
30919
31217
|
ffmpeg.kill("SIGTERM");
|
|
@@ -30958,7 +31256,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
30958
31256
|
});
|
|
30959
31257
|
return;
|
|
30960
31258
|
}
|
|
30961
|
-
const fileSize =
|
|
31259
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
30962
31260
|
resolve46({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
30963
31261
|
});
|
|
30964
31262
|
ffmpeg.on("error", (err) => {
|
|
@@ -30991,7 +31289,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
30991
31289
|
const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
|
|
30992
31290
|
const chunkCount = Math.ceil(files.length / chunkSize);
|
|
30993
31291
|
const chunkDir = join24(dirname7(outputPath), "chunk-encode");
|
|
30994
|
-
if (!
|
|
31292
|
+
if (!existsSync21(chunkDir)) mkdirSync11(chunkDir, { recursive: true });
|
|
30995
31293
|
const chunkPaths = [];
|
|
30996
31294
|
for (let i2 = 0; i2 < chunkCount; i2++) {
|
|
30997
31295
|
if (signal?.aborted) {
|
|
@@ -31024,6 +31322,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31024
31322
|
const args = buildEncoderArgs(options, inputArgs, chunkPath, gpuEncoder);
|
|
31025
31323
|
const chunkResult = await new Promise((resolve46) => {
|
|
31026
31324
|
const ffmpeg = spawn6("ffmpeg", args);
|
|
31325
|
+
trackChildProcess(ffmpeg);
|
|
31027
31326
|
let stderr = "";
|
|
31028
31327
|
ffmpeg.stderr.on("data", (d2) => {
|
|
31029
31328
|
stderr += d2.toString();
|
|
@@ -31065,6 +31364,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31065
31364
|
];
|
|
31066
31365
|
const concatResult = await new Promise((resolve46) => {
|
|
31067
31366
|
const ffmpeg = spawn6("ffmpeg", concatArgs);
|
|
31367
|
+
trackChildProcess(ffmpeg);
|
|
31068
31368
|
let stderr = "";
|
|
31069
31369
|
ffmpeg.stderr.on("data", (d2) => {
|
|
31070
31370
|
stderr += d2.toString();
|
|
@@ -31087,7 +31387,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31087
31387
|
error: concatResult.error
|
|
31088
31388
|
};
|
|
31089
31389
|
}
|
|
31090
|
-
const fileSize =
|
|
31390
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
31091
31391
|
return {
|
|
31092
31392
|
success: true,
|
|
31093
31393
|
outputPath,
|
|
@@ -31098,7 +31398,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31098
31398
|
}
|
|
31099
31399
|
async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
|
|
31100
31400
|
const outputDir = dirname7(outputPath);
|
|
31101
|
-
if (!
|
|
31401
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
31102
31402
|
const isWebm = outputPath.endsWith(".webm");
|
|
31103
31403
|
const isMov = outputPath.endsWith(".mov");
|
|
31104
31404
|
const args = ["-i", videoPath, "-i", audioPath, "-c:v", "copy"];
|
|
@@ -31155,6 +31455,7 @@ var ENCODER_PRESETS;
|
|
|
31155
31455
|
var init_chunkEncoder = __esm({
|
|
31156
31456
|
"../engine/src/services/chunkEncoder.ts"() {
|
|
31157
31457
|
"use strict";
|
|
31458
|
+
init_processTracker();
|
|
31158
31459
|
init_config2();
|
|
31159
31460
|
init_gpuEncoder();
|
|
31160
31461
|
init_hdr();
|
|
@@ -31171,7 +31472,7 @@ var init_chunkEncoder = __esm({
|
|
|
31171
31472
|
|
|
31172
31473
|
// ../engine/src/services/streamingEncoder.ts
|
|
31173
31474
|
import { spawn as spawn7 } from "child_process";
|
|
31174
|
-
import { existsSync as
|
|
31475
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync12, statSync as statSync7 } from "fs";
|
|
31175
31476
|
import { dirname as dirname8 } from "path";
|
|
31176
31477
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
31177
31478
|
let cursor = startFrame;
|
|
@@ -31373,7 +31674,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
31373
31674
|
}
|
|
31374
31675
|
async function spawnStreamingEncoder(outputPath, options, signal, config) {
|
|
31375
31676
|
const outputDir = dirname8(outputPath);
|
|
31376
|
-
if (!
|
|
31677
|
+
if (!existsSync22(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
31377
31678
|
let gpuEncoder = null;
|
|
31378
31679
|
if (options.useGpu) {
|
|
31379
31680
|
gpuEncoder = await getCachedGpuEncoder();
|
|
@@ -31383,6 +31684,7 @@ async function spawnStreamingEncoder(outputPath, options, signal, config) {
|
|
|
31383
31684
|
const ffmpeg = spawn7("ffmpeg", args, {
|
|
31384
31685
|
stdio: ["pipe", "pipe", "pipe"]
|
|
31385
31686
|
});
|
|
31687
|
+
trackChildProcess(ffmpeg);
|
|
31386
31688
|
let exitStatus = "running";
|
|
31387
31689
|
let stderr = "";
|
|
31388
31690
|
let exitCode = null;
|
|
@@ -31469,7 +31771,7 @@ Process error: ${err.message}`;
|
|
|
31469
31771
|
error: formatFfmpegError(exitCode, stderr)
|
|
31470
31772
|
};
|
|
31471
31773
|
}
|
|
31472
|
-
const fileSize =
|
|
31774
|
+
const fileSize = existsSync22(outputPath) ? statSync7(outputPath).size : 0;
|
|
31473
31775
|
return { success: true, durationMs, fileSize };
|
|
31474
31776
|
},
|
|
31475
31777
|
getExitStatus: () => exitStatus
|
|
@@ -31479,6 +31781,7 @@ Process error: ${err.message}`;
|
|
|
31479
31781
|
var init_streamingEncoder = __esm({
|
|
31480
31782
|
"../engine/src/services/streamingEncoder.ts"() {
|
|
31481
31783
|
"use strict";
|
|
31784
|
+
init_processTracker();
|
|
31482
31785
|
init_gpuEncoder();
|
|
31483
31786
|
init_runFfmpeg();
|
|
31484
31787
|
init_hdr();
|
|
@@ -31489,7 +31792,7 @@ var init_streamingEncoder = __esm({
|
|
|
31489
31792
|
|
|
31490
31793
|
// ../engine/src/utils/ffprobe.ts
|
|
31491
31794
|
import { spawn as spawn8 } from "child_process";
|
|
31492
|
-
import { readFileSync as
|
|
31795
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
31493
31796
|
import { extname as extname5 } from "path";
|
|
31494
31797
|
function runFfprobe(args) {
|
|
31495
31798
|
return new Promise((resolve46, reject) => {
|
|
@@ -31583,7 +31886,7 @@ function extractPngMetadataFromBuffer(buf) {
|
|
|
31583
31886
|
function extractStillImageMetadata(filePath) {
|
|
31584
31887
|
if (extname5(filePath).toLowerCase() !== ".png") return null;
|
|
31585
31888
|
try {
|
|
31586
|
-
return extractPngMetadataFromBuffer(
|
|
31889
|
+
return extractPngMetadataFromBuffer(readFileSync20(filePath));
|
|
31587
31890
|
} catch {
|
|
31588
31891
|
return null;
|
|
31589
31892
|
}
|
|
@@ -31770,7 +32073,7 @@ var init_ffprobe = __esm({
|
|
|
31770
32073
|
});
|
|
31771
32074
|
|
|
31772
32075
|
// ../engine/src/utils/urlDownloader.ts
|
|
31773
|
-
import { createWriteStream as createWriteStream2, existsSync as
|
|
32076
|
+
import { createWriteStream as createWriteStream2, existsSync as existsSync23, mkdirSync as mkdirSync13 } from "fs";
|
|
31774
32077
|
import { createHash as createHash3 } from "crypto";
|
|
31775
32078
|
import { join as join25, extname as extname6 } from "path";
|
|
31776
32079
|
import { Readable } from "stream";
|
|
@@ -31783,19 +32086,19 @@ function getFilenameFromUrl(url) {
|
|
|
31783
32086
|
}
|
|
31784
32087
|
async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
|
|
31785
32088
|
const cachedPath = downloadPathCache.get(url);
|
|
31786
|
-
if (cachedPath &&
|
|
32089
|
+
if (cachedPath && existsSync23(cachedPath)) {
|
|
31787
32090
|
return cachedPath;
|
|
31788
32091
|
}
|
|
31789
32092
|
const inFlight = inFlightDownloads.get(url);
|
|
31790
32093
|
if (inFlight) {
|
|
31791
32094
|
return inFlight;
|
|
31792
32095
|
}
|
|
31793
|
-
if (!
|
|
32096
|
+
if (!existsSync23(destDir)) {
|
|
31794
32097
|
mkdirSync13(destDir, { recursive: true });
|
|
31795
32098
|
}
|
|
31796
32099
|
const filename = getFilenameFromUrl(url);
|
|
31797
32100
|
const localPath = join25(destDir, filename);
|
|
31798
|
-
if (
|
|
32101
|
+
if (existsSync23(localPath)) {
|
|
31799
32102
|
downloadPathCache.set(url, localPath);
|
|
31800
32103
|
return localPath;
|
|
31801
32104
|
}
|
|
@@ -32551,7 +32854,7 @@ var init_inlineSubCompositions = __esm({
|
|
|
32551
32854
|
});
|
|
32552
32855
|
|
|
32553
32856
|
// ../core/src/compiler/htmlBundler.ts
|
|
32554
|
-
import { readFileSync as
|
|
32857
|
+
import { readFileSync as readFileSync21, existsSync as existsSync24 } from "fs";
|
|
32555
32858
|
import { join as join26, resolve as resolve14, relative as relative3, dirname as dirname9, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
32556
32859
|
import { transformSync } from "esbuild";
|
|
32557
32860
|
function safePath(projectDir, relativePath) {
|
|
@@ -32599,9 +32902,9 @@ function isRelativeUrl(url) {
|
|
|
32599
32902
|
return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute3(url);
|
|
32600
32903
|
}
|
|
32601
32904
|
function safeReadFile(filePath) {
|
|
32602
|
-
if (!
|
|
32905
|
+
if (!existsSync24(filePath)) return null;
|
|
32603
32906
|
try {
|
|
32604
|
-
return
|
|
32907
|
+
return readFileSync21(filePath, "utf-8");
|
|
32605
32908
|
} catch {
|
|
32606
32909
|
return null;
|
|
32607
32910
|
}
|
|
@@ -32671,9 +32974,9 @@ ${inlined}
|
|
|
32671
32974
|
return rebased;
|
|
32672
32975
|
}
|
|
32673
32976
|
function safeReadFileBuffer(filePath) {
|
|
32674
|
-
if (!
|
|
32977
|
+
if (!existsSync24(filePath)) return null;
|
|
32675
32978
|
try {
|
|
32676
|
-
return
|
|
32979
|
+
return readFileSync21(filePath);
|
|
32677
32980
|
} catch {
|
|
32678
32981
|
return null;
|
|
32679
32982
|
}
|
|
@@ -32975,8 +33278,8 @@ function stripJsCommentsParserSafe(source) {
|
|
|
32975
33278
|
}
|
|
32976
33279
|
async function bundleToSingleHtml(projectDir, options) {
|
|
32977
33280
|
const indexPath = join26(projectDir, "index.html");
|
|
32978
|
-
if (!
|
|
32979
|
-
const rawHtml =
|
|
33281
|
+
if (!existsSync24(indexPath)) throw new Error("index.html not found in project directory");
|
|
33282
|
+
const rawHtml = readFileSync21(indexPath, "utf-8");
|
|
32980
33283
|
const compiled = await compileHtml(rawHtml, projectDir, options?.probeMediaDuration);
|
|
32981
33284
|
const staticGuard = validateHyperframeHtmlContract(compiled);
|
|
32982
33285
|
if (!staticGuard.isValid) {
|
|
@@ -33329,7 +33632,7 @@ var init_htmlTemplate = __esm({
|
|
|
33329
33632
|
// ../engine/src/services/extractionCache.ts
|
|
33330
33633
|
import { createHash as createHash4 } from "crypto";
|
|
33331
33634
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync11, statSync as statSync8, writeFileSync as writeFileSync13 } from "fs";
|
|
33332
|
-
import { existsSync as
|
|
33635
|
+
import { existsSync as existsSync25 } from "fs";
|
|
33333
33636
|
import { join as join27 } from "path";
|
|
33334
33637
|
function readKeyStat(videoPath) {
|
|
33335
33638
|
try {
|
|
@@ -33360,7 +33663,7 @@ function cacheEntryDirName(keyHash) {
|
|
|
33360
33663
|
function lookupCacheEntry(rootDir, input) {
|
|
33361
33664
|
const keyHash = computeCacheKey(input);
|
|
33362
33665
|
const dir = join27(rootDir, cacheEntryDirName(keyHash));
|
|
33363
|
-
const complete =
|
|
33666
|
+
const complete = existsSync25(join27(dir, COMPLETE_SENTINEL));
|
|
33364
33667
|
return { entry: { dir, keyHash }, hit: complete };
|
|
33365
33668
|
}
|
|
33366
33669
|
function ensureCacheEntryDir(entry) {
|
|
@@ -33401,7 +33704,7 @@ var init_extractionCache = __esm({
|
|
|
33401
33704
|
|
|
33402
33705
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
33403
33706
|
import { spawn as spawn9 } from "child_process";
|
|
33404
|
-
import { existsSync as
|
|
33707
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync15, readdirSync as readdirSync12, rmSync as rmSync5 } from "fs";
|
|
33405
33708
|
import { isAbsolute as isAbsolute4, join as join28, posix as posix2, resolve as resolve15, sep as sep4 } from "path";
|
|
33406
33709
|
function parseVideoElements(html) {
|
|
33407
33710
|
const videos = [];
|
|
@@ -33473,7 +33776,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
33473
33776
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
33474
33777
|
const { fps, outputDir, quality = 95 } = options;
|
|
33475
33778
|
const videoOutputDir = outputDirOverride ?? join28(outputDir, videoId);
|
|
33476
|
-
if (!
|
|
33779
|
+
if (!existsSync26(videoOutputDir)) mkdirSync15(videoOutputDir, { recursive: true });
|
|
33477
33780
|
const metadata = await extractMediaMetadata(videoPath);
|
|
33478
33781
|
const format = resolveFrameFormat(metadata, options.format);
|
|
33479
33782
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
|
|
@@ -33499,6 +33802,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
33499
33802
|
args.push("-y", outputPattern);
|
|
33500
33803
|
return new Promise((resolve46, reject) => {
|
|
33501
33804
|
const ffmpeg = spawn9("ffmpeg", args);
|
|
33805
|
+
trackChildProcess(ffmpeg);
|
|
33502
33806
|
let stderr = "";
|
|
33503
33807
|
const onAbort = () => {
|
|
33504
33808
|
ffmpeg.kill("SIGTERM");
|
|
@@ -33661,7 +33965,7 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
|
|
|
33661
33965
|
candidates.push(join28(baseDir, stripped));
|
|
33662
33966
|
}
|
|
33663
33967
|
}
|
|
33664
|
-
return candidates.find(
|
|
33968
|
+
return candidates.find(existsSync26) ?? fromBase;
|
|
33665
33969
|
}
|
|
33666
33970
|
async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
|
|
33667
33971
|
const startTime = Date.now();
|
|
@@ -33695,7 +33999,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
33695
33999
|
mkdirSync15(downloadDir, { recursive: true });
|
|
33696
34000
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
33697
34001
|
}
|
|
33698
|
-
if (!
|
|
34002
|
+
if (!existsSync26(videoPath)) {
|
|
33699
34003
|
if (!warnedSrcs.has(video.src)) {
|
|
33700
34004
|
warnedSrcs.add(video.src);
|
|
33701
34005
|
process.stderr.write(
|
|
@@ -33961,6 +34265,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
33961
34265
|
"../engine/src/services/videoFrameExtractor.ts"() {
|
|
33962
34266
|
"use strict";
|
|
33963
34267
|
init_esm10();
|
|
34268
|
+
init_processTracker();
|
|
33964
34269
|
init_ffprobe();
|
|
33965
34270
|
init_hdr();
|
|
33966
34271
|
init_urlDownloader();
|
|
@@ -34064,7 +34369,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
34064
34369
|
cleanup() {
|
|
34065
34370
|
for (const video of this.videos.values()) {
|
|
34066
34371
|
if (video.extracted.ownedByLookup) continue;
|
|
34067
|
-
if (
|
|
34372
|
+
if (existsSync26(video.extracted.outputDir)) {
|
|
34068
34373
|
rmSync5(video.extracted.outputDir, { recursive: true, force: true });
|
|
34069
34374
|
}
|
|
34070
34375
|
}
|
|
@@ -34468,7 +34773,7 @@ var init_videoFrameInjector = __esm({
|
|
|
34468
34773
|
});
|
|
34469
34774
|
|
|
34470
34775
|
// ../engine/src/services/audioMixer.ts
|
|
34471
|
-
import { existsSync as
|
|
34776
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, rmSync as rmSync6 } from "fs";
|
|
34472
34777
|
import { isAbsolute as isAbsolute5, join as join29, dirname as dirname10 } from "path";
|
|
34473
34778
|
function parseAudioElements(html) {
|
|
34474
34779
|
const elements = [];
|
|
@@ -34520,7 +34825,7 @@ function parseAudioElements(html) {
|
|
|
34520
34825
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
|
|
34521
34826
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34522
34827
|
const outputDir = dirname10(outputPath);
|
|
34523
|
-
if (!
|
|
34828
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34524
34829
|
const args = ["-i", videoPath];
|
|
34525
34830
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
34526
34831
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -34547,7 +34852,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
34547
34852
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config) {
|
|
34548
34853
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34549
34854
|
const outputDir = dirname10(outputPath);
|
|
34550
|
-
if (!
|
|
34855
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34551
34856
|
const args = [
|
|
34552
34857
|
"-ss",
|
|
34553
34858
|
String(mediaStart),
|
|
@@ -34583,7 +34888,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
34583
34888
|
async function generateSilence(outputPath, duration, signal, config) {
|
|
34584
34889
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34585
34890
|
const outputDir = dirname10(outputPath);
|
|
34586
|
-
if (!
|
|
34891
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34587
34892
|
const args = [
|
|
34588
34893
|
"-f",
|
|
34589
34894
|
"lavfi",
|
|
@@ -34626,7 +34931,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
34626
34931
|
};
|
|
34627
34932
|
}
|
|
34628
34933
|
const outputDir = dirname10(outputPath);
|
|
34629
|
-
if (!
|
|
34934
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34630
34935
|
const inputs = [];
|
|
34631
34936
|
const filterParts = [];
|
|
34632
34937
|
tracks.forEach((track, i2) => {
|
|
@@ -34687,7 +34992,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34687
34992
|
const startMs = Date.now();
|
|
34688
34993
|
const tracks = [];
|
|
34689
34994
|
const errors = [];
|
|
34690
|
-
if (!
|
|
34995
|
+
if (!existsSync27(workDir)) mkdirSync16(workDir, { recursive: true });
|
|
34691
34996
|
await Promise.all(
|
|
34692
34997
|
elements.map(async (element) => {
|
|
34693
34998
|
if (signal?.aborted) {
|
|
@@ -34709,7 +35014,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34709
35014
|
return;
|
|
34710
35015
|
}
|
|
34711
35016
|
}
|
|
34712
|
-
if (!
|
|
35017
|
+
if (!existsSync27(srcPath)) {
|
|
34713
35018
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
34714
35019
|
return;
|
|
34715
35020
|
}
|
|
@@ -34873,7 +35178,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
34873
35178
|
|
|
34874
35179
|
// ../engine/src/services/parallelCoordinator.ts
|
|
34875
35180
|
import { cpus as cpus2, freemem as freemem2, totalmem as totalmem2 } from "os";
|
|
34876
|
-
import { existsSync as
|
|
35181
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "fs";
|
|
34877
35182
|
import { copyFile, rename } from "fs/promises";
|
|
34878
35183
|
import { join as join30 } from "path";
|
|
34879
35184
|
function defaultSafeMaxWorkers() {
|
|
@@ -34940,7 +35245,7 @@ function shouldVerifyWorkerGpu(workerId, config) {
|
|
|
34940
35245
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config) {
|
|
34941
35246
|
const startTime = Date.now();
|
|
34942
35247
|
let framesCaptured = 0;
|
|
34943
|
-
if (!
|
|
35248
|
+
if (!existsSync28(task.outputDir)) mkdirSync17(task.outputDir, { recursive: true });
|
|
34944
35249
|
let session = null;
|
|
34945
35250
|
let perf;
|
|
34946
35251
|
try {
|
|
@@ -35035,11 +35340,11 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
35035
35340
|
return results;
|
|
35036
35341
|
}
|
|
35037
35342
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
35038
|
-
if (!
|
|
35343
|
+
if (!existsSync28(outputDir)) mkdirSync17(outputDir, { recursive: true });
|
|
35039
35344
|
let totalFrames = 0;
|
|
35040
35345
|
const sortedTasks = [...tasks].sort((a, b2) => a.startFrame - b2.startFrame);
|
|
35041
35346
|
for (const task of sortedTasks) {
|
|
35042
|
-
if (!
|
|
35347
|
+
if (!existsSync28(task.outputDir)) {
|
|
35043
35348
|
continue;
|
|
35044
35349
|
}
|
|
35045
35350
|
const files = readdirSync13(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
@@ -35083,7 +35388,7 @@ var init_parallelCoordinator = __esm({
|
|
|
35083
35388
|
// ../engine/src/services/fileServer.ts
|
|
35084
35389
|
import { Hono as Hono2 } from "hono";
|
|
35085
35390
|
import { serve } from "@hono/node-server";
|
|
35086
|
-
import { readFileSync as
|
|
35391
|
+
import { readFileSync as readFileSync22, existsSync as existsSync29, statSync as statSync9 } from "fs";
|
|
35087
35392
|
import { join as join31, extname as extname7 } from "path";
|
|
35088
35393
|
function createFileServer(options) {
|
|
35089
35394
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
@@ -35096,20 +35401,20 @@ function createFileServer(options) {
|
|
|
35096
35401
|
const relativePath = requestPath.replace(/^\//, "");
|
|
35097
35402
|
const compiledPath = compiledDir ? join31(compiledDir, relativePath) : null;
|
|
35098
35403
|
const hasCompiledFile = Boolean(
|
|
35099
|
-
compiledPath &&
|
|
35404
|
+
compiledPath && existsSync29(compiledPath) && statSync9(compiledPath).isFile()
|
|
35100
35405
|
);
|
|
35101
35406
|
const filePath = hasCompiledFile ? compiledPath : join31(projectDir, relativePath);
|
|
35102
|
-
if (!
|
|
35407
|
+
if (!existsSync29(filePath) || !statSync9(filePath).isFile()) {
|
|
35103
35408
|
return c3.text("Not found", 404);
|
|
35104
35409
|
}
|
|
35105
35410
|
const ext = extname7(filePath).toLowerCase();
|
|
35106
35411
|
const contentType = MIME_TYPES2[ext] || "application/octet-stream";
|
|
35107
35412
|
if (ext === ".html") {
|
|
35108
|
-
const rawHtml =
|
|
35413
|
+
const rawHtml = readFileSync22(filePath, "utf-8");
|
|
35109
35414
|
const html = relativePath === "index.html" ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime) : rawHtml;
|
|
35110
35415
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
35111
35416
|
}
|
|
35112
|
-
const content =
|
|
35417
|
+
const content = readFileSync22(filePath);
|
|
35113
35418
|
return new Response(content, {
|
|
35114
35419
|
status: 200,
|
|
35115
35420
|
headers: { "Content-Type": contentType }
|
|
@@ -36412,7 +36717,7 @@ var init_shaderTransitions = __esm({
|
|
|
36412
36717
|
});
|
|
36413
36718
|
|
|
36414
36719
|
// ../engine/src/services/hdrCapture.ts
|
|
36415
|
-
import { existsSync as
|
|
36720
|
+
import { existsSync as existsSync30, readdirSync as readdirSync14 } from "fs";
|
|
36416
36721
|
import { join as join32 } from "path";
|
|
36417
36722
|
import { homedir as homedir7 } from "os";
|
|
36418
36723
|
function linearToPQ(L2) {
|
|
@@ -36530,7 +36835,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
36530
36835
|
}
|
|
36531
36836
|
function resolveHeadedChromePath() {
|
|
36532
36837
|
const baseDir = join32(homedir7(), ".cache", "puppeteer", "chrome");
|
|
36533
|
-
if (!
|
|
36838
|
+
if (!existsSync30(baseDir)) return void 0;
|
|
36534
36839
|
const versions = readdirSync14(baseDir).sort().reverse();
|
|
36535
36840
|
for (const version of versions) {
|
|
36536
36841
|
const candidates = [
|
|
@@ -36556,7 +36861,7 @@ function resolveHeadedChromePath() {
|
|
|
36556
36861
|
join32(baseDir, version, "chrome-win64", "chrome.exe")
|
|
36557
36862
|
];
|
|
36558
36863
|
for (const binary of candidates) {
|
|
36559
|
-
if (
|
|
36864
|
+
if (existsSync30(binary)) return binary;
|
|
36560
36865
|
}
|
|
36561
36866
|
}
|
|
36562
36867
|
return void 0;
|
|
@@ -36697,6 +37002,7 @@ __export(src_exports2, {
|
|
|
36697
37002
|
injectVideoFramesBatch: () => injectVideoFramesBatch,
|
|
36698
37003
|
isHdrColorSpace: () => isHdrColorSpace,
|
|
36699
37004
|
isHttpUrl: () => isHttpUrl,
|
|
37005
|
+
killTrackedProcesses: () => killTrackedProcesses,
|
|
36700
37006
|
launchHdrBrowser: () => launchHdrBrowser,
|
|
36701
37007
|
linearToHdr: () => linearToHdr,
|
|
36702
37008
|
mergeWorkerFrames: () => mergeWorkerFrames,
|
|
@@ -36727,6 +37033,7 @@ __export(src_exports2, {
|
|
|
36727
37033
|
showVideoElements: () => showVideoElements,
|
|
36728
37034
|
spawnStreamingEncoder: () => spawnStreamingEncoder,
|
|
36729
37035
|
syncVideoFrameVisibility: () => syncVideoFrameVisibility,
|
|
37036
|
+
trackChildProcess: () => trackChildProcess,
|
|
36730
37037
|
uploadAndReadbackHdrFrame: () => uploadAndReadbackHdrFrame
|
|
36731
37038
|
});
|
|
36732
37039
|
var init_src2 = __esm({
|
|
@@ -36749,6 +37056,7 @@ var init_src2 = __esm({
|
|
|
36749
37056
|
init_ffprobe();
|
|
36750
37057
|
init_urlDownloader();
|
|
36751
37058
|
init_runFfmpeg();
|
|
37059
|
+
init_processTracker();
|
|
36752
37060
|
init_alphaBlit();
|
|
36753
37061
|
init_layerCompositor();
|
|
36754
37062
|
init_shaderTransitions();
|
|
@@ -36825,7 +37133,7 @@ __export(deterministicFonts_exports, {
|
|
|
36825
37133
|
iterateFontFamilyDeclarations: () => iterateFontFamilyDeclarations,
|
|
36826
37134
|
parseFontFamilyValue: () => parseFontFamilyValue
|
|
36827
37135
|
});
|
|
36828
|
-
import { existsSync as
|
|
37136
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync23, writeFileSync as writeFileSync14 } from "fs";
|
|
36829
37137
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
|
|
36830
37138
|
import { join as join33 } from "path";
|
|
36831
37139
|
function parseFontFamilyValue(value) {
|
|
@@ -36954,7 +37262,7 @@ function fontSlug(familyName) {
|
|
|
36954
37262
|
}
|
|
36955
37263
|
function fontCacheDir(slug) {
|
|
36956
37264
|
const dir = join33(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
36957
|
-
if (!
|
|
37265
|
+
if (!existsSync31(dir)) {
|
|
36958
37266
|
mkdirSync18(dir, { recursive: true });
|
|
36959
37267
|
}
|
|
36960
37268
|
return dir;
|
|
@@ -36998,7 +37306,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
36998
37306
|
const woff2Url = match[3] || "";
|
|
36999
37307
|
if (!woff2Url) continue;
|
|
37000
37308
|
const cachePath2 = cachedWoff2Path(slug, weight, style);
|
|
37001
|
-
if (!
|
|
37309
|
+
if (!existsSync31(cachePath2)) {
|
|
37002
37310
|
const woff2What = `Google Fonts woff2 (${weight}/${style})`;
|
|
37003
37311
|
try {
|
|
37004
37312
|
const fontRes = await options.fetchImpl(woff2Url);
|
|
@@ -37018,7 +37326,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
37018
37326
|
continue;
|
|
37019
37327
|
}
|
|
37020
37328
|
}
|
|
37021
|
-
const fontBytes =
|
|
37329
|
+
const fontBytes = readFileSync23(cachePath2);
|
|
37022
37330
|
const dataUri = `data:font/woff2;base64,${fontBytes.toString("base64")}`;
|
|
37023
37331
|
faces.push({ weight, style, dataUri });
|
|
37024
37332
|
}
|
|
@@ -37218,7 +37526,7 @@ var init_deterministicFonts = __esm({
|
|
|
37218
37526
|
|
|
37219
37527
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
37220
37528
|
import { createHash as createHash5 } from "crypto";
|
|
37221
|
-
import { existsSync as
|
|
37529
|
+
import { existsSync as existsSync32, readFileSync as readFileSync24 } from "fs";
|
|
37222
37530
|
import { dirname as dirname11, resolve as resolve16 } from "path";
|
|
37223
37531
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
37224
37532
|
function resolveHyperframeManifestPath() {
|
|
@@ -37231,7 +37539,7 @@ function resolveHyperframeManifestPath() {
|
|
|
37231
37539
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
37232
37540
|
];
|
|
37233
37541
|
for (const candidate of candidates) {
|
|
37234
|
-
if (
|
|
37542
|
+
if (existsSync32(candidate)) {
|
|
37235
37543
|
return candidate;
|
|
37236
37544
|
}
|
|
37237
37545
|
}
|
|
@@ -37242,12 +37550,12 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
37242
37550
|
}
|
|
37243
37551
|
function resolveVerifiedHyperframeRuntime() {
|
|
37244
37552
|
const manifestPath = resolveHyperframeManifestPath();
|
|
37245
|
-
if (!
|
|
37553
|
+
if (!existsSync32(manifestPath)) {
|
|
37246
37554
|
throw new Error(
|
|
37247
37555
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
37248
37556
|
);
|
|
37249
37557
|
}
|
|
37250
|
-
const manifestRaw =
|
|
37558
|
+
const manifestRaw = readFileSync24(manifestPath, "utf8");
|
|
37251
37559
|
const manifest = JSON.parse(manifestRaw);
|
|
37252
37560
|
const runtimeFileName = manifest.artifacts?.iife;
|
|
37253
37561
|
if (!runtimeFileName || !manifest.sha256) {
|
|
@@ -37256,10 +37564,10 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
37256
37564
|
);
|
|
37257
37565
|
}
|
|
37258
37566
|
const runtimePath = resolve16(dirname11(manifestPath), runtimeFileName);
|
|
37259
|
-
if (!
|
|
37567
|
+
if (!existsSync32(runtimePath)) {
|
|
37260
37568
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
37261
37569
|
}
|
|
37262
|
-
const runtimeSource =
|
|
37570
|
+
const runtimeSource = readFileSync24(runtimePath, "utf8");
|
|
37263
37571
|
const runtimeSha = createHash5("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
37264
37572
|
if (runtimeSha !== manifest.sha256) {
|
|
37265
37573
|
throw new Error(
|
|
@@ -37298,7 +37606,7 @@ var init_hyperframeRuntimeLoader = __esm({
|
|
|
37298
37606
|
// ../producer/src/services/fileServer.ts
|
|
37299
37607
|
import { Hono as Hono3 } from "hono";
|
|
37300
37608
|
import { serve as serve2 } from "@hono/node-server";
|
|
37301
|
-
import { readFileSync as
|
|
37609
|
+
import { readFileSync as readFileSync25, existsSync as existsSync33, realpathSync, statSync as statSync10 } from "fs";
|
|
37302
37610
|
import { join as join34, extname as extname8, resolve as resolve17, sep as sep5 } from "path";
|
|
37303
37611
|
function isPathInside(child, parent, options = {}) {
|
|
37304
37612
|
const { resolveSymlinks = false, pathModule } = options;
|
|
@@ -37306,8 +37614,8 @@ function isPathInside(child, parent, options = {}) {
|
|
|
37306
37614
|
const separator = pathModule?.sep ?? sep5;
|
|
37307
37615
|
const resolvedChild = resolveFn(child);
|
|
37308
37616
|
const resolvedParent = resolveFn(parent);
|
|
37309
|
-
const normalizedChild = resolveSymlinks &&
|
|
37310
|
-
const normalizedParent = resolveSymlinks &&
|
|
37617
|
+
const normalizedChild = resolveSymlinks && existsSync33(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
37618
|
+
const normalizedParent = resolveSymlinks && existsSync33(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
37311
37619
|
if (normalizedChild === normalizedParent) return true;
|
|
37312
37620
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
37313
37621
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -37474,13 +37782,13 @@ function createFileServer2(options) {
|
|
|
37474
37782
|
let filePath = null;
|
|
37475
37783
|
if (compiledDir) {
|
|
37476
37784
|
const candidate = join34(compiledDir, relativePath);
|
|
37477
|
-
if (
|
|
37785
|
+
if (existsSync33(candidate) && isPathInside(candidate, compiledDir) && statSync10(candidate).isFile()) {
|
|
37478
37786
|
filePath = candidate;
|
|
37479
37787
|
}
|
|
37480
37788
|
}
|
|
37481
37789
|
if (!filePath) {
|
|
37482
37790
|
const candidate = join34(projectDir, relativePath);
|
|
37483
|
-
if (
|
|
37791
|
+
if (existsSync33(candidate) && isPathInside(candidate, projectDir) && statSync10(candidate).isFile()) {
|
|
37484
37792
|
filePath = candidate;
|
|
37485
37793
|
}
|
|
37486
37794
|
}
|
|
@@ -37493,7 +37801,7 @@ function createFileServer2(options) {
|
|
|
37493
37801
|
const ext = extname8(filePath).toLowerCase();
|
|
37494
37802
|
const contentType = MIME_TYPES3[ext] || "application/octet-stream";
|
|
37495
37803
|
if (ext === ".html") {
|
|
37496
|
-
const rawHtml =
|
|
37804
|
+
const rawHtml = readFileSync25(filePath, "utf-8");
|
|
37497
37805
|
const isIndex = relativePath === "index.html";
|
|
37498
37806
|
let html = rawHtml;
|
|
37499
37807
|
if (preHeadScripts.length > 0) {
|
|
@@ -37502,7 +37810,7 @@ function createFileServer2(options) {
|
|
|
37502
37810
|
html = isIndex ? injectScriptsIntoHtml(html, headScripts, bodyScripts, stripEmbeddedRuntime) : html;
|
|
37503
37811
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
37504
37812
|
}
|
|
37505
|
-
const content =
|
|
37813
|
+
const content = readFileSync25(filePath);
|
|
37506
37814
|
return new Response(content, {
|
|
37507
37815
|
status: 200,
|
|
37508
37816
|
headers: { "Content-Type": contentType }
|
|
@@ -37847,7 +38155,7 @@ var init_paths = __esm({
|
|
|
37847
38155
|
});
|
|
37848
38156
|
|
|
37849
38157
|
// ../producer/src/services/render/shared.ts
|
|
37850
|
-
import { copyFileSync as copyFileSync2, cpSync, existsSync as
|
|
38158
|
+
import { copyFileSync as copyFileSync2, cpSync, existsSync as existsSync34, mkdirSync as mkdirSync19, symlinkSync, writeFileSync as writeFileSync15 } from "fs";
|
|
37851
38159
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute6, join as join36, relative as relative4, resolve as resolve18 } from "path";
|
|
37852
38160
|
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
37853
38161
|
return browserEnd + (existingStart - browserStart);
|
|
@@ -38034,7 +38342,7 @@ var init_shared = __esm({
|
|
|
38034
38342
|
isAbsolute: isAbsolute6
|
|
38035
38343
|
};
|
|
38036
38344
|
materializeFileSystem = {
|
|
38037
|
-
existsSync:
|
|
38345
|
+
existsSync: existsSync34,
|
|
38038
38346
|
mkdirSync: mkdirSync19,
|
|
38039
38347
|
symlinkSync,
|
|
38040
38348
|
cpSync
|
|
@@ -38570,7 +38878,7 @@ var init_urlDownloader2 = __esm({
|
|
|
38570
38878
|
});
|
|
38571
38879
|
|
|
38572
38880
|
// ../producer/src/services/htmlCompiler.ts
|
|
38573
|
-
import { readFileSync as
|
|
38881
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35, mkdirSync as mkdirSync20 } from "fs";
|
|
38574
38882
|
import { join as join38, dirname as dirname13, resolve as resolve19 } from "path";
|
|
38575
38883
|
function dedupeElementsById(elements) {
|
|
38576
38884
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -38632,7 +38940,7 @@ function detectShaderTransitionUsage(html) {
|
|
|
38632
38940
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
38633
38941
|
let filePath = src;
|
|
38634
38942
|
if (isHttpUrl(src)) {
|
|
38635
|
-
if (!
|
|
38943
|
+
if (!existsSync35(downloadDir)) mkdirSync20(downloadDir, { recursive: true });
|
|
38636
38944
|
try {
|
|
38637
38945
|
filePath = await downloadToTemp(src, downloadDir);
|
|
38638
38946
|
} catch {
|
|
@@ -38641,7 +38949,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
38641
38949
|
} else if (!filePath.startsWith("/")) {
|
|
38642
38950
|
filePath = join38(baseDir, filePath);
|
|
38643
38951
|
}
|
|
38644
|
-
if (!
|
|
38952
|
+
if (!existsSync35(filePath)) {
|
|
38645
38953
|
return { duration: 0, resolvedPath: filePath };
|
|
38646
38954
|
}
|
|
38647
38955
|
let metadata;
|
|
@@ -38719,10 +39027,10 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
38719
39027
|
if (visited.has(filePath)) {
|
|
38720
39028
|
continue;
|
|
38721
39029
|
}
|
|
38722
|
-
if (!
|
|
39030
|
+
if (!existsSync35(filePath)) {
|
|
38723
39031
|
continue;
|
|
38724
39032
|
}
|
|
38725
|
-
const rawSubHtml =
|
|
39033
|
+
const rawSubHtml = readFileSync26(filePath, "utf-8");
|
|
38726
39034
|
const nestedVisited = new Set(visited);
|
|
38727
39035
|
nestedVisited.add(filePath);
|
|
38728
39036
|
workItems.push({ srcPath, absoluteStart, absoluteEnd, filePath, rawSubHtml, nestedVisited });
|
|
@@ -38907,8 +39215,8 @@ function inlineSubCompositions2(html, subCompositions, projectDir) {
|
|
|
38907
39215
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
38908
39216
|
if (!compHtml) {
|
|
38909
39217
|
const filePath = resolve19(projectDir, srcPath);
|
|
38910
|
-
if (
|
|
38911
|
-
compHtml =
|
|
39218
|
+
if (existsSync35(filePath)) {
|
|
39219
|
+
compHtml = readFileSync26(filePath, "utf-8");
|
|
38912
39220
|
}
|
|
38913
39221
|
}
|
|
38914
39222
|
return compHtml;
|
|
@@ -39065,7 +39373,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
39065
39373
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
39066
39374
|
return null;
|
|
39067
39375
|
}
|
|
39068
|
-
if (!
|
|
39376
|
+
if (!existsSync35(absPath)) return null;
|
|
39069
39377
|
const safeKey = toExternalAssetKey(absPath);
|
|
39070
39378
|
externalAssets.set(safeKey, absPath);
|
|
39071
39379
|
return safeKey;
|
|
@@ -39115,7 +39423,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39115
39423
|
(full, prefix, src, file, suffix) => {
|
|
39116
39424
|
if (/^https?:\/\//i.test(src)) return full;
|
|
39117
39425
|
const absPath = resolve19(projectDir, src);
|
|
39118
|
-
if (
|
|
39426
|
+
if (existsSync35(absPath)) return full;
|
|
39119
39427
|
console.log(
|
|
39120
39428
|
`[Compiler] Rewriting missing gsap script to CDN: ${src} \u2192 ${GSAP_CDN_BASE}${file}`
|
|
39121
39429
|
);
|
|
@@ -39124,7 +39432,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39124
39432
|
);
|
|
39125
39433
|
}
|
|
39126
39434
|
async function compileForRender(projectDir, htmlPath, downloadDir, options = {}) {
|
|
39127
|
-
const rawHtml = rewriteUnresolvableGsapToCdn(
|
|
39435
|
+
const rawHtml = rewriteUnresolvableGsapToCdn(readFileSync26(htmlPath, "utf-8"), projectDir);
|
|
39128
39436
|
const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
|
|
39129
39437
|
rawHtml,
|
|
39130
39438
|
projectDir,
|
|
@@ -39746,7 +40054,7 @@ var init_probeStage = __esm({
|
|
|
39746
40054
|
});
|
|
39747
40055
|
|
|
39748
40056
|
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
39749
|
-
import { existsSync as
|
|
40057
|
+
import { existsSync as existsSync36 } from "fs";
|
|
39750
40058
|
import { isAbsolute as isAbsolute7, join as join41 } from "path";
|
|
39751
40059
|
async function runExtractVideosStage(input) {
|
|
39752
40060
|
const {
|
|
@@ -39770,7 +40078,7 @@ async function runExtractVideosStage(input) {
|
|
|
39770
40078
|
await Promise.all(
|
|
39771
40079
|
composition.videos.map(async (v2) => {
|
|
39772
40080
|
const videoPath = isAbsolute7(v2.src) ? v2.src : resolveProjectRelativeSrc(v2.src, projectDir, compiledDir);
|
|
39773
|
-
if (!
|
|
40081
|
+
if (!existsSync36(videoPath)) return;
|
|
39774
40082
|
const meta = await extractMediaMetadata(videoPath);
|
|
39775
40083
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39776
40084
|
nativeHdrVideoIds.add(v2.id);
|
|
@@ -39788,10 +40096,10 @@ async function runExtractVideosStage(input) {
|
|
|
39788
40096
|
composition.images.map(async (img) => {
|
|
39789
40097
|
let imgPath = img.src;
|
|
39790
40098
|
if (!imgPath.startsWith("/")) {
|
|
39791
|
-
const fromCompiled =
|
|
40099
|
+
const fromCompiled = existsSync36(join41(compiledDir, imgPath)) ? join41(compiledDir, imgPath) : join41(projectDir, imgPath);
|
|
39792
40100
|
imgPath = fromCompiled;
|
|
39793
40101
|
}
|
|
39794
|
-
if (!
|
|
40102
|
+
if (!existsSync36(imgPath)) return null;
|
|
39795
40103
|
const meta = await extractMediaMetadata(imgPath);
|
|
39796
40104
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39797
40105
|
nativeHdrImageIds.add(img.id);
|
|
@@ -40266,7 +40574,7 @@ var init_hdrImageTransferCache = __esm({
|
|
|
40266
40574
|
});
|
|
40267
40575
|
|
|
40268
40576
|
// ../producer/src/services/render/stages/captureHdrResources.ts
|
|
40269
|
-
import { mkdirSync as mkdirSync21, openSync, readFileSync as
|
|
40577
|
+
import { mkdirSync as mkdirSync21, openSync, readFileSync as readFileSync27, statSync as statSync11 } from "fs";
|
|
40270
40578
|
import { join as join43 } from "path";
|
|
40271
40579
|
function planHdrResources(args) {
|
|
40272
40580
|
const { composition, nativeHdrVideoIds, nativeHdrImageIds, projectDir, compiledDir } = args;
|
|
@@ -40411,7 +40719,7 @@ function decodeHdrImageBuffers(args) {
|
|
|
40411
40719
|
const out = /* @__PURE__ */ new Map();
|
|
40412
40720
|
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
40413
40721
|
try {
|
|
40414
|
-
const decoded = decodePngToRgb48le(
|
|
40722
|
+
const decoded = decodePngToRgb48le(readFileSync27(srcPath));
|
|
40415
40723
|
const layout2 = prep.hdrExtractionDims.get(imageId);
|
|
40416
40724
|
const fitInfo = prep.hdrImageFitInfo.get(imageId);
|
|
40417
40725
|
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
@@ -40849,7 +41157,7 @@ import { Worker } from "worker_threads";
|
|
|
40849
41157
|
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
40850
41158
|
import { dirname as dirname14, join as join45 } from "path";
|
|
40851
41159
|
import { createRequire } from "module";
|
|
40852
|
-
import { existsSync as
|
|
41160
|
+
import { existsSync as existsSync37 } from "fs";
|
|
40853
41161
|
import { cpus as cpus3 } from "os";
|
|
40854
41162
|
function resolveWorkerEntry(explicit) {
|
|
40855
41163
|
if (explicit && explicit.length > 0) {
|
|
@@ -40862,7 +41170,7 @@ function resolveWorkerEntry(explicit) {
|
|
|
40862
41170
|
}
|
|
40863
41171
|
const moduleDir = dirname14(fileURLToPath3(import.meta.url));
|
|
40864
41172
|
const jsPath = join45(moduleDir, "shaderTransitionWorker.js");
|
|
40865
|
-
if (
|
|
41173
|
+
if (existsSync37(jsPath)) return { path: jsPath, isTs: false };
|
|
40866
41174
|
const tsPath = join45(moduleDir, "shaderTransitionWorker.ts");
|
|
40867
41175
|
return { path: tsPath, isTs: true };
|
|
40868
41176
|
}
|
|
@@ -41271,7 +41579,7 @@ var init_captureHdrHybridLoop = __esm({
|
|
|
41271
41579
|
});
|
|
41272
41580
|
|
|
41273
41581
|
// ../producer/src/services/render/stages/captureHdrStage.ts
|
|
41274
|
-
import { existsSync as
|
|
41582
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync22 } from "fs";
|
|
41275
41583
|
import { join as join47 } from "path";
|
|
41276
41584
|
async function runCaptureHdrStage(input) {
|
|
41277
41585
|
const {
|
|
@@ -41328,7 +41636,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41328
41636
|
nativeHdrImageIds,
|
|
41329
41637
|
projectDir,
|
|
41330
41638
|
compiledDir,
|
|
41331
|
-
existsSync:
|
|
41639
|
+
existsSync: existsSync38
|
|
41332
41640
|
});
|
|
41333
41641
|
const domSession = await createCaptureSession(
|
|
41334
41642
|
fileServer.url,
|
|
@@ -41432,7 +41740,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41432
41740
|
}
|
|
41433
41741
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
41434
41742
|
const debugDumpDir = debugDumpEnabled ? join47(framesDir, "debug-composite") : null;
|
|
41435
|
-
if (debugDumpDir && !
|
|
41743
|
+
if (debugDumpDir && !existsSync38(debugDumpDir)) {
|
|
41436
41744
|
mkdirSync22(debugDumpDir, { recursive: true });
|
|
41437
41745
|
}
|
|
41438
41746
|
const compositeTransfer = resolveCompositeTransfer(hasHdrContent, effectiveHdr);
|
|
@@ -41588,7 +41896,7 @@ var init_captureHdrStage = __esm({
|
|
|
41588
41896
|
});
|
|
41589
41897
|
|
|
41590
41898
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
41591
|
-
import { copyFileSync as copyFileSync3, existsSync as
|
|
41899
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync39, mkdirSync as mkdirSync23, readdirSync as readdirSync15 } from "fs";
|
|
41592
41900
|
import { join as join48 } from "path";
|
|
41593
41901
|
async function runEncodeStage(input) {
|
|
41594
41902
|
const {
|
|
@@ -41615,7 +41923,7 @@ async function runEncodeStage(input) {
|
|
|
41615
41923
|
const stage5Start = Date.now();
|
|
41616
41924
|
if (isPngSequence) {
|
|
41617
41925
|
updateJobStatus(job, "encoding", "Writing PNG sequence", 75, onProgress);
|
|
41618
|
-
if (!
|
|
41926
|
+
if (!existsSync39(outputPath)) mkdirSync23(outputPath, { recursive: true });
|
|
41619
41927
|
const captured = readdirSync15(framesDir).filter((name) => name.endsWith(".png")).sort();
|
|
41620
41928
|
if (captured.length === 0) {
|
|
41621
41929
|
throw new Error(
|
|
@@ -41626,7 +41934,7 @@ async function runEncodeStage(input) {
|
|
|
41626
41934
|
const dst = join48(outputPath, `frame_${String(i2 + 1).padStart(6, "0")}.png`);
|
|
41627
41935
|
copyFileSync3(join48(framesDir, name), dst);
|
|
41628
41936
|
});
|
|
41629
|
-
if (hasAudio && audioOutputPath &&
|
|
41937
|
+
if (hasAudio && audioOutputPath && existsSync39(audioOutputPath)) {
|
|
41630
41938
|
copyFileSync3(audioOutputPath, join48(outputPath, "audio.aac"));
|
|
41631
41939
|
log2.info(`[Render] png-sequence: audio.aac sidecar written to ${outputPath}/audio.aac`);
|
|
41632
41940
|
}
|
|
@@ -41718,9 +42026,9 @@ var init_assembleStage = __esm({
|
|
|
41718
42026
|
|
|
41719
42027
|
// ../producer/src/services/renderOrchestrator.ts
|
|
41720
42028
|
import {
|
|
41721
|
-
existsSync as
|
|
42029
|
+
existsSync as existsSync40,
|
|
41722
42030
|
mkdirSync as mkdirSync24,
|
|
41723
|
-
readFileSync as
|
|
42031
|
+
readFileSync as readFileSync28,
|
|
41724
42032
|
readSync,
|
|
41725
42033
|
closeSync,
|
|
41726
42034
|
readdirSync as readdirSync16,
|
|
@@ -41833,7 +42141,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
|
|
|
41833
42141
|
let rangeStart = null;
|
|
41834
42142
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41835
42143
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41836
|
-
const missing = !
|
|
42144
|
+
const missing = !existsSync40(framePath);
|
|
41837
42145
|
if (missing && rangeStart === null) {
|
|
41838
42146
|
rangeStart = frameIndex;
|
|
41839
42147
|
} else if (!missing && rangeStart !== null) {
|
|
@@ -41875,7 +42183,7 @@ function countCapturedFrames(totalFrames, framesDir, frameExt) {
|
|
|
41875
42183
|
let captured = 0;
|
|
41876
42184
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41877
42185
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41878
|
-
if (
|
|
42186
|
+
if (existsSync40(framePath)) captured++;
|
|
41879
42187
|
}
|
|
41880
42188
|
return captured;
|
|
41881
42189
|
}
|
|
@@ -42446,28 +42754,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42446
42754
|
};
|
|
42447
42755
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
42448
42756
|
assertNotAborted();
|
|
42449
|
-
if (!
|
|
42757
|
+
if (!existsSync40(workDir)) mkdirSync24(workDir, { recursive: true });
|
|
42450
42758
|
if (job.config.debug) {
|
|
42451
42759
|
const logPath = join49(workDir, "render.log");
|
|
42452
42760
|
restoreLogger = installDebugLogger(logPath, log2);
|
|
42453
42761
|
}
|
|
42454
42762
|
const entryFile = job.config.entryFile || "index.html";
|
|
42455
42763
|
let htmlPath = join49(projectDir, entryFile);
|
|
42456
|
-
if (!
|
|
42764
|
+
if (!existsSync40(htmlPath)) {
|
|
42457
42765
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
42458
42766
|
}
|
|
42459
42767
|
assertNotAborted();
|
|
42460
|
-
const rawEntry =
|
|
42768
|
+
const rawEntry = readFileSync28(htmlPath, "utf-8");
|
|
42461
42769
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
42462
42770
|
const wrapperPath = join49(workDir, "standalone-entry.html");
|
|
42463
42771
|
const projectIndexPath = join49(projectDir, "index.html");
|
|
42464
|
-
if (!
|
|
42772
|
+
if (!existsSync40(projectIndexPath)) {
|
|
42465
42773
|
throw new Error(
|
|
42466
42774
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
42467
42775
|
);
|
|
42468
42776
|
}
|
|
42469
42777
|
const standaloneHtml = extractStandaloneEntryFromIndex(
|
|
42470
|
-
|
|
42778
|
+
readFileSync28(projectIndexPath, "utf-8"),
|
|
42471
42779
|
entryFile
|
|
42472
42780
|
);
|
|
42473
42781
|
if (!standaloneHtml) {
|
|
@@ -42578,7 +42886,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42578
42886
|
assertNotAborted();
|
|
42579
42887
|
}
|
|
42580
42888
|
const framesDir = join49(workDir, "captured-frames");
|
|
42581
|
-
if (!
|
|
42889
|
+
if (!existsSync40(framesDir)) mkdirSync24(framesDir, { recursive: true });
|
|
42582
42890
|
const captureOptions = {
|
|
42583
42891
|
width,
|
|
42584
42892
|
height,
|
|
@@ -42833,7 +43141,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42833
43141
|
job.outputPath = outputPath;
|
|
42834
43142
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
42835
43143
|
const totalElapsed = Date.now() - pipelineStart;
|
|
42836
|
-
const tmpPeakBytes =
|
|
43144
|
+
const tmpPeakBytes = existsSync40(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
42837
43145
|
const perfSummary = buildRenderPerfSummary({
|
|
42838
43146
|
job,
|
|
42839
43147
|
workerCount,
|
|
@@ -42868,7 +43176,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42868
43176
|
}
|
|
42869
43177
|
}
|
|
42870
43178
|
if (job.config.debug) {
|
|
42871
|
-
if (!isPngSequence &&
|
|
43179
|
+
if (!isPngSequence && existsSync40(outputPath)) {
|
|
42872
43180
|
const debugOutput = join49(workDir, `output${videoExt}`);
|
|
42873
43181
|
copyFileSync4(outputPath, debugOutput);
|
|
42874
43182
|
}
|
|
@@ -42995,7 +43303,7 @@ var init_config3 = __esm({
|
|
|
42995
43303
|
});
|
|
42996
43304
|
|
|
42997
43305
|
// ../producer/src/services/hyperframeLint.ts
|
|
42998
|
-
import { existsSync as
|
|
43306
|
+
import { existsSync as existsSync41, readFileSync as readFileSync29, statSync as statSync13 } from "fs";
|
|
42999
43307
|
import { resolve as resolve21, join as join50 } from "path";
|
|
43000
43308
|
function isStringRecord(value) {
|
|
43001
43309
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -43024,7 +43332,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
43024
43332
|
}
|
|
43025
43333
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
43026
43334
|
const absProjectDir = resolve21(projectDir);
|
|
43027
|
-
if (!
|
|
43335
|
+
if (!existsSync41(absProjectDir) || !statSync13(absProjectDir).isDirectory()) {
|
|
43028
43336
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43029
43337
|
}
|
|
43030
43338
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -43035,10 +43343,10 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
43035
43343
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
43036
43344
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
43037
43345
|
}
|
|
43038
|
-
if (
|
|
43346
|
+
if (existsSync41(absoluteEntryPath) && statSync13(absoluteEntryPath).isFile()) {
|
|
43039
43347
|
return {
|
|
43040
43348
|
entryFile,
|
|
43041
|
-
html:
|
|
43349
|
+
html: readFileSync29(absoluteEntryPath, "utf-8"),
|
|
43042
43350
|
source: "projectDir"
|
|
43043
43351
|
};
|
|
43044
43352
|
}
|
|
@@ -43133,7 +43441,7 @@ var init_semaphore = __esm({
|
|
|
43133
43441
|
|
|
43134
43442
|
// ../producer/src/server.ts
|
|
43135
43443
|
import {
|
|
43136
|
-
existsSync as
|
|
43444
|
+
existsSync as existsSync42,
|
|
43137
43445
|
mkdirSync as mkdirSync25,
|
|
43138
43446
|
statSync as statSync14,
|
|
43139
43447
|
mkdtempSync as mkdtempSync2,
|
|
@@ -43166,11 +43474,11 @@ async function prepareRenderBody(body) {
|
|
|
43166
43474
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
43167
43475
|
if (projectDir) {
|
|
43168
43476
|
const absProjectDir = resolve22(projectDir);
|
|
43169
|
-
if (!
|
|
43477
|
+
if (!existsSync42(absProjectDir) || !statSync14(absProjectDir).isDirectory()) {
|
|
43170
43478
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43171
43479
|
}
|
|
43172
43480
|
const entry = options.entryFile || "index.html";
|
|
43173
|
-
if (!
|
|
43481
|
+
if (!existsSync42(resolve22(absProjectDir, entry))) {
|
|
43174
43482
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
43175
43483
|
}
|
|
43176
43484
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -43319,8 +43627,8 @@ function createRenderHandlers(options = {}) {
|
|
|
43319
43627
|
log2
|
|
43320
43628
|
);
|
|
43321
43629
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43322
|
-
if (!
|
|
43323
|
-
const
|
|
43630
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43631
|
+
const release4 = await renderSemaphore.acquire();
|
|
43324
43632
|
log2.info("render started", {
|
|
43325
43633
|
requestId,
|
|
43326
43634
|
projectDir: input.projectDir,
|
|
@@ -43346,7 +43654,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43346
43654
|
log2.info(`render progress ${pct}%`, { requestId, stage: j3.currentStage, message });
|
|
43347
43655
|
}
|
|
43348
43656
|
});
|
|
43349
|
-
const fileSize =
|
|
43657
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43350
43658
|
const durationMs = Date.now() - t0;
|
|
43351
43659
|
const outputToken = store.register(absoluteOutputPath);
|
|
43352
43660
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -43388,7 +43696,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43388
43696
|
500
|
|
43389
43697
|
);
|
|
43390
43698
|
} finally {
|
|
43391
|
-
|
|
43699
|
+
release4();
|
|
43392
43700
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43393
43701
|
}
|
|
43394
43702
|
};
|
|
@@ -43430,7 +43738,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43430
43738
|
log2
|
|
43431
43739
|
);
|
|
43432
43740
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43433
|
-
if (!
|
|
43741
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43434
43742
|
log2.info("render-stream started", { requestId, projectDir: input.projectDir });
|
|
43435
43743
|
const job = createRenderJob({
|
|
43436
43744
|
fps: input.fps,
|
|
@@ -43454,7 +43762,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43454
43762
|
})
|
|
43455
43763
|
});
|
|
43456
43764
|
}
|
|
43457
|
-
const
|
|
43765
|
+
const release4 = await renderSemaphore.acquire();
|
|
43458
43766
|
try {
|
|
43459
43767
|
await executeRenderJob(
|
|
43460
43768
|
job,
|
|
@@ -43475,7 +43783,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43475
43783
|
},
|
|
43476
43784
|
abortController.signal
|
|
43477
43785
|
);
|
|
43478
|
-
const fileSize =
|
|
43786
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43479
43787
|
const outputToken = store.register(absoluteOutputPath);
|
|
43480
43788
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
43481
43789
|
log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -43522,7 +43830,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43522
43830
|
})
|
|
43523
43831
|
});
|
|
43524
43832
|
} finally {
|
|
43525
|
-
|
|
43833
|
+
release4();
|
|
43526
43834
|
c3.req.raw.signal.removeEventListener("abort", onRequestAbort);
|
|
43527
43835
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43528
43836
|
}
|
|
@@ -43534,7 +43842,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43534
43842
|
if (!artifact) {
|
|
43535
43843
|
return c3.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
43536
43844
|
}
|
|
43537
|
-
if (!
|
|
43845
|
+
if (!existsSync42(artifact.path)) {
|
|
43538
43846
|
store.delete(token);
|
|
43539
43847
|
return c3.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
43540
43848
|
}
|
|
@@ -43688,7 +43996,7 @@ var init_planHash = __esm({
|
|
|
43688
43996
|
});
|
|
43689
43997
|
|
|
43690
43998
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
43691
|
-
import { existsSync as
|
|
43999
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync26, readFileSync as readFileSync30, readdirSync as readdirSync17, writeFileSync as writeFileSync20 } from "fs";
|
|
43692
44000
|
import { join as join52, relative as relative5, resolve as resolve23 } from "path";
|
|
43693
44001
|
function stripUndefined(value) {
|
|
43694
44002
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -43731,11 +44039,11 @@ function collectPlanAssetShas(planDir) {
|
|
|
43731
44039
|
const assets = [];
|
|
43732
44040
|
for (const file of files) {
|
|
43733
44041
|
if (file.planRelativePath === COMPILED_INDEX_RELATIVE_PATH) {
|
|
43734
|
-
compositionHtml =
|
|
44042
|
+
compositionHtml = readFileSync30(file.absolutePath);
|
|
43735
44043
|
continue;
|
|
43736
44044
|
}
|
|
43737
44045
|
if (HASH_EXCLUDED_PLAN_FILES.has(file.planRelativePath)) continue;
|
|
43738
|
-
const bytes =
|
|
44046
|
+
const bytes = readFileSync30(file.absolutePath);
|
|
43739
44047
|
assets.push({ path: file.planRelativePath, sha256: sha256Hex(bytes) });
|
|
43740
44048
|
}
|
|
43741
44049
|
if (compositionHtml === null) {
|
|
@@ -43748,14 +44056,14 @@ function collectPlanAssetShas(planDir) {
|
|
|
43748
44056
|
function recomputePlanHashFromPlanDir(planDir) {
|
|
43749
44057
|
const planJsonPath = join52(planDir, "plan.json");
|
|
43750
44058
|
const encoderJsonPath = join52(planDir, "meta", "encoder.json");
|
|
43751
|
-
if (!
|
|
44059
|
+
if (!existsSync43(planJsonPath)) {
|
|
43752
44060
|
throw new Error(`[freezePlan] plan.json missing: ${planJsonPath}`);
|
|
43753
44061
|
}
|
|
43754
|
-
if (!
|
|
44062
|
+
if (!existsSync43(encoderJsonPath)) {
|
|
43755
44063
|
throw new Error(`[freezePlan] meta/encoder.json missing: ${encoderJsonPath}`);
|
|
43756
44064
|
}
|
|
43757
|
-
const planJson = JSON.parse(
|
|
43758
|
-
const encoderConfigCanonicalJson =
|
|
44065
|
+
const planJson = JSON.parse(readFileSync30(planJsonPath, "utf-8"));
|
|
44066
|
+
const encoderConfigCanonicalJson = readFileSync30(encoderJsonPath, "utf-8");
|
|
43759
44067
|
const { compositionHtml, assets } = collectPlanAssetShas(planDir);
|
|
43760
44068
|
return computePlanHash({
|
|
43761
44069
|
compositionHtml,
|
|
@@ -43780,11 +44088,11 @@ async function freezePlan(input) {
|
|
|
43780
44088
|
totalFrames,
|
|
43781
44089
|
hasAudio
|
|
43782
44090
|
} = input;
|
|
43783
|
-
if (!
|
|
44091
|
+
if (!existsSync43(planDir)) {
|
|
43784
44092
|
throw new Error(`[freezePlan] planDir does not exist: ${planDir}`);
|
|
43785
44093
|
}
|
|
43786
44094
|
const metaDir = join52(planDir, "meta");
|
|
43787
|
-
if (!
|
|
44095
|
+
if (!existsSync43(metaDir)) mkdirSync26(metaDir, { recursive: true });
|
|
43788
44096
|
writeFileSync20(
|
|
43789
44097
|
join52(metaDir, "composition.json"),
|
|
43790
44098
|
`${JSON.stringify(composition, null, 2)}
|
|
@@ -43926,7 +44234,7 @@ var init_runtimeEnvSnapshot = __esm({
|
|
|
43926
44234
|
// ../producer/src/services/distributed/shared.ts
|
|
43927
44235
|
import { execFile as execFileCallback } from "child_process";
|
|
43928
44236
|
import { dirname as dirname17, join as join53 } from "path";
|
|
43929
|
-
import { existsSync as
|
|
44237
|
+
import { existsSync as existsSync44, readFileSync as readFileSync31 } from "fs";
|
|
43930
44238
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
43931
44239
|
import { promisify as promisify2 } from "util";
|
|
43932
44240
|
async function readFfmpegVersion() {
|
|
@@ -43964,9 +44272,9 @@ function readProducerVersion() {
|
|
|
43964
44272
|
let current = startDir;
|
|
43965
44273
|
for (let i2 = 0; i2 < 10; i2++) {
|
|
43966
44274
|
const candidate = join53(current, "package.json");
|
|
43967
|
-
if (
|
|
44275
|
+
if (existsSync44(candidate)) {
|
|
43968
44276
|
try {
|
|
43969
|
-
const pkg = JSON.parse(
|
|
44277
|
+
const pkg = JSON.parse(readFileSync31(candidate, "utf-8"));
|
|
43970
44278
|
if (pkg.name === "@hyperframes/producer" && typeof pkg.version === "string") {
|
|
43971
44279
|
cachedProducerVersion = pkg.version;
|
|
43972
44280
|
return pkg.version;
|
|
@@ -43997,7 +44305,7 @@ var init_shared2 = __esm({
|
|
|
43997
44305
|
// ../producer/src/services/distributed/plan.ts
|
|
43998
44306
|
import {
|
|
43999
44307
|
cpSync as cpSync2,
|
|
44000
|
-
existsSync as
|
|
44308
|
+
existsSync as existsSync45,
|
|
44001
44309
|
mkdirSync as mkdirSync27,
|
|
44002
44310
|
readdirSync as readdirSync18,
|
|
44003
44311
|
renameSync as renameSync3,
|
|
@@ -44162,7 +44470,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44162
44470
|
useGpu: false,
|
|
44163
44471
|
browserGpuMode: "software"
|
|
44164
44472
|
});
|
|
44165
|
-
if (!
|
|
44473
|
+
if (!existsSync45(planDir)) mkdirSync27(planDir, { recursive: true });
|
|
44166
44474
|
const log2 = config.logger ?? defaultLogger;
|
|
44167
44475
|
const abortSignal = config.abortSignal;
|
|
44168
44476
|
const assertNotAborted = () => {
|
|
@@ -44191,11 +44499,11 @@ async function plan(projectDir, config, planDir) {
|
|
|
44191
44499
|
});
|
|
44192
44500
|
const entryFile = config.entryFile ?? "index.html";
|
|
44193
44501
|
const htmlPath = join54(projectDir, entryFile);
|
|
44194
|
-
if (!
|
|
44502
|
+
if (!existsSync45(htmlPath)) {
|
|
44195
44503
|
throw new Error(`[plan] entry file not found: ${htmlPath}`);
|
|
44196
44504
|
}
|
|
44197
44505
|
const workDir = join54(planDir, ".plan-work");
|
|
44198
|
-
if (!
|
|
44506
|
+
if (!existsSync45(workDir)) mkdirSync27(workDir, { recursive: true });
|
|
44199
44507
|
const compiledDir = join54(workDir, "compiled");
|
|
44200
44508
|
mkdirSync27(compiledDir, { recursive: true });
|
|
44201
44509
|
cpSync2(projectDir, compiledDir, {
|
|
@@ -44281,13 +44589,13 @@ async function plan(projectDir, config, planDir) {
|
|
|
44281
44589
|
});
|
|
44282
44590
|
const stagedVideoFrames = join54(compiledDir, "__hyperframes_video_frames");
|
|
44283
44591
|
const videoFramesDst = join54(planDir, "video-frames");
|
|
44284
|
-
if (
|
|
44285
|
-
if (
|
|
44592
|
+
if (existsSync45(videoFramesDst)) rmSync11(videoFramesDst, { recursive: true, force: true });
|
|
44593
|
+
if (existsSync45(stagedVideoFrames)) {
|
|
44286
44594
|
renameSync3(stagedVideoFrames, videoFramesDst);
|
|
44287
44595
|
} else {
|
|
44288
44596
|
mkdirSync27(videoFramesDst, { recursive: true });
|
|
44289
44597
|
}
|
|
44290
|
-
if (
|
|
44598
|
+
if (existsSync45(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
44291
44599
|
renameSync3(compiledDir, finalCompiledDir);
|
|
44292
44600
|
const planVideosJson = {
|
|
44293
44601
|
videos: composition.videos,
|
|
@@ -44307,7 +44615,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44307
44615
|
"utf-8"
|
|
44308
44616
|
);
|
|
44309
44617
|
const planAudioPath = join54(planDir, "audio.aac");
|
|
44310
|
-
if (audioResult.hasAudio &&
|
|
44618
|
+
if (audioResult.hasAudio && existsSync45(audioResult.audioOutputPath)) {
|
|
44311
44619
|
renameSync3(audioResult.audioOutputPath, planAudioPath);
|
|
44312
44620
|
}
|
|
44313
44621
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
@@ -44446,13 +44754,13 @@ var init_plan = __esm({
|
|
|
44446
44754
|
|
|
44447
44755
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
44448
44756
|
import { randomBytes } from "crypto";
|
|
44449
|
-
import { existsSync as
|
|
44757
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync28, readFileSync as readFileSync32, readdirSync as readdirSync19, rmSync as rmSync12, writeFileSync as writeFileSync22 } from "fs";
|
|
44450
44758
|
import { extname as extname9, join as join55 } from "path";
|
|
44451
44759
|
function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
44452
44760
|
const result = [];
|
|
44453
44761
|
for (const v2 of videos) {
|
|
44454
44762
|
const outputDir = join55(planDir, "video-frames", v2.videoId);
|
|
44455
|
-
if (!
|
|
44763
|
+
if (!existsSync46(outputDir)) {
|
|
44456
44764
|
throw new Error(
|
|
44457
44765
|
`[renderChunk] planDir missing extracted video frames for ${JSON.stringify(v2.videoId)}: ${outputDir} not present. plan() should have written frames here; the planDir is malformed.`
|
|
44458
44766
|
);
|
|
@@ -44485,10 +44793,10 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
|
44485
44793
|
return result;
|
|
44486
44794
|
}
|
|
44487
44795
|
function hashChunkOutput(outputPath, kind) {
|
|
44488
|
-
if (kind === "file") return sha256Hex(
|
|
44796
|
+
if (kind === "file") return sha256Hex(readFileSync32(outputPath));
|
|
44489
44797
|
const entries2 = readdirSync19(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
44490
44798
|
const lines = entries2.map(
|
|
44491
|
-
(name) => `${name}\0${sha256Hex(
|
|
44799
|
+
(name) => `${name}\0${sha256Hex(readFileSync32(join55(outputPath, name)))}`
|
|
44492
44800
|
);
|
|
44493
44801
|
return sha256Hex(lines.join("\0"));
|
|
44494
44802
|
}
|
|
@@ -44505,21 +44813,21 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44505
44813
|
const encoderJsonPath = join55(planDir, "meta", "encoder.json");
|
|
44506
44814
|
const chunksJsonPath = join55(planDir, "meta", "chunks.json");
|
|
44507
44815
|
for (const required of [planJsonPath, encoderJsonPath, chunksJsonPath]) {
|
|
44508
|
-
if (!
|
|
44816
|
+
if (!existsSync46(required)) {
|
|
44509
44817
|
throw new RenderChunkValidationError(
|
|
44510
44818
|
MISSING_PLAN_ARTIFACT,
|
|
44511
44819
|
`[renderChunk] planDir is missing required artifact: ${required}`
|
|
44512
44820
|
);
|
|
44513
44821
|
}
|
|
44514
44822
|
}
|
|
44515
|
-
const plan2 = JSON.parse(
|
|
44516
|
-
const encoder = JSON.parse(
|
|
44517
|
-
const chunks = JSON.parse(
|
|
44823
|
+
const plan2 = JSON.parse(readFileSync32(planJsonPath, "utf-8"));
|
|
44824
|
+
const encoder = JSON.parse(readFileSync32(encoderJsonPath, "utf-8"));
|
|
44825
|
+
const chunks = JSON.parse(readFileSync32(chunksJsonPath, "utf-8"));
|
|
44518
44826
|
const videosJsonPath = join55(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
|
|
44519
44827
|
let planVideos = null;
|
|
44520
|
-
if (
|
|
44828
|
+
if (existsSync46(videosJsonPath)) {
|
|
44521
44829
|
try {
|
|
44522
|
-
planVideos = JSON.parse(
|
|
44830
|
+
planVideos = JSON.parse(readFileSync32(videosJsonPath, "utf-8"));
|
|
44523
44831
|
} catch (err) {
|
|
44524
44832
|
throw new RenderChunkValidationError(
|
|
44525
44833
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -44545,7 +44853,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44545
44853
|
);
|
|
44546
44854
|
}
|
|
44547
44855
|
const compiledDir = join55(planDir, "compiled");
|
|
44548
|
-
if (!
|
|
44856
|
+
if (!existsSync46(compiledDir)) {
|
|
44549
44857
|
throw new RenderChunkValidationError(
|
|
44550
44858
|
MISSING_PLAN_ARTIFACT,
|
|
44551
44859
|
`[renderChunk] planDir missing compiled/ directory: ${compiledDir}`
|
|
@@ -44669,10 +44977,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44669
44977
|
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
44670
44978
|
const videoOnlyPath = outputChunkPath;
|
|
44671
44979
|
if (isPngSequence) {
|
|
44672
|
-
if (!
|
|
44980
|
+
if (!existsSync46(outputChunkPath)) mkdirSync28(outputChunkPath, { recursive: true });
|
|
44673
44981
|
} else {
|
|
44674
44982
|
const outDir = join55(outputChunkPath, "..");
|
|
44675
|
-
if (!
|
|
44983
|
+
if (!existsSync46(outDir)) mkdirSync28(outDir, { recursive: true });
|
|
44676
44984
|
}
|
|
44677
44985
|
await runEncodeStage({
|
|
44678
44986
|
job,
|
|
@@ -44993,9 +45301,9 @@ var init_audioPadTrim = __esm({
|
|
|
44993
45301
|
// ../producer/src/services/distributed/assemble.ts
|
|
44994
45302
|
import {
|
|
44995
45303
|
cpSync as cpSync3,
|
|
44996
|
-
existsSync as
|
|
45304
|
+
existsSync as existsSync47,
|
|
44997
45305
|
mkdirSync as mkdirSync29,
|
|
44998
|
-
readFileSync as
|
|
45306
|
+
readFileSync as readFileSync33,
|
|
44999
45307
|
readdirSync as readdirSync20,
|
|
45000
45308
|
rmSync as rmSync13,
|
|
45001
45309
|
statSync as statSync16,
|
|
@@ -45008,32 +45316,32 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45008
45316
|
const abortSignal = options?.abortSignal;
|
|
45009
45317
|
const planJsonPath = join56(planDir, "plan.json");
|
|
45010
45318
|
const chunksJsonPath = join56(planDir, "meta", "chunks.json");
|
|
45011
|
-
if (!
|
|
45319
|
+
if (!existsSync47(planJsonPath)) {
|
|
45012
45320
|
throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
|
|
45013
45321
|
}
|
|
45014
|
-
if (!
|
|
45322
|
+
if (!existsSync47(chunksJsonPath)) {
|
|
45015
45323
|
throw new Error(`[assemble] planDir missing meta/chunks.json: ${chunksJsonPath}`);
|
|
45016
45324
|
}
|
|
45017
|
-
const plan2 = JSON.parse(
|
|
45018
|
-
const chunks = JSON.parse(
|
|
45325
|
+
const plan2 = JSON.parse(readFileSync33(planJsonPath, "utf-8"));
|
|
45326
|
+
const chunks = JSON.parse(readFileSync33(chunksJsonPath, "utf-8"));
|
|
45019
45327
|
if (chunkPaths.length !== chunks.length) {
|
|
45020
45328
|
throw new Error(
|
|
45021
45329
|
`[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
|
|
45022
45330
|
);
|
|
45023
45331
|
}
|
|
45024
45332
|
for (const path2 of chunkPaths) {
|
|
45025
|
-
if (!
|
|
45333
|
+
if (!existsSync47(path2)) {
|
|
45026
45334
|
throw new Error(`[assemble] chunk path does not exist: ${path2}`);
|
|
45027
45335
|
}
|
|
45028
45336
|
}
|
|
45029
45337
|
if (plan2.dimensions.format === "png-sequence") {
|
|
45030
45338
|
return mergePngFrameDirs(chunkPaths, outputPath, plan2.totalFrames, audioPath, start);
|
|
45031
45339
|
}
|
|
45032
|
-
if (!
|
|
45340
|
+
if (!existsSync47(dirname18(outputPath))) {
|
|
45033
45341
|
mkdirSync29(dirname18(outputPath), { recursive: true });
|
|
45034
45342
|
}
|
|
45035
45343
|
const workDir = `${outputPath}.assemble-work`;
|
|
45036
|
-
if (
|
|
45344
|
+
if (existsSync47(workDir)) rmSync13(workDir, { recursive: true, force: true });
|
|
45037
45345
|
mkdirSync29(workDir, { recursive: true });
|
|
45038
45346
|
try {
|
|
45039
45347
|
const concatListPath = join56(workDir, "concat-list.txt");
|
|
@@ -45060,7 +45368,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45060
45368
|
);
|
|
45061
45369
|
}
|
|
45062
45370
|
let audioForMux = null;
|
|
45063
|
-
if (audioPath !== null &&
|
|
45371
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45064
45372
|
const paddedAudioPath = join56(workDir, "audio-padded.aac");
|
|
45065
45373
|
const padTrimResult = await padOrTrimAudioToVideoFrameCount({
|
|
45066
45374
|
videoPath: concatOutputPath,
|
|
@@ -45103,7 +45411,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45103
45411
|
});
|
|
45104
45412
|
}
|
|
45105
45413
|
}
|
|
45106
|
-
const fileSize =
|
|
45414
|
+
const fileSize = existsSync47(outputPath) ? statSync16(outputPath).size : 0;
|
|
45107
45415
|
return {
|
|
45108
45416
|
outputPath,
|
|
45109
45417
|
durationMs: Date.now() - start,
|
|
@@ -45112,7 +45420,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45112
45420
|
};
|
|
45113
45421
|
}
|
|
45114
45422
|
function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, startTimeMs) {
|
|
45115
|
-
if (
|
|
45423
|
+
if (existsSync47(outputPath)) rmSync13(outputPath, { recursive: true, force: true });
|
|
45116
45424
|
mkdirSync29(outputPath, { recursive: true });
|
|
45117
45425
|
let globalIdx = 0;
|
|
45118
45426
|
for (const chunkDir of chunkPaths) {
|
|
@@ -45136,7 +45444,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
45136
45444
|
`[assemble] png-sequence frame count mismatch: merged ${globalIdx} frames vs plan.totalFrames=${totalFrames}. Using on-disk count.`
|
|
45137
45445
|
);
|
|
45138
45446
|
}
|
|
45139
|
-
if (audioPath !== null &&
|
|
45447
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45140
45448
|
const sidecar = join56(outputPath, "audio.aac");
|
|
45141
45449
|
cpSync3(audioPath, sidecar);
|
|
45142
45450
|
}
|
|
@@ -45224,12 +45532,13 @@ var init_src3 = __esm({
|
|
|
45224
45532
|
// src/server/studioServer.ts
|
|
45225
45533
|
var studioServer_exports = {};
|
|
45226
45534
|
__export(studioServer_exports, {
|
|
45535
|
+
closeThumbnailBrowser: () => closeThumbnailBrowser,
|
|
45227
45536
|
createStudioServer: () => createStudioServer,
|
|
45228
45537
|
resolveStudioBundle: () => resolveStudioBundle
|
|
45229
45538
|
});
|
|
45230
45539
|
import { Hono as Hono5 } from "hono";
|
|
45231
45540
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
45232
|
-
import { existsSync as
|
|
45541
|
+
import { existsSync as existsSync48, readFileSync as readFileSync34, writeFileSync as writeFileSync24, statSync as statSync17 } from "fs";
|
|
45233
45542
|
import { resolve as resolve24, join as join57, basename as basename5 } from "path";
|
|
45234
45543
|
function resolveDistDir() {
|
|
45235
45544
|
return resolveStudioBundle().dir;
|
|
@@ -45237,12 +45546,12 @@ function resolveDistDir() {
|
|
|
45237
45546
|
function resolveStudioBundle() {
|
|
45238
45547
|
const builtPath = resolve24(__dirname, "studio");
|
|
45239
45548
|
const builtIndex = resolve24(builtPath, "index.html");
|
|
45240
|
-
if (
|
|
45549
|
+
if (existsSync48(builtIndex)) {
|
|
45241
45550
|
return { dir: builtPath, indexPath: builtIndex, available: true, checkedPaths: [builtIndex] };
|
|
45242
45551
|
}
|
|
45243
45552
|
const devPath = resolve24(__dirname, "..", "..", "..", "studio", "dist");
|
|
45244
45553
|
const devIndex = resolve24(devPath, "index.html");
|
|
45245
|
-
if (
|
|
45554
|
+
if (existsSync48(devIndex)) {
|
|
45246
45555
|
return {
|
|
45247
45556
|
dir: devPath,
|
|
45248
45557
|
indexPath: devIndex,
|
|
@@ -45259,9 +45568,9 @@ function resolveStudioBundle() {
|
|
|
45259
45568
|
}
|
|
45260
45569
|
function resolveRuntimePath() {
|
|
45261
45570
|
const builtPath = resolve24(__dirname, "hyperframe-runtime.js");
|
|
45262
|
-
if (
|
|
45571
|
+
if (existsSync48(builtPath)) return builtPath;
|
|
45263
45572
|
const iifePath = resolve24(__dirname, "hyperframe.runtime.iife.js");
|
|
45264
|
-
if (
|
|
45573
|
+
if (existsSync48(iifePath)) return iifePath;
|
|
45265
45574
|
const devPath = resolve24(
|
|
45266
45575
|
__dirname,
|
|
45267
45576
|
"..",
|
|
@@ -45271,14 +45580,14 @@ function resolveRuntimePath() {
|
|
|
45271
45580
|
"dist",
|
|
45272
45581
|
"hyperframe.runtime.iife.js"
|
|
45273
45582
|
);
|
|
45274
|
-
if (
|
|
45583
|
+
if (existsSync48(devPath)) return devPath;
|
|
45275
45584
|
return builtPath;
|
|
45276
45585
|
}
|
|
45277
45586
|
function readStudioManualEditManifestContent(projectDir) {
|
|
45278
45587
|
const manifestPath = join57(projectDir, STUDIO_MANUAL_EDITS_PATH2);
|
|
45279
|
-
if (!
|
|
45588
|
+
if (!existsSync48(manifestPath)) return "";
|
|
45280
45589
|
try {
|
|
45281
|
-
return
|
|
45590
|
+
return readFileSync34(manifestPath, "utf-8");
|
|
45282
45591
|
} catch {
|
|
45283
45592
|
return "";
|
|
45284
45593
|
}
|
|
@@ -45319,16 +45628,6 @@ async function getThumbnailBrowser() {
|
|
|
45319
45628
|
_thumbnailBrowser = null;
|
|
45320
45629
|
_thumbnailBrowserInitializing = null;
|
|
45321
45630
|
});
|
|
45322
|
-
const onExit = async () => {
|
|
45323
|
-
const { releaseBrowser: releaseBrowser2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
45324
|
-
if (_thumbnailBrowser) {
|
|
45325
|
-
await releaseBrowser2(_thumbnailBrowser).catch(() => {
|
|
45326
|
-
});
|
|
45327
|
-
_thumbnailBrowser = null;
|
|
45328
|
-
}
|
|
45329
|
-
};
|
|
45330
|
-
process.once("SIGTERM", () => void onExit());
|
|
45331
|
-
process.once("SIGINT", () => void onExit());
|
|
45332
45631
|
return _thumbnailBrowser;
|
|
45333
45632
|
} catch (err) {
|
|
45334
45633
|
console.warn(
|
|
@@ -45341,6 +45640,15 @@ async function getThumbnailBrowser() {
|
|
|
45341
45640
|
})();
|
|
45342
45641
|
return _thumbnailBrowserInitializing;
|
|
45343
45642
|
}
|
|
45643
|
+
async function closeThumbnailBrowser() {
|
|
45644
|
+
if (!_thumbnailBrowser) return;
|
|
45645
|
+
const browser = _thumbnailBrowser;
|
|
45646
|
+
_thumbnailBrowser = null;
|
|
45647
|
+
_thumbnailBrowserInitializing = null;
|
|
45648
|
+
const { releaseBrowser: releaseBrowser2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
45649
|
+
await releaseBrowser2(browser).catch(() => {
|
|
45650
|
+
});
|
|
45651
|
+
}
|
|
45344
45652
|
function createStudioServer(options) {
|
|
45345
45653
|
const { projectDir, projectName } = options;
|
|
45346
45654
|
const projectId = projectName || basename5(projectDir);
|
|
@@ -45519,19 +45827,19 @@ function createStudioServer(options) {
|
|
|
45519
45827
|
async installRegistryBlock(opts) {
|
|
45520
45828
|
const { resolveItem: resolveItem2 } = await Promise.resolve().then(() => (init_resolver(), resolver_exports));
|
|
45521
45829
|
const { installItem: installItem2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
45522
|
-
const { readFileSync:
|
|
45523
|
-
const { join:
|
|
45830
|
+
const { readFileSync: readFileSync57, writeFileSync: writeFileSync39, existsSync: existsSync81 } = await import("fs");
|
|
45831
|
+
const { join: join90 } = await import("path");
|
|
45524
45832
|
const item = await resolveItem2(opts.blockName);
|
|
45525
45833
|
const { written } = await installItem2(item, { destDir: opts.project.dir });
|
|
45526
|
-
const indexPath =
|
|
45527
|
-
if (
|
|
45528
|
-
const indexHtml =
|
|
45834
|
+
const indexPath = join90(opts.project.dir, "index.html");
|
|
45835
|
+
if (existsSync81(indexPath)) {
|
|
45836
|
+
const indexHtml = readFileSync57(indexPath, "utf-8");
|
|
45529
45837
|
const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
|
|
45530
45838
|
const hostH = indexHtml.match(/data-height="(\d+)"/)?.[1];
|
|
45531
45839
|
if (hostW && hostH) {
|
|
45532
45840
|
for (const absPath of written) {
|
|
45533
45841
|
if (!absPath.endsWith(".html")) continue;
|
|
45534
|
-
let content =
|
|
45842
|
+
let content = readFileSync57(absPath, "utf-8");
|
|
45535
45843
|
content = content.replace(
|
|
45536
45844
|
/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+/i,
|
|
45537
45845
|
`$1${hostW}$2${hostH}`
|
|
@@ -45567,7 +45875,7 @@ function createStudioServer(options) {
|
|
|
45567
45875
|
});
|
|
45568
45876
|
app.get("/api/runtime.js", (c3) => {
|
|
45569
45877
|
const serve4 = async () => {
|
|
45570
|
-
const runtimeSource = await loadRuntimeSource() ?? (
|
|
45878
|
+
const runtimeSource = await loadRuntimeSource() ?? (existsSync48(runtimePath) ? readFileSync34(runtimePath, "utf-8") : null);
|
|
45571
45879
|
if (!runtimeSource) return c3.text("runtime not available", 404);
|
|
45572
45880
|
return c3.body(runtimeSource, 200, {
|
|
45573
45881
|
"Content-Type": "text/javascript",
|
|
@@ -45603,8 +45911,8 @@ function createStudioServer(options) {
|
|
|
45603
45911
|
});
|
|
45604
45912
|
const serveStudioStaticFile = (c3) => {
|
|
45605
45913
|
const filePath = resolve24(studioDir, c3.req.path.slice(1));
|
|
45606
|
-
if (!
|
|
45607
|
-
const content =
|
|
45914
|
+
if (!existsSync48(filePath) || !statSync17(filePath).isFile()) return c3.text("not found", 404);
|
|
45915
|
+
const content = readFileSync34(filePath);
|
|
45608
45916
|
return new Response(content, {
|
|
45609
45917
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
45610
45918
|
});
|
|
@@ -45624,7 +45932,7 @@ function createStudioServer(options) {
|
|
|
45624
45932
|
}
|
|
45625
45933
|
app.get("*", (c3) => {
|
|
45626
45934
|
const indexPath = resolve24(studioDir, "index.html");
|
|
45627
|
-
if (!
|
|
45935
|
+
if (!existsSync48(indexPath)) {
|
|
45628
45936
|
return c3.html(
|
|
45629
45937
|
`<!doctype html>
|
|
45630
45938
|
<html>
|
|
@@ -45680,7 +45988,7 @@ function createStudioServer(options) {
|
|
|
45680
45988
|
500
|
|
45681
45989
|
);
|
|
45682
45990
|
}
|
|
45683
|
-
let html =
|
|
45991
|
+
let html = readFileSync34(indexPath, "utf-8");
|
|
45684
45992
|
const envScript = buildRuntimeEnvScript();
|
|
45685
45993
|
if (envScript) {
|
|
45686
45994
|
html = html.replace("<head>", `<head>${envScript}`);
|
|
@@ -45712,7 +46020,7 @@ __export(preview_exports, {
|
|
|
45712
46020
|
examples: () => examples
|
|
45713
46021
|
});
|
|
45714
46022
|
import { spawn as spawn11 } from "child_process";
|
|
45715
|
-
import { existsSync as
|
|
46023
|
+
import { existsSync as existsSync49, lstatSync as lstatSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync30 } from "fs";
|
|
45716
46024
|
import { resolve as resolve25, dirname as dirname19, basename as basename6, join as join58 } from "path";
|
|
45717
46025
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
45718
46026
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -45725,7 +46033,7 @@ async function runDevMode(dir, options) {
|
|
|
45725
46033
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45726
46034
|
let createdSymlink = false;
|
|
45727
46035
|
if (dir !== symlinkPath) {
|
|
45728
|
-
if (
|
|
46036
|
+
if (existsSync49(symlinkPath)) {
|
|
45729
46037
|
try {
|
|
45730
46038
|
const stat3 = lstatSync2(symlinkPath);
|
|
45731
46039
|
if (stat3.isSymbolicLink()) {
|
|
@@ -45737,7 +46045,7 @@ async function runDevMode(dir, options) {
|
|
|
45737
46045
|
} catch {
|
|
45738
46046
|
}
|
|
45739
46047
|
}
|
|
45740
|
-
if (!
|
|
46048
|
+
if (!existsSync49(symlinkPath)) {
|
|
45741
46049
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45742
46050
|
createdSymlink = true;
|
|
45743
46051
|
}
|
|
@@ -45783,11 +46091,16 @@ async function runDevMode(dir, options) {
|
|
|
45783
46091
|
if (createdSymlink) {
|
|
45784
46092
|
process.on("exit", () => {
|
|
45785
46093
|
try {
|
|
45786
|
-
if (
|
|
46094
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45787
46095
|
} catch {
|
|
45788
46096
|
}
|
|
45789
46097
|
});
|
|
45790
46098
|
}
|
|
46099
|
+
const shutdown = () => {
|
|
46100
|
+
if (child.pid) killProcessTree(child.pid);
|
|
46101
|
+
};
|
|
46102
|
+
process.once("SIGINT", shutdown);
|
|
46103
|
+
process.once("SIGTERM", shutdown);
|
|
45791
46104
|
return new Promise((resolve46) => {
|
|
45792
46105
|
child.on("close", () => resolve46());
|
|
45793
46106
|
});
|
|
@@ -45810,12 +46123,12 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45810
46123
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45811
46124
|
let createdSymlink = false;
|
|
45812
46125
|
if (dir !== symlinkPath) {
|
|
45813
|
-
if (
|
|
46126
|
+
if (existsSync49(symlinkPath) && lstatSync2(symlinkPath).isSymbolicLink()) {
|
|
45814
46127
|
if (resolve25(readlinkSync(symlinkPath)) !== resolve25(dir)) {
|
|
45815
46128
|
unlinkSync5(symlinkPath);
|
|
45816
46129
|
}
|
|
45817
46130
|
}
|
|
45818
|
-
if (!
|
|
46131
|
+
if (!existsSync49(symlinkPath)) {
|
|
45819
46132
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45820
46133
|
createdSymlink = true;
|
|
45821
46134
|
}
|
|
@@ -45858,11 +46171,16 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45858
46171
|
if (createdSymlink) {
|
|
45859
46172
|
process.on("exit", () => {
|
|
45860
46173
|
try {
|
|
45861
|
-
if (
|
|
46174
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45862
46175
|
} catch {
|
|
45863
46176
|
}
|
|
45864
46177
|
});
|
|
45865
46178
|
}
|
|
46179
|
+
const shutdown = () => {
|
|
46180
|
+
if (child.pid) killProcessTree(child.pid);
|
|
46181
|
+
};
|
|
46182
|
+
process.once("SIGINT", shutdown);
|
|
46183
|
+
process.once("SIGTERM", shutdown);
|
|
45866
46184
|
return new Promise((resolve46) => {
|
|
45867
46185
|
child.on("close", () => resolve46());
|
|
45868
46186
|
});
|
|
@@ -45957,11 +46275,29 @@ async function runEmbeddedMode(dir, startPort, options) {
|
|
|
45957
46275
|
rl?.close();
|
|
45958
46276
|
console.log();
|
|
45959
46277
|
console.log(` ${c2.dim("Shutting down studio...")}`);
|
|
45960
|
-
|
|
45961
|
-
|
|
46278
|
+
setTimeout(() => process.exit(0), 3e3).unref();
|
|
46279
|
+
const cleanup = async () => {
|
|
46280
|
+
const { closeThumbnailBrowser: closeThumbnailBrowser2 } = await Promise.resolve().then(() => (init_studioServer(), studioServer_exports));
|
|
46281
|
+
const { drainBrowserPool: drainBrowserPool2, killTrackedProcesses: killTrackedProcesses2 } = await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
46282
|
+
killTrackedProcesses2();
|
|
46283
|
+
await closeThumbnailBrowser2().catch(() => {
|
|
46284
|
+
});
|
|
46285
|
+
await drainBrowserPool2().catch(() => {
|
|
46286
|
+
});
|
|
46287
|
+
};
|
|
46288
|
+
cleanup().catch(() => {
|
|
46289
|
+
}).finally(() => {
|
|
46290
|
+
result.server.close(() => resolveRun());
|
|
46291
|
+
});
|
|
45962
46292
|
};
|
|
45963
46293
|
process.once("SIGINT", shutdown);
|
|
45964
46294
|
process.once("SIGTERM", shutdown);
|
|
46295
|
+
Promise.resolve().then(() => (init_src2(), src_exports2)).then(({ killTrackedProcesses: killTrackedProcesses2 }) => {
|
|
46296
|
+
process.once("exit", () => {
|
|
46297
|
+
if (!shuttingDown) killTrackedProcesses2();
|
|
46298
|
+
});
|
|
46299
|
+
}).catch(() => {
|
|
46300
|
+
});
|
|
45965
46301
|
});
|
|
45966
46302
|
}
|
|
45967
46303
|
var examples, preview_default;
|
|
@@ -45976,6 +46312,7 @@ var init_preview2 = __esm({
|
|
|
45976
46312
|
init_lintProject();
|
|
45977
46313
|
init_lintFormat();
|
|
45978
46314
|
init_portUtils();
|
|
46315
|
+
init_orphanCleanup();
|
|
45979
46316
|
examples = [
|
|
45980
46317
|
["Preview the current project", "hyperframes preview"],
|
|
45981
46318
|
["Preview a specific project directory", "hyperframes preview ./my-video"],
|
|
@@ -46054,12 +46391,18 @@ var init_preview2 = __esm({
|
|
|
46054
46391
|
`);
|
|
46055
46392
|
return;
|
|
46056
46393
|
}
|
|
46394
|
+
const orphansKilled = killOrphanedProcesses();
|
|
46395
|
+
if (orphansKilled > 0) {
|
|
46396
|
+
console.log(
|
|
46397
|
+
` ${c2.dim(`Cleaned up ${orphansKilled} orphaned process${orphansKilled === 1 ? "" : "es"} from a previous session.`)}`
|
|
46398
|
+
);
|
|
46399
|
+
}
|
|
46057
46400
|
const rawArg = args.dir;
|
|
46058
46401
|
const dir = resolve25(rawArg ?? ".");
|
|
46059
46402
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
46060
46403
|
const projectName = isImplicitCwd ? basename6(process.env.PWD ?? dir) : basename6(dir);
|
|
46061
46404
|
const indexPath = join58(dir, "index.html");
|
|
46062
|
-
if (
|
|
46405
|
+
if (existsSync49(indexPath)) {
|
|
46063
46406
|
const project = { dir, name: projectName, indexPath };
|
|
46064
46407
|
const lintResult = lintProject(project);
|
|
46065
46408
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
@@ -46104,12 +46447,12 @@ __export(init_exports, {
|
|
|
46104
46447
|
injectTailwindBrowserScript: () => injectTailwindBrowserScript
|
|
46105
46448
|
});
|
|
46106
46449
|
import {
|
|
46107
|
-
existsSync as
|
|
46450
|
+
existsSync as existsSync50,
|
|
46108
46451
|
mkdirSync as mkdirSync31,
|
|
46109
46452
|
copyFileSync as copyFileSync5,
|
|
46110
46453
|
cpSync as cpSync4,
|
|
46111
46454
|
writeFileSync as writeFileSync25,
|
|
46112
|
-
readFileSync as
|
|
46455
|
+
readFileSync as readFileSync35,
|
|
46113
46456
|
readdirSync as readdirSync21
|
|
46114
46457
|
} from "fs";
|
|
46115
46458
|
import { resolve as resolve26, basename as basename7, join as join59, dirname as dirname20 } from "path";
|
|
@@ -46184,7 +46527,7 @@ function resolveAssetDir(devSegments, builtSegments) {
|
|
|
46184
46527
|
const base = dirname20(fileURLToPath7(import.meta.url));
|
|
46185
46528
|
const devPath = resolve26(base, ...devSegments);
|
|
46186
46529
|
const builtPath = resolve26(base, ...builtSegments);
|
|
46187
|
-
return
|
|
46530
|
+
return existsSync50(devPath) ? devPath : builtPath;
|
|
46188
46531
|
}
|
|
46189
46532
|
function getStaticTemplateDir(templateId) {
|
|
46190
46533
|
return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
|
|
@@ -46212,7 +46555,7 @@ function buildPackageScripts() {
|
|
|
46212
46555
|
}
|
|
46213
46556
|
function writeDefaultPackageJson(destDir, projectName) {
|
|
46214
46557
|
const packageJsonPath = resolve26(destDir, "package.json");
|
|
46215
|
-
if (
|
|
46558
|
+
if (existsSync50(packageJsonPath)) return;
|
|
46216
46559
|
writeFileSync25(
|
|
46217
46560
|
packageJsonPath,
|
|
46218
46561
|
`${JSON.stringify(
|
|
@@ -46274,14 +46617,14 @@ ${html}`;
|
|
|
46274
46617
|
}
|
|
46275
46618
|
function writeTailwindSupport(destDir) {
|
|
46276
46619
|
for (const file of listHtmlFiles(destDir)) {
|
|
46277
|
-
const html =
|
|
46620
|
+
const html = readFileSync35(file, "utf-8");
|
|
46278
46621
|
writeFileSync25(file, injectTailwindBrowserScript(html), "utf-8");
|
|
46279
46622
|
}
|
|
46280
46623
|
}
|
|
46281
46624
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
46282
46625
|
const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join59(e3.parentPath, e3.name));
|
|
46283
46626
|
for (const file of htmlFiles) {
|
|
46284
|
-
let content =
|
|
46627
|
+
let content = readFileSync35(file, "utf-8");
|
|
46285
46628
|
if (videoFilename) {
|
|
46286
46629
|
content = content.replaceAll("__VIDEO_SRC__", videoFilename);
|
|
46287
46630
|
} else {
|
|
@@ -46386,7 +46729,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
|
|
|
46386
46729
|
function applyResolutionPreset(destDir, resolution) {
|
|
46387
46730
|
const { width, height } = CANVAS_DIMENSIONS[resolution];
|
|
46388
46731
|
for (const file of listHtmlFiles(destDir)) {
|
|
46389
|
-
let html =
|
|
46732
|
+
let html = readFileSync35(file, "utf-8");
|
|
46390
46733
|
let changed = false;
|
|
46391
46734
|
const dataWidthRe = /(data-width=)["'](\d+)["']/g;
|
|
46392
46735
|
if (dataWidthRe.test(html)) {
|
|
@@ -46434,7 +46777,7 @@ function applyResolutionPreset(destDir, resolution) {
|
|
|
46434
46777
|
async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
|
|
46435
46778
|
mkdirSync31(destDir, { recursive: true });
|
|
46436
46779
|
const templateDir = getStaticTemplateDir(templateId);
|
|
46437
|
-
if (
|
|
46780
|
+
if (existsSync50(join59(templateDir, "index.html"))) {
|
|
46438
46781
|
cpSync4(templateDir, destDir, { recursive: true });
|
|
46439
46782
|
} else {
|
|
46440
46783
|
await fetchRemoteTemplate(templateId, destDir);
|
|
@@ -46455,13 +46798,13 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
46455
46798
|
),
|
|
46456
46799
|
"utf-8"
|
|
46457
46800
|
);
|
|
46458
|
-
if (!
|
|
46801
|
+
if (!existsSync50(resolve26(destDir, "hyperframes.json"))) {
|
|
46459
46802
|
const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
|
|
46460
46803
|
writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
|
|
46461
46804
|
}
|
|
46462
46805
|
writeDefaultPackageJson(destDir, name);
|
|
46463
46806
|
const sharedDir = getSharedTemplateDir();
|
|
46464
|
-
if (
|
|
46807
|
+
if (existsSync50(sharedDir)) {
|
|
46465
46808
|
for (const entry of readdirSync21(sharedDir, { withFileTypes: true })) {
|
|
46466
46809
|
const src = join59(sharedDir, entry.name);
|
|
46467
46810
|
const dest = resolve26(destDir, entry.name);
|
|
@@ -46621,7 +46964,7 @@ var init_init = __esm({
|
|
|
46621
46964
|
const templateId2 = exampleFlag ?? "blank";
|
|
46622
46965
|
const name2 = args.name ?? "my-video";
|
|
46623
46966
|
const destDir2 = resolve26(name2);
|
|
46624
|
-
if (
|
|
46967
|
+
if (existsSync50(destDir2) && readdirSync21(destDir2).length > 0) {
|
|
46625
46968
|
console.error(c2.error(`Directory already exists and is not empty: ${name2}`));
|
|
46626
46969
|
process.exit(1);
|
|
46627
46970
|
}
|
|
@@ -46635,7 +46978,7 @@ var init_init = __esm({
|
|
|
46635
46978
|
}
|
|
46636
46979
|
if (videoFlag) {
|
|
46637
46980
|
const videoPath = resolve26(videoFlag);
|
|
46638
|
-
if (!
|
|
46981
|
+
if (!existsSync50(videoPath)) {
|
|
46639
46982
|
console.error(c2.error(`Video file not found: ${videoFlag}`));
|
|
46640
46983
|
process.exit(1);
|
|
46641
46984
|
}
|
|
@@ -46649,7 +46992,7 @@ var init_init = __esm({
|
|
|
46649
46992
|
}
|
|
46650
46993
|
if (audioFlag) {
|
|
46651
46994
|
const audioPath = resolve26(audioFlag);
|
|
46652
|
-
if (!
|
|
46995
|
+
if (!existsSync50(audioPath)) {
|
|
46653
46996
|
console.error(c2.error(`Audio file not found: ${audioFlag}`));
|
|
46654
46997
|
process.exit(1);
|
|
46655
46998
|
}
|
|
@@ -46697,7 +47040,7 @@ var init_init = __esm({
|
|
|
46697
47040
|
}
|
|
46698
47041
|
trackInitTemplate(templateId2, { tailwind });
|
|
46699
47042
|
const transcriptFile2 = resolve26(destDir2, "transcript.json");
|
|
46700
|
-
if (
|
|
47043
|
+
if (existsSync50(transcriptFile2)) {
|
|
46701
47044
|
await patchTranscript(destDir2, transcriptFile2);
|
|
46702
47045
|
}
|
|
46703
47046
|
console.log(c2.success(`Created ${c2.accent(name2 + "/")}`));
|
|
@@ -46752,7 +47095,7 @@ var init_init = __esm({
|
|
|
46752
47095
|
name = nameResult;
|
|
46753
47096
|
}
|
|
46754
47097
|
const destDir = resolve26(name);
|
|
46755
|
-
if (
|
|
47098
|
+
if (existsSync50(destDir) && readdirSync21(destDir).length > 0) {
|
|
46756
47099
|
const overwrite = await ue({
|
|
46757
47100
|
message: `Directory ${c2.accent(name)} already exists and is not empty. Overwrite?`,
|
|
46758
47101
|
initialValue: false
|
|
@@ -46767,7 +47110,7 @@ var init_init = __esm({
|
|
|
46767
47110
|
let videoDuration;
|
|
46768
47111
|
if (videoFlag) {
|
|
46769
47112
|
const videoPath = resolve26(videoFlag);
|
|
46770
|
-
if (!
|
|
47113
|
+
if (!existsSync50(videoPath)) {
|
|
46771
47114
|
R2.error(`File not found: ${videoFlag}`);
|
|
46772
47115
|
me("Setup cancelled.");
|
|
46773
47116
|
process.exit(1);
|
|
@@ -46779,7 +47122,7 @@ var init_init = __esm({
|
|
|
46779
47122
|
videoDuration = result.meta.durationSeconds;
|
|
46780
47123
|
} else if (audioFlag) {
|
|
46781
47124
|
const audioPath = resolve26(audioFlag);
|
|
46782
|
-
if (!
|
|
47125
|
+
if (!existsSync50(audioPath)) {
|
|
46783
47126
|
R2.error(`File not found: ${audioFlag}`);
|
|
46784
47127
|
me("Setup cancelled.");
|
|
46785
47128
|
process.exit(1);
|
|
@@ -46880,7 +47223,7 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46880
47223
|
}
|
|
46881
47224
|
trackInitTemplate(templateId, { tailwind });
|
|
46882
47225
|
const transcriptFile = resolve26(destDir, "transcript.json");
|
|
46883
|
-
if (
|
|
47226
|
+
if (existsSync50(transcriptFile)) {
|
|
46884
47227
|
await patchTranscript(destDir, transcriptFile);
|
|
46885
47228
|
}
|
|
46886
47229
|
const files = readdirSync21(destDir);
|
|
@@ -46912,9 +47255,9 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46912
47255
|
|
|
46913
47256
|
// src/utils/clipboard.ts
|
|
46914
47257
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
46915
|
-
import { platform as
|
|
47258
|
+
import { platform as platform6 } from "os";
|
|
46916
47259
|
function detectProvider() {
|
|
46917
|
-
const os =
|
|
47260
|
+
const os = platform6();
|
|
46918
47261
|
if (os === "darwin") {
|
|
46919
47262
|
return { cmd: "pbcopy", args: [] };
|
|
46920
47263
|
}
|
|
@@ -46966,7 +47309,7 @@ __export(add_exports, {
|
|
|
46966
47309
|
remapTarget: () => remapTarget,
|
|
46967
47310
|
runAdd: () => runAdd
|
|
46968
47311
|
});
|
|
46969
|
-
import { existsSync as
|
|
47312
|
+
import { existsSync as existsSync51 } from "fs";
|
|
46970
47313
|
import { resolve as resolve27, relative as relative7 } from "path";
|
|
46971
47314
|
function remapTarget(item, originalTarget, paths) {
|
|
46972
47315
|
if (item.type === "hyperframes:block") {
|
|
@@ -46992,8 +47335,8 @@ function buildSnippet(item, relativeTarget) {
|
|
|
46992
47335
|
async function runAdd(opts) {
|
|
46993
47336
|
const projectDir = resolve27(opts.projectDir);
|
|
46994
47337
|
let config = loadProjectConfig(projectDir);
|
|
46995
|
-
const hasConfig =
|
|
46996
|
-
if (!hasConfig &&
|
|
47338
|
+
const hasConfig = existsSync51(projectConfigPath(projectDir));
|
|
47339
|
+
if (!hasConfig && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
46997
47340
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
46998
47341
|
config = DEFAULT_PROJECT_CONFIG;
|
|
46999
47342
|
}
|
|
@@ -47095,10 +47438,10 @@ var init_add = __esm({
|
|
|
47095
47438
|
const projectDir = resolve27(args.dir ?? process.cwd());
|
|
47096
47439
|
const json = args.json === true;
|
|
47097
47440
|
const skipClipboard = args["no-clipboard"] === true;
|
|
47098
|
-
const hasConfigBefore =
|
|
47441
|
+
const hasConfigBefore = existsSync51(projectConfigPath(projectDir));
|
|
47099
47442
|
try {
|
|
47100
47443
|
const result = await runAdd({ name: args.name, projectDir, skipClipboard });
|
|
47101
|
-
const wroteConfig = !hasConfigBefore &&
|
|
47444
|
+
const wroteConfig = !hasConfigBefore && existsSync51(projectConfigPath(projectDir));
|
|
47102
47445
|
if (json) {
|
|
47103
47446
|
console.log(JSON.stringify(result));
|
|
47104
47447
|
return;
|
|
@@ -47128,7 +47471,7 @@ var init_add = __esm({
|
|
|
47128
47471
|
process.exit(1);
|
|
47129
47472
|
}
|
|
47130
47473
|
let config = loadProjectConfig(projectDir);
|
|
47131
|
-
if (!
|
|
47474
|
+
if (!existsSync51(projectConfigPath(projectDir)) && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
47132
47475
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
47133
47476
|
config = DEFAULT_PROJECT_CONFIG;
|
|
47134
47477
|
}
|
|
@@ -47348,17 +47691,17 @@ var init_format = __esm({
|
|
|
47348
47691
|
});
|
|
47349
47692
|
|
|
47350
47693
|
// src/utils/project.ts
|
|
47351
|
-
import { existsSync as
|
|
47694
|
+
import { existsSync as existsSync52, statSync as statSync18 } from "fs";
|
|
47352
47695
|
import { resolve as resolve29, basename as basename8 } from "path";
|
|
47353
47696
|
function resolveProject(dirArg) {
|
|
47354
47697
|
const dir = resolve29(dirArg ?? ".");
|
|
47355
47698
|
const name = basename8(dir);
|
|
47356
47699
|
const indexPath = resolve29(dir, "index.html");
|
|
47357
|
-
if (!
|
|
47700
|
+
if (!existsSync52(dir) || !statSync18(dir).isDirectory()) {
|
|
47358
47701
|
errorBox("Not a directory: " + dir);
|
|
47359
47702
|
process.exit(1);
|
|
47360
47703
|
}
|
|
47361
|
-
if (!
|
|
47704
|
+
if (!existsSync52(indexPath)) {
|
|
47362
47705
|
errorBox(
|
|
47363
47706
|
"No composition found in " + dir,
|
|
47364
47707
|
"No index.html file found.",
|
|
@@ -47381,7 +47724,7 @@ __export(play_exports, {
|
|
|
47381
47724
|
default: () => play_default,
|
|
47382
47725
|
examples: () => examples5
|
|
47383
47726
|
});
|
|
47384
|
-
import { existsSync as
|
|
47727
|
+
import { existsSync as existsSync53, readFileSync as readFileSync36 } from "fs";
|
|
47385
47728
|
import { resolve as resolve30, dirname as dirname21 } from "path";
|
|
47386
47729
|
function commandDir() {
|
|
47387
47730
|
return dirname21(new URL(import.meta.url).pathname);
|
|
@@ -47396,7 +47739,7 @@ function resolveRuntimePath2() {
|
|
|
47396
47739
|
resolve30(d2, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
|
|
47397
47740
|
];
|
|
47398
47741
|
for (const p2 of candidates) {
|
|
47399
|
-
if (
|
|
47742
|
+
if (existsSync53(p2)) return p2;
|
|
47400
47743
|
}
|
|
47401
47744
|
return null;
|
|
47402
47745
|
}
|
|
@@ -47410,7 +47753,7 @@ function resolvePlayerPath() {
|
|
|
47410
47753
|
resolve30(d2, "..", "hyperframes-player.global.js")
|
|
47411
47754
|
];
|
|
47412
47755
|
for (const p2 of candidates) {
|
|
47413
|
-
if (
|
|
47756
|
+
if (existsSync53(p2)) return p2;
|
|
47414
47757
|
}
|
|
47415
47758
|
return null;
|
|
47416
47759
|
}
|
|
@@ -47520,13 +47863,13 @@ var init_play = __esm({
|
|
|
47520
47863
|
const { createAdaptorServer } = await import("@hono/node-server");
|
|
47521
47864
|
const app = new Hono6();
|
|
47522
47865
|
app.get("/player.js", (ctx) => {
|
|
47523
|
-
return ctx.body(
|
|
47866
|
+
return ctx.body(readFileSync36(playerPath, "utf-8"), 200, {
|
|
47524
47867
|
"Content-Type": "application/javascript",
|
|
47525
47868
|
"Cache-Control": "no-cache"
|
|
47526
47869
|
});
|
|
47527
47870
|
});
|
|
47528
47871
|
app.get("/runtime.js", (ctx) => {
|
|
47529
|
-
return ctx.body(
|
|
47872
|
+
return ctx.body(readFileSync36(runtimePath, "utf-8"), 200, {
|
|
47530
47873
|
"Content-Type": "application/javascript",
|
|
47531
47874
|
"Cache-Control": "no-cache"
|
|
47532
47875
|
});
|
|
@@ -47535,8 +47878,8 @@ var init_play = __esm({
|
|
|
47535
47878
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
47536
47879
|
const filePath = resolve30(project.dir, reqPath);
|
|
47537
47880
|
if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
|
|
47538
|
-
if (!
|
|
47539
|
-
const content =
|
|
47881
|
+
if (!existsSync53(filePath)) return ctx.text("Not found", 404);
|
|
47882
|
+
const content = readFileSync36(filePath, "utf-8");
|
|
47540
47883
|
if (filePath.endsWith(".html")) {
|
|
47541
47884
|
const injected = injectRuntime(content);
|
|
47542
47885
|
return ctx.html(injected);
|
|
@@ -47555,7 +47898,7 @@ var init_play = __esm({
|
|
|
47555
47898
|
mp3: "audio/mpeg",
|
|
47556
47899
|
wav: "audio/wav"
|
|
47557
47900
|
};
|
|
47558
|
-
return ctx.body(
|
|
47901
|
+
return ctx.body(readFileSync36(filePath), 200, {
|
|
47559
47902
|
"Content-Type": types3[ext] ?? "application/octet-stream"
|
|
47560
47903
|
});
|
|
47561
47904
|
});
|
|
@@ -47616,7 +47959,7 @@ var init_play = __esm({
|
|
|
47616
47959
|
|
|
47617
47960
|
// src/utils/publishProject.ts
|
|
47618
47961
|
import { basename as basename9, join as join60, relative as relative8 } from "path";
|
|
47619
|
-
import { readdirSync as readdirSync22, readFileSync as
|
|
47962
|
+
import { readdirSync as readdirSync22, readFileSync as readFileSync37, statSync as statSync19 } from "fs";
|
|
47620
47963
|
import AdmZip from "adm-zip";
|
|
47621
47964
|
function isRecord2(value) {
|
|
47622
47965
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -47735,7 +48078,7 @@ function createPublishArchive(projectDir) {
|
|
|
47735
48078
|
}
|
|
47736
48079
|
const archive = new AdmZip();
|
|
47737
48080
|
for (const filePath of filePaths) {
|
|
47738
|
-
archive.addFile(filePath,
|
|
48081
|
+
archive.addFile(filePath, readFileSync37(join60(projectDir, filePath)));
|
|
47739
48082
|
}
|
|
47740
48083
|
return {
|
|
47741
48084
|
buffer: archive.toBuffer(),
|
|
@@ -47856,7 +48199,7 @@ __export(publish_exports, {
|
|
|
47856
48199
|
examples: () => examples6
|
|
47857
48200
|
});
|
|
47858
48201
|
import { basename as basename10, resolve as resolve31 } from "path";
|
|
47859
|
-
import { existsSync as
|
|
48202
|
+
import { existsSync as existsSync54 } from "fs";
|
|
47860
48203
|
import { join as join61 } from "path";
|
|
47861
48204
|
var examples6, publish_default;
|
|
47862
48205
|
var init_publish = __esm({
|
|
@@ -47893,7 +48236,7 @@ var init_publish = __esm({
|
|
|
47893
48236
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
47894
48237
|
const projectName = isImplicitCwd ? basename10(process.env["PWD"] ?? dir) : basename10(dir);
|
|
47895
48238
|
const indexPath = join61(dir, "index.html");
|
|
47896
|
-
if (
|
|
48239
|
+
if (existsSync54(indexPath)) {
|
|
47897
48240
|
const lintResult = lintProject({ dir, name: projectName, indexPath });
|
|
47898
48241
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
47899
48242
|
console.log();
|
|
@@ -47963,9 +48306,9 @@ var init_dom = __esm({
|
|
|
47963
48306
|
});
|
|
47964
48307
|
|
|
47965
48308
|
// src/utils/variables.ts
|
|
47966
|
-
import { readFileSync as
|
|
48309
|
+
import { readFileSync as readFileSync38 } from "fs";
|
|
47967
48310
|
import { resolve as resolve32 } from "path";
|
|
47968
|
-
function parseVariablesArg(inline, filePath, readFile = (p2) =>
|
|
48311
|
+
function parseVariablesArg(inline, filePath, readFile = (p2) => readFileSync38(resolve32(p2), "utf8")) {
|
|
47969
48312
|
if (inline != null && filePath != null) {
|
|
47970
48313
|
return { ok: false, error: { kind: "conflict" } };
|
|
47971
48314
|
}
|
|
@@ -48048,7 +48391,7 @@ function validateVariablesAgainstProject(indexPath, values) {
|
|
|
48048
48391
|
function loadProjectVariableSchema(indexPath) {
|
|
48049
48392
|
let html;
|
|
48050
48393
|
try {
|
|
48051
|
-
html =
|
|
48394
|
+
html = readFileSync38(indexPath, "utf8");
|
|
48052
48395
|
} catch {
|
|
48053
48396
|
return [];
|
|
48054
48397
|
}
|
|
@@ -48176,11 +48519,11 @@ __export(ffmpeg_exports, {
|
|
|
48176
48519
|
findFFmpeg: () => findFFmpeg,
|
|
48177
48520
|
getFFmpegInstallHint: () => getFFmpegInstallHint
|
|
48178
48521
|
});
|
|
48179
|
-
import { execSync as
|
|
48522
|
+
import { execSync as execSync3 } from "child_process";
|
|
48180
48523
|
function findFFmpeg() {
|
|
48181
48524
|
try {
|
|
48182
48525
|
const cmd = process.platform === "win32" ? "where ffmpeg" : "which ffmpeg";
|
|
48183
|
-
const output =
|
|
48526
|
+
const output = execSync3(cmd, {
|
|
48184
48527
|
encoding: "utf-8",
|
|
48185
48528
|
stdio: ["pipe", "pipe", "pipe"],
|
|
48186
48529
|
timeout: 5e3
|
|
@@ -48215,7 +48558,7 @@ __export(render_exports, {
|
|
|
48215
48558
|
renderLocal: () => renderLocal,
|
|
48216
48559
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
48217
48560
|
});
|
|
48218
|
-
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as
|
|
48561
|
+
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as readFileSync39, statSync as statSync20, writeFileSync as writeFileSync26, rmSync as rmSync14 } from "fs";
|
|
48219
48562
|
import { cpus as cpus4, freemem as freemem4, tmpdir as tmpdir5 } from "os";
|
|
48220
48563
|
import { resolve as resolve33, dirname as dirname22, join as join62, basename as basename11 } from "path";
|
|
48221
48564
|
import { execFileSync as execFileSync6, spawn as spawn13 } from "child_process";
|
|
@@ -48276,7 +48619,7 @@ function ensureDockerImage(version, quiet) {
|
|
|
48276
48619
|
const dockerfilePath = resolveDockerfilePath();
|
|
48277
48620
|
const tmpDir = join62(tmpdir5(), `hyperframes-docker-${Date.now()}`);
|
|
48278
48621
|
mkdirSync32(tmpDir, { recursive: true });
|
|
48279
|
-
writeFileSync26(join62(tmpDir, "Dockerfile"),
|
|
48622
|
+
writeFileSync26(join62(tmpDir, "Dockerfile"), readFileSync39(dockerfilePath));
|
|
48280
48623
|
try {
|
|
48281
48624
|
execFileSync6(
|
|
48282
48625
|
"docker",
|
|
@@ -49135,7 +49478,7 @@ var init_lint3 = __esm({
|
|
|
49135
49478
|
|
|
49136
49479
|
// src/utils/staticProjectServer.ts
|
|
49137
49480
|
import { createServer } from "http";
|
|
49138
|
-
import { existsSync as
|
|
49481
|
+
import { existsSync as existsSync55, readFileSync as readFileSync40 } from "fs";
|
|
49139
49482
|
import { isAbsolute as isAbsolute8, relative as relative9, resolve as resolve34 } from "path";
|
|
49140
49483
|
async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Failed to bind local HTTP server") {
|
|
49141
49484
|
const server = createServer((req, res) => {
|
|
@@ -49152,9 +49495,9 @@ async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Fail
|
|
|
49152
49495
|
res.end();
|
|
49153
49496
|
return;
|
|
49154
49497
|
}
|
|
49155
|
-
if (
|
|
49498
|
+
if (existsSync55(filePath)) {
|
|
49156
49499
|
res.writeHead(200, { "Content-Type": getMimeType(filePath) });
|
|
49157
|
-
res.end(
|
|
49500
|
+
res.end(readFileSync40(filePath));
|
|
49158
49501
|
return;
|
|
49159
49502
|
}
|
|
49160
49503
|
res.writeHead(404);
|
|
@@ -49330,7 +49673,7 @@ __export(layout_exports, {
|
|
|
49330
49673
|
default: () => layout_default,
|
|
49331
49674
|
examples: () => examples9
|
|
49332
49675
|
});
|
|
49333
|
-
import { existsSync as
|
|
49676
|
+
import { existsSync as existsSync56, readFileSync as readFileSync41 } from "fs";
|
|
49334
49677
|
import { dirname as dirname23, join as join63 } from "path";
|
|
49335
49678
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
49336
49679
|
async function getCompositionDuration2(page) {
|
|
@@ -49481,7 +49824,7 @@ function loadLayoutAuditScript() {
|
|
|
49481
49824
|
join63(__dirname2, "commands", "layout-audit.browser.js")
|
|
49482
49825
|
];
|
|
49483
49826
|
for (const candidate of candidates) {
|
|
49484
|
-
if (
|
|
49827
|
+
if (existsSync56(candidate)) return readFileSync41(candidate, "utf-8");
|
|
49485
49828
|
}
|
|
49486
49829
|
throw new Error("Missing layout audit browser script");
|
|
49487
49830
|
}
|
|
@@ -49689,7 +50032,7 @@ __export(info_exports, {
|
|
|
49689
50032
|
default: () => info_default,
|
|
49690
50033
|
examples: () => examples11
|
|
49691
50034
|
});
|
|
49692
|
-
import { readFileSync as
|
|
50035
|
+
import { readFileSync as readFileSync42, readdirSync as readdirSync24, statSync as statSync21 } from "fs";
|
|
49693
50036
|
import { join as join64 } from "path";
|
|
49694
50037
|
function totalSize(dir) {
|
|
49695
50038
|
let total = 0;
|
|
@@ -49726,7 +50069,7 @@ var init_info = __esm({
|
|
|
49726
50069
|
},
|
|
49727
50070
|
async run({ args }) {
|
|
49728
50071
|
const project = resolveProject(args.dir);
|
|
49729
|
-
const html =
|
|
50072
|
+
const html = readFileSync42(project.indexPath, "utf-8");
|
|
49730
50073
|
ensureDOMParser();
|
|
49731
50074
|
const parsed = parseHtml(html);
|
|
49732
50075
|
const tracks = new Set(parsed.elements.map((el) => el.zIndex));
|
|
@@ -49784,7 +50127,7 @@ __export(compositions_exports, {
|
|
|
49784
50127
|
examples: () => examples12,
|
|
49785
50128
|
parseSubComposition: () => parseSubComposition
|
|
49786
50129
|
});
|
|
49787
|
-
import { existsSync as
|
|
50130
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43 } from "fs";
|
|
49788
50131
|
import { resolve as resolve35, dirname as dirname24 } from "path";
|
|
49789
50132
|
function countRenderableDescendants(root) {
|
|
49790
50133
|
return Array.from(root.querySelectorAll("*")).filter(
|
|
@@ -49818,8 +50161,8 @@ function parseCompositions(html, baseDir) {
|
|
|
49818
50161
|
const compositionSrc = div.getAttribute("data-composition-src");
|
|
49819
50162
|
if (compositionSrc) {
|
|
49820
50163
|
const subPath = resolve35(baseDir, compositionSrc);
|
|
49821
|
-
if (
|
|
49822
|
-
const subHtml =
|
|
50164
|
+
if (existsSync57(subPath)) {
|
|
50165
|
+
const subHtml = readFileSync43(subPath, "utf-8");
|
|
49823
50166
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
49824
50167
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
49825
50168
|
return;
|
|
@@ -49922,7 +50265,7 @@ var init_compositions = __esm({
|
|
|
49922
50265
|
},
|
|
49923
50266
|
async run({ args }) {
|
|
49924
50267
|
const project = resolveProject(args.dir);
|
|
49925
|
-
const html =
|
|
50268
|
+
const html = readFileSync43(project.indexPath, "utf-8");
|
|
49926
50269
|
ensureDOMParser();
|
|
49927
50270
|
const compositions = parseCompositions(html, dirname24(project.indexPath));
|
|
49928
50271
|
if (compositions.length === 0) {
|
|
@@ -49960,7 +50303,7 @@ __export(benchmark_exports, {
|
|
|
49960
50303
|
default: () => benchmark_default,
|
|
49961
50304
|
examples: () => examples13
|
|
49962
50305
|
});
|
|
49963
|
-
import { existsSync as
|
|
50306
|
+
import { existsSync as existsSync58, statSync as statSync22 } from "fs";
|
|
49964
50307
|
import { resolve as resolve36, join as join65 } from "path";
|
|
49965
50308
|
var examples13, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
|
|
49966
50309
|
var init_benchmark = __esm({
|
|
@@ -50053,7 +50396,7 @@ var init_benchmark = __esm({
|
|
|
50053
50396
|
await producer.executeRenderJob(job, project.dir, outputPath);
|
|
50054
50397
|
const elapsedMs = Date.now() - startTime;
|
|
50055
50398
|
let fileSize = null;
|
|
50056
|
-
if (
|
|
50399
|
+
if (existsSync58(outputPath)) {
|
|
50057
50400
|
const stat3 = statSync22(outputPath);
|
|
50058
50401
|
fileSize = stat3.size;
|
|
50059
50402
|
}
|
|
@@ -50307,8 +50650,8 @@ __export(manager_exports3, {
|
|
|
50307
50650
|
modelPath: () => modelPath,
|
|
50308
50651
|
selectProviders: () => selectProviders
|
|
50309
50652
|
});
|
|
50310
|
-
import { existsSync as
|
|
50311
|
-
import { homedir as homedir9, platform as
|
|
50653
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync33 } from "fs";
|
|
50654
|
+
import { homedir as homedir9, platform as platform7, arch } from "os";
|
|
50312
50655
|
import { join as join66 } from "path";
|
|
50313
50656
|
function isDevice(value) {
|
|
50314
50657
|
return typeof value === "string" && DEVICES.includes(value);
|
|
@@ -50334,7 +50677,7 @@ function selectProviders(device = "auto") {
|
|
|
50334
50677
|
}
|
|
50335
50678
|
return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
50336
50679
|
}
|
|
50337
|
-
if (hasCoreML &&
|
|
50680
|
+
if (hasCoreML && platform7() === "darwin" && arch() === "arm64") {
|
|
50338
50681
|
return { providers: ["coreml", "cpu"], label: "CoreML" };
|
|
50339
50682
|
}
|
|
50340
50683
|
if (hasCUDA) return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
@@ -50343,7 +50686,7 @@ function selectProviders(device = "auto") {
|
|
|
50343
50686
|
function listAvailableProviders() {
|
|
50344
50687
|
if (_cachedProviders) return _cachedProviders;
|
|
50345
50688
|
const out = ["cpu"];
|
|
50346
|
-
if (
|
|
50689
|
+
if (platform7() === "darwin" && arch() === "arm64") out.push("coreml");
|
|
50347
50690
|
if (process.env["HYPERFRAMES_CUDA"] === "1") out.push("cuda");
|
|
50348
50691
|
_cachedProviders = out;
|
|
50349
50692
|
return out;
|
|
@@ -50353,11 +50696,11 @@ function modelPath(model = DEFAULT_MODEL2) {
|
|
|
50353
50696
|
}
|
|
50354
50697
|
async function ensureModel2(model = DEFAULT_MODEL2, options) {
|
|
50355
50698
|
const dest = modelPath(model);
|
|
50356
|
-
if (
|
|
50699
|
+
if (existsSync59(dest)) return dest;
|
|
50357
50700
|
mkdirSync33(MODELS_DIR2, { recursive: true });
|
|
50358
50701
|
options?.onProgress?.(`Downloading ${model} weights (~168 MB)...`);
|
|
50359
50702
|
await downloadFile(MODEL_URLS[model], dest);
|
|
50360
|
-
if (!
|
|
50703
|
+
if (!existsSync59(dest)) {
|
|
50361
50704
|
throw new Error(`Model download failed: ${model}`);
|
|
50362
50705
|
}
|
|
50363
50706
|
return dest;
|
|
@@ -50838,12 +51181,12 @@ __export(remove_background_exports, {
|
|
|
50838
51181
|
examples: () => examples15
|
|
50839
51182
|
});
|
|
50840
51183
|
import { resolve as resolve37 } from "path";
|
|
50841
|
-
import { existsSync as
|
|
51184
|
+
import { existsSync as existsSync60 } from "fs";
|
|
50842
51185
|
async function showInfo(json) {
|
|
50843
51186
|
const { selectProviders: selectProviders2, listAvailableProviders: listAvailableProviders2, DEFAULT_MODEL: DEFAULT_MODEL4, MODEL_MEMORY_MB: MODEL_MEMORY_MB2, modelPath: modelPath2 } = await Promise.resolve().then(() => (init_manager3(), manager_exports3));
|
|
50844
51187
|
const providers = listAvailableProviders2();
|
|
50845
51188
|
const auto = selectProviders2("auto");
|
|
50846
|
-
const cached2 =
|
|
51189
|
+
const cached2 = existsSync60(modelPath2());
|
|
50847
51190
|
if (json) {
|
|
50848
51191
|
console.log(
|
|
50849
51192
|
JSON.stringify({
|
|
@@ -51050,7 +51393,7 @@ __export(transcribe_exports2, {
|
|
|
51050
51393
|
default: () => transcribe_default,
|
|
51051
51394
|
examples: () => examples16
|
|
51052
51395
|
});
|
|
51053
|
-
import { existsSync as
|
|
51396
|
+
import { existsSync as existsSync61, writeFileSync as writeFileSync27 } from "fs";
|
|
51054
51397
|
import { resolve as resolve38, join as join67, extname as extname11, dirname as dirname25 } from "path";
|
|
51055
51398
|
async function importTranscript(inputPath, dir, json) {
|
|
51056
51399
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
@@ -51176,7 +51519,7 @@ var init_transcribe2 = __esm({
|
|
|
51176
51519
|
},
|
|
51177
51520
|
async run({ args }) {
|
|
51178
51521
|
const inputPath = resolve38(args.input);
|
|
51179
|
-
if (!
|
|
51522
|
+
if (!existsSync61(inputPath)) {
|
|
51180
51523
|
console.error(c2.error(`File not found: ${args.input}`));
|
|
51181
51524
|
process.exit(1);
|
|
51182
51525
|
}
|
|
@@ -51197,7 +51540,7 @@ var init_transcribe2 = __esm({
|
|
|
51197
51540
|
});
|
|
51198
51541
|
|
|
51199
51542
|
// src/tts/manager.ts
|
|
51200
|
-
import { existsSync as
|
|
51543
|
+
import { existsSync as existsSync62, mkdirSync as mkdirSync34 } from "fs";
|
|
51201
51544
|
import { homedir as homedir10 } from "os";
|
|
51202
51545
|
import { join as join68 } from "path";
|
|
51203
51546
|
function inferLangFromVoiceId(voiceId) {
|
|
@@ -51209,7 +51552,7 @@ function isSupportedLang(value) {
|
|
|
51209
51552
|
}
|
|
51210
51553
|
async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
51211
51554
|
const modelPath2 = join68(MODELS_DIR3, `${model}.onnx`);
|
|
51212
|
-
if (
|
|
51555
|
+
if (existsSync62(modelPath2)) return modelPath2;
|
|
51213
51556
|
const url = MODEL_URLS2[model];
|
|
51214
51557
|
if (!url) {
|
|
51215
51558
|
throw new Error(
|
|
@@ -51219,18 +51562,18 @@ async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
|
51219
51562
|
mkdirSync34(MODELS_DIR3, { recursive: true });
|
|
51220
51563
|
options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
|
|
51221
51564
|
await downloadFile(url, modelPath2);
|
|
51222
|
-
if (!
|
|
51565
|
+
if (!existsSync62(modelPath2)) {
|
|
51223
51566
|
throw new Error(`Model download failed: ${model}`);
|
|
51224
51567
|
}
|
|
51225
51568
|
return modelPath2;
|
|
51226
51569
|
}
|
|
51227
51570
|
async function ensureVoices(options) {
|
|
51228
51571
|
const voicesPath = join68(VOICES_DIR, "voices-v1.0.bin");
|
|
51229
|
-
if (
|
|
51572
|
+
if (existsSync62(voicesPath)) return voicesPath;
|
|
51230
51573
|
mkdirSync34(VOICES_DIR, { recursive: true });
|
|
51231
51574
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
51232
51575
|
await downloadFile(VOICES_URL, voicesPath);
|
|
51233
|
-
if (!
|
|
51576
|
+
if (!existsSync62(voicesPath)) {
|
|
51234
51577
|
throw new Error("Voice data download failed");
|
|
51235
51578
|
}
|
|
51236
51579
|
return voicesPath;
|
|
@@ -51303,7 +51646,7 @@ __export(synthesize_exports, {
|
|
|
51303
51646
|
synthesize: () => synthesize
|
|
51304
51647
|
});
|
|
51305
51648
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
51306
|
-
import { existsSync as
|
|
51649
|
+
import { existsSync as existsSync63, writeFileSync as writeFileSync28, mkdirSync as mkdirSync35, readdirSync as readdirSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
51307
51650
|
import { join as join69, dirname as dirname26, basename as basename12 } from "path";
|
|
51308
51651
|
import { homedir as homedir11 } from "os";
|
|
51309
51652
|
function findPython() {
|
|
@@ -51340,7 +51683,7 @@ function hasPythonPackage(python, pkg) {
|
|
|
51340
51683
|
}
|
|
51341
51684
|
}
|
|
51342
51685
|
function ensureSynthScript() {
|
|
51343
|
-
if (!
|
|
51686
|
+
if (!existsSync63(SCRIPT_PATH)) {
|
|
51344
51687
|
mkdirSync35(SCRIPT_DIR, { recursive: true });
|
|
51345
51688
|
writeFileSync28(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
51346
51689
|
const currentName = basename12(SCRIPT_PATH);
|
|
@@ -51394,7 +51737,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51394
51737
|
stdio: ["pipe", "pipe", "pipe"]
|
|
51395
51738
|
}
|
|
51396
51739
|
);
|
|
51397
|
-
if (!
|
|
51740
|
+
if (!existsSync63(outputPath)) {
|
|
51398
51741
|
throw new Error("Synthesis completed but no output file was created");
|
|
51399
51742
|
}
|
|
51400
51743
|
const lines = stdout2.trim().split("\n");
|
|
@@ -51407,7 +51750,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51407
51750
|
langApplied: result.langApplied
|
|
51408
51751
|
};
|
|
51409
51752
|
} catch (err) {
|
|
51410
|
-
if (err instanceof SyntaxError &&
|
|
51753
|
+
if (err instanceof SyntaxError && existsSync63(outputPath)) {
|
|
51411
51754
|
throw new Error(
|
|
51412
51755
|
"Speech was generated but metadata could not be read. Check the output file manually."
|
|
51413
51756
|
);
|
|
@@ -51469,7 +51812,7 @@ __export(tts_exports, {
|
|
|
51469
51812
|
default: () => tts_default,
|
|
51470
51813
|
examples: () => examples17
|
|
51471
51814
|
});
|
|
51472
|
-
import { existsSync as
|
|
51815
|
+
import { existsSync as existsSync64, readFileSync as readFileSync44 } from "fs";
|
|
51473
51816
|
import { resolve as resolve39, extname as extname12 } from "path";
|
|
51474
51817
|
function listVoices(json) {
|
|
51475
51818
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -51579,8 +51922,8 @@ var init_tts = __esm({
|
|
|
51579
51922
|
}
|
|
51580
51923
|
let text;
|
|
51581
51924
|
const maybeFile = resolve39(args.input);
|
|
51582
|
-
if (
|
|
51583
|
-
text =
|
|
51925
|
+
if (existsSync64(maybeFile) && extname12(maybeFile).toLowerCase() === ".txt") {
|
|
51926
|
+
text = readFileSync44(maybeFile, "utf-8").trim();
|
|
51584
51927
|
if (!text) {
|
|
51585
51928
|
console.error(c2.error("File is empty."));
|
|
51586
51929
|
process.exit(1);
|
|
@@ -51672,7 +52015,7 @@ __export(docs_exports, {
|
|
|
51672
52015
|
default: () => docs_default,
|
|
51673
52016
|
examples: () => examples18
|
|
51674
52017
|
});
|
|
51675
|
-
import { readFileSync as
|
|
52018
|
+
import { readFileSync as readFileSync45, existsSync as existsSync65 } from "fs";
|
|
51676
52019
|
import { resolve as resolve40, dirname as dirname27, join as join70 } from "path";
|
|
51677
52020
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
51678
52021
|
function docsDir() {
|
|
@@ -51680,7 +52023,7 @@ function docsDir() {
|
|
|
51680
52023
|
const dir = dirname27(thisFile);
|
|
51681
52024
|
const devPath = resolve40(dir, "..", "docs");
|
|
51682
52025
|
const builtPath = resolve40(dir, "docs");
|
|
51683
|
-
return
|
|
52026
|
+
return existsSync65(devPath) ? devPath : builtPath;
|
|
51684
52027
|
}
|
|
51685
52028
|
function formatInlineCode(line) {
|
|
51686
52029
|
return line.replace(/`([^`]+)`/g, (_match, code) => c2.accent(code));
|
|
@@ -51778,11 +52121,11 @@ var init_docs = __esm({
|
|
|
51778
52121
|
process.exit(1);
|
|
51779
52122
|
}
|
|
51780
52123
|
const filePath = join70(docsDir(), entry.file);
|
|
51781
|
-
if (!
|
|
52124
|
+
if (!existsSync65(filePath)) {
|
|
51782
52125
|
console.error(c2.error(`Doc file not found: ${filePath}`));
|
|
51783
52126
|
process.exit(1);
|
|
51784
52127
|
}
|
|
51785
|
-
const content =
|
|
52128
|
+
const content = readFileSync45(filePath, "utf-8");
|
|
51786
52129
|
console.log();
|
|
51787
52130
|
renderMarkdown(content);
|
|
51788
52131
|
}
|
|
@@ -51798,13 +52141,13 @@ __export(doctor_exports, {
|
|
|
51798
52141
|
examples: () => examples19,
|
|
51799
52142
|
redactHome: () => redactHome
|
|
51800
52143
|
});
|
|
51801
|
-
import { execSync as
|
|
51802
|
-
import { freemem as freemem5, platform as
|
|
52144
|
+
import { execSync as execSync4 } from "child_process";
|
|
52145
|
+
import { freemem as freemem5, platform as platform8 } from "os";
|
|
51803
52146
|
function checkFFmpeg() {
|
|
51804
52147
|
const path2 = findFFmpeg();
|
|
51805
52148
|
if (path2) {
|
|
51806
52149
|
try {
|
|
51807
|
-
const version =
|
|
52150
|
+
const version = execSync4("ffmpeg -version", { encoding: "utf-8", timeout: 5e3 }).split("\n")[0] ?? "";
|
|
51808
52151
|
return { ok: true, detail: version.trim() };
|
|
51809
52152
|
} catch {
|
|
51810
52153
|
return { ok: true, detail: path2 };
|
|
@@ -51818,7 +52161,7 @@ function checkFFmpeg() {
|
|
|
51818
52161
|
}
|
|
51819
52162
|
function checkFFprobe() {
|
|
51820
52163
|
try {
|
|
51821
|
-
const version =
|
|
52164
|
+
const version = execSync4("ffprobe -version", { encoding: "utf-8", timeout: 5e3 }).split("\n")[0] ?? "";
|
|
51822
52165
|
return { ok: true, detail: version.trim() };
|
|
51823
52166
|
} catch {
|
|
51824
52167
|
return {
|
|
@@ -51841,7 +52184,7 @@ async function checkChrome() {
|
|
|
51841
52184
|
}
|
|
51842
52185
|
function checkDocker() {
|
|
51843
52186
|
try {
|
|
51844
|
-
const version =
|
|
52187
|
+
const version = execSync4("docker --version", { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
51845
52188
|
return { ok: true, detail: version };
|
|
51846
52189
|
} catch {
|
|
51847
52190
|
return {
|
|
@@ -51853,7 +52196,7 @@ function checkDocker() {
|
|
|
51853
52196
|
}
|
|
51854
52197
|
function checkDockerRunning() {
|
|
51855
52198
|
try {
|
|
51856
|
-
|
|
52199
|
+
execSync4("docker info", { stdio: "pipe", timeout: 5e3 });
|
|
51857
52200
|
return { ok: true, detail: "Running" };
|
|
51858
52201
|
} catch {
|
|
51859
52202
|
return {
|
|
@@ -51988,7 +52331,7 @@ var init_doctor = __esm({
|
|
|
51988
52331
|
{ name: "Memory", run: checkMemory },
|
|
51989
52332
|
{ name: "Disk", run: checkDisk }
|
|
51990
52333
|
];
|
|
51991
|
-
if (
|
|
52334
|
+
if (platform8() === "linux") {
|
|
51992
52335
|
checks.push({ name: "/dev/shm", run: checkShm });
|
|
51993
52336
|
}
|
|
51994
52337
|
checks.push(
|
|
@@ -52246,16 +52589,18 @@ function parseViewportDimension(value) {
|
|
|
52246
52589
|
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
52247
52590
|
return Math.min(parsed, MAX_VIEWPORT_DIMENSION);
|
|
52248
52591
|
}
|
|
52249
|
-
function
|
|
52592
|
+
function findCompositionDimensions(html) {
|
|
52250
52593
|
ensureDOMParser();
|
|
52251
52594
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
52252
52595
|
const root = doc.querySelector("[data-composition-id][data-width][data-height]");
|
|
52253
|
-
|
|
52254
|
-
const
|
|
52255
|
-
|
|
52256
|
-
|
|
52257
|
-
|
|
52258
|
-
|
|
52596
|
+
if (!root) return null;
|
|
52597
|
+
const width = parseViewportDimension(root.getAttribute("data-width"));
|
|
52598
|
+
const height = parseViewportDimension(root.getAttribute("data-height"));
|
|
52599
|
+
if (width === null || height === null) return null;
|
|
52600
|
+
return { width, height };
|
|
52601
|
+
}
|
|
52602
|
+
function resolveCompositionViewportFromHtml(html) {
|
|
52603
|
+
return findCompositionDimensions(html) ?? DEFAULT_VIEWPORT;
|
|
52259
52604
|
}
|
|
52260
52605
|
var DEFAULT_VIEWPORT, MAX_VIEWPORT_DIMENSION;
|
|
52261
52606
|
var init_compositionViewport = __esm({
|
|
@@ -52273,7 +52618,7 @@ __export(validate_exports, {
|
|
|
52273
52618
|
default: () => validate_default,
|
|
52274
52619
|
shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
|
|
52275
52620
|
});
|
|
52276
|
-
import { existsSync as
|
|
52621
|
+
import { existsSync as existsSync66, readFileSync as readFileSync46 } from "fs";
|
|
52277
52622
|
import { join as join71, dirname as dirname28 } from "path";
|
|
52278
52623
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
52279
52624
|
function shouldIgnoreRequestFailure(url, errorText) {
|
|
@@ -52330,7 +52675,7 @@ function loadContrastAuditScript() {
|
|
|
52330
52675
|
join71(__dirname3, "commands", "contrast-audit.browser.js")
|
|
52331
52676
|
];
|
|
52332
52677
|
for (const candidate of candidates) {
|
|
52333
|
-
if (
|
|
52678
|
+
if (existsSync66(candidate)) return readFileSync46(candidate, "utf-8");
|
|
52334
52679
|
}
|
|
52335
52680
|
throw new Error("Missing contrast audit browser script");
|
|
52336
52681
|
}
|
|
@@ -52348,9 +52693,9 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
52348
52693
|
return;
|
|
52349
52694
|
}
|
|
52350
52695
|
const filePath = join71(projectDir, decodeURIComponent(url));
|
|
52351
|
-
if (
|
|
52696
|
+
if (existsSync66(filePath)) {
|
|
52352
52697
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
52353
|
-
res.end(
|
|
52698
|
+
res.end(readFileSync46(filePath));
|
|
52354
52699
|
return;
|
|
52355
52700
|
}
|
|
52356
52701
|
res.writeHead(404);
|
|
@@ -52552,7 +52897,7 @@ __export(contactSheet_exports, {
|
|
|
52552
52897
|
createSvgContactSheet: () => createSvgContactSheet
|
|
52553
52898
|
});
|
|
52554
52899
|
import sharp from "sharp";
|
|
52555
|
-
import { readdirSync as readdirSync26, readFileSync as
|
|
52900
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync47, writeFileSync as writeFileSync29, unlinkSync as unlinkSync7, existsSync as existsSync67 } from "fs";
|
|
52556
52901
|
import { join as join72, extname as extname13, basename as basename13, dirname as dirname29 } from "path";
|
|
52557
52902
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
52558
52903
|
const {
|
|
@@ -52632,7 +52977,7 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
52632
52977
|
return results;
|
|
52633
52978
|
}
|
|
52634
52979
|
async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
52635
|
-
if (!
|
|
52980
|
+
if (!existsSync67(screenshotsDir)) return [];
|
|
52636
52981
|
const scrollFiles = readdirSync26(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
52637
52982
|
if (scrollFiles.length === 0) return [];
|
|
52638
52983
|
const paths = scrollFiles.map((f3) => join72(screenshotsDir, f3));
|
|
@@ -52649,7 +52994,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
|
52649
52994
|
);
|
|
52650
52995
|
}
|
|
52651
52996
|
async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
52652
|
-
if (!
|
|
52997
|
+
if (!existsSync67(snapshotsDir)) return [];
|
|
52653
52998
|
const snapshotFiles = readdirSync26(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
52654
52999
|
if (snapshotFiles.length === 0) return [];
|
|
52655
53000
|
const paths = snapshotFiles.map((f3) => join72(snapshotsDir, f3));
|
|
@@ -52666,7 +53011,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
|
52666
53011
|
);
|
|
52667
53012
|
}
|
|
52668
53013
|
async function createAssetContactSheet(assetsDir, outputPath) {
|
|
52669
|
-
if (!
|
|
53014
|
+
if (!existsSync67(assetsDir)) return [];
|
|
52670
53015
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
52671
53016
|
const assetFiles = readdirSync26(assetsDir).filter((f3) => imageExts.has(extname13(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
52672
53017
|
if (assetFiles.length === 0) return [];
|
|
@@ -52680,7 +53025,7 @@ async function createAssetContactSheet(assetsDir, outputPath) {
|
|
|
52680
53025
|
}
|
|
52681
53026
|
async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
52682
53027
|
const dirsToScan = [svgsDir, assetsRootDir].filter(
|
|
52683
|
-
(d2) => d2 !== void 0 &&
|
|
53028
|
+
(d2) => d2 !== void 0 && existsSync67(d2)
|
|
52684
53029
|
);
|
|
52685
53030
|
if (dirsToScan.length === 0) return [];
|
|
52686
53031
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -52703,7 +53048,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
|
52703
53048
|
const svgPath = svgPaths[i2];
|
|
52704
53049
|
const tmpPath = join72(tmpDir, `.thumb-${i2}.png`);
|
|
52705
53050
|
try {
|
|
52706
|
-
const svgBuf =
|
|
53051
|
+
const svgBuf = readFileSync47(svgPath);
|
|
52707
53052
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
52708
53053
|
fit: "contain",
|
|
52709
53054
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
@@ -93261,7 +93606,7 @@ __export(snapshot_exports, {
|
|
|
93261
93606
|
examples: () => examples22
|
|
93262
93607
|
});
|
|
93263
93608
|
import { spawn as spawn15 } from "child_process";
|
|
93264
|
-
import { existsSync as
|
|
93609
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync3, readFileSync as readFileSync48, mkdirSync as mkdirSync36, rmSync as rmSync15, writeFileSync as writeFileSync30 } from "fs";
|
|
93265
93610
|
import { tmpdir as tmpdir6 } from "os";
|
|
93266
93611
|
import { resolve as resolve41, join as join73, relative as relative10, isAbsolute as isAbsolute9 } from "path";
|
|
93267
93612
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
@@ -93306,8 +93651,8 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
93306
93651
|
});
|
|
93307
93652
|
}
|
|
93308
93653
|
);
|
|
93309
|
-
if (result.code !== 0 || result.timedOut || !
|
|
93310
|
-
return
|
|
93654
|
+
if (result.code !== 0 || result.timedOut || !existsSync68(outPath)) return null;
|
|
93655
|
+
return readFileSync48(outPath);
|
|
93311
93656
|
} finally {
|
|
93312
93657
|
try {
|
|
93313
93658
|
rmSync15(tmp, { recursive: true, force: true });
|
|
@@ -93505,7 +93850,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
93505
93850
|
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
|
93506
93851
|
const candidate = resolve41(projectDir, decodedPath);
|
|
93507
93852
|
const rel = relative10(projectDir, candidate);
|
|
93508
|
-
if (!rel.startsWith("..") && !isAbsolute9(rel) &&
|
|
93853
|
+
if (!rel.startsWith("..") && !isAbsolute9(rel) && existsSync68(candidate)) {
|
|
93509
93854
|
filePath = candidate;
|
|
93510
93855
|
}
|
|
93511
93856
|
} catch {
|
|
@@ -93656,8 +94001,8 @@ ${c2.success("\u25C7")} ${paths.length} snapshots saved to snapshots/`);
|
|
|
93656
94001
|
paths.map(async (p2) => {
|
|
93657
94002
|
const filename = p2.replace("snapshots/", "");
|
|
93658
94003
|
const filePath = join73(snapshotDir, filename);
|
|
93659
|
-
if (!
|
|
93660
|
-
const raw =
|
|
94004
|
+
if (!existsSync68(filePath)) return { filename, desc: "file not found" };
|
|
94005
|
+
const raw = readFileSync48(filePath);
|
|
93661
94006
|
let imageData;
|
|
93662
94007
|
let mimeType = "image/png";
|
|
93663
94008
|
if (sharpFn) {
|
|
@@ -94851,7 +95196,7 @@ var init_designStyleExtractor = __esm({
|
|
|
94851
95196
|
});
|
|
94852
95197
|
|
|
94853
95198
|
// src/capture/fontMetadataExtractor.ts
|
|
94854
|
-
import { readdirSync as readdirSync27, readFileSync as
|
|
95199
|
+
import { readdirSync as readdirSync27, readFileSync as readFileSync49, writeFileSync as writeFileSync32, existsSync as existsSync69 } from "fs";
|
|
94855
95200
|
import { join as join75 } from "path";
|
|
94856
95201
|
import * as fontkit from "fontkit";
|
|
94857
95202
|
function isFontCollection(value) {
|
|
@@ -94860,7 +95205,7 @@ function isFontCollection(value) {
|
|
|
94860
95205
|
function extractFontMetadata(fontsDir, outputPath) {
|
|
94861
95206
|
const files = [];
|
|
94862
95207
|
const unidentified = [];
|
|
94863
|
-
if (
|
|
95208
|
+
if (existsSync69(fontsDir)) {
|
|
94864
95209
|
const fontFiles = readdirSync27(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
94865
95210
|
for (const filename of fontFiles) {
|
|
94866
95211
|
const fullPath = join75(fontsDir, filename);
|
|
@@ -94901,7 +95246,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
94901
95246
|
identified: false
|
|
94902
95247
|
};
|
|
94903
95248
|
try {
|
|
94904
|
-
const buf =
|
|
95249
|
+
const buf = readFileSync49(fullPath);
|
|
94905
95250
|
const created = fontkit.create(buf);
|
|
94906
95251
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
94907
95252
|
if (!font) return empty;
|
|
@@ -95157,7 +95502,7 @@ var init_animationCataloger = __esm({
|
|
|
95157
95502
|
});
|
|
95158
95503
|
|
|
95159
95504
|
// src/capture/mediaCapture.ts
|
|
95160
|
-
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as
|
|
95505
|
+
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as readFileSync50, statSync as statSync24 } from "fs";
|
|
95161
95506
|
import { join as join76 } from "path";
|
|
95162
95507
|
async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
95163
95508
|
let savedCount = 0;
|
|
@@ -95224,7 +95569,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95224
95569
|
for (const file of readdirSync28(lottieDir)) {
|
|
95225
95570
|
if (!file.endsWith(".json")) continue;
|
|
95226
95571
|
try {
|
|
95227
|
-
const raw = JSON.parse(
|
|
95572
|
+
const raw = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95228
95573
|
const fr = raw.fr || 30;
|
|
95229
95574
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
95230
95575
|
const previewName = file.replace(".json", "-preview.png");
|
|
@@ -95234,7 +95579,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95234
95579
|
try {
|
|
95235
95580
|
previewPage = await chromeBrowser.newPage();
|
|
95236
95581
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
95237
|
-
const animData = JSON.parse(
|
|
95582
|
+
const animData = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95238
95583
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
95239
95584
|
await previewPage.setContent(
|
|
95240
95585
|
`<!DOCTYPE html>
|
|
@@ -95413,7 +95758,7 @@ var init_mediaCapture = __esm({
|
|
|
95413
95758
|
});
|
|
95414
95759
|
|
|
95415
95760
|
// src/capture/contentExtractor.ts
|
|
95416
|
-
import { existsSync as
|
|
95761
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, statSync as statSync25, readFileSync as readFileSync51 } from "fs";
|
|
95417
95762
|
import { join as join77 } from "path";
|
|
95418
95763
|
async function detectLibraries(page, capturedShaders) {
|
|
95419
95764
|
let detectedLibraries = [];
|
|
@@ -95546,7 +95891,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95546
95891
|
const filePath = join77(outputDir, "assets", file);
|
|
95547
95892
|
const stat3 = statSync25(filePath);
|
|
95548
95893
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
95549
|
-
const buffer =
|
|
95894
|
+
const buffer = readFileSync51(filePath);
|
|
95550
95895
|
const base64 = buffer.toString("base64");
|
|
95551
95896
|
const ext = file.split(".").pop()?.toLowerCase() || "png";
|
|
95552
95897
|
const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -95588,7 +95933,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95588
95933
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
95589
95934
|
}
|
|
95590
95935
|
const svgsSubdir = join77(assetsDir, "svgs");
|
|
95591
|
-
if (
|
|
95936
|
+
if (existsSync70(svgsSubdir)) {
|
|
95592
95937
|
for (const f3 of readdirSync29(svgsSubdir)) {
|
|
95593
95938
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
95594
95939
|
}
|
|
@@ -95602,7 +95947,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95602
95947
|
const results = await Promise.allSettled(
|
|
95603
95948
|
batch.map(async ({ relPath }) => {
|
|
95604
95949
|
const filePath = join77(assetsDir, relPath);
|
|
95605
|
-
let svgText =
|
|
95950
|
+
let svgText = readFileSync51(filePath, "utf-8");
|
|
95606
95951
|
if (svgText.length > MAX_SVG_CHARS) {
|
|
95607
95952
|
svgText = svgText.slice(0, MAX_SVG_CHARS) + "\n<!-- truncated -->";
|
|
95608
95953
|
}
|
|
@@ -95720,7 +96065,7 @@ var agentPromptGenerator_exports = {};
|
|
|
95720
96065
|
__export(agentPromptGenerator_exports, {
|
|
95721
96066
|
generateAgentPrompt: () => generateAgentPrompt
|
|
95722
96067
|
});
|
|
95723
|
-
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as
|
|
96068
|
+
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as existsSync71 } from "fs";
|
|
95724
96069
|
import { join as join78 } from "path";
|
|
95725
96070
|
function inferColorRole(hex) {
|
|
95726
96071
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -95752,7 +96097,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95752
96097
|
).join(", ") || "none detected";
|
|
95753
96098
|
function contactSheetRows(dir, baseFile, label2) {
|
|
95754
96099
|
const fullDir = join78(outputDir, dir);
|
|
95755
|
-
if (!
|
|
96100
|
+
if (!existsSync71(fullDir)) return [];
|
|
95756
96101
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
95757
96102
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95758
96103
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
@@ -95784,7 +96129,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95784
96129
|
tableRows.push(
|
|
95785
96130
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
95786
96131
|
);
|
|
95787
|
-
if (
|
|
96132
|
+
if (existsSync71(join78(outputDir, "extracted", "design-styles.json"))) {
|
|
95788
96133
|
tableRows.push(
|
|
95789
96134
|
"| `extracted/design-styles.json` | Computed styles from live DOM: typography hierarchy, button/card/nav styles, spacing scale, border-radius, box shadows. Primary data source for DESIGN.md. |"
|
|
95790
96135
|
);
|
|
@@ -95855,7 +96200,7 @@ var init_agentPromptGenerator = __esm({
|
|
|
95855
96200
|
});
|
|
95856
96201
|
|
|
95857
96202
|
// src/capture/scaffolding.ts
|
|
95858
|
-
import { existsSync as
|
|
96203
|
+
import { existsSync as existsSync72, writeFileSync as writeFileSync35, readFileSync as readFileSync52 } from "fs";
|
|
95859
96204
|
import { join as join79, resolve as resolve42 } from "path";
|
|
95860
96205
|
function loadEnvFile(startDir) {
|
|
95861
96206
|
try {
|
|
@@ -95863,7 +96208,7 @@ function loadEnvFile(startDir) {
|
|
|
95863
96208
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
95864
96209
|
const envPath = resolve42(dir, ".env");
|
|
95865
96210
|
try {
|
|
95866
|
-
const envContent =
|
|
96211
|
+
const envContent = readFileSync52(envPath, "utf-8");
|
|
95867
96212
|
for (const line of envContent.split("\n")) {
|
|
95868
96213
|
const trimmed = line.trim();
|
|
95869
96214
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -95883,7 +96228,7 @@ function loadEnvFile(startDir) {
|
|
|
95883
96228
|
}
|
|
95884
96229
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
95885
96230
|
const metaPath = join79(outputDir, "meta.json");
|
|
95886
|
-
if (!
|
|
96231
|
+
if (!existsSync72(metaPath)) {
|
|
95887
96232
|
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
95888
96233
|
writeFileSync35(
|
|
95889
96234
|
metaPath,
|
|
@@ -96290,7 +96635,7 @@ var capture_exports = {};
|
|
|
96290
96635
|
__export(capture_exports, {
|
|
96291
96636
|
captureWebsite: () => captureWebsite
|
|
96292
96637
|
});
|
|
96293
|
-
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as
|
|
96638
|
+
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as existsSync73 } from "fs";
|
|
96294
96639
|
import { join as join81 } from "path";
|
|
96295
96640
|
async function captureWebsite(opts, onProgress) {
|
|
96296
96641
|
const {
|
|
@@ -96653,7 +96998,7 @@ ${err.stack}` : String(err);
|
|
|
96653
96998
|
`Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
|
|
96654
96999
|
);
|
|
96655
97000
|
const assetsImgDir = join81(outputDir, "assets");
|
|
96656
|
-
if (
|
|
97001
|
+
if (existsSync73(assetsImgDir)) {
|
|
96657
97002
|
const assetSheets = await createAssetContactSheet2(
|
|
96658
97003
|
assetsImgDir,
|
|
96659
97004
|
join81(outputDir, "assets", "contact-sheet.jpg")
|
|
@@ -96666,7 +97011,7 @@ ${err.stack}` : String(err);
|
|
|
96666
97011
|
}
|
|
96667
97012
|
const svgsDir = join81(outputDir, "assets", "svgs");
|
|
96668
97013
|
const assetsRootDir = join81(outputDir, "assets");
|
|
96669
|
-
const svgOutputPath =
|
|
97014
|
+
const svgOutputPath = existsSync73(svgsDir) ? join81(outputDir, "assets", "svgs", "contact-sheet.jpg") : join81(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
96670
97015
|
const svgSheets = await createSvgContactSheet2(svgsDir, svgOutputPath, assetsRootDir);
|
|
96671
97016
|
if (svgSheets.length > 0)
|
|
96672
97017
|
progress(
|
|
@@ -96682,7 +97027,7 @@ ${err.stack}` : String(err);
|
|
|
96682
97027
|
animationCatalog,
|
|
96683
97028
|
screenshots.length > 0,
|
|
96684
97029
|
discoveredLotties.length > 0,
|
|
96685
|
-
|
|
97030
|
+
existsSync73(join81(outputDir, "extracted", "shaders.json")),
|
|
96686
97031
|
catalogedAssets,
|
|
96687
97032
|
progress,
|
|
96688
97033
|
warnings,
|
|
@@ -96910,7 +97255,7 @@ __export(state_exports, {
|
|
|
96910
97255
|
stateFilePath: () => stateFilePath,
|
|
96911
97256
|
writeStackOutputs: () => writeStackOutputs
|
|
96912
97257
|
});
|
|
96913
|
-
import { existsSync as
|
|
97258
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync41, readdirSync as readdirSync31, readFileSync as readFileSync53, rmSync as rmSync16, writeFileSync as writeFileSync38 } from "fs";
|
|
96914
97259
|
import { dirname as dirname30, join as join82 } from "path";
|
|
96915
97260
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96916
97261
|
return join82(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -96923,20 +97268,20 @@ function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
|
96923
97268
|
}
|
|
96924
97269
|
function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96925
97270
|
const path2 = stateFilePath(stackName, cwd);
|
|
96926
|
-
if (!
|
|
97271
|
+
if (!existsSync74(path2)) return null;
|
|
96927
97272
|
try {
|
|
96928
|
-
return JSON.parse(
|
|
97273
|
+
return JSON.parse(readFileSync53(path2, "utf-8"));
|
|
96929
97274
|
} catch {
|
|
96930
97275
|
return null;
|
|
96931
97276
|
}
|
|
96932
97277
|
}
|
|
96933
97278
|
function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96934
97279
|
const path2 = stateFilePath(stackName, cwd);
|
|
96935
|
-
if (
|
|
97280
|
+
if (existsSync74(path2)) rmSync16(path2);
|
|
96936
97281
|
}
|
|
96937
97282
|
function listStackNames(cwd = process.cwd()) {
|
|
96938
97283
|
const dir = join82(cwd, STATE_DIR_NAME);
|
|
96939
|
-
if (!
|
|
97284
|
+
if (!existsSync74(dir)) return [];
|
|
96940
97285
|
return readdirSync31(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
96941
97286
|
}
|
|
96942
97287
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
@@ -96966,7 +97311,7 @@ var init_state = __esm({
|
|
|
96966
97311
|
|
|
96967
97312
|
// src/commands/lambda/sam.ts
|
|
96968
97313
|
import { execFileSync as execFileSync9, spawnSync as spawnSync4 } from "child_process";
|
|
96969
|
-
import { existsSync as
|
|
97314
|
+
import { existsSync as existsSync75 } from "fs";
|
|
96970
97315
|
import { join as join83 } from "path";
|
|
96971
97316
|
function assertSamAvailable() {
|
|
96972
97317
|
try {
|
|
@@ -96988,7 +97333,7 @@ function assertAwsCliAvailable() {
|
|
|
96988
97333
|
}
|
|
96989
97334
|
function locateSamTemplate(repoRoot2) {
|
|
96990
97335
|
const candidate = join83(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
96991
|
-
if (!
|
|
97336
|
+
if (!existsSync75(candidate)) {
|
|
96992
97337
|
throw new Error(
|
|
96993
97338
|
`[lambda] SAM template not found at ${candidate}. If you're running from an installed package, point --sam-template at your local copy of examples/aws-lambda/template.yaml.`
|
|
96994
97339
|
);
|
|
@@ -97083,17 +97428,17 @@ var init_sam = __esm({
|
|
|
97083
97428
|
});
|
|
97084
97429
|
|
|
97085
97430
|
// src/commands/lambda/repoRoot.ts
|
|
97086
|
-
import { existsSync as
|
|
97431
|
+
import { existsSync as existsSync76 } from "fs";
|
|
97087
97432
|
import { dirname as dirname31, resolve as resolve44 } from "path";
|
|
97088
97433
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
97089
97434
|
function repoRoot() {
|
|
97090
97435
|
const override = process.env.HYPERFRAMES_REPO_ROOT;
|
|
97091
|
-
if (override &&
|
|
97436
|
+
if (override && existsSync76(resolve44(override, "packages", "aws-lambda", "package.json"))) {
|
|
97092
97437
|
return override;
|
|
97093
97438
|
}
|
|
97094
97439
|
let dir = dirname31(fileURLToPath11(import.meta.url));
|
|
97095
97440
|
for (let depth = 0; depth < 12; depth++) {
|
|
97096
|
-
if (
|
|
97441
|
+
if (existsSync76(resolve44(dir, "packages", "aws-lambda", "package.json"))) {
|
|
97097
97442
|
return dir;
|
|
97098
97443
|
}
|
|
97099
97444
|
const parent = dirname31(dir);
|
|
@@ -97116,7 +97461,7 @@ __export(deploy_exports, {
|
|
|
97116
97461
|
runDeploy: () => runDeploy
|
|
97117
97462
|
});
|
|
97118
97463
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
97119
|
-
import { existsSync as
|
|
97464
|
+
import { existsSync as existsSync77 } from "fs";
|
|
97120
97465
|
import { join as join84, resolve as resolve45 } from "path";
|
|
97121
97466
|
async function runDeploy(args = {}) {
|
|
97122
97467
|
const resolved = {
|
|
@@ -97135,7 +97480,7 @@ async function runDeploy(args = {}) {
|
|
|
97135
97480
|
buildHandlerZip(root);
|
|
97136
97481
|
} else {
|
|
97137
97482
|
const zip = join84(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
97138
|
-
if (!
|
|
97483
|
+
if (!existsSync77(zip)) {
|
|
97139
97484
|
throw new Error(
|
|
97140
97485
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
97141
97486
|
);
|
|
@@ -97246,23 +97591,61 @@ var init_sites = __esm({
|
|
|
97246
97591
|
}
|
|
97247
97592
|
});
|
|
97248
97593
|
|
|
97594
|
+
// src/commands/lambda/_dimensions.ts
|
|
97595
|
+
import { readFileSync as readFileSync54 } from "fs";
|
|
97596
|
+
import { join as join85 } from "path";
|
|
97597
|
+
function warnOnDimensionMismatch(args) {
|
|
97598
|
+
if (args.quiet) return;
|
|
97599
|
+
if (args.outputResolution) return;
|
|
97600
|
+
let html;
|
|
97601
|
+
try {
|
|
97602
|
+
html = readFileSync54(join85(args.projectDir, "index.html"), "utf-8");
|
|
97603
|
+
} catch {
|
|
97604
|
+
return;
|
|
97605
|
+
}
|
|
97606
|
+
const composition = findCompositionDimensions(html);
|
|
97607
|
+
if (!composition) return;
|
|
97608
|
+
if (composition.width === args.cliWidth && composition.height === args.cliHeight) return;
|
|
97609
|
+
console.warn(
|
|
97610
|
+
c2.warn(
|
|
97611
|
+
`--width/--height (${args.cliWidth}\xD7${args.cliHeight}) disagrees with the composition's data-width/data-height (${composition.width}\xD7${composition.height}). The runtime lays out the page at the composition's authored dimensions, so your output will be ${composition.width}\xD7${composition.height}, not ${args.cliWidth}\xD7${args.cliHeight}.
|
|
97612
|
+
To supersample to a higher resolution, pass --output-resolution (e.g. \`--output-resolution=4k\`).
|
|
97613
|
+
To truly change layout dimensions, edit the composition's data-width/data-height in index.html.`
|
|
97614
|
+
)
|
|
97615
|
+
);
|
|
97616
|
+
}
|
|
97617
|
+
var init_dimensions = __esm({
|
|
97618
|
+
"src/commands/lambda/_dimensions.ts"() {
|
|
97619
|
+
"use strict";
|
|
97620
|
+
init_colors();
|
|
97621
|
+
init_compositionViewport();
|
|
97622
|
+
}
|
|
97623
|
+
});
|
|
97624
|
+
|
|
97249
97625
|
// src/commands/lambda/render.ts
|
|
97250
97626
|
var render_exports2 = {};
|
|
97251
97627
|
__export(render_exports2, {
|
|
97252
97628
|
runRender: () => runRender
|
|
97253
97629
|
});
|
|
97254
|
-
import { existsSync as
|
|
97255
|
-
import { join as
|
|
97630
|
+
import { existsSync as existsSync78 } from "fs";
|
|
97631
|
+
import { join as join86, resolve as resolvePath2 } from "path";
|
|
97256
97632
|
async function loadSDK2() {
|
|
97257
97633
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97258
97634
|
}
|
|
97259
97635
|
async function runRender(args) {
|
|
97260
97636
|
const stack = requireStack(args.stackName);
|
|
97261
97637
|
const projectDir = resolvePath2(args.projectDir);
|
|
97638
|
+
warnOnDimensionMismatch({
|
|
97639
|
+
projectDir,
|
|
97640
|
+
cliWidth: args.width,
|
|
97641
|
+
cliHeight: args.height,
|
|
97642
|
+
outputResolution: args.outputResolution,
|
|
97643
|
+
quiet: args.json
|
|
97644
|
+
});
|
|
97262
97645
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
97263
97646
|
if (variables && Object.keys(variables).length > 0) {
|
|
97264
|
-
const indexPath =
|
|
97265
|
-
if (
|
|
97647
|
+
const indexPath = join86(projectDir, "index.html");
|
|
97648
|
+
if (existsSync78(indexPath)) {
|
|
97266
97649
|
const issues = validateVariablesAgainstProject(indexPath, variables);
|
|
97267
97650
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
97268
97651
|
} else if (args.strictVariables && !args.json) {
|
|
@@ -97277,6 +97660,7 @@ async function runRender(args) {
|
|
|
97277
97660
|
fps: args.fps,
|
|
97278
97661
|
width: args.width,
|
|
97279
97662
|
height: args.height,
|
|
97663
|
+
outputResolution: args.outputResolution,
|
|
97280
97664
|
format: args.format,
|
|
97281
97665
|
codec: args.codec,
|
|
97282
97666
|
quality: args.quality,
|
|
@@ -97372,6 +97756,7 @@ var init_render3 = __esm({
|
|
|
97372
97756
|
"use strict";
|
|
97373
97757
|
init_colors();
|
|
97374
97758
|
init_variables();
|
|
97759
|
+
init_dimensions();
|
|
97375
97760
|
init_state();
|
|
97376
97761
|
}
|
|
97377
97762
|
});
|
|
@@ -97383,8 +97768,8 @@ __export(render_batch_exports, {
|
|
|
97383
97768
|
runRenderBatch: () => runRenderBatch,
|
|
97384
97769
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
97385
97770
|
});
|
|
97386
|
-
import { existsSync as
|
|
97387
|
-
import { join as
|
|
97771
|
+
import { existsSync as existsSync79, readFileSync as readFileSync55 } from "fs";
|
|
97772
|
+
import { join as join87, resolve as resolvePath3 } from "path";
|
|
97388
97773
|
async function loadSDK3() {
|
|
97389
97774
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97390
97775
|
}
|
|
@@ -97392,7 +97777,7 @@ async function runRenderBatch(args) {
|
|
|
97392
97777
|
const projectDir = resolvePath3(args.projectDir);
|
|
97393
97778
|
const stack = requireStack(args.stackName);
|
|
97394
97779
|
const batchPath = resolvePath3(args.batch);
|
|
97395
|
-
if (!
|
|
97780
|
+
if (!existsSync79(batchPath)) {
|
|
97396
97781
|
errorBox("Batch file not found", `No such file: ${batchPath}`);
|
|
97397
97782
|
process.exit(1);
|
|
97398
97783
|
}
|
|
@@ -97401,7 +97786,14 @@ async function runRenderBatch(args) {
|
|
|
97401
97786
|
errorBox("Empty batch", `${batchPath} contains zero entries (every line was blank).`);
|
|
97402
97787
|
process.exit(1);
|
|
97403
97788
|
}
|
|
97404
|
-
|
|
97789
|
+
warnOnDimensionMismatch({
|
|
97790
|
+
projectDir,
|
|
97791
|
+
cliWidth: args.width,
|
|
97792
|
+
cliHeight: args.height,
|
|
97793
|
+
outputResolution: args.outputResolution,
|
|
97794
|
+
quiet: args.json
|
|
97795
|
+
});
|
|
97796
|
+
const schema = loadProjectVariableSchema(join87(projectDir, "index.html"));
|
|
97405
97797
|
const strict = args.strictVariables ?? false;
|
|
97406
97798
|
let hadStrictIssue = false;
|
|
97407
97799
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -97426,6 +97818,7 @@ async function runRenderBatch(args) {
|
|
|
97426
97818
|
fps: args.fps,
|
|
97427
97819
|
width: args.width,
|
|
97428
97820
|
height: args.height,
|
|
97821
|
+
outputResolution: args.outputResolution,
|
|
97429
97822
|
format: args.format,
|
|
97430
97823
|
codec: args.codec,
|
|
97431
97824
|
quality: args.quality,
|
|
@@ -97527,7 +97920,7 @@ function makePlaceholderSiteHandle(siteId, bucketName) {
|
|
|
97527
97920
|
};
|
|
97528
97921
|
}
|
|
97529
97922
|
function parseBatchFile(path2) {
|
|
97530
|
-
const raw =
|
|
97923
|
+
const raw = readFileSync55(path2, "utf8");
|
|
97531
97924
|
const lines = raw.split(/\r?\n/);
|
|
97532
97925
|
const out = [];
|
|
97533
97926
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
@@ -97608,6 +98001,7 @@ var init_render_batch = __esm({
|
|
|
97608
98001
|
init_colors();
|
|
97609
98002
|
init_format();
|
|
97610
98003
|
init_variables();
|
|
98004
|
+
init_dimensions();
|
|
97611
98005
|
init_state();
|
|
97612
98006
|
DEFAULT_MAX_CONCURRENT = 50;
|
|
97613
98007
|
}
|
|
@@ -97720,7 +98114,7 @@ __export(policies_exports, {
|
|
|
97720
98114
|
runPolicies: () => runPolicies,
|
|
97721
98115
|
validatePolicy: () => validatePolicy
|
|
97722
98116
|
});
|
|
97723
|
-
import { readFileSync as
|
|
98117
|
+
import { readFileSync as readFileSync56 } from "fs";
|
|
97724
98118
|
function allRequiredActions() {
|
|
97725
98119
|
const set = /* @__PURE__ */ new Set();
|
|
97726
98120
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -97826,7 +98220,7 @@ async function runPolicies(args) {
|
|
|
97826
98220
|
}
|
|
97827
98221
|
}
|
|
97828
98222
|
function validatePolicy(policyPath) {
|
|
97829
|
-
const raw =
|
|
98223
|
+
const raw = readFileSync56(policyPath, "utf-8");
|
|
97830
98224
|
const parsed = JSON.parse(raw);
|
|
97831
98225
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
97832
98226
|
parsed.Statement
|
|
@@ -98014,11 +98408,20 @@ function parseEnum(raw, allowed, errorPrefix, defaultValue) {
|
|
|
98014
98408
|
if (allowed.includes(s2)) return s2;
|
|
98015
98409
|
throw new Error(`${errorPrefix} must be ${allowed.join("|")}; got ${s2}`);
|
|
98016
98410
|
}
|
|
98411
|
+
function parseOutputResolution(raw) {
|
|
98412
|
+
if (raw == null || raw === "") return void 0;
|
|
98413
|
+
const normalized = normalizeResolutionFlag(String(raw));
|
|
98414
|
+
if (normalized) return normalized;
|
|
98415
|
+
throw new Error(
|
|
98416
|
+
`[lambda render] --output-resolution must be one of ${VALID_CANVAS_RESOLUTIONS.join("|")} (or an alias: 1080p, 4k, uhd, hd, 1080p-portrait, portrait-1080p, 4k-portrait, 1080p-square, square-1080p, 4k-square); got ${String(raw)}`
|
|
98417
|
+
);
|
|
98418
|
+
}
|
|
98017
98419
|
var examples24, HELP, lambda_default, FORMATS, CODECS, QUALITIES2, CHROME_SOURCES, parseFormat, parseCodec, parseQuality, parseChromeSource;
|
|
98018
98420
|
var init_lambda = __esm({
|
|
98019
98421
|
"src/commands/lambda.ts"() {
|
|
98020
98422
|
"use strict";
|
|
98021
98423
|
init_dist();
|
|
98424
|
+
init_src();
|
|
98022
98425
|
init_colors();
|
|
98023
98426
|
examples24 = [
|
|
98024
98427
|
["Deploy the Lambda render stack to AWS", "hyperframes lambda deploy"],
|
|
@@ -98030,6 +98433,10 @@ var init_lambda = __esm({
|
|
|
98030
98433
|
"Render and stream progress until done",
|
|
98031
98434
|
"hyperframes lambda render ./my-project --width 1920 --height 1080 --wait"
|
|
98032
98435
|
],
|
|
98436
|
+
[
|
|
98437
|
+
"Supersample a 1080p composition to 4K via Chrome deviceScaleFactor",
|
|
98438
|
+
"hyperframes lambda render ./my-project --width 1920 --height 1080 --output-resolution 4k --wait"
|
|
98439
|
+
],
|
|
98033
98440
|
[
|
|
98034
98441
|
"Render with composition variables (personalised template)",
|
|
98035
98442
|
`hyperframes lambda render ./my-template --site-id abc1234deadbeef0 --width 1920 --height 1080 --variables '{"title":"Hello Alice","accent":"#ff0000"}'`
|
|
@@ -98114,6 +98521,10 @@ ${c2.bold("REQUIREMENTS:")}
|
|
|
98114
98521
|
"site-id": { type: "string", description: "Explicit site id (overrides content hash)" },
|
|
98115
98522
|
width: { type: "string", description: "Render width in pixels" },
|
|
98116
98523
|
height: { type: "string", description: "Render height in pixels" },
|
|
98524
|
+
"output-resolution": {
|
|
98525
|
+
type: "string",
|
|
98526
|
+
description: "Output resolution preset that engages Chrome deviceScaleFactor supersampling. Accepts canonical names (landscape, landscape-4k, portrait, portrait-4k, square, square-4k) and aliases (1080p, 4k, uhd, hd). When set, the composition's authored data-width/data-height is supersampled to the target preset without changing the layout."
|
|
98527
|
+
},
|
|
98117
98528
|
fps: { type: "string", description: "Render fps (24 | 30 | 60)" },
|
|
98118
98529
|
format: { type: "string", description: "mp4 | mov | png-sequence | webm (default: mp4)" },
|
|
98119
98530
|
codec: { type: "string", description: "h264 | h265 (mp4 only)" },
|
|
@@ -98268,6 +98679,7 @@ Or, for an opt-in dev setup:
|
|
|
98268
98679
|
fps: fpsRaw,
|
|
98269
98680
|
width,
|
|
98270
98681
|
height,
|
|
98682
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98271
98683
|
format: parseFormat(args.format),
|
|
98272
98684
|
codec: parseCodec(args.codec),
|
|
98273
98685
|
quality: parseQuality(args.quality),
|
|
@@ -98319,6 +98731,7 @@ Or, for an opt-in dev setup:
|
|
|
98319
98731
|
fps: fpsRaw,
|
|
98320
98732
|
width,
|
|
98321
98733
|
height,
|
|
98734
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98322
98735
|
format: parseFormat(args.format),
|
|
98323
98736
|
codec: parseCodec(args.codec),
|
|
98324
98737
|
quality: parseQuality(args.quality),
|
|
@@ -98521,7 +98934,7 @@ __export(autoUpdate_exports, {
|
|
|
98521
98934
|
import { spawn as spawn16 } from "child_process";
|
|
98522
98935
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync42, openSync as openSync2 } from "fs";
|
|
98523
98936
|
import { homedir as homedir12 } from "os";
|
|
98524
|
-
import { join as
|
|
98937
|
+
import { join as join88 } from "path";
|
|
98525
98938
|
import { compareVersions as compareVersions2 } from "compare-versions";
|
|
98526
98939
|
function isAutoInstallDisabled() {
|
|
98527
98940
|
if (isDevMode()) return true;
|
|
@@ -98544,7 +98957,7 @@ function log(line) {
|
|
|
98544
98957
|
}
|
|
98545
98958
|
function launchDetachedInstall(installCommand, version) {
|
|
98546
98959
|
mkdirSync42(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
98547
|
-
const configFile =
|
|
98960
|
+
const configFile = join88(CONFIG_DIR2, "config.json");
|
|
98548
98961
|
const nodeScript = `
|
|
98549
98962
|
const { exec } = require("node:child_process");
|
|
98550
98963
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -98663,8 +99076,8 @@ var init_autoUpdate = __esm({
|
|
|
98663
99076
|
init_config();
|
|
98664
99077
|
init_env();
|
|
98665
99078
|
init_installerDetection();
|
|
98666
|
-
CONFIG_DIR2 =
|
|
98667
|
-
LOG_FILE =
|
|
99079
|
+
CONFIG_DIR2 = join88(homedir12(), ".hyperframes");
|
|
99080
|
+
LOG_FILE = join88(CONFIG_DIR2, "auto-update.log");
|
|
98668
99081
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
98669
99082
|
}
|
|
98670
99083
|
});
|
|
@@ -98852,17 +99265,17 @@ var init_help = __esm({
|
|
|
98852
99265
|
// src/cli.ts
|
|
98853
99266
|
init_version();
|
|
98854
99267
|
init_dist();
|
|
98855
|
-
import { dirname as dirname32, join as
|
|
99268
|
+
import { dirname as dirname32, join as join89 } from "path";
|
|
98856
99269
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
98857
|
-
import { existsSync as
|
|
99270
|
+
import { existsSync as existsSync80 } from "fs";
|
|
98858
99271
|
(() => {
|
|
98859
99272
|
const here = dirname32(fileURLToPath12(import.meta.url));
|
|
98860
|
-
const shader =
|
|
98861
|
-
const png =
|
|
98862
|
-
if (!process.env.HF_SHADER_WORKER_ENTRY &&
|
|
99273
|
+
const shader = join89(here, "shaderTransitionWorker.js");
|
|
99274
|
+
const png = join89(here, "pngDecodeBlitWorker.js");
|
|
99275
|
+
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync80(shader)) {
|
|
98863
99276
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
98864
99277
|
}
|
|
98865
|
-
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY &&
|
|
99278
|
+
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY && existsSync80(png)) {
|
|
98866
99279
|
process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY = png;
|
|
98867
99280
|
}
|
|
98868
99281
|
})();
|
|
@@ -98874,10 +99287,10 @@ if (rootVersionRequested) {
|
|
|
98874
99287
|
process.exit(0);
|
|
98875
99288
|
}
|
|
98876
99289
|
try {
|
|
98877
|
-
const { readFileSync:
|
|
99290
|
+
const { readFileSync: readFileSync57 } = await import("fs");
|
|
98878
99291
|
const { resolve: resolve46 } = await import("path");
|
|
98879
99292
|
const envPath = resolve46(process.cwd(), ".env");
|
|
98880
|
-
const envContent =
|
|
99293
|
+
const envContent = readFileSync57(envPath, "utf-8");
|
|
98881
99294
|
for (const rawLine of envContent.split("\n")) {
|
|
98882
99295
|
let line = rawLine.trim();
|
|
98883
99296
|
if (!line || line.startsWith("#")) continue;
|