hyperframes 0.6.36 → 0.6.37
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 +769 -538
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.6.
|
|
57
|
+
VERSION = true ? "0.6.37" : "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
|
}
|
|
@@ -13132,13 +13293,13 @@ var init_fileWatcher = __esm({
|
|
|
13132
13293
|
});
|
|
13133
13294
|
|
|
13134
13295
|
// src/server/runtimeSource.ts
|
|
13135
|
-
import { existsSync as
|
|
13296
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11 } from "fs";
|
|
13136
13297
|
import { resolve as resolve7, dirname as dirname5 } from "path";
|
|
13137
13298
|
async function loadRuntimeSource() {
|
|
13138
13299
|
return await buildFromSource2() ?? await getInlinedRuntime() ?? readPrebuiltArtifact();
|
|
13139
13300
|
}
|
|
13140
13301
|
async function buildFromSource2() {
|
|
13141
|
-
if (!
|
|
13302
|
+
if (!existsSync9(ENTRY_TS)) return null;
|
|
13142
13303
|
try {
|
|
13143
13304
|
const mod = await Promise.resolve().then(() => (init_src(), src_exports));
|
|
13144
13305
|
if (typeof mod.loadHyperframeRuntimeSource === "function") {
|
|
@@ -13165,7 +13326,7 @@ function readPrebuiltArtifact() {
|
|
|
13165
13326
|
function readFromDir(dir) {
|
|
13166
13327
|
for (const name of ARTIFACT_NAMES) {
|
|
13167
13328
|
const path2 = resolve7(dir, name);
|
|
13168
|
-
if (
|
|
13329
|
+
if (existsSync9(path2)) return readFileSync11(path2, "utf-8");
|
|
13169
13330
|
}
|
|
13170
13331
|
return null;
|
|
13171
13332
|
}
|
|
@@ -13383,7 +13544,7 @@ var init_mime = __esm({
|
|
|
13383
13544
|
|
|
13384
13545
|
// ../core/src/studio-api/helpers/waveform.ts
|
|
13385
13546
|
import { spawn as spawn3 } from "child_process";
|
|
13386
|
-
import { existsSync as
|
|
13547
|
+
import { existsSync as existsSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5 } from "fs";
|
|
13387
13548
|
import { join as join11 } from "path";
|
|
13388
13549
|
function buildWaveformCacheKey(assetPath) {
|
|
13389
13550
|
return `${WAVEFORM_CACHE_VERSION}_${assetPath.replace(/[/\\]/g, "_")}.json`;
|
|
@@ -13445,10 +13606,10 @@ function decodeAudioPeaks(audioPath) {
|
|
|
13445
13606
|
}
|
|
13446
13607
|
async function generateWaveformCache(projectDir, assetPath) {
|
|
13447
13608
|
const audioPath = join11(projectDir, assetPath);
|
|
13448
|
-
if (!
|
|
13609
|
+
if (!existsSync10(audioPath)) return;
|
|
13449
13610
|
const cacheDir = join11(projectDir, ".waveform-cache");
|
|
13450
13611
|
const cachePath2 = join11(cacheDir, buildWaveformCacheKey(assetPath));
|
|
13451
|
-
if (
|
|
13612
|
+
if (existsSync10(cachePath2)) return;
|
|
13452
13613
|
const peaks = await decodeAudioPeaks(audioPath);
|
|
13453
13614
|
mkdirSync5(cacheDir, { recursive: true });
|
|
13454
13615
|
writeFileSync6(cachePath2, JSON.stringify(peaks));
|
|
@@ -26303,8 +26464,8 @@ var init_sourceMutation = __esm({
|
|
|
26303
26464
|
// ../core/src/studio-api/routes/files.ts
|
|
26304
26465
|
import { bodyLimit } from "hono/body-limit";
|
|
26305
26466
|
import {
|
|
26306
|
-
existsSync as
|
|
26307
|
-
readFileSync as
|
|
26467
|
+
existsSync as existsSync11,
|
|
26468
|
+
readFileSync as readFileSync12,
|
|
26308
26469
|
writeFileSync as writeFileSync8,
|
|
26309
26470
|
mkdirSync as mkdirSync6,
|
|
26310
26471
|
unlinkSync as unlinkSync3,
|
|
@@ -26328,14 +26489,14 @@ async function resolveProjectFile(c3, adapter2, opts) {
|
|
|
26328
26489
|
if (!isSafePath(project.dir, absPath)) {
|
|
26329
26490
|
return { error: c3.json({ error: "forbidden" }, 403) };
|
|
26330
26491
|
}
|
|
26331
|
-
if (opts?.mustExist && !
|
|
26492
|
+
if (opts?.mustExist && !existsSync11(absPath)) {
|
|
26332
26493
|
return { error: c3.json({ error: "not found" }, 404) };
|
|
26333
26494
|
}
|
|
26334
26495
|
return { project, filePath, absPath };
|
|
26335
26496
|
}
|
|
26336
26497
|
function ensureDir(filePath) {
|
|
26337
26498
|
const dir = dirname6(filePath);
|
|
26338
|
-
if (!
|
|
26499
|
+
if (!existsSync11(dir)) mkdirSync6(dir, { recursive: true });
|
|
26339
26500
|
}
|
|
26340
26501
|
function generateCopyPath(projectDir, originalPath) {
|
|
26341
26502
|
const ext = originalPath.includes(".") ? "." + originalPath.split(".").pop() : "";
|
|
@@ -26344,7 +26505,7 @@ function generateCopyPath(projectDir, originalPath) {
|
|
|
26344
26505
|
const cleanBase = copyMatch ? base.slice(0, -copyMatch[0].length) : base;
|
|
26345
26506
|
let num = copyMatch ? copyMatch[1] ? parseInt(copyMatch[1]) + 1 : 2 : 1;
|
|
26346
26507
|
let candidate = num === 1 ? `${cleanBase} (copy)${ext}` : `${cleanBase} (copy ${num})${ext}`;
|
|
26347
|
-
while (
|
|
26508
|
+
while (existsSync11(resolve9(projectDir, candidate))) {
|
|
26348
26509
|
num++;
|
|
26349
26510
|
candidate = `${cleanBase} (copy ${num})${ext}`;
|
|
26350
26511
|
}
|
|
@@ -26371,7 +26532,7 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
26371
26532
|
);
|
|
26372
26533
|
let updatedCount = 0;
|
|
26373
26534
|
for (const file of textFiles) {
|
|
26374
|
-
const content =
|
|
26535
|
+
const content = readFileSync12(file, "utf-8");
|
|
26375
26536
|
if (!content.includes(oldPath)) continue;
|
|
26376
26537
|
const updated = content.split(oldPath).join(newPath);
|
|
26377
26538
|
if (updated !== content) {
|
|
@@ -26385,13 +26546,13 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26385
26546
|
api.get("/projects/:id/files/*", async (c3) => {
|
|
26386
26547
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26387
26548
|
if ("error" in res) return res.error;
|
|
26388
|
-
if (!
|
|
26549
|
+
if (!existsSync11(res.absPath)) {
|
|
26389
26550
|
if (c3.req.query("optional") === "1") {
|
|
26390
26551
|
return c3.json({ filename: res.filePath, content: "" });
|
|
26391
26552
|
}
|
|
26392
26553
|
return c3.json({ error: "not found" }, 404);
|
|
26393
26554
|
}
|
|
26394
|
-
const content =
|
|
26555
|
+
const content = readFileSync12(res.absPath, "utf-8");
|
|
26395
26556
|
return c3.json({ filename: res.filePath, content });
|
|
26396
26557
|
});
|
|
26397
26558
|
api.put("/projects/:id/files/*", async (c3) => {
|
|
@@ -26405,7 +26566,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26405
26566
|
api.post("/projects/:id/files/*", async (c3) => {
|
|
26406
26567
|
const res = await resolveProjectFile(c3, adapter2);
|
|
26407
26568
|
if ("error" in res) return res.error;
|
|
26408
|
-
if (
|
|
26569
|
+
if (existsSync11(res.absPath)) {
|
|
26409
26570
|
return c3.json({ error: "already exists" }, 409);
|
|
26410
26571
|
}
|
|
26411
26572
|
ensureDir(res.absPath);
|
|
@@ -26438,14 +26599,14 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26438
26599
|
if (!isSafePath(project.dir, absPath)) {
|
|
26439
26600
|
return c3.json({ error: "forbidden" }, 403);
|
|
26440
26601
|
}
|
|
26441
|
-
if (!
|
|
26602
|
+
if (!existsSync11(absPath)) {
|
|
26442
26603
|
return c3.json({ error: "not found" }, 404);
|
|
26443
26604
|
}
|
|
26444
26605
|
const body = await c3.req.json().catch(() => null);
|
|
26445
26606
|
if (!body?.target) {
|
|
26446
26607
|
return c3.json({ error: "target required" }, 400);
|
|
26447
26608
|
}
|
|
26448
|
-
const originalContent =
|
|
26609
|
+
const originalContent = readFileSync12(absPath, "utf-8");
|
|
26449
26610
|
const patchedContent = removeElementFromHtml2(originalContent, body.target);
|
|
26450
26611
|
if (patchedContent === originalContent) {
|
|
26451
26612
|
return c3.json({ ok: true, changed: false, content: originalContent });
|
|
@@ -26473,7 +26634,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26473
26634
|
}
|
|
26474
26635
|
let originalContent;
|
|
26475
26636
|
try {
|
|
26476
|
-
originalContent =
|
|
26637
|
+
originalContent = readFileSync12(absPath, "utf-8");
|
|
26477
26638
|
} catch {
|
|
26478
26639
|
return c3.json({ error: "not found" }, 404);
|
|
26479
26640
|
}
|
|
@@ -26495,7 +26656,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26495
26656
|
if (!isSafePath(res.project.dir, newAbs)) {
|
|
26496
26657
|
return c3.json({ error: "forbidden" }, 403);
|
|
26497
26658
|
}
|
|
26498
|
-
if (
|
|
26659
|
+
if (existsSync11(newAbs)) {
|
|
26499
26660
|
return c3.json({ error: "already exists" }, 409);
|
|
26500
26661
|
}
|
|
26501
26662
|
ensureDir(newAbs);
|
|
@@ -26511,7 +26672,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26511
26672
|
return c3.json({ error: "path required" }, 400);
|
|
26512
26673
|
}
|
|
26513
26674
|
const srcAbs = resolve9(project.dir, body.path);
|
|
26514
|
-
if (!isSafePath(project.dir, srcAbs) || !
|
|
26675
|
+
if (!isSafePath(project.dir, srcAbs) || !existsSync11(srcAbs)) {
|
|
26515
26676
|
return c3.json({ error: "not found" }, 404);
|
|
26516
26677
|
}
|
|
26517
26678
|
const copyPath = generateCopyPath(project.dir, body.path);
|
|
@@ -26520,7 +26681,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26520
26681
|
return c3.json({ error: "forbidden" }, 403);
|
|
26521
26682
|
}
|
|
26522
26683
|
ensureDir(destAbs);
|
|
26523
|
-
writeFileSync8(destAbs,
|
|
26684
|
+
writeFileSync8(destAbs, readFileSync12(srcAbs));
|
|
26524
26685
|
return c3.json({ ok: true, path: copyPath }, 201);
|
|
26525
26686
|
});
|
|
26526
26687
|
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
@@ -26536,7 +26697,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26536
26697
|
const subDir = c3.req.query("dir") ?? "";
|
|
26537
26698
|
const targetDir = subDir ? resolve9(project.dir, subDir) : project.dir;
|
|
26538
26699
|
if (!isSafePath(project.dir, targetDir)) return c3.json({ error: "forbidden" }, 403);
|
|
26539
|
-
if (subDir && !
|
|
26700
|
+
if (subDir && !existsSync11(targetDir)) mkdirSync6(targetDir, { recursive: true });
|
|
26540
26701
|
const formData = await c3.req.formData();
|
|
26541
26702
|
const uploaded = [];
|
|
26542
26703
|
const skipped = [];
|
|
@@ -26554,12 +26715,12 @@ function registerFileRoutes(api, adapter2) {
|
|
|
26554
26715
|
if (!isSafePath(project.dir, destPath)) continue;
|
|
26555
26716
|
let finalPath = destPath;
|
|
26556
26717
|
let finalName = name;
|
|
26557
|
-
if (
|
|
26718
|
+
if (existsSync11(finalPath)) {
|
|
26558
26719
|
const dotIdx = name.indexOf(".", name.startsWith(".") ? 1 : 0);
|
|
26559
26720
|
const ext = dotIdx > 0 ? name.slice(dotIdx) : "";
|
|
26560
26721
|
const base = dotIdx > 0 ? name.slice(0, dotIdx) : name;
|
|
26561
26722
|
let n = 2;
|
|
26562
|
-
while (n < 1e4 &&
|
|
26723
|
+
while (n < 1e4 && existsSync11(resolve9(targetDir, `${base} (${n})${ext}`))) n++;
|
|
26563
26724
|
if (n >= 1e4) {
|
|
26564
26725
|
skipped.push(name);
|
|
26565
26726
|
continue;
|
|
@@ -26781,7 +26942,7 @@ var init_htmlDocument = __esm({
|
|
|
26781
26942
|
});
|
|
26782
26943
|
|
|
26783
26944
|
// ../core/src/studio-api/helpers/subComposition.ts
|
|
26784
|
-
import { existsSync as
|
|
26945
|
+
import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
|
|
26785
26946
|
import { join as join14 } from "path";
|
|
26786
26947
|
function isFullHtmlDocument(html) {
|
|
26787
26948
|
return /^\s*(?:<!doctype\s|<html[\s>])/i.test(html);
|
|
@@ -26830,8 +26991,8 @@ function extractElementAttrs(el) {
|
|
|
26830
26991
|
}
|
|
26831
26992
|
function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
26832
26993
|
const compFile = join14(projectDir, compPath);
|
|
26833
|
-
if (!
|
|
26834
|
-
const rawComp =
|
|
26994
|
+
if (!existsSync12(compFile)) return null;
|
|
26995
|
+
const rawComp = readFileSync13(compFile, "utf-8");
|
|
26835
26996
|
let compHeadContent = "";
|
|
26836
26997
|
let rewrittenContent;
|
|
26837
26998
|
let htmlAttrs = "";
|
|
@@ -26859,8 +27020,8 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref) {
|
|
|
26859
27020
|
}
|
|
26860
27021
|
const indexPath = join14(projectDir, "index.html");
|
|
26861
27022
|
let headContent = "";
|
|
26862
|
-
if (
|
|
26863
|
-
const indexHtml =
|
|
27023
|
+
if (existsSync12(indexPath)) {
|
|
27024
|
+
const indexHtml = readFileSync13(indexPath, "utf-8");
|
|
26864
27025
|
const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
26865
27026
|
headContent = headMatch?.[1] ?? "";
|
|
26866
27027
|
}
|
|
@@ -26901,7 +27062,7 @@ var init_subComposition = __esm({
|
|
|
26901
27062
|
|
|
26902
27063
|
// ../core/src/studio-api/helpers/projectSignature.ts
|
|
26903
27064
|
import { createHash } from "crypto";
|
|
26904
|
-
import { lstatSync, readFileSync as
|
|
27065
|
+
import { lstatSync, readFileSync as readFileSync14, readdirSync as readdirSync5 } from "fs";
|
|
26905
27066
|
import { extname as extname4, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10 } from "path";
|
|
26906
27067
|
function isPathWithin(parentDir, childPath) {
|
|
26907
27068
|
const childRelativePath = relative2(parentDir, childPath);
|
|
@@ -26993,7 +27154,7 @@ function createProjectSignature(projectDir) {
|
|
|
26993
27154
|
hash2.update("\0");
|
|
26994
27155
|
if (entry.textContentEligible) {
|
|
26995
27156
|
try {
|
|
26996
|
-
hash2.update(
|
|
27157
|
+
hash2.update(readFileSync14(entry.file));
|
|
26997
27158
|
} catch {
|
|
26998
27159
|
hash2.update(String(entry.mtimeMs));
|
|
26999
27160
|
}
|
|
@@ -27238,7 +27399,7 @@ var init_studioMotionRenderScript = __esm({
|
|
|
27238
27399
|
});
|
|
27239
27400
|
|
|
27240
27401
|
// ../core/src/studio-api/routes/preview.ts
|
|
27241
|
-
import { existsSync as
|
|
27402
|
+
import { existsSync as existsSync13, readFileSync as readFileSync15, statSync as statSync2 } from "fs";
|
|
27242
27403
|
import { join as join15, resolve as resolve11 } from "path";
|
|
27243
27404
|
function resolveProjectSignature(adapter2, projectDir) {
|
|
27244
27405
|
return adapter2.getProjectSignature?.(projectDir) ?? createProjectSignature(projectDir);
|
|
@@ -27258,9 +27419,9 @@ ${html}`;
|
|
|
27258
27419
|
}
|
|
27259
27420
|
function readStudioMotionManifestContent(projectDir) {
|
|
27260
27421
|
const manifestPath = join15(projectDir, STUDIO_MOTION_PATH);
|
|
27261
|
-
if (!
|
|
27422
|
+
if (!existsSync13(manifestPath)) return "";
|
|
27262
27423
|
try {
|
|
27263
|
-
return
|
|
27424
|
+
return readFileSync15(manifestPath, "utf-8");
|
|
27264
27425
|
} catch {
|
|
27265
27426
|
return "";
|
|
27266
27427
|
}
|
|
@@ -27341,12 +27502,12 @@ async function transformPreviewHtml(html, adapter2, project, activeCompositionPa
|
|
|
27341
27502
|
}
|
|
27342
27503
|
function resolveProjectMainHtml(projectDir, projectId) {
|
|
27343
27504
|
const indexPath = join15(projectDir, "index.html");
|
|
27344
|
-
if (
|
|
27345
|
-
return { html:
|
|
27505
|
+
if (existsSync13(indexPath)) {
|
|
27506
|
+
return { html: readFileSync15(indexPath, "utf-8"), compositionPath: "index.html" };
|
|
27346
27507
|
}
|
|
27347
27508
|
const blockHtmlPath = join15(projectDir, `${projectId}.html`);
|
|
27348
|
-
if (
|
|
27349
|
-
return { html:
|
|
27509
|
+
if (existsSync13(blockHtmlPath)) {
|
|
27510
|
+
return { html: readFileSync15(blockHtmlPath, "utf-8"), compositionPath: `${projectId}.html` };
|
|
27350
27511
|
}
|
|
27351
27512
|
return null;
|
|
27352
27513
|
}
|
|
@@ -27415,7 +27576,7 @@ ${runtimeTag}`;
|
|
|
27415
27576
|
c3.req.path.replace(`/projects/${project.id}/preview/comp/`, "").split("?")[0] ?? ""
|
|
27416
27577
|
);
|
|
27417
27578
|
const compFile = resolve11(project.dir, compPath);
|
|
27418
|
-
if (!isSafePath(project.dir, compFile) || !
|
|
27579
|
+
if (!isSafePath(project.dir, compFile) || !existsSync13(compFile) || !statSync2(compFile).isFile()) {
|
|
27419
27580
|
return c3.text("not found", 404);
|
|
27420
27581
|
}
|
|
27421
27582
|
const etag = `"comp:${compPath}:${signature}"`;
|
|
@@ -27440,7 +27601,7 @@ ${runtimeTag}`;
|
|
|
27440
27601
|
c3.req.path.replace(`/projects/${project.id}/preview/`, "").split("?")[0] ?? ""
|
|
27441
27602
|
);
|
|
27442
27603
|
const file = resolve11(project.dir, subPath);
|
|
27443
|
-
const stat3 =
|
|
27604
|
+
const stat3 = existsSync13(file) ? statSync2(file) : null;
|
|
27444
27605
|
if (!isSafePath(project.dir, file) || !stat3?.isFile()) {
|
|
27445
27606
|
return c3.text("not found", 404);
|
|
27446
27607
|
}
|
|
@@ -27454,7 +27615,7 @@ ${runtimeTag}`;
|
|
|
27454
27615
|
return new Response(null, { status: 304, headers: cacheHeaders });
|
|
27455
27616
|
}
|
|
27456
27617
|
}
|
|
27457
|
-
const buffer = isText2 ? Buffer.from(
|
|
27618
|
+
const buffer = isText2 ? Buffer.from(readFileSync15(file, "utf-8"), "utf-8") : readFileSync15(file);
|
|
27458
27619
|
const totalSize2 = buffer.length;
|
|
27459
27620
|
const rangeHeader = c3.req.header("Range");
|
|
27460
27621
|
if (rangeHeader) {
|
|
@@ -27524,7 +27685,7 @@ var init_preview = __esm({
|
|
|
27524
27685
|
});
|
|
27525
27686
|
|
|
27526
27687
|
// ../core/src/studio-api/routes/lint.ts
|
|
27527
|
-
import { readFileSync as
|
|
27688
|
+
import { readFileSync as readFileSync16 } from "fs";
|
|
27528
27689
|
import { join as join16 } from "path";
|
|
27529
27690
|
function registerLintRoutes(api, adapter2) {
|
|
27530
27691
|
api.get("/projects/:id/lint", async (c3) => {
|
|
@@ -27534,7 +27695,7 @@ function registerLintRoutes(api, adapter2) {
|
|
|
27534
27695
|
const htmlFiles = walkDir(project.dir).filter((f3) => f3.endsWith(".html"));
|
|
27535
27696
|
const allFindings = [];
|
|
27536
27697
|
for (const file of htmlFiles) {
|
|
27537
|
-
const content =
|
|
27698
|
+
const content = readFileSync16(join16(project.dir, file), "utf-8");
|
|
27538
27699
|
const result = await adapter2.lint(content, { filePath: file });
|
|
27539
27700
|
if (result?.findings) {
|
|
27540
27701
|
for (const f3 of result.findings) {
|
|
@@ -27558,7 +27719,7 @@ var init_lint2 = __esm({
|
|
|
27558
27719
|
|
|
27559
27720
|
// ../core/src/studio-api/routes/render.ts
|
|
27560
27721
|
import { streamSSE } from "hono/streaming";
|
|
27561
|
-
import { existsSync as
|
|
27722
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, mkdirSync as mkdirSync7, unlinkSync as unlinkSync4, readdirSync as readdirSync6, statSync as statSync3 } from "fs";
|
|
27562
27723
|
import { join as join17, resolve as resolve12, sep as sep2 } from "path";
|
|
27563
27724
|
function registerRenderRoutes(api, adapter2) {
|
|
27564
27725
|
const renderJobs = /* @__PURE__ */ new Map();
|
|
@@ -27610,7 +27771,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27610
27771
|
const timePart = now.toTimeString().slice(0, 8).replace(/:/g, "-");
|
|
27611
27772
|
const jobId = `${project.id}_${datePart}_${timePart}`;
|
|
27612
27773
|
const rendersDir = adapter2.rendersDir(project);
|
|
27613
|
-
if (!
|
|
27774
|
+
if (!existsSync14(rendersDir)) mkdirSync7(rendersDir, { recursive: true });
|
|
27614
27775
|
const ext = FORMAT_EXT2[format] ?? ".mp4";
|
|
27615
27776
|
const outputPath = join17(rendersDir, `${jobId}${ext}`);
|
|
27616
27777
|
const jobState = adapter2.startRender({
|
|
@@ -27663,12 +27824,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27663
27824
|
api.get("/render/:jobId/view", (c3) => {
|
|
27664
27825
|
const { jobId } = c3.req.param();
|
|
27665
27826
|
const job = renderJobs.get(jobId);
|
|
27666
|
-
if (!job?.outputPath || !
|
|
27827
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27667
27828
|
return c3.json({ error: "not found" }, 404);
|
|
27668
27829
|
}
|
|
27669
27830
|
const contentType = renderContentType(job.outputPath);
|
|
27670
27831
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27671
|
-
const content =
|
|
27832
|
+
const content = readFileSync17(job.outputPath);
|
|
27672
27833
|
return new Response(content, {
|
|
27673
27834
|
headers: {
|
|
27674
27835
|
"Content-Type": contentType,
|
|
@@ -27681,12 +27842,12 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27681
27842
|
api.get("/render/:jobId/download", (c3) => {
|
|
27682
27843
|
const { jobId } = c3.req.param();
|
|
27683
27844
|
const job = renderJobs.get(jobId);
|
|
27684
|
-
if (!job?.outputPath || !
|
|
27845
|
+
if (!job?.outputPath || !existsSync14(job.outputPath)) {
|
|
27685
27846
|
return c3.json({ error: "not found" }, 404);
|
|
27686
27847
|
}
|
|
27687
27848
|
const contentType = renderContentType(job.outputPath);
|
|
27688
27849
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
27689
|
-
const content =
|
|
27850
|
+
const content = readFileSync17(job.outputPath);
|
|
27690
27851
|
return new Response(content, {
|
|
27691
27852
|
headers: {
|
|
27692
27853
|
"Content-Type": contentType,
|
|
@@ -27701,7 +27862,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27701
27862
|
const dir = state.outputPath.replace(/\/[^/]+$/, "");
|
|
27702
27863
|
for (const ext of [".mp4", ".webm", ".mov", ".meta.json"]) {
|
|
27703
27864
|
const fp = join17(dir, `${jobId}${ext}`);
|
|
27704
|
-
if (
|
|
27865
|
+
if (existsSync14(fp)) unlinkSync4(fp);
|
|
27705
27866
|
}
|
|
27706
27867
|
break;
|
|
27707
27868
|
}
|
|
@@ -27716,9 +27877,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27716
27877
|
if (!filename) return c3.json({ error: "missing filename" }, 400);
|
|
27717
27878
|
const rendersDir = adapter2.rendersDir(project);
|
|
27718
27879
|
const fp = join17(rendersDir, filename);
|
|
27719
|
-
if (!
|
|
27880
|
+
if (!existsSync14(fp)) return c3.json({ error: "not found" }, 404);
|
|
27720
27881
|
const contentType = renderContentType(fp);
|
|
27721
|
-
const content =
|
|
27882
|
+
const content = readFileSync17(fp);
|
|
27722
27883
|
return new Response(content, {
|
|
27723
27884
|
headers: {
|
|
27724
27885
|
"Content-Type": contentType,
|
|
@@ -27732,7 +27893,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27732
27893
|
const project = await adapter2.resolveProject(c3.req.param("id"));
|
|
27733
27894
|
if (!project) return c3.json({ error: "not found" }, 404);
|
|
27734
27895
|
const rendersDir = adapter2.rendersDir(project);
|
|
27735
|
-
if (!
|
|
27896
|
+
if (!existsSync14(rendersDir)) return c3.json({ renders: [] });
|
|
27736
27897
|
const files = readdirSync6(rendersDir).filter((f3) => f3.endsWith(".mp4") || f3.endsWith(".webm") || f3.endsWith(".mov")).map((f3) => {
|
|
27737
27898
|
const fp = join17(rendersDir, f3);
|
|
27738
27899
|
const stat3 = statSync3(fp);
|
|
@@ -27740,9 +27901,9 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
27740
27901
|
const metaPath = join17(rendersDir, `${rid}.meta.json`);
|
|
27741
27902
|
let status = "complete";
|
|
27742
27903
|
let durationMs;
|
|
27743
|
-
if (
|
|
27904
|
+
if (existsSync14(metaPath)) {
|
|
27744
27905
|
try {
|
|
27745
|
-
const meta = JSON.parse(
|
|
27906
|
+
const meta = JSON.parse(readFileSync17(metaPath, "utf-8"));
|
|
27746
27907
|
if (meta.status === "failed") status = "failed";
|
|
27747
27908
|
if (meta.durationMs) durationMs = meta.durationMs;
|
|
27748
27909
|
} catch {
|
|
@@ -28365,7 +28526,7 @@ var init_manualEditsRenderScript = __esm({
|
|
|
28365
28526
|
});
|
|
28366
28527
|
|
|
28367
28528
|
// ../core/src/studio-api/routes/thumbnail.ts
|
|
28368
|
-
import { existsSync as
|
|
28529
|
+
import { existsSync as existsSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync9, mkdirSync as mkdirSync8, statSync as statSync4 } from "fs";
|
|
28369
28530
|
import { join as join18 } from "path";
|
|
28370
28531
|
import { createHash as createHash2 } from "crypto";
|
|
28371
28532
|
function registerThumbnailRoutes(api, adapter2) {
|
|
@@ -28396,9 +28557,9 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28396
28557
|
let sourceMtime = 0;
|
|
28397
28558
|
if (!vpWidth) {
|
|
28398
28559
|
const htmlFile = join18(project.dir, compPath);
|
|
28399
|
-
if (
|
|
28560
|
+
if (existsSync15(htmlFile)) {
|
|
28400
28561
|
sourceMtime = Math.round(statSync4(htmlFile).mtimeMs);
|
|
28401
|
-
const html =
|
|
28562
|
+
const html = readFileSync18(htmlFile, "utf-8");
|
|
28402
28563
|
const wMatch = html.match(/data-width=["'](\d+)["']/);
|
|
28403
28564
|
const hMatch = html.match(/data-height=["'](\d+)["']/);
|
|
28404
28565
|
if (wMatch?.[1]) compW = parseInt(wMatch[1]);
|
|
@@ -28407,15 +28568,15 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28407
28568
|
}
|
|
28408
28569
|
const manualEditsFile = join18(project.dir, STUDIO_MANUAL_EDITS_PATH);
|
|
28409
28570
|
let manualEditsKey = "";
|
|
28410
|
-
if (
|
|
28411
|
-
const manualEditsContent =
|
|
28571
|
+
if (existsSync15(manualEditsFile)) {
|
|
28572
|
+
const manualEditsContent = readFileSync18(manualEditsFile, "utf-8");
|
|
28412
28573
|
manualEditsKey = `_${createHash2("sha1").update(manualEditsContent).digest("hex").slice(0, 16)}`;
|
|
28413
28574
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(manualEditsFile).mtimeMs));
|
|
28414
28575
|
}
|
|
28415
28576
|
const motionFile = join18(project.dir, STUDIO_MOTION_PATH);
|
|
28416
28577
|
let motionKey = "";
|
|
28417
|
-
if (
|
|
28418
|
-
const motionContent =
|
|
28578
|
+
if (existsSync15(motionFile)) {
|
|
28579
|
+
const motionContent = readFileSync18(motionFile, "utf-8");
|
|
28419
28580
|
motionKey = `_${createHash2("sha1").update(motionContent).digest("hex").slice(0, 16)}`;
|
|
28420
28581
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync4(motionFile).mtimeMs));
|
|
28421
28582
|
}
|
|
@@ -28425,8 +28586,8 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28425
28586
|
const urlVersionKey = urlVersion ? `_${urlVersion.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 32)}` : "";
|
|
28426
28587
|
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
28588
|
const cachePath2 = join18(cacheDir, cacheKey);
|
|
28428
|
-
if (
|
|
28429
|
-
return new Response(new Uint8Array(
|
|
28589
|
+
if (existsSync15(cachePath2)) {
|
|
28590
|
+
return new Response(new Uint8Array(readFileSync18(cachePath2)), {
|
|
28430
28591
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
28431
28592
|
});
|
|
28432
28593
|
}
|
|
@@ -28448,7 +28609,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
28448
28609
|
500
|
|
28449
28610
|
);
|
|
28450
28611
|
}
|
|
28451
|
-
if (!
|
|
28612
|
+
if (!existsSync15(cacheDir)) mkdirSync8(cacheDir, { recursive: true });
|
|
28452
28613
|
writeFileSync9(cachePath2, buffer);
|
|
28453
28614
|
return new Response(new Uint8Array(buffer), {
|
|
28454
28615
|
headers: { "Content-Type": contentType, "Cache-Control": "public, max-age=60" }
|
|
@@ -28470,7 +28631,7 @@ var init_thumbnail = __esm({
|
|
|
28470
28631
|
});
|
|
28471
28632
|
|
|
28472
28633
|
// ../core/src/studio-api/routes/waveform.ts
|
|
28473
|
-
import { existsSync as
|
|
28634
|
+
import { existsSync as existsSync16, readFileSync as readFileSync19, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9 } from "fs";
|
|
28474
28635
|
import { join as join19 } from "path";
|
|
28475
28636
|
function registerWaveformRoutes(api, adapter2) {
|
|
28476
28637
|
api.get("/projects/:id/waveform/*", async (c3) => {
|
|
@@ -28480,12 +28641,12 @@ function registerWaveformRoutes(api, adapter2) {
|
|
|
28480
28641
|
c3.req.path.replace(`/projects/${project.id}/waveform/`, "").split("?")[0] ?? ""
|
|
28481
28642
|
);
|
|
28482
28643
|
const audioPath = join19(project.dir, assetPath);
|
|
28483
|
-
if (!
|
|
28644
|
+
if (!existsSync16(audioPath)) return c3.json({ error: "file not found" }, 404);
|
|
28484
28645
|
const cacheDir = join19(project.dir, ".waveform-cache");
|
|
28485
28646
|
const cachePath2 = join19(cacheDir, buildWaveformCacheKey(assetPath));
|
|
28486
|
-
if (
|
|
28647
|
+
if (existsSync16(cachePath2)) {
|
|
28487
28648
|
try {
|
|
28488
|
-
const peaks2 = JSON.parse(
|
|
28649
|
+
const peaks2 = JSON.parse(readFileSync19(cachePath2, "utf-8"));
|
|
28489
28650
|
return c3.json({ peaks: peaks2 });
|
|
28490
28651
|
} catch {
|
|
28491
28652
|
}
|
|
@@ -28513,15 +28674,15 @@ var init_waveform2 = __esm({
|
|
|
28513
28674
|
|
|
28514
28675
|
// ../core/src/studio-api/routes/fonts.ts
|
|
28515
28676
|
import { execFileSync as execFileSync4 } from "child_process";
|
|
28516
|
-
import { existsSync as
|
|
28517
|
-
import { homedir as homedir4, platform as
|
|
28677
|
+
import { existsSync as existsSync17, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
|
|
28678
|
+
import { homedir as homedir4, platform as platform5 } from "os";
|
|
28518
28679
|
import { join as join20 } from "path";
|
|
28519
28680
|
function isRecord(value) {
|
|
28520
28681
|
return typeof value === "object" && value !== null;
|
|
28521
28682
|
}
|
|
28522
28683
|
function fontDirectories() {
|
|
28523
28684
|
const home = homedir4();
|
|
28524
|
-
if (
|
|
28685
|
+
if (platform5() === "darwin") {
|
|
28525
28686
|
return [
|
|
28526
28687
|
join20(home, "Library", "Fonts"),
|
|
28527
28688
|
"/Library/Fonts",
|
|
@@ -28529,7 +28690,7 @@ function fontDirectories() {
|
|
|
28529
28690
|
"/System/Library/Fonts/Supplemental"
|
|
28530
28691
|
];
|
|
28531
28692
|
}
|
|
28532
|
-
if (
|
|
28693
|
+
if (platform5() === "win32") {
|
|
28533
28694
|
return [join20(process.env.WINDIR || "C:\\Windows", "Fonts")];
|
|
28534
28695
|
}
|
|
28535
28696
|
return [
|
|
@@ -28551,7 +28712,7 @@ function toFamilyName(fileName) {
|
|
|
28551
28712
|
return family.length >= 2 ? family : null;
|
|
28552
28713
|
}
|
|
28553
28714
|
function collectMacSystemProfilerFonts() {
|
|
28554
|
-
if (
|
|
28715
|
+
if (platform5() !== "darwin") return [];
|
|
28555
28716
|
let parsed;
|
|
28556
28717
|
try {
|
|
28557
28718
|
const raw = execFileSync4("system_profiler", ["SPFontsDataType", "-json"], {
|
|
@@ -28586,7 +28747,7 @@ function collectMacSystemProfilerFonts() {
|
|
|
28586
28747
|
return fonts;
|
|
28587
28748
|
}
|
|
28588
28749
|
function collectFontsFromDir(dir, depth = 0) {
|
|
28589
|
-
if (!
|
|
28750
|
+
if (!existsSync17(dir) || depth > 2) return [];
|
|
28590
28751
|
const fonts = [];
|
|
28591
28752
|
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
28592
28753
|
const fullPath = join20(dir, entry.name);
|
|
@@ -28858,7 +29019,7 @@ __export(manager_exports2, {
|
|
|
28858
29019
|
isLinuxArm: () => isLinuxArm
|
|
28859
29020
|
});
|
|
28860
29021
|
import { execSync, spawnSync as spawnSync2 } from "child_process";
|
|
28861
|
-
import { existsSync as
|
|
29022
|
+
import { existsSync as existsSync18, readdirSync as readdirSync8, rmSync as rmSync4 } from "fs";
|
|
28862
29023
|
import { basename as basename2 } from "path";
|
|
28863
29024
|
import { homedir as homedir5 } from "os";
|
|
28864
29025
|
import { join as join21 } from "path";
|
|
@@ -28879,7 +29040,7 @@ function whichBinary2(name) {
|
|
|
28879
29040
|
}
|
|
28880
29041
|
function findFromEnv2() {
|
|
28881
29042
|
const envPath = process.env["HYPERFRAMES_BROWSER_PATH"];
|
|
28882
|
-
if (envPath &&
|
|
29043
|
+
if (envPath && existsSync18(envPath)) {
|
|
28883
29044
|
return { executablePath: envPath, source: "env" };
|
|
28884
29045
|
}
|
|
28885
29046
|
return void 0;
|
|
@@ -28889,7 +29050,7 @@ async function findFromCache() {
|
|
|
28889
29050
|
if (fromPuppeteer) {
|
|
28890
29051
|
return fromPuppeteer;
|
|
28891
29052
|
}
|
|
28892
|
-
if (
|
|
29053
|
+
if (existsSync18(CACHE_DIR2)) {
|
|
28893
29054
|
const installed = await getInstalledBrowsers({ cacheDir: CACHE_DIR2 });
|
|
28894
29055
|
const match = installed.find((b2) => b2.browser === Browser.CHROMEHEADLESSSHELL);
|
|
28895
29056
|
if (match) {
|
|
@@ -28927,7 +29088,7 @@ function compareVersionDirsDescending(a, b2) {
|
|
|
28927
29088
|
return 0;
|
|
28928
29089
|
}
|
|
28929
29090
|
function findFromPuppeteerCache() {
|
|
28930
|
-
if (!
|
|
29091
|
+
if (!existsSync18(PUPPETEER_CACHE_DIR)) return void 0;
|
|
28931
29092
|
let versions;
|
|
28932
29093
|
try {
|
|
28933
29094
|
versions = [...readdirSync8(PUPPETEER_CACHE_DIR)].sort(compareVersionDirsDescending);
|
|
@@ -28952,7 +29113,7 @@ function findFromPuppeteerCache() {
|
|
|
28952
29113
|
)
|
|
28953
29114
|
];
|
|
28954
29115
|
for (const binary of candidates) {
|
|
28955
|
-
if (
|
|
29116
|
+
if (existsSync18(binary)) {
|
|
28956
29117
|
return { executablePath: binary, source: "cache" };
|
|
28957
29118
|
}
|
|
28958
29119
|
}
|
|
@@ -28979,7 +29140,7 @@ function _resetSystemFallbackWarnForTests() {
|
|
|
28979
29140
|
}
|
|
28980
29141
|
function findFromSystem2() {
|
|
28981
29142
|
for (const p2 of SYSTEM_CHROME_PATHS) {
|
|
28982
|
-
if (
|
|
29143
|
+
if (existsSync18(p2)) {
|
|
28983
29144
|
return { executablePath: p2, source: "system" };
|
|
28984
29145
|
}
|
|
28985
29146
|
}
|
|
@@ -29004,7 +29165,7 @@ async function ensureLinuxArmBrowser(options) {
|
|
|
29004
29165
|
void options;
|
|
29005
29166
|
const existing = await findBrowser();
|
|
29006
29167
|
if (existing) return existing;
|
|
29007
|
-
const hasApt =
|
|
29168
|
+
const hasApt = existsSync18("/usr/bin/apt-get");
|
|
29008
29169
|
if (hasApt) {
|
|
29009
29170
|
console.error(
|
|
29010
29171
|
"\n\u{1F50D} Linux ARM64 detected \u2014 Chrome Headless Shell is not available for this platform."
|
|
@@ -29042,8 +29203,8 @@ Then re-run your command. The HYPERFRAMES_BROWSER_PATH env var persists for the
|
|
|
29042
29203
|
async function ensureBrowser(options) {
|
|
29043
29204
|
const existing = await findBrowser();
|
|
29044
29205
|
if (existing) return existing;
|
|
29045
|
-
const
|
|
29046
|
-
if (!
|
|
29206
|
+
const platform9 = detectBrowserPlatform();
|
|
29207
|
+
if (!platform9) {
|
|
29047
29208
|
throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
|
|
29048
29209
|
}
|
|
29049
29210
|
if (isLinuxArm()) {
|
|
@@ -29053,13 +29214,13 @@ async function ensureBrowser(options) {
|
|
|
29053
29214
|
cacheDir: CACHE_DIR2,
|
|
29054
29215
|
browser: Browser.CHROMEHEADLESSSHELL,
|
|
29055
29216
|
buildId: CHROME_VERSION,
|
|
29056
|
-
platform:
|
|
29217
|
+
platform: platform9,
|
|
29057
29218
|
downloadProgressCallback: options?.onProgress
|
|
29058
29219
|
});
|
|
29059
29220
|
return { executablePath: installed.executablePath, source: "download" };
|
|
29060
29221
|
}
|
|
29061
29222
|
function clearBrowser() {
|
|
29062
|
-
if (!
|
|
29223
|
+
if (!existsSync18(CACHE_DIR2)) {
|
|
29063
29224
|
return false;
|
|
29064
29225
|
}
|
|
29065
29226
|
rmSync4(CACHE_DIR2, { recursive: true, force: true });
|
|
@@ -29230,7 +29391,7 @@ var init_config2 = __esm({
|
|
|
29230
29391
|
});
|
|
29231
29392
|
|
|
29232
29393
|
// ../engine/src/services/browserManager.ts
|
|
29233
|
-
import { existsSync as
|
|
29394
|
+
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
29234
29395
|
import { join as join22 } from "path";
|
|
29235
29396
|
import { homedir as homedir6 } from "os";
|
|
29236
29397
|
async function getPuppeteer() {
|
|
@@ -29253,7 +29414,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29253
29414
|
return process.env.PRODUCER_HEADLESS_SHELL_PATH;
|
|
29254
29415
|
}
|
|
29255
29416
|
const baseDir = join22(homedir6(), ".cache", "puppeteer", "chrome-headless-shell");
|
|
29256
|
-
if (!
|
|
29417
|
+
if (!existsSync19(baseDir)) return void 0;
|
|
29257
29418
|
try {
|
|
29258
29419
|
const versions = readdirSync9(baseDir).sort().reverse();
|
|
29259
29420
|
for (const version of versions) {
|
|
@@ -29264,7 +29425,7 @@ function resolveHeadlessShellPath(config) {
|
|
|
29264
29425
|
join22(baseDir, version, "chrome-headless-shell-win64", "chrome-headless-shell.exe")
|
|
29265
29426
|
];
|
|
29266
29427
|
for (const binary of candidates) {
|
|
29267
|
-
if (
|
|
29428
|
+
if (existsSync19(binary)) return binary;
|
|
29268
29429
|
}
|
|
29269
29430
|
}
|
|
29270
29431
|
} catch {
|
|
@@ -29303,7 +29464,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29303
29464
|
if (mode !== "auto") return Promise.resolve(mode);
|
|
29304
29465
|
if (_autoBrowserGpuModeCache) return _autoBrowserGpuModeCache;
|
|
29305
29466
|
_autoBrowserGpuModeCache = (async () => {
|
|
29306
|
-
const
|
|
29467
|
+
const platform9 = options.platform ?? process.platform;
|
|
29307
29468
|
const browserTimeout = options.browserTimeout ?? DEFAULT_CONFIG2.browserTimeout;
|
|
29308
29469
|
const executablePath = options.chromePath ?? resolveHeadlessShellPath({});
|
|
29309
29470
|
const probeArgs = [
|
|
@@ -29312,7 +29473,7 @@ function resolveBrowserGpuMode(mode, options = {}) {
|
|
|
29312
29473
|
"--disable-dev-shm-usage",
|
|
29313
29474
|
"--enable-webgl",
|
|
29314
29475
|
"--ignore-gpu-blocklist",
|
|
29315
|
-
...getBrowserGpuArgs("hardware",
|
|
29476
|
+
...getBrowserGpuArgs("hardware", platform9)
|
|
29316
29477
|
];
|
|
29317
29478
|
const ppt = await getPuppeteer().catch(() => null);
|
|
29318
29479
|
if (!ppt) {
|
|
@@ -29505,7 +29666,7 @@ async function drainBrowserPool() {
|
|
|
29505
29666
|
}
|
|
29506
29667
|
}
|
|
29507
29668
|
function buildChromeArgs(options, config) {
|
|
29508
|
-
const
|
|
29669
|
+
const platform9 = options.platform ?? process.platform;
|
|
29509
29670
|
const gpuDisabled = config?.disableGpu ?? DEFAULT_CONFIG2.disableGpu;
|
|
29510
29671
|
const browserGpuMode = gpuDisabled ? "software" : config?.browserGpuMode ?? DEFAULT_CONFIG2.browserGpuMode;
|
|
29511
29672
|
const chromeArgs = [
|
|
@@ -29515,7 +29676,7 @@ function buildChromeArgs(options, config) {
|
|
|
29515
29676
|
CANVAS_DRAW_ELEMENT_FEATURE_FLAG,
|
|
29516
29677
|
"--enable-webgl",
|
|
29517
29678
|
"--ignore-gpu-blocklist",
|
|
29518
|
-
...getBrowserGpuArgs(browserGpuMode,
|
|
29679
|
+
...getBrowserGpuArgs(browserGpuMode, platform9),
|
|
29519
29680
|
"--font-render-hinting=none",
|
|
29520
29681
|
"--force-color-profile=srgb",
|
|
29521
29682
|
`--window-size=${options.width},${options.height}`,
|
|
@@ -29563,14 +29724,14 @@ function buildChromeArgs(options, config) {
|
|
|
29563
29724
|
}
|
|
29564
29725
|
return chromeArgs;
|
|
29565
29726
|
}
|
|
29566
|
-
function getBrowserGpuArgs(mode,
|
|
29727
|
+
function getBrowserGpuArgs(mode, platform9) {
|
|
29567
29728
|
if (mode === "software") {
|
|
29568
29729
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29569
29730
|
}
|
|
29570
29731
|
if (mode === "auto") {
|
|
29571
29732
|
return ["--use-gl=angle", "--use-angle=swiftshader", "--enable-unsafe-swiftshader"];
|
|
29572
29733
|
}
|
|
29573
|
-
switch (
|
|
29734
|
+
switch (platform9) {
|
|
29574
29735
|
case "darwin":
|
|
29575
29736
|
return ["--use-gl=angle", "--use-angle=metal", "--enable-gpu-rasterization"];
|
|
29576
29737
|
case "win32":
|
|
@@ -29893,7 +30054,7 @@ var init_screenshotService = __esm({
|
|
|
29893
30054
|
});
|
|
29894
30055
|
|
|
29895
30056
|
// ../engine/src/services/frameCapture.ts
|
|
29896
|
-
import { existsSync as
|
|
30057
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
|
|
29897
30058
|
import { join as join23 } from "path";
|
|
29898
30059
|
async function driveWarmupTicks(options, state) {
|
|
29899
30060
|
const sleep3 = options.sleep ?? realSleep;
|
|
@@ -29930,7 +30091,7 @@ async function waitForCloseWithTimeout(promise) {
|
|
|
29930
30091
|
return !timedOut;
|
|
29931
30092
|
}
|
|
29932
30093
|
async function createCaptureSession(serverUrl, outputDir, options, onBeforeCapture = null, config) {
|
|
29933
|
-
if (!
|
|
30094
|
+
if (!existsSync20(outputDir)) mkdirSync10(outputDir, { recursive: true });
|
|
29934
30095
|
const headlessShell = resolveHeadlessShellPath(config);
|
|
29935
30096
|
const isLinux = process.platform === "linux";
|
|
29936
30097
|
const forceScreenshot = config?.forceScreenshot ?? DEFAULT_CONFIG2.forceScreenshot;
|
|
@@ -30276,7 +30437,7 @@ async function initializeSession(session) {
|
|
|
30276
30437
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
30277
30438
|
try {
|
|
30278
30439
|
const diagnosticsDir = join23(session.outputDir, "diagnostics");
|
|
30279
|
-
if (!
|
|
30440
|
+
if (!existsSync20(diagnosticsDir)) mkdirSync10(diagnosticsDir, { recursive: true });
|
|
30280
30441
|
const base = join23(diagnosticsDir, `frame-error-${frameIndex}`);
|
|
30281
30442
|
await session.page.screenshot({ path: `${base}.png`, type: "png", fullPage: true });
|
|
30282
30443
|
const html = await session.page.content();
|
|
@@ -30439,7 +30600,7 @@ async function closeCaptureSession(session) {
|
|
|
30439
30600
|
session.isInitialized = false;
|
|
30440
30601
|
}
|
|
30441
30602
|
function prepareCaptureSessionForReuse(session, outputDir, onBeforeCapture) {
|
|
30442
|
-
if (!
|
|
30603
|
+
if (!existsSync20(outputDir)) {
|
|
30443
30604
|
mkdirSync10(outputDir, { recursive: true });
|
|
30444
30605
|
}
|
|
30445
30606
|
session.outputDir = outputDir;
|
|
@@ -30680,7 +30841,7 @@ var init_runFfmpeg = __esm({
|
|
|
30680
30841
|
|
|
30681
30842
|
// ../engine/src/services/chunkEncoder.ts
|
|
30682
30843
|
import { spawn as spawn6 } from "child_process";
|
|
30683
|
-
import { copyFileSync, existsSync as
|
|
30844
|
+
import { copyFileSync, existsSync as existsSync21, mkdirSync as mkdirSync11, readdirSync as readdirSync10, statSync as statSync6, writeFileSync as writeFileSync12 } from "fs";
|
|
30684
30845
|
import { join as join24, dirname as dirname7 } from "path";
|
|
30685
30846
|
function getEncoderPreset(quality, format = "mp4", hdr) {
|
|
30686
30847
|
const base = ENCODER_PRESETS[quality];
|
|
@@ -30892,7 +31053,7 @@ function buildEncoderArgs(options, inputArgs, outputPath, gpuEncoder = null) {
|
|
|
30892
31053
|
async function encodeFramesFromDir(framesDir, framePattern, outputPath, options, signal, config) {
|
|
30893
31054
|
const startTime = Date.now();
|
|
30894
31055
|
const outputDir = dirname7(outputPath);
|
|
30895
|
-
if (!
|
|
31056
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
30896
31057
|
const files = readdirSync10(framesDir).filter((f3) => f3.match(/\.(jpg|jpeg|png)$/i));
|
|
30897
31058
|
const frameCount = files.length;
|
|
30898
31059
|
if (frameCount === 0) {
|
|
@@ -30958,7 +31119,7 @@ async function encodeFramesFromDir(framesDir, framePattern, outputPath, options,
|
|
|
30958
31119
|
});
|
|
30959
31120
|
return;
|
|
30960
31121
|
}
|
|
30961
|
-
const fileSize =
|
|
31122
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
30962
31123
|
resolve46({ success: true, outputPath, durationMs, framesEncoded: frameCount, fileSize });
|
|
30963
31124
|
});
|
|
30964
31125
|
ffmpeg.on("error", (err) => {
|
|
@@ -30991,7 +31152,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
30991
31152
|
const chunkSize = Math.max(30, Math.floor(chunkSizeFrames));
|
|
30992
31153
|
const chunkCount = Math.ceil(files.length / chunkSize);
|
|
30993
31154
|
const chunkDir = join24(dirname7(outputPath), "chunk-encode");
|
|
30994
|
-
if (!
|
|
31155
|
+
if (!existsSync21(chunkDir)) mkdirSync11(chunkDir, { recursive: true });
|
|
30995
31156
|
const chunkPaths = [];
|
|
30996
31157
|
for (let i2 = 0; i2 < chunkCount; i2++) {
|
|
30997
31158
|
if (signal?.aborted) {
|
|
@@ -31087,7 +31248,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31087
31248
|
error: concatResult.error
|
|
31088
31249
|
};
|
|
31089
31250
|
}
|
|
31090
|
-
const fileSize =
|
|
31251
|
+
const fileSize = existsSync21(outputPath) ? statSync6(outputPath).size : 0;
|
|
31091
31252
|
return {
|
|
31092
31253
|
success: true,
|
|
31093
31254
|
outputPath,
|
|
@@ -31098,7 +31259,7 @@ async function encodeFramesChunkedConcat(framesDir, framePattern, outputPath, op
|
|
|
31098
31259
|
}
|
|
31099
31260
|
async function muxVideoWithAudio(videoPath, audioPath, outputPath, signal, config) {
|
|
31100
31261
|
const outputDir = dirname7(outputPath);
|
|
31101
|
-
if (!
|
|
31262
|
+
if (!existsSync21(outputDir)) mkdirSync11(outputDir, { recursive: true });
|
|
31102
31263
|
const isWebm = outputPath.endsWith(".webm");
|
|
31103
31264
|
const isMov = outputPath.endsWith(".mov");
|
|
31104
31265
|
const args = ["-i", videoPath, "-i", audioPath, "-c:v", "copy"];
|
|
@@ -31171,7 +31332,7 @@ var init_chunkEncoder = __esm({
|
|
|
31171
31332
|
|
|
31172
31333
|
// ../engine/src/services/streamingEncoder.ts
|
|
31173
31334
|
import { spawn as spawn7 } from "child_process";
|
|
31174
|
-
import { existsSync as
|
|
31335
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync12, statSync as statSync7 } from "fs";
|
|
31175
31336
|
import { dirname as dirname8 } from "path";
|
|
31176
31337
|
function createFrameReorderBuffer(startFrame, endFrame) {
|
|
31177
31338
|
let cursor = startFrame;
|
|
@@ -31373,7 +31534,7 @@ function buildStreamingArgs(options, outputPath, gpuEncoder = null) {
|
|
|
31373
31534
|
}
|
|
31374
31535
|
async function spawnStreamingEncoder(outputPath, options, signal, config) {
|
|
31375
31536
|
const outputDir = dirname8(outputPath);
|
|
31376
|
-
if (!
|
|
31537
|
+
if (!existsSync22(outputDir)) mkdirSync12(outputDir, { recursive: true });
|
|
31377
31538
|
let gpuEncoder = null;
|
|
31378
31539
|
if (options.useGpu) {
|
|
31379
31540
|
gpuEncoder = await getCachedGpuEncoder();
|
|
@@ -31469,7 +31630,7 @@ Process error: ${err.message}`;
|
|
|
31469
31630
|
error: formatFfmpegError(exitCode, stderr)
|
|
31470
31631
|
};
|
|
31471
31632
|
}
|
|
31472
|
-
const fileSize =
|
|
31633
|
+
const fileSize = existsSync22(outputPath) ? statSync7(outputPath).size : 0;
|
|
31473
31634
|
return { success: true, durationMs, fileSize };
|
|
31474
31635
|
},
|
|
31475
31636
|
getExitStatus: () => exitStatus
|
|
@@ -31489,7 +31650,7 @@ var init_streamingEncoder = __esm({
|
|
|
31489
31650
|
|
|
31490
31651
|
// ../engine/src/utils/ffprobe.ts
|
|
31491
31652
|
import { spawn as spawn8 } from "child_process";
|
|
31492
|
-
import { readFileSync as
|
|
31653
|
+
import { readFileSync as readFileSync20 } from "fs";
|
|
31493
31654
|
import { extname as extname5 } from "path";
|
|
31494
31655
|
function runFfprobe(args) {
|
|
31495
31656
|
return new Promise((resolve46, reject) => {
|
|
@@ -31583,7 +31744,7 @@ function extractPngMetadataFromBuffer(buf) {
|
|
|
31583
31744
|
function extractStillImageMetadata(filePath) {
|
|
31584
31745
|
if (extname5(filePath).toLowerCase() !== ".png") return null;
|
|
31585
31746
|
try {
|
|
31586
|
-
return extractPngMetadataFromBuffer(
|
|
31747
|
+
return extractPngMetadataFromBuffer(readFileSync20(filePath));
|
|
31587
31748
|
} catch {
|
|
31588
31749
|
return null;
|
|
31589
31750
|
}
|
|
@@ -31770,7 +31931,7 @@ var init_ffprobe = __esm({
|
|
|
31770
31931
|
});
|
|
31771
31932
|
|
|
31772
31933
|
// ../engine/src/utils/urlDownloader.ts
|
|
31773
|
-
import { createWriteStream as createWriteStream2, existsSync as
|
|
31934
|
+
import { createWriteStream as createWriteStream2, existsSync as existsSync23, mkdirSync as mkdirSync13 } from "fs";
|
|
31774
31935
|
import { createHash as createHash3 } from "crypto";
|
|
31775
31936
|
import { join as join25, extname as extname6 } from "path";
|
|
31776
31937
|
import { Readable } from "stream";
|
|
@@ -31783,19 +31944,19 @@ function getFilenameFromUrl(url) {
|
|
|
31783
31944
|
}
|
|
31784
31945
|
async function downloadToTemp(url, destDir, timeoutMs = 3e5) {
|
|
31785
31946
|
const cachedPath = downloadPathCache.get(url);
|
|
31786
|
-
if (cachedPath &&
|
|
31947
|
+
if (cachedPath && existsSync23(cachedPath)) {
|
|
31787
31948
|
return cachedPath;
|
|
31788
31949
|
}
|
|
31789
31950
|
const inFlight = inFlightDownloads.get(url);
|
|
31790
31951
|
if (inFlight) {
|
|
31791
31952
|
return inFlight;
|
|
31792
31953
|
}
|
|
31793
|
-
if (!
|
|
31954
|
+
if (!existsSync23(destDir)) {
|
|
31794
31955
|
mkdirSync13(destDir, { recursive: true });
|
|
31795
31956
|
}
|
|
31796
31957
|
const filename = getFilenameFromUrl(url);
|
|
31797
31958
|
const localPath = join25(destDir, filename);
|
|
31798
|
-
if (
|
|
31959
|
+
if (existsSync23(localPath)) {
|
|
31799
31960
|
downloadPathCache.set(url, localPath);
|
|
31800
31961
|
return localPath;
|
|
31801
31962
|
}
|
|
@@ -32551,7 +32712,7 @@ var init_inlineSubCompositions = __esm({
|
|
|
32551
32712
|
});
|
|
32552
32713
|
|
|
32553
32714
|
// ../core/src/compiler/htmlBundler.ts
|
|
32554
|
-
import { readFileSync as
|
|
32715
|
+
import { readFileSync as readFileSync21, existsSync as existsSync24 } from "fs";
|
|
32555
32716
|
import { join as join26, resolve as resolve14, relative as relative3, dirname as dirname9, isAbsolute as isAbsolute3, sep as sep3 } from "path";
|
|
32556
32717
|
import { transformSync } from "esbuild";
|
|
32557
32718
|
function safePath(projectDir, relativePath) {
|
|
@@ -32599,9 +32760,9 @@ function isRelativeUrl(url) {
|
|
|
32599
32760
|
return !url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("//") && !url.startsWith("data:") && !isAbsolute3(url);
|
|
32600
32761
|
}
|
|
32601
32762
|
function safeReadFile(filePath) {
|
|
32602
|
-
if (!
|
|
32763
|
+
if (!existsSync24(filePath)) return null;
|
|
32603
32764
|
try {
|
|
32604
|
-
return
|
|
32765
|
+
return readFileSync21(filePath, "utf-8");
|
|
32605
32766
|
} catch {
|
|
32606
32767
|
return null;
|
|
32607
32768
|
}
|
|
@@ -32671,9 +32832,9 @@ ${inlined}
|
|
|
32671
32832
|
return rebased;
|
|
32672
32833
|
}
|
|
32673
32834
|
function safeReadFileBuffer(filePath) {
|
|
32674
|
-
if (!
|
|
32835
|
+
if (!existsSync24(filePath)) return null;
|
|
32675
32836
|
try {
|
|
32676
|
-
return
|
|
32837
|
+
return readFileSync21(filePath);
|
|
32677
32838
|
} catch {
|
|
32678
32839
|
return null;
|
|
32679
32840
|
}
|
|
@@ -32975,8 +33136,8 @@ function stripJsCommentsParserSafe(source) {
|
|
|
32975
33136
|
}
|
|
32976
33137
|
async function bundleToSingleHtml(projectDir, options) {
|
|
32977
33138
|
const indexPath = join26(projectDir, "index.html");
|
|
32978
|
-
if (!
|
|
32979
|
-
const rawHtml =
|
|
33139
|
+
if (!existsSync24(indexPath)) throw new Error("index.html not found in project directory");
|
|
33140
|
+
const rawHtml = readFileSync21(indexPath, "utf-8");
|
|
32980
33141
|
const compiled = await compileHtml(rawHtml, projectDir, options?.probeMediaDuration);
|
|
32981
33142
|
const staticGuard = validateHyperframeHtmlContract(compiled);
|
|
32982
33143
|
if (!staticGuard.isValid) {
|
|
@@ -33329,7 +33490,7 @@ var init_htmlTemplate = __esm({
|
|
|
33329
33490
|
// ../engine/src/services/extractionCache.ts
|
|
33330
33491
|
import { createHash as createHash4 } from "crypto";
|
|
33331
33492
|
import { mkdirSync as mkdirSync14, readdirSync as readdirSync11, statSync as statSync8, writeFileSync as writeFileSync13 } from "fs";
|
|
33332
|
-
import { existsSync as
|
|
33493
|
+
import { existsSync as existsSync25 } from "fs";
|
|
33333
33494
|
import { join as join27 } from "path";
|
|
33334
33495
|
function readKeyStat(videoPath) {
|
|
33335
33496
|
try {
|
|
@@ -33360,7 +33521,7 @@ function cacheEntryDirName(keyHash) {
|
|
|
33360
33521
|
function lookupCacheEntry(rootDir, input) {
|
|
33361
33522
|
const keyHash = computeCacheKey(input);
|
|
33362
33523
|
const dir = join27(rootDir, cacheEntryDirName(keyHash));
|
|
33363
|
-
const complete =
|
|
33524
|
+
const complete = existsSync25(join27(dir, COMPLETE_SENTINEL));
|
|
33364
33525
|
return { entry: { dir, keyHash }, hit: complete };
|
|
33365
33526
|
}
|
|
33366
33527
|
function ensureCacheEntryDir(entry) {
|
|
@@ -33401,7 +33562,7 @@ var init_extractionCache = __esm({
|
|
|
33401
33562
|
|
|
33402
33563
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
33403
33564
|
import { spawn as spawn9 } from "child_process";
|
|
33404
|
-
import { existsSync as
|
|
33565
|
+
import { existsSync as existsSync26, mkdirSync as mkdirSync15, readdirSync as readdirSync12, rmSync as rmSync5 } from "fs";
|
|
33405
33566
|
import { isAbsolute as isAbsolute4, join as join28, posix as posix2, resolve as resolve15, sep as sep4 } from "path";
|
|
33406
33567
|
function parseVideoElements(html) {
|
|
33407
33568
|
const videos = [];
|
|
@@ -33473,7 +33634,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
33473
33634
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
33474
33635
|
const { fps, outputDir, quality = 95 } = options;
|
|
33475
33636
|
const videoOutputDir = outputDirOverride ?? join28(outputDir, videoId);
|
|
33476
|
-
if (!
|
|
33637
|
+
if (!existsSync26(videoOutputDir)) mkdirSync15(videoOutputDir, { recursive: true });
|
|
33477
33638
|
const metadata = await extractMediaMetadata(videoPath);
|
|
33478
33639
|
const format = resolveFrameFormat(metadata, options.format);
|
|
33479
33640
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${format}`;
|
|
@@ -33661,7 +33822,7 @@ function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
|
|
|
33661
33822
|
candidates.push(join28(baseDir, stripped));
|
|
33662
33823
|
}
|
|
33663
33824
|
}
|
|
33664
|
-
return candidates.find(
|
|
33825
|
+
return candidates.find(existsSync26) ?? fromBase;
|
|
33665
33826
|
}
|
|
33666
33827
|
async function extractAllVideoFrames(videos, baseDir, options, signal, config, compiledDir) {
|
|
33667
33828
|
const startTime = Date.now();
|
|
@@ -33695,7 +33856,7 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
33695
33856
|
mkdirSync15(downloadDir, { recursive: true });
|
|
33696
33857
|
videoPath = await downloadToTemp(videoPath, downloadDir);
|
|
33697
33858
|
}
|
|
33698
|
-
if (!
|
|
33859
|
+
if (!existsSync26(videoPath)) {
|
|
33699
33860
|
if (!warnedSrcs.has(video.src)) {
|
|
33700
33861
|
warnedSrcs.add(video.src);
|
|
33701
33862
|
process.stderr.write(
|
|
@@ -34064,7 +34225,7 @@ var init_videoFrameExtractor = __esm({
|
|
|
34064
34225
|
cleanup() {
|
|
34065
34226
|
for (const video of this.videos.values()) {
|
|
34066
34227
|
if (video.extracted.ownedByLookup) continue;
|
|
34067
|
-
if (
|
|
34228
|
+
if (existsSync26(video.extracted.outputDir)) {
|
|
34068
34229
|
rmSync5(video.extracted.outputDir, { recursive: true, force: true });
|
|
34069
34230
|
}
|
|
34070
34231
|
}
|
|
@@ -34468,7 +34629,7 @@ var init_videoFrameInjector = __esm({
|
|
|
34468
34629
|
});
|
|
34469
34630
|
|
|
34470
34631
|
// ../engine/src/services/audioMixer.ts
|
|
34471
|
-
import { existsSync as
|
|
34632
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, rmSync as rmSync6 } from "fs";
|
|
34472
34633
|
import { isAbsolute as isAbsolute5, join as join29, dirname as dirname10 } from "path";
|
|
34473
34634
|
function parseAudioElements(html) {
|
|
34474
34635
|
const elements = [];
|
|
@@ -34520,7 +34681,7 @@ function parseAudioElements(html) {
|
|
|
34520
34681
|
async function extractAudioFromVideo(videoPath, outputPath, options, signal, config) {
|
|
34521
34682
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34522
34683
|
const outputDir = dirname10(outputPath);
|
|
34523
|
-
if (!
|
|
34684
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34524
34685
|
const args = ["-i", videoPath];
|
|
34525
34686
|
if (options?.startTime !== void 0) args.push("-ss", String(options.startTime));
|
|
34526
34687
|
if (options?.duration !== void 0) args.push("-t", String(options.duration));
|
|
@@ -34547,7 +34708,7 @@ async function extractAudioFromVideo(videoPath, outputPath, options, signal, con
|
|
|
34547
34708
|
async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, signal, config) {
|
|
34548
34709
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34549
34710
|
const outputDir = dirname10(outputPath);
|
|
34550
|
-
if (!
|
|
34711
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34551
34712
|
const args = [
|
|
34552
34713
|
"-ss",
|
|
34553
34714
|
String(mediaStart),
|
|
@@ -34583,7 +34744,7 @@ async function prepareAudioTrack(srcPath, outputPath, mediaStart, duration, sign
|
|
|
34583
34744
|
async function generateSilence(outputPath, duration, signal, config) {
|
|
34584
34745
|
const ffmpegProcessTimeout = config?.ffmpegProcessTimeout ?? DEFAULT_CONFIG2.ffmpegProcessTimeout;
|
|
34585
34746
|
const outputDir = dirname10(outputPath);
|
|
34586
|
-
if (!
|
|
34747
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34587
34748
|
const args = [
|
|
34588
34749
|
"-f",
|
|
34589
34750
|
"lavfi",
|
|
@@ -34626,7 +34787,7 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
34626
34787
|
};
|
|
34627
34788
|
}
|
|
34628
34789
|
const outputDir = dirname10(outputPath);
|
|
34629
|
-
if (!
|
|
34790
|
+
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
34630
34791
|
const inputs = [];
|
|
34631
34792
|
const filterParts = [];
|
|
34632
34793
|
tracks.forEach((track, i2) => {
|
|
@@ -34687,7 +34848,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34687
34848
|
const startMs = Date.now();
|
|
34688
34849
|
const tracks = [];
|
|
34689
34850
|
const errors = [];
|
|
34690
|
-
if (!
|
|
34851
|
+
if (!existsSync27(workDir)) mkdirSync16(workDir, { recursive: true });
|
|
34691
34852
|
await Promise.all(
|
|
34692
34853
|
elements.map(async (element) => {
|
|
34693
34854
|
if (signal?.aborted) {
|
|
@@ -34709,7 +34870,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
34709
34870
|
return;
|
|
34710
34871
|
}
|
|
34711
34872
|
}
|
|
34712
|
-
if (!
|
|
34873
|
+
if (!existsSync27(srcPath)) {
|
|
34713
34874
|
errors.push(`Source not found: ${element.id} (${element.src})`);
|
|
34714
34875
|
return;
|
|
34715
34876
|
}
|
|
@@ -34873,7 +35034,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
34873
35034
|
|
|
34874
35035
|
// ../engine/src/services/parallelCoordinator.ts
|
|
34875
35036
|
import { cpus as cpus2, freemem as freemem2, totalmem as totalmem2 } from "os";
|
|
34876
|
-
import { existsSync as
|
|
35037
|
+
import { existsSync as existsSync28, mkdirSync as mkdirSync17, readdirSync as readdirSync13 } from "fs";
|
|
34877
35038
|
import { copyFile, rename } from "fs/promises";
|
|
34878
35039
|
import { join as join30 } from "path";
|
|
34879
35040
|
function defaultSafeMaxWorkers() {
|
|
@@ -34940,7 +35101,7 @@ function shouldVerifyWorkerGpu(workerId, config) {
|
|
|
34940
35101
|
async function executeWorkerTask(task, serverUrl, captureOptions, createBeforeCaptureHook, signal, onFrameCaptured, onFrameBuffer, config) {
|
|
34941
35102
|
const startTime = Date.now();
|
|
34942
35103
|
let framesCaptured = 0;
|
|
34943
|
-
if (!
|
|
35104
|
+
if (!existsSync28(task.outputDir)) mkdirSync17(task.outputDir, { recursive: true });
|
|
34944
35105
|
let session = null;
|
|
34945
35106
|
let perf;
|
|
34946
35107
|
try {
|
|
@@ -35035,11 +35196,11 @@ async function executeParallelCapture(serverUrl, workDir, tasks, captureOptions,
|
|
|
35035
35196
|
return results;
|
|
35036
35197
|
}
|
|
35037
35198
|
async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
35038
|
-
if (!
|
|
35199
|
+
if (!existsSync28(outputDir)) mkdirSync17(outputDir, { recursive: true });
|
|
35039
35200
|
let totalFrames = 0;
|
|
35040
35201
|
const sortedTasks = [...tasks].sort((a, b2) => a.startFrame - b2.startFrame);
|
|
35041
35202
|
for (const task of sortedTasks) {
|
|
35042
|
-
if (!
|
|
35203
|
+
if (!existsSync28(task.outputDir)) {
|
|
35043
35204
|
continue;
|
|
35044
35205
|
}
|
|
35045
35206
|
const files = readdirSync13(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
@@ -35083,7 +35244,7 @@ var init_parallelCoordinator = __esm({
|
|
|
35083
35244
|
// ../engine/src/services/fileServer.ts
|
|
35084
35245
|
import { Hono as Hono2 } from "hono";
|
|
35085
35246
|
import { serve } from "@hono/node-server";
|
|
35086
|
-
import { readFileSync as
|
|
35247
|
+
import { readFileSync as readFileSync22, existsSync as existsSync29, statSync as statSync9 } from "fs";
|
|
35087
35248
|
import { join as join31, extname as extname7 } from "path";
|
|
35088
35249
|
function createFileServer(options) {
|
|
35089
35250
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
@@ -35096,20 +35257,20 @@ function createFileServer(options) {
|
|
|
35096
35257
|
const relativePath = requestPath.replace(/^\//, "");
|
|
35097
35258
|
const compiledPath = compiledDir ? join31(compiledDir, relativePath) : null;
|
|
35098
35259
|
const hasCompiledFile = Boolean(
|
|
35099
|
-
compiledPath &&
|
|
35260
|
+
compiledPath && existsSync29(compiledPath) && statSync9(compiledPath).isFile()
|
|
35100
35261
|
);
|
|
35101
35262
|
const filePath = hasCompiledFile ? compiledPath : join31(projectDir, relativePath);
|
|
35102
|
-
if (!
|
|
35263
|
+
if (!existsSync29(filePath) || !statSync9(filePath).isFile()) {
|
|
35103
35264
|
return c3.text("Not found", 404);
|
|
35104
35265
|
}
|
|
35105
35266
|
const ext = extname7(filePath).toLowerCase();
|
|
35106
35267
|
const contentType = MIME_TYPES2[ext] || "application/octet-stream";
|
|
35107
35268
|
if (ext === ".html") {
|
|
35108
|
-
const rawHtml =
|
|
35269
|
+
const rawHtml = readFileSync22(filePath, "utf-8");
|
|
35109
35270
|
const html = relativePath === "index.html" ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime) : rawHtml;
|
|
35110
35271
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
35111
35272
|
}
|
|
35112
|
-
const content =
|
|
35273
|
+
const content = readFileSync22(filePath);
|
|
35113
35274
|
return new Response(content, {
|
|
35114
35275
|
status: 200,
|
|
35115
35276
|
headers: { "Content-Type": contentType }
|
|
@@ -36412,7 +36573,7 @@ var init_shaderTransitions = __esm({
|
|
|
36412
36573
|
});
|
|
36413
36574
|
|
|
36414
36575
|
// ../engine/src/services/hdrCapture.ts
|
|
36415
|
-
import { existsSync as
|
|
36576
|
+
import { existsSync as existsSync30, readdirSync as readdirSync14 } from "fs";
|
|
36416
36577
|
import { join as join32 } from "path";
|
|
36417
36578
|
import { homedir as homedir7 } from "os";
|
|
36418
36579
|
function linearToPQ(L2) {
|
|
@@ -36530,7 +36691,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
36530
36691
|
}
|
|
36531
36692
|
function resolveHeadedChromePath() {
|
|
36532
36693
|
const baseDir = join32(homedir7(), ".cache", "puppeteer", "chrome");
|
|
36533
|
-
if (!
|
|
36694
|
+
if (!existsSync30(baseDir)) return void 0;
|
|
36534
36695
|
const versions = readdirSync14(baseDir).sort().reverse();
|
|
36535
36696
|
for (const version of versions) {
|
|
36536
36697
|
const candidates = [
|
|
@@ -36556,7 +36717,7 @@ function resolveHeadedChromePath() {
|
|
|
36556
36717
|
join32(baseDir, version, "chrome-win64", "chrome.exe")
|
|
36557
36718
|
];
|
|
36558
36719
|
for (const binary of candidates) {
|
|
36559
|
-
if (
|
|
36720
|
+
if (existsSync30(binary)) return binary;
|
|
36560
36721
|
}
|
|
36561
36722
|
}
|
|
36562
36723
|
return void 0;
|
|
@@ -36825,7 +36986,7 @@ __export(deterministicFonts_exports, {
|
|
|
36825
36986
|
iterateFontFamilyDeclarations: () => iterateFontFamilyDeclarations,
|
|
36826
36987
|
parseFontFamilyValue: () => parseFontFamilyValue
|
|
36827
36988
|
});
|
|
36828
|
-
import { existsSync as
|
|
36989
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync23, writeFileSync as writeFileSync14 } from "fs";
|
|
36829
36990
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
|
|
36830
36991
|
import { join as join33 } from "path";
|
|
36831
36992
|
function parseFontFamilyValue(value) {
|
|
@@ -36954,7 +37115,7 @@ function fontSlug(familyName) {
|
|
|
36954
37115
|
}
|
|
36955
37116
|
function fontCacheDir(slug) {
|
|
36956
37117
|
const dir = join33(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
36957
|
-
if (!
|
|
37118
|
+
if (!existsSync31(dir)) {
|
|
36958
37119
|
mkdirSync18(dir, { recursive: true });
|
|
36959
37120
|
}
|
|
36960
37121
|
return dir;
|
|
@@ -36998,7 +37159,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
36998
37159
|
const woff2Url = match[3] || "";
|
|
36999
37160
|
if (!woff2Url) continue;
|
|
37000
37161
|
const cachePath2 = cachedWoff2Path(slug, weight, style);
|
|
37001
|
-
if (!
|
|
37162
|
+
if (!existsSync31(cachePath2)) {
|
|
37002
37163
|
const woff2What = `Google Fonts woff2 (${weight}/${style})`;
|
|
37003
37164
|
try {
|
|
37004
37165
|
const fontRes = await options.fetchImpl(woff2Url);
|
|
@@ -37018,7 +37179,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
37018
37179
|
continue;
|
|
37019
37180
|
}
|
|
37020
37181
|
}
|
|
37021
|
-
const fontBytes =
|
|
37182
|
+
const fontBytes = readFileSync23(cachePath2);
|
|
37022
37183
|
const dataUri = `data:font/woff2;base64,${fontBytes.toString("base64")}`;
|
|
37023
37184
|
faces.push({ weight, style, dataUri });
|
|
37024
37185
|
}
|
|
@@ -37218,7 +37379,7 @@ var init_deterministicFonts = __esm({
|
|
|
37218
37379
|
|
|
37219
37380
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
37220
37381
|
import { createHash as createHash5 } from "crypto";
|
|
37221
|
-
import { existsSync as
|
|
37382
|
+
import { existsSync as existsSync32, readFileSync as readFileSync24 } from "fs";
|
|
37222
37383
|
import { dirname as dirname11, resolve as resolve16 } from "path";
|
|
37223
37384
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
37224
37385
|
function resolveHyperframeManifestPath() {
|
|
@@ -37231,7 +37392,7 @@ function resolveHyperframeManifestPath() {
|
|
|
37231
37392
|
MODULE_RELATIVE_MANIFEST_PATH
|
|
37232
37393
|
];
|
|
37233
37394
|
for (const candidate of candidates) {
|
|
37234
|
-
if (
|
|
37395
|
+
if (existsSync32(candidate)) {
|
|
37235
37396
|
return candidate;
|
|
37236
37397
|
}
|
|
37237
37398
|
}
|
|
@@ -37242,12 +37403,12 @@ function getVerifiedHyperframeRuntimeSource() {
|
|
|
37242
37403
|
}
|
|
37243
37404
|
function resolveVerifiedHyperframeRuntime() {
|
|
37244
37405
|
const manifestPath = resolveHyperframeManifestPath();
|
|
37245
|
-
if (!
|
|
37406
|
+
if (!existsSync32(manifestPath)) {
|
|
37246
37407
|
throw new Error(
|
|
37247
37408
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
37248
37409
|
);
|
|
37249
37410
|
}
|
|
37250
|
-
const manifestRaw =
|
|
37411
|
+
const manifestRaw = readFileSync24(manifestPath, "utf8");
|
|
37251
37412
|
const manifest = JSON.parse(manifestRaw);
|
|
37252
37413
|
const runtimeFileName = manifest.artifacts?.iife;
|
|
37253
37414
|
if (!runtimeFileName || !manifest.sha256) {
|
|
@@ -37256,10 +37417,10 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
37256
37417
|
);
|
|
37257
37418
|
}
|
|
37258
37419
|
const runtimePath = resolve16(dirname11(manifestPath), runtimeFileName);
|
|
37259
|
-
if (!
|
|
37420
|
+
if (!existsSync32(runtimePath)) {
|
|
37260
37421
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
37261
37422
|
}
|
|
37262
|
-
const runtimeSource =
|
|
37423
|
+
const runtimeSource = readFileSync24(runtimePath, "utf8");
|
|
37263
37424
|
const runtimeSha = createHash5("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
37264
37425
|
if (runtimeSha !== manifest.sha256) {
|
|
37265
37426
|
throw new Error(
|
|
@@ -37298,7 +37459,7 @@ var init_hyperframeRuntimeLoader = __esm({
|
|
|
37298
37459
|
// ../producer/src/services/fileServer.ts
|
|
37299
37460
|
import { Hono as Hono3 } from "hono";
|
|
37300
37461
|
import { serve as serve2 } from "@hono/node-server";
|
|
37301
|
-
import { readFileSync as
|
|
37462
|
+
import { readFileSync as readFileSync25, existsSync as existsSync33, realpathSync, statSync as statSync10 } from "fs";
|
|
37302
37463
|
import { join as join34, extname as extname8, resolve as resolve17, sep as sep5 } from "path";
|
|
37303
37464
|
function isPathInside(child, parent, options = {}) {
|
|
37304
37465
|
const { resolveSymlinks = false, pathModule } = options;
|
|
@@ -37306,8 +37467,8 @@ function isPathInside(child, parent, options = {}) {
|
|
|
37306
37467
|
const separator = pathModule?.sep ?? sep5;
|
|
37307
37468
|
const resolvedChild = resolveFn(child);
|
|
37308
37469
|
const resolvedParent = resolveFn(parent);
|
|
37309
|
-
const normalizedChild = resolveSymlinks &&
|
|
37310
|
-
const normalizedParent = resolveSymlinks &&
|
|
37470
|
+
const normalizedChild = resolveSymlinks && existsSync33(resolvedChild) ? realpathSync.native(resolvedChild) : resolvedChild;
|
|
37471
|
+
const normalizedParent = resolveSymlinks && existsSync33(resolvedParent) ? realpathSync.native(resolvedParent) : resolvedParent;
|
|
37311
37472
|
if (normalizedChild === normalizedParent) return true;
|
|
37312
37473
|
const parentWithSep = normalizedParent.endsWith(separator) ? normalizedParent : normalizedParent + separator;
|
|
37313
37474
|
return normalizedChild.startsWith(parentWithSep);
|
|
@@ -37474,13 +37635,13 @@ function createFileServer2(options) {
|
|
|
37474
37635
|
let filePath = null;
|
|
37475
37636
|
if (compiledDir) {
|
|
37476
37637
|
const candidate = join34(compiledDir, relativePath);
|
|
37477
|
-
if (
|
|
37638
|
+
if (existsSync33(candidate) && isPathInside(candidate, compiledDir) && statSync10(candidate).isFile()) {
|
|
37478
37639
|
filePath = candidate;
|
|
37479
37640
|
}
|
|
37480
37641
|
}
|
|
37481
37642
|
if (!filePath) {
|
|
37482
37643
|
const candidate = join34(projectDir, relativePath);
|
|
37483
|
-
if (
|
|
37644
|
+
if (existsSync33(candidate) && isPathInside(candidate, projectDir) && statSync10(candidate).isFile()) {
|
|
37484
37645
|
filePath = candidate;
|
|
37485
37646
|
}
|
|
37486
37647
|
}
|
|
@@ -37493,7 +37654,7 @@ function createFileServer2(options) {
|
|
|
37493
37654
|
const ext = extname8(filePath).toLowerCase();
|
|
37494
37655
|
const contentType = MIME_TYPES3[ext] || "application/octet-stream";
|
|
37495
37656
|
if (ext === ".html") {
|
|
37496
|
-
const rawHtml =
|
|
37657
|
+
const rawHtml = readFileSync25(filePath, "utf-8");
|
|
37497
37658
|
const isIndex = relativePath === "index.html";
|
|
37498
37659
|
let html = rawHtml;
|
|
37499
37660
|
if (preHeadScripts.length > 0) {
|
|
@@ -37502,7 +37663,7 @@ function createFileServer2(options) {
|
|
|
37502
37663
|
html = isIndex ? injectScriptsIntoHtml(html, headScripts, bodyScripts, stripEmbeddedRuntime) : html;
|
|
37503
37664
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
37504
37665
|
}
|
|
37505
|
-
const content =
|
|
37666
|
+
const content = readFileSync25(filePath);
|
|
37506
37667
|
return new Response(content, {
|
|
37507
37668
|
status: 200,
|
|
37508
37669
|
headers: { "Content-Type": contentType }
|
|
@@ -37847,7 +38008,7 @@ var init_paths = __esm({
|
|
|
37847
38008
|
});
|
|
37848
38009
|
|
|
37849
38010
|
// ../producer/src/services/render/shared.ts
|
|
37850
|
-
import { copyFileSync as copyFileSync2, cpSync, existsSync as
|
|
38011
|
+
import { copyFileSync as copyFileSync2, cpSync, existsSync as existsSync34, mkdirSync as mkdirSync19, symlinkSync, writeFileSync as writeFileSync15 } from "fs";
|
|
37851
38012
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute6, join as join36, relative as relative4, resolve as resolve18 } from "path";
|
|
37852
38013
|
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
37853
38014
|
return browserEnd + (existingStart - browserStart);
|
|
@@ -38034,7 +38195,7 @@ var init_shared = __esm({
|
|
|
38034
38195
|
isAbsolute: isAbsolute6
|
|
38035
38196
|
};
|
|
38036
38197
|
materializeFileSystem = {
|
|
38037
|
-
existsSync:
|
|
38198
|
+
existsSync: existsSync34,
|
|
38038
38199
|
mkdirSync: mkdirSync19,
|
|
38039
38200
|
symlinkSync,
|
|
38040
38201
|
cpSync
|
|
@@ -38570,7 +38731,7 @@ var init_urlDownloader2 = __esm({
|
|
|
38570
38731
|
});
|
|
38571
38732
|
|
|
38572
38733
|
// ../producer/src/services/htmlCompiler.ts
|
|
38573
|
-
import { readFileSync as
|
|
38734
|
+
import { readFileSync as readFileSync26, existsSync as existsSync35, mkdirSync as mkdirSync20 } from "fs";
|
|
38574
38735
|
import { join as join38, dirname as dirname13, resolve as resolve19 } from "path";
|
|
38575
38736
|
function dedupeElementsById(elements) {
|
|
38576
38737
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -38632,7 +38793,7 @@ function detectShaderTransitionUsage(html) {
|
|
|
38632
38793
|
async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagName19) {
|
|
38633
38794
|
let filePath = src;
|
|
38634
38795
|
if (isHttpUrl(src)) {
|
|
38635
|
-
if (!
|
|
38796
|
+
if (!existsSync35(downloadDir)) mkdirSync20(downloadDir, { recursive: true });
|
|
38636
38797
|
try {
|
|
38637
38798
|
filePath = await downloadToTemp(src, downloadDir);
|
|
38638
38799
|
} catch {
|
|
@@ -38641,7 +38802,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
38641
38802
|
} else if (!filePath.startsWith("/")) {
|
|
38642
38803
|
filePath = join38(baseDir, filePath);
|
|
38643
38804
|
}
|
|
38644
|
-
if (!
|
|
38805
|
+
if (!existsSync35(filePath)) {
|
|
38645
38806
|
return { duration: 0, resolvedPath: filePath };
|
|
38646
38807
|
}
|
|
38647
38808
|
let metadata;
|
|
@@ -38719,10 +38880,10 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
38719
38880
|
if (visited.has(filePath)) {
|
|
38720
38881
|
continue;
|
|
38721
38882
|
}
|
|
38722
|
-
if (!
|
|
38883
|
+
if (!existsSync35(filePath)) {
|
|
38723
38884
|
continue;
|
|
38724
38885
|
}
|
|
38725
|
-
const rawSubHtml =
|
|
38886
|
+
const rawSubHtml = readFileSync26(filePath, "utf-8");
|
|
38726
38887
|
const nestedVisited = new Set(visited);
|
|
38727
38888
|
nestedVisited.add(filePath);
|
|
38728
38889
|
workItems.push({ srcPath, absoluteStart, absoluteEnd, filePath, rawSubHtml, nestedVisited });
|
|
@@ -38907,8 +39068,8 @@ function inlineSubCompositions2(html, subCompositions, projectDir) {
|
|
|
38907
39068
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
38908
39069
|
if (!compHtml) {
|
|
38909
39070
|
const filePath = resolve19(projectDir, srcPath);
|
|
38910
|
-
if (
|
|
38911
|
-
compHtml =
|
|
39071
|
+
if (existsSync35(filePath)) {
|
|
39072
|
+
compHtml = readFileSync26(filePath, "utf-8");
|
|
38912
39073
|
}
|
|
38913
39074
|
}
|
|
38914
39075
|
return compHtml;
|
|
@@ -39065,7 +39226,7 @@ function collectExternalAssets(html, projectDir) {
|
|
|
39065
39226
|
if (isPathInside2(absPath, absProjectDir)) {
|
|
39066
39227
|
return null;
|
|
39067
39228
|
}
|
|
39068
|
-
if (!
|
|
39229
|
+
if (!existsSync35(absPath)) return null;
|
|
39069
39230
|
const safeKey = toExternalAssetKey(absPath);
|
|
39070
39231
|
externalAssets.set(safeKey, absPath);
|
|
39071
39232
|
return safeKey;
|
|
@@ -39115,7 +39276,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39115
39276
|
(full, prefix, src, file, suffix) => {
|
|
39116
39277
|
if (/^https?:\/\//i.test(src)) return full;
|
|
39117
39278
|
const absPath = resolve19(projectDir, src);
|
|
39118
|
-
if (
|
|
39279
|
+
if (existsSync35(absPath)) return full;
|
|
39119
39280
|
console.log(
|
|
39120
39281
|
`[Compiler] Rewriting missing gsap script to CDN: ${src} \u2192 ${GSAP_CDN_BASE}${file}`
|
|
39121
39282
|
);
|
|
@@ -39124,7 +39285,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
39124
39285
|
);
|
|
39125
39286
|
}
|
|
39126
39287
|
async function compileForRender(projectDir, htmlPath, downloadDir, options = {}) {
|
|
39127
|
-
const rawHtml = rewriteUnresolvableGsapToCdn(
|
|
39288
|
+
const rawHtml = rewriteUnresolvableGsapToCdn(readFileSync26(htmlPath, "utf-8"), projectDir);
|
|
39128
39289
|
const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
|
|
39129
39290
|
rawHtml,
|
|
39130
39291
|
projectDir,
|
|
@@ -39746,7 +39907,7 @@ var init_probeStage = __esm({
|
|
|
39746
39907
|
});
|
|
39747
39908
|
|
|
39748
39909
|
// ../producer/src/services/render/stages/extractVideosStage.ts
|
|
39749
|
-
import { existsSync as
|
|
39910
|
+
import { existsSync as existsSync36 } from "fs";
|
|
39750
39911
|
import { isAbsolute as isAbsolute7, join as join41 } from "path";
|
|
39751
39912
|
async function runExtractVideosStage(input) {
|
|
39752
39913
|
const {
|
|
@@ -39770,7 +39931,7 @@ async function runExtractVideosStage(input) {
|
|
|
39770
39931
|
await Promise.all(
|
|
39771
39932
|
composition.videos.map(async (v2) => {
|
|
39772
39933
|
const videoPath = isAbsolute7(v2.src) ? v2.src : resolveProjectRelativeSrc(v2.src, projectDir, compiledDir);
|
|
39773
|
-
if (!
|
|
39934
|
+
if (!existsSync36(videoPath)) return;
|
|
39774
39935
|
const meta = await extractMediaMetadata(videoPath);
|
|
39775
39936
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39776
39937
|
nativeHdrVideoIds.add(v2.id);
|
|
@@ -39788,10 +39949,10 @@ async function runExtractVideosStage(input) {
|
|
|
39788
39949
|
composition.images.map(async (img) => {
|
|
39789
39950
|
let imgPath = img.src;
|
|
39790
39951
|
if (!imgPath.startsWith("/")) {
|
|
39791
|
-
const fromCompiled =
|
|
39952
|
+
const fromCompiled = existsSync36(join41(compiledDir, imgPath)) ? join41(compiledDir, imgPath) : join41(projectDir, imgPath);
|
|
39792
39953
|
imgPath = fromCompiled;
|
|
39793
39954
|
}
|
|
39794
|
-
if (!
|
|
39955
|
+
if (!existsSync36(imgPath)) return null;
|
|
39795
39956
|
const meta = await extractMediaMetadata(imgPath);
|
|
39796
39957
|
if (isHdrColorSpace(meta.colorSpace)) {
|
|
39797
39958
|
nativeHdrImageIds.add(img.id);
|
|
@@ -40266,7 +40427,7 @@ var init_hdrImageTransferCache = __esm({
|
|
|
40266
40427
|
});
|
|
40267
40428
|
|
|
40268
40429
|
// ../producer/src/services/render/stages/captureHdrResources.ts
|
|
40269
|
-
import { mkdirSync as mkdirSync21, openSync, readFileSync as
|
|
40430
|
+
import { mkdirSync as mkdirSync21, openSync, readFileSync as readFileSync27, statSync as statSync11 } from "fs";
|
|
40270
40431
|
import { join as join43 } from "path";
|
|
40271
40432
|
function planHdrResources(args) {
|
|
40272
40433
|
const { composition, nativeHdrVideoIds, nativeHdrImageIds, projectDir, compiledDir } = args;
|
|
@@ -40411,7 +40572,7 @@ function decodeHdrImageBuffers(args) {
|
|
|
40411
40572
|
const out = /* @__PURE__ */ new Map();
|
|
40412
40573
|
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
40413
40574
|
try {
|
|
40414
|
-
const decoded = decodePngToRgb48le(
|
|
40575
|
+
const decoded = decodePngToRgb48le(readFileSync27(srcPath));
|
|
40415
40576
|
const layout2 = prep.hdrExtractionDims.get(imageId);
|
|
40416
40577
|
const fitInfo = prep.hdrImageFitInfo.get(imageId);
|
|
40417
40578
|
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
@@ -40849,7 +41010,7 @@ import { Worker } from "worker_threads";
|
|
|
40849
41010
|
import { fileURLToPath as fileURLToPath3, pathToFileURL } from "url";
|
|
40850
41011
|
import { dirname as dirname14, join as join45 } from "path";
|
|
40851
41012
|
import { createRequire } from "module";
|
|
40852
|
-
import { existsSync as
|
|
41013
|
+
import { existsSync as existsSync37 } from "fs";
|
|
40853
41014
|
import { cpus as cpus3 } from "os";
|
|
40854
41015
|
function resolveWorkerEntry(explicit) {
|
|
40855
41016
|
if (explicit && explicit.length > 0) {
|
|
@@ -40862,7 +41023,7 @@ function resolveWorkerEntry(explicit) {
|
|
|
40862
41023
|
}
|
|
40863
41024
|
const moduleDir = dirname14(fileURLToPath3(import.meta.url));
|
|
40864
41025
|
const jsPath = join45(moduleDir, "shaderTransitionWorker.js");
|
|
40865
|
-
if (
|
|
41026
|
+
if (existsSync37(jsPath)) return { path: jsPath, isTs: false };
|
|
40866
41027
|
const tsPath = join45(moduleDir, "shaderTransitionWorker.ts");
|
|
40867
41028
|
return { path: tsPath, isTs: true };
|
|
40868
41029
|
}
|
|
@@ -41271,7 +41432,7 @@ var init_captureHdrHybridLoop = __esm({
|
|
|
41271
41432
|
});
|
|
41272
41433
|
|
|
41273
41434
|
// ../producer/src/services/render/stages/captureHdrStage.ts
|
|
41274
|
-
import { existsSync as
|
|
41435
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync22 } from "fs";
|
|
41275
41436
|
import { join as join47 } from "path";
|
|
41276
41437
|
async function runCaptureHdrStage(input) {
|
|
41277
41438
|
const {
|
|
@@ -41328,7 +41489,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41328
41489
|
nativeHdrImageIds,
|
|
41329
41490
|
projectDir,
|
|
41330
41491
|
compiledDir,
|
|
41331
|
-
existsSync:
|
|
41492
|
+
existsSync: existsSync38
|
|
41332
41493
|
});
|
|
41333
41494
|
const domSession = await createCaptureSession(
|
|
41334
41495
|
fileServer.url,
|
|
@@ -41432,7 +41593,7 @@ async function runCaptureHdrStage(input) {
|
|
|
41432
41593
|
}
|
|
41433
41594
|
const debugDumpEnabled = process.env.KEEP_TEMP === "1";
|
|
41434
41595
|
const debugDumpDir = debugDumpEnabled ? join47(framesDir, "debug-composite") : null;
|
|
41435
|
-
if (debugDumpDir && !
|
|
41596
|
+
if (debugDumpDir && !existsSync38(debugDumpDir)) {
|
|
41436
41597
|
mkdirSync22(debugDumpDir, { recursive: true });
|
|
41437
41598
|
}
|
|
41438
41599
|
const compositeTransfer = resolveCompositeTransfer(hasHdrContent, effectiveHdr);
|
|
@@ -41588,7 +41749,7 @@ var init_captureHdrStage = __esm({
|
|
|
41588
41749
|
});
|
|
41589
41750
|
|
|
41590
41751
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
41591
|
-
import { copyFileSync as copyFileSync3, existsSync as
|
|
41752
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync39, mkdirSync as mkdirSync23, readdirSync as readdirSync15 } from "fs";
|
|
41592
41753
|
import { join as join48 } from "path";
|
|
41593
41754
|
async function runEncodeStage(input) {
|
|
41594
41755
|
const {
|
|
@@ -41615,7 +41776,7 @@ async function runEncodeStage(input) {
|
|
|
41615
41776
|
const stage5Start = Date.now();
|
|
41616
41777
|
if (isPngSequence) {
|
|
41617
41778
|
updateJobStatus(job, "encoding", "Writing PNG sequence", 75, onProgress);
|
|
41618
|
-
if (!
|
|
41779
|
+
if (!existsSync39(outputPath)) mkdirSync23(outputPath, { recursive: true });
|
|
41619
41780
|
const captured = readdirSync15(framesDir).filter((name) => name.endsWith(".png")).sort();
|
|
41620
41781
|
if (captured.length === 0) {
|
|
41621
41782
|
throw new Error(
|
|
@@ -41626,7 +41787,7 @@ async function runEncodeStage(input) {
|
|
|
41626
41787
|
const dst = join48(outputPath, `frame_${String(i2 + 1).padStart(6, "0")}.png`);
|
|
41627
41788
|
copyFileSync3(join48(framesDir, name), dst);
|
|
41628
41789
|
});
|
|
41629
|
-
if (hasAudio && audioOutputPath &&
|
|
41790
|
+
if (hasAudio && audioOutputPath && existsSync39(audioOutputPath)) {
|
|
41630
41791
|
copyFileSync3(audioOutputPath, join48(outputPath, "audio.aac"));
|
|
41631
41792
|
log2.info(`[Render] png-sequence: audio.aac sidecar written to ${outputPath}/audio.aac`);
|
|
41632
41793
|
}
|
|
@@ -41718,9 +41879,9 @@ var init_assembleStage = __esm({
|
|
|
41718
41879
|
|
|
41719
41880
|
// ../producer/src/services/renderOrchestrator.ts
|
|
41720
41881
|
import {
|
|
41721
|
-
existsSync as
|
|
41882
|
+
existsSync as existsSync40,
|
|
41722
41883
|
mkdirSync as mkdirSync24,
|
|
41723
|
-
readFileSync as
|
|
41884
|
+
readFileSync as readFileSync28,
|
|
41724
41885
|
readSync,
|
|
41725
41886
|
closeSync,
|
|
41726
41887
|
readdirSync as readdirSync16,
|
|
@@ -41833,7 +41994,7 @@ function findMissingFrameRanges(totalFrames, framesDir, frameExt) {
|
|
|
41833
41994
|
let rangeStart = null;
|
|
41834
41995
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41835
41996
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41836
|
-
const missing = !
|
|
41997
|
+
const missing = !existsSync40(framePath);
|
|
41837
41998
|
if (missing && rangeStart === null) {
|
|
41838
41999
|
rangeStart = frameIndex;
|
|
41839
42000
|
} else if (!missing && rangeStart !== null) {
|
|
@@ -41875,7 +42036,7 @@ function countCapturedFrames(totalFrames, framesDir, frameExt) {
|
|
|
41875
42036
|
let captured = 0;
|
|
41876
42037
|
for (let frameIndex = 0; frameIndex < totalFrames; frameIndex++) {
|
|
41877
42038
|
const framePath = join49(framesDir, `frame_${String(frameIndex).padStart(6, "0")}.${frameExt}`);
|
|
41878
|
-
if (
|
|
42039
|
+
if (existsSync40(framePath)) captured++;
|
|
41879
42040
|
}
|
|
41880
42041
|
return captured;
|
|
41881
42042
|
}
|
|
@@ -42446,28 +42607,28 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42446
42607
|
};
|
|
42447
42608
|
job.startedAt = /* @__PURE__ */ new Date();
|
|
42448
42609
|
assertNotAborted();
|
|
42449
|
-
if (!
|
|
42610
|
+
if (!existsSync40(workDir)) mkdirSync24(workDir, { recursive: true });
|
|
42450
42611
|
if (job.config.debug) {
|
|
42451
42612
|
const logPath = join49(workDir, "render.log");
|
|
42452
42613
|
restoreLogger = installDebugLogger(logPath, log2);
|
|
42453
42614
|
}
|
|
42454
42615
|
const entryFile = job.config.entryFile || "index.html";
|
|
42455
42616
|
let htmlPath = join49(projectDir, entryFile);
|
|
42456
|
-
if (!
|
|
42617
|
+
if (!existsSync40(htmlPath)) {
|
|
42457
42618
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
42458
42619
|
}
|
|
42459
42620
|
assertNotAborted();
|
|
42460
|
-
const rawEntry =
|
|
42621
|
+
const rawEntry = readFileSync28(htmlPath, "utf-8");
|
|
42461
42622
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
42462
42623
|
const wrapperPath = join49(workDir, "standalone-entry.html");
|
|
42463
42624
|
const projectIndexPath = join49(projectDir, "index.html");
|
|
42464
|
-
if (!
|
|
42625
|
+
if (!existsSync40(projectIndexPath)) {
|
|
42465
42626
|
throw new Error(
|
|
42466
42627
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
42467
42628
|
);
|
|
42468
42629
|
}
|
|
42469
42630
|
const standaloneHtml = extractStandaloneEntryFromIndex(
|
|
42470
|
-
|
|
42631
|
+
readFileSync28(projectIndexPath, "utf-8"),
|
|
42471
42632
|
entryFile
|
|
42472
42633
|
);
|
|
42473
42634
|
if (!standaloneHtml) {
|
|
@@ -42578,7 +42739,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42578
42739
|
assertNotAborted();
|
|
42579
42740
|
}
|
|
42580
42741
|
const framesDir = join49(workDir, "captured-frames");
|
|
42581
|
-
if (!
|
|
42742
|
+
if (!existsSync40(framesDir)) mkdirSync24(framesDir, { recursive: true });
|
|
42582
42743
|
const captureOptions = {
|
|
42583
42744
|
width,
|
|
42584
42745
|
height,
|
|
@@ -42833,7 +42994,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42833
42994
|
job.outputPath = outputPath;
|
|
42834
42995
|
updateJobStatus(job, "complete", "Render complete", 100, onProgress);
|
|
42835
42996
|
const totalElapsed = Date.now() - pipelineStart;
|
|
42836
|
-
const tmpPeakBytes =
|
|
42997
|
+
const tmpPeakBytes = existsSync40(workDir) ? sampleDirectoryBytes(workDir) : 0;
|
|
42837
42998
|
const perfSummary = buildRenderPerfSummary({
|
|
42838
42999
|
job,
|
|
42839
43000
|
workerCount,
|
|
@@ -42868,7 +43029,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
42868
43029
|
}
|
|
42869
43030
|
}
|
|
42870
43031
|
if (job.config.debug) {
|
|
42871
|
-
if (!isPngSequence &&
|
|
43032
|
+
if (!isPngSequence && existsSync40(outputPath)) {
|
|
42872
43033
|
const debugOutput = join49(workDir, `output${videoExt}`);
|
|
42873
43034
|
copyFileSync4(outputPath, debugOutput);
|
|
42874
43035
|
}
|
|
@@ -42995,7 +43156,7 @@ var init_config3 = __esm({
|
|
|
42995
43156
|
});
|
|
42996
43157
|
|
|
42997
43158
|
// ../producer/src/services/hyperframeLint.ts
|
|
42998
|
-
import { existsSync as
|
|
43159
|
+
import { existsSync as existsSync41, readFileSync as readFileSync29, statSync as statSync13 } from "fs";
|
|
42999
43160
|
import { resolve as resolve21, join as join50 } from "path";
|
|
43000
43161
|
function isStringRecord(value) {
|
|
43001
43162
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -43024,7 +43185,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
43024
43185
|
}
|
|
43025
43186
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
43026
43187
|
const absProjectDir = resolve21(projectDir);
|
|
43027
|
-
if (!
|
|
43188
|
+
if (!existsSync41(absProjectDir) || !statSync13(absProjectDir).isDirectory()) {
|
|
43028
43189
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43029
43190
|
}
|
|
43030
43191
|
const entryCandidates = [preferredEntryFile, "index.html", "src/index.html"].filter(
|
|
@@ -43035,10 +43196,10 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
43035
43196
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
43036
43197
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
43037
43198
|
}
|
|
43038
|
-
if (
|
|
43199
|
+
if (existsSync41(absoluteEntryPath) && statSync13(absoluteEntryPath).isFile()) {
|
|
43039
43200
|
return {
|
|
43040
43201
|
entryFile,
|
|
43041
|
-
html:
|
|
43202
|
+
html: readFileSync29(absoluteEntryPath, "utf-8"),
|
|
43042
43203
|
source: "projectDir"
|
|
43043
43204
|
};
|
|
43044
43205
|
}
|
|
@@ -43133,7 +43294,7 @@ var init_semaphore = __esm({
|
|
|
43133
43294
|
|
|
43134
43295
|
// ../producer/src/server.ts
|
|
43135
43296
|
import {
|
|
43136
|
-
existsSync as
|
|
43297
|
+
existsSync as existsSync42,
|
|
43137
43298
|
mkdirSync as mkdirSync25,
|
|
43138
43299
|
statSync as statSync14,
|
|
43139
43300
|
mkdtempSync as mkdtempSync2,
|
|
@@ -43166,11 +43327,11 @@ async function prepareRenderBody(body) {
|
|
|
43166
43327
|
const projectDir = typeof body.projectDir === "string" ? body.projectDir : void 0;
|
|
43167
43328
|
if (projectDir) {
|
|
43168
43329
|
const absProjectDir = resolve22(projectDir);
|
|
43169
|
-
if (!
|
|
43330
|
+
if (!existsSync42(absProjectDir) || !statSync14(absProjectDir).isDirectory()) {
|
|
43170
43331
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
43171
43332
|
}
|
|
43172
43333
|
const entry = options.entryFile || "index.html";
|
|
43173
|
-
if (!
|
|
43334
|
+
if (!existsSync42(resolve22(absProjectDir, entry))) {
|
|
43174
43335
|
return { error: `Entry file "${entry}" not found in project directory: ${absProjectDir}` };
|
|
43175
43336
|
}
|
|
43176
43337
|
return { prepared: { input: { projectDir: absProjectDir, ...options } } };
|
|
@@ -43319,8 +43480,8 @@ function createRenderHandlers(options = {}) {
|
|
|
43319
43480
|
log2
|
|
43320
43481
|
);
|
|
43321
43482
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43322
|
-
if (!
|
|
43323
|
-
const
|
|
43483
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43484
|
+
const release4 = await renderSemaphore.acquire();
|
|
43324
43485
|
log2.info("render started", {
|
|
43325
43486
|
requestId,
|
|
43326
43487
|
projectDir: input.projectDir,
|
|
@@ -43346,7 +43507,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43346
43507
|
log2.info(`render progress ${pct}%`, { requestId, stage: j3.currentStage, message });
|
|
43347
43508
|
}
|
|
43348
43509
|
});
|
|
43349
|
-
const fileSize =
|
|
43510
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43350
43511
|
const durationMs = Date.now() - t0;
|
|
43351
43512
|
const outputToken = store.register(absoluteOutputPath);
|
|
43352
43513
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
@@ -43388,7 +43549,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43388
43549
|
500
|
|
43389
43550
|
);
|
|
43390
43551
|
} finally {
|
|
43391
|
-
|
|
43552
|
+
release4();
|
|
43392
43553
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43393
43554
|
}
|
|
43394
43555
|
};
|
|
@@ -43430,7 +43591,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43430
43591
|
log2
|
|
43431
43592
|
);
|
|
43432
43593
|
const outputDir = dirname16(absoluteOutputPath);
|
|
43433
|
-
if (!
|
|
43594
|
+
if (!existsSync42(outputDir)) mkdirSync25(outputDir, { recursive: true });
|
|
43434
43595
|
log2.info("render-stream started", { requestId, projectDir: input.projectDir });
|
|
43435
43596
|
const job = createRenderJob({
|
|
43436
43597
|
fps: input.fps,
|
|
@@ -43454,7 +43615,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43454
43615
|
})
|
|
43455
43616
|
});
|
|
43456
43617
|
}
|
|
43457
|
-
const
|
|
43618
|
+
const release4 = await renderSemaphore.acquire();
|
|
43458
43619
|
try {
|
|
43459
43620
|
await executeRenderJob(
|
|
43460
43621
|
job,
|
|
@@ -43475,7 +43636,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43475
43636
|
},
|
|
43476
43637
|
abortController.signal
|
|
43477
43638
|
);
|
|
43478
|
-
const fileSize =
|
|
43639
|
+
const fileSize = existsSync42(absoluteOutputPath) ? statSync14(absoluteOutputPath).size : 0;
|
|
43479
43640
|
const outputToken = store.register(absoluteOutputPath);
|
|
43480
43641
|
const outputUrl = `${outputUrlPrefix}/${outputToken}`;
|
|
43481
43642
|
log2.info("render-stream completed", { requestId, fileSize, perf: job.perfSummary ?? null });
|
|
@@ -43522,7 +43683,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43522
43683
|
})
|
|
43523
43684
|
});
|
|
43524
43685
|
} finally {
|
|
43525
|
-
|
|
43686
|
+
release4();
|
|
43526
43687
|
c3.req.raw.signal.removeEventListener("abort", onRequestAbort);
|
|
43527
43688
|
cleanupTempDir(cleanupProjectDir, log2);
|
|
43528
43689
|
}
|
|
@@ -43534,7 +43695,7 @@ function createRenderHandlers(options = {}) {
|
|
|
43534
43695
|
if (!artifact) {
|
|
43535
43696
|
return c3.json({ success: false, error: "Output artifact not found or expired" }, 404);
|
|
43536
43697
|
}
|
|
43537
|
-
if (!
|
|
43698
|
+
if (!existsSync42(artifact.path)) {
|
|
43538
43699
|
store.delete(token);
|
|
43539
43700
|
return c3.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
43540
43701
|
}
|
|
@@ -43688,7 +43849,7 @@ var init_planHash = __esm({
|
|
|
43688
43849
|
});
|
|
43689
43850
|
|
|
43690
43851
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
43691
|
-
import { existsSync as
|
|
43852
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync26, readFileSync as readFileSync30, readdirSync as readdirSync17, writeFileSync as writeFileSync20 } from "fs";
|
|
43692
43853
|
import { join as join52, relative as relative5, resolve as resolve23 } from "path";
|
|
43693
43854
|
function stripUndefined(value) {
|
|
43694
43855
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -43731,11 +43892,11 @@ function collectPlanAssetShas(planDir) {
|
|
|
43731
43892
|
const assets = [];
|
|
43732
43893
|
for (const file of files) {
|
|
43733
43894
|
if (file.planRelativePath === COMPILED_INDEX_RELATIVE_PATH) {
|
|
43734
|
-
compositionHtml =
|
|
43895
|
+
compositionHtml = readFileSync30(file.absolutePath);
|
|
43735
43896
|
continue;
|
|
43736
43897
|
}
|
|
43737
43898
|
if (HASH_EXCLUDED_PLAN_FILES.has(file.planRelativePath)) continue;
|
|
43738
|
-
const bytes =
|
|
43899
|
+
const bytes = readFileSync30(file.absolutePath);
|
|
43739
43900
|
assets.push({ path: file.planRelativePath, sha256: sha256Hex(bytes) });
|
|
43740
43901
|
}
|
|
43741
43902
|
if (compositionHtml === null) {
|
|
@@ -43748,14 +43909,14 @@ function collectPlanAssetShas(planDir) {
|
|
|
43748
43909
|
function recomputePlanHashFromPlanDir(planDir) {
|
|
43749
43910
|
const planJsonPath = join52(planDir, "plan.json");
|
|
43750
43911
|
const encoderJsonPath = join52(planDir, "meta", "encoder.json");
|
|
43751
|
-
if (!
|
|
43912
|
+
if (!existsSync43(planJsonPath)) {
|
|
43752
43913
|
throw new Error(`[freezePlan] plan.json missing: ${planJsonPath}`);
|
|
43753
43914
|
}
|
|
43754
|
-
if (!
|
|
43915
|
+
if (!existsSync43(encoderJsonPath)) {
|
|
43755
43916
|
throw new Error(`[freezePlan] meta/encoder.json missing: ${encoderJsonPath}`);
|
|
43756
43917
|
}
|
|
43757
|
-
const planJson = JSON.parse(
|
|
43758
|
-
const encoderConfigCanonicalJson =
|
|
43918
|
+
const planJson = JSON.parse(readFileSync30(planJsonPath, "utf-8"));
|
|
43919
|
+
const encoderConfigCanonicalJson = readFileSync30(encoderJsonPath, "utf-8");
|
|
43759
43920
|
const { compositionHtml, assets } = collectPlanAssetShas(planDir);
|
|
43760
43921
|
return computePlanHash({
|
|
43761
43922
|
compositionHtml,
|
|
@@ -43780,11 +43941,11 @@ async function freezePlan(input) {
|
|
|
43780
43941
|
totalFrames,
|
|
43781
43942
|
hasAudio
|
|
43782
43943
|
} = input;
|
|
43783
|
-
if (!
|
|
43944
|
+
if (!existsSync43(planDir)) {
|
|
43784
43945
|
throw new Error(`[freezePlan] planDir does not exist: ${planDir}`);
|
|
43785
43946
|
}
|
|
43786
43947
|
const metaDir = join52(planDir, "meta");
|
|
43787
|
-
if (!
|
|
43948
|
+
if (!existsSync43(metaDir)) mkdirSync26(metaDir, { recursive: true });
|
|
43788
43949
|
writeFileSync20(
|
|
43789
43950
|
join52(metaDir, "composition.json"),
|
|
43790
43951
|
`${JSON.stringify(composition, null, 2)}
|
|
@@ -43926,7 +44087,7 @@ var init_runtimeEnvSnapshot = __esm({
|
|
|
43926
44087
|
// ../producer/src/services/distributed/shared.ts
|
|
43927
44088
|
import { execFile as execFileCallback } from "child_process";
|
|
43928
44089
|
import { dirname as dirname17, join as join53 } from "path";
|
|
43929
|
-
import { existsSync as
|
|
44090
|
+
import { existsSync as existsSync44, readFileSync as readFileSync31 } from "fs";
|
|
43930
44091
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
43931
44092
|
import { promisify as promisify2 } from "util";
|
|
43932
44093
|
async function readFfmpegVersion() {
|
|
@@ -43964,9 +44125,9 @@ function readProducerVersion() {
|
|
|
43964
44125
|
let current = startDir;
|
|
43965
44126
|
for (let i2 = 0; i2 < 10; i2++) {
|
|
43966
44127
|
const candidate = join53(current, "package.json");
|
|
43967
|
-
if (
|
|
44128
|
+
if (existsSync44(candidate)) {
|
|
43968
44129
|
try {
|
|
43969
|
-
const pkg = JSON.parse(
|
|
44130
|
+
const pkg = JSON.parse(readFileSync31(candidate, "utf-8"));
|
|
43970
44131
|
if (pkg.name === "@hyperframes/producer" && typeof pkg.version === "string") {
|
|
43971
44132
|
cachedProducerVersion = pkg.version;
|
|
43972
44133
|
return pkg.version;
|
|
@@ -43997,7 +44158,7 @@ var init_shared2 = __esm({
|
|
|
43997
44158
|
// ../producer/src/services/distributed/plan.ts
|
|
43998
44159
|
import {
|
|
43999
44160
|
cpSync as cpSync2,
|
|
44000
|
-
existsSync as
|
|
44161
|
+
existsSync as existsSync45,
|
|
44001
44162
|
mkdirSync as mkdirSync27,
|
|
44002
44163
|
readdirSync as readdirSync18,
|
|
44003
44164
|
renameSync as renameSync3,
|
|
@@ -44162,7 +44323,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44162
44323
|
useGpu: false,
|
|
44163
44324
|
browserGpuMode: "software"
|
|
44164
44325
|
});
|
|
44165
|
-
if (!
|
|
44326
|
+
if (!existsSync45(planDir)) mkdirSync27(planDir, { recursive: true });
|
|
44166
44327
|
const log2 = config.logger ?? defaultLogger;
|
|
44167
44328
|
const abortSignal = config.abortSignal;
|
|
44168
44329
|
const assertNotAborted = () => {
|
|
@@ -44191,11 +44352,11 @@ async function plan(projectDir, config, planDir) {
|
|
|
44191
44352
|
});
|
|
44192
44353
|
const entryFile = config.entryFile ?? "index.html";
|
|
44193
44354
|
const htmlPath = join54(projectDir, entryFile);
|
|
44194
|
-
if (!
|
|
44355
|
+
if (!existsSync45(htmlPath)) {
|
|
44195
44356
|
throw new Error(`[plan] entry file not found: ${htmlPath}`);
|
|
44196
44357
|
}
|
|
44197
44358
|
const workDir = join54(planDir, ".plan-work");
|
|
44198
|
-
if (!
|
|
44359
|
+
if (!existsSync45(workDir)) mkdirSync27(workDir, { recursive: true });
|
|
44199
44360
|
const compiledDir = join54(workDir, "compiled");
|
|
44200
44361
|
mkdirSync27(compiledDir, { recursive: true });
|
|
44201
44362
|
cpSync2(projectDir, compiledDir, {
|
|
@@ -44281,13 +44442,13 @@ async function plan(projectDir, config, planDir) {
|
|
|
44281
44442
|
});
|
|
44282
44443
|
const stagedVideoFrames = join54(compiledDir, "__hyperframes_video_frames");
|
|
44283
44444
|
const videoFramesDst = join54(planDir, "video-frames");
|
|
44284
|
-
if (
|
|
44285
|
-
if (
|
|
44445
|
+
if (existsSync45(videoFramesDst)) rmSync11(videoFramesDst, { recursive: true, force: true });
|
|
44446
|
+
if (existsSync45(stagedVideoFrames)) {
|
|
44286
44447
|
renameSync3(stagedVideoFrames, videoFramesDst);
|
|
44287
44448
|
} else {
|
|
44288
44449
|
mkdirSync27(videoFramesDst, { recursive: true });
|
|
44289
44450
|
}
|
|
44290
|
-
if (
|
|
44451
|
+
if (existsSync45(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
44291
44452
|
renameSync3(compiledDir, finalCompiledDir);
|
|
44292
44453
|
const planVideosJson = {
|
|
44293
44454
|
videos: composition.videos,
|
|
@@ -44307,7 +44468,7 @@ async function plan(projectDir, config, planDir) {
|
|
|
44307
44468
|
"utf-8"
|
|
44308
44469
|
);
|
|
44309
44470
|
const planAudioPath = join54(planDir, "audio.aac");
|
|
44310
|
-
if (audioResult.hasAudio &&
|
|
44471
|
+
if (audioResult.hasAudio && existsSync45(audioResult.audioOutputPath)) {
|
|
44311
44472
|
renameSync3(audioResult.audioOutputPath, planAudioPath);
|
|
44312
44473
|
}
|
|
44313
44474
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
@@ -44446,13 +44607,13 @@ var init_plan = __esm({
|
|
|
44446
44607
|
|
|
44447
44608
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
44448
44609
|
import { randomBytes } from "crypto";
|
|
44449
|
-
import { existsSync as
|
|
44610
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync28, readFileSync as readFileSync32, readdirSync as readdirSync19, rmSync as rmSync12, writeFileSync as writeFileSync22 } from "fs";
|
|
44450
44611
|
import { extname as extname9, join as join55 } from "path";
|
|
44451
44612
|
function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
44452
44613
|
const result = [];
|
|
44453
44614
|
for (const v2 of videos) {
|
|
44454
44615
|
const outputDir = join55(planDir, "video-frames", v2.videoId);
|
|
44455
|
-
if (!
|
|
44616
|
+
if (!existsSync46(outputDir)) {
|
|
44456
44617
|
throw new Error(
|
|
44457
44618
|
`[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
44619
|
);
|
|
@@ -44485,10 +44646,10 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
|
44485
44646
|
return result;
|
|
44486
44647
|
}
|
|
44487
44648
|
function hashChunkOutput(outputPath, kind) {
|
|
44488
|
-
if (kind === "file") return sha256Hex(
|
|
44649
|
+
if (kind === "file") return sha256Hex(readFileSync32(outputPath));
|
|
44489
44650
|
const entries2 = readdirSync19(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
44490
44651
|
const lines = entries2.map(
|
|
44491
|
-
(name) => `${name}\0${sha256Hex(
|
|
44652
|
+
(name) => `${name}\0${sha256Hex(readFileSync32(join55(outputPath, name)))}`
|
|
44492
44653
|
);
|
|
44493
44654
|
return sha256Hex(lines.join("\0"));
|
|
44494
44655
|
}
|
|
@@ -44505,21 +44666,21 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44505
44666
|
const encoderJsonPath = join55(planDir, "meta", "encoder.json");
|
|
44506
44667
|
const chunksJsonPath = join55(planDir, "meta", "chunks.json");
|
|
44507
44668
|
for (const required of [planJsonPath, encoderJsonPath, chunksJsonPath]) {
|
|
44508
|
-
if (!
|
|
44669
|
+
if (!existsSync46(required)) {
|
|
44509
44670
|
throw new RenderChunkValidationError(
|
|
44510
44671
|
MISSING_PLAN_ARTIFACT,
|
|
44511
44672
|
`[renderChunk] planDir is missing required artifact: ${required}`
|
|
44512
44673
|
);
|
|
44513
44674
|
}
|
|
44514
44675
|
}
|
|
44515
|
-
const plan2 = JSON.parse(
|
|
44516
|
-
const encoder = JSON.parse(
|
|
44517
|
-
const chunks = JSON.parse(
|
|
44676
|
+
const plan2 = JSON.parse(readFileSync32(planJsonPath, "utf-8"));
|
|
44677
|
+
const encoder = JSON.parse(readFileSync32(encoderJsonPath, "utf-8"));
|
|
44678
|
+
const chunks = JSON.parse(readFileSync32(chunksJsonPath, "utf-8"));
|
|
44518
44679
|
const videosJsonPath = join55(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
|
|
44519
44680
|
let planVideos = null;
|
|
44520
|
-
if (
|
|
44681
|
+
if (existsSync46(videosJsonPath)) {
|
|
44521
44682
|
try {
|
|
44522
|
-
planVideos = JSON.parse(
|
|
44683
|
+
planVideos = JSON.parse(readFileSync32(videosJsonPath, "utf-8"));
|
|
44523
44684
|
} catch (err) {
|
|
44524
44685
|
throw new RenderChunkValidationError(
|
|
44525
44686
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -44545,7 +44706,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44545
44706
|
);
|
|
44546
44707
|
}
|
|
44547
44708
|
const compiledDir = join55(planDir, "compiled");
|
|
44548
|
-
if (!
|
|
44709
|
+
if (!existsSync46(compiledDir)) {
|
|
44549
44710
|
throw new RenderChunkValidationError(
|
|
44550
44711
|
MISSING_PLAN_ARTIFACT,
|
|
44551
44712
|
`[renderChunk] planDir missing compiled/ directory: ${compiledDir}`
|
|
@@ -44669,10 +44830,10 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
44669
44830
|
const effectiveBitrate = encoder.crf != null ? void 0 : encoder.bitrate;
|
|
44670
44831
|
const videoOnlyPath = outputChunkPath;
|
|
44671
44832
|
if (isPngSequence) {
|
|
44672
|
-
if (!
|
|
44833
|
+
if (!existsSync46(outputChunkPath)) mkdirSync28(outputChunkPath, { recursive: true });
|
|
44673
44834
|
} else {
|
|
44674
44835
|
const outDir = join55(outputChunkPath, "..");
|
|
44675
|
-
if (!
|
|
44836
|
+
if (!existsSync46(outDir)) mkdirSync28(outDir, { recursive: true });
|
|
44676
44837
|
}
|
|
44677
44838
|
await runEncodeStage({
|
|
44678
44839
|
job,
|
|
@@ -44993,9 +45154,9 @@ var init_audioPadTrim = __esm({
|
|
|
44993
45154
|
// ../producer/src/services/distributed/assemble.ts
|
|
44994
45155
|
import {
|
|
44995
45156
|
cpSync as cpSync3,
|
|
44996
|
-
existsSync as
|
|
45157
|
+
existsSync as existsSync47,
|
|
44997
45158
|
mkdirSync as mkdirSync29,
|
|
44998
|
-
readFileSync as
|
|
45159
|
+
readFileSync as readFileSync33,
|
|
44999
45160
|
readdirSync as readdirSync20,
|
|
45000
45161
|
rmSync as rmSync13,
|
|
45001
45162
|
statSync as statSync16,
|
|
@@ -45008,32 +45169,32 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45008
45169
|
const abortSignal = options?.abortSignal;
|
|
45009
45170
|
const planJsonPath = join56(planDir, "plan.json");
|
|
45010
45171
|
const chunksJsonPath = join56(planDir, "meta", "chunks.json");
|
|
45011
|
-
if (!
|
|
45172
|
+
if (!existsSync47(planJsonPath)) {
|
|
45012
45173
|
throw new Error(`[assemble] planDir missing plan.json: ${planJsonPath}`);
|
|
45013
45174
|
}
|
|
45014
|
-
if (!
|
|
45175
|
+
if (!existsSync47(chunksJsonPath)) {
|
|
45015
45176
|
throw new Error(`[assemble] planDir missing meta/chunks.json: ${chunksJsonPath}`);
|
|
45016
45177
|
}
|
|
45017
|
-
const plan2 = JSON.parse(
|
|
45018
|
-
const chunks = JSON.parse(
|
|
45178
|
+
const plan2 = JSON.parse(readFileSync33(planJsonPath, "utf-8"));
|
|
45179
|
+
const chunks = JSON.parse(readFileSync33(chunksJsonPath, "utf-8"));
|
|
45019
45180
|
if (chunkPaths.length !== chunks.length) {
|
|
45020
45181
|
throw new Error(
|
|
45021
45182
|
`[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
|
|
45022
45183
|
);
|
|
45023
45184
|
}
|
|
45024
45185
|
for (const path2 of chunkPaths) {
|
|
45025
|
-
if (!
|
|
45186
|
+
if (!existsSync47(path2)) {
|
|
45026
45187
|
throw new Error(`[assemble] chunk path does not exist: ${path2}`);
|
|
45027
45188
|
}
|
|
45028
45189
|
}
|
|
45029
45190
|
if (plan2.dimensions.format === "png-sequence") {
|
|
45030
45191
|
return mergePngFrameDirs(chunkPaths, outputPath, plan2.totalFrames, audioPath, start);
|
|
45031
45192
|
}
|
|
45032
|
-
if (!
|
|
45193
|
+
if (!existsSync47(dirname18(outputPath))) {
|
|
45033
45194
|
mkdirSync29(dirname18(outputPath), { recursive: true });
|
|
45034
45195
|
}
|
|
45035
45196
|
const workDir = `${outputPath}.assemble-work`;
|
|
45036
|
-
if (
|
|
45197
|
+
if (existsSync47(workDir)) rmSync13(workDir, { recursive: true, force: true });
|
|
45037
45198
|
mkdirSync29(workDir, { recursive: true });
|
|
45038
45199
|
try {
|
|
45039
45200
|
const concatListPath = join56(workDir, "concat-list.txt");
|
|
@@ -45060,7 +45221,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45060
45221
|
);
|
|
45061
45222
|
}
|
|
45062
45223
|
let audioForMux = null;
|
|
45063
|
-
if (audioPath !== null &&
|
|
45224
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45064
45225
|
const paddedAudioPath = join56(workDir, "audio-padded.aac");
|
|
45065
45226
|
const padTrimResult = await padOrTrimAudioToVideoFrameCount({
|
|
45066
45227
|
videoPath: concatOutputPath,
|
|
@@ -45103,7 +45264,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45103
45264
|
});
|
|
45104
45265
|
}
|
|
45105
45266
|
}
|
|
45106
|
-
const fileSize =
|
|
45267
|
+
const fileSize = existsSync47(outputPath) ? statSync16(outputPath).size : 0;
|
|
45107
45268
|
return {
|
|
45108
45269
|
outputPath,
|
|
45109
45270
|
durationMs: Date.now() - start,
|
|
@@ -45112,7 +45273,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
45112
45273
|
};
|
|
45113
45274
|
}
|
|
45114
45275
|
function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, startTimeMs) {
|
|
45115
|
-
if (
|
|
45276
|
+
if (existsSync47(outputPath)) rmSync13(outputPath, { recursive: true, force: true });
|
|
45116
45277
|
mkdirSync29(outputPath, { recursive: true });
|
|
45117
45278
|
let globalIdx = 0;
|
|
45118
45279
|
for (const chunkDir of chunkPaths) {
|
|
@@ -45136,7 +45297,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
45136
45297
|
`[assemble] png-sequence frame count mismatch: merged ${globalIdx} frames vs plan.totalFrames=${totalFrames}. Using on-disk count.`
|
|
45137
45298
|
);
|
|
45138
45299
|
}
|
|
45139
|
-
if (audioPath !== null &&
|
|
45300
|
+
if (audioPath !== null && existsSync47(audioPath)) {
|
|
45140
45301
|
const sidecar = join56(outputPath, "audio.aac");
|
|
45141
45302
|
cpSync3(audioPath, sidecar);
|
|
45142
45303
|
}
|
|
@@ -45229,7 +45390,7 @@ __export(studioServer_exports, {
|
|
|
45229
45390
|
});
|
|
45230
45391
|
import { Hono as Hono5 } from "hono";
|
|
45231
45392
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
45232
|
-
import { existsSync as
|
|
45393
|
+
import { existsSync as existsSync48, readFileSync as readFileSync34, writeFileSync as writeFileSync24, statSync as statSync17 } from "fs";
|
|
45233
45394
|
import { resolve as resolve24, join as join57, basename as basename5 } from "path";
|
|
45234
45395
|
function resolveDistDir() {
|
|
45235
45396
|
return resolveStudioBundle().dir;
|
|
@@ -45237,12 +45398,12 @@ function resolveDistDir() {
|
|
|
45237
45398
|
function resolveStudioBundle() {
|
|
45238
45399
|
const builtPath = resolve24(__dirname, "studio");
|
|
45239
45400
|
const builtIndex = resolve24(builtPath, "index.html");
|
|
45240
|
-
if (
|
|
45401
|
+
if (existsSync48(builtIndex)) {
|
|
45241
45402
|
return { dir: builtPath, indexPath: builtIndex, available: true, checkedPaths: [builtIndex] };
|
|
45242
45403
|
}
|
|
45243
45404
|
const devPath = resolve24(__dirname, "..", "..", "..", "studio", "dist");
|
|
45244
45405
|
const devIndex = resolve24(devPath, "index.html");
|
|
45245
|
-
if (
|
|
45406
|
+
if (existsSync48(devIndex)) {
|
|
45246
45407
|
return {
|
|
45247
45408
|
dir: devPath,
|
|
45248
45409
|
indexPath: devIndex,
|
|
@@ -45259,9 +45420,9 @@ function resolveStudioBundle() {
|
|
|
45259
45420
|
}
|
|
45260
45421
|
function resolveRuntimePath() {
|
|
45261
45422
|
const builtPath = resolve24(__dirname, "hyperframe-runtime.js");
|
|
45262
|
-
if (
|
|
45423
|
+
if (existsSync48(builtPath)) return builtPath;
|
|
45263
45424
|
const iifePath = resolve24(__dirname, "hyperframe.runtime.iife.js");
|
|
45264
|
-
if (
|
|
45425
|
+
if (existsSync48(iifePath)) return iifePath;
|
|
45265
45426
|
const devPath = resolve24(
|
|
45266
45427
|
__dirname,
|
|
45267
45428
|
"..",
|
|
@@ -45271,14 +45432,14 @@ function resolveRuntimePath() {
|
|
|
45271
45432
|
"dist",
|
|
45272
45433
|
"hyperframe.runtime.iife.js"
|
|
45273
45434
|
);
|
|
45274
|
-
if (
|
|
45435
|
+
if (existsSync48(devPath)) return devPath;
|
|
45275
45436
|
return builtPath;
|
|
45276
45437
|
}
|
|
45277
45438
|
function readStudioManualEditManifestContent(projectDir) {
|
|
45278
45439
|
const manifestPath = join57(projectDir, STUDIO_MANUAL_EDITS_PATH2);
|
|
45279
|
-
if (!
|
|
45440
|
+
if (!existsSync48(manifestPath)) return "";
|
|
45280
45441
|
try {
|
|
45281
|
-
return
|
|
45442
|
+
return readFileSync34(manifestPath, "utf-8");
|
|
45282
45443
|
} catch {
|
|
45283
45444
|
return "";
|
|
45284
45445
|
}
|
|
@@ -45519,19 +45680,19 @@ function createStudioServer(options) {
|
|
|
45519
45680
|
async installRegistryBlock(opts) {
|
|
45520
45681
|
const { resolveItem: resolveItem2 } = await Promise.resolve().then(() => (init_resolver(), resolver_exports));
|
|
45521
45682
|
const { installItem: installItem2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
45522
|
-
const { readFileSync:
|
|
45523
|
-
const { join:
|
|
45683
|
+
const { readFileSync: readFileSync57, writeFileSync: writeFileSync39, existsSync: existsSync81 } = await import("fs");
|
|
45684
|
+
const { join: join90 } = await import("path");
|
|
45524
45685
|
const item = await resolveItem2(opts.blockName);
|
|
45525
45686
|
const { written } = await installItem2(item, { destDir: opts.project.dir });
|
|
45526
|
-
const indexPath =
|
|
45527
|
-
if (
|
|
45528
|
-
const indexHtml =
|
|
45687
|
+
const indexPath = join90(opts.project.dir, "index.html");
|
|
45688
|
+
if (existsSync81(indexPath)) {
|
|
45689
|
+
const indexHtml = readFileSync57(indexPath, "utf-8");
|
|
45529
45690
|
const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
|
|
45530
45691
|
const hostH = indexHtml.match(/data-height="(\d+)"/)?.[1];
|
|
45531
45692
|
if (hostW && hostH) {
|
|
45532
45693
|
for (const absPath of written) {
|
|
45533
45694
|
if (!absPath.endsWith(".html")) continue;
|
|
45534
|
-
let content =
|
|
45695
|
+
let content = readFileSync57(absPath, "utf-8");
|
|
45535
45696
|
content = content.replace(
|
|
45536
45697
|
/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+/i,
|
|
45537
45698
|
`$1${hostW}$2${hostH}`
|
|
@@ -45567,7 +45728,7 @@ function createStudioServer(options) {
|
|
|
45567
45728
|
});
|
|
45568
45729
|
app.get("/api/runtime.js", (c3) => {
|
|
45569
45730
|
const serve4 = async () => {
|
|
45570
|
-
const runtimeSource = await loadRuntimeSource() ?? (
|
|
45731
|
+
const runtimeSource = await loadRuntimeSource() ?? (existsSync48(runtimePath) ? readFileSync34(runtimePath, "utf-8") : null);
|
|
45571
45732
|
if (!runtimeSource) return c3.text("runtime not available", 404);
|
|
45572
45733
|
return c3.body(runtimeSource, 200, {
|
|
45573
45734
|
"Content-Type": "text/javascript",
|
|
@@ -45603,8 +45764,8 @@ function createStudioServer(options) {
|
|
|
45603
45764
|
});
|
|
45604
45765
|
const serveStudioStaticFile = (c3) => {
|
|
45605
45766
|
const filePath = resolve24(studioDir, c3.req.path.slice(1));
|
|
45606
|
-
if (!
|
|
45607
|
-
const content =
|
|
45767
|
+
if (!existsSync48(filePath) || !statSync17(filePath).isFile()) return c3.text("not found", 404);
|
|
45768
|
+
const content = readFileSync34(filePath);
|
|
45608
45769
|
return new Response(content, {
|
|
45609
45770
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
45610
45771
|
});
|
|
@@ -45624,7 +45785,7 @@ function createStudioServer(options) {
|
|
|
45624
45785
|
}
|
|
45625
45786
|
app.get("*", (c3) => {
|
|
45626
45787
|
const indexPath = resolve24(studioDir, "index.html");
|
|
45627
|
-
if (!
|
|
45788
|
+
if (!existsSync48(indexPath)) {
|
|
45628
45789
|
return c3.html(
|
|
45629
45790
|
`<!doctype html>
|
|
45630
45791
|
<html>
|
|
@@ -45680,7 +45841,7 @@ function createStudioServer(options) {
|
|
|
45680
45841
|
500
|
|
45681
45842
|
);
|
|
45682
45843
|
}
|
|
45683
|
-
let html =
|
|
45844
|
+
let html = readFileSync34(indexPath, "utf-8");
|
|
45684
45845
|
const envScript = buildRuntimeEnvScript();
|
|
45685
45846
|
if (envScript) {
|
|
45686
45847
|
html = html.replace("<head>", `<head>${envScript}`);
|
|
@@ -45712,7 +45873,7 @@ __export(preview_exports, {
|
|
|
45712
45873
|
examples: () => examples
|
|
45713
45874
|
});
|
|
45714
45875
|
import { spawn as spawn11 } from "child_process";
|
|
45715
|
-
import { existsSync as
|
|
45876
|
+
import { existsSync as existsSync49, lstatSync as lstatSync2, symlinkSync as symlinkSync2, unlinkSync as unlinkSync5, readlinkSync, mkdirSync as mkdirSync30 } from "fs";
|
|
45716
45877
|
import { resolve as resolve25, dirname as dirname19, basename as basename6, join as join58 } from "path";
|
|
45717
45878
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
45718
45879
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -45725,7 +45886,7 @@ async function runDevMode(dir, options) {
|
|
|
45725
45886
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45726
45887
|
let createdSymlink = false;
|
|
45727
45888
|
if (dir !== symlinkPath) {
|
|
45728
|
-
if (
|
|
45889
|
+
if (existsSync49(symlinkPath)) {
|
|
45729
45890
|
try {
|
|
45730
45891
|
const stat3 = lstatSync2(symlinkPath);
|
|
45731
45892
|
if (stat3.isSymbolicLink()) {
|
|
@@ -45737,7 +45898,7 @@ async function runDevMode(dir, options) {
|
|
|
45737
45898
|
} catch {
|
|
45738
45899
|
}
|
|
45739
45900
|
}
|
|
45740
|
-
if (!
|
|
45901
|
+
if (!existsSync49(symlinkPath)) {
|
|
45741
45902
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45742
45903
|
createdSymlink = true;
|
|
45743
45904
|
}
|
|
@@ -45783,7 +45944,7 @@ async function runDevMode(dir, options) {
|
|
|
45783
45944
|
if (createdSymlink) {
|
|
45784
45945
|
process.on("exit", () => {
|
|
45785
45946
|
try {
|
|
45786
|
-
if (
|
|
45947
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45787
45948
|
} catch {
|
|
45788
45949
|
}
|
|
45789
45950
|
});
|
|
@@ -45810,12 +45971,12 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45810
45971
|
mkdirSync30(projectsDir, { recursive: true });
|
|
45811
45972
|
let createdSymlink = false;
|
|
45812
45973
|
if (dir !== symlinkPath) {
|
|
45813
|
-
if (
|
|
45974
|
+
if (existsSync49(symlinkPath) && lstatSync2(symlinkPath).isSymbolicLink()) {
|
|
45814
45975
|
if (resolve25(readlinkSync(symlinkPath)) !== resolve25(dir)) {
|
|
45815
45976
|
unlinkSync5(symlinkPath);
|
|
45816
45977
|
}
|
|
45817
45978
|
}
|
|
45818
|
-
if (!
|
|
45979
|
+
if (!existsSync49(symlinkPath)) {
|
|
45819
45980
|
symlinkSync2(dir, symlinkPath, "dir");
|
|
45820
45981
|
createdSymlink = true;
|
|
45821
45982
|
}
|
|
@@ -45858,7 +46019,7 @@ async function runLocalStudioMode(dir, options) {
|
|
|
45858
46019
|
if (createdSymlink) {
|
|
45859
46020
|
process.on("exit", () => {
|
|
45860
46021
|
try {
|
|
45861
|
-
if (
|
|
46022
|
+
if (existsSync49(symlinkPath)) unlinkSync5(symlinkPath);
|
|
45862
46023
|
} catch {
|
|
45863
46024
|
}
|
|
45864
46025
|
});
|
|
@@ -46059,7 +46220,7 @@ var init_preview2 = __esm({
|
|
|
46059
46220
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
46060
46221
|
const projectName = isImplicitCwd ? basename6(process.env.PWD ?? dir) : basename6(dir);
|
|
46061
46222
|
const indexPath = join58(dir, "index.html");
|
|
46062
|
-
if (
|
|
46223
|
+
if (existsSync49(indexPath)) {
|
|
46063
46224
|
const project = { dir, name: projectName, indexPath };
|
|
46064
46225
|
const lintResult = lintProject(project);
|
|
46065
46226
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
@@ -46104,12 +46265,12 @@ __export(init_exports, {
|
|
|
46104
46265
|
injectTailwindBrowserScript: () => injectTailwindBrowserScript
|
|
46105
46266
|
});
|
|
46106
46267
|
import {
|
|
46107
|
-
existsSync as
|
|
46268
|
+
existsSync as existsSync50,
|
|
46108
46269
|
mkdirSync as mkdirSync31,
|
|
46109
46270
|
copyFileSync as copyFileSync5,
|
|
46110
46271
|
cpSync as cpSync4,
|
|
46111
46272
|
writeFileSync as writeFileSync25,
|
|
46112
|
-
readFileSync as
|
|
46273
|
+
readFileSync as readFileSync35,
|
|
46113
46274
|
readdirSync as readdirSync21
|
|
46114
46275
|
} from "fs";
|
|
46115
46276
|
import { resolve as resolve26, basename as basename7, join as join59, dirname as dirname20 } from "path";
|
|
@@ -46184,7 +46345,7 @@ function resolveAssetDir(devSegments, builtSegments) {
|
|
|
46184
46345
|
const base = dirname20(fileURLToPath7(import.meta.url));
|
|
46185
46346
|
const devPath = resolve26(base, ...devSegments);
|
|
46186
46347
|
const builtPath = resolve26(base, ...builtSegments);
|
|
46187
|
-
return
|
|
46348
|
+
return existsSync50(devPath) ? devPath : builtPath;
|
|
46188
46349
|
}
|
|
46189
46350
|
function getStaticTemplateDir(templateId) {
|
|
46190
46351
|
return resolveAssetDir(["..", "templates", templateId], ["templates", templateId]);
|
|
@@ -46212,7 +46373,7 @@ function buildPackageScripts() {
|
|
|
46212
46373
|
}
|
|
46213
46374
|
function writeDefaultPackageJson(destDir, projectName) {
|
|
46214
46375
|
const packageJsonPath = resolve26(destDir, "package.json");
|
|
46215
|
-
if (
|
|
46376
|
+
if (existsSync50(packageJsonPath)) return;
|
|
46216
46377
|
writeFileSync25(
|
|
46217
46378
|
packageJsonPath,
|
|
46218
46379
|
`${JSON.stringify(
|
|
@@ -46274,14 +46435,14 @@ ${html}`;
|
|
|
46274
46435
|
}
|
|
46275
46436
|
function writeTailwindSupport(destDir) {
|
|
46276
46437
|
for (const file of listHtmlFiles(destDir)) {
|
|
46277
|
-
const html =
|
|
46438
|
+
const html = readFileSync35(file, "utf-8");
|
|
46278
46439
|
writeFileSync25(file, injectTailwindBrowserScript(html), "utf-8");
|
|
46279
46440
|
}
|
|
46280
46441
|
}
|
|
46281
46442
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
46282
46443
|
const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join59(e3.parentPath, e3.name));
|
|
46283
46444
|
for (const file of htmlFiles) {
|
|
46284
|
-
let content =
|
|
46445
|
+
let content = readFileSync35(file, "utf-8");
|
|
46285
46446
|
if (videoFilename) {
|
|
46286
46447
|
content = content.replaceAll("__VIDEO_SRC__", videoFilename);
|
|
46287
46448
|
} else {
|
|
@@ -46386,7 +46547,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
|
|
|
46386
46547
|
function applyResolutionPreset(destDir, resolution) {
|
|
46387
46548
|
const { width, height } = CANVAS_DIMENSIONS[resolution];
|
|
46388
46549
|
for (const file of listHtmlFiles(destDir)) {
|
|
46389
|
-
let html =
|
|
46550
|
+
let html = readFileSync35(file, "utf-8");
|
|
46390
46551
|
let changed = false;
|
|
46391
46552
|
const dataWidthRe = /(data-width=)["'](\d+)["']/g;
|
|
46392
46553
|
if (dataWidthRe.test(html)) {
|
|
@@ -46434,7 +46595,7 @@ function applyResolutionPreset(destDir, resolution) {
|
|
|
46434
46595
|
async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
|
|
46435
46596
|
mkdirSync31(destDir, { recursive: true });
|
|
46436
46597
|
const templateDir = getStaticTemplateDir(templateId);
|
|
46437
|
-
if (
|
|
46598
|
+
if (existsSync50(join59(templateDir, "index.html"))) {
|
|
46438
46599
|
cpSync4(templateDir, destDir, { recursive: true });
|
|
46439
46600
|
} else {
|
|
46440
46601
|
await fetchRemoteTemplate(templateId, destDir);
|
|
@@ -46455,13 +46616,13 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
46455
46616
|
),
|
|
46456
46617
|
"utf-8"
|
|
46457
46618
|
);
|
|
46458
|
-
if (!
|
|
46619
|
+
if (!existsSync50(resolve26(destDir, "hyperframes.json"))) {
|
|
46459
46620
|
const { writeProjectConfig: writeProjectConfig2, DEFAULT_PROJECT_CONFIG: DEFAULT_PROJECT_CONFIG2 } = await Promise.resolve().then(() => (init_projectConfig(), projectConfig_exports));
|
|
46460
46621
|
writeProjectConfig2(destDir, DEFAULT_PROJECT_CONFIG2);
|
|
46461
46622
|
}
|
|
46462
46623
|
writeDefaultPackageJson(destDir, name);
|
|
46463
46624
|
const sharedDir = getSharedTemplateDir();
|
|
46464
|
-
if (
|
|
46625
|
+
if (existsSync50(sharedDir)) {
|
|
46465
46626
|
for (const entry of readdirSync21(sharedDir, { withFileTypes: true })) {
|
|
46466
46627
|
const src = join59(sharedDir, entry.name);
|
|
46467
46628
|
const dest = resolve26(destDir, entry.name);
|
|
@@ -46621,7 +46782,7 @@ var init_init = __esm({
|
|
|
46621
46782
|
const templateId2 = exampleFlag ?? "blank";
|
|
46622
46783
|
const name2 = args.name ?? "my-video";
|
|
46623
46784
|
const destDir2 = resolve26(name2);
|
|
46624
|
-
if (
|
|
46785
|
+
if (existsSync50(destDir2) && readdirSync21(destDir2).length > 0) {
|
|
46625
46786
|
console.error(c2.error(`Directory already exists and is not empty: ${name2}`));
|
|
46626
46787
|
process.exit(1);
|
|
46627
46788
|
}
|
|
@@ -46635,7 +46796,7 @@ var init_init = __esm({
|
|
|
46635
46796
|
}
|
|
46636
46797
|
if (videoFlag) {
|
|
46637
46798
|
const videoPath = resolve26(videoFlag);
|
|
46638
|
-
if (!
|
|
46799
|
+
if (!existsSync50(videoPath)) {
|
|
46639
46800
|
console.error(c2.error(`Video file not found: ${videoFlag}`));
|
|
46640
46801
|
process.exit(1);
|
|
46641
46802
|
}
|
|
@@ -46649,7 +46810,7 @@ var init_init = __esm({
|
|
|
46649
46810
|
}
|
|
46650
46811
|
if (audioFlag) {
|
|
46651
46812
|
const audioPath = resolve26(audioFlag);
|
|
46652
|
-
if (!
|
|
46813
|
+
if (!existsSync50(audioPath)) {
|
|
46653
46814
|
console.error(c2.error(`Audio file not found: ${audioFlag}`));
|
|
46654
46815
|
process.exit(1);
|
|
46655
46816
|
}
|
|
@@ -46697,7 +46858,7 @@ var init_init = __esm({
|
|
|
46697
46858
|
}
|
|
46698
46859
|
trackInitTemplate(templateId2, { tailwind });
|
|
46699
46860
|
const transcriptFile2 = resolve26(destDir2, "transcript.json");
|
|
46700
|
-
if (
|
|
46861
|
+
if (existsSync50(transcriptFile2)) {
|
|
46701
46862
|
await patchTranscript(destDir2, transcriptFile2);
|
|
46702
46863
|
}
|
|
46703
46864
|
console.log(c2.success(`Created ${c2.accent(name2 + "/")}`));
|
|
@@ -46752,7 +46913,7 @@ var init_init = __esm({
|
|
|
46752
46913
|
name = nameResult;
|
|
46753
46914
|
}
|
|
46754
46915
|
const destDir = resolve26(name);
|
|
46755
|
-
if (
|
|
46916
|
+
if (existsSync50(destDir) && readdirSync21(destDir).length > 0) {
|
|
46756
46917
|
const overwrite = await ue({
|
|
46757
46918
|
message: `Directory ${c2.accent(name)} already exists and is not empty. Overwrite?`,
|
|
46758
46919
|
initialValue: false
|
|
@@ -46767,7 +46928,7 @@ var init_init = __esm({
|
|
|
46767
46928
|
let videoDuration;
|
|
46768
46929
|
if (videoFlag) {
|
|
46769
46930
|
const videoPath = resolve26(videoFlag);
|
|
46770
|
-
if (!
|
|
46931
|
+
if (!existsSync50(videoPath)) {
|
|
46771
46932
|
R2.error(`File not found: ${videoFlag}`);
|
|
46772
46933
|
me("Setup cancelled.");
|
|
46773
46934
|
process.exit(1);
|
|
@@ -46779,7 +46940,7 @@ var init_init = __esm({
|
|
|
46779
46940
|
videoDuration = result.meta.durationSeconds;
|
|
46780
46941
|
} else if (audioFlag) {
|
|
46781
46942
|
const audioPath = resolve26(audioFlag);
|
|
46782
|
-
if (!
|
|
46943
|
+
if (!existsSync50(audioPath)) {
|
|
46783
46944
|
R2.error(`File not found: ${audioFlag}`);
|
|
46784
46945
|
me("Setup cancelled.");
|
|
46785
46946
|
process.exit(1);
|
|
@@ -46880,7 +47041,7 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46880
47041
|
}
|
|
46881
47042
|
trackInitTemplate(templateId, { tailwind });
|
|
46882
47043
|
const transcriptFile = resolve26(destDir, "transcript.json");
|
|
46883
|
-
if (
|
|
47044
|
+
if (existsSync50(transcriptFile)) {
|
|
46884
47045
|
await patchTranscript(destDir, transcriptFile);
|
|
46885
47046
|
}
|
|
46886
47047
|
const files = readdirSync21(destDir);
|
|
@@ -46912,9 +47073,9 @@ ${c2.dim("Use --example blank for offline use.")}`
|
|
|
46912
47073
|
|
|
46913
47074
|
// src/utils/clipboard.ts
|
|
46914
47075
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
46915
|
-
import { platform as
|
|
47076
|
+
import { platform as platform6 } from "os";
|
|
46916
47077
|
function detectProvider() {
|
|
46917
|
-
const os =
|
|
47078
|
+
const os = platform6();
|
|
46918
47079
|
if (os === "darwin") {
|
|
46919
47080
|
return { cmd: "pbcopy", args: [] };
|
|
46920
47081
|
}
|
|
@@ -46966,7 +47127,7 @@ __export(add_exports, {
|
|
|
46966
47127
|
remapTarget: () => remapTarget,
|
|
46967
47128
|
runAdd: () => runAdd
|
|
46968
47129
|
});
|
|
46969
|
-
import { existsSync as
|
|
47130
|
+
import { existsSync as existsSync51 } from "fs";
|
|
46970
47131
|
import { resolve as resolve27, relative as relative7 } from "path";
|
|
46971
47132
|
function remapTarget(item, originalTarget, paths) {
|
|
46972
47133
|
if (item.type === "hyperframes:block") {
|
|
@@ -46992,8 +47153,8 @@ function buildSnippet(item, relativeTarget) {
|
|
|
46992
47153
|
async function runAdd(opts) {
|
|
46993
47154
|
const projectDir = resolve27(opts.projectDir);
|
|
46994
47155
|
let config = loadProjectConfig(projectDir);
|
|
46995
|
-
const hasConfig =
|
|
46996
|
-
if (!hasConfig &&
|
|
47156
|
+
const hasConfig = existsSync51(projectConfigPath(projectDir));
|
|
47157
|
+
if (!hasConfig && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
46997
47158
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
46998
47159
|
config = DEFAULT_PROJECT_CONFIG;
|
|
46999
47160
|
}
|
|
@@ -47095,10 +47256,10 @@ var init_add = __esm({
|
|
|
47095
47256
|
const projectDir = resolve27(args.dir ?? process.cwd());
|
|
47096
47257
|
const json = args.json === true;
|
|
47097
47258
|
const skipClipboard = args["no-clipboard"] === true;
|
|
47098
|
-
const hasConfigBefore =
|
|
47259
|
+
const hasConfigBefore = existsSync51(projectConfigPath(projectDir));
|
|
47099
47260
|
try {
|
|
47100
47261
|
const result = await runAdd({ name: args.name, projectDir, skipClipboard });
|
|
47101
|
-
const wroteConfig = !hasConfigBefore &&
|
|
47262
|
+
const wroteConfig = !hasConfigBefore && existsSync51(projectConfigPath(projectDir));
|
|
47102
47263
|
if (json) {
|
|
47103
47264
|
console.log(JSON.stringify(result));
|
|
47104
47265
|
return;
|
|
@@ -47128,7 +47289,7 @@ var init_add = __esm({
|
|
|
47128
47289
|
process.exit(1);
|
|
47129
47290
|
}
|
|
47130
47291
|
let config = loadProjectConfig(projectDir);
|
|
47131
|
-
if (!
|
|
47292
|
+
if (!existsSync51(projectConfigPath(projectDir)) && existsSync51(resolve27(projectDir, "index.html"))) {
|
|
47132
47293
|
writeProjectConfig(projectDir, DEFAULT_PROJECT_CONFIG);
|
|
47133
47294
|
config = DEFAULT_PROJECT_CONFIG;
|
|
47134
47295
|
}
|
|
@@ -47348,17 +47509,17 @@ var init_format = __esm({
|
|
|
47348
47509
|
});
|
|
47349
47510
|
|
|
47350
47511
|
// src/utils/project.ts
|
|
47351
|
-
import { existsSync as
|
|
47512
|
+
import { existsSync as existsSync52, statSync as statSync18 } from "fs";
|
|
47352
47513
|
import { resolve as resolve29, basename as basename8 } from "path";
|
|
47353
47514
|
function resolveProject(dirArg) {
|
|
47354
47515
|
const dir = resolve29(dirArg ?? ".");
|
|
47355
47516
|
const name = basename8(dir);
|
|
47356
47517
|
const indexPath = resolve29(dir, "index.html");
|
|
47357
|
-
if (!
|
|
47518
|
+
if (!existsSync52(dir) || !statSync18(dir).isDirectory()) {
|
|
47358
47519
|
errorBox("Not a directory: " + dir);
|
|
47359
47520
|
process.exit(1);
|
|
47360
47521
|
}
|
|
47361
|
-
if (!
|
|
47522
|
+
if (!existsSync52(indexPath)) {
|
|
47362
47523
|
errorBox(
|
|
47363
47524
|
"No composition found in " + dir,
|
|
47364
47525
|
"No index.html file found.",
|
|
@@ -47381,7 +47542,7 @@ __export(play_exports, {
|
|
|
47381
47542
|
default: () => play_default,
|
|
47382
47543
|
examples: () => examples5
|
|
47383
47544
|
});
|
|
47384
|
-
import { existsSync as
|
|
47545
|
+
import { existsSync as existsSync53, readFileSync as readFileSync36 } from "fs";
|
|
47385
47546
|
import { resolve as resolve30, dirname as dirname21 } from "path";
|
|
47386
47547
|
function commandDir() {
|
|
47387
47548
|
return dirname21(new URL(import.meta.url).pathname);
|
|
@@ -47396,7 +47557,7 @@ function resolveRuntimePath2() {
|
|
|
47396
47557
|
resolve30(d2, "..", "..", "..", "core", "dist", "hyperframe.runtime.iife.js")
|
|
47397
47558
|
];
|
|
47398
47559
|
for (const p2 of candidates) {
|
|
47399
|
-
if (
|
|
47560
|
+
if (existsSync53(p2)) return p2;
|
|
47400
47561
|
}
|
|
47401
47562
|
return null;
|
|
47402
47563
|
}
|
|
@@ -47410,7 +47571,7 @@ function resolvePlayerPath() {
|
|
|
47410
47571
|
resolve30(d2, "..", "hyperframes-player.global.js")
|
|
47411
47572
|
];
|
|
47412
47573
|
for (const p2 of candidates) {
|
|
47413
|
-
if (
|
|
47574
|
+
if (existsSync53(p2)) return p2;
|
|
47414
47575
|
}
|
|
47415
47576
|
return null;
|
|
47416
47577
|
}
|
|
@@ -47520,13 +47681,13 @@ var init_play = __esm({
|
|
|
47520
47681
|
const { createAdaptorServer } = await import("@hono/node-server");
|
|
47521
47682
|
const app = new Hono6();
|
|
47522
47683
|
app.get("/player.js", (ctx) => {
|
|
47523
|
-
return ctx.body(
|
|
47684
|
+
return ctx.body(readFileSync36(playerPath, "utf-8"), 200, {
|
|
47524
47685
|
"Content-Type": "application/javascript",
|
|
47525
47686
|
"Cache-Control": "no-cache"
|
|
47526
47687
|
});
|
|
47527
47688
|
});
|
|
47528
47689
|
app.get("/runtime.js", (ctx) => {
|
|
47529
|
-
return ctx.body(
|
|
47690
|
+
return ctx.body(readFileSync36(runtimePath, "utf-8"), 200, {
|
|
47530
47691
|
"Content-Type": "application/javascript",
|
|
47531
47692
|
"Cache-Control": "no-cache"
|
|
47532
47693
|
});
|
|
@@ -47535,8 +47696,8 @@ var init_play = __esm({
|
|
|
47535
47696
|
const reqPath = ctx.req.path.replace("/composition/", "");
|
|
47536
47697
|
const filePath = resolve30(project.dir, reqPath);
|
|
47537
47698
|
if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
|
|
47538
|
-
if (!
|
|
47539
|
-
const content =
|
|
47699
|
+
if (!existsSync53(filePath)) return ctx.text("Not found", 404);
|
|
47700
|
+
const content = readFileSync36(filePath, "utf-8");
|
|
47540
47701
|
if (filePath.endsWith(".html")) {
|
|
47541
47702
|
const injected = injectRuntime(content);
|
|
47542
47703
|
return ctx.html(injected);
|
|
@@ -47555,7 +47716,7 @@ var init_play = __esm({
|
|
|
47555
47716
|
mp3: "audio/mpeg",
|
|
47556
47717
|
wav: "audio/wav"
|
|
47557
47718
|
};
|
|
47558
|
-
return ctx.body(
|
|
47719
|
+
return ctx.body(readFileSync36(filePath), 200, {
|
|
47559
47720
|
"Content-Type": types3[ext] ?? "application/octet-stream"
|
|
47560
47721
|
});
|
|
47561
47722
|
});
|
|
@@ -47616,7 +47777,7 @@ var init_play = __esm({
|
|
|
47616
47777
|
|
|
47617
47778
|
// src/utils/publishProject.ts
|
|
47618
47779
|
import { basename as basename9, join as join60, relative as relative8 } from "path";
|
|
47619
|
-
import { readdirSync as readdirSync22, readFileSync as
|
|
47780
|
+
import { readdirSync as readdirSync22, readFileSync as readFileSync37, statSync as statSync19 } from "fs";
|
|
47620
47781
|
import AdmZip from "adm-zip";
|
|
47621
47782
|
function isRecord2(value) {
|
|
47622
47783
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -47735,7 +47896,7 @@ function createPublishArchive(projectDir) {
|
|
|
47735
47896
|
}
|
|
47736
47897
|
const archive = new AdmZip();
|
|
47737
47898
|
for (const filePath of filePaths) {
|
|
47738
|
-
archive.addFile(filePath,
|
|
47899
|
+
archive.addFile(filePath, readFileSync37(join60(projectDir, filePath)));
|
|
47739
47900
|
}
|
|
47740
47901
|
return {
|
|
47741
47902
|
buffer: archive.toBuffer(),
|
|
@@ -47856,7 +48017,7 @@ __export(publish_exports, {
|
|
|
47856
48017
|
examples: () => examples6
|
|
47857
48018
|
});
|
|
47858
48019
|
import { basename as basename10, resolve as resolve31 } from "path";
|
|
47859
|
-
import { existsSync as
|
|
48020
|
+
import { existsSync as existsSync54 } from "fs";
|
|
47860
48021
|
import { join as join61 } from "path";
|
|
47861
48022
|
var examples6, publish_default;
|
|
47862
48023
|
var init_publish = __esm({
|
|
@@ -47893,7 +48054,7 @@ var init_publish = __esm({
|
|
|
47893
48054
|
const isImplicitCwd = !rawArg || rawArg === "." || rawArg === "./";
|
|
47894
48055
|
const projectName = isImplicitCwd ? basename10(process.env["PWD"] ?? dir) : basename10(dir);
|
|
47895
48056
|
const indexPath = join61(dir, "index.html");
|
|
47896
|
-
if (
|
|
48057
|
+
if (existsSync54(indexPath)) {
|
|
47897
48058
|
const lintResult = lintProject({ dir, name: projectName, indexPath });
|
|
47898
48059
|
if (lintResult.totalErrors > 0 || lintResult.totalWarnings > 0) {
|
|
47899
48060
|
console.log();
|
|
@@ -47963,9 +48124,9 @@ var init_dom = __esm({
|
|
|
47963
48124
|
});
|
|
47964
48125
|
|
|
47965
48126
|
// src/utils/variables.ts
|
|
47966
|
-
import { readFileSync as
|
|
48127
|
+
import { readFileSync as readFileSync38 } from "fs";
|
|
47967
48128
|
import { resolve as resolve32 } from "path";
|
|
47968
|
-
function parseVariablesArg(inline, filePath, readFile = (p2) =>
|
|
48129
|
+
function parseVariablesArg(inline, filePath, readFile = (p2) => readFileSync38(resolve32(p2), "utf8")) {
|
|
47969
48130
|
if (inline != null && filePath != null) {
|
|
47970
48131
|
return { ok: false, error: { kind: "conflict" } };
|
|
47971
48132
|
}
|
|
@@ -48048,7 +48209,7 @@ function validateVariablesAgainstProject(indexPath, values) {
|
|
|
48048
48209
|
function loadProjectVariableSchema(indexPath) {
|
|
48049
48210
|
let html;
|
|
48050
48211
|
try {
|
|
48051
|
-
html =
|
|
48212
|
+
html = readFileSync38(indexPath, "utf8");
|
|
48052
48213
|
} catch {
|
|
48053
48214
|
return [];
|
|
48054
48215
|
}
|
|
@@ -48215,7 +48376,7 @@ __export(render_exports, {
|
|
|
48215
48376
|
renderLocal: () => renderLocal,
|
|
48216
48377
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
48217
48378
|
});
|
|
48218
|
-
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as
|
|
48379
|
+
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as readFileSync39, statSync as statSync20, writeFileSync as writeFileSync26, rmSync as rmSync14 } from "fs";
|
|
48219
48380
|
import { cpus as cpus4, freemem as freemem4, tmpdir as tmpdir5 } from "os";
|
|
48220
48381
|
import { resolve as resolve33, dirname as dirname22, join as join62, basename as basename11 } from "path";
|
|
48221
48382
|
import { execFileSync as execFileSync6, spawn as spawn13 } from "child_process";
|
|
@@ -48276,7 +48437,7 @@ function ensureDockerImage(version, quiet) {
|
|
|
48276
48437
|
const dockerfilePath = resolveDockerfilePath();
|
|
48277
48438
|
const tmpDir = join62(tmpdir5(), `hyperframes-docker-${Date.now()}`);
|
|
48278
48439
|
mkdirSync32(tmpDir, { recursive: true });
|
|
48279
|
-
writeFileSync26(join62(tmpDir, "Dockerfile"),
|
|
48440
|
+
writeFileSync26(join62(tmpDir, "Dockerfile"), readFileSync39(dockerfilePath));
|
|
48280
48441
|
try {
|
|
48281
48442
|
execFileSync6(
|
|
48282
48443
|
"docker",
|
|
@@ -49135,7 +49296,7 @@ var init_lint3 = __esm({
|
|
|
49135
49296
|
|
|
49136
49297
|
// src/utils/staticProjectServer.ts
|
|
49137
49298
|
import { createServer } from "http";
|
|
49138
|
-
import { existsSync as
|
|
49299
|
+
import { existsSync as existsSync55, readFileSync as readFileSync40 } from "fs";
|
|
49139
49300
|
import { isAbsolute as isAbsolute8, relative as relative9, resolve as resolve34 } from "path";
|
|
49140
49301
|
async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Failed to bind local HTTP server") {
|
|
49141
49302
|
const server = createServer((req, res) => {
|
|
@@ -49152,9 +49313,9 @@ async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Fail
|
|
|
49152
49313
|
res.end();
|
|
49153
49314
|
return;
|
|
49154
49315
|
}
|
|
49155
|
-
if (
|
|
49316
|
+
if (existsSync55(filePath)) {
|
|
49156
49317
|
res.writeHead(200, { "Content-Type": getMimeType(filePath) });
|
|
49157
|
-
res.end(
|
|
49318
|
+
res.end(readFileSync40(filePath));
|
|
49158
49319
|
return;
|
|
49159
49320
|
}
|
|
49160
49321
|
res.writeHead(404);
|
|
@@ -49330,7 +49491,7 @@ __export(layout_exports, {
|
|
|
49330
49491
|
default: () => layout_default,
|
|
49331
49492
|
examples: () => examples9
|
|
49332
49493
|
});
|
|
49333
|
-
import { existsSync as
|
|
49494
|
+
import { existsSync as existsSync56, readFileSync as readFileSync41 } from "fs";
|
|
49334
49495
|
import { dirname as dirname23, join as join63 } from "path";
|
|
49335
49496
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
49336
49497
|
async function getCompositionDuration2(page) {
|
|
@@ -49481,7 +49642,7 @@ function loadLayoutAuditScript() {
|
|
|
49481
49642
|
join63(__dirname2, "commands", "layout-audit.browser.js")
|
|
49482
49643
|
];
|
|
49483
49644
|
for (const candidate of candidates) {
|
|
49484
|
-
if (
|
|
49645
|
+
if (existsSync56(candidate)) return readFileSync41(candidate, "utf-8");
|
|
49485
49646
|
}
|
|
49486
49647
|
throw new Error("Missing layout audit browser script");
|
|
49487
49648
|
}
|
|
@@ -49689,7 +49850,7 @@ __export(info_exports, {
|
|
|
49689
49850
|
default: () => info_default,
|
|
49690
49851
|
examples: () => examples11
|
|
49691
49852
|
});
|
|
49692
|
-
import { readFileSync as
|
|
49853
|
+
import { readFileSync as readFileSync42, readdirSync as readdirSync24, statSync as statSync21 } from "fs";
|
|
49693
49854
|
import { join as join64 } from "path";
|
|
49694
49855
|
function totalSize(dir) {
|
|
49695
49856
|
let total = 0;
|
|
@@ -49726,7 +49887,7 @@ var init_info = __esm({
|
|
|
49726
49887
|
},
|
|
49727
49888
|
async run({ args }) {
|
|
49728
49889
|
const project = resolveProject(args.dir);
|
|
49729
|
-
const html =
|
|
49890
|
+
const html = readFileSync42(project.indexPath, "utf-8");
|
|
49730
49891
|
ensureDOMParser();
|
|
49731
49892
|
const parsed = parseHtml(html);
|
|
49732
49893
|
const tracks = new Set(parsed.elements.map((el) => el.zIndex));
|
|
@@ -49784,7 +49945,7 @@ __export(compositions_exports, {
|
|
|
49784
49945
|
examples: () => examples12,
|
|
49785
49946
|
parseSubComposition: () => parseSubComposition
|
|
49786
49947
|
});
|
|
49787
|
-
import { existsSync as
|
|
49948
|
+
import { existsSync as existsSync57, readFileSync as readFileSync43 } from "fs";
|
|
49788
49949
|
import { resolve as resolve35, dirname as dirname24 } from "path";
|
|
49789
49950
|
function countRenderableDescendants(root) {
|
|
49790
49951
|
return Array.from(root.querySelectorAll("*")).filter(
|
|
@@ -49818,8 +49979,8 @@ function parseCompositions(html, baseDir) {
|
|
|
49818
49979
|
const compositionSrc = div.getAttribute("data-composition-src");
|
|
49819
49980
|
if (compositionSrc) {
|
|
49820
49981
|
const subPath = resolve35(baseDir, compositionSrc);
|
|
49821
|
-
if (
|
|
49822
|
-
const subHtml =
|
|
49982
|
+
if (existsSync57(subPath)) {
|
|
49983
|
+
const subHtml = readFileSync43(subPath, "utf-8");
|
|
49823
49984
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
49824
49985
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
49825
49986
|
return;
|
|
@@ -49922,7 +50083,7 @@ var init_compositions = __esm({
|
|
|
49922
50083
|
},
|
|
49923
50084
|
async run({ args }) {
|
|
49924
50085
|
const project = resolveProject(args.dir);
|
|
49925
|
-
const html =
|
|
50086
|
+
const html = readFileSync43(project.indexPath, "utf-8");
|
|
49926
50087
|
ensureDOMParser();
|
|
49927
50088
|
const compositions = parseCompositions(html, dirname24(project.indexPath));
|
|
49928
50089
|
if (compositions.length === 0) {
|
|
@@ -49960,7 +50121,7 @@ __export(benchmark_exports, {
|
|
|
49960
50121
|
default: () => benchmark_default,
|
|
49961
50122
|
examples: () => examples13
|
|
49962
50123
|
});
|
|
49963
|
-
import { existsSync as
|
|
50124
|
+
import { existsSync as existsSync58, statSync as statSync22 } from "fs";
|
|
49964
50125
|
import { resolve as resolve36, join as join65 } from "path";
|
|
49965
50126
|
var examples13, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
|
|
49966
50127
|
var init_benchmark = __esm({
|
|
@@ -50053,7 +50214,7 @@ var init_benchmark = __esm({
|
|
|
50053
50214
|
await producer.executeRenderJob(job, project.dir, outputPath);
|
|
50054
50215
|
const elapsedMs = Date.now() - startTime;
|
|
50055
50216
|
let fileSize = null;
|
|
50056
|
-
if (
|
|
50217
|
+
if (existsSync58(outputPath)) {
|
|
50057
50218
|
const stat3 = statSync22(outputPath);
|
|
50058
50219
|
fileSize = stat3.size;
|
|
50059
50220
|
}
|
|
@@ -50307,8 +50468,8 @@ __export(manager_exports3, {
|
|
|
50307
50468
|
modelPath: () => modelPath,
|
|
50308
50469
|
selectProviders: () => selectProviders
|
|
50309
50470
|
});
|
|
50310
|
-
import { existsSync as
|
|
50311
|
-
import { homedir as homedir9, platform as
|
|
50471
|
+
import { existsSync as existsSync59, mkdirSync as mkdirSync33 } from "fs";
|
|
50472
|
+
import { homedir as homedir9, platform as platform7, arch } from "os";
|
|
50312
50473
|
import { join as join66 } from "path";
|
|
50313
50474
|
function isDevice(value) {
|
|
50314
50475
|
return typeof value === "string" && DEVICES.includes(value);
|
|
@@ -50334,7 +50495,7 @@ function selectProviders(device = "auto") {
|
|
|
50334
50495
|
}
|
|
50335
50496
|
return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
50336
50497
|
}
|
|
50337
|
-
if (hasCoreML &&
|
|
50498
|
+
if (hasCoreML && platform7() === "darwin" && arch() === "arm64") {
|
|
50338
50499
|
return { providers: ["coreml", "cpu"], label: "CoreML" };
|
|
50339
50500
|
}
|
|
50340
50501
|
if (hasCUDA) return { providers: ["cuda", "cpu"], label: "CUDA" };
|
|
@@ -50343,7 +50504,7 @@ function selectProviders(device = "auto") {
|
|
|
50343
50504
|
function listAvailableProviders() {
|
|
50344
50505
|
if (_cachedProviders) return _cachedProviders;
|
|
50345
50506
|
const out = ["cpu"];
|
|
50346
|
-
if (
|
|
50507
|
+
if (platform7() === "darwin" && arch() === "arm64") out.push("coreml");
|
|
50347
50508
|
if (process.env["HYPERFRAMES_CUDA"] === "1") out.push("cuda");
|
|
50348
50509
|
_cachedProviders = out;
|
|
50349
50510
|
return out;
|
|
@@ -50353,11 +50514,11 @@ function modelPath(model = DEFAULT_MODEL2) {
|
|
|
50353
50514
|
}
|
|
50354
50515
|
async function ensureModel2(model = DEFAULT_MODEL2, options) {
|
|
50355
50516
|
const dest = modelPath(model);
|
|
50356
|
-
if (
|
|
50517
|
+
if (existsSync59(dest)) return dest;
|
|
50357
50518
|
mkdirSync33(MODELS_DIR2, { recursive: true });
|
|
50358
50519
|
options?.onProgress?.(`Downloading ${model} weights (~168 MB)...`);
|
|
50359
50520
|
await downloadFile(MODEL_URLS[model], dest);
|
|
50360
|
-
if (!
|
|
50521
|
+
if (!existsSync59(dest)) {
|
|
50361
50522
|
throw new Error(`Model download failed: ${model}`);
|
|
50362
50523
|
}
|
|
50363
50524
|
return dest;
|
|
@@ -50838,12 +50999,12 @@ __export(remove_background_exports, {
|
|
|
50838
50999
|
examples: () => examples15
|
|
50839
51000
|
});
|
|
50840
51001
|
import { resolve as resolve37 } from "path";
|
|
50841
|
-
import { existsSync as
|
|
51002
|
+
import { existsSync as existsSync60 } from "fs";
|
|
50842
51003
|
async function showInfo(json) {
|
|
50843
51004
|
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
51005
|
const providers = listAvailableProviders2();
|
|
50845
51006
|
const auto = selectProviders2("auto");
|
|
50846
|
-
const cached2 =
|
|
51007
|
+
const cached2 = existsSync60(modelPath2());
|
|
50847
51008
|
if (json) {
|
|
50848
51009
|
console.log(
|
|
50849
51010
|
JSON.stringify({
|
|
@@ -51050,7 +51211,7 @@ __export(transcribe_exports2, {
|
|
|
51050
51211
|
default: () => transcribe_default,
|
|
51051
51212
|
examples: () => examples16
|
|
51052
51213
|
});
|
|
51053
|
-
import { existsSync as
|
|
51214
|
+
import { existsSync as existsSync61, writeFileSync as writeFileSync27 } from "fs";
|
|
51054
51215
|
import { resolve as resolve38, join as join67, extname as extname11, dirname as dirname25 } from "path";
|
|
51055
51216
|
async function importTranscript(inputPath, dir, json) {
|
|
51056
51217
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
@@ -51176,7 +51337,7 @@ var init_transcribe2 = __esm({
|
|
|
51176
51337
|
},
|
|
51177
51338
|
async run({ args }) {
|
|
51178
51339
|
const inputPath = resolve38(args.input);
|
|
51179
|
-
if (!
|
|
51340
|
+
if (!existsSync61(inputPath)) {
|
|
51180
51341
|
console.error(c2.error(`File not found: ${args.input}`));
|
|
51181
51342
|
process.exit(1);
|
|
51182
51343
|
}
|
|
@@ -51197,7 +51358,7 @@ var init_transcribe2 = __esm({
|
|
|
51197
51358
|
});
|
|
51198
51359
|
|
|
51199
51360
|
// src/tts/manager.ts
|
|
51200
|
-
import { existsSync as
|
|
51361
|
+
import { existsSync as existsSync62, mkdirSync as mkdirSync34 } from "fs";
|
|
51201
51362
|
import { homedir as homedir10 } from "os";
|
|
51202
51363
|
import { join as join68 } from "path";
|
|
51203
51364
|
function inferLangFromVoiceId(voiceId) {
|
|
@@ -51209,7 +51370,7 @@ function isSupportedLang(value) {
|
|
|
51209
51370
|
}
|
|
51210
51371
|
async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
51211
51372
|
const modelPath2 = join68(MODELS_DIR3, `${model}.onnx`);
|
|
51212
|
-
if (
|
|
51373
|
+
if (existsSync62(modelPath2)) return modelPath2;
|
|
51213
51374
|
const url = MODEL_URLS2[model];
|
|
51214
51375
|
if (!url) {
|
|
51215
51376
|
throw new Error(
|
|
@@ -51219,18 +51380,18 @@ async function ensureModel3(model = DEFAULT_MODEL3, options) {
|
|
|
51219
51380
|
mkdirSync34(MODELS_DIR3, { recursive: true });
|
|
51220
51381
|
options?.onProgress?.(`Downloading TTS model ${model} (~311 MB)...`);
|
|
51221
51382
|
await downloadFile(url, modelPath2);
|
|
51222
|
-
if (!
|
|
51383
|
+
if (!existsSync62(modelPath2)) {
|
|
51223
51384
|
throw new Error(`Model download failed: ${model}`);
|
|
51224
51385
|
}
|
|
51225
51386
|
return modelPath2;
|
|
51226
51387
|
}
|
|
51227
51388
|
async function ensureVoices(options) {
|
|
51228
51389
|
const voicesPath = join68(VOICES_DIR, "voices-v1.0.bin");
|
|
51229
|
-
if (
|
|
51390
|
+
if (existsSync62(voicesPath)) return voicesPath;
|
|
51230
51391
|
mkdirSync34(VOICES_DIR, { recursive: true });
|
|
51231
51392
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
51232
51393
|
await downloadFile(VOICES_URL, voicesPath);
|
|
51233
|
-
if (!
|
|
51394
|
+
if (!existsSync62(voicesPath)) {
|
|
51234
51395
|
throw new Error("Voice data download failed");
|
|
51235
51396
|
}
|
|
51236
51397
|
return voicesPath;
|
|
@@ -51303,7 +51464,7 @@ __export(synthesize_exports, {
|
|
|
51303
51464
|
synthesize: () => synthesize
|
|
51304
51465
|
});
|
|
51305
51466
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
51306
|
-
import { existsSync as
|
|
51467
|
+
import { existsSync as existsSync63, writeFileSync as writeFileSync28, mkdirSync as mkdirSync35, readdirSync as readdirSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
51307
51468
|
import { join as join69, dirname as dirname26, basename as basename12 } from "path";
|
|
51308
51469
|
import { homedir as homedir11 } from "os";
|
|
51309
51470
|
function findPython() {
|
|
@@ -51340,7 +51501,7 @@ function hasPythonPackage(python, pkg) {
|
|
|
51340
51501
|
}
|
|
51341
51502
|
}
|
|
51342
51503
|
function ensureSynthScript() {
|
|
51343
|
-
if (!
|
|
51504
|
+
if (!existsSync63(SCRIPT_PATH)) {
|
|
51344
51505
|
mkdirSync35(SCRIPT_DIR, { recursive: true });
|
|
51345
51506
|
writeFileSync28(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
51346
51507
|
const currentName = basename12(SCRIPT_PATH);
|
|
@@ -51394,7 +51555,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51394
51555
|
stdio: ["pipe", "pipe", "pipe"]
|
|
51395
51556
|
}
|
|
51396
51557
|
);
|
|
51397
|
-
if (!
|
|
51558
|
+
if (!existsSync63(outputPath)) {
|
|
51398
51559
|
throw new Error("Synthesis completed but no output file was created");
|
|
51399
51560
|
}
|
|
51400
51561
|
const lines = stdout2.trim().split("\n");
|
|
@@ -51407,7 +51568,7 @@ async function synthesize(text, outputPath, options) {
|
|
|
51407
51568
|
langApplied: result.langApplied
|
|
51408
51569
|
};
|
|
51409
51570
|
} catch (err) {
|
|
51410
|
-
if (err instanceof SyntaxError &&
|
|
51571
|
+
if (err instanceof SyntaxError && existsSync63(outputPath)) {
|
|
51411
51572
|
throw new Error(
|
|
51412
51573
|
"Speech was generated but metadata could not be read. Check the output file manually."
|
|
51413
51574
|
);
|
|
@@ -51469,7 +51630,7 @@ __export(tts_exports, {
|
|
|
51469
51630
|
default: () => tts_default,
|
|
51470
51631
|
examples: () => examples17
|
|
51471
51632
|
});
|
|
51472
|
-
import { existsSync as
|
|
51633
|
+
import { existsSync as existsSync64, readFileSync as readFileSync44 } from "fs";
|
|
51473
51634
|
import { resolve as resolve39, extname as extname12 } from "path";
|
|
51474
51635
|
function listVoices(json) {
|
|
51475
51636
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -51579,8 +51740,8 @@ var init_tts = __esm({
|
|
|
51579
51740
|
}
|
|
51580
51741
|
let text;
|
|
51581
51742
|
const maybeFile = resolve39(args.input);
|
|
51582
|
-
if (
|
|
51583
|
-
text =
|
|
51743
|
+
if (existsSync64(maybeFile) && extname12(maybeFile).toLowerCase() === ".txt") {
|
|
51744
|
+
text = readFileSync44(maybeFile, "utf-8").trim();
|
|
51584
51745
|
if (!text) {
|
|
51585
51746
|
console.error(c2.error("File is empty."));
|
|
51586
51747
|
process.exit(1);
|
|
@@ -51672,7 +51833,7 @@ __export(docs_exports, {
|
|
|
51672
51833
|
default: () => docs_default,
|
|
51673
51834
|
examples: () => examples18
|
|
51674
51835
|
});
|
|
51675
|
-
import { readFileSync as
|
|
51836
|
+
import { readFileSync as readFileSync45, existsSync as existsSync65 } from "fs";
|
|
51676
51837
|
import { resolve as resolve40, dirname as dirname27, join as join70 } from "path";
|
|
51677
51838
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
51678
51839
|
function docsDir() {
|
|
@@ -51680,7 +51841,7 @@ function docsDir() {
|
|
|
51680
51841
|
const dir = dirname27(thisFile);
|
|
51681
51842
|
const devPath = resolve40(dir, "..", "docs");
|
|
51682
51843
|
const builtPath = resolve40(dir, "docs");
|
|
51683
|
-
return
|
|
51844
|
+
return existsSync65(devPath) ? devPath : builtPath;
|
|
51684
51845
|
}
|
|
51685
51846
|
function formatInlineCode(line) {
|
|
51686
51847
|
return line.replace(/`([^`]+)`/g, (_match, code) => c2.accent(code));
|
|
@@ -51778,11 +51939,11 @@ var init_docs = __esm({
|
|
|
51778
51939
|
process.exit(1);
|
|
51779
51940
|
}
|
|
51780
51941
|
const filePath = join70(docsDir(), entry.file);
|
|
51781
|
-
if (!
|
|
51942
|
+
if (!existsSync65(filePath)) {
|
|
51782
51943
|
console.error(c2.error(`Doc file not found: ${filePath}`));
|
|
51783
51944
|
process.exit(1);
|
|
51784
51945
|
}
|
|
51785
|
-
const content =
|
|
51946
|
+
const content = readFileSync45(filePath, "utf-8");
|
|
51786
51947
|
console.log();
|
|
51787
51948
|
renderMarkdown(content);
|
|
51788
51949
|
}
|
|
@@ -51799,7 +51960,7 @@ __export(doctor_exports, {
|
|
|
51799
51960
|
redactHome: () => redactHome
|
|
51800
51961
|
});
|
|
51801
51962
|
import { execSync as execSync3 } from "child_process";
|
|
51802
|
-
import { freemem as freemem5, platform as
|
|
51963
|
+
import { freemem as freemem5, platform as platform8 } from "os";
|
|
51803
51964
|
function checkFFmpeg() {
|
|
51804
51965
|
const path2 = findFFmpeg();
|
|
51805
51966
|
if (path2) {
|
|
@@ -51988,7 +52149,7 @@ var init_doctor = __esm({
|
|
|
51988
52149
|
{ name: "Memory", run: checkMemory },
|
|
51989
52150
|
{ name: "Disk", run: checkDisk }
|
|
51990
52151
|
];
|
|
51991
|
-
if (
|
|
52152
|
+
if (platform8() === "linux") {
|
|
51992
52153
|
checks.push({ name: "/dev/shm", run: checkShm });
|
|
51993
52154
|
}
|
|
51994
52155
|
checks.push(
|
|
@@ -52246,16 +52407,18 @@ function parseViewportDimension(value) {
|
|
|
52246
52407
|
if (!Number.isFinite(parsed) || parsed <= 0) return null;
|
|
52247
52408
|
return Math.min(parsed, MAX_VIEWPORT_DIMENSION);
|
|
52248
52409
|
}
|
|
52249
|
-
function
|
|
52410
|
+
function findCompositionDimensions(html) {
|
|
52250
52411
|
ensureDOMParser();
|
|
52251
52412
|
const doc = new DOMParser().parseFromString(html, "text/html");
|
|
52252
52413
|
const root = doc.querySelector("[data-composition-id][data-width][data-height]");
|
|
52253
|
-
|
|
52254
|
-
const
|
|
52255
|
-
|
|
52256
|
-
|
|
52257
|
-
|
|
52258
|
-
|
|
52414
|
+
if (!root) return null;
|
|
52415
|
+
const width = parseViewportDimension(root.getAttribute("data-width"));
|
|
52416
|
+
const height = parseViewportDimension(root.getAttribute("data-height"));
|
|
52417
|
+
if (width === null || height === null) return null;
|
|
52418
|
+
return { width, height };
|
|
52419
|
+
}
|
|
52420
|
+
function resolveCompositionViewportFromHtml(html) {
|
|
52421
|
+
return findCompositionDimensions(html) ?? DEFAULT_VIEWPORT;
|
|
52259
52422
|
}
|
|
52260
52423
|
var DEFAULT_VIEWPORT, MAX_VIEWPORT_DIMENSION;
|
|
52261
52424
|
var init_compositionViewport = __esm({
|
|
@@ -52273,7 +52436,7 @@ __export(validate_exports, {
|
|
|
52273
52436
|
default: () => validate_default,
|
|
52274
52437
|
shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
|
|
52275
52438
|
});
|
|
52276
|
-
import { existsSync as
|
|
52439
|
+
import { existsSync as existsSync66, readFileSync as readFileSync46 } from "fs";
|
|
52277
52440
|
import { join as join71, dirname as dirname28 } from "path";
|
|
52278
52441
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
52279
52442
|
function shouldIgnoreRequestFailure(url, errorText) {
|
|
@@ -52330,7 +52493,7 @@ function loadContrastAuditScript() {
|
|
|
52330
52493
|
join71(__dirname3, "commands", "contrast-audit.browser.js")
|
|
52331
52494
|
];
|
|
52332
52495
|
for (const candidate of candidates) {
|
|
52333
|
-
if (
|
|
52496
|
+
if (existsSync66(candidate)) return readFileSync46(candidate, "utf-8");
|
|
52334
52497
|
}
|
|
52335
52498
|
throw new Error("Missing contrast audit browser script");
|
|
52336
52499
|
}
|
|
@@ -52348,9 +52511,9 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
52348
52511
|
return;
|
|
52349
52512
|
}
|
|
52350
52513
|
const filePath = join71(projectDir, decodeURIComponent(url));
|
|
52351
|
-
if (
|
|
52514
|
+
if (existsSync66(filePath)) {
|
|
52352
52515
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
52353
|
-
res.end(
|
|
52516
|
+
res.end(readFileSync46(filePath));
|
|
52354
52517
|
return;
|
|
52355
52518
|
}
|
|
52356
52519
|
res.writeHead(404);
|
|
@@ -52552,7 +52715,7 @@ __export(contactSheet_exports, {
|
|
|
52552
52715
|
createSvgContactSheet: () => createSvgContactSheet
|
|
52553
52716
|
});
|
|
52554
52717
|
import sharp from "sharp";
|
|
52555
|
-
import { readdirSync as readdirSync26, readFileSync as
|
|
52718
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync47, writeFileSync as writeFileSync29, unlinkSync as unlinkSync7, existsSync as existsSync67 } from "fs";
|
|
52556
52719
|
import { join as join72, extname as extname13, basename as basename13, dirname as dirname29 } from "path";
|
|
52557
52720
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
52558
52721
|
const {
|
|
@@ -52632,7 +52795,7 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
52632
52795
|
return results;
|
|
52633
52796
|
}
|
|
52634
52797
|
async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
52635
|
-
if (!
|
|
52798
|
+
if (!existsSync67(screenshotsDir)) return [];
|
|
52636
52799
|
const scrollFiles = readdirSync26(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
52637
52800
|
if (scrollFiles.length === 0) return [];
|
|
52638
52801
|
const paths = scrollFiles.map((f3) => join72(screenshotsDir, f3));
|
|
@@ -52649,7 +52812,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath) {
|
|
|
52649
52812
|
);
|
|
52650
52813
|
}
|
|
52651
52814
|
async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
52652
|
-
if (!
|
|
52815
|
+
if (!existsSync67(snapshotsDir)) return [];
|
|
52653
52816
|
const snapshotFiles = readdirSync26(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
52654
52817
|
if (snapshotFiles.length === 0) return [];
|
|
52655
52818
|
const paths = snapshotFiles.map((f3) => join72(snapshotsDir, f3));
|
|
@@ -52666,7 +52829,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath) {
|
|
|
52666
52829
|
);
|
|
52667
52830
|
}
|
|
52668
52831
|
async function createAssetContactSheet(assetsDir, outputPath) {
|
|
52669
|
-
if (!
|
|
52832
|
+
if (!existsSync67(assetsDir)) return [];
|
|
52670
52833
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
52671
52834
|
const assetFiles = readdirSync26(assetsDir).filter((f3) => imageExts.has(extname13(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
52672
52835
|
if (assetFiles.length === 0) return [];
|
|
@@ -52680,7 +52843,7 @@ async function createAssetContactSheet(assetsDir, outputPath) {
|
|
|
52680
52843
|
}
|
|
52681
52844
|
async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
52682
52845
|
const dirsToScan = [svgsDir, assetsRootDir].filter(
|
|
52683
|
-
(d2) => d2 !== void 0 &&
|
|
52846
|
+
(d2) => d2 !== void 0 && existsSync67(d2)
|
|
52684
52847
|
);
|
|
52685
52848
|
if (dirsToScan.length === 0) return [];
|
|
52686
52849
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -52703,7 +52866,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
|
52703
52866
|
const svgPath = svgPaths[i2];
|
|
52704
52867
|
const tmpPath = join72(tmpDir, `.thumb-${i2}.png`);
|
|
52705
52868
|
try {
|
|
52706
|
-
const svgBuf =
|
|
52869
|
+
const svgBuf = readFileSync47(svgPath);
|
|
52707
52870
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
52708
52871
|
fit: "contain",
|
|
52709
52872
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
@@ -93261,7 +93424,7 @@ __export(snapshot_exports, {
|
|
|
93261
93424
|
examples: () => examples22
|
|
93262
93425
|
});
|
|
93263
93426
|
import { spawn as spawn15 } from "child_process";
|
|
93264
|
-
import { existsSync as
|
|
93427
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync3, readFileSync as readFileSync48, mkdirSync as mkdirSync36, rmSync as rmSync15, writeFileSync as writeFileSync30 } from "fs";
|
|
93265
93428
|
import { tmpdir as tmpdir6 } from "os";
|
|
93266
93429
|
import { resolve as resolve41, join as join73, relative as relative10, isAbsolute as isAbsolute9 } from "path";
|
|
93267
93430
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
@@ -93306,8 +93469,8 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
93306
93469
|
});
|
|
93307
93470
|
}
|
|
93308
93471
|
);
|
|
93309
|
-
if (result.code !== 0 || result.timedOut || !
|
|
93310
|
-
return
|
|
93472
|
+
if (result.code !== 0 || result.timedOut || !existsSync68(outPath)) return null;
|
|
93473
|
+
return readFileSync48(outPath);
|
|
93311
93474
|
} finally {
|
|
93312
93475
|
try {
|
|
93313
93476
|
rmSync15(tmp, { recursive: true, force: true });
|
|
@@ -93505,7 +93668,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
93505
93668
|
const decodedPath = decodeURIComponent(url.pathname).replace(/^\//, "");
|
|
93506
93669
|
const candidate = resolve41(projectDir, decodedPath);
|
|
93507
93670
|
const rel = relative10(projectDir, candidate);
|
|
93508
|
-
if (!rel.startsWith("..") && !isAbsolute9(rel) &&
|
|
93671
|
+
if (!rel.startsWith("..") && !isAbsolute9(rel) && existsSync68(candidate)) {
|
|
93509
93672
|
filePath = candidate;
|
|
93510
93673
|
}
|
|
93511
93674
|
} catch {
|
|
@@ -93656,8 +93819,8 @@ ${c2.success("\u25C7")} ${paths.length} snapshots saved to snapshots/`);
|
|
|
93656
93819
|
paths.map(async (p2) => {
|
|
93657
93820
|
const filename = p2.replace("snapshots/", "");
|
|
93658
93821
|
const filePath = join73(snapshotDir, filename);
|
|
93659
|
-
if (!
|
|
93660
|
-
const raw =
|
|
93822
|
+
if (!existsSync68(filePath)) return { filename, desc: "file not found" };
|
|
93823
|
+
const raw = readFileSync48(filePath);
|
|
93661
93824
|
let imageData;
|
|
93662
93825
|
let mimeType = "image/png";
|
|
93663
93826
|
if (sharpFn) {
|
|
@@ -94851,7 +95014,7 @@ var init_designStyleExtractor = __esm({
|
|
|
94851
95014
|
});
|
|
94852
95015
|
|
|
94853
95016
|
// src/capture/fontMetadataExtractor.ts
|
|
94854
|
-
import { readdirSync as readdirSync27, readFileSync as
|
|
95017
|
+
import { readdirSync as readdirSync27, readFileSync as readFileSync49, writeFileSync as writeFileSync32, existsSync as existsSync69 } from "fs";
|
|
94855
95018
|
import { join as join75 } from "path";
|
|
94856
95019
|
import * as fontkit from "fontkit";
|
|
94857
95020
|
function isFontCollection(value) {
|
|
@@ -94860,7 +95023,7 @@ function isFontCollection(value) {
|
|
|
94860
95023
|
function extractFontMetadata(fontsDir, outputPath) {
|
|
94861
95024
|
const files = [];
|
|
94862
95025
|
const unidentified = [];
|
|
94863
|
-
if (
|
|
95026
|
+
if (existsSync69(fontsDir)) {
|
|
94864
95027
|
const fontFiles = readdirSync27(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
94865
95028
|
for (const filename of fontFiles) {
|
|
94866
95029
|
const fullPath = join75(fontsDir, filename);
|
|
@@ -94901,7 +95064,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
94901
95064
|
identified: false
|
|
94902
95065
|
};
|
|
94903
95066
|
try {
|
|
94904
|
-
const buf =
|
|
95067
|
+
const buf = readFileSync49(fullPath);
|
|
94905
95068
|
const created = fontkit.create(buf);
|
|
94906
95069
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
94907
95070
|
if (!font) return empty;
|
|
@@ -95157,7 +95320,7 @@ var init_animationCataloger = __esm({
|
|
|
95157
95320
|
});
|
|
95158
95321
|
|
|
95159
95322
|
// src/capture/mediaCapture.ts
|
|
95160
|
-
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as
|
|
95323
|
+
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync33, readdirSync as readdirSync28, readFileSync as readFileSync50, statSync as statSync24 } from "fs";
|
|
95161
95324
|
import { join as join76 } from "path";
|
|
95162
95325
|
async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
95163
95326
|
let savedCount = 0;
|
|
@@ -95224,7 +95387,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95224
95387
|
for (const file of readdirSync28(lottieDir)) {
|
|
95225
95388
|
if (!file.endsWith(".json")) continue;
|
|
95226
95389
|
try {
|
|
95227
|
-
const raw = JSON.parse(
|
|
95390
|
+
const raw = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95228
95391
|
const fr = raw.fr || 30;
|
|
95229
95392
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
95230
95393
|
const previewName = file.replace(".json", "-preview.png");
|
|
@@ -95234,7 +95397,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
95234
95397
|
try {
|
|
95235
95398
|
previewPage = await chromeBrowser.newPage();
|
|
95236
95399
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
95237
|
-
const animData = JSON.parse(
|
|
95400
|
+
const animData = JSON.parse(readFileSync50(join76(lottieDir, file), "utf-8"));
|
|
95238
95401
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
95239
95402
|
await previewPage.setContent(
|
|
95240
95403
|
`<!DOCTYPE html>
|
|
@@ -95413,7 +95576,7 @@ var init_mediaCapture = __esm({
|
|
|
95413
95576
|
});
|
|
95414
95577
|
|
|
95415
95578
|
// src/capture/contentExtractor.ts
|
|
95416
|
-
import { existsSync as
|
|
95579
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, statSync as statSync25, readFileSync as readFileSync51 } from "fs";
|
|
95417
95580
|
import { join as join77 } from "path";
|
|
95418
95581
|
async function detectLibraries(page, capturedShaders) {
|
|
95419
95582
|
let detectedLibraries = [];
|
|
@@ -95546,7 +95709,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95546
95709
|
const filePath = join77(outputDir, "assets", file);
|
|
95547
95710
|
const stat3 = statSync25(filePath);
|
|
95548
95711
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
95549
|
-
const buffer =
|
|
95712
|
+
const buffer = readFileSync51(filePath);
|
|
95550
95713
|
const base64 = buffer.toString("base64");
|
|
95551
95714
|
const ext = file.split(".").pop()?.toLowerCase() || "png";
|
|
95552
95715
|
const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -95588,7 +95751,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95588
95751
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
95589
95752
|
}
|
|
95590
95753
|
const svgsSubdir = join77(assetsDir, "svgs");
|
|
95591
|
-
if (
|
|
95754
|
+
if (existsSync70(svgsSubdir)) {
|
|
95592
95755
|
for (const f3 of readdirSync29(svgsSubdir)) {
|
|
95593
95756
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
95594
95757
|
}
|
|
@@ -95602,7 +95765,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
95602
95765
|
const results = await Promise.allSettled(
|
|
95603
95766
|
batch.map(async ({ relPath }) => {
|
|
95604
95767
|
const filePath = join77(assetsDir, relPath);
|
|
95605
|
-
let svgText =
|
|
95768
|
+
let svgText = readFileSync51(filePath, "utf-8");
|
|
95606
95769
|
if (svgText.length > MAX_SVG_CHARS) {
|
|
95607
95770
|
svgText = svgText.slice(0, MAX_SVG_CHARS) + "\n<!-- truncated -->";
|
|
95608
95771
|
}
|
|
@@ -95720,7 +95883,7 @@ var agentPromptGenerator_exports = {};
|
|
|
95720
95883
|
__export(agentPromptGenerator_exports, {
|
|
95721
95884
|
generateAgentPrompt: () => generateAgentPrompt
|
|
95722
95885
|
});
|
|
95723
|
-
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as
|
|
95886
|
+
import { writeFileSync as writeFileSync34, readdirSync as readdirSync30, existsSync as existsSync71 } from "fs";
|
|
95724
95887
|
import { join as join78 } from "path";
|
|
95725
95888
|
function inferColorRole(hex) {
|
|
95726
95889
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -95752,7 +95915,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95752
95915
|
).join(", ") || "none detected";
|
|
95753
95916
|
function contactSheetRows(dir, baseFile, label2) {
|
|
95754
95917
|
const fullDir = join78(outputDir, dir);
|
|
95755
|
-
if (!
|
|
95918
|
+
if (!existsSync71(fullDir)) return [];
|
|
95756
95919
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
95757
95920
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
95758
95921
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
@@ -95784,7 +95947,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
95784
95947
|
tableRows.push(
|
|
95785
95948
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
95786
95949
|
);
|
|
95787
|
-
if (
|
|
95950
|
+
if (existsSync71(join78(outputDir, "extracted", "design-styles.json"))) {
|
|
95788
95951
|
tableRows.push(
|
|
95789
95952
|
"| `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
95953
|
);
|
|
@@ -95855,7 +96018,7 @@ var init_agentPromptGenerator = __esm({
|
|
|
95855
96018
|
});
|
|
95856
96019
|
|
|
95857
96020
|
// src/capture/scaffolding.ts
|
|
95858
|
-
import { existsSync as
|
|
96021
|
+
import { existsSync as existsSync72, writeFileSync as writeFileSync35, readFileSync as readFileSync52 } from "fs";
|
|
95859
96022
|
import { join as join79, resolve as resolve42 } from "path";
|
|
95860
96023
|
function loadEnvFile(startDir) {
|
|
95861
96024
|
try {
|
|
@@ -95863,7 +96026,7 @@ function loadEnvFile(startDir) {
|
|
|
95863
96026
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
95864
96027
|
const envPath = resolve42(dir, ".env");
|
|
95865
96028
|
try {
|
|
95866
|
-
const envContent =
|
|
96029
|
+
const envContent = readFileSync52(envPath, "utf-8");
|
|
95867
96030
|
for (const line of envContent.split("\n")) {
|
|
95868
96031
|
const trimmed = line.trim();
|
|
95869
96032
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -95883,7 +96046,7 @@ function loadEnvFile(startDir) {
|
|
|
95883
96046
|
}
|
|
95884
96047
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
95885
96048
|
const metaPath = join79(outputDir, "meta.json");
|
|
95886
|
-
if (!
|
|
96049
|
+
if (!existsSync72(metaPath)) {
|
|
95887
96050
|
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
95888
96051
|
writeFileSync35(
|
|
95889
96052
|
metaPath,
|
|
@@ -96290,7 +96453,7 @@ var capture_exports = {};
|
|
|
96290
96453
|
__export(capture_exports, {
|
|
96291
96454
|
captureWebsite: () => captureWebsite
|
|
96292
96455
|
});
|
|
96293
|
-
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as
|
|
96456
|
+
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync37, existsSync as existsSync73 } from "fs";
|
|
96294
96457
|
import { join as join81 } from "path";
|
|
96295
96458
|
async function captureWebsite(opts, onProgress) {
|
|
96296
96459
|
const {
|
|
@@ -96653,7 +96816,7 @@ ${err.stack}` : String(err);
|
|
|
96653
96816
|
`Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
|
|
96654
96817
|
);
|
|
96655
96818
|
const assetsImgDir = join81(outputDir, "assets");
|
|
96656
|
-
if (
|
|
96819
|
+
if (existsSync73(assetsImgDir)) {
|
|
96657
96820
|
const assetSheets = await createAssetContactSheet2(
|
|
96658
96821
|
assetsImgDir,
|
|
96659
96822
|
join81(outputDir, "assets", "contact-sheet.jpg")
|
|
@@ -96666,7 +96829,7 @@ ${err.stack}` : String(err);
|
|
|
96666
96829
|
}
|
|
96667
96830
|
const svgsDir = join81(outputDir, "assets", "svgs");
|
|
96668
96831
|
const assetsRootDir = join81(outputDir, "assets");
|
|
96669
|
-
const svgOutputPath =
|
|
96832
|
+
const svgOutputPath = existsSync73(svgsDir) ? join81(outputDir, "assets", "svgs", "contact-sheet.jpg") : join81(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
96670
96833
|
const svgSheets = await createSvgContactSheet2(svgsDir, svgOutputPath, assetsRootDir);
|
|
96671
96834
|
if (svgSheets.length > 0)
|
|
96672
96835
|
progress(
|
|
@@ -96682,7 +96845,7 @@ ${err.stack}` : String(err);
|
|
|
96682
96845
|
animationCatalog,
|
|
96683
96846
|
screenshots.length > 0,
|
|
96684
96847
|
discoveredLotties.length > 0,
|
|
96685
|
-
|
|
96848
|
+
existsSync73(join81(outputDir, "extracted", "shaders.json")),
|
|
96686
96849
|
catalogedAssets,
|
|
96687
96850
|
progress,
|
|
96688
96851
|
warnings,
|
|
@@ -96910,7 +97073,7 @@ __export(state_exports, {
|
|
|
96910
97073
|
stateFilePath: () => stateFilePath,
|
|
96911
97074
|
writeStackOutputs: () => writeStackOutputs
|
|
96912
97075
|
});
|
|
96913
|
-
import { existsSync as
|
|
97076
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync41, readdirSync as readdirSync31, readFileSync as readFileSync53, rmSync as rmSync16, writeFileSync as writeFileSync38 } from "fs";
|
|
96914
97077
|
import { dirname as dirname30, join as join82 } from "path";
|
|
96915
97078
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96916
97079
|
return join82(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -96923,20 +97086,20 @@ function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
|
96923
97086
|
}
|
|
96924
97087
|
function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96925
97088
|
const path2 = stateFilePath(stackName, cwd);
|
|
96926
|
-
if (!
|
|
97089
|
+
if (!existsSync74(path2)) return null;
|
|
96927
97090
|
try {
|
|
96928
|
-
return JSON.parse(
|
|
97091
|
+
return JSON.parse(readFileSync53(path2, "utf-8"));
|
|
96929
97092
|
} catch {
|
|
96930
97093
|
return null;
|
|
96931
97094
|
}
|
|
96932
97095
|
}
|
|
96933
97096
|
function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
96934
97097
|
const path2 = stateFilePath(stackName, cwd);
|
|
96935
|
-
if (
|
|
97098
|
+
if (existsSync74(path2)) rmSync16(path2);
|
|
96936
97099
|
}
|
|
96937
97100
|
function listStackNames(cwd = process.cwd()) {
|
|
96938
97101
|
const dir = join82(cwd, STATE_DIR_NAME);
|
|
96939
|
-
if (!
|
|
97102
|
+
if (!existsSync74(dir)) return [];
|
|
96940
97103
|
return readdirSync31(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
96941
97104
|
}
|
|
96942
97105
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
@@ -96966,7 +97129,7 @@ var init_state = __esm({
|
|
|
96966
97129
|
|
|
96967
97130
|
// src/commands/lambda/sam.ts
|
|
96968
97131
|
import { execFileSync as execFileSync9, spawnSync as spawnSync4 } from "child_process";
|
|
96969
|
-
import { existsSync as
|
|
97132
|
+
import { existsSync as existsSync75 } from "fs";
|
|
96970
97133
|
import { join as join83 } from "path";
|
|
96971
97134
|
function assertSamAvailable() {
|
|
96972
97135
|
try {
|
|
@@ -96988,7 +97151,7 @@ function assertAwsCliAvailable() {
|
|
|
96988
97151
|
}
|
|
96989
97152
|
function locateSamTemplate(repoRoot2) {
|
|
96990
97153
|
const candidate = join83(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
96991
|
-
if (!
|
|
97154
|
+
if (!existsSync75(candidate)) {
|
|
96992
97155
|
throw new Error(
|
|
96993
97156
|
`[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
97157
|
);
|
|
@@ -97083,17 +97246,17 @@ var init_sam = __esm({
|
|
|
97083
97246
|
});
|
|
97084
97247
|
|
|
97085
97248
|
// src/commands/lambda/repoRoot.ts
|
|
97086
|
-
import { existsSync as
|
|
97249
|
+
import { existsSync as existsSync76 } from "fs";
|
|
97087
97250
|
import { dirname as dirname31, resolve as resolve44 } from "path";
|
|
97088
97251
|
import { fileURLToPath as fileURLToPath11 } from "url";
|
|
97089
97252
|
function repoRoot() {
|
|
97090
97253
|
const override = process.env.HYPERFRAMES_REPO_ROOT;
|
|
97091
|
-
if (override &&
|
|
97254
|
+
if (override && existsSync76(resolve44(override, "packages", "aws-lambda", "package.json"))) {
|
|
97092
97255
|
return override;
|
|
97093
97256
|
}
|
|
97094
97257
|
let dir = dirname31(fileURLToPath11(import.meta.url));
|
|
97095
97258
|
for (let depth = 0; depth < 12; depth++) {
|
|
97096
|
-
if (
|
|
97259
|
+
if (existsSync76(resolve44(dir, "packages", "aws-lambda", "package.json"))) {
|
|
97097
97260
|
return dir;
|
|
97098
97261
|
}
|
|
97099
97262
|
const parent = dirname31(dir);
|
|
@@ -97116,7 +97279,7 @@ __export(deploy_exports, {
|
|
|
97116
97279
|
runDeploy: () => runDeploy
|
|
97117
97280
|
});
|
|
97118
97281
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
97119
|
-
import { existsSync as
|
|
97282
|
+
import { existsSync as existsSync77 } from "fs";
|
|
97120
97283
|
import { join as join84, resolve as resolve45 } from "path";
|
|
97121
97284
|
async function runDeploy(args = {}) {
|
|
97122
97285
|
const resolved = {
|
|
@@ -97135,7 +97298,7 @@ async function runDeploy(args = {}) {
|
|
|
97135
97298
|
buildHandlerZip(root);
|
|
97136
97299
|
} else {
|
|
97137
97300
|
const zip = join84(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
97138
|
-
if (!
|
|
97301
|
+
if (!existsSync77(zip)) {
|
|
97139
97302
|
throw new Error(
|
|
97140
97303
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
97141
97304
|
);
|
|
@@ -97246,23 +97409,61 @@ var init_sites = __esm({
|
|
|
97246
97409
|
}
|
|
97247
97410
|
});
|
|
97248
97411
|
|
|
97412
|
+
// src/commands/lambda/_dimensions.ts
|
|
97413
|
+
import { readFileSync as readFileSync54 } from "fs";
|
|
97414
|
+
import { join as join85 } from "path";
|
|
97415
|
+
function warnOnDimensionMismatch(args) {
|
|
97416
|
+
if (args.quiet) return;
|
|
97417
|
+
if (args.outputResolution) return;
|
|
97418
|
+
let html;
|
|
97419
|
+
try {
|
|
97420
|
+
html = readFileSync54(join85(args.projectDir, "index.html"), "utf-8");
|
|
97421
|
+
} catch {
|
|
97422
|
+
return;
|
|
97423
|
+
}
|
|
97424
|
+
const composition = findCompositionDimensions(html);
|
|
97425
|
+
if (!composition) return;
|
|
97426
|
+
if (composition.width === args.cliWidth && composition.height === args.cliHeight) return;
|
|
97427
|
+
console.warn(
|
|
97428
|
+
c2.warn(
|
|
97429
|
+
`--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}.
|
|
97430
|
+
To supersample to a higher resolution, pass --output-resolution (e.g. \`--output-resolution=4k\`).
|
|
97431
|
+
To truly change layout dimensions, edit the composition's data-width/data-height in index.html.`
|
|
97432
|
+
)
|
|
97433
|
+
);
|
|
97434
|
+
}
|
|
97435
|
+
var init_dimensions = __esm({
|
|
97436
|
+
"src/commands/lambda/_dimensions.ts"() {
|
|
97437
|
+
"use strict";
|
|
97438
|
+
init_colors();
|
|
97439
|
+
init_compositionViewport();
|
|
97440
|
+
}
|
|
97441
|
+
});
|
|
97442
|
+
|
|
97249
97443
|
// src/commands/lambda/render.ts
|
|
97250
97444
|
var render_exports2 = {};
|
|
97251
97445
|
__export(render_exports2, {
|
|
97252
97446
|
runRender: () => runRender
|
|
97253
97447
|
});
|
|
97254
|
-
import { existsSync as
|
|
97255
|
-
import { join as
|
|
97448
|
+
import { existsSync as existsSync78 } from "fs";
|
|
97449
|
+
import { join as join86, resolve as resolvePath2 } from "path";
|
|
97256
97450
|
async function loadSDK2() {
|
|
97257
97451
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97258
97452
|
}
|
|
97259
97453
|
async function runRender(args) {
|
|
97260
97454
|
const stack = requireStack(args.stackName);
|
|
97261
97455
|
const projectDir = resolvePath2(args.projectDir);
|
|
97456
|
+
warnOnDimensionMismatch({
|
|
97457
|
+
projectDir,
|
|
97458
|
+
cliWidth: args.width,
|
|
97459
|
+
cliHeight: args.height,
|
|
97460
|
+
outputResolution: args.outputResolution,
|
|
97461
|
+
quiet: args.json
|
|
97462
|
+
});
|
|
97262
97463
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
97263
97464
|
if (variables && Object.keys(variables).length > 0) {
|
|
97264
|
-
const indexPath =
|
|
97265
|
-
if (
|
|
97465
|
+
const indexPath = join86(projectDir, "index.html");
|
|
97466
|
+
if (existsSync78(indexPath)) {
|
|
97266
97467
|
const issues = validateVariablesAgainstProject(indexPath, variables);
|
|
97267
97468
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
97268
97469
|
} else if (args.strictVariables && !args.json) {
|
|
@@ -97277,6 +97478,7 @@ async function runRender(args) {
|
|
|
97277
97478
|
fps: args.fps,
|
|
97278
97479
|
width: args.width,
|
|
97279
97480
|
height: args.height,
|
|
97481
|
+
outputResolution: args.outputResolution,
|
|
97280
97482
|
format: args.format,
|
|
97281
97483
|
codec: args.codec,
|
|
97282
97484
|
quality: args.quality,
|
|
@@ -97372,6 +97574,7 @@ var init_render3 = __esm({
|
|
|
97372
97574
|
"use strict";
|
|
97373
97575
|
init_colors();
|
|
97374
97576
|
init_variables();
|
|
97577
|
+
init_dimensions();
|
|
97375
97578
|
init_state();
|
|
97376
97579
|
}
|
|
97377
97580
|
});
|
|
@@ -97383,8 +97586,8 @@ __export(render_batch_exports, {
|
|
|
97383
97586
|
runRenderBatch: () => runRenderBatch,
|
|
97384
97587
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
97385
97588
|
});
|
|
97386
|
-
import { existsSync as
|
|
97387
|
-
import { join as
|
|
97589
|
+
import { existsSync as existsSync79, readFileSync as readFileSync55 } from "fs";
|
|
97590
|
+
import { join as join87, resolve as resolvePath3 } from "path";
|
|
97388
97591
|
async function loadSDK3() {
|
|
97389
97592
|
return import("@hyperframes/aws-lambda/sdk");
|
|
97390
97593
|
}
|
|
@@ -97392,7 +97595,7 @@ async function runRenderBatch(args) {
|
|
|
97392
97595
|
const projectDir = resolvePath3(args.projectDir);
|
|
97393
97596
|
const stack = requireStack(args.stackName);
|
|
97394
97597
|
const batchPath = resolvePath3(args.batch);
|
|
97395
|
-
if (!
|
|
97598
|
+
if (!existsSync79(batchPath)) {
|
|
97396
97599
|
errorBox("Batch file not found", `No such file: ${batchPath}`);
|
|
97397
97600
|
process.exit(1);
|
|
97398
97601
|
}
|
|
@@ -97401,7 +97604,14 @@ async function runRenderBatch(args) {
|
|
|
97401
97604
|
errorBox("Empty batch", `${batchPath} contains zero entries (every line was blank).`);
|
|
97402
97605
|
process.exit(1);
|
|
97403
97606
|
}
|
|
97404
|
-
|
|
97607
|
+
warnOnDimensionMismatch({
|
|
97608
|
+
projectDir,
|
|
97609
|
+
cliWidth: args.width,
|
|
97610
|
+
cliHeight: args.height,
|
|
97611
|
+
outputResolution: args.outputResolution,
|
|
97612
|
+
quiet: args.json
|
|
97613
|
+
});
|
|
97614
|
+
const schema = loadProjectVariableSchema(join87(projectDir, "index.html"));
|
|
97405
97615
|
const strict = args.strictVariables ?? false;
|
|
97406
97616
|
let hadStrictIssue = false;
|
|
97407
97617
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -97426,6 +97636,7 @@ async function runRenderBatch(args) {
|
|
|
97426
97636
|
fps: args.fps,
|
|
97427
97637
|
width: args.width,
|
|
97428
97638
|
height: args.height,
|
|
97639
|
+
outputResolution: args.outputResolution,
|
|
97429
97640
|
format: args.format,
|
|
97430
97641
|
codec: args.codec,
|
|
97431
97642
|
quality: args.quality,
|
|
@@ -97527,7 +97738,7 @@ function makePlaceholderSiteHandle(siteId, bucketName) {
|
|
|
97527
97738
|
};
|
|
97528
97739
|
}
|
|
97529
97740
|
function parseBatchFile(path2) {
|
|
97530
|
-
const raw =
|
|
97741
|
+
const raw = readFileSync55(path2, "utf8");
|
|
97531
97742
|
const lines = raw.split(/\r?\n/);
|
|
97532
97743
|
const out = [];
|
|
97533
97744
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
@@ -97608,6 +97819,7 @@ var init_render_batch = __esm({
|
|
|
97608
97819
|
init_colors();
|
|
97609
97820
|
init_format();
|
|
97610
97821
|
init_variables();
|
|
97822
|
+
init_dimensions();
|
|
97611
97823
|
init_state();
|
|
97612
97824
|
DEFAULT_MAX_CONCURRENT = 50;
|
|
97613
97825
|
}
|
|
@@ -97720,7 +97932,7 @@ __export(policies_exports, {
|
|
|
97720
97932
|
runPolicies: () => runPolicies,
|
|
97721
97933
|
validatePolicy: () => validatePolicy
|
|
97722
97934
|
});
|
|
97723
|
-
import { readFileSync as
|
|
97935
|
+
import { readFileSync as readFileSync56 } from "fs";
|
|
97724
97936
|
function allRequiredActions() {
|
|
97725
97937
|
const set = /* @__PURE__ */ new Set();
|
|
97726
97938
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -97826,7 +98038,7 @@ async function runPolicies(args) {
|
|
|
97826
98038
|
}
|
|
97827
98039
|
}
|
|
97828
98040
|
function validatePolicy(policyPath) {
|
|
97829
|
-
const raw =
|
|
98041
|
+
const raw = readFileSync56(policyPath, "utf-8");
|
|
97830
98042
|
const parsed = JSON.parse(raw);
|
|
97831
98043
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
97832
98044
|
parsed.Statement
|
|
@@ -98014,11 +98226,20 @@ function parseEnum(raw, allowed, errorPrefix, defaultValue) {
|
|
|
98014
98226
|
if (allowed.includes(s2)) return s2;
|
|
98015
98227
|
throw new Error(`${errorPrefix} must be ${allowed.join("|")}; got ${s2}`);
|
|
98016
98228
|
}
|
|
98229
|
+
function parseOutputResolution(raw) {
|
|
98230
|
+
if (raw == null || raw === "") return void 0;
|
|
98231
|
+
const normalized = normalizeResolutionFlag(String(raw));
|
|
98232
|
+
if (normalized) return normalized;
|
|
98233
|
+
throw new Error(
|
|
98234
|
+
`[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)}`
|
|
98235
|
+
);
|
|
98236
|
+
}
|
|
98017
98237
|
var examples24, HELP, lambda_default, FORMATS, CODECS, QUALITIES2, CHROME_SOURCES, parseFormat, parseCodec, parseQuality, parseChromeSource;
|
|
98018
98238
|
var init_lambda = __esm({
|
|
98019
98239
|
"src/commands/lambda.ts"() {
|
|
98020
98240
|
"use strict";
|
|
98021
98241
|
init_dist();
|
|
98242
|
+
init_src();
|
|
98022
98243
|
init_colors();
|
|
98023
98244
|
examples24 = [
|
|
98024
98245
|
["Deploy the Lambda render stack to AWS", "hyperframes lambda deploy"],
|
|
@@ -98030,6 +98251,10 @@ var init_lambda = __esm({
|
|
|
98030
98251
|
"Render and stream progress until done",
|
|
98031
98252
|
"hyperframes lambda render ./my-project --width 1920 --height 1080 --wait"
|
|
98032
98253
|
],
|
|
98254
|
+
[
|
|
98255
|
+
"Supersample a 1080p composition to 4K via Chrome deviceScaleFactor",
|
|
98256
|
+
"hyperframes lambda render ./my-project --width 1920 --height 1080 --output-resolution 4k --wait"
|
|
98257
|
+
],
|
|
98033
98258
|
[
|
|
98034
98259
|
"Render with composition variables (personalised template)",
|
|
98035
98260
|
`hyperframes lambda render ./my-template --site-id abc1234deadbeef0 --width 1920 --height 1080 --variables '{"title":"Hello Alice","accent":"#ff0000"}'`
|
|
@@ -98114,6 +98339,10 @@ ${c2.bold("REQUIREMENTS:")}
|
|
|
98114
98339
|
"site-id": { type: "string", description: "Explicit site id (overrides content hash)" },
|
|
98115
98340
|
width: { type: "string", description: "Render width in pixels" },
|
|
98116
98341
|
height: { type: "string", description: "Render height in pixels" },
|
|
98342
|
+
"output-resolution": {
|
|
98343
|
+
type: "string",
|
|
98344
|
+
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."
|
|
98345
|
+
},
|
|
98117
98346
|
fps: { type: "string", description: "Render fps (24 | 30 | 60)" },
|
|
98118
98347
|
format: { type: "string", description: "mp4 | mov | png-sequence | webm (default: mp4)" },
|
|
98119
98348
|
codec: { type: "string", description: "h264 | h265 (mp4 only)" },
|
|
@@ -98268,6 +98497,7 @@ Or, for an opt-in dev setup:
|
|
|
98268
98497
|
fps: fpsRaw,
|
|
98269
98498
|
width,
|
|
98270
98499
|
height,
|
|
98500
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98271
98501
|
format: parseFormat(args.format),
|
|
98272
98502
|
codec: parseCodec(args.codec),
|
|
98273
98503
|
quality: parseQuality(args.quality),
|
|
@@ -98319,6 +98549,7 @@ Or, for an opt-in dev setup:
|
|
|
98319
98549
|
fps: fpsRaw,
|
|
98320
98550
|
width,
|
|
98321
98551
|
height,
|
|
98552
|
+
outputResolution: parseOutputResolution(args["output-resolution"]),
|
|
98322
98553
|
format: parseFormat(args.format),
|
|
98323
98554
|
codec: parseCodec(args.codec),
|
|
98324
98555
|
quality: parseQuality(args.quality),
|
|
@@ -98521,7 +98752,7 @@ __export(autoUpdate_exports, {
|
|
|
98521
98752
|
import { spawn as spawn16 } from "child_process";
|
|
98522
98753
|
import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync42, openSync as openSync2 } from "fs";
|
|
98523
98754
|
import { homedir as homedir12 } from "os";
|
|
98524
|
-
import { join as
|
|
98755
|
+
import { join as join88 } from "path";
|
|
98525
98756
|
import { compareVersions as compareVersions2 } from "compare-versions";
|
|
98526
98757
|
function isAutoInstallDisabled() {
|
|
98527
98758
|
if (isDevMode()) return true;
|
|
@@ -98544,7 +98775,7 @@ function log(line) {
|
|
|
98544
98775
|
}
|
|
98545
98776
|
function launchDetachedInstall(installCommand, version) {
|
|
98546
98777
|
mkdirSync42(CONFIG_DIR2, { recursive: true, mode: 448 });
|
|
98547
|
-
const configFile =
|
|
98778
|
+
const configFile = join88(CONFIG_DIR2, "config.json");
|
|
98548
98779
|
const nodeScript = `
|
|
98549
98780
|
const { exec } = require("node:child_process");
|
|
98550
98781
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -98663,8 +98894,8 @@ var init_autoUpdate = __esm({
|
|
|
98663
98894
|
init_config();
|
|
98664
98895
|
init_env();
|
|
98665
98896
|
init_installerDetection();
|
|
98666
|
-
CONFIG_DIR2 =
|
|
98667
|
-
LOG_FILE =
|
|
98897
|
+
CONFIG_DIR2 = join88(homedir12(), ".hyperframes");
|
|
98898
|
+
LOG_FILE = join88(CONFIG_DIR2, "auto-update.log");
|
|
98668
98899
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
98669
98900
|
}
|
|
98670
98901
|
});
|
|
@@ -98852,17 +99083,17 @@ var init_help = __esm({
|
|
|
98852
99083
|
// src/cli.ts
|
|
98853
99084
|
init_version();
|
|
98854
99085
|
init_dist();
|
|
98855
|
-
import { dirname as dirname32, join as
|
|
99086
|
+
import { dirname as dirname32, join as join89 } from "path";
|
|
98856
99087
|
import { fileURLToPath as fileURLToPath12 } from "url";
|
|
98857
|
-
import { existsSync as
|
|
99088
|
+
import { existsSync as existsSync80 } from "fs";
|
|
98858
99089
|
(() => {
|
|
98859
99090
|
const here = dirname32(fileURLToPath12(import.meta.url));
|
|
98860
|
-
const shader =
|
|
98861
|
-
const png =
|
|
98862
|
-
if (!process.env.HF_SHADER_WORKER_ENTRY &&
|
|
99091
|
+
const shader = join89(here, "shaderTransitionWorker.js");
|
|
99092
|
+
const png = join89(here, "pngDecodeBlitWorker.js");
|
|
99093
|
+
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync80(shader)) {
|
|
98863
99094
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
98864
99095
|
}
|
|
98865
|
-
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY &&
|
|
99096
|
+
if (!process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY && existsSync80(png)) {
|
|
98866
99097
|
process.env.HF_PNG_DECODE_BLIT_WORKER_ENTRY = png;
|
|
98867
99098
|
}
|
|
98868
99099
|
})();
|
|
@@ -98874,10 +99105,10 @@ if (rootVersionRequested) {
|
|
|
98874
99105
|
process.exit(0);
|
|
98875
99106
|
}
|
|
98876
99107
|
try {
|
|
98877
|
-
const { readFileSync:
|
|
99108
|
+
const { readFileSync: readFileSync57 } = await import("fs");
|
|
98878
99109
|
const { resolve: resolve46 } = await import("path");
|
|
98879
99110
|
const envPath = resolve46(process.cwd(), ".env");
|
|
98880
|
-
const envContent =
|
|
99111
|
+
const envContent = readFileSync57(envPath, "utf-8");
|
|
98881
99112
|
for (const rawLine of envContent.split("\n")) {
|
|
98882
99113
|
let line = rawLine.trim();
|
|
98883
99114
|
if (!line || line.startsWith("#")) continue;
|