hyperframes 0.8.57 → 0.8.58
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 +1050 -444
- package/dist/fontLocalizeCli.js +2 -2
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-c23wnIfc.js → hyperframes-player-zGyOcwwh.js} +1 -1
- package/dist/studio/assets/{index-DgkAzx3n.js → index-BcE2OSVA.js} +1 -1
- package/dist/studio/assets/{index-IDNr3X1H.js → index-ZJaRCDYV.js} +1 -1
- package/dist/studio/assets/{index-gbOCDCuZ.js → index-d8ferjRc.js} +123 -123
- package/dist/studio/index.d.ts +30 -1
- package/dist/studio/index.html +1 -1
- package/dist/studio/index.js +1217 -1151
- package/dist/studio/index.js.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.8.
|
|
53
|
+
VERSION = true ? "0.8.58" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -4887,7 +4887,7 @@ var require_util = __commonJS({
|
|
|
4887
4887
|
return path;
|
|
4888
4888
|
}
|
|
4889
4889
|
exports.normalize = normalize3;
|
|
4890
|
-
function
|
|
4890
|
+
function join157(aRoot, aPath) {
|
|
4891
4891
|
if (aRoot === "") {
|
|
4892
4892
|
aRoot = ".";
|
|
4893
4893
|
}
|
|
@@ -4919,7 +4919,7 @@ var require_util = __commonJS({
|
|
|
4919
4919
|
}
|
|
4920
4920
|
return joined;
|
|
4921
4921
|
}
|
|
4922
|
-
exports.join =
|
|
4922
|
+
exports.join = join157;
|
|
4923
4923
|
exports.isAbsolute = function(aPath) {
|
|
4924
4924
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
4925
4925
|
};
|
|
@@ -5092,7 +5092,7 @@ var require_util = __commonJS({
|
|
|
5092
5092
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
5093
5093
|
}
|
|
5094
5094
|
}
|
|
5095
|
-
sourceURL =
|
|
5095
|
+
sourceURL = join157(urlGenerate(parsed), sourceURL);
|
|
5096
5096
|
}
|
|
5097
5097
|
return normalize3(sourceURL);
|
|
5098
5098
|
}
|
|
@@ -13450,8 +13450,8 @@ var require_lines = __commonJS({
|
|
|
13450
13450
|
if (isOnlyWhitespace(sliced)) {
|
|
13451
13451
|
continue;
|
|
13452
13452
|
}
|
|
13453
|
-
var
|
|
13454
|
-
counts[
|
|
13453
|
+
var diff2 = Math.abs(info.indent - lastIndent);
|
|
13454
|
+
counts[diff2] = ~~counts[diff2] + 1;
|
|
13455
13455
|
lastIndent = info.indent;
|
|
13456
13456
|
}
|
|
13457
13457
|
var maxCount = -1;
|
|
@@ -13477,12 +13477,12 @@ var require_lines = __commonJS({
|
|
|
13477
13477
|
Lines2.prototype.isPrecededOnlyByWhitespace = function(pos) {
|
|
13478
13478
|
var info = this.infos[pos.line - 1];
|
|
13479
13479
|
var indent = Math.max(info.indent, 0);
|
|
13480
|
-
var
|
|
13481
|
-
if (
|
|
13480
|
+
var diff2 = pos.column - indent;
|
|
13481
|
+
if (diff2 <= 0) {
|
|
13482
13482
|
return true;
|
|
13483
13483
|
}
|
|
13484
13484
|
var start = info.sliceStart;
|
|
13485
|
-
var end = Math.min(start +
|
|
13485
|
+
var end = Math.min(start + diff2, info.sliceEnd);
|
|
13486
13486
|
var prefix = info.line.slice(start, end);
|
|
13487
13487
|
return isOnlyWhitespace(prefix);
|
|
13488
13488
|
};
|
|
@@ -67717,9 +67717,9 @@ function motionBlurWindowIsStatic(plan2, frameIndex, staticFrames) {
|
|
|
67717
67717
|
}
|
|
67718
67718
|
return true;
|
|
67719
67719
|
}
|
|
67720
|
-
function adaptiveSampleCount(
|
|
67720
|
+
function adaptiveSampleCount(diff2) {
|
|
67721
67721
|
for (const step of ADAPTIVE_SAMPLE_STEPS) {
|
|
67722
|
-
if (
|
|
67722
|
+
if (diff2 <= step.maxDiff) return step.samples;
|
|
67723
67723
|
}
|
|
67724
67724
|
return MAX_SAMPLES_PER_FRAME;
|
|
67725
67725
|
}
|
|
@@ -93681,10 +93681,10 @@ function simplifyVolumeKeyframes(keyframes) {
|
|
|
93681
93681
|
return sampled;
|
|
93682
93682
|
}
|
|
93683
93683
|
function buildVolumeExpression(track, ignoreKeyframes = false) {
|
|
93684
|
-
const
|
|
93684
|
+
const trimDuration2 = track.end - track.start;
|
|
93685
93685
|
const staticVolume = clampVolume(track.volume);
|
|
93686
93686
|
const keyframes = (ignoreKeyframes ? [] : track.volumeKeyframes ?? []).filter((keyframe) => Number.isFinite(keyframe.time) && Number.isFinite(keyframe.volume)).map((keyframe) => ({
|
|
93687
|
-
time: Math.max(0, Math.min(
|
|
93687
|
+
time: Math.max(0, Math.min(trimDuration2, keyframe.time - track.start)),
|
|
93688
93688
|
volume: clampVolume(keyframe.volume)
|
|
93689
93689
|
})).sort((a, b2) => a.time - b2.time);
|
|
93690
93690
|
if (keyframes.length === 0) return `volume=${formatFilterNumber(staticVolume)}`;
|
|
@@ -94044,10 +94044,10 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
94044
94044
|
const filterParts = [];
|
|
94045
94045
|
tracks.forEach((track, i) => {
|
|
94046
94046
|
const delayMs = Math.round(track.start * 1e3);
|
|
94047
|
-
const
|
|
94047
|
+
const trimDuration2 = track.end - track.start + (track.tailSeconds ?? 0);
|
|
94048
94048
|
const volumeFilter = buildVolumeExpression(track, ignoreAutomation);
|
|
94049
94049
|
filterParts.push(
|
|
94050
|
-
`[${i}:a]atrim=0:${formatFilterNumber(
|
|
94050
|
+
`[${i}:a]atrim=0:${formatFilterNumber(trimDuration2)},${volumeFilter},adelay=${delayMs}|${delayMs},apad,asetpts=N/SR/TB,atrim=0:${formatFilterNumber(totalDuration)}[a${i}]`
|
|
94051
94051
|
);
|
|
94052
94052
|
});
|
|
94053
94053
|
const mixInputs = tracks.map((_, i) => `[a${i}]`).join("");
|
|
@@ -94150,9 +94150,9 @@ async function mixGroupMembers(memberTracks, outputPath, totalDuration, signal,
|
|
|
94150
94150
|
if (!existsSync16(outputDir)) mkdirSync8(outputDir, { recursive: true });
|
|
94151
94151
|
const buildInputFilters = (ignoreKeyframes) => memberTracks.map((track, i) => {
|
|
94152
94152
|
const delayMs = Math.round(track.start * 1e3);
|
|
94153
|
-
const
|
|
94153
|
+
const trimDuration2 = track.end - track.start + (track.tailSeconds ?? 0);
|
|
94154
94154
|
const volumeFilter = buildVolumeExpression(track, ignoreKeyframes);
|
|
94155
|
-
return `[${i}:a]atrim=0:${formatFilterNumber(
|
|
94155
|
+
return `[${i}:a]atrim=0:${formatFilterNumber(trimDuration2)},${volumeFilter},adelay=${delayMs}|${delayMs},apad,asetpts=N/SR/TB,atrim=0:${formatFilterNumber(totalDuration)}[a${i}]`;
|
|
94156
94156
|
});
|
|
94157
94157
|
const mixInputs = memberTracks.map((_, i) => `[a${i}]`).join("");
|
|
94158
94158
|
const runOnce = async (useNormalize2, ignoreKeyframes = false) => {
|
|
@@ -95579,27 +95579,27 @@ function diffGpuParityPngs(pngA, pngB, options = {}) {
|
|
|
95579
95579
|
return diffGpuParityFrames(a, b2, options);
|
|
95580
95580
|
}
|
|
95581
95581
|
function verifyGpuParity(a, b2, options = {}) {
|
|
95582
|
-
const
|
|
95582
|
+
const diff2 = diffGpuParityFrames(a, b2, options);
|
|
95583
95583
|
const threshold = options.blackOnlyFractionThreshold ?? DEFAULT_BLACK_ONLY_FRACTION_THRESHOLD;
|
|
95584
|
-
if (
|
|
95585
|
-
const bb =
|
|
95584
|
+
if (diff2.blackOnlyInA.fraction > threshold) {
|
|
95585
|
+
const bb = diff2.blackOnlyInA.boundingBox;
|
|
95586
95586
|
const region = bb ? ` (bbox ${bb.x},${bb.y} ${bb.width}x${bb.height})` : "";
|
|
95587
95587
|
return {
|
|
95588
95588
|
ok: false,
|
|
95589
|
-
reason: `hardware-GPU frame has ${
|
|
95590
|
-
diff
|
|
95589
|
+
reason: `hardware-GPU frame has ${diff2.blackOnlyInA.pixels} pixel(s) (${(diff2.blackOnlyInA.fraction * 100).toFixed(3)}%) that are solid-black while software-GPU frame has content there${region} \u2014 likely shape-dependent hardware-GPU capture bug`,
|
|
95590
|
+
diff: diff2
|
|
95591
95591
|
};
|
|
95592
95592
|
}
|
|
95593
|
-
if (
|
|
95594
|
-
const bb =
|
|
95593
|
+
if (diff2.blackOnlyInB.fraction > threshold) {
|
|
95594
|
+
const bb = diff2.blackOnlyInB.boundingBox;
|
|
95595
95595
|
const region = bb ? ` (bbox ${bb.x},${bb.y} ${bb.width}x${bb.height})` : "";
|
|
95596
95596
|
return {
|
|
95597
95597
|
ok: false,
|
|
95598
|
-
reason: `software-GPU frame has ${
|
|
95599
|
-
diff
|
|
95598
|
+
reason: `software-GPU frame has ${diff2.blackOnlyInB.pixels} pixel(s) (${(diff2.blackOnlyInB.fraction * 100).toFixed(3)}%) that are solid-black while hardware-GPU frame has content there${region} \u2014 unexpected inverse pattern, worth investigating`,
|
|
95599
|
+
diff: diff2
|
|
95600
95600
|
};
|
|
95601
95601
|
}
|
|
95602
|
-
return { ok: true, reason: "", diff };
|
|
95602
|
+
return { ok: true, reason: "", diff: diff2 };
|
|
95603
95603
|
}
|
|
95604
95604
|
var DEFAULT_PIXEL_CHANNEL_TOLERANCE, DEFAULT_BLACK_SUM_THRESHOLD, DEFAULT_CONTENT_SUM_THRESHOLD, DEFAULT_BLACK_ONLY_FRACTION_THRESHOLD;
|
|
95605
95605
|
var init_gpuParityDiff = __esm({
|
|
@@ -103585,7 +103585,7 @@ var require_compile = __commonJS({
|
|
|
103585
103585
|
}
|
|
103586
103586
|
}
|
|
103587
103587
|
exports.compileSchema = compileSchema;
|
|
103588
|
-
function
|
|
103588
|
+
function resolveRef2(root, baseId, ref2) {
|
|
103589
103589
|
var _a3;
|
|
103590
103590
|
ref2 = (0, resolve_1.resolveUrl)(this.opts.uriResolver, baseId, ref2);
|
|
103591
103591
|
const schOrFunc = root.refs[ref2];
|
|
@@ -103602,7 +103602,7 @@ var require_compile = __commonJS({
|
|
|
103602
103602
|
return;
|
|
103603
103603
|
return root.refs[ref2] = inlineOrCompile.call(this, _sch);
|
|
103604
103604
|
}
|
|
103605
|
-
exports.resolveRef =
|
|
103605
|
+
exports.resolveRef = resolveRef2;
|
|
103606
103606
|
function inlineOrCompile(sch) {
|
|
103607
103607
|
if ((0, resolve_1.inlineRef)(sch.schema, this.opts.inlineRefs))
|
|
103608
103608
|
return sch.schema;
|
|
@@ -111061,7 +111061,7 @@ async function checkSkills(opts = {}) {
|
|
|
111061
111061
|
const skillNames = Object.keys(latest.skills);
|
|
111062
111062
|
const root = locateInstall(skillNames, { dir: opts.dir, cwd: opts.cwd, home: opts.home });
|
|
111063
111063
|
const installed = root ? hashInstalled(root, skillNames) : {};
|
|
111064
|
-
const
|
|
111064
|
+
const diff2 = diffSkills(installed, latest);
|
|
111065
111065
|
const removedResult = root ? detectRemoved(root, latest, { cwd: opts.cwd, home: opts.home }) : { removed: [], lockMissing: false };
|
|
111066
111066
|
const { removed, lockMissing } = removedResult;
|
|
111067
111067
|
return {
|
|
@@ -111070,9 +111070,9 @@ async function checkSkills(opts = {}) {
|
|
|
111070
111070
|
scope: root?.scope ?? null,
|
|
111071
111071
|
// Removed skills also mean the install isn't reconciled with the manifest —
|
|
111072
111072
|
// `skills update` now prunes them, so they count toward "update available".
|
|
111073
|
-
updateAvailable:
|
|
111074
|
-
summary: { ...
|
|
111075
|
-
skills: [...
|
|
111073
|
+
updateAvailable: diff2.updateAvailable || removed.length > 0,
|
|
111074
|
+
summary: { ...diff2.summary, removed: removed.length },
|
|
111075
|
+
skills: [...diff2.skills, ...removed],
|
|
111076
111076
|
lockMissing
|
|
111077
111077
|
};
|
|
111078
111078
|
}
|
|
@@ -121471,8 +121471,8 @@ import {
|
|
|
121471
121471
|
existsSync as existsSync37,
|
|
121472
121472
|
ftruncateSync as ftruncateSync2,
|
|
121473
121473
|
openSync as openSync8,
|
|
121474
|
-
readFileSync as
|
|
121475
|
-
writeFileSync as
|
|
121474
|
+
readFileSync as readFileSync52,
|
|
121475
|
+
writeFileSync as writeFileSync52,
|
|
121476
121476
|
writeSync as writeSync2,
|
|
121477
121477
|
mkdirSync as mkdirSync32,
|
|
121478
121478
|
unlinkSync as unlinkSync23,
|
|
@@ -121502,14 +121502,15 @@ import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as
|
|
|
121502
121502
|
import { Buffer as Buffer2 } from "buffer";
|
|
121503
121503
|
import { join as join52, relative as relative22 } from "path";
|
|
121504
121504
|
import { createHash as createHash22, randomUUID as randomUUID9 } from "crypto";
|
|
121505
|
-
import {
|
|
121505
|
+
import { readFileSync as readFileSync32, writeFileSync as writeFileSync42 } from "fs";
|
|
121506
|
+
import { existsSync as existsSync211, readFileSync as readFileSync42, realpathSync as realpathSync8 } from "fs";
|
|
121506
121507
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
121507
121508
|
import { dirname as dirname22, relative as relative32, resolve as resolve24, sep as sep22 } from "path";
|
|
121508
|
-
import { createReadStream as createReadStream3, existsSync as existsSync52, readFileSync as
|
|
121509
|
+
import { createReadStream as createReadStream3, existsSync as existsSync52, readFileSync as readFileSync82, statSync as statSync32 } from "fs";
|
|
121509
121510
|
import { Readable as Readable2 } from "stream";
|
|
121510
121511
|
import { join as join82, resolve as resolve42 } from "path";
|
|
121511
121512
|
import { createHash as createHash32 } from "crypto";
|
|
121512
|
-
import { existsSync as existsSync42, readFileSync as
|
|
121513
|
+
import { existsSync as existsSync42, readFileSync as readFileSync62 } from "fs";
|
|
121513
121514
|
import { join as join72 } from "path";
|
|
121514
121515
|
import {
|
|
121515
121516
|
closeSync as closeSync22,
|
|
@@ -121517,35 +121518,35 @@ import {
|
|
|
121517
121518
|
fstatSync as fstatSync4,
|
|
121518
121519
|
ftruncateSync as ftruncateSync22,
|
|
121519
121520
|
openSync as openSync22,
|
|
121520
|
-
readFileSync as
|
|
121521
|
-
writeFileSync as
|
|
121521
|
+
readFileSync as readFileSync72,
|
|
121522
|
+
writeFileSync as writeFileSync62,
|
|
121522
121523
|
writeSync as writeSync22
|
|
121523
121524
|
} from "fs";
|
|
121524
|
-
import { readFileSync as
|
|
121525
|
+
import { readFileSync as readFileSync92 } from "fs";
|
|
121525
121526
|
import { join as join92 } from "path";
|
|
121526
121527
|
import { streamSSE } from "hono/streaming";
|
|
121527
|
-
import { existsSync as existsSync62, readFileSync as
|
|
121528
|
+
import { existsSync as existsSync62, readFileSync as readFileSync102, mkdirSync as mkdirSync42, unlinkSync as unlinkSync32, readdirSync as readdirSync52, statSync as statSync42 } from "fs";
|
|
121528
121529
|
import { join as join102 } from "path";
|
|
121529
121530
|
import {
|
|
121530
121531
|
existsSync as existsSync72,
|
|
121531
121532
|
mkdirSync as mkdirSync52,
|
|
121532
|
-
readFileSync as
|
|
121533
|
+
readFileSync as readFileSync112,
|
|
121533
121534
|
readdirSync as readdirSync62,
|
|
121534
121535
|
renameSync as renameSync32,
|
|
121535
121536
|
rmSync as rmSync42,
|
|
121536
121537
|
statSync as statSync52,
|
|
121537
121538
|
unlinkSync as unlinkSync42,
|
|
121538
|
-
writeFileSync as
|
|
121539
|
+
writeFileSync as writeFileSync72
|
|
121539
121540
|
} from "fs";
|
|
121540
121541
|
import { join as join112 } from "path";
|
|
121541
121542
|
import { createHash as createHash42, randomUUID as randomUUID32 } from "crypto";
|
|
121542
|
-
import { existsSync as existsSync82, readFileSync as
|
|
121543
|
+
import { existsSync as existsSync82, readFileSync as readFileSync122, statSync as statSync62 } from "fs";
|
|
121543
121544
|
import { join as join122 } from "path";
|
|
121544
121545
|
import { closeSync as closeSync32, constants as constants22, fstatSync as fstatSync22, openSync as openSync32, readSync as readSync2 } from "fs";
|
|
121545
121546
|
import { streamSSE as streamSSE2 } from "hono/streaming";
|
|
121546
121547
|
import { existsSync as existsSync92, mkdirSync as mkdirSync62 } from "fs";
|
|
121547
121548
|
import { basename as basename22, dirname as dirname42, extname as extname22, join as join132 } from "path";
|
|
121548
|
-
import { existsSync as existsSync102, readFileSync as
|
|
121549
|
+
import { existsSync as existsSync102, readFileSync as readFileSync132 } from "fs";
|
|
121549
121550
|
import { homedir as homedir10 } from "os";
|
|
121550
121551
|
import { join as join142 } from "path";
|
|
121551
121552
|
function shouldIgnoreDir(rel) {
|
|
@@ -121956,6 +121957,13 @@ function recordFileWriteReceipt(absPath, receipt) {
|
|
|
121956
121957
|
current2.push({ ...receipt, recordedAt: now });
|
|
121957
121958
|
receipts.set(absPath, current2);
|
|
121958
121959
|
}
|
|
121960
|
+
function clearFileWriteReceipt(absPath, version2, writeToken) {
|
|
121961
|
+
const current2 = (receipts.get(absPath) ?? []).filter(
|
|
121962
|
+
(entry) => entry.version !== version2 || entry.writeToken !== writeToken
|
|
121963
|
+
);
|
|
121964
|
+
if (current2.length > 0) receipts.set(absPath, current2);
|
|
121965
|
+
else receipts.delete(absPath);
|
|
121966
|
+
}
|
|
121959
121967
|
function identifyFileWrite(absPath, expectedVersion) {
|
|
121960
121968
|
const now = Date.now();
|
|
121961
121969
|
const current2 = (receipts.get(absPath) ?? []).filter(
|
|
@@ -121971,6 +121979,76 @@ function identifyFileWrite(absPath, expectedVersion) {
|
|
|
121971
121979
|
const { path, version: version2, writeToken } = receipt;
|
|
121972
121980
|
return { path, version: version2, writeToken };
|
|
121973
121981
|
}
|
|
121982
|
+
function applyFileMutations(projectDir, mutations, requestToken, writeFile3 = writeFileSync42) {
|
|
121983
|
+
const prepared = mutations.map((mutation) => ({
|
|
121984
|
+
...mutation,
|
|
121985
|
+
before: mutation.before ?? readFileSync32(mutation.absPath, "utf-8")
|
|
121986
|
+
}));
|
|
121987
|
+
const results = [];
|
|
121988
|
+
const attempted = [];
|
|
121989
|
+
try {
|
|
121990
|
+
for (const mutation of prepared) {
|
|
121991
|
+
results.push(applyOneMutation(projectDir, mutation, requestToken, writeFile3, attempted));
|
|
121992
|
+
}
|
|
121993
|
+
return results;
|
|
121994
|
+
} catch (error) {
|
|
121995
|
+
const rollbackErrors = [];
|
|
121996
|
+
for (const mutation of attempted.reverse()) {
|
|
121997
|
+
try {
|
|
121998
|
+
writeFile3(mutation.absPath, mutation.before, "utf-8");
|
|
121999
|
+
clearFileWriteReceipt(mutation.absPath, mutation.version, mutation.writeToken);
|
|
122000
|
+
} catch (rollbackError) {
|
|
122001
|
+
rollbackErrors.push(rollbackError);
|
|
122002
|
+
}
|
|
122003
|
+
}
|
|
122004
|
+
if (rollbackErrors.length > 0) {
|
|
122005
|
+
throw new AggregateError(
|
|
122006
|
+
[error, ...rollbackErrors],
|
|
122007
|
+
"File mutation failed and rollback did not complete"
|
|
122008
|
+
);
|
|
122009
|
+
}
|
|
122010
|
+
throw error;
|
|
122011
|
+
}
|
|
122012
|
+
}
|
|
122013
|
+
function applyOneMutation(projectDir, mutation, requestToken, writeFile3, attempted) {
|
|
122014
|
+
const current2 = readFileSync32(mutation.absPath, "utf-8");
|
|
122015
|
+
assertExpectedVersion(mutation.expectedVersion, current2);
|
|
122016
|
+
if (mutation.after === mutation.before) {
|
|
122017
|
+
return {
|
|
122018
|
+
...mutation,
|
|
122019
|
+
before: current2,
|
|
122020
|
+
changed: false,
|
|
122021
|
+
backupPath: null,
|
|
122022
|
+
version: fileContentVersion(mutation.before),
|
|
122023
|
+
writeToken: null
|
|
122024
|
+
};
|
|
122025
|
+
}
|
|
122026
|
+
const backup = snapshotBeforeWrite(projectDir, mutation.absPath);
|
|
122027
|
+
if (backup.error) throw new Error(`backup failed: ${backup.error}`);
|
|
122028
|
+
const before3 = current2;
|
|
122029
|
+
const version2 = fileContentVersion(mutation.after);
|
|
122030
|
+
const writeToken = createWriteToken(requestToken);
|
|
122031
|
+
attempted.push({ ...mutation, before: before3, version: version2, writeToken });
|
|
122032
|
+
writeFile3(mutation.absPath, mutation.after, "utf-8");
|
|
122033
|
+
recordFileWriteReceipt(mutation.absPath, {
|
|
122034
|
+
path: mutation.sourceFile,
|
|
122035
|
+
version: version2,
|
|
122036
|
+
writeToken
|
|
122037
|
+
});
|
|
122038
|
+
return {
|
|
122039
|
+
...mutation,
|
|
122040
|
+
before: before3,
|
|
122041
|
+
changed: true,
|
|
122042
|
+
backupPath: backupPathForResponse(projectDir, backup.backupPath),
|
|
122043
|
+
version: version2,
|
|
122044
|
+
writeToken
|
|
122045
|
+
};
|
|
122046
|
+
}
|
|
122047
|
+
function assertExpectedVersion(expectedVersion, current2) {
|
|
122048
|
+
if (expectedVersion !== void 0 && fileContentVersion(current2) !== expectedVersion) {
|
|
122049
|
+
throw new Error("file changed since the timeline was read");
|
|
122050
|
+
}
|
|
122051
|
+
}
|
|
121974
122052
|
function descendants(root, selector) {
|
|
121975
122053
|
const found = Array.from(root.querySelectorAll(selector));
|
|
121976
122054
|
for (const template of root.querySelectorAll("template")) {
|
|
@@ -122032,7 +122110,7 @@ function validateDependencyGraph(projectDir, targetAbs, sourceAbs) {
|
|
|
122032
122110
|
}
|
|
122033
122111
|
if (visited.has(file)) return;
|
|
122034
122112
|
visiting.add(file);
|
|
122035
|
-
const source =
|
|
122113
|
+
const source = readFileSync42(file, "utf-8");
|
|
122036
122114
|
const { document: document2 } = compositionRoot(source);
|
|
122037
122115
|
for (const host of descendants(document2, "[data-composition-src]")) {
|
|
122038
122116
|
const dependency = host.getAttribute("data-composition-src");
|
|
@@ -122096,7 +122174,7 @@ function insertCompositionIntoSource(input2) {
|
|
|
122096
122174
|
const targetAbs = canonicalProjectFile(input2.projectDir, input2.targetPath);
|
|
122097
122175
|
const sourceAbs = canonicalProjectFile(input2.projectDir, input2.sourcePath);
|
|
122098
122176
|
validateDependencyGraph(input2.projectDir, targetAbs, sourceAbs);
|
|
122099
|
-
const source =
|
|
122177
|
+
const source = readFileSync42(sourceAbs, "utf-8");
|
|
122100
122178
|
const sourceComposition = compositionRoot(source).root;
|
|
122101
122179
|
const duration = positiveAttribute(
|
|
122102
122180
|
sourceComposition,
|
|
@@ -122224,7 +122302,7 @@ function foldElementPatches(originalContent, patches) {
|
|
|
122224
122302
|
}
|
|
122225
122303
|
return { content, matched };
|
|
122226
122304
|
}
|
|
122227
|
-
function commitElementPatchBatches(projectDir, batches, writeFile3 =
|
|
122305
|
+
function commitElementPatchBatches(projectDir, batches, writeFile3 = writeFileSync52, requestToken) {
|
|
122228
122306
|
const resolvedPaths = /* @__PURE__ */ new Set();
|
|
122229
122307
|
const prepared = [];
|
|
122230
122308
|
for (const batch of batches) {
|
|
@@ -122234,7 +122312,7 @@ function commitElementPatchBatches(projectDir, batches, writeFile3 = writeFileSy
|
|
|
122234
122312
|
resolvedPaths.add(absPath);
|
|
122235
122313
|
let before3;
|
|
122236
122314
|
try {
|
|
122237
|
-
before3 =
|
|
122315
|
+
before3 = readFileSync52(absPath, "utf-8");
|
|
122238
122316
|
} catch {
|
|
122239
122317
|
return { error: "not-found", sourceFile: batch.sourceFile };
|
|
122240
122318
|
}
|
|
@@ -122260,64 +122338,34 @@ function commitElementPatchBatches(projectDir, batches, writeFile3 = writeFileSy
|
|
|
122260
122338
|
}))
|
|
122261
122339
|
};
|
|
122262
122340
|
}
|
|
122263
|
-
const
|
|
122264
|
-
|
|
122265
|
-
|
|
122266
|
-
|
|
122267
|
-
|
|
122268
|
-
|
|
122269
|
-
|
|
122270
|
-
|
|
122271
|
-
|
|
122272
|
-
|
|
122273
|
-
|
|
122274
|
-
|
|
122275
|
-
|
|
122276
|
-
|
|
122277
|
-
|
|
122278
|
-
|
|
122279
|
-
|
|
122280
|
-
|
|
122281
|
-
|
|
122282
|
-
writeFile3(file.absPath, file.after, "utf-8");
|
|
122283
|
-
files.push({
|
|
122284
|
-
sourceFile: file.sourceFile,
|
|
122285
|
-
changed: true,
|
|
122286
|
-
matched: file.matched,
|
|
122287
|
-
before: file.before,
|
|
122288
|
-
after: file.after,
|
|
122289
|
-
backupPath: backupPathForResponse(projectDir, backup.backupPath)
|
|
122290
|
-
});
|
|
122291
|
-
}
|
|
122292
|
-
} catch (error) {
|
|
122293
|
-
const rollbackErrors = [];
|
|
122294
|
-
for (const file of attemptedWrites.reverse()) {
|
|
122295
|
-
try {
|
|
122296
|
-
writeFile3(file.absPath, file.before, "utf-8");
|
|
122297
|
-
} catch (rollbackError) {
|
|
122298
|
-
rollbackErrors.push(rollbackError);
|
|
122299
|
-
}
|
|
122300
|
-
}
|
|
122301
|
-
if (rollbackErrors.length > 0) {
|
|
122302
|
-
throw new AggregateError(
|
|
122303
|
-
[error, ...rollbackErrors],
|
|
122304
|
-
"Element patch batch failed and rollback did not complete"
|
|
122305
|
-
);
|
|
122306
|
-
}
|
|
122307
|
-
throw error;
|
|
122308
|
-
}
|
|
122341
|
+
const applied = applyFileMutations(
|
|
122342
|
+
projectDir,
|
|
122343
|
+
prepared.map(({ sourceFile, absPath, before: before3, after: after2 }) => ({
|
|
122344
|
+
sourceFile,
|
|
122345
|
+
absPath,
|
|
122346
|
+
before: before3,
|
|
122347
|
+
after: after2
|
|
122348
|
+
})),
|
|
122349
|
+
requestToken,
|
|
122350
|
+
writeFile3
|
|
122351
|
+
);
|
|
122352
|
+
const files = applied.map((file, index) => ({
|
|
122353
|
+
sourceFile: file.sourceFile,
|
|
122354
|
+
changed: file.changed,
|
|
122355
|
+
matched: prepared[index]?.matched ?? [],
|
|
122356
|
+
before: file.before,
|
|
122357
|
+
after: file.after,
|
|
122358
|
+
backupPath: file.backupPath ?? void 0
|
|
122359
|
+
}));
|
|
122309
122360
|
return { durable: true, files };
|
|
122310
122361
|
}
|
|
122311
122362
|
function commitElementPatchBatchesWithReceipts(c3, projectDir, batches) {
|
|
122312
|
-
|
|
122313
|
-
|
|
122314
|
-
|
|
122315
|
-
|
|
122316
|
-
|
|
122317
|
-
|
|
122318
|
-
recordMutationReceipt(c3, file.sourceFile, absPath, file.after);
|
|
122319
|
-
}
|
|
122320
|
-
return result;
|
|
122363
|
+
return commitElementPatchBatches(
|
|
122364
|
+
projectDir,
|
|
122365
|
+
batches,
|
|
122366
|
+
writeFileSync52,
|
|
122367
|
+
c3.req.header("X-Hyperframes-Write-Token")
|
|
122368
|
+
);
|
|
122321
122369
|
}
|
|
122322
122370
|
function recordMutationReceipt(c3, filePath, absPath, html) {
|
|
122323
122371
|
const version2 = fileContentVersion(html);
|
|
@@ -122326,7 +122374,7 @@ function recordMutationReceipt(c3, filePath, absPath, html) {
|
|
|
122326
122374
|
return { version: version2, writeToken };
|
|
122327
122375
|
}
|
|
122328
122376
|
function writeFileWithReceipt(c3, filePath, absPath, html) {
|
|
122329
|
-
|
|
122377
|
+
writeFileSync52(absPath, html, "utf-8");
|
|
122330
122378
|
return recordMutationReceipt(c3, filePath, absPath, html);
|
|
122331
122379
|
}
|
|
122332
122380
|
function writeMutationResult(c3, projectDir, filePath, absPath, html) {
|
|
@@ -122339,9 +122387,9 @@ function writeIfChanged(c3, projectDir, filePath, absPath, original, next) {
|
|
|
122339
122387
|
if (next === original) {
|
|
122340
122388
|
return c3.json({ ok: true, changed: false, content: original, path: filePath });
|
|
122341
122389
|
}
|
|
122342
|
-
const
|
|
122343
|
-
if (
|
|
122344
|
-
const { backupPath } =
|
|
122390
|
+
const mutationResult2 = writeMutationResult(c3, projectDir, filePath, absPath, next);
|
|
122391
|
+
if (mutationResult2 instanceof Response) return mutationResult2;
|
|
122392
|
+
const { backupPath } = mutationResult2;
|
|
122345
122393
|
return c3.json({
|
|
122346
122394
|
ok: true,
|
|
122347
122395
|
changed: true,
|
|
@@ -122411,11 +122459,11 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
122411
122459
|
let updatedCount = 0;
|
|
122412
122460
|
for (const file of textFiles) {
|
|
122413
122461
|
if (!isSafePath(projectDir, file)) continue;
|
|
122414
|
-
const content =
|
|
122462
|
+
const content = readFileSync52(file, "utf-8");
|
|
122415
122463
|
if (!content.includes(oldPath)) continue;
|
|
122416
122464
|
const updated = content.split(oldPath).join(newPath);
|
|
122417
122465
|
if (updated !== content) {
|
|
122418
|
-
|
|
122466
|
+
writeFileSync52(file, updated, "utf-8");
|
|
122419
122467
|
updatedCount++;
|
|
122420
122468
|
}
|
|
122421
122469
|
}
|
|
@@ -122654,7 +122702,7 @@ function containsRawGsapExpression(value) {
|
|
|
122654
122702
|
return Object.values(value).some(containsRawGsapExpression);
|
|
122655
122703
|
}
|
|
122656
122704
|
async function prepareGsapMutationScript(c3, res, firstMutation) {
|
|
122657
|
-
const beforeHtml =
|
|
122705
|
+
const beforeHtml = readFileSync52(res.absPath, "utf-8");
|
|
122658
122706
|
let html = beforeHtml;
|
|
122659
122707
|
let block = extractGsapScriptBlock(html);
|
|
122660
122708
|
if (!block && (firstMutation.type === "add" || firstMutation.type === "add-with-keyframes")) {
|
|
@@ -122721,19 +122769,19 @@ async function applyGsapMutations(c3, res, mutations) {
|
|
|
122721
122769
|
const changed = block.scriptText !== initialScript;
|
|
122722
122770
|
const newHtml = changed ? block.replaceScript(block.scriptText) : html;
|
|
122723
122771
|
let backupPath = null;
|
|
122724
|
-
if (
|
|
122772
|
+
if (readFileSync52(res.absPath, "utf-8") !== beforeHtml) {
|
|
122725
122773
|
return c3.json({ error: "file changed during GSAP mutation", conflict: true }, 409);
|
|
122726
122774
|
}
|
|
122727
122775
|
if (changed) {
|
|
122728
|
-
const
|
|
122776
|
+
const mutationResult2 = writeMutationResult(
|
|
122729
122777
|
c3,
|
|
122730
122778
|
res.project.dir,
|
|
122731
122779
|
res.filePath,
|
|
122732
122780
|
res.absPath,
|
|
122733
122781
|
newHtml
|
|
122734
122782
|
);
|
|
122735
|
-
if (
|
|
122736
|
-
backupPath =
|
|
122783
|
+
if (mutationResult2 instanceof Response) return mutationResult2;
|
|
122784
|
+
backupPath = mutationResult2.backupPath;
|
|
122737
122785
|
}
|
|
122738
122786
|
const responsePayload = {
|
|
122739
122787
|
ok: true,
|
|
@@ -123504,7 +123552,7 @@ async function processUploadedFiles(formData, targetDir, projectDir) {
|
|
|
123504
123552
|
try {
|
|
123505
123553
|
const fd = openSync8(finalPath, "wx");
|
|
123506
123554
|
try {
|
|
123507
|
-
|
|
123555
|
+
writeFileSync52(fd, buffer);
|
|
123508
123556
|
} finally {
|
|
123509
123557
|
closeSync8(fd);
|
|
123510
123558
|
}
|
|
@@ -123542,7 +123590,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123542
123590
|
}
|
|
123543
123591
|
return c3.json({ error: "not found" }, 404);
|
|
123544
123592
|
}
|
|
123545
|
-
const content =
|
|
123593
|
+
const content = readFileSync52(res.absPath);
|
|
123546
123594
|
const version2 = fileContentVersion(content);
|
|
123547
123595
|
c3.header("ETag", version2);
|
|
123548
123596
|
return c3.json({ filename: res.filePath, content: content.toString("utf-8"), version: version2 });
|
|
@@ -123556,7 +123604,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123556
123604
|
if (expectedVersion === null && !createOnly) {
|
|
123557
123605
|
let currentContent = null;
|
|
123558
123606
|
try {
|
|
123559
|
-
currentContent =
|
|
123607
|
+
currentContent = readFileSync52(res.absPath);
|
|
123560
123608
|
} catch (error) {
|
|
123561
123609
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "ENOENT") {
|
|
123562
123610
|
throw error;
|
|
@@ -123582,7 +123630,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123582
123630
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
123583
123631
|
throw error;
|
|
123584
123632
|
}
|
|
123585
|
-
const currentContent =
|
|
123633
|
+
const currentContent = readFileSync52(res.absPath);
|
|
123586
123634
|
return c3.json(
|
|
123587
123635
|
{
|
|
123588
123636
|
error: "file conflict",
|
|
@@ -123617,7 +123665,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123617
123665
|
);
|
|
123618
123666
|
}
|
|
123619
123667
|
try {
|
|
123620
|
-
const currentContent =
|
|
123668
|
+
const currentContent = readFileSync52(fd);
|
|
123621
123669
|
const currentVersion = fileContentVersion(currentContent);
|
|
123622
123670
|
if (expectedVersion !== currentVersion) {
|
|
123623
123671
|
return c3.json(
|
|
@@ -123656,7 +123704,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123656
123704
|
ensureDir(res.absPath);
|
|
123657
123705
|
const body = Buffer.from(await c3.req.arrayBuffer());
|
|
123658
123706
|
try {
|
|
123659
|
-
|
|
123707
|
+
writeFileSync52(res.absPath, body, { flag: "wx" });
|
|
123660
123708
|
} catch (error) {
|
|
123661
123709
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "EEXIST") {
|
|
123662
123710
|
throw error;
|
|
@@ -123690,7 +123738,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123690
123738
|
}
|
|
123691
123739
|
let before3;
|
|
123692
123740
|
try {
|
|
123693
|
-
before3 =
|
|
123741
|
+
before3 = readFileSync52(ctx.absPath, "utf-8");
|
|
123694
123742
|
} catch (error) {
|
|
123695
123743
|
if (!error || typeof error !== "object" || !("code" in error) || error.code !== "ENOENT") {
|
|
123696
123744
|
throw error;
|
|
@@ -123747,7 +123795,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123747
123795
|
}
|
|
123748
123796
|
const parsed = await parseMutationBody(c3);
|
|
123749
123797
|
if ("error" in parsed) return parsed.error;
|
|
123750
|
-
const originalContent =
|
|
123798
|
+
const originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
123751
123799
|
return writeIfChanged(
|
|
123752
123800
|
c3,
|
|
123753
123801
|
ctx.project.dir,
|
|
@@ -123768,7 +123816,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123768
123816
|
if (!Array.isArray(targets) || targets.length === 0) {
|
|
123769
123817
|
return c3.json({ error: "targets required" }, 400);
|
|
123770
123818
|
}
|
|
123771
|
-
const originalContent =
|
|
123819
|
+
const originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
123772
123820
|
let next = originalContent;
|
|
123773
123821
|
for (const target of targets) {
|
|
123774
123822
|
next = removeElementFromHtml2(next, target);
|
|
@@ -123801,7 +123849,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123801
123849
|
seen.add(absPath);
|
|
123802
123850
|
let before3;
|
|
123803
123851
|
try {
|
|
123804
|
-
before3 =
|
|
123852
|
+
before3 = readFileSync52(absPath, "utf-8");
|
|
123805
123853
|
} catch {
|
|
123806
123854
|
return c3.json({ error: `not found: ${file.path}` }, 404);
|
|
123807
123855
|
}
|
|
@@ -123828,7 +123876,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123828
123876
|
prepared.push(folded);
|
|
123829
123877
|
}
|
|
123830
123878
|
for (const file of prepared) {
|
|
123831
|
-
const current2 =
|
|
123879
|
+
const current2 = readFileSync52(file.absPath, "utf-8");
|
|
123832
123880
|
if (current2 !== file.before) {
|
|
123833
123881
|
return c3.json(
|
|
123834
123882
|
{
|
|
@@ -123858,7 +123906,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123858
123906
|
const written = [];
|
|
123859
123907
|
try {
|
|
123860
123908
|
for (const file of prepared) {
|
|
123861
|
-
|
|
123909
|
+
writeFileSync52(file.absPath, file.after, "utf-8");
|
|
123862
123910
|
written.push(file);
|
|
123863
123911
|
recordFileWriteReceipt(file.absPath, {
|
|
123864
123912
|
path: file.path,
|
|
@@ -123870,12 +123918,12 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123870
123918
|
const conflicts = [];
|
|
123871
123919
|
for (const file of written.reverse()) {
|
|
123872
123920
|
try {
|
|
123873
|
-
const current2 =
|
|
123921
|
+
const current2 = readFileSync52(file.absPath, "utf-8");
|
|
123874
123922
|
if (current2 !== file.after) {
|
|
123875
123923
|
conflicts.push(file.path);
|
|
123876
123924
|
continue;
|
|
123877
123925
|
}
|
|
123878
|
-
|
|
123926
|
+
writeFileSync52(file.absPath, file.before, "utf-8");
|
|
123879
123927
|
recordFileWriteReceipt(file.absPath, {
|
|
123880
123928
|
path: file.path,
|
|
123881
123929
|
version: fileContentVersion(file.before),
|
|
@@ -123918,7 +123966,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123918
123966
|
const fallbackTiming = typeof parsed.body.elementStart === "number" && typeof parsed.body.elementDuration === "number" ? { start: parsed.body.elementStart, duration: parsed.body.elementDuration } : void 0;
|
|
123919
123967
|
let originalContent;
|
|
123920
123968
|
try {
|
|
123921
|
-
originalContent =
|
|
123969
|
+
originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
123922
123970
|
} catch {
|
|
123923
123971
|
return c3.json({ error: "not found" }, 404);
|
|
123924
123972
|
}
|
|
@@ -123940,15 +123988,15 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123940
123988
|
version: version22
|
|
123941
123989
|
});
|
|
123942
123990
|
}
|
|
123943
|
-
const
|
|
123991
|
+
const mutationResult2 = writeMutationResult(
|
|
123944
123992
|
c3,
|
|
123945
123993
|
ctx.project.dir,
|
|
123946
123994
|
ctx.filePath,
|
|
123947
123995
|
ctx.absPath,
|
|
123948
123996
|
result.html
|
|
123949
123997
|
);
|
|
123950
|
-
if (
|
|
123951
|
-
const { version: version2, backupPath } =
|
|
123998
|
+
if (mutationResult2 instanceof Response) return mutationResult2;
|
|
123999
|
+
const { version: version2, backupPath } = mutationResult2;
|
|
123952
124000
|
c3.header("ETag", version2);
|
|
123953
124001
|
return c3.json({
|
|
123954
124002
|
ok: true,
|
|
@@ -123974,7 +124022,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123974
124022
|
}
|
|
123975
124023
|
let originalContent;
|
|
123976
124024
|
try {
|
|
123977
|
-
originalContent =
|
|
124025
|
+
originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
123978
124026
|
} catch {
|
|
123979
124027
|
return c3.json({ error: "not found" }, 404);
|
|
123980
124028
|
}
|
|
@@ -123995,15 +124043,15 @@ function registerFileRoutes(api, adapter2) {
|
|
|
123995
124043
|
version: version22
|
|
123996
124044
|
});
|
|
123997
124045
|
}
|
|
123998
|
-
const
|
|
124046
|
+
const mutationResult2 = writeMutationResult(
|
|
123999
124047
|
c3,
|
|
124000
124048
|
ctx.project.dir,
|
|
124001
124049
|
ctx.filePath,
|
|
124002
124050
|
ctx.absPath,
|
|
124003
124051
|
patched
|
|
124004
124052
|
);
|
|
124005
|
-
if (
|
|
124006
|
-
const { backupPath, version: version2 } =
|
|
124053
|
+
if (mutationResult2 instanceof Response) return mutationResult2;
|
|
124054
|
+
const { backupPath, version: version2 } = mutationResult2;
|
|
124007
124055
|
c3.header("ETag", version2);
|
|
124008
124056
|
return c3.json({
|
|
124009
124057
|
ok: true,
|
|
@@ -124075,7 +124123,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124075
124123
|
}
|
|
124076
124124
|
let originalContent;
|
|
124077
124125
|
try {
|
|
124078
|
-
originalContent =
|
|
124126
|
+
originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
124079
124127
|
} catch {
|
|
124080
124128
|
return c3.json({ error: "not found" }, 404);
|
|
124081
124129
|
}
|
|
@@ -124098,15 +124146,15 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124098
124146
|
result.error === "grouped elements must share a single parent" ? 422 : 400
|
|
124099
124147
|
);
|
|
124100
124148
|
}
|
|
124101
|
-
const
|
|
124149
|
+
const mutationResult2 = writeMutationResult(
|
|
124102
124150
|
c3,
|
|
124103
124151
|
ctx.project.dir,
|
|
124104
124152
|
ctx.filePath,
|
|
124105
124153
|
ctx.absPath,
|
|
124106
124154
|
result.html
|
|
124107
124155
|
);
|
|
124108
|
-
if (
|
|
124109
|
-
const { backupPath } =
|
|
124156
|
+
if (mutationResult2 instanceof Response) return mutationResult2;
|
|
124157
|
+
const { backupPath } = mutationResult2;
|
|
124110
124158
|
return c3.json({
|
|
124111
124159
|
ok: true,
|
|
124112
124160
|
changed: true,
|
|
@@ -124130,7 +124178,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124130
124178
|
).map((entry) => ({ target: entry.target, track: entry.track }));
|
|
124131
124179
|
let originalContent;
|
|
124132
124180
|
try {
|
|
124133
|
-
originalContent =
|
|
124181
|
+
originalContent = readFileSync52(ctx.absPath, "utf-8");
|
|
124134
124182
|
} catch {
|
|
124135
124183
|
return c3.json({ error: "not found" }, 404);
|
|
124136
124184
|
}
|
|
@@ -124159,7 +124207,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124159
124207
|
if ("error" in parsed) return parsed.error;
|
|
124160
124208
|
let content;
|
|
124161
124209
|
try {
|
|
124162
|
-
content =
|
|
124210
|
+
content = readFileSync52(ctx.absPath, "utf-8");
|
|
124163
124211
|
} catch {
|
|
124164
124212
|
return c3.json({ exists: false });
|
|
124165
124213
|
}
|
|
@@ -124202,7 +124250,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124202
124250
|
return c3.json({ error: "forbidden" }, 403);
|
|
124203
124251
|
}
|
|
124204
124252
|
ensureDir(destAbs);
|
|
124205
|
-
|
|
124253
|
+
writeFileSync52(destAbs, readFileSync52(srcAbs));
|
|
124206
124254
|
return c3.json({ ok: true, path: copyPath }, 201);
|
|
124207
124255
|
});
|
|
124208
124256
|
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
@@ -124232,7 +124280,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124232
124280
|
mustExist: true
|
|
124233
124281
|
});
|
|
124234
124282
|
if ("error" in res) return res.error;
|
|
124235
|
-
const html =
|
|
124283
|
+
const html = readFileSync52(res.absPath, "utf-8");
|
|
124236
124284
|
const block = extractGsapScriptBlock(html);
|
|
124237
124285
|
if (!block) {
|
|
124238
124286
|
return c3.json({
|
|
@@ -124291,11 +124339,11 @@ function registerFileRoutes(api, adapter2) {
|
|
|
124291
124339
|
if (!body || typeof body.expected !== "string" || typeof body.restore !== "string") {
|
|
124292
124340
|
return c3.json({ error: "expected and restore contents required" }, 400);
|
|
124293
124341
|
}
|
|
124294
|
-
const current2 =
|
|
124342
|
+
const current2 = readFileSync52(res.absPath, "utf-8");
|
|
124295
124343
|
if (current2 !== body.expected) {
|
|
124296
124344
|
return c3.json({ ok: true, restored: false, conflict: true });
|
|
124297
124345
|
}
|
|
124298
|
-
|
|
124346
|
+
writeFileSync52(res.absPath, body.restore, "utf-8");
|
|
124299
124347
|
return c3.json({ ok: true, restored: true, conflict: false });
|
|
124300
124348
|
});
|
|
124301
124349
|
}
|
|
@@ -124400,7 +124448,7 @@ function tagRootCompositionFile(bodyHtml, compPath) {
|
|
|
124400
124448
|
function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref, rawOverride) {
|
|
124401
124449
|
const compFile = join72(projectDir, compPath);
|
|
124402
124450
|
if (!existsSync42(compFile)) return null;
|
|
124403
|
-
const rawComp = rawOverride ??
|
|
124451
|
+
const rawComp = rawOverride ?? readFileSync62(compFile, "utf-8");
|
|
124404
124452
|
let compHeadContent = "";
|
|
124405
124453
|
let rewrittenContent;
|
|
124406
124454
|
let htmlAttrs = "";
|
|
@@ -124433,7 +124481,7 @@ function buildSubCompositionHtml(projectDir, compPath, runtimeUrl, baseHref, raw
|
|
|
124433
124481
|
const indexPath2 = join72(projectDir, "index.html");
|
|
124434
124482
|
let headContent = "";
|
|
124435
124483
|
if (existsSync42(indexPath2)) {
|
|
124436
|
-
const indexHtml =
|
|
124484
|
+
const indexHtml = readFileSync62(indexPath2, "utf-8");
|
|
124437
124485
|
const headMatch = indexHtml.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
|
|
124438
124486
|
headContent = headMatch?.[1] ?? "";
|
|
124439
124487
|
}
|
|
@@ -124471,9 +124519,9 @@ function persistHfIdsIfNeeded(filePath, html) {
|
|
|
124471
124519
|
const idsAfter = (normalized2.match(/\bdata-hf-id=/g) ?? []).length;
|
|
124472
124520
|
if (idsAfter > idsBefore) {
|
|
124473
124521
|
try {
|
|
124474
|
-
const current2 =
|
|
124522
|
+
const current2 = readFileSync72(filePath, "utf-8");
|
|
124475
124523
|
if (current2 === html) {
|
|
124476
|
-
|
|
124524
|
+
writeFileSync62(filePath, normalized2, "utf-8");
|
|
124477
124525
|
}
|
|
124478
124526
|
} catch (err) {
|
|
124479
124527
|
console.warn("[hyperframes] persistHfIdsIfNeeded: failed to write ids to disk:", err);
|
|
@@ -124499,7 +124547,7 @@ function stampFileHfIds(filePath) {
|
|
|
124499
124547
|
if (fd === null) return null;
|
|
124500
124548
|
try {
|
|
124501
124549
|
if (!fstatSync4(fd).isFile()) return null;
|
|
124502
|
-
const html =
|
|
124550
|
+
const html = readFileSync72(fd, "utf-8");
|
|
124503
124551
|
const normalized2 = ensureHfIds(html);
|
|
124504
124552
|
const idsBefore = (html.match(/\bdata-hf-id=/g) ?? []).length;
|
|
124505
124553
|
const idsAfter = (normalized2.match(/\bdata-hf-id=/g) ?? []).length;
|
|
@@ -124549,7 +124597,7 @@ function readStudioMotionManifestContent(projectDir) {
|
|
|
124549
124597
|
const manifestPath3 = join82(projectDir, STUDIO_MOTION_PATH);
|
|
124550
124598
|
if (!existsSync52(manifestPath3)) return "";
|
|
124551
124599
|
try {
|
|
124552
|
-
return
|
|
124600
|
+
return readFileSync82(manifestPath3, "utf-8");
|
|
124553
124601
|
} catch {
|
|
124554
124602
|
return "";
|
|
124555
124603
|
}
|
|
@@ -124675,14 +124723,14 @@ function resolveProjectMainHtml(projectDir, projectId) {
|
|
|
124675
124723
|
const indexPath2 = join82(projectDir, "index.html");
|
|
124676
124724
|
if (existsSync52(indexPath2)) {
|
|
124677
124725
|
return {
|
|
124678
|
-
html:
|
|
124726
|
+
html: readFileSync82(indexPath2, "utf-8"),
|
|
124679
124727
|
compositionPath: "index.html"
|
|
124680
124728
|
};
|
|
124681
124729
|
}
|
|
124682
124730
|
const blockHtmlPath = join82(projectDir, `${projectId}.html`);
|
|
124683
124731
|
if (existsSync52(blockHtmlPath)) {
|
|
124684
124732
|
return {
|
|
124685
|
-
html:
|
|
124733
|
+
html: readFileSync82(blockHtmlPath, "utf-8"),
|
|
124686
124734
|
compositionPath: `${projectId}.html`
|
|
124687
124735
|
};
|
|
124688
124736
|
}
|
|
@@ -124876,7 +124924,7 @@ ${runtimeTag}`;
|
|
|
124876
124924
|
}
|
|
124877
124925
|
servedContentType = PROXY_VARIANT_CONFIG[proxyVariant].contentType;
|
|
124878
124926
|
}
|
|
124879
|
-
const textBuffer = isText2 ? Buffer.from(
|
|
124927
|
+
const textBuffer = isText2 ? Buffer.from(readFileSync82(file, "utf-8"), "utf-8") : null;
|
|
124880
124928
|
const totalSize2 = textBuffer ? textBuffer.length : statSync32(servedPath).size;
|
|
124881
124929
|
const bodyFor = (start, end) => textBuffer ? new Uint8Array(textBuffer.subarray(start, end + 1)) : (
|
|
124882
124930
|
// Node's web stream type and the DOM one do not overlap for tsc on
|
|
@@ -124935,7 +124983,7 @@ async function lintUncoveredHtml(adapter2, projectDir, htmlFiles, coveredFiles)
|
|
|
124935
124983
|
const findings = [];
|
|
124936
124984
|
for (const file of htmlFiles) {
|
|
124937
124985
|
if (coveredFiles.has(file)) continue;
|
|
124938
|
-
const content =
|
|
124986
|
+
const content = readFileSync92(join92(projectDir, file), "utf-8");
|
|
124939
124987
|
const result = await adapter2.lint(content, { filePath: file, isSubComposition: true });
|
|
124940
124988
|
for (const finding of result?.findings ?? []) {
|
|
124941
124989
|
findings.push({ ...finding, file });
|
|
@@ -125098,7 +125146,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
125098
125146
|
}
|
|
125099
125147
|
const contentType = renderContentType(job.outputPath);
|
|
125100
125148
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
125101
|
-
const content =
|
|
125149
|
+
const content = readFileSync102(job.outputPath);
|
|
125102
125150
|
return new Response(content, {
|
|
125103
125151
|
headers: {
|
|
125104
125152
|
"Content-Type": contentType,
|
|
@@ -125116,7 +125164,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
125116
125164
|
}
|
|
125117
125165
|
const contentType = renderContentType(job.outputPath);
|
|
125118
125166
|
const filename = job.outputPath.split("/").pop() ?? `render.mp4`;
|
|
125119
|
-
const content =
|
|
125167
|
+
const content = readFileSync102(job.outputPath);
|
|
125120
125168
|
return new Response(content, {
|
|
125121
125169
|
headers: {
|
|
125122
125170
|
"Content-Type": contentType,
|
|
@@ -125149,7 +125197,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
125149
125197
|
if (!fp) return c3.json({ error: "forbidden" }, 403);
|
|
125150
125198
|
if (!existsSync62(fp)) return c3.json({ error: "not found" }, 404);
|
|
125151
125199
|
const contentType = renderContentType(fp);
|
|
125152
|
-
const content =
|
|
125200
|
+
const content = readFileSync102(fp);
|
|
125153
125201
|
return new Response(content, {
|
|
125154
125202
|
headers: {
|
|
125155
125203
|
"Content-Type": contentType,
|
|
@@ -125173,7 +125221,7 @@ function registerRenderRoutes(api, adapter2) {
|
|
|
125173
125221
|
let durationMs;
|
|
125174
125222
|
if (existsSync62(metaPath)) {
|
|
125175
125223
|
try {
|
|
125176
|
-
const meta = JSON.parse(
|
|
125224
|
+
const meta = JSON.parse(readFileSync102(metaPath, "utf-8"));
|
|
125177
125225
|
if (meta.status === "failed" && !existsSync62(fp)) status = "failed";
|
|
125178
125226
|
if (meta.durationMs) durationMs = meta.durationMs;
|
|
125179
125227
|
} catch {
|
|
@@ -125236,7 +125284,7 @@ function pruneThumbnailCache(cacheDir, protectedPaths, now = Date.now()) {
|
|
|
125236
125284
|
function writeThumbnailAtomically(path, buffer) {
|
|
125237
125285
|
const temporaryPath = `${path}.${process.pid}.${randomUUID32()}.tmp`;
|
|
125238
125286
|
try {
|
|
125239
|
-
|
|
125287
|
+
writeFileSync72(temporaryPath, buffer, { flag: "wx" });
|
|
125240
125288
|
renameSync32(temporaryPath, path);
|
|
125241
125289
|
} finally {
|
|
125242
125290
|
rmSync42(temporaryPath, { force: true });
|
|
@@ -125274,7 +125322,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
125274
125322
|
let sourceKey = "";
|
|
125275
125323
|
const htmlFile = join112(project.dir, compPath);
|
|
125276
125324
|
if (existsSync72(htmlFile)) {
|
|
125277
|
-
const html =
|
|
125325
|
+
const html = readFileSync112(htmlFile, "utf-8");
|
|
125278
125326
|
sourceKey = `_${createHash42("sha1").update(html).digest("hex").slice(0, 16)}`;
|
|
125279
125327
|
sourceMtime = Math.round(statSync52(htmlFile).mtimeMs);
|
|
125280
125328
|
if (!vpWidth) {
|
|
@@ -125287,14 +125335,14 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
125287
125335
|
const manualEditsFile = join112(project.dir, STUDIO_MANUAL_EDITS_PATH);
|
|
125288
125336
|
let manualEditsKey = "";
|
|
125289
125337
|
if (existsSync72(manualEditsFile)) {
|
|
125290
|
-
const manualEditsContent =
|
|
125338
|
+
const manualEditsContent = readFileSync112(manualEditsFile, "utf-8");
|
|
125291
125339
|
manualEditsKey = `_${createHash42("sha1").update(manualEditsContent).digest("hex").slice(0, 16)}`;
|
|
125292
125340
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync52(manualEditsFile).mtimeMs));
|
|
125293
125341
|
}
|
|
125294
125342
|
const motionFile = join112(project.dir, STUDIO_MOTION_PATH);
|
|
125295
125343
|
let motionKey = "";
|
|
125296
125344
|
if (existsSync72(motionFile)) {
|
|
125297
|
-
const motionContent =
|
|
125345
|
+
const motionContent = readFileSync112(motionFile, "utf-8");
|
|
125298
125346
|
motionKey = `_${createHash42("sha1").update(motionContent).digest("hex").slice(0, 16)}`;
|
|
125299
125347
|
sourceMtime = Math.max(sourceMtime, Math.round(statSync52(motionFile).mtimeMs));
|
|
125300
125348
|
}
|
|
@@ -125316,7 +125364,7 @@ function registerThumbnailRoutes(api, adapter2) {
|
|
|
125316
125364
|
);
|
|
125317
125365
|
}
|
|
125318
125366
|
if (existsSync72(cachePath2)) {
|
|
125319
|
-
return new Response(new Uint8Array(
|
|
125367
|
+
return new Response(new Uint8Array(readFileSync112(cachePath2)), {
|
|
125320
125368
|
headers: { "Content-Type": contentType, "Cache-Control": "no-cache" }
|
|
125321
125369
|
});
|
|
125322
125370
|
}
|
|
@@ -125383,7 +125431,7 @@ function registerWaveformRoutes(api, adapter2) {
|
|
|
125383
125431
|
const cachePath2 = join122(cacheDir, buildWaveformCacheKey(assetPath, stats));
|
|
125384
125432
|
try {
|
|
125385
125433
|
if (isWaveformCacheDirectory(cacheDir) && existsSync82(cachePath2)) {
|
|
125386
|
-
const peaks2 = JSON.parse(
|
|
125434
|
+
const peaks2 = JSON.parse(readFileSync122(cachePath2, "utf-8"));
|
|
125387
125435
|
return c3.json({ peaks: peaks2 });
|
|
125388
125436
|
}
|
|
125389
125437
|
} catch {
|
|
@@ -125809,7 +125857,7 @@ function readGlobalAssets(home = homedir10()) {
|
|
|
125809
125857
|
const manifestPath3 = join142(home, ".media", "manifest.jsonl");
|
|
125810
125858
|
if (!existsSync102(manifestPath3)) return [];
|
|
125811
125859
|
const out = [];
|
|
125812
|
-
for (const line3 of
|
|
125860
|
+
for (const line3 of readFileSync132(manifestPath3, "utf8").split("\n")) {
|
|
125813
125861
|
if (!line3.trim()) continue;
|
|
125814
125862
|
try {
|
|
125815
125863
|
const rec = JSON.parse(line3);
|
|
@@ -155540,6 +155588,7 @@ __export(studio_api_exports, {
|
|
|
155540
155588
|
STUDIO_MANUAL_EDITS_PATH: () => STUDIO_MANUAL_EDITS_PATH,
|
|
155541
155589
|
STUDIO_MOTION_PATH: () => STUDIO_MOTION_PATH,
|
|
155542
155590
|
affectsProjectSignature: () => affectsProjectSignature,
|
|
155591
|
+
applyFileMutations: () => applyFileMutations,
|
|
155543
155592
|
buildSubCompositionHtml: () => buildSubCompositionHtml,
|
|
155544
155593
|
consumeFileWriteReceipt: () => consumeFileWriteReceipt,
|
|
155545
155594
|
createBackgroundRemovalJob: () => createBackgroundRemovalJob,
|
|
@@ -155553,6 +155602,9 @@ __export(studio_api_exports, {
|
|
|
155553
155602
|
getMimeType: () => getMimeType,
|
|
155554
155603
|
identifyFileWrite: () => identifyFileWrite,
|
|
155555
155604
|
isSafePath: () => isSafePath,
|
|
155605
|
+
patchElementInHtml: () => patchElementInHtml,
|
|
155606
|
+
removeElementFromHtml: () => removeElementFromHtml2,
|
|
155607
|
+
splitElementInHtml: () => splitElementInHtml,
|
|
155556
155608
|
thumbnailDeviceScaleFactor: () => thumbnailDeviceScaleFactor,
|
|
155557
155609
|
walkDir: () => walkDir
|
|
155558
155610
|
});
|
|
@@ -170293,27 +170345,32 @@ function mainTimelineStart(scope, el, start) {
|
|
|
170293
170345
|
ordinaryStart
|
|
170294
170346
|
});
|
|
170295
170347
|
}
|
|
170296
|
-
async function
|
|
170348
|
+
async function resolveRowTiming(scope, node, depth) {
|
|
170297
170349
|
const { el } = node;
|
|
170298
|
-
const
|
|
170299
|
-
const
|
|
170300
|
-
const authored = resolveReferencedDuration(doc, el, startCache, /* @__PURE__ */ new Set());
|
|
170350
|
+
const start = resolveReferencedStart(scope.doc, el, scope.startCache, /* @__PURE__ */ new Set());
|
|
170351
|
+
const authored = resolveReferencedDuration(scope.doc, el, scope.startCache, /* @__PURE__ */ new Set());
|
|
170301
170352
|
const host = el.getAttribute("data-composition-src");
|
|
170302
170353
|
const absStart = mainTimelineStart(scope, el, start);
|
|
170303
170354
|
const children = host && depth === 0 ? await readSubComposition(host, scope, absStart) : [];
|
|
170304
170355
|
const kind = el.tagName.toLowerCase();
|
|
170305
|
-
const
|
|
170356
|
+
const duration = MEDIA_TAG.test(kind) ? await resolveMediaRowDuration(scope, el, kind, authored) : resolveContainerDuration(authored, children);
|
|
170357
|
+
return { start, authored, absStart, children, duration };
|
|
170358
|
+
}
|
|
170359
|
+
function describeRowFields(scope, node, timing2) {
|
|
170360
|
+
const { el } = node;
|
|
170361
|
+
const kind = el.tagName.toLowerCase();
|
|
170362
|
+
const host = el.getAttribute("data-composition-src");
|
|
170306
170363
|
const rate = parseNumeric2(el.getAttribute("data-playback-rate"));
|
|
170307
170364
|
return {
|
|
170308
170365
|
id: el.id || el.getAttribute("data-composition-id") || kind,
|
|
170309
170366
|
label: null,
|
|
170310
170367
|
kind,
|
|
170311
170368
|
trackKind: trackKindOf(node).kind,
|
|
170312
|
-
start,
|
|
170313
|
-
duration,
|
|
170314
|
-
end: start + duration,
|
|
170315
|
-
absStart: roundMs(absStart),
|
|
170316
|
-
absEnd: roundMs(absStart + duration),
|
|
170369
|
+
start: timing2.start,
|
|
170370
|
+
duration: timing2.duration.duration,
|
|
170371
|
+
end: timing2.start + timing2.duration.duration,
|
|
170372
|
+
absStart: roundMs(timing2.absStart),
|
|
170373
|
+
absEnd: roundMs(timing2.absStart + timing2.duration.duration),
|
|
170317
170374
|
file: scope.file,
|
|
170318
170375
|
trackIndex: parseNumeric2(el.getAttribute("data-track-index")) ?? 0,
|
|
170319
170376
|
src: el.getAttribute("src") ?? host,
|
|
@@ -170323,17 +170380,26 @@ async function describeRow(scope, node, depth) {
|
|
|
170323
170380
|
playbackRate: rate === 1 ? null : rate,
|
|
170324
170381
|
audioGroup: el.getAttribute(HF_AUDIO_GROUP_ATTR),
|
|
170325
170382
|
role: null,
|
|
170326
|
-
durationAuthored: authored !== null,
|
|
170327
|
-
durationSource,
|
|
170328
|
-
pendingReason:
|
|
170329
|
-
children
|
|
170383
|
+
durationAuthored: timing2.authored !== null,
|
|
170384
|
+
durationSource: timing2.duration.durationSource,
|
|
170385
|
+
pendingReason: timing2.duration.pendingReason,
|
|
170386
|
+
children: timing2.children,
|
|
170387
|
+
ref: "",
|
|
170388
|
+
warnings: [],
|
|
170389
|
+
elementId: el.id || null,
|
|
170390
|
+
hfId: el.getAttribute("data-hf-id")
|
|
170330
170391
|
};
|
|
170331
170392
|
}
|
|
170393
|
+
async function describeRow(scope, node, depth) {
|
|
170394
|
+
return describeRowFields(scope, node, await resolveRowTiming(scope, node, depth));
|
|
170395
|
+
}
|
|
170332
170396
|
async function readSubComposition(src, parent, origin) {
|
|
170333
170397
|
const authored = resolve64(parent.dir, src);
|
|
170334
170398
|
const file = realFileInside(parent.projectDir, authored);
|
|
170335
170399
|
if (!file) return [];
|
|
170336
|
-
const
|
|
170400
|
+
const relativeFile = relative30(parent.projectDir, authored).split(sep17).join("/");
|
|
170401
|
+
const source = parent.sourceOverrides.get(relativeFile) ?? readFileSync76(file, "utf-8");
|
|
170402
|
+
const doc = new DOMParser().parseFromString(source, "text/html");
|
|
170337
170403
|
const template = doc.querySelector("template");
|
|
170338
170404
|
const root = (template?.content ?? doc).querySelector("[data-composition-id]");
|
|
170339
170405
|
if (!root) return [];
|
|
@@ -170345,7 +170411,8 @@ async function readSubComposition(src, parent, origin) {
|
|
|
170345
170411
|
origin,
|
|
170346
170412
|
file: relative30(parent.projectDir, authored).split(sep17).join("/"),
|
|
170347
170413
|
withProbeSlot: parent.withProbeSlot,
|
|
170348
|
-
measure: parent.measure
|
|
170414
|
+
measure: parent.measure,
|
|
170415
|
+
sourceOverrides: parent.sourceOverrides
|
|
170349
170416
|
};
|
|
170350
170417
|
const rows = await Promise.all(
|
|
170351
170418
|
topLevelElements(toNode2(root)).map((node) => describeRow(scope, node, 1))
|
|
@@ -170375,22 +170442,42 @@ function flatten(top) {
|
|
|
170375
170442
|
byKind.flatMap((t) => t.entries.map((e2, index) => [e2.clip, { kind: t.kind, index }]))
|
|
170376
170443
|
);
|
|
170377
170444
|
const at4 = (clip) => pointers.get(clip);
|
|
170445
|
+
const fileIds = /* @__PURE__ */ new Map();
|
|
170446
|
+
for (const { entries: entries3 } of byKind) {
|
|
170447
|
+
for (const { clip } of entries3) {
|
|
170448
|
+
if (!clip.elementId) continue;
|
|
170449
|
+
const ids = fileIds.get(clip.file) ?? /* @__PURE__ */ new Map();
|
|
170450
|
+
ids.set(clip.elementId, (ids.get(clip.elementId) ?? 0) + 1);
|
|
170451
|
+
fileIds.set(clip.file, ids);
|
|
170452
|
+
}
|
|
170453
|
+
}
|
|
170378
170454
|
return byKind.map(({ kind, entries: kindEntries }) => ({
|
|
170379
170455
|
kind,
|
|
170380
|
-
rows: kindEntries.map(({ clip, host }, index) =>
|
|
170381
|
-
|
|
170382
|
-
index
|
|
170383
|
-
|
|
170384
|
-
|
|
170385
|
-
|
|
170386
|
-
|
|
170387
|
-
|
|
170456
|
+
rows: kindEntries.map(({ clip, host }, index) => {
|
|
170457
|
+
const uniqueId = clip.elementId && fileIds.get(clip.file)?.get(clip.elementId) === 1;
|
|
170458
|
+
const ref2 = uniqueId ? `#${clip.elementId}` : clip.hfId ? `hf:${clip.hfId}` : `${kind}/${index}`;
|
|
170459
|
+
const warnings = uniqueId || clip.hfId ? [] : [
|
|
170460
|
+
'row has no stable name; add id="<name>" to the element in this file, then retry with #<name>'
|
|
170461
|
+
];
|
|
170462
|
+
return {
|
|
170463
|
+
...clip,
|
|
170464
|
+
index,
|
|
170465
|
+
ref: ref2,
|
|
170466
|
+
warnings,
|
|
170467
|
+
nested: host !== null,
|
|
170468
|
+
host: host && host.id,
|
|
170469
|
+
hostRow: host && at4(host),
|
|
170470
|
+
children: clip.children.map(at4)
|
|
170471
|
+
};
|
|
170472
|
+
})
|
|
170388
170473
|
}));
|
|
170389
170474
|
}
|
|
170390
|
-
async function describeProject(indexPath2, measure = measureWithFfprobe) {
|
|
170391
|
-
const
|
|
170475
|
+
async function describeProject(indexPath2, measure = measureWithFfprobe, sourceOverrides = /* @__PURE__ */ new Map()) {
|
|
170476
|
+
const projectDir = dirname55(indexPath2);
|
|
170477
|
+
const source = sourceOverrides.get(basename24(indexPath2)) ?? readFileSync76(indexPath2, "utf-8");
|
|
170478
|
+
const doc = new DOMParser().parseFromString(source, "text/html");
|
|
170392
170479
|
const root = doc.querySelector("[data-composition-id]") ?? doc.body;
|
|
170393
|
-
const dir =
|
|
170480
|
+
const dir = projectDir;
|
|
170394
170481
|
const scope = {
|
|
170395
170482
|
doc,
|
|
170396
170483
|
dir,
|
|
@@ -170399,7 +170486,8 @@ async function describeProject(indexPath2, measure = measureWithFfprobe) {
|
|
|
170399
170486
|
origin: 0,
|
|
170400
170487
|
file: basename24(indexPath2),
|
|
170401
170488
|
withProbeSlot: createProbeGate(PROBE_CONCURRENCY3),
|
|
170402
|
-
measure
|
|
170489
|
+
measure,
|
|
170490
|
+
sourceOverrides
|
|
170403
170491
|
};
|
|
170404
170492
|
const rows = (await Promise.all(topLevelElements(toNode2(root)).map((node) => describeRow(scope, node, 0)))).sort(byStart);
|
|
170405
170493
|
const declared = parseNumeric2(root.getAttribute("data-duration"));
|
|
@@ -170470,7 +170558,7 @@ function details(row) {
|
|
|
170470
170558
|
}
|
|
170471
170559
|
function line2(row, total) {
|
|
170472
170560
|
const times = row.host ? `${span(row.absStart, row.absEnd)} (local ${span(row.start, row.end)}) nested in ${row.host} ${row.file}` : span(row.start, row.end);
|
|
170473
|
-
return ` |${bar(row, total)}| ${row.id} ${times} ${details(row)}`.trimEnd();
|
|
170561
|
+
return ` |${bar(row, total)}| ${row.ref} ${row.id} ${times} ${details(row)}`.trimEnd();
|
|
170474
170562
|
}
|
|
170475
170563
|
function header({ kind, rows }) {
|
|
170476
170564
|
const nested = rows.filter((r) => r.nested).length;
|
|
@@ -170495,36 +170583,554 @@ var init_formatTimeline = __esm({
|
|
|
170495
170583
|
}
|
|
170496
170584
|
});
|
|
170497
170585
|
|
|
170586
|
+
// src/timeline/resolveRef.ts
|
|
170587
|
+
function targetFor(row) {
|
|
170588
|
+
if (row.ref.startsWith("#")) return { id: row.ref.slice(1) };
|
|
170589
|
+
if (row.ref.startsWith("hf:")) return { hfId: row.ref.slice(3) };
|
|
170590
|
+
return row.id && row.id !== row.kind ? { id: row.id } : null;
|
|
170591
|
+
}
|
|
170592
|
+
function resolveRef(timeline, ref2) {
|
|
170593
|
+
const rows = timeline.tracks.flatMap((track) => track.rows);
|
|
170594
|
+
const matches2 = ref2.startsWith("#") ? rows.filter((row2) => row2.ref === ref2 || row2.id === ref2.slice(1)) : ref2.startsWith("hf:") ? rows.filter((row2) => row2.ref === ref2) : (() => {
|
|
170595
|
+
const match = /^(video|graphics|captions|audio)\/(\d+)$/.exec(ref2);
|
|
170596
|
+
if (!match) return [];
|
|
170597
|
+
const row2 = timeline.tracks.find((track) => track.kind === match[1])?.rows.find((candidate) => candidate.index === Number(match[2]));
|
|
170598
|
+
return row2 ? [row2] : [];
|
|
170599
|
+
})();
|
|
170600
|
+
if (matches2.length !== 1) {
|
|
170601
|
+
return {
|
|
170602
|
+
ok: false,
|
|
170603
|
+
reason: matches2.length === 0 ? `${ref2} was not found` : `${ref2} matches ${matches2.length} rows`,
|
|
170604
|
+
fix: 'add id="<name>" to the element in its source file, then retry with #<name>'
|
|
170605
|
+
};
|
|
170606
|
+
}
|
|
170607
|
+
const row = matches2[0];
|
|
170608
|
+
const target = targetFor(row);
|
|
170609
|
+
if (!target) {
|
|
170610
|
+
return {
|
|
170611
|
+
ok: false,
|
|
170612
|
+
reason: `${ref2} has no stable element id in ${row.file}`,
|
|
170613
|
+
fix: `add id="<name>" to the element in ${row.file}, then retry with #<name>`
|
|
170614
|
+
};
|
|
170615
|
+
}
|
|
170616
|
+
return { ok: true, row, target };
|
|
170617
|
+
}
|
|
170618
|
+
var init_resolveRef = __esm({
|
|
170619
|
+
"src/timeline/resolveRef.ts"() {
|
|
170620
|
+
"use strict";
|
|
170621
|
+
}
|
|
170622
|
+
});
|
|
170623
|
+
|
|
170624
|
+
// src/timeline/timeExpr.ts
|
|
170625
|
+
function parseTimeExpression(expression, context) {
|
|
170626
|
+
const raw = expression.trim();
|
|
170627
|
+
if (raw === "end") return { ok: true, seconds: context.duration };
|
|
170628
|
+
const frames = /^(-?\d+(?:\.\d+)?)f$/.exec(raw);
|
|
170629
|
+
if (frames) return { ok: true, seconds: Number(frames[1]) / context.fps };
|
|
170630
|
+
const absolute = /^\d+(?:\.\d+)?$/.test(raw);
|
|
170631
|
+
const relative38 = /^[+-]\d+(?:\.\d+)?$/.test(raw);
|
|
170632
|
+
if (absolute) return { ok: true, seconds: Number(raw) };
|
|
170633
|
+
if (relative38) return { ok: true, seconds: context.row.start + Number(raw) };
|
|
170634
|
+
const anchor = /^(after|before|start-of|end-of):(.+)$/.exec(raw);
|
|
170635
|
+
if (!anchor) return { ok: false, reason: `invalid time expression: ${expression}` };
|
|
170636
|
+
const row = context.resolveAnchor(anchor[2]);
|
|
170637
|
+
if (!row) return { ok: false, reason: `anchor ref not found: ${anchor[2]}` };
|
|
170638
|
+
switch (anchor[1]) {
|
|
170639
|
+
case "after":
|
|
170640
|
+
case "end-of":
|
|
170641
|
+
return { ok: true, seconds: row.end };
|
|
170642
|
+
case "before":
|
|
170643
|
+
case "start-of":
|
|
170644
|
+
return { ok: true, seconds: row.start };
|
|
170645
|
+
}
|
|
170646
|
+
return { ok: false, reason: `invalid time anchor: ${anchor[1]}` };
|
|
170647
|
+
}
|
|
170648
|
+
var init_timeExpr = __esm({
|
|
170649
|
+
"src/timeline/timeExpr.ts"() {
|
|
170650
|
+
"use strict";
|
|
170651
|
+
}
|
|
170652
|
+
});
|
|
170653
|
+
|
|
170498
170654
|
// src/commands/timeline.ts
|
|
170499
170655
|
var timeline_exports = {};
|
|
170500
170656
|
__export(timeline_exports, {
|
|
170501
170657
|
default: () => timeline_default,
|
|
170502
170658
|
examples: () => examples19
|
|
170503
170659
|
});
|
|
170504
|
-
|
|
170660
|
+
import { readFileSync as readFileSync77 } from "fs";
|
|
170661
|
+
import { join as join116 } from "path";
|
|
170662
|
+
function refusal(reason, fix, json) {
|
|
170663
|
+
setCommandExitCode(2);
|
|
170664
|
+
const payload = { ok: false, reason, fix };
|
|
170665
|
+
console.error(json ? JSON.stringify(payload, null, 2) : `${reason}; ${fix}.`);
|
|
170666
|
+
}
|
|
170667
|
+
function fpsFor(indexPath2) {
|
|
170668
|
+
const parsed = parseFpsWithDefault(
|
|
170669
|
+
readCompositionFps(readFileSync77(indexPath2, "utf-8")) ?? void 0
|
|
170670
|
+
);
|
|
170671
|
+
return fpsToNumber(parsed.ok ? parsed.value : { num: 30, den: 1 });
|
|
170672
|
+
}
|
|
170673
|
+
function declaredFps(source) {
|
|
170674
|
+
const raw = readCompositionFps(source);
|
|
170675
|
+
if (raw === null) return null;
|
|
170676
|
+
const parsed = parseFpsWithDefault(raw);
|
|
170677
|
+
return parsed.ok ? fpsToNumber(parsed.value) : null;
|
|
170678
|
+
}
|
|
170679
|
+
function splitBaseId(row) {
|
|
170680
|
+
return row.ref.startsWith("hf:") ? row.ref.slice(3) : row.id;
|
|
170681
|
+
}
|
|
170682
|
+
function nextFreeSplitId(source, base2) {
|
|
170683
|
+
const document2 = new DOMParser().parseFromString(source, "text/html");
|
|
170684
|
+
const existing = new Set(Array.from(document2.querySelectorAll("[id]"), (element) => element.id));
|
|
170685
|
+
const match = /^(.*)-(\d+)$/.exec(base2);
|
|
170686
|
+
const prefix = match && existing.has(match[1]) ? match[1] : base2;
|
|
170687
|
+
let suffix = 2;
|
|
170688
|
+
while (existing.has(`${prefix}-${suffix}`)) suffix += 1;
|
|
170689
|
+
return `${prefix}-${suffix}`;
|
|
170690
|
+
}
|
|
170691
|
+
function parseMutationTime(context, expression, fix) {
|
|
170692
|
+
const value = context.parseTime(expression);
|
|
170693
|
+
if (!value.ok) return { ok: false, reason: value.reason, fix };
|
|
170694
|
+
if (value.seconds < 0 || value.seconds > context.duration) {
|
|
170695
|
+
return {
|
|
170696
|
+
ok: false,
|
|
170697
|
+
reason: `time ${value.seconds} is outside the composition duration`,
|
|
170698
|
+
fix: "pass a time between 0 and the composition duration"
|
|
170699
|
+
};
|
|
170700
|
+
}
|
|
170701
|
+
return { ok: true, seconds: value.seconds };
|
|
170702
|
+
}
|
|
170703
|
+
function diff(before3, after2) {
|
|
170704
|
+
if (before3 === after2) return "";
|
|
170705
|
+
const beforeLines = before3.split("\n");
|
|
170706
|
+
const afterLines = after2.split("\n");
|
|
170707
|
+
let prefix = 0;
|
|
170708
|
+
while (prefix < beforeLines.length && prefix < afterLines.length && beforeLines[prefix] === afterLines[prefix]) {
|
|
170709
|
+
prefix += 1;
|
|
170710
|
+
}
|
|
170711
|
+
let suffix = 0;
|
|
170712
|
+
while (suffix < beforeLines.length - prefix && suffix < afterLines.length - prefix && beforeLines[beforeLines.length - suffix - 1] === afterLines[afterLines.length - suffix - 1]) {
|
|
170713
|
+
suffix += 1;
|
|
170714
|
+
}
|
|
170715
|
+
const changedBefore = beforeLines.slice(prefix, beforeLines.length - suffix);
|
|
170716
|
+
const changedAfter = afterLines.slice(prefix, afterLines.length - suffix);
|
|
170717
|
+
const lines = [
|
|
170718
|
+
"--- before",
|
|
170719
|
+
"+++ after",
|
|
170720
|
+
...changedBefore.map((line3) => `-${line3}`),
|
|
170721
|
+
...changedAfter.map((line3) => `+${line3}`)
|
|
170722
|
+
];
|
|
170723
|
+
const output = lines.join("\n");
|
|
170724
|
+
return output.length <= 8e3 ? output : `${output.slice(0, 7997)}...`;
|
|
170725
|
+
}
|
|
170726
|
+
function overlap(row, timeline, start, end) {
|
|
170727
|
+
return allRows(timeline).find(
|
|
170728
|
+
(candidate) => candidate !== row && candidate.file === row.file && candidate.trackIndex === row.trackIndex && Math.max(start, candidate.start) < Math.min(end, candidate.end)
|
|
170729
|
+
);
|
|
170730
|
+
}
|
|
170731
|
+
function moveMutation(context, args) {
|
|
170732
|
+
const expression = typeof args.time === "string" ? args.time : "";
|
|
170733
|
+
const time = parseMutationTime(context, expression, "pass a valid time expression");
|
|
170734
|
+
if (!time.ok) return time;
|
|
170735
|
+
const end = time.seconds + context.row.duration;
|
|
170736
|
+
if (end > context.duration) {
|
|
170737
|
+
return {
|
|
170738
|
+
ok: false,
|
|
170739
|
+
reason: `move would end at ${end}, beyond composition duration ${context.duration}`,
|
|
170740
|
+
fix: `choose a start at or before the latest valid start ${context.duration - context.row.duration}`
|
|
170741
|
+
};
|
|
170742
|
+
}
|
|
170743
|
+
const patched = patchElementInHtml(context.before, context.resolved.target, [
|
|
170744
|
+
{ type: "html-attribute", property: "data-start", value: String(time.seconds) }
|
|
170745
|
+
]);
|
|
170746
|
+
if (!patched.matched) {
|
|
170747
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
170748
|
+
}
|
|
170749
|
+
return {
|
|
170750
|
+
ok: true,
|
|
170751
|
+
after: patched.html,
|
|
170752
|
+
nextStart: time.seconds,
|
|
170753
|
+
nextDuration: context.row.duration
|
|
170754
|
+
};
|
|
170755
|
+
}
|
|
170756
|
+
function splitMutation(context, args) {
|
|
170757
|
+
const expression = typeof args.time === "string" ? args.time : "";
|
|
170758
|
+
const time = parseMutationTime(context, expression, "pass a valid time expression");
|
|
170759
|
+
if (!time.ok) return time;
|
|
170760
|
+
const split = splitElementInHtml(
|
|
170761
|
+
context.before,
|
|
170762
|
+
context.resolved.target,
|
|
170763
|
+
time.seconds,
|
|
170764
|
+
nextFreeSplitId(context.before, splitBaseId(context.row)),
|
|
170765
|
+
{
|
|
170766
|
+
start: context.row.start,
|
|
170767
|
+
duration: context.row.duration,
|
|
170768
|
+
track: context.row.trackIndex
|
|
170769
|
+
}
|
|
170770
|
+
);
|
|
170771
|
+
if (!split.matched || !split.newId) {
|
|
170772
|
+
return {
|
|
170773
|
+
ok: false,
|
|
170774
|
+
reason: `${context.ref} cannot be split at ${time.seconds}`,
|
|
170775
|
+
fix: "choose a time inside the clip"
|
|
170776
|
+
};
|
|
170777
|
+
}
|
|
170778
|
+
return {
|
|
170779
|
+
ok: true,
|
|
170780
|
+
after: split.html,
|
|
170781
|
+
nextStart: context.row.start,
|
|
170782
|
+
nextDuration: context.row.duration
|
|
170783
|
+
};
|
|
170784
|
+
}
|
|
170785
|
+
function trimMutation(context, args) {
|
|
170786
|
+
const bounds = trimBounds(context, args);
|
|
170787
|
+
if (!bounds.ok) return bounds;
|
|
170788
|
+
const patched = patchElementInHtml(context.before, context.resolved.target, [
|
|
170789
|
+
{ type: "html-attribute", property: "data-start", value: String(bounds.nextStart) },
|
|
170790
|
+
{ type: "html-attribute", property: "data-duration", value: String(bounds.nextDuration) }
|
|
170791
|
+
]);
|
|
170792
|
+
if (!patched.matched) {
|
|
170793
|
+
return { ok: false, reason: `${context.ref} was not found`, fix: "choose an existing clip" };
|
|
170794
|
+
}
|
|
170795
|
+
return {
|
|
170796
|
+
ok: true,
|
|
170797
|
+
after: patched.html,
|
|
170798
|
+
nextStart: bounds.nextStart,
|
|
170799
|
+
nextDuration: bounds.nextDuration
|
|
170800
|
+
};
|
|
170801
|
+
}
|
|
170802
|
+
function trimBounds(context, args) {
|
|
170803
|
+
const input2 = trimInput(args);
|
|
170804
|
+
if (!input2.ok) return input2;
|
|
170805
|
+
const start = trimStart(context, input2.start);
|
|
170806
|
+
if (!start.ok) return start;
|
|
170807
|
+
return finishTrim(
|
|
170808
|
+
context,
|
|
170809
|
+
start.seconds,
|
|
170810
|
+
trimEnd(context, input2.end),
|
|
170811
|
+
trimDuration(context, input2.duration)
|
|
170812
|
+
);
|
|
170813
|
+
}
|
|
170814
|
+
function trimInput(args) {
|
|
170815
|
+
const input2 = {
|
|
170816
|
+
start: typeof args.start === "string" ? args.start : void 0,
|
|
170817
|
+
end: typeof args.end === "string" ? args.end : void 0,
|
|
170818
|
+
duration: typeof args.duration === "string" ? args.duration : void 0
|
|
170819
|
+
};
|
|
170820
|
+
if (input2.start || input2.end || input2.duration) return { ok: true, ...input2 };
|
|
170821
|
+
return {
|
|
170822
|
+
ok: false,
|
|
170823
|
+
reason: "trim requires --start, --end, or --duration",
|
|
170824
|
+
fix: "pass one trim option"
|
|
170825
|
+
};
|
|
170826
|
+
}
|
|
170827
|
+
function finishTrim(context, nextStart, end, duration) {
|
|
170828
|
+
if (end && !end.ok) return end;
|
|
170829
|
+
if (duration && !duration.ok) return duration;
|
|
170830
|
+
const nextDuration = duration?.seconds ?? (end ? end.seconds - nextStart : context.row.duration);
|
|
170831
|
+
if (nextDuration <= 0) {
|
|
170832
|
+
return {
|
|
170833
|
+
ok: false,
|
|
170834
|
+
reason: "trim duration must be positive",
|
|
170835
|
+
fix: "choose a later end or positive duration"
|
|
170836
|
+
};
|
|
170837
|
+
}
|
|
170838
|
+
return { ok: true, nextStart, nextDuration };
|
|
170839
|
+
}
|
|
170840
|
+
function trimStart(context, expression) {
|
|
170841
|
+
if (!expression) return { ok: true, seconds: context.row.start };
|
|
170842
|
+
return parseMutationTime(context, expression, "pass a valid time expression");
|
|
170843
|
+
}
|
|
170844
|
+
function trimEnd(context, expression) {
|
|
170845
|
+
if (!expression) return void 0;
|
|
170846
|
+
return parseMutationTime(context, expression, "pass a valid time expression");
|
|
170847
|
+
}
|
|
170848
|
+
function trimDuration(context, expression) {
|
|
170849
|
+
if (!expression) return void 0;
|
|
170850
|
+
return parseMutationTime(context, expression, "pass a valid duration");
|
|
170851
|
+
}
|
|
170852
|
+
function deleteMutation(context) {
|
|
170853
|
+
return {
|
|
170854
|
+
ok: true,
|
|
170855
|
+
after: removeElementFromHtml2(context.before, context.resolved.target),
|
|
170856
|
+
nextStart: context.row.start,
|
|
170857
|
+
nextDuration: context.row.duration
|
|
170858
|
+
};
|
|
170859
|
+
}
|
|
170860
|
+
function decideMutation(verb, context, args) {
|
|
170861
|
+
switch (verb) {
|
|
170862
|
+
case "move":
|
|
170863
|
+
return moveMutation(context, args);
|
|
170864
|
+
case "trim":
|
|
170865
|
+
return trimMutation(context, args);
|
|
170866
|
+
case "split":
|
|
170867
|
+
return splitMutation(context, args);
|
|
170868
|
+
case "delete":
|
|
170869
|
+
return deleteMutation(context);
|
|
170870
|
+
}
|
|
170871
|
+
}
|
|
170872
|
+
async function runMutation(verb, args) {
|
|
170873
|
+
const setup = await prepareMutation(args);
|
|
170874
|
+
if (!setup.ok) return refusal(setup.reason, setup.fix, setup.json);
|
|
170875
|
+
const decision = decideMutation(verb, setup.context, args);
|
|
170876
|
+
if (!decision.ok) return refusal(decision.reason, decision.fix, setup.json);
|
|
170877
|
+
await finishMutation(setup, verb, decision);
|
|
170878
|
+
}
|
|
170879
|
+
async function prepareMutation(args) {
|
|
170880
|
+
const project = resolveProject(typeof args.dir === "string" ? args.dir : void 0);
|
|
170881
|
+
const ref2 = typeof args.ref === "string" ? args.ref : "";
|
|
170882
|
+
const json = args.json === true;
|
|
170883
|
+
const plan2 = args.plan === true;
|
|
170884
|
+
const overwrite = args.overwrite === true;
|
|
170885
|
+
const snap = args.snap === true;
|
|
170886
|
+
ensureDOMParser();
|
|
170887
|
+
const indexSource = readFileSync77(project.indexPath, "utf-8");
|
|
170888
|
+
const initialTimeline = await describeProject(
|
|
170889
|
+
project.indexPath,
|
|
170890
|
+
void 0,
|
|
170891
|
+
/* @__PURE__ */ new Map([["index.html", indexSource]])
|
|
170892
|
+
);
|
|
170893
|
+
const projectFps = declaredFps(indexSource);
|
|
170894
|
+
if (snap && projectFps === null) {
|
|
170895
|
+
return {
|
|
170896
|
+
ok: false,
|
|
170897
|
+
reason: "project fps is unknown",
|
|
170898
|
+
fix: "set data-fps on the project, then rerun with --snap",
|
|
170899
|
+
json
|
|
170900
|
+
};
|
|
170901
|
+
}
|
|
170902
|
+
const initialResolved = resolveRef(initialTimeline, ref2);
|
|
170903
|
+
if (!initialResolved.ok)
|
|
170904
|
+
return { ok: false, reason: initialResolved.reason, fix: initialResolved.fix, json };
|
|
170905
|
+
const initialRow = initialResolved.row;
|
|
170906
|
+
const filePath = join116(project.dir, initialRow.file);
|
|
170907
|
+
const before3 = readFileSync77(filePath, "utf-8");
|
|
170908
|
+
const expectedVersion = fileContentVersion(before3);
|
|
170909
|
+
const sources = /* @__PURE__ */ new Map([
|
|
170910
|
+
["index.html", indexSource],
|
|
170911
|
+
[initialRow.file, before3]
|
|
170912
|
+
]);
|
|
170913
|
+
const timeline = await describeProject(project.indexPath, void 0, sources);
|
|
170914
|
+
const resolved2 = resolveRef(timeline, ref2);
|
|
170915
|
+
if (!resolved2.ok) return { ok: false, reason: resolved2.reason, fix: resolved2.fix, json };
|
|
170916
|
+
const row = resolved2.row;
|
|
170917
|
+
const anchor = (anchorRef) => {
|
|
170918
|
+
const found = resolveRef(timeline, anchorRef);
|
|
170919
|
+
return found.ok ? found.row : void 0;
|
|
170920
|
+
};
|
|
170921
|
+
const parseTime = (expression) => {
|
|
170922
|
+
const parsed = parseTimeExpression(expression, {
|
|
170923
|
+
row,
|
|
170924
|
+
duration: timeline.duration,
|
|
170925
|
+
fps: fpsFor(project.indexPath),
|
|
170926
|
+
resolveAnchor: anchor
|
|
170927
|
+
});
|
|
170928
|
+
if (!parsed.ok || !snap) return parsed;
|
|
170929
|
+
return { ok: true, seconds: Math.round(parsed.seconds * projectFps) / projectFps };
|
|
170930
|
+
};
|
|
170931
|
+
return {
|
|
170932
|
+
ok: true,
|
|
170933
|
+
project,
|
|
170934
|
+
ref: ref2,
|
|
170935
|
+
json,
|
|
170936
|
+
plan: plan2,
|
|
170937
|
+
overwrite,
|
|
170938
|
+
timeline,
|
|
170939
|
+
indexSource,
|
|
170940
|
+
row,
|
|
170941
|
+
resolved: resolved2,
|
|
170942
|
+
filePath,
|
|
170943
|
+
before: before3,
|
|
170944
|
+
expectedVersion,
|
|
170945
|
+
context: {
|
|
170946
|
+
ref: ref2,
|
|
170947
|
+
row,
|
|
170948
|
+
before: before3,
|
|
170949
|
+
resolved: resolved2,
|
|
170950
|
+
parseTime,
|
|
170951
|
+
// Nested rows use the visible host clip duration as their composition bound.
|
|
170952
|
+
duration: row.nested && row.hostRow ? rowAt(timeline, row.hostRow).duration : timeline.duration
|
|
170953
|
+
}
|
|
170954
|
+
};
|
|
170955
|
+
}
|
|
170956
|
+
async function finishMutation(setup, verb, decision) {
|
|
170957
|
+
const { after: after2, nextStart, nextDuration } = decision;
|
|
170958
|
+
const { ref: ref2, row, timeline, json, overwrite, project, before: before3 } = setup;
|
|
170959
|
+
const refusalMessage = mutationRefusal(verb, after2, before3, ref2);
|
|
170960
|
+
if (refusalMessage) return refusal(refusalMessage.reason, refusalMessage.fix, json);
|
|
170961
|
+
const conflict = mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration);
|
|
170962
|
+
if (conflict) return refusal(conflict.reason, conflict.fix, json);
|
|
170963
|
+
const describeSource2 = (source) => describeProject(
|
|
170964
|
+
project.indexPath,
|
|
170965
|
+
void 0,
|
|
170966
|
+
/* @__PURE__ */ new Map([
|
|
170967
|
+
["index.html", setup.indexSource],
|
|
170968
|
+
[row.file, source]
|
|
170969
|
+
])
|
|
170970
|
+
);
|
|
170971
|
+
const describedBefore = await describeSource2(before3);
|
|
170972
|
+
const result = mutationResult(row, describedBefore, setup.plan);
|
|
170973
|
+
if (setup.plan) return printPlan(result, json, timeline, describeSource2, after2, before3);
|
|
170974
|
+
return applyAndPrint({
|
|
170975
|
+
setup,
|
|
170976
|
+
verb,
|
|
170977
|
+
json,
|
|
170978
|
+
row,
|
|
170979
|
+
nextStart,
|
|
170980
|
+
nextDuration,
|
|
170981
|
+
after: after2,
|
|
170982
|
+
before: before3,
|
|
170983
|
+
result,
|
|
170984
|
+
describeSource: describeSource2
|
|
170985
|
+
});
|
|
170986
|
+
}
|
|
170987
|
+
async function applyAndPrint(args) {
|
|
170988
|
+
const receipt = applyMutation(args.setup, args.after);
|
|
170989
|
+
if (receipt && "error" in receipt)
|
|
170990
|
+
return refusal(receipt.error, "re-run hyperframes timeline", args.json);
|
|
170991
|
+
if (!receipt && args.after !== args.before) {
|
|
170992
|
+
return refusal("mutation produced no receipt", "re-run hyperframes timeline", args.json);
|
|
170993
|
+
}
|
|
170994
|
+
args.result.after = rowsForFile(await args.describeSource(args.after), args.row.file);
|
|
170995
|
+
args.result.receipt = receipt ? {
|
|
170996
|
+
file: receipt.sourceFile,
|
|
170997
|
+
version: receipt.version,
|
|
170998
|
+
writeToken: receipt.writeToken,
|
|
170999
|
+
changed: receipt.changed,
|
|
171000
|
+
backupPath: receipt.backupPath
|
|
171001
|
+
} : null;
|
|
171002
|
+
if (args.json) {
|
|
171003
|
+
console.log(JSON.stringify(withMeta(args.result), null, 2));
|
|
171004
|
+
return;
|
|
171005
|
+
}
|
|
171006
|
+
console.log(
|
|
171007
|
+
`${args.verb} ${args.row.ref}: ${args.row.start}-${args.row.end}s -> ${args.nextStart}-${args.nextStart + args.nextDuration}s
|
|
171008
|
+
receipt: ${receipt?.version ?? "unchanged"}`
|
|
171009
|
+
);
|
|
171010
|
+
}
|
|
171011
|
+
function rowsForFile(timeline, file) {
|
|
171012
|
+
return allRows(timeline).filter((candidate) => candidate.file === file);
|
|
171013
|
+
}
|
|
171014
|
+
function rowAt(timeline, pointer) {
|
|
171015
|
+
const track = timeline.tracks.find((candidate) => candidate.kind === pointer.kind);
|
|
171016
|
+
if (!track) throw new Error(`missing track ${pointer.kind}`);
|
|
171017
|
+
const row = track.rows[pointer.index];
|
|
171018
|
+
if (!row) throw new Error(`missing row ${pointer.kind}/${pointer.index}`);
|
|
171019
|
+
return row;
|
|
171020
|
+
}
|
|
171021
|
+
function mutationResult(row, before3, planned) {
|
|
171022
|
+
return {
|
|
171023
|
+
ok: true,
|
|
171024
|
+
receipt: null,
|
|
171025
|
+
file: row.file,
|
|
171026
|
+
before: rowsForFile(before3, row.file),
|
|
171027
|
+
after: [],
|
|
171028
|
+
warnings: row.warnings,
|
|
171029
|
+
planned
|
|
171030
|
+
};
|
|
171031
|
+
}
|
|
171032
|
+
async function printPlan(result, json, timeline, describeSource2, after2, before3) {
|
|
171033
|
+
const plannedTimeline = await describeSource2(after2);
|
|
171034
|
+
result.after = rowsForFile(plannedTimeline, result.file);
|
|
171035
|
+
if (json) console.log(JSON.stringify(withMeta(result), null, 2));
|
|
171036
|
+
else
|
|
171037
|
+
console.log(
|
|
171038
|
+
`${formatTimeline(timeline)}
|
|
171039
|
+
|
|
171040
|
+
planned:
|
|
171041
|
+
${formatTimeline(plannedTimeline)}
|
|
171042
|
+
|
|
171043
|
+
diff:
|
|
171044
|
+
${diff(before3, after2)}`
|
|
171045
|
+
);
|
|
171046
|
+
}
|
|
171047
|
+
function applyMutation(setup, after2) {
|
|
171048
|
+
try {
|
|
171049
|
+
return applyFileMutations(setup.project.dir, [
|
|
171050
|
+
{
|
|
171051
|
+
sourceFile: setup.row.file,
|
|
171052
|
+
absPath: setup.filePath,
|
|
171053
|
+
before: setup.before,
|
|
171054
|
+
after: after2,
|
|
171055
|
+
expectedVersion: setup.expectedVersion
|
|
171056
|
+
}
|
|
171057
|
+
])[0];
|
|
171058
|
+
} catch (error) {
|
|
171059
|
+
if (error instanceof Error && error.message === "file changed since the timeline was read") {
|
|
171060
|
+
return { error: error.message };
|
|
171061
|
+
}
|
|
171062
|
+
throw error;
|
|
171063
|
+
}
|
|
171064
|
+
}
|
|
171065
|
+
function mutationRefusal(verb, after2, before3, ref2) {
|
|
171066
|
+
if (verb !== "delete" || after2 !== before3) return null;
|
|
171067
|
+
return { reason: `${ref2} was not found`, fix: "choose an existing clip" };
|
|
171068
|
+
}
|
|
171069
|
+
function mutationConflict(verb, overwrite, row, timeline, nextStart, nextDuration) {
|
|
171070
|
+
if (verb !== "move" && verb !== "trim" || overwrite) return null;
|
|
171071
|
+
const conflict = overlap(row, timeline, nextStart, nextStart + nextDuration);
|
|
171072
|
+
if (!conflict) return null;
|
|
171073
|
+
return {
|
|
171074
|
+
reason: `${row.ref} would overlap ${conflict.ref} at ${nextStart}-${nextStart + nextDuration}`,
|
|
171075
|
+
fix: "pass --overwrite or move the named neighbour"
|
|
171076
|
+
};
|
|
171077
|
+
}
|
|
171078
|
+
function mutationCommand(verb) {
|
|
171079
|
+
return defineCommand({
|
|
171080
|
+
meta: { name: verb, description: `${verb} a timeline clip` },
|
|
171081
|
+
args: {
|
|
171082
|
+
ref: { type: "positional", required: true },
|
|
171083
|
+
time: { type: "positional", required: verb === "move" || verb === "split" },
|
|
171084
|
+
dir: { type: "string" },
|
|
171085
|
+
start: { type: "string" },
|
|
171086
|
+
end: { type: "string" },
|
|
171087
|
+
duration: { type: "string" },
|
|
171088
|
+
plan: { type: "boolean", default: false },
|
|
171089
|
+
json: { type: "boolean", default: false },
|
|
171090
|
+
overwrite: { type: "boolean", default: false },
|
|
171091
|
+
snap: { type: "boolean", default: false }
|
|
171092
|
+
},
|
|
171093
|
+
async run({ args }) {
|
|
171094
|
+
await runMutation(verb, args);
|
|
171095
|
+
}
|
|
171096
|
+
});
|
|
171097
|
+
}
|
|
171098
|
+
var examples19, allRows, timeline_default;
|
|
170505
171099
|
var init_timeline = __esm({
|
|
170506
171100
|
"src/commands/timeline.ts"() {
|
|
170507
171101
|
"use strict";
|
|
171102
|
+
init_dist9();
|
|
171103
|
+
init_dist3();
|
|
171104
|
+
init_compositionFps();
|
|
170508
171105
|
init_dist();
|
|
170509
171106
|
init_describeProject();
|
|
170510
171107
|
init_formatTimeline();
|
|
171108
|
+
init_resolveRef();
|
|
171109
|
+
init_timeExpr();
|
|
170511
171110
|
init_dom();
|
|
171111
|
+
init_commandResult();
|
|
170512
171112
|
init_project();
|
|
170513
171113
|
init_updateCheck();
|
|
170514
171114
|
examples19 = [
|
|
170515
171115
|
["Show every track and clip of the project in the current directory", "hyperframes timeline"],
|
|
170516
|
-
["
|
|
171116
|
+
["Move a clip without writing", "hyperframes timeline move '#hero' +2 --plan"],
|
|
171117
|
+
["Delete a clip and return a receipt", "hyperframes timeline delete '#hero' --json"]
|
|
170517
171118
|
];
|
|
171119
|
+
allRows = (timeline) => timeline.tracks.flatMap((track) => track.rows);
|
|
170518
171120
|
timeline_default = defineCommand({
|
|
170519
|
-
meta: {
|
|
170520
|
-
name: "timeline",
|
|
170521
|
-
description: "Print the project's tracks and clips (start, duration, source, volume, rate)"
|
|
170522
|
-
},
|
|
171121
|
+
meta: { name: "timeline", description: "Print and edit the project's tracks and clips" },
|
|
170523
171122
|
args: {
|
|
170524
171123
|
dir: { type: "positional", description: "Project directory", required: false },
|
|
170525
171124
|
json: { type: "boolean", description: "Output as JSON", default: false }
|
|
170526
171125
|
},
|
|
171126
|
+
subCommands: {
|
|
171127
|
+
move: () => mutationCommand("move"),
|
|
171128
|
+
trim: () => mutationCommand("trim"),
|
|
171129
|
+
split: () => mutationCommand("split"),
|
|
171130
|
+
delete: () => mutationCommand("delete")
|
|
171131
|
+
},
|
|
170527
171132
|
async run({ args }) {
|
|
171133
|
+
if (args._?.[0]) return;
|
|
170528
171134
|
const project = resolveProject(args.dir);
|
|
170529
171135
|
ensureDOMParser();
|
|
170530
171136
|
const timeline = await describeProject(project.indexPath);
|
|
@@ -170543,7 +171149,7 @@ __export(benchmark_exports, {
|
|
|
170543
171149
|
examples: () => examples20
|
|
170544
171150
|
});
|
|
170545
171151
|
import { existsSync as existsSync99, statSync as statSync41 } from "fs";
|
|
170546
|
-
import { resolve as resolve65, join as
|
|
171152
|
+
import { resolve as resolve65, join as join117 } from "path";
|
|
170547
171153
|
var examples20, FPS_30, FPS_60, DEFAULT_CONFIGS, benchmark_default;
|
|
170548
171154
|
var init_benchmark = __esm({
|
|
170549
171155
|
"src/commands/benchmark.ts"() {
|
|
@@ -170622,7 +171228,7 @@ var init_benchmark = __esm({
|
|
|
170622
171228
|
s?.start(`Benchmarking ${config.label}...`);
|
|
170623
171229
|
for (let i = 0; i < runsPerConfig; i++) {
|
|
170624
171230
|
s?.message(`${config.label} \u2014 run ${i + 1}/${runsPerConfig}`);
|
|
170625
|
-
const outputPath =
|
|
171231
|
+
const outputPath = join117(
|
|
170626
171232
|
benchDir,
|
|
170627
171233
|
`${config.label.replace(/[^a-zA-Z0-9]/g, "_")}_run${i}.mp4`
|
|
170628
171234
|
);
|
|
@@ -171124,9 +171730,9 @@ var init_remove_background = __esm({
|
|
|
171124
171730
|
|
|
171125
171731
|
// src/whisper/parakeet.ts
|
|
171126
171732
|
import { execFileSync as execFileSync13 } from "child_process";
|
|
171127
|
-
import { existsSync as existsSync101, mkdtempSync as mkdtempSync23, readFileSync as
|
|
171733
|
+
import { existsSync as existsSync101, mkdtempSync as mkdtempSync23, readFileSync as readFileSync78, rmSync as rmSync36, writeFileSync as writeFileSync44 } from "fs";
|
|
171128
171734
|
import { homedir as homedir21, tmpdir as tmpdir15 } from "os";
|
|
171129
|
-
import { basename as basename25, extname as extname16, join as
|
|
171735
|
+
import { basename as basename25, extname as extname16, join as join118 } from "path";
|
|
171130
171736
|
function isRunnable(bin) {
|
|
171131
171737
|
try {
|
|
171132
171738
|
execFileSync13(bin, ["--help"], { stdio: ["ignore", "ignore", "ignore"], timeout: 1e4 });
|
|
@@ -171138,7 +171744,7 @@ function isRunnable(bin) {
|
|
|
171138
171744
|
function findParakeet() {
|
|
171139
171745
|
const candidates = [
|
|
171140
171746
|
process.env.HYPERFRAMES_PARAKEET,
|
|
171141
|
-
|
|
171747
|
+
join118(homedir21(), ".venvs", "parakeet", "bin", "parakeet-mlx")
|
|
171142
171748
|
].filter((p2) => Boolean(p2));
|
|
171143
171749
|
for (const path of candidates) {
|
|
171144
171750
|
if (existsSync101(path) && isRunnable(path)) return path;
|
|
@@ -171189,20 +171795,20 @@ function transcribeWithParakeet(inputPath, dir, options) {
|
|
|
171189
171795
|
}
|
|
171190
171796
|
const model = options?.model ?? DEFAULT_MODEL3;
|
|
171191
171797
|
const cached3 = existsSync101(
|
|
171192
|
-
|
|
171798
|
+
join118(homedir21(), ".cache", "huggingface", "hub", `models--${model.replace(/\//g, "--")}`)
|
|
171193
171799
|
);
|
|
171194
171800
|
options?.onProgress?.(
|
|
171195
171801
|
cached3 ? "Transcribing with Parakeet..." : "Downloading Parakeet model (first run, ~600MB)..."
|
|
171196
171802
|
);
|
|
171197
|
-
const workDir = mkdtempSync23(
|
|
171803
|
+
const workDir = mkdtempSync23(join118(tmpdir15(), "hyperframes-parakeet-"));
|
|
171198
171804
|
try {
|
|
171199
171805
|
const argv2 = [inputPath, "--model", model, "--output-format", "json", "--output-dir", workDir];
|
|
171200
171806
|
if (options?.language) argv2.push("--language", options.language);
|
|
171201
171807
|
execFileSync13(runner, argv2, { stdio: ["ignore", "pipe", "pipe"], timeout: 18e5 });
|
|
171202
|
-
const produced =
|
|
171808
|
+
const produced = join118(workDir, `${basename25(inputPath, extname16(inputPath))}.json`);
|
|
171203
171809
|
if (!existsSync101(produced)) throw new Error("Parakeet did not produce output.");
|
|
171204
|
-
const words = mergeTokensToWords(JSON.parse(
|
|
171205
|
-
const transcriptPath =
|
|
171810
|
+
const words = mergeTokensToWords(JSON.parse(readFileSync78(produced, "utf-8")));
|
|
171811
|
+
const transcriptPath = join118(dir, "transcript.json");
|
|
171206
171812
|
writeFileSync44(transcriptPath, JSON.stringify(words, null, 2));
|
|
171207
171813
|
const durationSeconds = words.length > 0 ? words[words.length - 1].end : 0;
|
|
171208
171814
|
return { transcriptPath, wordCount: words.length, durationSeconds, speechOnsetSeconds: null };
|
|
@@ -171226,7 +171832,7 @@ __export(transcribe_exports2, {
|
|
|
171226
171832
|
examples: () => examples23
|
|
171227
171833
|
});
|
|
171228
171834
|
import { existsSync as existsSync103, writeFileSync as writeFileSync45 } from "fs";
|
|
171229
|
-
import { resolve as resolve67, join as
|
|
171835
|
+
import { resolve as resolve67, join as join119, extname as extname17, dirname as dirname56 } from "path";
|
|
171230
171836
|
function parseTimeoutMs(raw, json) {
|
|
171231
171837
|
const source = raw ?? process.env["HYPERFRAMES_TRANSCRIBE_TIMEOUT_MS"];
|
|
171232
171838
|
if (source == null || source === "") return void 0;
|
|
@@ -171262,7 +171868,7 @@ async function importTranscript(inputPath, dir, json) {
|
|
|
171262
171868
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
171263
171869
|
const { words, format } = loadTranscript2(inputPath);
|
|
171264
171870
|
if (words.length === 0) exitNoWords(json);
|
|
171265
|
-
const outPath =
|
|
171871
|
+
const outPath = join119(dir, "transcript.json");
|
|
171266
171872
|
writeFileSync45(outPath, JSON.stringify(words, null, 2));
|
|
171267
171873
|
patchCaptionHtml2(dir, words);
|
|
171268
171874
|
if (json) {
|
|
@@ -171280,7 +171886,7 @@ async function exportTranscript(inputPath, dir, to, output, json, preserveCues)
|
|
|
171280
171886
|
const { words, format } = loadTranscript2(inputPath);
|
|
171281
171887
|
if (words.length === 0) exitNoWords(json);
|
|
171282
171888
|
const preGrouped = preserveCues || format === "srt" || format === "vtt" || void 0;
|
|
171283
|
-
const outPath = resolve67(output ??
|
|
171889
|
+
const outPath = resolve67(output ?? join119(dir, `transcript.${to}`));
|
|
171284
171890
|
const content = to === "srt" ? formatSrt2(words, { preGrouped }) : formatVtt2(words, { preGrouped });
|
|
171285
171891
|
writeFileSync45(outPath, content);
|
|
171286
171892
|
if (json) {
|
|
@@ -171503,7 +172109,7 @@ var init_transcribe2 = __esm({
|
|
|
171503
172109
|
// src/tts/manager.ts
|
|
171504
172110
|
import { existsSync as existsSync104, mkdirSync as mkdirSync54 } from "fs";
|
|
171505
172111
|
import { homedir as homedir22 } from "os";
|
|
171506
|
-
import { join as
|
|
172112
|
+
import { join as join120 } from "path";
|
|
171507
172113
|
function inferLangFromVoiceId(voiceId) {
|
|
171508
172114
|
const first = voiceId.charAt(0).toLowerCase();
|
|
171509
172115
|
return VOICE_PREFIX_LANG[first] ?? "en-us";
|
|
@@ -171512,7 +172118,7 @@ function isSupportedLang(value) {
|
|
|
171512
172118
|
return SUPPORTED_LANGS.includes(value);
|
|
171513
172119
|
}
|
|
171514
172120
|
async function ensureModel3(model = DEFAULT_MODEL4, options) {
|
|
171515
|
-
const modelPath2 =
|
|
172121
|
+
const modelPath2 = join120(MODELS_DIR4, `${model}.onnx`);
|
|
171516
172122
|
if (existsSync104(modelPath2)) return modelPath2;
|
|
171517
172123
|
const url = MODEL_URLS2[model];
|
|
171518
172124
|
if (!url) {
|
|
@@ -171529,7 +172135,7 @@ async function ensureModel3(model = DEFAULT_MODEL4, options) {
|
|
|
171529
172135
|
return modelPath2;
|
|
171530
172136
|
}
|
|
171531
172137
|
async function ensureVoices(options) {
|
|
171532
|
-
const voicesPath =
|
|
172138
|
+
const voicesPath = join120(VOICES_DIR, "voices-v1.0.bin");
|
|
171533
172139
|
if (existsSync104(voicesPath)) return voicesPath;
|
|
171534
172140
|
mkdirSync54(VOICES_DIR, { recursive: true });
|
|
171535
172141
|
options?.onProgress?.("Downloading voice data (~27 MB)...");
|
|
@@ -171544,9 +172150,9 @@ var init_manager4 = __esm({
|
|
|
171544
172150
|
"src/tts/manager.ts"() {
|
|
171545
172151
|
"use strict";
|
|
171546
172152
|
init_download();
|
|
171547
|
-
CACHE_DIR4 =
|
|
171548
|
-
MODELS_DIR4 =
|
|
171549
|
-
VOICES_DIR =
|
|
172153
|
+
CACHE_DIR4 = join120(homedir22(), ".cache", "hyperframes", "tts");
|
|
172154
|
+
MODELS_DIR4 = join120(CACHE_DIR4, "models");
|
|
172155
|
+
VOICES_DIR = join120(CACHE_DIR4, "voices");
|
|
171550
172156
|
DEFAULT_MODEL4 = "kokoro-v1.0";
|
|
171551
172157
|
MODEL_URLS2 = {
|
|
171552
172158
|
"kokoro-v1.0": "https://github.com/thewh1teagle/kokoro-onnx/releases/download/model-files-v1.0/kokoro-v1.0.onnx"
|
|
@@ -171689,7 +172295,7 @@ __export(synthesize_exports, {
|
|
|
171689
172295
|
});
|
|
171690
172296
|
import { execFileSync as execFileSync15 } from "child_process";
|
|
171691
172297
|
import { existsSync as existsSync105, mkdirSync as mkdirSync55, readdirSync as readdirSync37, unlinkSync as unlinkSync9 } from "fs";
|
|
171692
|
-
import { join as
|
|
172298
|
+
import { join as join121, dirname as dirname57, basename as basename26 } from "path";
|
|
171693
172299
|
import { homedir as homedir23 } from "os";
|
|
171694
172300
|
function ensureSynthScript() {
|
|
171695
172301
|
if (!existsSync105(SCRIPT_PATH)) {
|
|
@@ -171700,7 +172306,7 @@ function ensureSynthScript() {
|
|
|
171700
172306
|
for (const entry of readdirSync37(SCRIPT_DIR)) {
|
|
171701
172307
|
if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
|
|
171702
172308
|
try {
|
|
171703
|
-
unlinkSync9(
|
|
172309
|
+
unlinkSync9(join121(SCRIPT_DIR, entry));
|
|
171704
172310
|
} catch {
|
|
171705
172311
|
}
|
|
171706
172312
|
}
|
|
@@ -171848,8 +172454,8 @@ print(json.dumps({
|
|
|
171848
172454
|
ESPEAK_LANG_OVERRIDES = {
|
|
171849
172455
|
zh: "cmn"
|
|
171850
172456
|
};
|
|
171851
|
-
SCRIPT_DIR =
|
|
171852
|
-
SCRIPT_PATH =
|
|
172457
|
+
SCRIPT_DIR = join121(homedir23(), ".cache", "hyperframes", "tts");
|
|
172458
|
+
SCRIPT_PATH = join121(SCRIPT_DIR, "synth-v3.py");
|
|
171853
172459
|
}
|
|
171854
172460
|
});
|
|
171855
172461
|
|
|
@@ -171859,7 +172465,7 @@ __export(tts_exports, {
|
|
|
171859
172465
|
default: () => tts_default,
|
|
171860
172466
|
examples: () => examples24
|
|
171861
172467
|
});
|
|
171862
|
-
import { existsSync as existsSync106, readFileSync as
|
|
172468
|
+
import { existsSync as existsSync106, readFileSync as readFileSync79 } from "fs";
|
|
171863
172469
|
import { resolve as resolve68, extname as extname18 } from "path";
|
|
171864
172470
|
function listVoices(json) {
|
|
171865
172471
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -171977,7 +172583,7 @@ var init_tts = __esm({
|
|
|
171977
172583
|
let text2;
|
|
171978
172584
|
const maybeFile = resolve68(input2);
|
|
171979
172585
|
if (existsSync106(maybeFile) && extname18(maybeFile).toLowerCase() === ".txt") {
|
|
171980
|
-
text2 =
|
|
172586
|
+
text2 = readFileSync79(maybeFile, "utf-8").trim();
|
|
171981
172587
|
if (!text2) {
|
|
171982
172588
|
console.error(c.error("File is empty."));
|
|
171983
172589
|
failCommand();
|
|
@@ -172069,8 +172675,8 @@ __export(docs_exports, {
|
|
|
172069
172675
|
default: () => docs_default,
|
|
172070
172676
|
examples: () => examples25
|
|
172071
172677
|
});
|
|
172072
|
-
import { readFileSync as
|
|
172073
|
-
import { resolve as resolve69, dirname as dirname58, join as
|
|
172678
|
+
import { readFileSync as readFileSync80, existsSync as existsSync107 } from "fs";
|
|
172679
|
+
import { resolve as resolve69, dirname as dirname58, join as join123 } from "path";
|
|
172074
172680
|
import { fileURLToPath as fileURLToPath15 } from "url";
|
|
172075
172681
|
function docsDir() {
|
|
172076
172682
|
const thisFile = fileURLToPath15(import.meta.url);
|
|
@@ -172175,12 +172781,12 @@ var init_docs = __esm({
|
|
|
172175
172781
|
}
|
|
172176
172782
|
failCommand();
|
|
172177
172783
|
}
|
|
172178
|
-
const filePath =
|
|
172784
|
+
const filePath = join123(docsDir(), entry.file);
|
|
172179
172785
|
if (!existsSync107(filePath)) {
|
|
172180
172786
|
console.error(c.error(`Doc file not found: ${filePath}`));
|
|
172181
172787
|
failCommand();
|
|
172182
172788
|
}
|
|
172183
|
-
const content =
|
|
172789
|
+
const content = readFileSync80(filePath, "utf-8");
|
|
172184
172790
|
console.log();
|
|
172185
172791
|
renderMarkdown(content);
|
|
172186
172792
|
}
|
|
@@ -172594,7 +173200,7 @@ __export(upgrade_exports, {
|
|
|
172594
173200
|
upgradeProjectPins: () => upgradeProjectPins
|
|
172595
173201
|
});
|
|
172596
173202
|
import { execFileSync as execFileSync17 } from "child_process";
|
|
172597
|
-
import { existsSync as existsSync109, readFileSync as
|
|
173203
|
+
import { existsSync as existsSync109, readFileSync as readFileSync81, writeFileSync as writeFileSync46, renameSync as renameSync20, readdirSync as readdirSync38 } from "fs";
|
|
172598
173204
|
import { resolve as resolve70 } from "path";
|
|
172599
173205
|
async function confirmUpgrade() {
|
|
172600
173206
|
const shouldUpgrade = await ue({ message: "Upgrade now?" });
|
|
@@ -172657,14 +173263,14 @@ async function upgradeProjectPins(dir, opts) {
|
|
|
172657
173263
|
if (!existsSync109(pkgPath)) {
|
|
172658
173264
|
return { changed: false, from: [], to: "", path: pkgPath };
|
|
172659
173265
|
}
|
|
172660
|
-
const raw = JSON.parse(
|
|
173266
|
+
const raw = JSON.parse(readFileSync81(pkgPath, "utf-8"));
|
|
172661
173267
|
const scripts = raw.scripts ?? {};
|
|
172662
173268
|
const { latest } = await checkForUpdate(true);
|
|
172663
173269
|
if (!isSafeVersion(latest)) return { changed: false, from: [], to: latest, path: pkgPath };
|
|
172664
173270
|
const rewrite = rewriteProjectPinnedScripts(scripts, latest);
|
|
172665
173271
|
const wrapperRewrites = readdirSync38(dir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".sh")).map((entry) => {
|
|
172666
173272
|
const path = resolve70(dir, entry.name);
|
|
172667
|
-
return { path, rewrite: rewritePinnedHyperframesText(
|
|
173273
|
+
return { path, rewrite: rewritePinnedHyperframesText(readFileSync81(path, "utf-8"), latest) };
|
|
172668
173274
|
});
|
|
172669
173275
|
if (rewrite.changed && !opts.check) {
|
|
172670
173276
|
raw.scripts = rewrite.scripts;
|
|
@@ -173378,8 +173984,8 @@ __export(contactSheet_exports, {
|
|
|
173378
173984
|
createSvgContactSheet: () => createSvgContactSheet
|
|
173379
173985
|
});
|
|
173380
173986
|
import sharp from "sharp";
|
|
173381
|
-
import { readdirSync as readdirSync39, readFileSync as
|
|
173382
|
-
import { join as
|
|
173987
|
+
import { readdirSync as readdirSync39, readFileSync as readFileSync83, writeFileSync as writeFileSync47, unlinkSync as unlinkSync10, existsSync as existsSync110 } from "fs";
|
|
173988
|
+
import { join as join124, extname as extname19, basename as basename27, dirname as dirname60 } from "path";
|
|
173383
173989
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
173384
173990
|
const {
|
|
173385
173991
|
cols = 3,
|
|
@@ -173468,7 +174074,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath, budget = {})
|
|
|
173468
174074
|
if (!existsSync110(screenshotsDir)) return [];
|
|
173469
174075
|
const scrollFiles = readdirSync39(screenshotsDir).filter((f) => f.startsWith("scroll-") && f.endsWith(".png")).sort();
|
|
173470
174076
|
if (scrollFiles.length === 0) return [];
|
|
173471
|
-
const paths = scrollFiles.map((f) =>
|
|
174077
|
+
const paths = scrollFiles.map((f) => join124(screenshotsDir, f));
|
|
173472
174078
|
const labels = scrollFiles.map((f) => {
|
|
173473
174079
|
const m = f.match(/scroll-(\d+)\.png/);
|
|
173474
174080
|
return m ? `${m[1]}% scroll` : f;
|
|
@@ -173485,7 +174091,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {})
|
|
|
173485
174091
|
if (!existsSync110(snapshotsDir)) return [];
|
|
173486
174092
|
const snapshotFiles = readdirSync39(snapshotsDir).filter((f) => f.startsWith("frame-") && f.endsWith(".png")).sort();
|
|
173487
174093
|
if (snapshotFiles.length === 0) return [];
|
|
173488
|
-
const paths = snapshotFiles.map((f) =>
|
|
174094
|
+
const paths = snapshotFiles.map((f) => join124(snapshotsDir, f));
|
|
173489
174095
|
const labels = snapshotFiles.map((f) => {
|
|
173490
174096
|
const m = f.match(/at-([\d.]+)s/);
|
|
173491
174097
|
return m ? `${m[1]}s` : f;
|
|
@@ -173503,7 +174109,7 @@ async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
|
173503
174109
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
173504
174110
|
const assetFiles = readdirSync39(assetsDir).filter((f) => imageExts.has(extname19(f).toLowerCase()) && !f.includes("contact-sheet")).sort();
|
|
173505
174111
|
if (assetFiles.length === 0) return [];
|
|
173506
|
-
const paths = assetFiles.map((f) =>
|
|
174112
|
+
const paths = assetFiles.map((f) => join124(assetsDir, f));
|
|
173507
174113
|
return createContactSheetPages(paths, outputPath, {
|
|
173508
174114
|
cols: 4,
|
|
173509
174115
|
cellWidth: 480,
|
|
@@ -173523,7 +174129,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
173523
174129
|
for (const f of readdirSync39(dir).filter((f2) => f2.endsWith(".svg")).sort()) {
|
|
173524
174130
|
if (!seen.has(f)) {
|
|
173525
174131
|
seen.add(f);
|
|
173526
|
-
svgPaths.push(
|
|
174132
|
+
svgPaths.push(join124(dir, f));
|
|
173527
174133
|
}
|
|
173528
174134
|
}
|
|
173529
174135
|
}
|
|
@@ -173536,9 +174142,9 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
173536
174142
|
for (let i = 0; i < svgPaths.length; i++) {
|
|
173537
174143
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
173538
174144
|
const svgPath = svgPaths[i];
|
|
173539
|
-
const tmpPath =
|
|
174145
|
+
const tmpPath = join124(tmpDir, `.thumb-${i}.png`);
|
|
173540
174146
|
try {
|
|
173541
|
-
const svgBuf =
|
|
174147
|
+
const svgBuf = readFileSync83(svgPath);
|
|
173542
174148
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
173543
174149
|
fit: "contain",
|
|
173544
174150
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
@@ -173594,9 +174200,9 @@ __export(snapshot_exports, {
|
|
|
173594
174200
|
resolveSnapshotVideoRateSpec: () => resolveSnapshotVideoRateSpec,
|
|
173595
174201
|
tailFrameTime: () => tailFrameTime
|
|
173596
174202
|
});
|
|
173597
|
-
import { existsSync as existsSync111, mkdtempSync as mkdtempSync24, readFileSync as
|
|
174203
|
+
import { existsSync as existsSync111, mkdtempSync as mkdtempSync24, readFileSync as readFileSync84, mkdirSync as mkdirSync56, rmSync as rmSync37, writeFileSync as writeFileSync48 } from "fs";
|
|
173598
174204
|
import { tmpdir as tmpdir16 } from "os";
|
|
173599
|
-
import { resolve as resolve72, join as
|
|
174205
|
+
import { resolve as resolve72, join as join125, relative as relative31, isAbsolute as isAbsolute19, basename as basename28, posix as posix6 } from "path";
|
|
173600
174206
|
function orbitStageSource() {
|
|
173601
174207
|
return `function(cam) {
|
|
173602
174208
|
var root = document.querySelector("[data-composition-id]")
|
|
@@ -173650,8 +174256,8 @@ function requireSnapshotFfmpeg(ffmpegPath) {
|
|
|
173650
174256
|
);
|
|
173651
174257
|
}
|
|
173652
174258
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false, accurateSeek = false) {
|
|
173653
|
-
const tmp = mkdtempSync24(
|
|
173654
|
-
const outPath =
|
|
174259
|
+
const tmp = mkdtempSync24(join125(tmpdir16(), "hf-snapshot-frame-"));
|
|
174260
|
+
const outPath = join125(tmp, "frame.png");
|
|
173655
174261
|
try {
|
|
173656
174262
|
const ffmpegPath = requireSnapshotFfmpeg(findFFmpeg());
|
|
173657
174263
|
const args = ["-hide_banner", "-loglevel", "error"];
|
|
@@ -173670,7 +174276,7 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
173670
174276
|
);
|
|
173671
174277
|
const result = await runFfmpegOnce(ffmpegPath, args, FFMPEG_EXTRACT_TIMEOUT_MS);
|
|
173672
174278
|
if (result.code !== 0 || result.timedOut || !existsSync111(outPath)) return null;
|
|
173673
|
-
return
|
|
174279
|
+
return readFileSync84(outPath);
|
|
173674
174280
|
} finally {
|
|
173675
174281
|
try {
|
|
173676
174282
|
rmSync37(tmp, { recursive: true, force: true });
|
|
@@ -173762,13 +174368,13 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
173762
174368
|
);
|
|
173763
174369
|
}
|
|
173764
174370
|
const cameraExpr = opts.angle && (opts.angle.yaw !== 0 || opts.angle.pitch !== 0) ? `(${orbitStageSource()})(${JSON.stringify(opts.angle)})` : null;
|
|
173765
|
-
const snapshotDir = opts.outputDir ??
|
|
174371
|
+
const snapshotDir = opts.outputDir ?? join125(projectDir, "snapshots");
|
|
173766
174372
|
mkdirSync56(snapshotDir, { recursive: true });
|
|
173767
174373
|
try {
|
|
173768
174374
|
const { readdirSync: readdirSync46 } = await import("fs");
|
|
173769
174375
|
for (const file of readdirSync46(snapshotDir)) {
|
|
173770
174376
|
if (/\.(png|jpg|jpeg)$/i.test(file)) {
|
|
173771
|
-
rmSync37(
|
|
174377
|
+
rmSync37(join125(snapshotDir, file), { force: true });
|
|
173772
174378
|
}
|
|
173773
174379
|
}
|
|
173774
174380
|
} catch {
|
|
@@ -173902,7 +174508,7 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
173902
174508
|
const timeLabel = formatSnapshotTimestamp(time);
|
|
173903
174509
|
const index = String(i).padStart(2, "0");
|
|
173904
174510
|
const filename = `frame-${index}-at-${timeLabel}.png`;
|
|
173905
|
-
const framePath =
|
|
174511
|
+
const framePath = join125(snapshotDir, filename);
|
|
173906
174512
|
if (opts.zoom) {
|
|
173907
174513
|
const canvas = await page.evaluate(() => ({
|
|
173908
174514
|
width: window.innerWidth,
|
|
@@ -173931,9 +174537,9 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
173931
174537
|
` ${c.warn("\u26A0")} --against has no frame at ${timeLabel} \u2014 reference pair skipped`
|
|
173932
174538
|
);
|
|
173933
174539
|
} else {
|
|
173934
|
-
const refPath =
|
|
174540
|
+
const refPath = join125(snapshotDir, `ref-${index}-at-${timeLabel}.png`);
|
|
173935
174541
|
writeFileSync48(refPath, refPng);
|
|
173936
|
-
const pairPath =
|
|
174542
|
+
const pairPath = join125(snapshotDir, `pair-${index}-at-${timeLabel}.jpg`);
|
|
173937
174543
|
const { createContactSheet: createContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
173938
174544
|
await createContactSheet2([framePath, refPath], pairPath, {
|
|
173939
174545
|
cols: 2,
|
|
@@ -174100,7 +174706,7 @@ var init_snapshot = __esm({
|
|
|
174100
174706
|
const angleLabel = camera && (camera.yaw !== 0 || camera.pitch !== 0) ? ` ${c.dim(`(angle yaw ${camera.yaw}\xB0 pitch ${camera.pitch}\xB0)`)}` : "";
|
|
174101
174707
|
console.log(`${c.accent("\u25C6")} Capturing ${label2} from ${c.accent(project.name)}${angleLabel}`);
|
|
174102
174708
|
try {
|
|
174103
|
-
const snapshotDir = args.output ? resolve72(String(args.output)) :
|
|
174709
|
+
const snapshotDir = args.output ? resolve72(String(args.output)) : join125(project.dir, "snapshots");
|
|
174104
174710
|
const paths = await captureSnapshots(project.dir, {
|
|
174105
174711
|
frames,
|
|
174106
174712
|
timeout,
|
|
@@ -174137,7 +174743,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
174137
174743
|
const { createSnapshotContactSheet: createSnapshotContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
174138
174744
|
const sheets = await createSnapshotContactSheet2(
|
|
174139
174745
|
snapshotDir,
|
|
174140
|
-
|
|
174746
|
+
join125(snapshotDir, "contact-sheet.jpg")
|
|
174141
174747
|
);
|
|
174142
174748
|
if (sheets.length > 0) {
|
|
174143
174749
|
const label3 = sheets.length === 1 ? "contact-sheet.jpg" : `contact-sheet-1..${sheets.length}.jpg`;
|
|
@@ -174173,9 +174779,9 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
174173
174779
|
const results = await Promise.allSettled(
|
|
174174
174780
|
paths.map(async (p2) => {
|
|
174175
174781
|
const filename = basename28(p2);
|
|
174176
|
-
const filePath =
|
|
174782
|
+
const filePath = join125(snapshotDir, filename);
|
|
174177
174783
|
if (!existsSync111(filePath)) return { filename, desc: "file not found" };
|
|
174178
|
-
const raw =
|
|
174784
|
+
const raw = readFileSync84(filePath);
|
|
174179
174785
|
let imageData;
|
|
174180
174786
|
let mimeType = "image/png";
|
|
174181
174787
|
if (sharpFn) {
|
|
@@ -174211,7 +174817,7 @@ ${c.success("\u25C7")} ${paths.length} snapshots saved to ${args.output ? snaps
|
|
|
174211
174817
|
descriptions.push(`## (error)`, `Gemini call failed: ${errMsg.slice(0, 120)}`, ``);
|
|
174212
174818
|
}
|
|
174213
174819
|
}
|
|
174214
|
-
const descPath =
|
|
174820
|
+
const descPath = join125(snapshotDir, "descriptions.md");
|
|
174215
174821
|
writeFileSync48(descPath, descriptions.join("\n"));
|
|
174216
174822
|
console.log(` ${c.dim("descriptions.md")} (Gemini frame analysis)`);
|
|
174217
174823
|
}
|
|
@@ -174544,8 +175150,8 @@ __export(media_treatment_exports, {
|
|
|
174544
175150
|
mediaTreatmentCommand: () => mediaTreatmentCommand,
|
|
174545
175151
|
resolveMediaTreatmentSource: () => resolveMediaTreatmentSource
|
|
174546
175152
|
});
|
|
174547
|
-
import { existsSync as existsSync112, readFileSync as
|
|
174548
|
-
import { join as
|
|
175153
|
+
import { existsSync as existsSync112, readFileSync as readFileSync85, writeFileSync as writeFileSync49 } from "fs";
|
|
175154
|
+
import { join as join126, relative as relative34, resolve as resolve74 } from "path";
|
|
174549
175155
|
function getMediaTreatmentCapabilityOverview() {
|
|
174550
175156
|
const capabilities = getHfColorGradingCapabilities();
|
|
174551
175157
|
const family = (id, label2, description) => ({
|
|
@@ -174923,7 +175529,7 @@ function resolveMediaTreatmentSource(projectDir, compositionFile, source) {
|
|
|
174923
175529
|
}
|
|
174924
175530
|
const cleanSource = cleanAssetUrl(sourceUrl);
|
|
174925
175531
|
if (!cleanSource) throw new Error("Selected media has no analyzable local src");
|
|
174926
|
-
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync112(
|
|
175532
|
+
const projectRelative = cleanSource.startsWith("/") ? cleanSource : rewriteAssetPath(compositionFile, cleanSource, (path) => existsSync112(join126(projectDir, path)));
|
|
174927
175533
|
const asset = resolveExistingLocalAsset(projectDir, projectRelative);
|
|
174928
175534
|
if (!asset) throw new Error(`Media file not found: ${source}`);
|
|
174929
175535
|
return asset.resolved;
|
|
@@ -174988,7 +175594,7 @@ function analyzeTarget(args) {
|
|
|
174988
175594
|
}
|
|
174989
175595
|
const selectorIndex = parseSelectorIndex(readOptionalString(args["selector-index"]));
|
|
174990
175596
|
const { element, tag } = selectMediaElement(
|
|
174991
|
-
|
|
175597
|
+
readFileSync85(filePath, "utf8"),
|
|
174992
175598
|
selector,
|
|
174993
175599
|
selectorIndex
|
|
174994
175600
|
);
|
|
@@ -175006,14 +175612,14 @@ function analyzeTarget(args) {
|
|
|
175006
175612
|
...analyzeMediaTreatment(mediaPath)
|
|
175007
175613
|
};
|
|
175008
175614
|
}
|
|
175009
|
-
function
|
|
175615
|
+
function prepareMutation2(args) {
|
|
175010
175616
|
const { project, filePath } = resolveMutationFile(args);
|
|
175011
175617
|
const selector = readOptionalString(args.selector);
|
|
175012
175618
|
if (!selector) throw new Error("--selector is required");
|
|
175013
175619
|
const clear = args.clear === true;
|
|
175014
175620
|
const apply = args.apply === true;
|
|
175015
175621
|
const selectorIndex = parseSelectorIndex(readOptionalString(args["selector-index"]));
|
|
175016
|
-
const result = applyMediaTreatmentToHtml(
|
|
175622
|
+
const result = applyMediaTreatmentToHtml(readFileSync85(filePath, "utf8"), {
|
|
175017
175623
|
selector,
|
|
175018
175624
|
selectorIndex,
|
|
175019
175625
|
grading: parseGrading(readOptionalString(args.grading), apply, clear),
|
|
@@ -175055,7 +175661,7 @@ function printAnalysis(args) {
|
|
|
175055
175661
|
console.log(` suggested patch: ${JSON.stringify(result.suggestedPatch)}`);
|
|
175056
175662
|
}
|
|
175057
175663
|
function printMutation(args) {
|
|
175058
|
-
const { action, result, selector, payload } =
|
|
175664
|
+
const { action, result, selector, payload } = prepareMutation2(args);
|
|
175059
175665
|
if (args.json === true) {
|
|
175060
175666
|
console.log(JSON.stringify(withMeta(payload), null, 2));
|
|
175061
175667
|
return;
|
|
@@ -175202,12 +175808,12 @@ import {
|
|
|
175202
175808
|
existsSync as existsSync113,
|
|
175203
175809
|
mkdirSync as mkdirSync57,
|
|
175204
175810
|
mkdtempSync as mkdtempSync25,
|
|
175205
|
-
readFileSync as
|
|
175811
|
+
readFileSync as readFileSync86,
|
|
175206
175812
|
rmSync as rmSync38,
|
|
175207
175813
|
writeFileSync as writeFileSync50
|
|
175208
175814
|
} from "fs";
|
|
175209
175815
|
import { tmpdir as tmpdir17 } from "os";
|
|
175210
|
-
import { basename as basename30, dirname as dirname61, extname as extname21, join as
|
|
175816
|
+
import { basename as basename30, dirname as dirname61, extname as extname21, join as join127, resolve as resolve75 } from "path";
|
|
175211
175817
|
import sharp2 from "sharp";
|
|
175212
175818
|
function isRecord14(value) {
|
|
175213
175819
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -175298,7 +175904,7 @@ function parseGradesFile(filePath) {
|
|
|
175298
175904
|
}
|
|
175299
175905
|
let parsed;
|
|
175300
175906
|
try {
|
|
175301
|
-
parsed = JSON.parse(
|
|
175907
|
+
parsed = JSON.parse(readFileSync86(filePath, "utf-8"));
|
|
175302
175908
|
} catch (err) {
|
|
175303
175909
|
throw new Error(`Could not parse grades JSON: ${normalizeErrorMessage(err)}`);
|
|
175304
175910
|
}
|
|
@@ -175463,10 +176069,10 @@ function frameFileNameForPath(framePath) {
|
|
|
175463
176069
|
return "frame.png";
|
|
175464
176070
|
}
|
|
175465
176071
|
async function prepareGradeCompareTempProject(opts) {
|
|
175466
|
-
const tempDir = mkdtempSync25(
|
|
176072
|
+
const tempDir = mkdtempSync25(join127(tmpdir17(), "hf-grade-compare-"));
|
|
175467
176073
|
try {
|
|
175468
176074
|
const frameFileName2 = opts.frameFileName ?? frameFileNameForPath(opts.framePath);
|
|
175469
|
-
writeFileSync50(
|
|
176075
|
+
writeFileSync50(join127(tempDir, frameFileName2), opts.frameBuffer);
|
|
175470
176076
|
let lutIndex = 0;
|
|
175471
176077
|
const stagedCells = opts.cells.map((cell) => {
|
|
175472
176078
|
const lutSrc = lutSrcFromGrading(cell.grading);
|
|
@@ -175475,7 +176081,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
175475
176081
|
if (!existsSync113(sourcePath)) {
|
|
175476
176082
|
throw new Error(`LUT file not found for "${cell.label}": ${sourcePath}`);
|
|
175477
176083
|
}
|
|
175478
|
-
const lutText =
|
|
176084
|
+
const lutText = readFileSync86(sourcePath, "utf-8");
|
|
175479
176085
|
try {
|
|
175480
176086
|
parseCubeLut(lutText, { maxSize: 64 });
|
|
175481
176087
|
} catch (err) {
|
|
@@ -175486,7 +176092,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
175486
176092
|
const lutExt = extname21(sourcePath) || ".cube";
|
|
175487
176093
|
const stagedName = `lut-${lutIndex}${lutExt}`;
|
|
175488
176094
|
lutIndex += 1;
|
|
175489
|
-
copyFileSync10(sourcePath,
|
|
176095
|
+
copyFileSync10(sourcePath, join127(tempDir, stagedName));
|
|
175490
176096
|
return {
|
|
175491
176097
|
label: cell.label,
|
|
175492
176098
|
grading: rewriteGradingLutSrc(cell.grading, stagedName)
|
|
@@ -175498,7 +176104,7 @@ async function prepareGradeCompareTempProject(opts) {
|
|
|
175498
176104
|
frameWidth: opts.frameWidth,
|
|
175499
176105
|
frameHeight: opts.frameHeight
|
|
175500
176106
|
});
|
|
175501
|
-
writeFileSync50(
|
|
176107
|
+
writeFileSync50(join127(tempDir, "index.html"), html);
|
|
175502
176108
|
return { tempDir, html, cells: stagedCells };
|
|
175503
176109
|
} catch (err) {
|
|
175504
176110
|
rmSync38(tempDir, { recursive: true, force: true });
|
|
@@ -175510,8 +176116,8 @@ function isVideoPath2(filePath) {
|
|
|
175510
176116
|
return [".mp4", ".mov", ".m4v", ".webm", ".mkv", ".avi", ".mpeg", ".mpg", ".ogv"].includes(ext);
|
|
175511
176117
|
}
|
|
175512
176118
|
async function extractVideoFrameToBuffer2(videoPath) {
|
|
175513
|
-
const tmp = mkdtempSync25(
|
|
175514
|
-
const outPath =
|
|
176119
|
+
const tmp = mkdtempSync25(join127(tmpdir17(), "hf-grade-compare-frame-"));
|
|
176120
|
+
const outPath = join127(tmp, "frame.png");
|
|
175515
176121
|
try {
|
|
175516
176122
|
const ffmpegPath = findFFmpeg();
|
|
175517
176123
|
if (!ffmpegPath) return null;
|
|
@@ -175538,7 +176144,7 @@ async function extractVideoFrameToBuffer2(videoPath) {
|
|
|
175538
176144
|
const detail = result.stderr.trim() ? `: ${result.stderr.trim()}` : "";
|
|
175539
176145
|
throw new Error(`ffmpeg could not extract first frame from ${videoPath}${detail}`);
|
|
175540
176146
|
}
|
|
175541
|
-
return
|
|
176147
|
+
return readFileSync86(outPath);
|
|
175542
176148
|
} finally {
|
|
175543
176149
|
rmSync38(tmp, { recursive: true, force: true });
|
|
175544
176150
|
}
|
|
@@ -175547,7 +176153,7 @@ async function loadReferenceFrame(framePath) {
|
|
|
175547
176153
|
if (!existsSync113(framePath)) {
|
|
175548
176154
|
throw new Error(`Reference frame not found: ${framePath}`);
|
|
175549
176155
|
}
|
|
175550
|
-
const buffer = isVideoPath2(framePath) ? await extractVideoFrameToBuffer2(framePath) :
|
|
176156
|
+
const buffer = isVideoPath2(framePath) ? await extractVideoFrameToBuffer2(framePath) : readFileSync86(framePath);
|
|
175551
176157
|
if (!buffer) {
|
|
175552
176158
|
throw new Error(`Could not extract a frame from video: ${framePath}`);
|
|
175553
176159
|
}
|
|
@@ -175566,7 +176172,7 @@ async function captureGradeCompareSheet(projectDir, timeoutMs) {
|
|
|
175566
176172
|
const { bundleToSingleHtml: bundleToSingleHtml2 } = await Promise.resolve().then(() => (init_compiler(), compiler_exports));
|
|
175567
176173
|
const html = await bundleToSingleHtml2(projectDir);
|
|
175568
176174
|
const server = await serveStaticProjectHtml(projectDir, html);
|
|
175569
|
-
const sheetPath =
|
|
176175
|
+
const sheetPath = join127(projectDir, "grade-compare.png");
|
|
175570
176176
|
try {
|
|
175571
176177
|
const {
|
|
175572
176178
|
browser: chromeBrowser,
|
|
@@ -175754,7 +176360,7 @@ __export(compare_exports, {
|
|
|
175754
176360
|
});
|
|
175755
176361
|
import { cpSync as cpSync6, existsSync as existsSync114, mkdirSync as mkdirSync58, mkdtempSync as mkdtempSync26, renameSync as renameSync21, rmSync as rmSync39, statSync as statSync43 } from "fs";
|
|
175756
176362
|
import { tmpdir as tmpdir18 } from "os";
|
|
175757
|
-
import { basename as basename31, dirname as dirname62, extname as extname23, join as
|
|
176363
|
+
import { basename as basename31, dirname as dirname62, extname as extname23, join as join128 } from "path";
|
|
175758
176364
|
function defaultLabelForPath(input2) {
|
|
175759
176365
|
const name = basename31(input2);
|
|
175760
176366
|
return extname23(name).toLowerCase() === ".html" ? basename31(name, extname23(name)) : name;
|
|
@@ -175853,7 +176459,7 @@ function inputError(variant) {
|
|
|
175853
176459
|
);
|
|
175854
176460
|
}
|
|
175855
176461
|
function stageHtmlVariant(variant) {
|
|
175856
|
-
const stagedDir = mkdtempSync26(
|
|
176462
|
+
const stagedDir = mkdtempSync26(join128(tmpdir18(), "hf-compare-variant-"));
|
|
175857
176463
|
try {
|
|
175858
176464
|
cpSync6(dirname62(variant.inputPath), stagedDir, {
|
|
175859
176465
|
recursive: true,
|
|
@@ -175864,7 +176470,7 @@ function stageHtmlVariant(variant) {
|
|
|
175864
176470
|
});
|
|
175865
176471
|
const sourceName = basename31(variant.inputPath);
|
|
175866
176472
|
if (sourceName !== "index.html") {
|
|
175867
|
-
renameSync21(
|
|
176473
|
+
renameSync21(join128(stagedDir, sourceName), join128(stagedDir, "index.html"));
|
|
175868
176474
|
}
|
|
175869
176475
|
return {
|
|
175870
176476
|
...variant,
|
|
@@ -175884,7 +176490,7 @@ function prepareCompareVariantProjects(variants) {
|
|
|
175884
176490
|
throw inputError(variant);
|
|
175885
176491
|
}
|
|
175886
176492
|
const stat = statSync43(variant.inputPath);
|
|
175887
|
-
if (stat.isDirectory() && existsSync114(
|
|
176493
|
+
if (stat.isDirectory() && existsSync114(join128(variant.inputPath, "index.html"))) {
|
|
175888
176494
|
prepared.push({
|
|
175889
176495
|
...variant,
|
|
175890
176496
|
projectDir: variant.inputPath
|
|
@@ -175950,13 +176556,13 @@ async function renderCompareSheet(parsed) {
|
|
|
175950
176556
|
const capResult = capCompareVariants(parsed.variants);
|
|
175951
176557
|
const variants = capResult.variants;
|
|
175952
176558
|
const prepared = prepareCompareVariantProjects(variants);
|
|
175953
|
-
const frameDir = mkdtempSync26(
|
|
176559
|
+
const frameDir = mkdtempSync26(join128(tmpdir18(), "hf-compare-frames-"));
|
|
175954
176560
|
const framePaths = [];
|
|
175955
176561
|
try {
|
|
175956
176562
|
let renderReadyTimedOut = false;
|
|
175957
176563
|
for (let i = 0; i < prepared.length; i++) {
|
|
175958
176564
|
const variant = prepared[i];
|
|
175959
|
-
const framePath =
|
|
176565
|
+
const framePath = join128(frameDir, `variant-${String(i + 1).padStart(2, "0")}.png`);
|
|
175960
176566
|
const rendered = await renderCompareVariant(variant, {
|
|
175961
176567
|
atSeconds: parsed.atSeconds,
|
|
175962
176568
|
framePath,
|
|
@@ -176467,7 +177073,7 @@ var init_captureImageValidation = __esm({
|
|
|
176467
177073
|
|
|
176468
177074
|
// src/capture/assetDownloader.ts
|
|
176469
177075
|
import { writeFileSync as writeFileSync51, mkdirSync as mkdirSync59 } from "fs";
|
|
176470
|
-
import { join as
|
|
177076
|
+
import { join as join129, extname as extname24 } from "path";
|
|
176471
177077
|
import { createHash as createHash27 } from "crypto";
|
|
176472
177078
|
function noDrops() {
|
|
176473
177079
|
return { "size-floor": 0, "budget-exhausted": 0, "cap-reached": 0, unavailable: 0 };
|
|
@@ -176529,7 +177135,7 @@ async function fetchAndInspectIcon(icon, rank, stem, outputDir, timeoutMs, byteB
|
|
|
176529
177135
|
const ext = await captureImageExtension(buffer);
|
|
176530
177136
|
if (!ext) return null;
|
|
176531
177137
|
const file = `assets/${stem}${ext}`;
|
|
176532
|
-
writeFileSync51(
|
|
177138
|
+
writeFileSync51(join129(outputDir, file), buffer);
|
|
176533
177139
|
const verdict = await classifyIcon(buffer, ext);
|
|
176534
177140
|
return {
|
|
176535
177141
|
buffer,
|
|
@@ -176551,7 +177157,7 @@ function promoteHeadline(manifest, bytesByFile, outputDir) {
|
|
|
176551
177157
|
)[0];
|
|
176552
177158
|
if (!chosen) return null;
|
|
176553
177159
|
const file = `assets/favicon${extname24(chosen.file)}`;
|
|
176554
|
-
writeFileSync51(
|
|
177160
|
+
writeFileSync51(join129(outputDir, file), bytesByFile.get(chosen.file));
|
|
176555
177161
|
manifest.headline = {
|
|
176556
177162
|
file,
|
|
176557
177163
|
source: chosen.file,
|
|
@@ -176606,13 +177212,13 @@ async function downloadDeclaredIcons(faviconLinks, outputDir, drops, options) {
|
|
|
176606
177212
|
}
|
|
176607
177213
|
async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks, options = {}) {
|
|
176608
177214
|
options = { ...options, byteBudget: options.byteBudget ?? createCaptureDownloadBudget() };
|
|
176609
|
-
const assetsDir =
|
|
177215
|
+
const assetsDir = join129(outputDir, "assets");
|
|
176610
177216
|
mkdirSync59(assetsDir, { recursive: true });
|
|
176611
177217
|
const assets = [];
|
|
176612
177218
|
const drops = noDrops();
|
|
176613
177219
|
const downloadedUrls = /* @__PURE__ */ new Set();
|
|
176614
177220
|
let icons = emptyIconManifest();
|
|
176615
|
-
mkdirSync59(
|
|
177221
|
+
mkdirSync59(join129(outputDir, "assets", "svgs"), { recursive: true });
|
|
176616
177222
|
const usedSvgNames = /* @__PURE__ */ new Set();
|
|
176617
177223
|
const MAX_INLINE_SVGS = 30;
|
|
176618
177224
|
drops["cap-reached"] += Math.max(0, tokens.svgs.length - MAX_INLINE_SVGS);
|
|
@@ -176634,7 +177240,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
176634
177240
|
const name = `${finalSlug}.svg`;
|
|
176635
177241
|
const localPath = `assets/svgs/${name}`;
|
|
176636
177242
|
try {
|
|
176637
|
-
writeFileSync51(
|
|
177243
|
+
writeFileSync51(join129(outputDir, localPath), svgFile, "utf-8");
|
|
176638
177244
|
assets.push({ url: "", localPath, type: "svg" });
|
|
176639
177245
|
} catch {
|
|
176640
177246
|
drops.unavailable++;
|
|
@@ -176724,7 +177330,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
176724
177330
|
const name = `${slug}${ext}`;
|
|
176725
177331
|
usedNames.add(slug);
|
|
176726
177332
|
const localPath = `assets/${name}`;
|
|
176727
|
-
writeFileSync51(
|
|
177333
|
+
writeFileSync51(join129(outputDir, localPath), buffer);
|
|
176728
177334
|
assets.push({ url, localPath, type: "image" });
|
|
176729
177335
|
imgIdx++;
|
|
176730
177336
|
} catch {
|
|
@@ -176751,7 +177357,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks,
|
|
|
176751
177357
|
drops["size-floor"]++;
|
|
176752
177358
|
} else {
|
|
176753
177359
|
const localPath = `assets/og-image${ext}`;
|
|
176754
|
-
writeFileSync51(
|
|
177360
|
+
writeFileSync51(join129(outputDir, localPath), buffer);
|
|
176755
177361
|
assets.push({ url: tokens.ogImage, localPath, type: "image" });
|
|
176756
177362
|
}
|
|
176757
177363
|
}
|
|
@@ -176777,7 +177383,7 @@ function normalizeUrl(u) {
|
|
|
176777
177383
|
}
|
|
176778
177384
|
async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
176779
177385
|
options = { ...options, byteBudget: options.byteBudget ?? createCaptureDownloadBudget() };
|
|
176780
|
-
const assetsDir =
|
|
177386
|
+
const assetsDir = join129(outputDir, "assets", "fonts");
|
|
176781
177387
|
mkdirSync59(assetsDir, { recursive: true });
|
|
176782
177388
|
const drops = noDrops();
|
|
176783
177389
|
const fontUrlRegex = /url\(['"]?(https?:\/\/[^'")\s]+\.(?:woff2?|ttf|otf)[^'")\s]*?)['"]?\)/g;
|
|
@@ -176835,7 +177441,7 @@ async function downloadAndRewriteFonts(css, outputDir, options = {}) {
|
|
|
176835
177441
|
const extension = buffer && captureFontExtension(buffer);
|
|
176836
177442
|
if (buffer && extension) {
|
|
176837
177443
|
const filename = captureFontFilename(fontUrl, extension, usedFontNames);
|
|
176838
|
-
const localPath =
|
|
177444
|
+
const localPath = join129(assetsDir, filename);
|
|
176839
177445
|
const relativePath = `assets/fonts/${filename}`;
|
|
176840
177446
|
writeFileSync51(localPath, buffer);
|
|
176841
177447
|
rewritten = rewritten.split(fontUrl).join(relativePath);
|
|
@@ -176957,8 +177563,8 @@ __export(video_exports, {
|
|
|
176957
177563
|
runVideoMode: () => runVideoMode,
|
|
176958
177564
|
safeFilename: () => safeFilename
|
|
176959
177565
|
});
|
|
176960
|
-
import { createWriteStream as createWriteStream3, existsSync as existsSync115, mkdirSync as mkdirSync60, readFileSync as
|
|
176961
|
-
import { resolve as resolve76, join as
|
|
177566
|
+
import { createWriteStream as createWriteStream3, existsSync as existsSync115, mkdirSync as mkdirSync60, readFileSync as readFileSync87, unlinkSync as unlinkSync11 } from "fs";
|
|
177567
|
+
import { resolve as resolve76, join as join130, basename as basename32 } from "path";
|
|
176962
177568
|
async function streamToFile(url, destPath) {
|
|
176963
177569
|
const r = await safeFetch(url, {
|
|
176964
177570
|
signal: AbortSignal.timeout(12e4),
|
|
@@ -177077,8 +177683,8 @@ function pickManifestEntry(manifest, args) {
|
|
|
177077
177683
|
}
|
|
177078
177684
|
async function runVideoMode(args) {
|
|
177079
177685
|
const projectDir = resolve76(args.project);
|
|
177080
|
-
const directPath =
|
|
177081
|
-
const w2hPath =
|
|
177686
|
+
const directPath = join130(projectDir, "extracted", "video-manifest.json");
|
|
177687
|
+
const w2hPath = join130(projectDir, "capture", "extracted", "video-manifest.json");
|
|
177082
177688
|
const manifestPath3 = existsSync115(directPath) ? directPath : w2hPath;
|
|
177083
177689
|
const isW2hLayout = manifestPath3 === w2hPath;
|
|
177084
177690
|
if (!existsSync115(manifestPath3)) {
|
|
@@ -177091,7 +177697,7 @@ async function runVideoMode(args) {
|
|
|
177091
177697
|
}
|
|
177092
177698
|
let manifest;
|
|
177093
177699
|
try {
|
|
177094
|
-
manifest = JSON.parse(
|
|
177700
|
+
manifest = JSON.parse(readFileSync87(manifestPath3, "utf-8"));
|
|
177095
177701
|
} catch (e2) {
|
|
177096
177702
|
console.error(`${c.error("\u2717")} video-manifest.json is malformed: ${e2.message}`);
|
|
177097
177703
|
setCommandExitCode(1);
|
|
@@ -177132,10 +177738,10 @@ async function runVideoMode(args) {
|
|
|
177132
177738
|
setCommandExitCode(1);
|
|
177133
177739
|
return;
|
|
177134
177740
|
}
|
|
177135
|
-
const outDir = isW2hLayout ?
|
|
177741
|
+
const outDir = isW2hLayout ? join130(projectDir, "capture", "assets", "videos") : join130(projectDir, "assets", "videos");
|
|
177136
177742
|
mkdirSync60(outDir, { recursive: true });
|
|
177137
177743
|
const fname = safeFilename(entry.filename || basename32(entry.url));
|
|
177138
|
-
const outPath =
|
|
177744
|
+
const outPath = join130(outDir, fname);
|
|
177139
177745
|
const relPath = isW2hLayout ? `capture/assets/videos/${fname}` : `assets/videos/${fname}`;
|
|
177140
177746
|
console.log(
|
|
177141
177747
|
`${c.accent("\u25B8")} downloading [${entry.index}] ${entry.filename} (${entry.sourceWidth || entry.width}\xD7${entry.sourceHeight || entry.height})`
|
|
@@ -178632,8 +179238,8 @@ var init_designStyleExtractor = __esm({
|
|
|
178632
179238
|
});
|
|
178633
179239
|
|
|
178634
179240
|
// src/capture/fontMetadataExtractor.ts
|
|
178635
|
-
import { readdirSync as readdirSync40, readFileSync as
|
|
178636
|
-
import { join as
|
|
179241
|
+
import { readdirSync as readdirSync40, readFileSync as readFileSync88, writeFileSync as writeFileSync53, existsSync as existsSync116 } from "fs";
|
|
179242
|
+
import { join as join131 } from "path";
|
|
178637
179243
|
import * as fontkit from "fontkit";
|
|
178638
179244
|
function isFontCollection(value) {
|
|
178639
179245
|
return value.type === "TTC" || value.type === "DFont";
|
|
@@ -178644,7 +179250,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
178644
179250
|
if (existsSync116(fontsDir)) {
|
|
178645
179251
|
const fontFiles = readdirSync40(fontsDir).filter((f) => /\.(woff2?|ttf|otf)$/i.test(f));
|
|
178646
179252
|
for (const filename of fontFiles) {
|
|
178647
|
-
const fullPath =
|
|
179253
|
+
const fullPath = join131(fontsDir, filename);
|
|
178648
179254
|
const meta = readSingleFont(fullPath, filename);
|
|
178649
179255
|
if (meta.identified) {
|
|
178650
179256
|
files.push(meta);
|
|
@@ -178683,7 +179289,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
178683
179289
|
isIcon: false
|
|
178684
179290
|
};
|
|
178685
179291
|
try {
|
|
178686
|
-
const buf =
|
|
179292
|
+
const buf = readFileSync88(fullPath);
|
|
178687
179293
|
const created = fontkit.create(buf);
|
|
178688
179294
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
178689
179295
|
if (!font) return empty2;
|
|
@@ -179199,8 +179805,8 @@ var init_lottiePreviewRequests = __esm({
|
|
|
179199
179805
|
});
|
|
179200
179806
|
|
|
179201
179807
|
// src/capture/mediaCapture.ts
|
|
179202
|
-
import { mkdirSync as mkdirSync61, writeFileSync as writeFileSync54, readdirSync as readdirSync41, readFileSync as
|
|
179203
|
-
import { join as
|
|
179808
|
+
import { mkdirSync as mkdirSync61, writeFileSync as writeFileSync54, readdirSync as readdirSync41, readFileSync as readFileSync89, statSync as statSync44 } from "fs";
|
|
179809
|
+
import { join as join133, extname as extname25 } from "path";
|
|
179204
179810
|
function liveRemainingMs(budget, fallbackMs) {
|
|
179205
179811
|
return budget.remainingMs?.() ?? fallbackMs;
|
|
179206
179812
|
}
|
|
@@ -179238,7 +179844,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
179238
179844
|
if (savedHashes.has(hash2)) continue;
|
|
179239
179845
|
savedHashes.add(hash2);
|
|
179240
179846
|
if (!validLottieJson(jsonData)) continue;
|
|
179241
|
-
writeFileSync54(
|
|
179847
|
+
writeFileSync54(join133(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
|
|
179242
179848
|
savedCount++;
|
|
179243
179849
|
}
|
|
179244
179850
|
} catch {
|
|
@@ -179248,18 +179854,18 @@ async function saveLottieAnimations(discoveredLotties, lottieDir, budget = {}) {
|
|
|
179248
179854
|
}
|
|
179249
179855
|
async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget = {}) {
|
|
179250
179856
|
const manifest = [];
|
|
179251
|
-
const previewDir =
|
|
179857
|
+
const previewDir = join133(lottieDir, "previews");
|
|
179252
179858
|
mkdirSync61(previewDir, { recursive: true });
|
|
179253
179859
|
for (const file of readdirSync41(lottieDir)) {
|
|
179254
179860
|
if (!file.endsWith(".json")) continue;
|
|
179255
179861
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
179256
179862
|
try {
|
|
179257
|
-
const raw = JSON.parse(
|
|
179863
|
+
const raw = JSON.parse(readFileSync89(join133(lottieDir, file), "utf-8"));
|
|
179258
179864
|
const fr = raw.fr || 30;
|
|
179259
179865
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
179260
179866
|
const previewName = file.replace(".json", "-preview.png");
|
|
179261
179867
|
let preview;
|
|
179262
|
-
const fileSize = statSync44(
|
|
179868
|
+
const fileSize = statSync44(join133(lottieDir, file)).size;
|
|
179263
179869
|
if (fileSize > 2e6) continue;
|
|
179264
179870
|
let previewPage;
|
|
179265
179871
|
try {
|
|
@@ -179268,7 +179874,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
179268
179874
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
179269
179875
|
await guardLottiePreviewRequests(previewPage);
|
|
179270
179876
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
179271
|
-
const animData = JSON.parse(
|
|
179877
|
+
const animData = JSON.parse(readFileSync89(join133(lottieDir, file), "utf-8"));
|
|
179272
179878
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
179273
179879
|
await previewPage.setContent(
|
|
179274
179880
|
`<!DOCTYPE html>
|
|
@@ -179299,7 +179905,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
179299
179905
|
});
|
|
179300
179906
|
if (liveRemainingMs(budget, 1) > 0) {
|
|
179301
179907
|
await previewPage.screenshot({
|
|
179302
|
-
path:
|
|
179908
|
+
path: join133(previewDir, previewName),
|
|
179303
179909
|
type: "png",
|
|
179304
179910
|
omitBackground: true
|
|
179305
179911
|
});
|
|
@@ -179325,7 +179931,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
179325
179931
|
}
|
|
179326
179932
|
if (manifest.length > 0) {
|
|
179327
179933
|
writeFileSync54(
|
|
179328
|
-
|
|
179934
|
+
join133(outputDir, "extracted", "lottie-manifest.json"),
|
|
179329
179935
|
JSON.stringify(manifest, null, 2),
|
|
179330
179936
|
"utf-8"
|
|
179331
179937
|
);
|
|
@@ -179363,7 +179969,7 @@ async function downloadVideoBody(srcUrl, filename, videosDir, timeoutMs) {
|
|
|
179363
179969
|
}
|
|
179364
179970
|
if (total < 1024) return null;
|
|
179365
179971
|
const safe = /\.[a-z0-9]+$/i.test(filename) ? filename.replace(/[^\w.-]/g, "_") : `video${ext}`;
|
|
179366
|
-
writeFileSync54(
|
|
179972
|
+
writeFileSync54(join133(videosDir, safe), Buffer.concat(chunks));
|
|
179367
179973
|
return `assets/videos/${safe}`;
|
|
179368
179974
|
} catch {
|
|
179369
179975
|
return null;
|
|
@@ -179430,9 +180036,9 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
179430
180036
|
}
|
|
179431
180037
|
const merged = [...byKey.values()];
|
|
179432
180038
|
if (merged.length === 0) return;
|
|
179433
|
-
const videoManifestDir =
|
|
180039
|
+
const videoManifestDir = join133(outputDir, "assets", "videos");
|
|
179434
180040
|
mkdirSync61(videoManifestDir, { recursive: true });
|
|
179435
|
-
const previewDir =
|
|
180041
|
+
const previewDir = join133(videoManifestDir, "previews");
|
|
179436
180042
|
mkdirSync61(previewDir, { recursive: true });
|
|
179437
180043
|
const videoManifest = [];
|
|
179438
180044
|
const dlStart = Date.now();
|
|
@@ -179461,7 +180067,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
179461
180067
|
await new Promise((r) => setTimeout(r, 200));
|
|
179462
180068
|
if (liveRemainingMs(opts ?? {}, 1) > 0) {
|
|
179463
180069
|
await page.screenshot({
|
|
179464
|
-
path:
|
|
180070
|
+
path: join133(previewDir, previewName),
|
|
179465
180071
|
clip: {
|
|
179466
180072
|
x: Math.max(0, rect.x),
|
|
179467
180073
|
y: Math.max(0, rect.y),
|
|
@@ -179498,7 +180104,7 @@ async function captureVideoManifest(page, outputDir, progress, opts) {
|
|
|
179498
180104
|
}
|
|
179499
180105
|
if (videoManifest.length > 0) {
|
|
179500
180106
|
writeFileSync54(
|
|
179501
|
-
|
|
180107
|
+
join133(outputDir, "extracted", "video-manifest.json"),
|
|
179502
180108
|
JSON.stringify(videoManifest, null, 2),
|
|
179503
180109
|
"utf-8"
|
|
179504
180110
|
);
|
|
@@ -179575,12 +180181,12 @@ import {
|
|
|
179575
180181
|
existsSync as existsSync117,
|
|
179576
180182
|
readdirSync as readdirSync43,
|
|
179577
180183
|
statSync as statSync45,
|
|
179578
|
-
readFileSync as
|
|
180184
|
+
readFileSync as readFileSync90,
|
|
179579
180185
|
openSync as openSync14,
|
|
179580
180186
|
fstatSync as fstatSync9,
|
|
179581
180187
|
closeSync as closeSync15
|
|
179582
180188
|
} from "fs";
|
|
179583
|
-
import { basename as basename33, join as
|
|
180189
|
+
import { basename as basename33, join as join134 } from "path";
|
|
179584
180190
|
function resolveVisionPhaseCompletion(outcome, remainingMs) {
|
|
179585
180191
|
if (outcome.budgetExhausted || remainingMs <= 0) {
|
|
179586
180192
|
return { status: "degraded", reason: "budget-exhausted" };
|
|
@@ -179861,7 +180467,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179861
180467
|
return response.text?.trim() || "";
|
|
179862
180468
|
};
|
|
179863
180469
|
}
|
|
179864
|
-
const imageFiles = readdirSync43(
|
|
180470
|
+
const imageFiles = readdirSync43(join134(outputDir, "assets")).filter(
|
|
179865
180471
|
(f) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f)
|
|
179866
180472
|
);
|
|
179867
180473
|
const BATCH_SIZE = 20;
|
|
@@ -179889,13 +180495,13 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179889
180495
|
const batch = imageFiles.slice(i, i + BATCH_SIZE);
|
|
179890
180496
|
const results = await Promise.allSettled(
|
|
179891
180497
|
batch.map(async (file) => {
|
|
179892
|
-
const filePath =
|
|
180498
|
+
const filePath = join134(outputDir, "assets", file);
|
|
179893
180499
|
const fd = openSync14(filePath, "r");
|
|
179894
180500
|
let buffer;
|
|
179895
180501
|
try {
|
|
179896
180502
|
const stat = fstatSync9(fd);
|
|
179897
180503
|
if (stat.size > 4e6) return { file, caption: "" };
|
|
179898
|
-
buffer =
|
|
180504
|
+
buffer = readFileSync90(fd);
|
|
179899
180505
|
} finally {
|
|
179900
180506
|
closeSync15(fd);
|
|
179901
180507
|
}
|
|
@@ -179928,11 +180534,11 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179928
180534
|
`${Object.keys(geminiCaptions).length} images captioned with ${providerName}`
|
|
179929
180535
|
);
|
|
179930
180536
|
const svgFiles = [];
|
|
179931
|
-
const assetsDir =
|
|
180537
|
+
const assetsDir = join134(outputDir, "assets");
|
|
179932
180538
|
for (const f of readdirSync43(assetsDir)) {
|
|
179933
180539
|
if (/\.svg$/i.test(f)) svgFiles.push({ file: f, relPath: f });
|
|
179934
180540
|
}
|
|
179935
|
-
const svgsSubdir =
|
|
180541
|
+
const svgsSubdir = join134(assetsDir, "svgs");
|
|
179936
180542
|
if (existsSync117(svgsSubdir)) {
|
|
179937
180543
|
for (const f of readdirSync43(svgsSubdir)) {
|
|
179938
180544
|
if (/\.svg$/i.test(f)) svgFiles.push({ file: f, relPath: `svgs/${f}` });
|
|
@@ -179966,9 +180572,9 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
179966
180572
|
sharp5.concurrency(1);
|
|
179967
180573
|
try {
|
|
179968
180574
|
for (const { relPath } of batch) {
|
|
179969
|
-
const filePath =
|
|
180575
|
+
const filePath = join134(assetsDir, relPath);
|
|
179970
180576
|
try {
|
|
179971
|
-
const svgSource =
|
|
180577
|
+
const svgSource = readFileSync90(filePath, "utf-8");
|
|
179972
180578
|
const lightFillHits = (svgSource.match(/fill\s*=\s*["'](#fff(fff)?|white|#[ef][ef][ef]|#[ef]{6})["']/gi) || []).length;
|
|
179973
180579
|
const darkFillHits = (svgSource.match(/fill\s*=\s*["'](#000(000)?|black|#[0-3]{6}|#[0-3]{3})["']/gi) || []).length;
|
|
179974
180580
|
const bg = lightFillHits > darkFillHits ? { r: 32, g: 32, b: 32 } : { r: 255, g: 255, b: 255 };
|
|
@@ -180041,11 +180647,11 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180041
180647
|
const uncaptionedLines = [];
|
|
180042
180648
|
const svgLines = [];
|
|
180043
180649
|
const fontLines = [];
|
|
180044
|
-
const assetsPath =
|
|
180650
|
+
const assetsPath = join134(outputDir, "assets");
|
|
180045
180651
|
try {
|
|
180046
180652
|
for (const file of readdirSync43(assetsPath)) {
|
|
180047
180653
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
180048
|
-
const filePath =
|
|
180654
|
+
const filePath = join134(assetsPath, file);
|
|
180049
180655
|
const stat = statSync45(filePath);
|
|
180050
180656
|
if (!stat.isFile()) continue;
|
|
180051
180657
|
const sizeKb = Math.round(stat.size / 1024);
|
|
@@ -180074,7 +180680,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180074
180680
|
} catch {
|
|
180075
180681
|
}
|
|
180076
180682
|
try {
|
|
180077
|
-
const svgsPath =
|
|
180683
|
+
const svgsPath = join134(assetsPath, "svgs");
|
|
180078
180684
|
for (const file of readdirSync43(svgsPath)) {
|
|
180079
180685
|
if (!file.endsWith(".svg")) continue;
|
|
180080
180686
|
const svgMatch = tokens.svgs.find(
|
|
@@ -180093,7 +180699,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180093
180699
|
} catch {
|
|
180094
180700
|
}
|
|
180095
180701
|
try {
|
|
180096
|
-
const fontsPath =
|
|
180702
|
+
const fontsPath = join134(assetsPath, "fonts");
|
|
180097
180703
|
for (const file of readdirSync43(fontsPath)) {
|
|
180098
180704
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
180099
180705
|
}
|
|
@@ -180102,7 +180708,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
180102
180708
|
const videoLines = [];
|
|
180103
180709
|
try {
|
|
180104
180710
|
const manifest = JSON.parse(
|
|
180105
|
-
|
|
180711
|
+
readFileSync90(join134(outputDir, "extracted", "video-manifest.json"), "utf-8")
|
|
180106
180712
|
);
|
|
180107
180713
|
for (const v2 of manifest) {
|
|
180108
180714
|
if (!v2.localPath) continue;
|
|
@@ -180139,7 +180745,7 @@ __export(agentPromptGenerator_exports, {
|
|
|
180139
180745
|
generateAgentPrompt: () => generateAgentPrompt
|
|
180140
180746
|
});
|
|
180141
180747
|
import { writeFileSync as writeFileSync55, readdirSync as readdirSync44, existsSync as existsSync118 } from "fs";
|
|
180142
|
-
import { join as
|
|
180748
|
+
import { join as join135 } from "path";
|
|
180143
180749
|
function inferColorRole(hex) {
|
|
180144
180750
|
const r = parseInt(hex.slice(1, 3), 16) / 255;
|
|
180145
180751
|
const g = parseInt(hex.slice(3, 5), 16) / 255;
|
|
@@ -180158,9 +180764,9 @@ function inferColorRole(hex) {
|
|
|
180158
180764
|
}
|
|
180159
180765
|
function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
|
|
180160
180766
|
const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
|
|
180161
|
-
writeFileSync55(
|
|
180162
|
-
writeFileSync55(
|
|
180163
|
-
writeFileSync55(
|
|
180767
|
+
writeFileSync55(join135(outputDir, "AGENTS.md"), prompt, "utf-8");
|
|
180768
|
+
writeFileSync55(join135(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
|
180769
|
+
writeFileSync55(join135(outputDir, ".cursorrules"), prompt, "utf-8");
|
|
180164
180770
|
}
|
|
180165
180771
|
function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
|
|
180166
180772
|
const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -180169,7 +180775,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
180169
180775
|
(f) => f.family + (f.variable && f.weightRange ? ` (${f.weightRange[0]}-${f.weightRange[1]} variable)` : f.weights.length > 0 ? ` (${f.weights.join(",")})` : "")
|
|
180170
180776
|
).join(", ") || "none detected";
|
|
180171
180777
|
function contactSheetRows(dir, baseFile, label2) {
|
|
180172
|
-
const fullDir =
|
|
180778
|
+
const fullDir = join135(outputDir, dir);
|
|
180173
180779
|
if (!existsSync118(fullDir)) return [];
|
|
180174
180780
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
180175
180781
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -180202,7 +180808,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
180202
180808
|
tableRows.push(
|
|
180203
180809
|
`| \`extracted/tokens.json\` | Design tokens: ${tokens.colors.length} colors, ${tokens.fonts.length} fonts, ${tokens.headings?.length ?? 0} headings, ${tokens.ctas?.length ?? 0} CTAs |`
|
|
180204
180810
|
);
|
|
180205
|
-
if (existsSync118(
|
|
180811
|
+
if (existsSync118(join135(outputDir, "extracted", "design-styles.json"))) {
|
|
180206
180812
|
tableRows.push(
|
|
180207
180813
|
"| `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. |"
|
|
180208
180814
|
);
|
|
@@ -180273,15 +180879,15 @@ var init_agentPromptGenerator = __esm({
|
|
|
180273
180879
|
});
|
|
180274
180880
|
|
|
180275
180881
|
// src/capture/scaffolding.ts
|
|
180276
|
-
import { existsSync as existsSync119, readFileSync as
|
|
180277
|
-
import { join as
|
|
180882
|
+
import { existsSync as existsSync119, readFileSync as readFileSync91 } from "fs";
|
|
180883
|
+
import { join as join136, resolve as resolve77 } from "path";
|
|
180278
180884
|
function loadEnvFile(startDir) {
|
|
180279
180885
|
try {
|
|
180280
180886
|
let dir = resolve77(startDir);
|
|
180281
180887
|
for (let i = 0; i < 5; i++) {
|
|
180282
180888
|
const envPath = resolve77(dir, ".env");
|
|
180283
180889
|
try {
|
|
180284
|
-
const envContent =
|
|
180890
|
+
const envContent = readFileSync91(envPath, "utf-8");
|
|
180285
180891
|
for (const line3 of envContent.split("\n")) {
|
|
180286
180892
|
const trimmed = line3.trim();
|
|
180287
180893
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -180300,7 +180906,7 @@ function loadEnvFile(startDir) {
|
|
|
180300
180906
|
}
|
|
180301
180907
|
}
|
|
180302
180908
|
async function generateProjectScaffold(outputDir, url, tokens, animationCatalog, hasScreenshots, hasLotties, hasShaders, catalogedAssets, progress, warnings, detectedLibraries) {
|
|
180303
|
-
const metaPath =
|
|
180909
|
+
const metaPath = join136(outputDir, "meta.json");
|
|
180304
180910
|
if (!existsSync119(metaPath)) {
|
|
180305
180911
|
const hostname2 = new URL(url).hostname.replace(/^www\./, "");
|
|
180306
180912
|
writeNewFileSync(
|
|
@@ -180354,10 +180960,10 @@ var init_pageBlockDetection = __esm({
|
|
|
180354
180960
|
|
|
180355
180961
|
// src/capture/responseRecord.ts
|
|
180356
180962
|
import { writeFileSync as writeFileSync56 } from "fs";
|
|
180357
|
-
import { join as
|
|
180963
|
+
import { join as join137 } from "path";
|
|
180358
180964
|
function writeResponseRecord(extractedDir, record2) {
|
|
180359
180965
|
writeFileSync56(
|
|
180360
|
-
|
|
180966
|
+
join137(extractedDir, RESPONSE_RECORD_FILENAME),
|
|
180361
180967
|
JSON.stringify(record2, null, 2),
|
|
180362
180968
|
"utf-8"
|
|
180363
180969
|
);
|
|
@@ -180422,7 +181028,7 @@ __export(screenshotCapture_exports, {
|
|
|
180422
181028
|
pngHeight: () => pngHeight
|
|
180423
181029
|
});
|
|
180424
181030
|
import { writeFileSync as writeFileSync57, mkdirSync as mkdirSync63 } from "fs";
|
|
180425
|
-
import { join as
|
|
181031
|
+
import { join as join138 } from "path";
|
|
180426
181032
|
function pngHeight(buf) {
|
|
180427
181033
|
if (buf.length < 24) return null;
|
|
180428
181034
|
if (buf[12] !== 73 || buf[13] !== 72 || buf[14] !== 68 || buf[15] !== 82) return null;
|
|
@@ -180447,7 +181053,7 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
180447
181053
|
const buffer = await page.screenshot({ type: "png", fullPage: true });
|
|
180448
181054
|
const produced = pngHeight(buffer);
|
|
180449
181055
|
if (produced != null && produced > MAX_PLATE_HEIGHT_PX) return null;
|
|
180450
|
-
writeFileSync57(
|
|
181056
|
+
writeFileSync57(join138(screenshotsDir, "full-page.png"), buffer);
|
|
180451
181057
|
return "screenshots/full-page.png";
|
|
180452
181058
|
} finally {
|
|
180453
181059
|
try {
|
|
@@ -180462,7 +181068,7 @@ async function captureFullPagePlate(page, screenshotsDir, budget = {}) {
|
|
|
180462
181068
|
}
|
|
180463
181069
|
}
|
|
180464
181070
|
async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
180465
|
-
const screenshotsDir =
|
|
181071
|
+
const screenshotsDir = join138(outputDir, "screenshots");
|
|
180466
181072
|
mkdirSync63(screenshotsDir, { recursive: true });
|
|
180467
181073
|
const MAX_SCREENSHOTS = 20;
|
|
180468
181074
|
const filePaths = [];
|
|
@@ -180559,7 +181165,7 @@ async function captureScrollScreenshots(page, outputDir, budget = {}) {
|
|
|
180559
181165
|
finalPositions[i] / Math.max(1, scrollHeight - viewportHeight) * 100
|
|
180560
181166
|
);
|
|
180561
181167
|
const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
|
|
180562
|
-
const filePath =
|
|
181168
|
+
const filePath = join138(screenshotsDir, filename);
|
|
180563
181169
|
if ((budget.remainingMs?.() ?? 1) <= 0) break;
|
|
180564
181170
|
const buffer = await page.screenshot({ type: "png" });
|
|
180565
181171
|
writeFileSync57(filePath, buffer);
|
|
@@ -180920,7 +181526,7 @@ __export(capture_exports, {
|
|
|
180920
181526
|
captureWebsite: () => captureWebsite
|
|
180921
181527
|
});
|
|
180922
181528
|
import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync58, existsSync as existsSync120 } from "fs";
|
|
180923
|
-
import { join as
|
|
181529
|
+
import { join as join139 } from "path";
|
|
180924
181530
|
async function captureWebsite(opts, onProgress) {
|
|
180925
181531
|
const {
|
|
180926
181532
|
url,
|
|
@@ -180962,9 +181568,9 @@ async function captureWebsite(opts, onProgress) {
|
|
|
180962
181568
|
};
|
|
180963
181569
|
phase("browser", "started");
|
|
180964
181570
|
loadEnvFile(outputDir);
|
|
180965
|
-
mkdirSync64(
|
|
180966
|
-
mkdirSync64(
|
|
180967
|
-
mkdirSync64(
|
|
181571
|
+
mkdirSync64(join139(outputDir, "extracted"), { recursive: true });
|
|
181572
|
+
mkdirSync64(join139(outputDir, "screenshots"), { recursive: true });
|
|
181573
|
+
mkdirSync64(join139(outputDir, "assets"), { recursive: true });
|
|
180968
181574
|
progress("browser", "Launching headless Chrome...");
|
|
180969
181575
|
const { ensureBrowser: ensureBrowser2 } = await Promise.resolve().then(() => (init_manager2(), manager_exports2));
|
|
180970
181576
|
const browser = await ensureBrowser2();
|
|
@@ -181075,7 +181681,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
181075
181681
|
progress("warn", message);
|
|
181076
181682
|
}
|
|
181077
181683
|
const httpStatus = navigationResponse?.status() ?? null;
|
|
181078
|
-
writeResponseRecord(
|
|
181684
|
+
writeResponseRecord(join139(outputDir, "extracted"), { status: httpStatus });
|
|
181079
181685
|
const blockedReason = detectBlockedPage({
|
|
181080
181686
|
httpStatus,
|
|
181081
181687
|
...contentCheckTimedOut ? {
|
|
@@ -181139,7 +181745,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
181139
181745
|
else discoveredLotties[existing] = found;
|
|
181140
181746
|
}
|
|
181141
181747
|
if (discoveredLotties.length > 0 && remainingMs() > 0) {
|
|
181142
|
-
const lottieDir =
|
|
181748
|
+
const lottieDir = join139(outputDir, "assets", "lottie");
|
|
181143
181749
|
mkdirSync64(lottieDir, { recursive: true });
|
|
181144
181750
|
const lottieBudget = { remainingMs, byteBudget: downloadByteBudget };
|
|
181145
181751
|
const savedCount = await saveLottieAnimations(discoveredLotties, lottieDir, lottieBudget);
|
|
@@ -181160,7 +181766,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
181160
181766
|
});
|
|
181161
181767
|
capturedShaders = unique;
|
|
181162
181768
|
writeFileSync58(
|
|
181163
|
-
|
|
181769
|
+
join139(outputDir, "extracted", "shaders.json"),
|
|
181164
181770
|
JSON.stringify(unique, null, 2),
|
|
181165
181771
|
"utf-8"
|
|
181166
181772
|
);
|
|
@@ -181175,7 +181781,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
181175
181781
|
svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
|
|
181176
181782
|
};
|
|
181177
181783
|
writeFileSync58(
|
|
181178
|
-
|
|
181784
|
+
join139(outputDir, "extracted", "tokens.json"),
|
|
181179
181785
|
JSON.stringify(tokensForDisk, null, 2),
|
|
181180
181786
|
"utf-8"
|
|
181181
181787
|
);
|
|
@@ -181183,7 +181789,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
181183
181789
|
try {
|
|
181184
181790
|
const designStyles = await extractDesignStyles(page1);
|
|
181185
181791
|
writeFileSync58(
|
|
181186
|
-
|
|
181792
|
+
join139(outputDir, "extracted", "design-styles.json"),
|
|
181187
181793
|
JSON.stringify(designStyles, null, 2),
|
|
181188
181794
|
"utf-8"
|
|
181189
181795
|
);
|
|
@@ -181317,8 +181923,8 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
181317
181923
|
);
|
|
181318
181924
|
try {
|
|
181319
181925
|
const fontsManifest = extractFontMetadata(
|
|
181320
|
-
|
|
181321
|
-
|
|
181926
|
+
join139(outputDir, "assets", "fonts"),
|
|
181927
|
+
join139(outputDir, "extracted", "fonts-manifest.json")
|
|
181322
181928
|
);
|
|
181323
181929
|
if (fontsManifest.families.length > 0) {
|
|
181324
181930
|
const summary = fontsManifest.families.map((f) => `${f.family}${f.variable ? " (variable)" : ""} \xD7 ${f.fileCount}`).join(", ");
|
|
@@ -181345,7 +181951,7 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
181345
181951
|
representativeAnimations: representativeAnims
|
|
181346
181952
|
};
|
|
181347
181953
|
writeFileSync58(
|
|
181348
|
-
|
|
181954
|
+
join139(outputDir, "extracted", "animations.json"),
|
|
181349
181955
|
JSON.stringify(leanCatalog, null, 2),
|
|
181350
181956
|
"utf-8"
|
|
181351
181957
|
);
|
|
@@ -181362,7 +181968,7 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
181362
181968
|
assets = assetPass.assets;
|
|
181363
181969
|
assetDrops = assetPass.drops;
|
|
181364
181970
|
writeFileSync58(
|
|
181365
|
-
|
|
181971
|
+
join139(outputDir, "extracted", "icons-manifest.json"),
|
|
181366
181972
|
JSON.stringify(assetPass.icons, null, 2),
|
|
181367
181973
|
"utf-8"
|
|
181368
181974
|
);
|
|
@@ -181403,7 +182009,7 @@ ${err.stack}` : normalizeErrorMessage(err);
|
|
|
181403
182009
|
svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
|
|
181404
182010
|
};
|
|
181405
182011
|
writeFileSync58(
|
|
181406
|
-
|
|
182012
|
+
join139(outputDir, "extracted", "tokens.json"),
|
|
181407
182013
|
JSON.stringify(tokensForDisk2, null, 2),
|
|
181408
182014
|
"utf-8"
|
|
181409
182015
|
);
|
|
@@ -181419,12 +182025,12 @@ ${extracted.bodyHtml}
|
|
|
181419
182025
|
</body>
|
|
181420
182026
|
</html>
|
|
181421
182027
|
`;
|
|
181422
|
-
writeFileSync58(
|
|
182028
|
+
writeFileSync58(join139(outputDir, "extracted", "page.html"), pageHtml, "utf-8");
|
|
181423
182029
|
} catch (err) {
|
|
181424
182030
|
warnings.push(`page.html write failed: ${err}`);
|
|
181425
182031
|
}
|
|
181426
182032
|
if (visibleTextContent) {
|
|
181427
|
-
writeFileSync58(
|
|
182033
|
+
writeFileSync58(join139(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
|
|
181428
182034
|
}
|
|
181429
182035
|
let geminiCaptions = {};
|
|
181430
182036
|
if (skipVision) {
|
|
@@ -181461,7 +182067,7 @@ ${extracted.bodyHtml}
|
|
|
181461
182067
|
const hasVisionKey = !!(!skipVision && (process.env.OPENROUTER_API_KEY || process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY || process.env.HYPERFRAMES_VERTEX_PROJECT_ID && process.env.HYPERFRAMES_VERTEX_SERVICE_ACCOUNT));
|
|
181462
182068
|
const header2 = hasVisionKey ? "# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\nTo find a specific brand or icon, **grep this file for the brand name in the description text** (e.g. `grep -i 'autodesk' asset-descriptions.md`). The Gemini Vision captions identify what's actually in each file \u2014 that's the agent's selector.\n\nThe `logo-<hash>.svg` filename prefix is a cheap structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). It is NOT a content claim \u2014 many `logo-*` files are nav icons or decorative shapes. Trust the captions, not the filename prefix.\n\n" : "# Asset Descriptions\n\n\u26A0\uFE0F No vision credentials \u2014 descriptions below are catalog-derived (alt text, headings, section context, filename) instead of Vision-generated. To get richer Vision descriptions on the next capture, set GEMINI_API_KEY (or GOOGLE_API_KEY), or HYPERFRAMES_VERTEX_PROJECT_ID plus HYPERFRAMES_VERTEX_SERVICE_ACCOUNT for Vertex service-account auth, and re-run.\n\nThe `logo-<hash>.svg` filename prefix is a structural hint (DOM said this SVG was inside a `<header>`, home-link `<a>`, or had an aria-label matching the page brand). To pick the actual brand logo without Vision, open the `logo-*` candidates in a previewer or rasterize them with `sharp` before referencing \u2014 composing a fake logo ships off-brand in the final video.\n\n";
|
|
181463
182069
|
writeFileSync58(
|
|
181464
|
-
|
|
182070
|
+
join139(outputDir, "extracted", "asset-descriptions.md"),
|
|
181465
182071
|
header2 + lines.map((l) => "- " + l).join("\n") + "\n",
|
|
181466
182072
|
"utf-8"
|
|
181467
182073
|
);
|
|
@@ -181479,8 +182085,8 @@ ${extracted.bodyHtml}
|
|
|
181479
182085
|
const { createScrollContactSheet: createScrollContactSheet2, createAssetContactSheet: createAssetContactSheet2, createSvgContactSheet: createSvgContactSheet2 } = await Promise.resolve().then(() => (init_contactSheet(), contactSheet_exports));
|
|
181480
182086
|
const contactSheetBudget = { remainingMs };
|
|
181481
182087
|
const scrollSheets = await createScrollContactSheet2(
|
|
181482
|
-
|
|
181483
|
-
|
|
182088
|
+
join139(outputDir, "screenshots"),
|
|
182089
|
+
join139(outputDir, "screenshots", "contact-sheet.jpg"),
|
|
181484
182090
|
contactSheetBudget
|
|
181485
182091
|
);
|
|
181486
182092
|
if (scrollSheets.length > 0)
|
|
@@ -181488,11 +182094,11 @@ ${extracted.bodyHtml}
|
|
|
181488
182094
|
"design",
|
|
181489
182095
|
`Screenshot contact sheet generated (${scrollSheets.length} page${scrollSheets.length > 1 ? "s" : ""})`
|
|
181490
182096
|
);
|
|
181491
|
-
const assetsImgDir =
|
|
182097
|
+
const assetsImgDir = join139(outputDir, "assets");
|
|
181492
182098
|
if (existsSync120(assetsImgDir)) {
|
|
181493
182099
|
const assetSheets = await createAssetContactSheet2(
|
|
181494
182100
|
assetsImgDir,
|
|
181495
|
-
|
|
182101
|
+
join139(outputDir, "assets", "contact-sheet.jpg"),
|
|
181496
182102
|
contactSheetBudget
|
|
181497
182103
|
);
|
|
181498
182104
|
if (assetSheets.length > 0)
|
|
@@ -181501,9 +182107,9 @@ ${extracted.bodyHtml}
|
|
|
181501
182107
|
`Asset contact sheet generated (${assetSheets.length} page${assetSheets.length > 1 ? "s" : ""})`
|
|
181502
182108
|
);
|
|
181503
182109
|
}
|
|
181504
|
-
const svgsDir =
|
|
181505
|
-
const assetsRootDir =
|
|
181506
|
-
const svgOutputPath = existsSync120(svgsDir) ?
|
|
182110
|
+
const svgsDir = join139(outputDir, "assets", "svgs");
|
|
182111
|
+
const assetsRootDir = join139(outputDir, "assets");
|
|
182112
|
+
const svgOutputPath = existsSync120(svgsDir) ? join139(outputDir, "assets", "svgs", "contact-sheet.jpg") : join139(outputDir, "assets", "contact-sheet-svgs.jpg");
|
|
181507
182113
|
const svgSheets = await createSvgContactSheet2(
|
|
181508
182114
|
svgsDir,
|
|
181509
182115
|
svgOutputPath,
|
|
@@ -181536,7 +182142,7 @@ ${extracted.bodyHtml}
|
|
|
181536
182142
|
animationCatalog,
|
|
181537
182143
|
screenshots.length > 0,
|
|
181538
182144
|
discoveredLotties.length > 0,
|
|
181539
|
-
existsSync120(
|
|
182145
|
+
existsSync120(join139(outputDir, "extracted", "shaders.json")),
|
|
181540
182146
|
catalogedAssets,
|
|
181541
182147
|
progress,
|
|
181542
182148
|
warnings,
|
|
@@ -181900,10 +182506,10 @@ __export(state_exports, {
|
|
|
181900
182506
|
stateFilePath: () => stateFilePath,
|
|
181901
182507
|
writeStackOutputs: () => writeStackOutputs
|
|
181902
182508
|
});
|
|
181903
|
-
import { existsSync as existsSync121, mkdirSync as mkdirSync65, readdirSync as readdirSync45, readFileSync as
|
|
181904
|
-
import { dirname as dirname63, join as
|
|
182509
|
+
import { existsSync as existsSync121, mkdirSync as mkdirSync65, readdirSync as readdirSync45, readFileSync as readFileSync93, rmSync as rmSync40, writeFileSync as writeFileSync59 } from "fs";
|
|
182510
|
+
import { dirname as dirname63, join as join140 } from "path";
|
|
181905
182511
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
181906
|
-
return
|
|
182512
|
+
return join140(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
181907
182513
|
}
|
|
181908
182514
|
function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
181909
182515
|
const path = stateFilePath(outputs.stackName, cwd);
|
|
@@ -181915,7 +182521,7 @@ function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
|
181915
182521
|
const path = stateFilePath(stackName, cwd);
|
|
181916
182522
|
if (!existsSync121(path)) return null;
|
|
181917
182523
|
try {
|
|
181918
|
-
return JSON.parse(
|
|
182524
|
+
return JSON.parse(readFileSync93(path, "utf-8"));
|
|
181919
182525
|
} catch {
|
|
181920
182526
|
return null;
|
|
181921
182527
|
}
|
|
@@ -181925,7 +182531,7 @@ function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd())
|
|
|
181925
182531
|
if (existsSync121(path)) rmSync40(path);
|
|
181926
182532
|
}
|
|
181927
182533
|
function listStackNames(cwd = process.cwd()) {
|
|
181928
|
-
const dir =
|
|
182534
|
+
const dir = join140(cwd, STATE_DIR_NAME);
|
|
181929
182535
|
if (!existsSync121(dir)) return [];
|
|
181930
182536
|
return readdirSync45(dir).filter((f) => f.startsWith(STATE_FILE_PREFIX) && f.endsWith(".json")).map((f) => f.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
181931
182537
|
}
|
|
@@ -181958,7 +182564,7 @@ var init_state = __esm({
|
|
|
181958
182564
|
// src/commands/lambda/sam.ts
|
|
181959
182565
|
import { execFileSync as execFileSync19, spawnSync as spawnSync4 } from "child_process";
|
|
181960
182566
|
import { existsSync as existsSync122 } from "fs";
|
|
181961
|
-
import { join as
|
|
182567
|
+
import { join as join141 } from "path";
|
|
181962
182568
|
function assertSamAvailable() {
|
|
181963
182569
|
try {
|
|
181964
182570
|
execFileSync19("sam", ["--version"], { stdio: "ignore" });
|
|
@@ -181978,7 +182584,7 @@ function assertAwsCliAvailable() {
|
|
|
181978
182584
|
}
|
|
181979
182585
|
}
|
|
181980
182586
|
function locateSamTemplate(repoRoot2) {
|
|
181981
|
-
const candidate =
|
|
182587
|
+
const candidate = join141(repoRoot2, "examples", "aws-lambda", "template.yaml");
|
|
181982
182588
|
if (!existsSync122(candidate)) {
|
|
181983
182589
|
throw new Error(
|
|
181984
182590
|
`[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.`
|
|
@@ -182012,7 +182618,7 @@ function samDeploy(opts) {
|
|
|
182012
182618
|
if (opts.awsProfile) {
|
|
182013
182619
|
args.push("--profile", opts.awsProfile);
|
|
182014
182620
|
}
|
|
182015
|
-
const samDir =
|
|
182621
|
+
const samDir = join141(opts.repoRoot, "examples", "aws-lambda");
|
|
182016
182622
|
const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
182017
182623
|
if (result.status !== 0) {
|
|
182018
182624
|
throw new Error(
|
|
@@ -182030,7 +182636,7 @@ function samDelete(opts) {
|
|
|
182030
182636
|
if (opts.awsProfile) {
|
|
182031
182637
|
args.push("--profile", opts.awsProfile);
|
|
182032
182638
|
}
|
|
182033
|
-
const samDir =
|
|
182639
|
+
const samDir = join141(opts.repoRoot, "examples", "aws-lambda");
|
|
182034
182640
|
const result = spawnSync4("sam", args, { cwd: samDir, stdio: opts.stdio ?? "inherit" });
|
|
182035
182641
|
if (result.status !== 0) {
|
|
182036
182642
|
throw new Error(`[lambda] sam delete exited with code ${result.status ?? "unknown"}`);
|
|
@@ -182114,7 +182720,7 @@ __export(deploy_exports, {
|
|
|
182114
182720
|
});
|
|
182115
182721
|
import { spawnSync as spawnSync5 } from "child_process";
|
|
182116
182722
|
import { existsSync as existsSync124 } from "fs";
|
|
182117
|
-
import { join as
|
|
182723
|
+
import { join as join143, resolve as resolve80 } from "path";
|
|
182118
182724
|
async function runDeploy(args = {}) {
|
|
182119
182725
|
const resolved2 = {
|
|
182120
182726
|
stackName: args.stackName ?? DEFAULT_STACK_NAME,
|
|
@@ -182131,7 +182737,7 @@ async function runDeploy(args = {}) {
|
|
|
182131
182737
|
console.log(c.dim("\u2192 Building handler ZIP"));
|
|
182132
182738
|
buildHandlerZip(root);
|
|
182133
182739
|
} else {
|
|
182134
|
-
const zip =
|
|
182740
|
+
const zip = join143(root, "packages", "aws-lambda", "dist", "handler.zip");
|
|
182135
182741
|
if (!existsSync124(zip)) {
|
|
182136
182742
|
throw new Error(
|
|
182137
182743
|
`--skip-build set but ${zip} does not exist. Run \`bun run --cwd packages/aws-lambda build:zip\` first or drop --skip-build.`
|
|
@@ -182175,7 +182781,7 @@ async function runDeploy(args = {}) {
|
|
|
182175
182781
|
function buildHandlerZip(root) {
|
|
182176
182782
|
const result = spawnSync5(
|
|
182177
182783
|
"bun",
|
|
182178
|
-
["run", "--cwd",
|
|
182784
|
+
["run", "--cwd", join143(root, "packages", "aws-lambda"), "build:zip"],
|
|
182179
182785
|
{ stdio: "inherit" }
|
|
182180
182786
|
);
|
|
182181
182787
|
if (result.status !== 0) {
|
|
@@ -182244,14 +182850,14 @@ var init_sites = __esm({
|
|
|
182244
182850
|
});
|
|
182245
182851
|
|
|
182246
182852
|
// src/commands/lambda/_dimensions.ts
|
|
182247
|
-
import { readFileSync as
|
|
182248
|
-
import { join as
|
|
182853
|
+
import { readFileSync as readFileSync94 } from "fs";
|
|
182854
|
+
import { join as join144 } from "path";
|
|
182249
182855
|
function warnOnDimensionMismatch(args) {
|
|
182250
182856
|
if (args.quiet) return;
|
|
182251
182857
|
if (args.outputResolution) return;
|
|
182252
182858
|
let html;
|
|
182253
182859
|
try {
|
|
182254
|
-
html =
|
|
182860
|
+
html = readFileSync94(join144(args.projectDir, "index.html"), "utf-8");
|
|
182255
182861
|
} catch {
|
|
182256
182862
|
return;
|
|
182257
182863
|
}
|
|
@@ -182281,7 +182887,7 @@ __export(render_exports2, {
|
|
|
182281
182887
|
runRender: () => runRender
|
|
182282
182888
|
});
|
|
182283
182889
|
import { existsSync as existsSync125 } from "fs";
|
|
182284
|
-
import { join as
|
|
182890
|
+
import { join as join145, resolve as resolvePath2 } from "path";
|
|
182285
182891
|
async function loadSDK2() {
|
|
182286
182892
|
return import("@hyperframes/aws-lambda/sdk");
|
|
182287
182893
|
}
|
|
@@ -182297,7 +182903,7 @@ async function runRender(args) {
|
|
|
182297
182903
|
});
|
|
182298
182904
|
const variables = resolveVariablesArg(args.variables, args.variablesFile);
|
|
182299
182905
|
if (variables && Object.keys(variables).length > 0) {
|
|
182300
|
-
const indexPath2 =
|
|
182906
|
+
const indexPath2 = join145(projectDir, "index.html");
|
|
182301
182907
|
if (existsSync125(indexPath2)) {
|
|
182302
182908
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
182303
182909
|
reportVariableIssues(issues, { strict: args.strictVariables ?? false, quiet: args.json });
|
|
@@ -182431,8 +183037,8 @@ __export(render_batch_exports, {
|
|
|
182431
183037
|
runRenderBatch: () => runRenderBatch,
|
|
182432
183038
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
182433
183039
|
});
|
|
182434
|
-
import { existsSync as existsSync126, readFileSync as
|
|
182435
|
-
import { join as
|
|
183040
|
+
import { existsSync as existsSync126, readFileSync as readFileSync95 } from "fs";
|
|
183041
|
+
import { join as join146, resolve as resolvePath3 } from "path";
|
|
182436
183042
|
async function loadSDK3() {
|
|
182437
183043
|
return import("@hyperframes/aws-lambda/sdk");
|
|
182438
183044
|
}
|
|
@@ -182456,7 +183062,7 @@ async function runRenderBatch(args) {
|
|
|
182456
183062
|
outputResolution: args.outputResolution,
|
|
182457
183063
|
quiet: args.json
|
|
182458
183064
|
});
|
|
182459
|
-
const schema = loadProjectVariableSchema(
|
|
183065
|
+
const schema = loadProjectVariableSchema(join146(projectDir, "index.html"));
|
|
182460
183066
|
const strict = args.strictVariables ?? false;
|
|
182461
183067
|
let hadStrictIssue = false;
|
|
182462
183068
|
for (const { entry, lineNumber } of entries2) {
|
|
@@ -182591,7 +183197,7 @@ function buildLambdaBatchRenderConfig(args) {
|
|
|
182591
183197
|
return config;
|
|
182592
183198
|
}
|
|
182593
183199
|
function parseBatchFile(path) {
|
|
182594
|
-
const raw =
|
|
183200
|
+
const raw = readFileSync95(path, "utf8");
|
|
182595
183201
|
const lines = raw.split(/\r?\n/);
|
|
182596
183202
|
const out = [];
|
|
182597
183203
|
for (let i = 0; i < lines.length; i++) {
|
|
@@ -182785,7 +183391,7 @@ __export(policies_exports, {
|
|
|
182785
183391
|
runPolicies: () => runPolicies,
|
|
182786
183392
|
validatePolicy: () => validatePolicy
|
|
182787
183393
|
});
|
|
182788
|
-
import { readFileSync as
|
|
183394
|
+
import { readFileSync as readFileSync96 } from "fs";
|
|
182789
183395
|
function allRequiredActions() {
|
|
182790
183396
|
const set = /* @__PURE__ */ new Set();
|
|
182791
183397
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -182891,7 +183497,7 @@ async function runPolicies(args) {
|
|
|
182891
183497
|
}
|
|
182892
183498
|
}
|
|
182893
183499
|
function validatePolicy(policyPath) {
|
|
182894
|
-
const raw =
|
|
183500
|
+
const raw = readFileSync96(policyPath, "utf-8");
|
|
182895
183501
|
const parsed = JSON.parse(raw);
|
|
182896
183502
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
182897
183503
|
parsed.Statement
|
|
@@ -183502,9 +184108,9 @@ __export(cloudrun_exports, {
|
|
|
183502
184108
|
missingCloudRunAdapterMessage: () => missingCloudRunAdapterMessage
|
|
183503
184109
|
});
|
|
183504
184110
|
import { spawnSync as spawnSync6 } from "child_process";
|
|
183505
|
-
import { existsSync as existsSync127, mkdirSync as mkdirSync66, readFileSync as
|
|
184111
|
+
import { existsSync as existsSync127, mkdirSync as mkdirSync66, readFileSync as readFileSync97, writeFileSync as writeFileSync60 } from "fs";
|
|
183506
184112
|
import { homedir as homedir24 } from "os";
|
|
183507
|
-
import { join as
|
|
184113
|
+
import { join as join147, resolve as resolve81 } from "path";
|
|
183508
184114
|
function loadCloudRunAdapter() {
|
|
183509
184115
|
cloudRunAdapterPromise ??= Promise.all([
|
|
183510
184116
|
import("@hyperframes/gcp-cloud-run/sdk"),
|
|
@@ -183523,10 +184129,10 @@ Or, for an opt-in project setup:
|
|
|
183523
184129
|
${c.accent("npm install @hyperframes/gcp-cloud-run")}`;
|
|
183524
184130
|
}
|
|
183525
184131
|
function stateDir() {
|
|
183526
|
-
return
|
|
184132
|
+
return join147(homedir24(), ".hyperframes");
|
|
183527
184133
|
}
|
|
183528
184134
|
function statePath() {
|
|
183529
|
-
return
|
|
184135
|
+
return join147(stateDir(), "cloudrun-state.json");
|
|
183530
184136
|
}
|
|
183531
184137
|
function writeState2(state) {
|
|
183532
184138
|
mkdirSync66(stateDir(), { recursive: true });
|
|
@@ -183540,7 +184146,7 @@ function readState2(args) {
|
|
|
183540
184146
|
let base2 = {};
|
|
183541
184147
|
if (existsSync127(statePath())) {
|
|
183542
184148
|
try {
|
|
183543
|
-
base2 = JSON.parse(
|
|
184149
|
+
base2 = JSON.parse(readFileSync97(statePath(), "utf8"));
|
|
183544
184150
|
} catch {
|
|
183545
184151
|
}
|
|
183546
184152
|
}
|
|
@@ -183683,11 +184289,11 @@ function machineVars(args, project, region, image) {
|
|
|
183683
184289
|
}
|
|
183684
184290
|
function findRepoRoot(tfDir) {
|
|
183685
184291
|
const candidate = resolve81(tfDir, "..", "..", "..");
|
|
183686
|
-
if (existsSync127(
|
|
184292
|
+
if (existsSync127(join147(candidate, "packages", "gcp-cloud-run", "Dockerfile"))) return candidate;
|
|
183687
184293
|
return null;
|
|
183688
184294
|
}
|
|
183689
184295
|
function writeCloudBuildConfig(image) {
|
|
183690
|
-
const cfgPath =
|
|
184296
|
+
const cfgPath = join147(stateDir(), "cloudrun-cloudbuild.yaml");
|
|
183691
184297
|
mkdirSync66(stateDir(), { recursive: true });
|
|
183692
184298
|
writeFileSync60(
|
|
183693
184299
|
cfgPath,
|
|
@@ -183899,7 +184505,7 @@ async function runRenderBatch2(args) {
|
|
|
183899
184505
|
if (failed.length > 0) failCommand();
|
|
183900
184506
|
}
|
|
183901
184507
|
function parseBatchFile2(path) {
|
|
183902
|
-
const lines =
|
|
184508
|
+
const lines = readFileSync97(path, "utf8").split(/\r?\n/);
|
|
183903
184509
|
const entries2 = [];
|
|
183904
184510
|
lines.forEach((line3, idx) => {
|
|
183905
184511
|
const trimmed = line3.trim();
|
|
@@ -183924,7 +184530,7 @@ function parseBatchFile2(path) {
|
|
|
183924
184530
|
async function runDestroy2(args) {
|
|
183925
184531
|
const { getTerraformModuleDir } = await loadCloudRunAdapter();
|
|
183926
184532
|
const tfDir = getTerraformModuleDir();
|
|
183927
|
-
const state = existsSync127(statePath()) ? JSON.parse(
|
|
184533
|
+
const state = existsSync127(statePath()) ? JSON.parse(readFileSync97(statePath(), "utf8")) : {};
|
|
183928
184534
|
const project = args.project ?? state.projectId;
|
|
183929
184535
|
const region = args.region ?? state.region ?? "us-central1";
|
|
183930
184536
|
const image = args.image ?? "unused:latest";
|
|
@@ -183979,7 +184585,7 @@ function resolveAndValidateVariables(args, projectDir) {
|
|
|
183979
184585
|
args["variables-file"]
|
|
183980
184586
|
);
|
|
183981
184587
|
if (variables && Object.keys(variables).length > 0) {
|
|
183982
|
-
const indexPath2 =
|
|
184588
|
+
const indexPath2 = join147(projectDir, "index.html");
|
|
183983
184589
|
if (existsSync127(indexPath2)) {
|
|
183984
184590
|
const issues = validateVariablesAgainstProject(indexPath2, variables);
|
|
183985
184591
|
reportVariableIssues(issues, {
|
|
@@ -184226,7 +184832,7 @@ ${HELP2}`);
|
|
|
184226
184832
|
});
|
|
184227
184833
|
|
|
184228
184834
|
// src/cloud/detectAspectRatio.ts
|
|
184229
|
-
import { readFileSync as
|
|
184835
|
+
import { readFileSync as readFileSync98 } from "fs";
|
|
184230
184836
|
function extractAttributeNumber(tag, re2) {
|
|
184231
184837
|
const match = tag.match(re2);
|
|
184232
184838
|
if (!match) return null;
|
|
@@ -184238,7 +184844,7 @@ function extractAttributeNumber(tag, re2) {
|
|
|
184238
184844
|
function detectAspectRatioFromHtml(entryHtmlPath) {
|
|
184239
184845
|
let html;
|
|
184240
184846
|
try {
|
|
184241
|
-
html =
|
|
184847
|
+
html = readFileSync98(entryHtmlPath, "utf-8");
|
|
184242
184848
|
} catch (err) {
|
|
184243
184849
|
return { kind: "read-error", error: normalizeErrorMessage(err) };
|
|
184244
184850
|
}
|
|
@@ -184352,7 +184958,7 @@ import {
|
|
|
184352
184958
|
rmSync as rmSync41,
|
|
184353
184959
|
statSync as statSync46
|
|
184354
184960
|
} from "fs";
|
|
184355
|
-
import { dirname as dirname65, join as
|
|
184961
|
+
import { dirname as dirname65, join as join148, resolve as resolve82 } from "path";
|
|
184356
184962
|
import { pipeline as pipeline3 } from "stream/promises";
|
|
184357
184963
|
async function downloadToFile(url, destPath, options = {}) {
|
|
184358
184964
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -184369,8 +184975,8 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
184369
184975
|
const totalOpt = total !== void 0 && Number.isFinite(total) ? total : void 0;
|
|
184370
184976
|
const destination = resolveDownloadDestination(destPath);
|
|
184371
184977
|
const previous = statSync46(destination, { throwIfNoEntry: false });
|
|
184372
|
-
const stage = mkdtempSync27(
|
|
184373
|
-
const stagedFile =
|
|
184978
|
+
const stage = mkdtempSync27(join148(dirname65(destination), ".hf-download-"));
|
|
184979
|
+
const stagedFile = join148(stage, "download");
|
|
184374
184980
|
let bytes = 0;
|
|
184375
184981
|
try {
|
|
184376
184982
|
await pipeline3(
|
|
@@ -187036,12 +187642,12 @@ var init_freeze = __esm({
|
|
|
187036
187642
|
});
|
|
187037
187643
|
|
|
187038
187644
|
// ../core/dist/figma/jsonl.js
|
|
187039
|
-
import { existsSync as existsSync129, readFileSync as
|
|
187645
|
+
import { existsSync as existsSync129, readFileSync as readFileSync99 } from "fs";
|
|
187040
187646
|
function readJsonlValues(path) {
|
|
187041
187647
|
if (!existsSync129(path))
|
|
187042
187648
|
return [];
|
|
187043
187649
|
const out = [];
|
|
187044
|
-
for (const line3 of
|
|
187650
|
+
for (const line3 of readFileSync99(path, "utf8").split(/\r?\n/)) {
|
|
187045
187651
|
const trimmed = line3.trim();
|
|
187046
187652
|
if (trimmed.length === 0)
|
|
187047
187653
|
continue;
|
|
@@ -187060,16 +187666,16 @@ var init_jsonl = __esm({
|
|
|
187060
187666
|
});
|
|
187061
187667
|
|
|
187062
187668
|
// ../core/dist/figma/manifest.js
|
|
187063
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync130, mkdirSync as mkdirSync69, readFileSync as
|
|
187064
|
-
import { join as
|
|
187669
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync130, mkdirSync as mkdirSync69, readFileSync as readFileSync100, writeFileSync as writeFileSync63 } from "fs";
|
|
187670
|
+
import { join as join149 } from "path";
|
|
187065
187671
|
function mediaDir(projectDir) {
|
|
187066
|
-
return
|
|
187672
|
+
return join149(projectDir, ".media");
|
|
187067
187673
|
}
|
|
187068
187674
|
function manifestPath2(projectDir) {
|
|
187069
|
-
return
|
|
187675
|
+
return join149(mediaDir(projectDir), MANIFEST_FILE2);
|
|
187070
187676
|
}
|
|
187071
187677
|
function typeDirPath(projectDir, type) {
|
|
187072
|
-
return
|
|
187678
|
+
return join149(mediaDir(projectDir), TYPE_DIRS[type]);
|
|
187073
187679
|
}
|
|
187074
187680
|
function isFigmaManifestRecord(value) {
|
|
187075
187681
|
if (typeof value !== "object" || value === null)
|
|
@@ -187101,7 +187707,7 @@ function findAllByFigmaNode(projectDir, fileKey2, nodeId) {
|
|
|
187101
187707
|
}
|
|
187102
187708
|
function updateRecord(projectDir, record2) {
|
|
187103
187709
|
const p2 = manifestPath2(projectDir);
|
|
187104
|
-
const lines =
|
|
187710
|
+
const lines = readFileSync100(p2, "utf8").split(/\r?\n/);
|
|
187105
187711
|
const out = lines.map((line3) => {
|
|
187106
187712
|
const trimmed = line3.trim();
|
|
187107
187713
|
if (trimmed.length === 0)
|
|
@@ -187122,7 +187728,7 @@ function nextId(projectDir, type) {
|
|
|
187122
187728
|
const p2 = manifestPath2(projectDir);
|
|
187123
187729
|
if (!existsSync130(p2))
|
|
187124
187730
|
return `${type}_001`;
|
|
187125
|
-
for (const line3 of
|
|
187731
|
+
for (const line3 of readFileSync100(p2, "utf8").split(/\r?\n/)) {
|
|
187126
187732
|
const trimmed = line3.trim();
|
|
187127
187733
|
if (trimmed.length === 0)
|
|
187128
187734
|
continue;
|
|
@@ -187156,12 +187762,12 @@ var init_manifest = __esm({
|
|
|
187156
187762
|
|
|
187157
187763
|
// ../core/dist/figma/mediaIndex.js
|
|
187158
187764
|
import { mkdirSync as mkdirSync70, writeFileSync as writeFileSync64 } from "fs";
|
|
187159
|
-
import { dirname as dirname67, join as
|
|
187765
|
+
import { dirname as dirname67, join as join150 } from "path";
|
|
187160
187766
|
function isRow(value) {
|
|
187161
187767
|
return typeof value === "object" && value !== null;
|
|
187162
187768
|
}
|
|
187163
187769
|
function indexPath(projectDir) {
|
|
187164
|
-
return
|
|
187770
|
+
return join150(mediaDir(projectDir), "index.md");
|
|
187165
187771
|
}
|
|
187166
187772
|
function pad(str, len2) {
|
|
187167
187773
|
return String(str ?? "").padEnd(len2);
|
|
@@ -187273,9 +187879,9 @@ var init_sanitizeSvg = __esm({
|
|
|
187273
187879
|
|
|
187274
187880
|
// ../core/dist/figma/bindings.js
|
|
187275
187881
|
import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync71, writeFileSync as writeFileSync65 } from "fs";
|
|
187276
|
-
import { join as
|
|
187882
|
+
import { join as join151 } from "path";
|
|
187277
187883
|
function bindingsPath(projectDir) {
|
|
187278
|
-
return
|
|
187884
|
+
return join151(mediaDir(projectDir), BINDINGS_FILE);
|
|
187279
187885
|
}
|
|
187280
187886
|
function isRecord16(value) {
|
|
187281
187887
|
return typeof value === "object" && value !== null;
|
|
@@ -187876,7 +188482,7 @@ __export(asset_exports, {
|
|
|
187876
188482
|
runAssetImportMany: () => runAssetImportMany
|
|
187877
188483
|
});
|
|
187878
188484
|
import { existsSync as existsSync131 } from "fs";
|
|
187879
|
-
import { join as
|
|
188485
|
+
import { join as join152, relative as relative36 } from "path";
|
|
187880
188486
|
function gatherAssetRefs(positionals) {
|
|
187881
188487
|
return positionals.flatMap((r) => /^https?:/i.test(r.trim()) ? [r] : r.split(",")).map((r) => r.trim()).filter((r) => r.length > 0);
|
|
187882
188488
|
}
|
|
@@ -187890,7 +188496,7 @@ function requireNodeRef(refInput) {
|
|
|
187890
188496
|
}
|
|
187891
188497
|
function reuseExisting(fileKey2, nodeId, opts, version2, deps, description, entity) {
|
|
187892
188498
|
const existing = findAllByFigmaNode(deps.projectDir, fileKey2, nodeId).find(
|
|
187893
|
-
(r) => r.provenance.format === opts.format && (r.provenance.scale ?? 1) === (opts.scale ?? 1) && r.provenance.version === version2 && existsSync131(
|
|
188499
|
+
(r) => r.provenance.format === opts.format && (r.provenance.scale ?? 1) === (opts.scale ?? 1) && r.provenance.version === version2 && existsSync131(join152(deps.projectDir, r.path))
|
|
187894
188500
|
);
|
|
187895
188501
|
if (!existing) return null;
|
|
187896
188502
|
let record2 = existing;
|
|
@@ -187913,7 +188519,7 @@ async function freezeAndRecord(fileKey2, nodeId, url, ext, opts, version2, deps,
|
|
|
187913
188519
|
bytes = new TextEncoder().encode(sanitizeSvg(new TextDecoder().decode(bytes)));
|
|
187914
188520
|
}
|
|
187915
188521
|
const id = nextId(deps.projectDir, "image");
|
|
187916
|
-
const destAbs =
|
|
188522
|
+
const destAbs = join152(typeDirPath(deps.projectDir, "image"), `${id}.${ext}`);
|
|
187917
188523
|
freezeBytes(bytes, destAbs);
|
|
187918
188524
|
const record2 = {
|
|
187919
188525
|
id,
|
|
@@ -188083,11 +188689,11 @@ __export(tokens_exports, {
|
|
|
188083
188689
|
runTokensImport: () => runTokensImport
|
|
188084
188690
|
});
|
|
188085
188691
|
import { writeFileSync as writeFileSync66 } from "fs";
|
|
188086
|
-
import { join as
|
|
188692
|
+
import { join as join153 } from "path";
|
|
188087
188693
|
async function runTokensImport(refInput, deps) {
|
|
188088
188694
|
const { fileKey: fileKey2 } = parseFigmaRef(refInput);
|
|
188089
188695
|
const { version: version2 } = await deps.client.fileVersion(fileKey2);
|
|
188090
|
-
const sidecarPath =
|
|
188696
|
+
const sidecarPath = join153(deps.projectDir, "figma-tokens.json");
|
|
188091
188697
|
let vars = null;
|
|
188092
188698
|
try {
|
|
188093
188699
|
vars = await deps.client.variables(fileKey2);
|
|
@@ -188162,7 +188768,7 @@ __export(component_exports, {
|
|
|
188162
188768
|
runComponentImport: () => runComponentImport
|
|
188163
188769
|
});
|
|
188164
188770
|
import { existsSync as existsSync132, mkdirSync as mkdirSync72, writeFileSync as writeFileSync67 } from "fs";
|
|
188165
|
-
import { join as
|
|
188771
|
+
import { join as join154, relative as relative37 } from "path";
|
|
188166
188772
|
function escapeAttr2(value) {
|
|
188167
188773
|
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
188168
188774
|
}
|
|
@@ -188173,7 +188779,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
188173
188779
|
const bindings = resolveBindings(tree, readBindings(deps.projectDir));
|
|
188174
188780
|
const mapped = nodeToHtml(tree, bindings, { rootName: deps.name });
|
|
188175
188781
|
const name = slugify(deps.name ?? tree.name);
|
|
188176
|
-
const componentDir =
|
|
188782
|
+
const componentDir = join154(deps.projectDir, "compositions", "components", name);
|
|
188177
188783
|
if (existsSync132(componentDir))
|
|
188178
188784
|
console.warn(
|
|
188179
188785
|
`component dir compositions/components/${name} already exists \u2014 overwriting (rename the figma frame for a separate import)`
|
|
@@ -188185,7 +188791,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
188185
188791
|
componentDir,
|
|
188186
188792
|
deps
|
|
188187
188793
|
);
|
|
188188
|
-
const htmlFile =
|
|
188794
|
+
const htmlFile = join154(componentDir, `${name}.html`);
|
|
188189
188795
|
writeFileSync67(htmlFile, html + "\n");
|
|
188190
188796
|
const registryItem = {
|
|
188191
188797
|
name,
|
|
@@ -188207,7 +188813,7 @@ async function runComponentImport(refInput, deps) {
|
|
|
188207
188813
|
]
|
|
188208
188814
|
};
|
|
188209
188815
|
writeFileSync67(
|
|
188210
|
-
|
|
188816
|
+
join154(componentDir, "registry-item.json"),
|
|
188211
188817
|
JSON.stringify(registryItem, null, 2) + "\n"
|
|
188212
188818
|
);
|
|
188213
188819
|
return {
|
|
@@ -188232,7 +188838,7 @@ async function rasterizeFallback(mapped, fileKey2, componentDir, deps) {
|
|
|
188232
188838
|
continue;
|
|
188233
188839
|
}
|
|
188234
188840
|
frozenAssets.push(asset.record.path);
|
|
188235
|
-
const srcRel = relative37(componentDir,
|
|
188841
|
+
const srcRel = relative37(componentDir, join154(deps.projectDir, asset.record.path)).replaceAll(
|
|
188236
188842
|
"\\",
|
|
188237
188843
|
"/"
|
|
188238
188844
|
);
|
|
@@ -188381,7 +188987,7 @@ __export(autoUpdate_exports, {
|
|
|
188381
188987
|
import { spawn as spawn19 } from "child_process";
|
|
188382
188988
|
import { appendFileSync as appendFileSync4, mkdirSync as mkdirSync73, openSync as openSync15 } from "fs";
|
|
188383
188989
|
import { homedir as homedir25 } from "os";
|
|
188384
|
-
import { join as
|
|
188990
|
+
import { join as join155 } from "path";
|
|
188385
188991
|
import { compareVersions as compareVersions3 } from "compare-versions";
|
|
188386
188992
|
function isAutoInstallDisabled() {
|
|
188387
188993
|
if (isDevMode()) return true;
|
|
@@ -188404,7 +189010,7 @@ function log(line3) {
|
|
|
188404
189010
|
}
|
|
188405
189011
|
function launchDetachedInstall(invocation, displayCommand, version2) {
|
|
188406
189012
|
mkdirSync73(CONFIG_DIR3, { recursive: true, mode: 448 });
|
|
188407
|
-
const configFile =
|
|
189013
|
+
const configFile = join155(CONFIG_DIR3, "config.json");
|
|
188408
189014
|
const nodeScript = `
|
|
188409
189015
|
const { execFile } = require("node:child_process");
|
|
188410
189016
|
const { readFileSync, renameSync, writeFileSync } = require("node:fs");
|
|
@@ -188525,8 +189131,8 @@ var init_autoUpdate = __esm({
|
|
|
188525
189131
|
init_config();
|
|
188526
189132
|
init_env();
|
|
188527
189133
|
init_installerDetection();
|
|
188528
|
-
CONFIG_DIR3 =
|
|
188529
|
-
LOG_FILE =
|
|
189134
|
+
CONFIG_DIR3 = join155(homedir25(), ".hyperframes");
|
|
189135
|
+
LOG_FILE = join155(CONFIG_DIR3, "auto-update.log");
|
|
188530
189136
|
PENDING_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
188531
189137
|
}
|
|
188532
189138
|
});
|
|
@@ -188722,7 +189328,7 @@ var init_help = __esm({
|
|
|
188722
189328
|
init_version();
|
|
188723
189329
|
init_dist();
|
|
188724
189330
|
init_runId();
|
|
188725
|
-
import { dirname as dirname68, join as
|
|
189331
|
+
import { dirname as dirname68, join as join156, resolve as resolve83 } from "path";
|
|
188726
189332
|
import { fileURLToPath as fileURLToPath17 } from "url";
|
|
188727
189333
|
import { existsSync as existsSync133 } from "fs";
|
|
188728
189334
|
|
|
@@ -188842,7 +189448,7 @@ for (const stream of [process.stdout, process.stderr]) {
|
|
|
188842
189448
|
}
|
|
188843
189449
|
(() => {
|
|
188844
189450
|
const here = dirname68(fileURLToPath17(import.meta.url));
|
|
188845
|
-
const shader =
|
|
189451
|
+
const shader = join156(here, "shaderTransitionWorker.js");
|
|
188846
189452
|
if (!process.env.HF_SHADER_WORKER_ENTRY && existsSync133(shader)) {
|
|
188847
189453
|
process.env.HF_SHADER_WORKER_ENTRY = shader;
|
|
188848
189454
|
}
|
|
@@ -188855,10 +189461,10 @@ if (rootVersionRequested) {
|
|
|
188855
189461
|
process.exit(0);
|
|
188856
189462
|
}
|
|
188857
189463
|
try {
|
|
188858
|
-
const { readFileSync:
|
|
189464
|
+
const { readFileSync: readFileSync101 } = await import("fs");
|
|
188859
189465
|
const { resolve: resolve84 } = await import("path");
|
|
188860
189466
|
const envPath = resolve84(process.cwd(), ".env");
|
|
188861
|
-
const envContent =
|
|
189467
|
+
const envContent = readFileSync101(envPath, "utf-8");
|
|
188862
189468
|
for (const rawLine of envContent.split("\n")) {
|
|
188863
189469
|
let line3 = rawLine.trim();
|
|
188864
189470
|
if (!line3 || line3.startsWith("#")) continue;
|