hyperframes 0.7.92 → 0.7.93
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 +1507 -377
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-9qOa08Tv.js → hyperframes-player-NSdcoOcK.js} +1 -1
- package/dist/studio/assets/{index-CDTN2ZVa.js → index-CCGnc_0M.js} +1 -1
- package/dist/studio/assets/index-D78KEjgB.css +1 -0
- package/dist/studio/assets/index-Dp1zVb9X.js +428 -0
- package/dist/studio/assets/{index-Bw4lNdtO.js → index-wS6f7F5q.js} +1 -1
- package/dist/studio/index.d.ts +20 -20
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +7055 -5321
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/index-BXkzp_OU.css +0 -1
- package/dist/studio/assets/index-DIntkrQl.js +0 -428
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.7.
|
|
53
|
+
VERSION = true ? "0.7.93" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -52025,8 +52025,62 @@ function containsTimelineCall(node, timelineVar) {
|
|
|
52025
52025
|
function rangeOf(node) {
|
|
52026
52026
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
52027
52027
|
}
|
|
52028
|
+
function isSafeDefaultExpression(node, earlierParams) {
|
|
52029
|
+
let safe = true;
|
|
52030
|
+
const visit = (current2, parent, key2) => {
|
|
52031
|
+
if (!isNode2(current2) || !safe) return;
|
|
52032
|
+
if (!SAFE_DEFAULT_NODES.has(current2.type)) {
|
|
52033
|
+
safe = false;
|
|
52034
|
+
return;
|
|
52035
|
+
}
|
|
52036
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
52037
|
+
safe = false;
|
|
52038
|
+
return;
|
|
52039
|
+
}
|
|
52040
|
+
if (current2.type === "Identifier") {
|
|
52041
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot(parent, key2) : false;
|
|
52042
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
52043
|
+
safe = false;
|
|
52044
|
+
}
|
|
52045
|
+
return;
|
|
52046
|
+
}
|
|
52047
|
+
for (const childKey of Object.keys(current2)) {
|
|
52048
|
+
if (SKIP_KEYS.has(childKey)) continue;
|
|
52049
|
+
const child = current2[childKey];
|
|
52050
|
+
if (Array.isArray(child)) {
|
|
52051
|
+
for (const item of child) visit(item, current2, childKey);
|
|
52052
|
+
} else {
|
|
52053
|
+
visit(child, current2, childKey);
|
|
52054
|
+
}
|
|
52055
|
+
}
|
|
52056
|
+
};
|
|
52057
|
+
visit(node);
|
|
52058
|
+
return safe;
|
|
52059
|
+
}
|
|
52060
|
+
function supportedParam(param, earlier) {
|
|
52061
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
52062
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
52063
|
+
if (!isSafeDefaultExpression(param.right, earlier)) return null;
|
|
52064
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
52065
|
+
}
|
|
52066
|
+
function supportedParams(fn) {
|
|
52067
|
+
if (SUPPORTED_PARAMS_CACHE.has(fn)) return SUPPORTED_PARAMS_CACHE.get(fn) ?? null;
|
|
52068
|
+
const params = [];
|
|
52069
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
52070
|
+
for (const param of fn.params ?? []) {
|
|
52071
|
+
const parsed = supportedParam(param, earlier);
|
|
52072
|
+
if (!parsed) {
|
|
52073
|
+
SUPPORTED_PARAMS_CACHE.set(fn, null);
|
|
52074
|
+
return null;
|
|
52075
|
+
}
|
|
52076
|
+
params.push(parsed);
|
|
52077
|
+
earlier.add(parsed.name);
|
|
52078
|
+
}
|
|
52079
|
+
SUPPORTED_PARAMS_CACHE.set(fn, params);
|
|
52080
|
+
return params;
|
|
52081
|
+
}
|
|
52028
52082
|
function isShapeEligible(fn) {
|
|
52029
|
-
return isFunctionNode(fn) && fn.body?.type === "BlockStatement" &&
|
|
52083
|
+
return isFunctionNode(fn) && fn.body?.type === "BlockStatement" && supportedParams(fn) !== null;
|
|
52030
52084
|
}
|
|
52031
52085
|
function callsAny(node, names) {
|
|
52032
52086
|
let hit = false;
|
|
@@ -52076,20 +52130,55 @@ function timelineBuildingNames(candidates, timelineVar) {
|
|
|
52076
52130
|
function bump(counts, key2) {
|
|
52077
52131
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
52078
52132
|
}
|
|
52133
|
+
function undefinedIdentifier() {
|
|
52134
|
+
return { type: "Identifier", name: "undefined" };
|
|
52135
|
+
}
|
|
52136
|
+
function isExplicitUndefined(node) {
|
|
52137
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
52138
|
+
}
|
|
52139
|
+
function resolveHelperBindings(call, params) {
|
|
52140
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
52141
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
52142
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
52143
|
+
const param = params[i2];
|
|
52144
|
+
const arg = call.arguments?.[i2];
|
|
52145
|
+
if (arg && !isExplicitUndefined(arg)) {
|
|
52146
|
+
bindings.set(param.name, arg);
|
|
52147
|
+
} else if (param.defaultExpression) {
|
|
52148
|
+
bindings.set(param.name, substituteParams(cloneNode2(param.defaultExpression), bindings));
|
|
52149
|
+
} else {
|
|
52150
|
+
bindings.set(param.name, undefinedIdentifier());
|
|
52151
|
+
}
|
|
52152
|
+
}
|
|
52153
|
+
return bindings;
|
|
52154
|
+
}
|
|
52155
|
+
function statementHelperCall(node, names) {
|
|
52156
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
52157
|
+
const expression = node.expression;
|
|
52158
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
52159
|
+
return void 0;
|
|
52160
|
+
}
|
|
52161
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
52162
|
+
}
|
|
52079
52163
|
function safelyDroppable(program, candidates) {
|
|
52080
52164
|
const names = new Set(candidates.keys());
|
|
52081
52165
|
const totalIds = /* @__PURE__ */ new Map();
|
|
52082
52166
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
52167
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
52083
52168
|
walkNodes(program, (n2) => {
|
|
52084
52169
|
if (n2.type === "Identifier" && names.has(n2.name)) bump(totalIds, n2.name);
|
|
52085
|
-
const
|
|
52086
|
-
if (
|
|
52087
|
-
|
|
52088
|
-
|
|
52170
|
+
const call = statementHelperCall(n2, names);
|
|
52171
|
+
if (!call) return;
|
|
52172
|
+
bump(stmtCalls, call.callee.name);
|
|
52173
|
+
const fn = candidates.get(call.callee.name);
|
|
52174
|
+
const params = fn && supportedParams(fn);
|
|
52175
|
+
if (!params || !resolveHelperBindings(call, params)) unbindable.add(call.callee.name);
|
|
52089
52176
|
});
|
|
52090
52177
|
const safe = /* @__PURE__ */ new Map();
|
|
52091
52178
|
for (const [name, fn] of candidates) {
|
|
52092
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
52179
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
52180
|
+
safe.set(name, fn);
|
|
52181
|
+
}
|
|
52093
52182
|
}
|
|
52094
52183
|
return safe;
|
|
52095
52184
|
}
|
|
@@ -52132,11 +52221,11 @@ function expandBody(bodyStmts, bindings, prov, ctx) {
|
|
|
52132
52221
|
}
|
|
52133
52222
|
function inlineHelper(call, ctx) {
|
|
52134
52223
|
const fn = ctx.helpers.get(call.callee.name);
|
|
52135
|
-
|
|
52136
|
-
|
|
52137
|
-
|
|
52138
|
-
|
|
52139
|
-
|
|
52224
|
+
if (!fn) return null;
|
|
52225
|
+
const params = supportedParams(fn);
|
|
52226
|
+
if (!params) return null;
|
|
52227
|
+
const bindings = resolveHelperBindings(call, params);
|
|
52228
|
+
if (!bindings) return null;
|
|
52140
52229
|
const prov = {
|
|
52141
52230
|
kind: "helper",
|
|
52142
52231
|
fn: call.callee.name,
|
|
@@ -54683,7 +54772,7 @@ function decodeUrlPathVariants(path2) {
|
|
|
54683
54772
|
}
|
|
54684
54773
|
return variants;
|
|
54685
54774
|
}
|
|
54686
|
-
var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, COMPOSITION_VARIABLE_TYPES, TIMELINE_COLORS, DEFAULT_DURATIONS, PROPERTY_GROUPS, PROP_TO_GROUP, FORBIDDEN_GSAP_PATTERNS, roundPercentage, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION, DEFAULT_TYPEOF, EXCLUDED_TAGS, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, ClipTimingWriteError, REFERENCE_ID_PATTERN, DERIVED_END_EQUALITY_EPSILON_SECONDS, MEDIA_TYPES, CompositionHtmlParseError, UHD_SQUARE_MIN, UHD_RECT_MIN, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS;
|
|
54775
|
+
var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, COMPOSITION_VARIABLE_TYPES, TIMELINE_COLORS, DEFAULT_DURATIONS, PROPERTY_GROUPS, PROP_TO_GROUP, FORBIDDEN_GSAP_PATTERNS, roundPercentage, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, SAFE_DEFAULT_NODES, SUPPORTED_PARAMS_CACHE, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION, DEFAULT_TYPEOF, EXCLUDED_TAGS, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, ClipTimingWriteError, REFERENCE_ID_PATTERN, DERIVED_END_EQUALITY_EPSILON_SECONDS, MEDIA_TYPES, CompositionHtmlParseError, UHD_SQUARE_MIN, UHD_RECT_MIN, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS;
|
|
54687
54776
|
var init_dist2 = __esm({
|
|
54688
54777
|
"../parsers/dist/index.js"() {
|
|
54689
54778
|
"use strict";
|
|
@@ -54791,6 +54880,23 @@ var init_dist2 = __esm({
|
|
|
54791
54880
|
GSAP_METHODS = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
54792
54881
|
MAX_DEPTH = 8;
|
|
54793
54882
|
MAX_ITERS = 512;
|
|
54883
|
+
SAFE_DEFAULT_NODES = /* @__PURE__ */ new Set([
|
|
54884
|
+
"ArrayExpression",
|
|
54885
|
+
"BinaryExpression",
|
|
54886
|
+
"ChainExpression",
|
|
54887
|
+
"ConditionalExpression",
|
|
54888
|
+
"Identifier",
|
|
54889
|
+
"Literal",
|
|
54890
|
+
"LogicalExpression",
|
|
54891
|
+
"MemberExpression",
|
|
54892
|
+
"ObjectExpression",
|
|
54893
|
+
"Property",
|
|
54894
|
+
"SpreadElement",
|
|
54895
|
+
"TemplateElement",
|
|
54896
|
+
"TemplateLiteral",
|
|
54897
|
+
"UnaryExpression"
|
|
54898
|
+
]);
|
|
54899
|
+
SUPPORTED_PARAMS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
54794
54900
|
GSAP_METHODS2 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
54795
54901
|
QUERY_METHODS = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
54796
54902
|
ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
@@ -58530,17 +58636,46 @@ function truncateTelemetryString(value, maxLength) {
|
|
|
58530
58636
|
function redactUrlQueryStrings(value) {
|
|
58531
58637
|
return value.replace(/\b(https?:\/\/[^\s?]+)\?[^\s]*/g, "$1?\u2026");
|
|
58532
58638
|
}
|
|
58639
|
+
function redactKnownPaths(value, paths) {
|
|
58640
|
+
if (typeof value !== "string")
|
|
58641
|
+
return "";
|
|
58642
|
+
let out = value;
|
|
58643
|
+
for (const path2 of paths) {
|
|
58644
|
+
if (typeof path2 !== "string" || path2.length === 0)
|
|
58645
|
+
continue;
|
|
58646
|
+
const basename31 = path2.split(/[\\/]/).pop() ?? "";
|
|
58647
|
+
for (const literal2 of [path2, basename31].filter((v2) => v2.length > 2)) {
|
|
58648
|
+
out = out.split(literal2).join("[path]");
|
|
58649
|
+
}
|
|
58650
|
+
}
|
|
58651
|
+
return out;
|
|
58652
|
+
}
|
|
58533
58653
|
function redactFilePaths(value) {
|
|
58534
|
-
return value.replace(/file:\/\/[^\s'")]+/g, "[file-url]").replace(
|
|
58654
|
+
return value.replace(/file:\/\/[^\s'")]+/g, "[file-url]").replace(RELATIVE_PATH, "[path]").replace(BARE_RELATIVE_PATH, "[path]").replace(ABSOLUTE_PATH, "[path]").replace(ASSET_BASENAME, "[file]");
|
|
58535
58655
|
}
|
|
58536
58656
|
function redactTelemetryString(value, maxLength = MAX_TELEMETRY_STRING_LENGTH) {
|
|
58537
58657
|
return truncateTelemetryString(redactFilePaths(redactUrlQueryStrings(value)), maxLength);
|
|
58538
58658
|
}
|
|
58539
|
-
var MAX_TELEMETRY_STRING_LENGTH;
|
|
58659
|
+
var MAX_TELEMETRY_STRING_LENGTH, SEGMENT, SEGMENT_NODOT, TOKEN_TAIL, ABSOLUTE_PATH, RELATIVE_PATH, ASSET_BASENAME, BARE_RELATIVE_PATH;
|
|
58540
58660
|
var init_telemetryRedaction = __esm({
|
|
58541
58661
|
"../core/dist/telemetryRedaction.js"() {
|
|
58542
58662
|
"use strict";
|
|
58543
58663
|
MAX_TELEMETRY_STRING_LENGTH = 240;
|
|
58664
|
+
SEGMENT = String.raw`[^\s/\\'"]+`;
|
|
58665
|
+
SEGMENT_NODOT = String.raw`[^\s/\\'".]+`;
|
|
58666
|
+
TOKEN_TAIL = String.raw`[^\s'")]*`;
|
|
58667
|
+
ABSOLUTE_PATH = new RegExp(String.raw`(?<![:\w/\\])(?:[A-Za-z]:)?(?:[\\/]${SEGMENT}){2,}${TOKEN_TAIL}`, "g");
|
|
58668
|
+
RELATIVE_PATH = new RegExp(String.raw`(?<![\w/\\.])\.{1,2}(?:[\\/]${SEGMENT})+${TOKEN_TAIL}`, "g");
|
|
58669
|
+
ASSET_BASENAME = /(?<![\w/\\])[^\s/\\'"]+\.(?:mp4|mov|mkv|webm|avi|m4v|mpe?g|ts|mp3|wav|aac|m4a|flac|ogg|opus|png|jpe?g|gif|webp|svg|html?|json|srt|vtt|ass)\b/gi;
|
|
58670
|
+
BARE_RELATIVE_PATH = new RegExp([
|
|
58671
|
+
// Two or more separators: `customer/acme/video.mp4`. No extension needed —
|
|
58672
|
+
// that much structure is already a path.
|
|
58673
|
+
String.raw`(?<![^\s'\"(=,\[])(?:${SEGMENT}[\\/]){2,}${SEGMENT}${TOKEN_TAIL}`,
|
|
58674
|
+
// One separator, but the last segment carries a file extension:
|
|
58675
|
+
// `assets/bgm.mp3`. That segment is dot-free on purpose — SEGMENT includes
|
|
58676
|
+
// `.`, so a greedy one swallows the extension this rule needs.
|
|
58677
|
+
String.raw`(?<![^\s'\"(=,\[])${SEGMENT}[\\/]${SEGMENT_NODOT}\.\w{1,8}\b${TOKEN_TAIL}`
|
|
58678
|
+
].join("|"), "g");
|
|
58544
58679
|
}
|
|
58545
58680
|
});
|
|
58546
58681
|
|
|
@@ -62432,6 +62567,7 @@ __export(dist_exports, {
|
|
|
62432
62567
|
quantizeTimeToFrame: () => quantizeTimeToFrame,
|
|
62433
62568
|
queryByAttr: () => queryByAttr2,
|
|
62434
62569
|
readClipTiming: () => readClipTiming2,
|
|
62570
|
+
redactKnownPaths: () => redactKnownPaths,
|
|
62435
62571
|
redactTelemetryString: () => redactTelemetryString,
|
|
62436
62572
|
removeElementFromHtml: () => removeElementFromHtml,
|
|
62437
62573
|
resolveHfColorGradingVariables: () => resolveHfColorGradingVariables,
|
|
@@ -64060,7 +64196,7 @@ async function probeAutoBrowserGpuMode(options) {
|
|
|
64060
64196
|
const ppt = await getPuppeteerOrNull();
|
|
64061
64197
|
if (ppt === null) {
|
|
64062
64198
|
logResolvedBrowserGpuMode("software", "puppeteer unavailable");
|
|
64063
|
-
return "software";
|
|
64199
|
+
return { mode: "software", cause: "probe-error" };
|
|
64064
64200
|
}
|
|
64065
64201
|
try {
|
|
64066
64202
|
const info = await probeHardwareWebGlInfo(ppt, {
|
|
@@ -64070,20 +64206,37 @@ async function probeAutoBrowserGpuMode(options) {
|
|
|
64070
64206
|
});
|
|
64071
64207
|
const resolved2 = resolveWebGlProbeMode(info);
|
|
64072
64208
|
logResolvedBrowserGpuMode(resolved2, describeWebGlProbe(info));
|
|
64073
|
-
return resolved2;
|
|
64209
|
+
return resolved2 === "hardware" ? { mode: "hardware" } : { mode: "software", cause: "no-gpu" };
|
|
64074
64210
|
} catch (err) {
|
|
64075
64211
|
logResolvedBrowserGpuMode("software", formatProbeFailure(err));
|
|
64076
|
-
return "software";
|
|
64212
|
+
return { mode: "software", cause: "probe-error" };
|
|
64077
64213
|
}
|
|
64078
64214
|
}
|
|
64079
64215
|
function resolveBrowserGpuMode(mode, options = {}) {
|
|
64080
|
-
if (mode
|
|
64081
|
-
|
|
64082
|
-
|
|
64083
|
-
return _autoBrowserGpuModeCache
|
|
64216
|
+
if (mode === "software") return Promise.resolve(mode);
|
|
64217
|
+
_autoBrowserGpuModeCache ??= probeAutoBrowserGpuMode(options);
|
|
64218
|
+
if (mode === "auto") return _autoBrowserGpuModeCache.then((probed) => probed.mode);
|
|
64219
|
+
return _autoBrowserGpuModeCache.then((probed) => {
|
|
64220
|
+
if (probed.mode === "software" && !_unverifiedHardwareGpuWarned) {
|
|
64221
|
+
_unverifiedHardwareGpuWarned = true;
|
|
64222
|
+
console.warn(
|
|
64223
|
+
buildUnverifiedHardwareGpuWarning(options.platform ?? process.platform, probed.cause)
|
|
64224
|
+
);
|
|
64225
|
+
}
|
|
64226
|
+
return "hardware";
|
|
64227
|
+
});
|
|
64228
|
+
}
|
|
64229
|
+
function buildUnverifiedHardwareGpuWarning(platform10, cause) {
|
|
64230
|
+
if (cause === "probe-error") {
|
|
64231
|
+
return "[hyperframes] browserGpuMode=hardware was requested, but the GPU probe could not run, so hardware acceleration is UNVERIFIED \u2014 if Chrome falls back to software WebGL the capture will run at CPU speed. Honouring the explicit request anyway.\n This is a probe failure, not evidence of a missing GPU: see the `browserGpuMode probe \u2192 software (probe failed ...)` line above for the underlying error, which usually means Chrome could not launch (bad HYPERFRAMES_BROWSER_PATH, missing shared libraries, or a denied sandbox) rather than a GPU problem.\n Run `hyperframes doctor` to check the Chrome install.";
|
|
64232
|
+
}
|
|
64233
|
+
const remediation = platform10 === "linux" ? "Inside Docker, the container needs GPU passthrough: `--gpus all` with the NVIDIA Container Toolkit installed, or `--device /dev/dri` for Mesa/AMD/Intel. The image also needs the matching userspace driver + libEGL. Verify with `hyperframes render --browser-gpu` and watch for this warning disappearing." : "Check that the host exposes a GPU to this process and that the graphics drivers are installed.";
|
|
64234
|
+
return `[hyperframes] browserGpuMode=hardware was requested, but the WebGL probe found no hardware GPU \u2014 Chrome will silently fall back to software WebGL and the capture will run at CPU speed. Honouring the explicit request anyway.
|
|
64235
|
+
${remediation}
|
|
64236
|
+
Pass --no-browser-gpu to select deterministic SwiftShader instead of waiting on a hardware path that is not there.`;
|
|
64084
64237
|
}
|
|
64085
64238
|
function logResolvedBrowserGpuMode(resolved2, reason) {
|
|
64086
|
-
console.error(`[hyperframes] browserGpuMode
|
|
64239
|
+
console.error(`[hyperframes] browserGpuMode probe \u2192 ${resolved2} (${reason})`);
|
|
64087
64240
|
}
|
|
64088
64241
|
function createBrowserLaunchFingerprint(chromeArgs, config) {
|
|
64089
64242
|
const launchConfig = {
|
|
@@ -64306,7 +64459,7 @@ function getBrowserGpuArgs(mode, platform10) {
|
|
|
64306
64459
|
return ["--enable-gpu-rasterization"];
|
|
64307
64460
|
}
|
|
64308
64461
|
}
|
|
64309
|
-
var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG;
|
|
64462
|
+
var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, _unverifiedHardwareGpuWarned, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG;
|
|
64310
64463
|
var init_browserManager = __esm({
|
|
64311
64464
|
"../engine/src/services/browserManager.ts"() {
|
|
64312
64465
|
"use strict";
|
|
@@ -64336,6 +64489,7 @@ var init_browserManager = __esm({
|
|
|
64336
64489
|
BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS = 10;
|
|
64337
64490
|
BEGINFRAME_PROBE_TIMEOUT_MS = 2e3;
|
|
64338
64491
|
BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS = 250;
|
|
64492
|
+
_unverifiedHardwareGpuWarned = false;
|
|
64339
64493
|
browserLeasePool = new BrowserLeasePool({
|
|
64340
64494
|
launch: launchBrowser,
|
|
64341
64495
|
close: async (browser) => browser.close(),
|
|
@@ -66612,6 +66766,50 @@ function formatHttpErrorDiagnostic(input2) {
|
|
|
66612
66766
|
const statusText = input2.statusText ? ` ${input2.statusText}` : "";
|
|
66613
66767
|
return `[Browser:HTTP${input2.status}] ${input2.method} ${sanitizeDiagnosticUrl(input2.url)} resource=${input2.resourceType}${statusText}`;
|
|
66614
66768
|
}
|
|
66769
|
+
function warmupFrameTimeTicks(state, intervalMs) {
|
|
66770
|
+
return state.ticks * intervalMs;
|
|
66771
|
+
}
|
|
66772
|
+
function deriveBeginFrameTimeTicks(state, warmupIntervalMs, captureIntervalMs) {
|
|
66773
|
+
const legacyCaptureTimeTicks = (state.ticks + BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS) * captureIntervalMs;
|
|
66774
|
+
const legacyCommitTimeTicks = deriveBeginFrameCommitTimeTicks(
|
|
66775
|
+
legacyCaptureTimeTicks,
|
|
66776
|
+
captureIntervalMs
|
|
66777
|
+
);
|
|
66778
|
+
const lastWarmupTimeTicks = Math.max(0, state.ticks - 1) * warmupIntervalMs;
|
|
66779
|
+
if (legacyCommitTimeTicks > lastWarmupTimeTicks) return legacyCaptureTimeTicks;
|
|
66780
|
+
const monotonicCaptureTimeTicks = warmupFrameTimeTicks(state, warmupIntervalMs) + BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS * captureIntervalMs;
|
|
66781
|
+
return monotonicCaptureTimeTicks;
|
|
66782
|
+
}
|
|
66783
|
+
function deriveBeginFrameCommitTimeTicks(captureTimeTicks, captureIntervalMs) {
|
|
66784
|
+
return captureTimeTicks - BEGIN_FRAME_COMMIT_LEAD_INTERVALS * captureIntervalMs;
|
|
66785
|
+
}
|
|
66786
|
+
function deriveBeginFrameProbeTimeTicks(captureTimeTicks, captureIntervalMs) {
|
|
66787
|
+
return Math.max(0, captureTimeTicks - BEGIN_FRAME_PROBE_LEAD_INTERVALS * captureIntervalMs);
|
|
66788
|
+
}
|
|
66789
|
+
function deriveBeginFrameTimelineTicks(state, warmupIntervalMs, captureIntervalMs) {
|
|
66790
|
+
const capture2 = deriveBeginFrameTimeTicks(state, warmupIntervalMs, captureIntervalMs);
|
|
66791
|
+
return {
|
|
66792
|
+
capture: capture2,
|
|
66793
|
+
commit: deriveBeginFrameCommitTimeTicks(capture2, captureIntervalMs),
|
|
66794
|
+
probe: deriveBeginFrameProbeTimeTicks(capture2, captureIntervalMs)
|
|
66795
|
+
};
|
|
66796
|
+
}
|
|
66797
|
+
function prepareBeginFrameTimeline(session, state, warmupIntervalMs) {
|
|
66798
|
+
const timeline = deriveBeginFrameTimelineTicks(
|
|
66799
|
+
state,
|
|
66800
|
+
warmupIntervalMs,
|
|
66801
|
+
session.beginFrameIntervalMs
|
|
66802
|
+
);
|
|
66803
|
+
session.beginFrameTimeTicks = timeline.capture;
|
|
66804
|
+
return {
|
|
66805
|
+
timeline,
|
|
66806
|
+
commitParams: {
|
|
66807
|
+
frameTimeTicks: timeline.commit,
|
|
66808
|
+
interval: session.beginFrameIntervalMs,
|
|
66809
|
+
noDisplayUpdates: false
|
|
66810
|
+
}
|
|
66811
|
+
};
|
|
66812
|
+
}
|
|
66615
66813
|
async function driveWarmupTicks(options, state) {
|
|
66616
66814
|
const sleep5 = options.sleep ?? realSleep;
|
|
66617
66815
|
while (true) {
|
|
@@ -67557,17 +67755,16 @@ async function initializeSession(session) {
|
|
|
67557
67755
|
warmupState.running = false;
|
|
67558
67756
|
await warmupLoopPromise.catch(() => {
|
|
67559
67757
|
});
|
|
67560
|
-
const
|
|
67561
|
-
|
|
67758
|
+
const preparedBeginFrameTimeline = prepareBeginFrameTimeline(
|
|
67759
|
+
session,
|
|
67760
|
+
warmupState,
|
|
67761
|
+
warmupIntervalMs
|
|
67762
|
+
);
|
|
67562
67763
|
await initDrawElementOrTransparentBackground(session, page, logInitPhase);
|
|
67563
67764
|
await armStaticDedup(session, session.page, logInitPhase);
|
|
67564
67765
|
await ensureRenderFrameSiblings(page);
|
|
67565
67766
|
const commitCdp = await getCdpSession(page);
|
|
67566
|
-
await commitCdp.send("HeadlessExperimental.beginFrame",
|
|
67567
|
-
frameTimeTicks: session.beginFrameTimeTicks - 6 * session.beginFrameIntervalMs,
|
|
67568
|
-
interval: session.beginFrameIntervalMs,
|
|
67569
|
-
noDisplayUpdates: false
|
|
67570
|
-
});
|
|
67767
|
+
await commitCdp.send("HeadlessExperimental.beginFrame", preparedBeginFrameTimeline.commitParams);
|
|
67571
67768
|
session.isInitialized = true;
|
|
67572
67769
|
}
|
|
67573
67770
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
@@ -68406,7 +68603,7 @@ function getCapturePerfSummary(session) {
|
|
|
68406
68603
|
deNcprFallbacks: session.deNcprFallbacks ?? 0
|
|
68407
68604
|
};
|
|
68408
68605
|
}
|
|
68409
|
-
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS;
|
|
68606
|
+
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS, BEGIN_FRAME_COMMIT_LEAD_INTERVALS, BEGIN_FRAME_PROBE_LEAD_INTERVALS, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS;
|
|
68410
68607
|
var init_frameCapture = __esm({
|
|
68411
68608
|
"../engine/src/services/frameCapture.ts"() {
|
|
68412
68609
|
"use strict";
|
|
@@ -68437,6 +68634,9 @@ var init_frameCapture = __esm({
|
|
|
68437
68634
|
CAPTURE_SESSION_CLOSE_TIMEOUT_MS = 5e3;
|
|
68438
68635
|
LOCKED_WARMUP_TICKS = 60;
|
|
68439
68636
|
realSleep = (ms) => new Promise((resolve77) => setTimeout(resolve77, ms));
|
|
68637
|
+
BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS = 10;
|
|
68638
|
+
BEGIN_FRAME_COMMIT_LEAD_INTERVALS = 6;
|
|
68639
|
+
BEGIN_FRAME_PROBE_LEAD_INTERVALS = 5;
|
|
68440
68640
|
HF_READY_DIAGNOSTIC_EXPR = `(function() {
|
|
68441
68641
|
var hf = window.__hf;
|
|
68442
68642
|
var player = window.__player;
|
|
@@ -70621,21 +70821,25 @@ var init_referenceResolver = __esm({
|
|
|
70621
70821
|
// ../engine/src/utils/urlDownloader.ts
|
|
70622
70822
|
import {
|
|
70623
70823
|
closeSync,
|
|
70824
|
+
createReadStream as createReadStream2,
|
|
70624
70825
|
createWriteStream,
|
|
70625
70826
|
existsSync as existsSync9,
|
|
70626
70827
|
fsyncSync,
|
|
70828
|
+
linkSync,
|
|
70627
70829
|
mkdtempSync,
|
|
70628
70830
|
mkdirSync as mkdirSync5,
|
|
70629
70831
|
lstatSync,
|
|
70630
70832
|
openSync,
|
|
70631
|
-
|
|
70833
|
+
readdirSync as readdirSync3,
|
|
70834
|
+
rmdirSync,
|
|
70632
70835
|
rmSync as rmSync2,
|
|
70633
|
-
statSync as statSync4
|
|
70836
|
+
statSync as statSync4,
|
|
70837
|
+
unlinkSync
|
|
70634
70838
|
} from "fs";
|
|
70635
|
-
import { createHash } from "crypto";
|
|
70839
|
+
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
70636
70840
|
import { BlockList, isIP } from "net";
|
|
70637
70841
|
import { dirname as dirname6, extname as extname2, join as join9 } from "path";
|
|
70638
|
-
import { Readable } from "stream";
|
|
70842
|
+
import { Readable, Transform } from "stream";
|
|
70639
70843
|
import { pipeline } from "stream/promises";
|
|
70640
70844
|
function signalScopeKey(signal) {
|
|
70641
70845
|
if (!signal) return "none";
|
|
@@ -70647,8 +70851,29 @@ function signalScopeKey(signal) {
|
|
|
70647
70851
|
}
|
|
70648
70852
|
return String(scope);
|
|
70649
70853
|
}
|
|
70650
|
-
function
|
|
70651
|
-
|
|
70854
|
+
function safeDownloadUrlIdentity(url) {
|
|
70855
|
+
let canonical = url;
|
|
70856
|
+
let host;
|
|
70857
|
+
try {
|
|
70858
|
+
const parsed = new URL(url);
|
|
70859
|
+
canonical = `${parsed.origin}${parsed.pathname}`;
|
|
70860
|
+
host = parsed.hostname.toLowerCase();
|
|
70861
|
+
} catch {
|
|
70862
|
+
}
|
|
70863
|
+
return {
|
|
70864
|
+
urlFingerprint: createHash("sha256").update(canonical).digest("hex"),
|
|
70865
|
+
host
|
|
70866
|
+
};
|
|
70867
|
+
}
|
|
70868
|
+
function writeUrlDownloadTelemetry(event) {
|
|
70869
|
+
try {
|
|
70870
|
+
process.stderr.write(`[hyperframes:download] ${JSON.stringify(event)}
|
|
70871
|
+
`);
|
|
70872
|
+
} catch {
|
|
70873
|
+
}
|
|
70874
|
+
}
|
|
70875
|
+
function classifyHttpFailure(status) {
|
|
70876
|
+
const message = `HTTP ${status}`;
|
|
70652
70877
|
if (status === 404 || status === 410) {
|
|
70653
70878
|
return new UrlDownloadError("http_not_found", false, message, status);
|
|
70654
70879
|
}
|
|
@@ -70659,15 +70884,22 @@ function classifyHttpFailure(status, statusText) {
|
|
|
70659
70884
|
}
|
|
70660
70885
|
function classifyDownloadFailure(error) {
|
|
70661
70886
|
if (error instanceof UrlDownloadError) return error;
|
|
70662
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
70663
70887
|
let current2 = error;
|
|
70664
70888
|
for (let depth = 0; current2 && depth < 4; depth += 1) {
|
|
70665
70889
|
if (isRetryableNetworkCause(current2)) {
|
|
70666
|
-
return new UrlDownloadError(
|
|
70890
|
+
return new UrlDownloadError(
|
|
70891
|
+
"network",
|
|
70892
|
+
true,
|
|
70893
|
+
"Download failed due to a transient network error"
|
|
70894
|
+
);
|
|
70667
70895
|
}
|
|
70668
70896
|
current2 = typeof current2 === "object" && current2 !== null && "cause" in current2 ? current2.cause : void 0;
|
|
70669
70897
|
}
|
|
70670
|
-
return new UrlDownloadError(
|
|
70898
|
+
return new UrlDownloadError(
|
|
70899
|
+
"filesystem",
|
|
70900
|
+
false,
|
|
70901
|
+
"Download failed while writing the local artifact"
|
|
70902
|
+
);
|
|
70671
70903
|
}
|
|
70672
70904
|
function isRetryableNetworkCause(error) {
|
|
70673
70905
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -70686,31 +70918,155 @@ function assertPublicHttpsUrl(url) {
|
|
|
70686
70918
|
try {
|
|
70687
70919
|
parsed = new URL(url);
|
|
70688
70920
|
} catch {
|
|
70689
|
-
throw new Error(
|
|
70921
|
+
throw new Error("[URLDownloader] Invalid URL");
|
|
70690
70922
|
}
|
|
70691
70923
|
if (parsed.protocol !== "https:") {
|
|
70692
|
-
throw new Error(
|
|
70693
|
-
`[URLDownloader] Only HTTPS URLs are permitted in compositions (got ${parsed.protocol}): ${url}`
|
|
70694
|
-
);
|
|
70924
|
+
throw new Error(`[URLDownloader] Only HTTPS URLs are permitted in compositions`);
|
|
70695
70925
|
}
|
|
70696
70926
|
if (isBlockedHost(parsed.hostname)) {
|
|
70697
|
-
throw new Error(
|
|
70698
|
-
`[URLDownloader] URL targets a private/reserved address and is not permitted: ${url}`
|
|
70699
|
-
);
|
|
70927
|
+
throw new Error("[URLDownloader] URL targets a private/reserved address and is not permitted");
|
|
70700
70928
|
}
|
|
70701
70929
|
}
|
|
70702
|
-
function getFilenameFromUrl(url) {
|
|
70703
|
-
const
|
|
70930
|
+
function getFilenameFromUrl(url, validationScope) {
|
|
70931
|
+
const physicalIdentity = validationScope === "" ? url : `${url}\0${validationScope}`;
|
|
70932
|
+
const hash2 = createHash("md5").update(physicalIdentity).digest("hex").slice(0, 12);
|
|
70704
70933
|
const urlObj = new URL(url);
|
|
70705
70934
|
const ext = extname2(urlObj.pathname) || ".mp4";
|
|
70706
70935
|
return `download_${hash2}${ext}`;
|
|
70707
70936
|
}
|
|
70708
|
-
function
|
|
70709
|
-
|
|
70710
|
-
|
|
70711
|
-
|
|
70712
|
-
|
|
70713
|
-
|
|
70937
|
+
function sameFileIdentity(left, right) {
|
|
70938
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
70939
|
+
}
|
|
70940
|
+
function sameCacheLockStatGeneration(left, right) {
|
|
70941
|
+
return sameFileIdentity(left, right) && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.birthtimeMs === right.birthtimeMs;
|
|
70942
|
+
}
|
|
70943
|
+
function observeCachePathLock(lockPath) {
|
|
70944
|
+
for (let pass = 0; pass < 3; pass += 1) {
|
|
70945
|
+
const before3 = lstatSync(lockPath);
|
|
70946
|
+
const owner = readdirSync3(lockPath).find((name) => name.startsWith(CACHE_LOCK_OWNER_PREFIX));
|
|
70947
|
+
const after2 = lstatSync(lockPath);
|
|
70948
|
+
if (sameCacheLockStatGeneration(before3, after2)) return { stats: after2, owner };
|
|
70949
|
+
}
|
|
70950
|
+
throw new UrlDownloadError("filesystem", true, "Cache lock changed repeatedly during inspection");
|
|
70951
|
+
}
|
|
70952
|
+
function sameCachePathLock(left, right) {
|
|
70953
|
+
if (left.owner !== void 0 || right.owner !== void 0) {
|
|
70954
|
+
return left.owner !== void 0 && left.owner === right.owner;
|
|
70955
|
+
}
|
|
70956
|
+
return sameFileIdentity(left.stats, right.stats);
|
|
70957
|
+
}
|
|
70958
|
+
function removeCacheLockDirectoryIfEmpty(lockPath) {
|
|
70959
|
+
try {
|
|
70960
|
+
rmdirSync(lockPath);
|
|
70961
|
+
} catch (error) {
|
|
70962
|
+
const code = error.code;
|
|
70963
|
+
if (code !== "ENOENT" && code !== "ENOTEMPTY" && code !== "EEXIST") throw error;
|
|
70964
|
+
}
|
|
70965
|
+
}
|
|
70966
|
+
function releaseOwnedCachePathLock(lockPath, owner) {
|
|
70967
|
+
try {
|
|
70968
|
+
rmdirSync(join9(lockPath, owner));
|
|
70969
|
+
} catch (error) {
|
|
70970
|
+
if (error.code === "ENOENT") return;
|
|
70971
|
+
throw error;
|
|
70972
|
+
}
|
|
70973
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
70974
|
+
}
|
|
70975
|
+
async function waitForCacheLock(signal) {
|
|
70976
|
+
if (signal?.aborted) {
|
|
70977
|
+
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70978
|
+
}
|
|
70979
|
+
await new Promise((resolve77, reject) => {
|
|
70980
|
+
const timeout = setTimeout(() => {
|
|
70981
|
+
signal?.removeEventListener("abort", onAbort);
|
|
70982
|
+
resolve77();
|
|
70983
|
+
}, CACHE_LOCK_POLL_MS);
|
|
70984
|
+
const onAbort = () => {
|
|
70985
|
+
clearTimeout(timeout);
|
|
70986
|
+
signal?.removeEventListener("abort", onAbort);
|
|
70987
|
+
reject(new UrlDownloadError("cancelled", false, "Download cancelled"));
|
|
70988
|
+
};
|
|
70989
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
70990
|
+
});
|
|
70991
|
+
}
|
|
70992
|
+
async function acquireCachePathLock(localPath, timeoutMs, signal) {
|
|
70993
|
+
const lockPath = `${localPath}.hf-lock`;
|
|
70994
|
+
const startedAt = Date.now();
|
|
70995
|
+
for (; ; ) {
|
|
70996
|
+
if (signal?.aborted) {
|
|
70997
|
+
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70998
|
+
}
|
|
70999
|
+
let createdLock = false;
|
|
71000
|
+
try {
|
|
71001
|
+
mkdirSync5(lockPath);
|
|
71002
|
+
createdLock = true;
|
|
71003
|
+
} catch (error) {
|
|
71004
|
+
if (error.code !== "EEXIST") throw error;
|
|
71005
|
+
}
|
|
71006
|
+
if (createdLock) {
|
|
71007
|
+
const owner = `${CACHE_LOCK_OWNER_PREFIX}${randomUUID2()}`;
|
|
71008
|
+
try {
|
|
71009
|
+
mkdirSync5(join9(lockPath, owner));
|
|
71010
|
+
const entries2 = readdirSync3(lockPath);
|
|
71011
|
+
if (entries2.length === 1 && entries2[0] === owner) {
|
|
71012
|
+
return () => releaseOwnedCachePathLock(lockPath, owner);
|
|
71013
|
+
}
|
|
71014
|
+
rmdirSync(join9(lockPath, owner));
|
|
71015
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71016
|
+
continue;
|
|
71017
|
+
} catch (error) {
|
|
71018
|
+
if (error.code === "ENOENT") continue;
|
|
71019
|
+
throw error;
|
|
71020
|
+
}
|
|
71021
|
+
}
|
|
71022
|
+
let observedLock;
|
|
71023
|
+
try {
|
|
71024
|
+
observedLock = observeCachePathLock(lockPath);
|
|
71025
|
+
} catch (error) {
|
|
71026
|
+
if (error.code === "ENOENT") continue;
|
|
71027
|
+
throw error;
|
|
71028
|
+
}
|
|
71029
|
+
if (Date.now() - observedLock.stats.mtimeMs > CACHE_LOCK_STALE_MS) {
|
|
71030
|
+
if (observedLock.owner) {
|
|
71031
|
+
try {
|
|
71032
|
+
rmdirSync(join9(lockPath, observedLock.owner));
|
|
71033
|
+
} catch (error) {
|
|
71034
|
+
if (error.code === "ENOENT") continue;
|
|
71035
|
+
throw error;
|
|
71036
|
+
}
|
|
71037
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71038
|
+
continue;
|
|
71039
|
+
}
|
|
71040
|
+
const reclaimPath = join9(lockPath, CACHE_LOCK_RECLAIM_NAME);
|
|
71041
|
+
try {
|
|
71042
|
+
mkdirSync5(reclaimPath);
|
|
71043
|
+
} catch (error) {
|
|
71044
|
+
const code = error.code;
|
|
71045
|
+
if (code === "EEXIST" || code === "ENOENT") continue;
|
|
71046
|
+
throw error;
|
|
71047
|
+
}
|
|
71048
|
+
try {
|
|
71049
|
+
const currentLock = observeCachePathLock(lockPath);
|
|
71050
|
+
if (sameCachePathLock(currentLock, observedLock)) {
|
|
71051
|
+
rmdirSync(reclaimPath);
|
|
71052
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71053
|
+
} else {
|
|
71054
|
+
rmdirSync(reclaimPath);
|
|
71055
|
+
}
|
|
71056
|
+
} catch (error) {
|
|
71057
|
+
if (error.code !== "ENOENT") throw error;
|
|
71058
|
+
}
|
|
71059
|
+
continue;
|
|
71060
|
+
}
|
|
71061
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
71062
|
+
throw new UrlDownloadError(
|
|
71063
|
+
"timeout",
|
|
71064
|
+
true,
|
|
71065
|
+
`Download cache lock timeout after ${timeoutMs / 1e3}s`
|
|
71066
|
+
);
|
|
71067
|
+
}
|
|
71068
|
+
await waitForCacheLock(signal);
|
|
71069
|
+
}
|
|
70714
71070
|
}
|
|
70715
71071
|
function assertAllowedDownloadUrl(url, redirect) {
|
|
70716
71072
|
try {
|
|
@@ -70753,31 +71109,335 @@ async function fetchWithValidatedRedirects(initialUrl, controller) {
|
|
|
70753
71109
|
assertAllowedDownloadUrl(currentUrl, redirects > 0);
|
|
70754
71110
|
const response = await fetch(currentUrl, {
|
|
70755
71111
|
signal: controller.signal,
|
|
70756
|
-
redirect: "manual"
|
|
71112
|
+
redirect: "manual",
|
|
71113
|
+
headers: { "accept-encoding": "identity" }
|
|
70757
71114
|
});
|
|
70758
|
-
if (!REDIRECT_STATUSES.has(response.status)) return response;
|
|
71115
|
+
if (!REDIRECT_STATUSES.has(response.status)) return { response, finalUrl: currentUrl };
|
|
70759
71116
|
await cancelResponseBody(response);
|
|
70760
71117
|
currentUrl = resolveRedirectUrl(response, currentUrl, redirects);
|
|
70761
71118
|
}
|
|
70762
71119
|
}
|
|
70763
|
-
async function
|
|
70764
|
-
const
|
|
71120
|
+
async function fetchPublicHttpsText(url, options) {
|
|
71121
|
+
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
71122
|
+
if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes <= 0) {
|
|
71123
|
+
throw new RangeError("maxBytes must be a positive safe integer");
|
|
71124
|
+
}
|
|
71125
|
+
assertPublicHttpsUrl(url);
|
|
71126
|
+
const controller = new AbortController();
|
|
71127
|
+
let timedOut = false;
|
|
71128
|
+
let callerAborted = options.signal?.aborted ?? false;
|
|
71129
|
+
const onCallerAbort = () => {
|
|
71130
|
+
callerAborted = true;
|
|
71131
|
+
controller.abort();
|
|
71132
|
+
};
|
|
71133
|
+
options.signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
71134
|
+
const timeoutId = setTimeout(() => {
|
|
71135
|
+
timedOut = true;
|
|
71136
|
+
controller.abort();
|
|
71137
|
+
}, timeoutMs);
|
|
71138
|
+
try {
|
|
71139
|
+
if (callerAborted) {
|
|
71140
|
+
throw new UrlDownloadError("cancelled", false, "Text fetch cancelled");
|
|
71141
|
+
}
|
|
71142
|
+
const { response } = await fetchWithValidatedRedirects(url, controller);
|
|
71143
|
+
if (!response.ok) {
|
|
71144
|
+
await cancelResponseBody(response);
|
|
71145
|
+
throw classifyHttpFailure(response.status);
|
|
71146
|
+
}
|
|
71147
|
+
if (!response.body) return "";
|
|
71148
|
+
let declaredLength;
|
|
71149
|
+
try {
|
|
71150
|
+
declaredLength = parseDeclaredLength(response);
|
|
71151
|
+
} catch (error) {
|
|
71152
|
+
await cancelResponseBody(response);
|
|
71153
|
+
throw error;
|
|
71154
|
+
}
|
|
71155
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71156
|
+
const expectedBytes = !contentEncoding || contentEncoding === "identity" ? declaredLength : void 0;
|
|
71157
|
+
if (declaredLength !== void 0 && declaredLength > options.maxBytes) {
|
|
71158
|
+
await cancelResponseBody(response);
|
|
71159
|
+
throw new UrlDownloadError(
|
|
71160
|
+
"length_mismatch",
|
|
71161
|
+
false,
|
|
71162
|
+
"Text response exceeded the configured byte limit",
|
|
71163
|
+
response.status
|
|
71164
|
+
);
|
|
71165
|
+
}
|
|
71166
|
+
const reader = response.body.getReader();
|
|
71167
|
+
const chunks = [];
|
|
71168
|
+
let receivedBytes = 0;
|
|
71169
|
+
for (; ; ) {
|
|
71170
|
+
const { done, value } = await reader.read();
|
|
71171
|
+
if (done) break;
|
|
71172
|
+
receivedBytes += value.byteLength;
|
|
71173
|
+
if (receivedBytes > options.maxBytes) {
|
|
71174
|
+
await reader.cancel();
|
|
71175
|
+
throw new UrlDownloadError(
|
|
71176
|
+
"length_mismatch",
|
|
71177
|
+
false,
|
|
71178
|
+
"Text response exceeded the configured byte limit",
|
|
71179
|
+
response.status,
|
|
71180
|
+
{ receivedBytes }
|
|
71181
|
+
);
|
|
71182
|
+
}
|
|
71183
|
+
chunks.push(value);
|
|
71184
|
+
}
|
|
71185
|
+
if (expectedBytes !== void 0 && receivedBytes !== expectedBytes) {
|
|
71186
|
+
throw new UrlDownloadError(
|
|
71187
|
+
"length_mismatch",
|
|
71188
|
+
true,
|
|
71189
|
+
"Text response byte count did not match its declared length",
|
|
71190
|
+
response.status,
|
|
71191
|
+
{ expectedBytes, receivedBytes }
|
|
71192
|
+
);
|
|
71193
|
+
}
|
|
71194
|
+
return new TextDecoder().decode(Buffer.concat(chunks.map((chunk) => Buffer.from(chunk))));
|
|
71195
|
+
} catch (error) {
|
|
71196
|
+
if (callerAborted) {
|
|
71197
|
+
throw new UrlDownloadError("cancelled", false, "Text fetch cancelled");
|
|
71198
|
+
}
|
|
71199
|
+
if (timedOut) {
|
|
71200
|
+
throw new UrlDownloadError("timeout", true, `Text fetch timeout after ${timeoutMs / 1e3}s`);
|
|
71201
|
+
}
|
|
71202
|
+
throw classifyDownloadFailure(error);
|
|
71203
|
+
} finally {
|
|
71204
|
+
clearTimeout(timeoutId);
|
|
71205
|
+
options.signal?.removeEventListener("abort", onCallerAbort);
|
|
71206
|
+
controller.abort();
|
|
71207
|
+
}
|
|
71208
|
+
}
|
|
71209
|
+
function parseDeclaredLength(response) {
|
|
71210
|
+
const raw = response.headers.get("content-length");
|
|
71211
|
+
if (raw === null) return void 0;
|
|
71212
|
+
if (!/^\d+$/.test(raw.trim())) {
|
|
71213
|
+
throw new UrlDownloadError(
|
|
71214
|
+
"length_mismatch",
|
|
71215
|
+
true,
|
|
71216
|
+
"Download response Content-Length is malformed",
|
|
71217
|
+
response.status,
|
|
71218
|
+
{ status: response.status }
|
|
71219
|
+
);
|
|
71220
|
+
}
|
|
71221
|
+
const value = Number(raw);
|
|
71222
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
71223
|
+
throw new UrlDownloadError(
|
|
71224
|
+
"length_mismatch",
|
|
71225
|
+
true,
|
|
71226
|
+
"Download response Content-Length is out of range",
|
|
71227
|
+
response.status,
|
|
71228
|
+
{ status: response.status }
|
|
71229
|
+
);
|
|
71230
|
+
}
|
|
71231
|
+
return value;
|
|
71232
|
+
}
|
|
71233
|
+
function classifyRangeDisposition(response) {
|
|
71234
|
+
const contentRange = response.headers.get("content-range");
|
|
71235
|
+
if (response.status === 206) {
|
|
71236
|
+
const match2 = contentRange?.match(/^bytes (\d+)-(\d+)\/(\d+|\*)$/i);
|
|
71237
|
+
if (!match2) return "malformed_206";
|
|
71238
|
+
const start2 = Number(match2[1]);
|
|
71239
|
+
const end2 = Number(match2[2]);
|
|
71240
|
+
const total2 = match2[3] === "*" ? void 0 : Number(match2[3]);
|
|
71241
|
+
if (!Number.isSafeInteger(start2) || !Number.isSafeInteger(end2) || start2 < 0 || end2 < start2 || total2 !== void 0 && (!Number.isSafeInteger(total2) || total2 <= end2)) {
|
|
71242
|
+
return "malformed_206";
|
|
71243
|
+
}
|
|
71244
|
+
return "unsolicited_206";
|
|
71245
|
+
}
|
|
71246
|
+
if (response.status !== 200 || contentRange === null) return "none";
|
|
71247
|
+
const match = contentRange.match(/^bytes (\d+)-(\d+)\/(\d+)$/i);
|
|
71248
|
+
const contentLength = response.headers.get("content-length")?.trim();
|
|
71249
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71250
|
+
if (!match || !contentLength || !/^\d+$/.test(contentLength)) {
|
|
71251
|
+
return "content_range_on_200";
|
|
71252
|
+
}
|
|
71253
|
+
const start = Number(match[1]);
|
|
71254
|
+
const end = Number(match[2]);
|
|
71255
|
+
const total = Number(match[3]);
|
|
71256
|
+
const declaredLength = Number(contentLength);
|
|
71257
|
+
return Number.isSafeInteger(start) && Number.isSafeInteger(end) && Number.isSafeInteger(total) && Number.isSafeInteger(declaredLength) && start === 0 && total > 0 && end === total - 1 && declaredLength === total && (!contentEncoding || contentEncoding === "identity") ? "full_object_200" : "content_range_on_200";
|
|
71258
|
+
}
|
|
71259
|
+
function looksLikeRemoteErrorDocument(prefix) {
|
|
71260
|
+
const text2 = prefix.toString("utf8").replace(/^\uFEFF?\s*/, "").toLowerCase();
|
|
71261
|
+
return text2.startsWith("<!doctype html") || text2.startsWith("<html") || text2.startsWith("<head") || text2.startsWith("<body") || text2.startsWith("<error") || /^\{\s*"(?:error|message|detail|code|status)"\s*:/i.test(text2) || /^<\?xml\b/.test(text2) && /<(?:html|error)\b/.test(text2);
|
|
71262
|
+
}
|
|
71263
|
+
function normalizeCallerSha256(value) {
|
|
71264
|
+
if (value === void 0) return void 0;
|
|
71265
|
+
const normalized2 = value.trim().toLowerCase();
|
|
71266
|
+
if (!/^[a-f0-9]{64}$/.test(normalized2)) {
|
|
71267
|
+
throw new UrlDownloadError(
|
|
71268
|
+
"hash_mismatch",
|
|
71269
|
+
false,
|
|
71270
|
+
"Caller-provided SHA-256 checksum is malformed"
|
|
71271
|
+
);
|
|
71272
|
+
}
|
|
71273
|
+
return normalized2;
|
|
71274
|
+
}
|
|
71275
|
+
function expectedResponseSha256(response, callerSha256) {
|
|
71276
|
+
if (callerSha256) return { value: callerSha256, encoding: "hex", source: "caller" };
|
|
71277
|
+
const amazonChecksum = response.headers.get("x-amz-checksum-sha256")?.trim();
|
|
71278
|
+
const amazonChecksumType = response.headers.get("x-amz-checksum-type")?.trim().toUpperCase();
|
|
71279
|
+
if (amazonChecksum && amazonChecksumType !== "COMPOSITE") {
|
|
71280
|
+
return { value: amazonChecksum, encoding: "base64", source: "server" };
|
|
71281
|
+
}
|
|
71282
|
+
const digest = response.headers.get("digest");
|
|
71283
|
+
const sha256Digest = digest?.match(/(?:^|,)\s*sha-256=:?([^,:\s]+):?/i)?.[1];
|
|
71284
|
+
return sha256Digest ? { value: sha256Digest, encoding: "base64", source: "server" } : null;
|
|
71285
|
+
}
|
|
71286
|
+
function checksumMismatchError(source, status, telemetry) {
|
|
71287
|
+
return new UrlDownloadError(
|
|
71288
|
+
"hash_mismatch",
|
|
71289
|
+
source === "server",
|
|
71290
|
+
"Download payload checksum did not match",
|
|
71291
|
+
status,
|
|
71292
|
+
telemetry,
|
|
71293
|
+
true
|
|
71294
|
+
);
|
|
71295
|
+
}
|
|
71296
|
+
async function fetchToPartial(url, partialPath, controller, options) {
|
|
71297
|
+
const { response, finalUrl } = await fetchWithValidatedRedirects(url, controller);
|
|
71298
|
+
const finalIdentity = safeDownloadUrlIdentity(finalUrl);
|
|
71299
|
+
const rangeDisposition = classifyRangeDisposition(response);
|
|
71300
|
+
if (rangeDisposition !== "none" && rangeDisposition !== "full_object_200") {
|
|
71301
|
+
await cancelResponseBody(response);
|
|
71302
|
+
throw new UrlDownloadError(
|
|
71303
|
+
"range_protocol",
|
|
71304
|
+
true,
|
|
71305
|
+
rangeDisposition === "malformed_206" ? "Download received a malformed unsolicited partial response" : "Download received an unsolicited partial response",
|
|
71306
|
+
response.status,
|
|
71307
|
+
{
|
|
71308
|
+
finalHost: finalIdentity.host,
|
|
71309
|
+
status: response.status,
|
|
71310
|
+
rangeDisposition
|
|
71311
|
+
}
|
|
71312
|
+
);
|
|
71313
|
+
}
|
|
70765
71314
|
if (!response.ok) {
|
|
70766
71315
|
try {
|
|
70767
71316
|
await response.body?.cancel();
|
|
70768
71317
|
} catch {
|
|
70769
71318
|
}
|
|
70770
|
-
|
|
71319
|
+
const classified = classifyHttpFailure(response.status);
|
|
71320
|
+
throw new UrlDownloadError(
|
|
71321
|
+
classified.kind,
|
|
71322
|
+
classified.retryable,
|
|
71323
|
+
classified.message,
|
|
71324
|
+
classified.status,
|
|
71325
|
+
{ finalHost: finalIdentity.host, status: response.status, rangeDisposition }
|
|
71326
|
+
);
|
|
70771
71327
|
}
|
|
70772
71328
|
if (!response.body) {
|
|
70773
|
-
throw new UrlDownloadError(
|
|
71329
|
+
throw new UrlDownloadError(
|
|
71330
|
+
"empty_body",
|
|
71331
|
+
true,
|
|
71332
|
+
"Download response body is empty",
|
|
71333
|
+
response.status,
|
|
71334
|
+
{
|
|
71335
|
+
finalHost: finalIdentity.host,
|
|
71336
|
+
status: response.status
|
|
71337
|
+
}
|
|
71338
|
+
);
|
|
70774
71339
|
}
|
|
70775
|
-
|
|
71340
|
+
let declaredLength;
|
|
71341
|
+
try {
|
|
71342
|
+
declaredLength = parseDeclaredLength(response);
|
|
71343
|
+
} catch (error) {
|
|
71344
|
+
await cancelResponseBody(response);
|
|
71345
|
+
if (error instanceof UrlDownloadError) {
|
|
71346
|
+
throw new UrlDownloadError(error.kind, error.retryable, error.message, error.status, {
|
|
71347
|
+
...error.telemetry,
|
|
71348
|
+
finalHost: finalIdentity.host,
|
|
71349
|
+
rangeDisposition
|
|
71350
|
+
});
|
|
71351
|
+
}
|
|
71352
|
+
throw error;
|
|
71353
|
+
}
|
|
71354
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71355
|
+
const expectedBytes = !contentEncoding || contentEncoding === "identity" ? declaredLength : void 0;
|
|
71356
|
+
let receivedBytes = 0;
|
|
71357
|
+
const sha256 = createHash("sha256");
|
|
71358
|
+
const md5 = createHash("md5");
|
|
71359
|
+
const prefixChunks = [];
|
|
71360
|
+
let prefixBytes = 0;
|
|
71361
|
+
const inspector = new Transform({
|
|
71362
|
+
transform(chunk, _encoding, callback) {
|
|
71363
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
71364
|
+
receivedBytes += bytes.length;
|
|
71365
|
+
sha256.update(bytes);
|
|
71366
|
+
md5.update(bytes);
|
|
71367
|
+
if (prefixBytes < 1024) {
|
|
71368
|
+
const remaining = 1024 - prefixBytes;
|
|
71369
|
+
const sample = bytes.subarray(0, remaining);
|
|
71370
|
+
prefixChunks.push(sample);
|
|
71371
|
+
prefixBytes += sample.length;
|
|
71372
|
+
}
|
|
71373
|
+
callback(null, bytes);
|
|
71374
|
+
}
|
|
71375
|
+
});
|
|
70776
71376
|
const readableStream = Readable.fromWeb(response.body);
|
|
70777
|
-
|
|
70778
|
-
|
|
70779
|
-
|
|
71377
|
+
const fileStream = createWriteStream(partialPath, { flags: "wx" });
|
|
71378
|
+
await pipeline(readableStream, inspector, fileStream);
|
|
71379
|
+
const localSize = statSync4(partialPath).size;
|
|
71380
|
+
const sha256Bytes = sha256.digest();
|
|
71381
|
+
const localSha256 = sha256Bytes.toString("hex");
|
|
71382
|
+
const md5Base64 = md5.digest("base64");
|
|
71383
|
+
const telemetry = {
|
|
71384
|
+
finalHost: finalIdentity.host,
|
|
71385
|
+
status: response.status,
|
|
71386
|
+
expectedBytes,
|
|
71387
|
+
receivedBytes,
|
|
71388
|
+
rangeDisposition,
|
|
71389
|
+
localSize,
|
|
71390
|
+
localSha256
|
|
71391
|
+
};
|
|
71392
|
+
if (receivedBytes === 0 || localSize === 0) {
|
|
71393
|
+
throw new UrlDownloadError(
|
|
71394
|
+
"empty_body",
|
|
71395
|
+
true,
|
|
71396
|
+
"Download response body contained zero bytes",
|
|
71397
|
+
response.status,
|
|
71398
|
+
telemetry
|
|
71399
|
+
);
|
|
71400
|
+
}
|
|
71401
|
+
if (localSize !== receivedBytes || expectedBytes !== void 0 && receivedBytes !== expectedBytes) {
|
|
71402
|
+
throw new UrlDownloadError(
|
|
71403
|
+
"length_mismatch",
|
|
71404
|
+
true,
|
|
71405
|
+
"Download response byte count did not match its declared length",
|
|
71406
|
+
response.status,
|
|
71407
|
+
telemetry
|
|
71408
|
+
);
|
|
70780
71409
|
}
|
|
71410
|
+
const prefix = Buffer.concat(prefixChunks);
|
|
71411
|
+
if (looksLikeRemoteErrorDocument(prefix)) {
|
|
71412
|
+
throw new UrlDownloadError(
|
|
71413
|
+
"invalid_payload",
|
|
71414
|
+
false,
|
|
71415
|
+
"Download returned an HTML or JSON error document",
|
|
71416
|
+
response.status,
|
|
71417
|
+
telemetry
|
|
71418
|
+
);
|
|
71419
|
+
}
|
|
71420
|
+
const expectedSha256 = expectedResponseSha256(response, options.expectedSha256);
|
|
71421
|
+
const checksumMatches = expectedSha256 === null || (expectedSha256.encoding === "base64" ? sha256Bytes.toString("base64") === expectedSha256.value : localSha256 === expectedSha256.value);
|
|
71422
|
+
const contentMd5 = response.headers.get("content-md5")?.trim();
|
|
71423
|
+
if (!checksumMatches) {
|
|
71424
|
+
throw checksumMismatchError(expectedSha256?.source ?? "server", response.status, telemetry);
|
|
71425
|
+
}
|
|
71426
|
+
if (expectedSha256 === null && contentMd5 && md5Base64 !== contentMd5) {
|
|
71427
|
+
throw checksumMismatchError("server", response.status, telemetry);
|
|
71428
|
+
}
|
|
71429
|
+
const etag = response.headers.get("etag")?.trim();
|
|
71430
|
+
return {
|
|
71431
|
+
finalHost: finalIdentity.host,
|
|
71432
|
+
status: response.status,
|
|
71433
|
+
expectedBytes,
|
|
71434
|
+
receivedBytes,
|
|
71435
|
+
rangeDisposition,
|
|
71436
|
+
etagFingerprint: etag ? createHash("sha256").update(etag).digest("hex") : void 0,
|
|
71437
|
+
etagWeak: etag ? /^W\//i.test(etag) : void 0,
|
|
71438
|
+
localSize,
|
|
71439
|
+
localSha256
|
|
71440
|
+
};
|
|
70781
71441
|
}
|
|
70782
71442
|
function syncAndPublishPartial(partialPath, localPath) {
|
|
70783
71443
|
const fd = openSync(partialPath, "r+");
|
|
@@ -70786,14 +71446,35 @@ function syncAndPublishPartial(partialPath, localPath) {
|
|
|
70786
71446
|
} finally {
|
|
70787
71447
|
closeSync(fd);
|
|
70788
71448
|
}
|
|
70789
|
-
if (hasCompleteFile(localPath)) return;
|
|
70790
71449
|
try {
|
|
70791
|
-
|
|
71450
|
+
linkSync(partialPath, localPath);
|
|
71451
|
+
unlinkSync(partialPath);
|
|
71452
|
+
return "published";
|
|
70792
71453
|
} catch (error) {
|
|
70793
|
-
|
|
71454
|
+
const code = error.code;
|
|
71455
|
+
if (code !== "EEXIST") throw error;
|
|
71456
|
+
let winner;
|
|
71457
|
+
try {
|
|
71458
|
+
winner = lstatSync(localPath);
|
|
71459
|
+
} catch (inspectionError) {
|
|
71460
|
+
if (inspectionError.code !== "ENOENT") throw inspectionError;
|
|
71461
|
+
throw new UrlDownloadError(
|
|
71462
|
+
"filesystem",
|
|
71463
|
+
true,
|
|
71464
|
+
"Concurrent cache artifact disappeared before validation"
|
|
71465
|
+
);
|
|
71466
|
+
}
|
|
71467
|
+
if (!winner.isFile() || winner.size === 0) throw error;
|
|
71468
|
+
return "race_reused";
|
|
70794
71469
|
}
|
|
70795
71470
|
}
|
|
70796
|
-
|
|
71471
|
+
function emitDownloadTelemetry(options, event) {
|
|
71472
|
+
try {
|
|
71473
|
+
options.onTelemetry?.(event);
|
|
71474
|
+
} catch {
|
|
71475
|
+
}
|
|
71476
|
+
}
|
|
71477
|
+
async function runDownloadAttempt(url, localPath, timeoutMs, attempt, options, signal) {
|
|
70797
71478
|
const attemptDir = mkdtempSync(join9(dirname6(localPath), ".hf-download-"));
|
|
70798
71479
|
const partialPath = join9(attemptDir, "payload");
|
|
70799
71480
|
const controller = new AbortController();
|
|
@@ -70808,21 +71489,91 @@ async function runDownloadAttempt(url, localPath, timeoutMs, signal) {
|
|
|
70808
71489
|
timedOut = true;
|
|
70809
71490
|
controller.abort();
|
|
70810
71491
|
}, timeoutMs);
|
|
71492
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
70811
71493
|
try {
|
|
70812
71494
|
if (callerAborted) {
|
|
70813
71495
|
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70814
71496
|
}
|
|
70815
|
-
await fetchToPartial(url, partialPath, controller);
|
|
70816
|
-
syncAndPublishPartial(partialPath, localPath);
|
|
71497
|
+
const integrity = await fetchToPartial(url, partialPath, controller, options);
|
|
71498
|
+
let outcome = syncAndPublishPartial(partialPath, localPath);
|
|
71499
|
+
let publishedIntegrity = integrity;
|
|
71500
|
+
if (outcome === "race_reused") {
|
|
71501
|
+
let inspection;
|
|
71502
|
+
try {
|
|
71503
|
+
inspection = await inspectExistingFile(localPath);
|
|
71504
|
+
} catch (error) {
|
|
71505
|
+
if (error.code !== "ENOENT") throw error;
|
|
71506
|
+
throw new UrlDownloadError(
|
|
71507
|
+
"filesystem",
|
|
71508
|
+
true,
|
|
71509
|
+
"Concurrent cache artifact disappeared before validation",
|
|
71510
|
+
integrity.status,
|
|
71511
|
+
integrity
|
|
71512
|
+
);
|
|
71513
|
+
}
|
|
71514
|
+
publishedIntegrity = {
|
|
71515
|
+
...integrity,
|
|
71516
|
+
localSize: inspection.localSize,
|
|
71517
|
+
localSha256: inspection.localSha256
|
|
71518
|
+
};
|
|
71519
|
+
if (!localInspectionMatchesOptions(inspection, options)) {
|
|
71520
|
+
if (looksLikeRemoteErrorDocument(inspection.prefix)) {
|
|
71521
|
+
throw new UrlDownloadError(
|
|
71522
|
+
"invalid_payload",
|
|
71523
|
+
false,
|
|
71524
|
+
"Concurrent download published an HTML or JSON error document",
|
|
71525
|
+
integrity.status,
|
|
71526
|
+
publishedIntegrity
|
|
71527
|
+
);
|
|
71528
|
+
}
|
|
71529
|
+
throw checksumMismatchError("caller", integrity.status, publishedIntegrity);
|
|
71530
|
+
}
|
|
71531
|
+
}
|
|
71532
|
+
emitDownloadTelemetry(options, {
|
|
71533
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71534
|
+
initialHost: identity.host,
|
|
71535
|
+
attempt,
|
|
71536
|
+
outcome,
|
|
71537
|
+
...publishedIntegrity
|
|
71538
|
+
});
|
|
70817
71539
|
return localPath;
|
|
70818
71540
|
} catch (error) {
|
|
70819
71541
|
if (callerAborted) {
|
|
70820
|
-
|
|
71542
|
+
const classified2 = new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
71543
|
+
emitDownloadTelemetry(options, {
|
|
71544
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71545
|
+
initialHost: identity.host,
|
|
71546
|
+
attempt,
|
|
71547
|
+
outcome: "attempt_failed",
|
|
71548
|
+
failureKind: classified2.kind
|
|
71549
|
+
});
|
|
71550
|
+
throw classified2;
|
|
70821
71551
|
}
|
|
70822
71552
|
if (timedOut) {
|
|
70823
|
-
|
|
71553
|
+
const classified2 = new UrlDownloadError(
|
|
71554
|
+
"timeout",
|
|
71555
|
+
true,
|
|
71556
|
+
`Download timeout after ${timeoutMs / 1e3}s`
|
|
71557
|
+
);
|
|
71558
|
+
emitDownloadTelemetry(options, {
|
|
71559
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71560
|
+
initialHost: identity.host,
|
|
71561
|
+
attempt,
|
|
71562
|
+
outcome: "attempt_failed",
|
|
71563
|
+
failureKind: classified2.kind
|
|
71564
|
+
});
|
|
71565
|
+
throw classified2;
|
|
70824
71566
|
}
|
|
70825
|
-
|
|
71567
|
+
const classified = classifyDownloadFailure(error);
|
|
71568
|
+
emitDownloadTelemetry(options, {
|
|
71569
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71570
|
+
initialHost: identity.host,
|
|
71571
|
+
attempt,
|
|
71572
|
+
outcome: "attempt_failed",
|
|
71573
|
+
failureKind: classified.kind,
|
|
71574
|
+
...classified.telemetry
|
|
71575
|
+
});
|
|
71576
|
+
throw classified;
|
|
70826
71577
|
} finally {
|
|
70827
71578
|
clearTimeout(timeoutId);
|
|
70828
71579
|
signal?.removeEventListener("abort", onCallerAbort);
|
|
@@ -70830,22 +71581,114 @@ async function runDownloadAttempt(url, localPath, timeoutMs, signal) {
|
|
|
70830
71581
|
rmSync2(attemptDir, { recursive: true, force: true });
|
|
70831
71582
|
}
|
|
70832
71583
|
}
|
|
70833
|
-
async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientRetry) {
|
|
71584
|
+
async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientRetry, options = {}) {
|
|
70834
71585
|
const maxTransientRetries = 1;
|
|
70835
71586
|
for (let attempt = 0; ; attempt += 1) {
|
|
70836
71587
|
try {
|
|
70837
|
-
return await runDownloadAttempt(url, localPath, timeoutMs, signal);
|
|
71588
|
+
return await runDownloadAttempt(url, localPath, timeoutMs, attempt + 1, options, signal);
|
|
70838
71589
|
} catch (error) {
|
|
70839
71590
|
const classified = classifyDownloadFailure(error);
|
|
70840
|
-
if (!classified.
|
|
70841
|
-
onTransientRetry?.(classified);
|
|
71591
|
+
if (!classified.locallyRetryable || attempt >= maxTransientRetries) throw classified;
|
|
71592
|
+
if (classified.retryable) onTransientRetry?.(classified);
|
|
71593
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
71594
|
+
emitDownloadTelemetry(options, {
|
|
71595
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71596
|
+
initialHost: identity.host,
|
|
71597
|
+
attempt: attempt + 1,
|
|
71598
|
+
outcome: "retrying",
|
|
71599
|
+
failureKind: classified.kind,
|
|
71600
|
+
...classified.telemetry
|
|
71601
|
+
});
|
|
71602
|
+
}
|
|
71603
|
+
}
|
|
71604
|
+
}
|
|
71605
|
+
async function inspectExistingFile(path2) {
|
|
71606
|
+
const sha256 = createHash("sha256");
|
|
71607
|
+
const prefixChunks = [];
|
|
71608
|
+
let prefixBytes = 0;
|
|
71609
|
+
let localSize = 0;
|
|
71610
|
+
for await (const chunk of createReadStream2(path2)) {
|
|
71611
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
71612
|
+
localSize += bytes.length;
|
|
71613
|
+
sha256.update(bytes);
|
|
71614
|
+
if (prefixBytes < 1024) {
|
|
71615
|
+
const sample = bytes.subarray(0, 1024 - prefixBytes);
|
|
71616
|
+
prefixChunks.push(sample);
|
|
71617
|
+
prefixBytes += sample.length;
|
|
70842
71618
|
}
|
|
70843
71619
|
}
|
|
71620
|
+
return {
|
|
71621
|
+
localSize,
|
|
71622
|
+
localSha256: sha256.digest("hex"),
|
|
71623
|
+
prefix: Buffer.concat(prefixChunks)
|
|
71624
|
+
};
|
|
71625
|
+
}
|
|
71626
|
+
function localInspectionMatchesOptions(inspection, options) {
|
|
71627
|
+
const expectedSha256 = options.expectedSha256?.trim().toLowerCase();
|
|
71628
|
+
return inspection.localSize > 0 && !looksLikeRemoteErrorDocument(inspection.prefix) && (!expectedSha256 || inspection.localSha256 === expectedSha256);
|
|
70844
71629
|
}
|
|
70845
|
-
|
|
71630
|
+
function sameCacheEntry(before3, after2) {
|
|
71631
|
+
return sameFileIdentity(before3, after2) && before3.size === after2.size && before3.mtimeMs === after2.mtimeMs;
|
|
71632
|
+
}
|
|
71633
|
+
async function reuseOrInvalidateCachedFile(url, localPath, timeoutMs, signal, options) {
|
|
71634
|
+
const releaseLock = await acquireCachePathLock(localPath, timeoutMs, signal);
|
|
71635
|
+
try {
|
|
71636
|
+
for (let pass = 0; pass < 3; pass += 1) {
|
|
71637
|
+
let before3;
|
|
71638
|
+
try {
|
|
71639
|
+
before3 = lstatSync(localPath);
|
|
71640
|
+
} catch (error) {
|
|
71641
|
+
if (error.code === "ENOENT") continue;
|
|
71642
|
+
throw error;
|
|
71643
|
+
}
|
|
71644
|
+
if (!before3.isFile() || before3.size === 0) {
|
|
71645
|
+
rmSync2(localPath, { recursive: before3.isDirectory(), force: true });
|
|
71646
|
+
return false;
|
|
71647
|
+
}
|
|
71648
|
+
let inspection;
|
|
71649
|
+
try {
|
|
71650
|
+
inspection = await inspectExistingFile(localPath);
|
|
71651
|
+
} catch (error) {
|
|
71652
|
+
if (error.code === "ENOENT") continue;
|
|
71653
|
+
throw error;
|
|
71654
|
+
}
|
|
71655
|
+
let after2;
|
|
71656
|
+
try {
|
|
71657
|
+
after2 = lstatSync(localPath);
|
|
71658
|
+
} catch (error) {
|
|
71659
|
+
if (error.code === "ENOENT") continue;
|
|
71660
|
+
throw error;
|
|
71661
|
+
}
|
|
71662
|
+
if (!sameCacheEntry(before3, after2)) continue;
|
|
71663
|
+
if (localInspectionMatchesOptions(inspection, options)) {
|
|
71664
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
71665
|
+
emitDownloadTelemetry(options, {
|
|
71666
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71667
|
+
initialHost: identity.host,
|
|
71668
|
+
attempt: 0,
|
|
71669
|
+
outcome: "cache_hit",
|
|
71670
|
+
receivedBytes: inspection.localSize,
|
|
71671
|
+
localSize: inspection.localSize,
|
|
71672
|
+
localSha256: inspection.localSha256,
|
|
71673
|
+
rangeDisposition: "none"
|
|
71674
|
+
});
|
|
71675
|
+
return true;
|
|
71676
|
+
}
|
|
71677
|
+
rmSync2(localPath, { force: true });
|
|
71678
|
+
return false;
|
|
71679
|
+
}
|
|
71680
|
+
return false;
|
|
71681
|
+
} finally {
|
|
71682
|
+
releaseLock();
|
|
71683
|
+
}
|
|
71684
|
+
}
|
|
71685
|
+
async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransientRetry, options = {}) {
|
|
70846
71686
|
assertPublicHttpsUrl(url);
|
|
71687
|
+
const expectedSha256 = normalizeCallerSha256(options.expectedSha256);
|
|
71688
|
+
const normalizedOptions = { ...options, expectedSha256 };
|
|
70847
71689
|
const cacheKey = `${url}\0${destDir}`;
|
|
70848
|
-
const
|
|
71690
|
+
const validationScope = expectedSha256 ?? "";
|
|
71691
|
+
const inFlightKey = `${cacheKey}\0${timeoutMs}\0${signalScopeKey(signal)}\0${validationScope}`;
|
|
70849
71692
|
const inFlight2 = inFlightDownloads.get(inFlightKey);
|
|
70850
71693
|
if (inFlight2) {
|
|
70851
71694
|
return inFlight2;
|
|
@@ -70853,10 +71696,35 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransient
|
|
|
70853
71696
|
if (!existsSync9(destDir)) {
|
|
70854
71697
|
mkdirSync5(destDir, { recursive: true });
|
|
70855
71698
|
}
|
|
70856
|
-
const filename = getFilenameFromUrl(url);
|
|
71699
|
+
const filename = getFilenameFromUrl(url, validationScope);
|
|
70857
71700
|
const localPath = join9(destDir, filename);
|
|
70858
|
-
|
|
70859
|
-
|
|
71701
|
+
const downloadPromise = (async () => {
|
|
71702
|
+
const cacheStartedAt = Date.now();
|
|
71703
|
+
const reused = await reuseOrInvalidateCachedFile(
|
|
71704
|
+
url,
|
|
71705
|
+
localPath,
|
|
71706
|
+
timeoutMs,
|
|
71707
|
+
signal,
|
|
71708
|
+
normalizedOptions
|
|
71709
|
+
);
|
|
71710
|
+
const remainingTimeoutMs = timeoutMs - (Date.now() - cacheStartedAt);
|
|
71711
|
+
if (remainingTimeoutMs <= 0) {
|
|
71712
|
+
throw new UrlDownloadError(
|
|
71713
|
+
"timeout",
|
|
71714
|
+
true,
|
|
71715
|
+
`Download cache inspection timeout after ${timeoutMs / 1e3}s`
|
|
71716
|
+
);
|
|
71717
|
+
}
|
|
71718
|
+
if (reused) return localPath;
|
|
71719
|
+
return downloadWithRetry(
|
|
71720
|
+
url,
|
|
71721
|
+
localPath,
|
|
71722
|
+
remainingTimeoutMs,
|
|
71723
|
+
signal,
|
|
71724
|
+
onTransientRetry,
|
|
71725
|
+
normalizedOptions
|
|
71726
|
+
);
|
|
71727
|
+
})();
|
|
70860
71728
|
const trackedDownload = downloadPromise.finally(() => {
|
|
70861
71729
|
inFlightDownloads.delete(inFlightKey);
|
|
70862
71730
|
});
|
|
@@ -70866,7 +71734,7 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransient
|
|
|
70866
71734
|
function isHttpUrl(path2) {
|
|
70867
71735
|
return path2.startsWith("http://") || path2.startsWith("https://");
|
|
70868
71736
|
}
|
|
70869
|
-
var inFlightDownloads, signalScopes, nextSignalScope, UrlDownloadError, RETRYABLE_NETWORK_CODES, NON_PUBLIC_IPV4_ADDRESSES, NON_PUBLIC_IPV6_ADDRESSES, REDIRECT_STATUSES, MAX_REDIRECTS;
|
|
71737
|
+
var inFlightDownloads, signalScopes, nextSignalScope, UrlDownloadError, RETRYABLE_NETWORK_CODES, NON_PUBLIC_IPV4_ADDRESSES, NON_PUBLIC_IPV6_ADDRESSES, CACHE_LOCK_POLL_MS, CACHE_LOCK_STALE_MS, CACHE_LOCK_RECLAIM_NAME, CACHE_LOCK_OWNER_PREFIX, REDIRECT_STATUSES, MAX_REDIRECTS;
|
|
70870
71738
|
var init_urlDownloader = __esm({
|
|
70871
71739
|
"../engine/src/utils/urlDownloader.ts"() {
|
|
70872
71740
|
"use strict";
|
|
@@ -70874,16 +71742,20 @@ var init_urlDownloader = __esm({
|
|
|
70874
71742
|
signalScopes = /* @__PURE__ */ new WeakMap();
|
|
70875
71743
|
nextSignalScope = 1;
|
|
70876
71744
|
UrlDownloadError = class extends Error {
|
|
70877
|
-
constructor(kind, retryable, message, status) {
|
|
71745
|
+
constructor(kind, retryable, message, status, telemetry, locallyRetryable = retryable) {
|
|
70878
71746
|
super(message);
|
|
70879
71747
|
this.kind = kind;
|
|
70880
71748
|
this.retryable = retryable;
|
|
70881
71749
|
this.status = status;
|
|
71750
|
+
this.telemetry = telemetry;
|
|
71751
|
+
this.locallyRetryable = locallyRetryable;
|
|
70882
71752
|
this.name = "UrlDownloadError";
|
|
70883
71753
|
}
|
|
70884
71754
|
kind;
|
|
70885
71755
|
retryable;
|
|
70886
71756
|
status;
|
|
71757
|
+
telemetry;
|
|
71758
|
+
locallyRetryable;
|
|
70887
71759
|
};
|
|
70888
71760
|
RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set(["ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "EAI_AGAIN"]);
|
|
70889
71761
|
NON_PUBLIC_IPV4_ADDRESSES = new BlockList();
|
|
@@ -70919,6 +71791,10 @@ var init_urlDownloader = __esm({
|
|
|
70919
71791
|
]) {
|
|
70920
71792
|
NON_PUBLIC_IPV6_ADDRESSES.addSubnet(network, prefix, "ipv6");
|
|
70921
71793
|
}
|
|
71794
|
+
CACHE_LOCK_POLL_MS = 10;
|
|
71795
|
+
CACHE_LOCK_STALE_MS = 5 * 6e4;
|
|
71796
|
+
CACHE_LOCK_RECLAIM_NAME = ".hf-reclaim";
|
|
71797
|
+
CACHE_LOCK_OWNER_PREFIX = ".hf-owner-";
|
|
70922
71798
|
REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
70923
71799
|
MAX_REDIRECTS = 5;
|
|
70924
71800
|
}
|
|
@@ -75531,8 +76407,62 @@ function containsTimelineCall2(node, timelineVar) {
|
|
|
75531
76407
|
function rangeOf2(node) {
|
|
75532
76408
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
75533
76409
|
}
|
|
76410
|
+
function isSafeDefaultExpression2(node, earlierParams) {
|
|
76411
|
+
let safe = true;
|
|
76412
|
+
const visit = (current2, parent, key2) => {
|
|
76413
|
+
if (!isNode3(current2) || !safe) return;
|
|
76414
|
+
if (!SAFE_DEFAULT_NODES2.has(current2.type)) {
|
|
76415
|
+
safe = false;
|
|
76416
|
+
return;
|
|
76417
|
+
}
|
|
76418
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
76419
|
+
safe = false;
|
|
76420
|
+
return;
|
|
76421
|
+
}
|
|
76422
|
+
if (current2.type === "Identifier") {
|
|
76423
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot2(parent, key2) : false;
|
|
76424
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
76425
|
+
safe = false;
|
|
76426
|
+
}
|
|
76427
|
+
return;
|
|
76428
|
+
}
|
|
76429
|
+
for (const childKey of Object.keys(current2)) {
|
|
76430
|
+
if (SKIP_KEYS2.has(childKey)) continue;
|
|
76431
|
+
const child = current2[childKey];
|
|
76432
|
+
if (Array.isArray(child)) {
|
|
76433
|
+
for (const item of child) visit(item, current2, childKey);
|
|
76434
|
+
} else {
|
|
76435
|
+
visit(child, current2, childKey);
|
|
76436
|
+
}
|
|
76437
|
+
}
|
|
76438
|
+
};
|
|
76439
|
+
visit(node);
|
|
76440
|
+
return safe;
|
|
76441
|
+
}
|
|
76442
|
+
function supportedParam2(param, earlier) {
|
|
76443
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
76444
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
76445
|
+
if (!isSafeDefaultExpression2(param.right, earlier)) return null;
|
|
76446
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
76447
|
+
}
|
|
76448
|
+
function supportedParams2(fn) {
|
|
76449
|
+
if (SUPPORTED_PARAMS_CACHE2.has(fn)) return SUPPORTED_PARAMS_CACHE2.get(fn) ?? null;
|
|
76450
|
+
const params = [];
|
|
76451
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
76452
|
+
for (const param of fn.params ?? []) {
|
|
76453
|
+
const parsed = supportedParam2(param, earlier);
|
|
76454
|
+
if (!parsed) {
|
|
76455
|
+
SUPPORTED_PARAMS_CACHE2.set(fn, null);
|
|
76456
|
+
return null;
|
|
76457
|
+
}
|
|
76458
|
+
params.push(parsed);
|
|
76459
|
+
earlier.add(parsed.name);
|
|
76460
|
+
}
|
|
76461
|
+
SUPPORTED_PARAMS_CACHE2.set(fn, params);
|
|
76462
|
+
return params;
|
|
76463
|
+
}
|
|
75534
76464
|
function isShapeEligible2(fn) {
|
|
75535
|
-
return isFunctionNode3(fn) && fn.body?.type === "BlockStatement" &&
|
|
76465
|
+
return isFunctionNode3(fn) && fn.body?.type === "BlockStatement" && supportedParams2(fn) !== null;
|
|
75536
76466
|
}
|
|
75537
76467
|
function callsAny2(node, names) {
|
|
75538
76468
|
let hit = false;
|
|
@@ -75582,20 +76512,55 @@ function timelineBuildingNames2(candidates, timelineVar) {
|
|
|
75582
76512
|
function bump2(counts, key2) {
|
|
75583
76513
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
75584
76514
|
}
|
|
76515
|
+
function undefinedIdentifier2() {
|
|
76516
|
+
return { type: "Identifier", name: "undefined" };
|
|
76517
|
+
}
|
|
76518
|
+
function isExplicitUndefined2(node) {
|
|
76519
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
76520
|
+
}
|
|
76521
|
+
function resolveHelperBindings2(call, params) {
|
|
76522
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
76523
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
76524
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
76525
|
+
const param = params[i2];
|
|
76526
|
+
const arg = call.arguments?.[i2];
|
|
76527
|
+
if (arg && !isExplicitUndefined2(arg)) {
|
|
76528
|
+
bindings.set(param.name, arg);
|
|
76529
|
+
} else if (param.defaultExpression) {
|
|
76530
|
+
bindings.set(param.name, substituteParams2(cloneNode3(param.defaultExpression), bindings));
|
|
76531
|
+
} else {
|
|
76532
|
+
bindings.set(param.name, undefinedIdentifier2());
|
|
76533
|
+
}
|
|
76534
|
+
}
|
|
76535
|
+
return bindings;
|
|
76536
|
+
}
|
|
76537
|
+
function statementHelperCall2(node, names) {
|
|
76538
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
76539
|
+
const expression = node.expression;
|
|
76540
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
76541
|
+
return void 0;
|
|
76542
|
+
}
|
|
76543
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
76544
|
+
}
|
|
75585
76545
|
function safelyDroppable2(program, candidates) {
|
|
75586
76546
|
const names = new Set(candidates.keys());
|
|
75587
76547
|
const totalIds = /* @__PURE__ */ new Map();
|
|
75588
76548
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
76549
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
75589
76550
|
walkNodes2(program, (n2) => {
|
|
75590
76551
|
if (n2.type === "Identifier" && names.has(n2.name)) bump2(totalIds, n2.name);
|
|
75591
|
-
const
|
|
75592
|
-
if (
|
|
75593
|
-
|
|
75594
|
-
|
|
76552
|
+
const call = statementHelperCall2(n2, names);
|
|
76553
|
+
if (!call) return;
|
|
76554
|
+
bump2(stmtCalls, call.callee.name);
|
|
76555
|
+
const fn = candidates.get(call.callee.name);
|
|
76556
|
+
const params = fn && supportedParams2(fn);
|
|
76557
|
+
if (!params || !resolveHelperBindings2(call, params)) unbindable.add(call.callee.name);
|
|
75595
76558
|
});
|
|
75596
76559
|
const safe = /* @__PURE__ */ new Map();
|
|
75597
76560
|
for (const [name, fn] of candidates) {
|
|
75598
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
76561
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
76562
|
+
safe.set(name, fn);
|
|
76563
|
+
}
|
|
75599
76564
|
}
|
|
75600
76565
|
return safe;
|
|
75601
76566
|
}
|
|
@@ -75638,11 +76603,11 @@ function expandBody2(bodyStmts, bindings, prov, ctx) {
|
|
|
75638
76603
|
}
|
|
75639
76604
|
function inlineHelper2(call, ctx) {
|
|
75640
76605
|
const fn = ctx.helpers.get(call.callee.name);
|
|
75641
|
-
|
|
75642
|
-
|
|
75643
|
-
|
|
75644
|
-
|
|
75645
|
-
|
|
76606
|
+
if (!fn) return null;
|
|
76607
|
+
const params = supportedParams2(fn);
|
|
76608
|
+
if (!params) return null;
|
|
76609
|
+
const bindings = resolveHelperBindings2(call, params);
|
|
76610
|
+
if (!bindings) return null;
|
|
75646
76611
|
const prov = {
|
|
75647
76612
|
kind: "helper",
|
|
75648
76613
|
fn: call.callee.name,
|
|
@@ -77117,7 +78082,7 @@ function extractGsapLabels(script) {
|
|
|
77117
78082
|
return [];
|
|
77118
78083
|
}
|
|
77119
78084
|
}
|
|
77120
|
-
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS2, FUNCTION_TYPES2, GSAP_METHODS3, MAX_DEPTH2, MAX_ITERS2, roundPercentage2, GSAP_METHODS22, QUERY_METHODS2, ITERATION_METHODS2, SCOPE_NODE_TYPES2, CONST_NODES2, MATH_FNS2, MATH_CONSTS2, BUILTIN_VAR_KEYS2, DROPPED_VAR_KEYS2, EXTRAS_KEYS2, PERCENTAGE_KEY_RE2, GSAP_DEFAULT_DURATION2;
|
|
78085
|
+
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS2, FUNCTION_TYPES2, GSAP_METHODS3, MAX_DEPTH2, MAX_ITERS2, SAFE_DEFAULT_NODES2, SUPPORTED_PARAMS_CACHE2, roundPercentage2, GSAP_METHODS22, QUERY_METHODS2, ITERATION_METHODS2, SCOPE_NODE_TYPES2, CONST_NODES2, MATH_FNS2, MATH_CONSTS2, BUILTIN_VAR_KEYS2, DROPPED_VAR_KEYS2, EXTRAS_KEYS2, PERCENTAGE_KEY_RE2, GSAP_DEFAULT_DURATION2;
|
|
77121
78086
|
var init_gsapParserAcorn = __esm({
|
|
77122
78087
|
"../parsers/dist/gsapParserAcorn.js"() {
|
|
77123
78088
|
"use strict";
|
|
@@ -77144,6 +78109,23 @@ var init_gsapParserAcorn = __esm({
|
|
|
77144
78109
|
GSAP_METHODS3 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
77145
78110
|
MAX_DEPTH2 = 8;
|
|
77146
78111
|
MAX_ITERS2 = 512;
|
|
78112
|
+
SAFE_DEFAULT_NODES2 = /* @__PURE__ */ new Set([
|
|
78113
|
+
"ArrayExpression",
|
|
78114
|
+
"BinaryExpression",
|
|
78115
|
+
"ChainExpression",
|
|
78116
|
+
"ConditionalExpression",
|
|
78117
|
+
"Identifier",
|
|
78118
|
+
"Literal",
|
|
78119
|
+
"LogicalExpression",
|
|
78120
|
+
"MemberExpression",
|
|
78121
|
+
"ObjectExpression",
|
|
78122
|
+
"Property",
|
|
78123
|
+
"SpreadElement",
|
|
78124
|
+
"TemplateElement",
|
|
78125
|
+
"TemplateLiteral",
|
|
78126
|
+
"UnaryExpression"
|
|
78127
|
+
]);
|
|
78128
|
+
SUPPORTED_PARAMS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
77147
78129
|
roundPercentage2 = (percentage) => Math.round(percentage * 10) / 10;
|
|
77148
78130
|
GSAP_METHODS22 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
77149
78131
|
QUERY_METHODS2 = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
@@ -77184,7 +78166,7 @@ __export(dist_exports2, {
|
|
|
77184
78166
|
});
|
|
77185
78167
|
import postcss2 from "postcss";
|
|
77186
78168
|
import postcss22 from "postcss";
|
|
77187
|
-
import { existsSync as existsSync22, readFileSync as readFileSync4, readdirSync as
|
|
78169
|
+
import { existsSync as existsSync22, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
|
|
77188
78170
|
import { dirname as dirname7, extname as extname3, join as join22, relative as relative3, resolve as resolve8 } from "path";
|
|
77189
78171
|
import { execFile } from "child_process";
|
|
77190
78172
|
import { existsSync as existsSync11 } from "fs";
|
|
@@ -79013,6 +79995,7 @@ async function probeIsHevc(ffprobePath, filePath) {
|
|
|
79013
79995
|
"stream=codec_name",
|
|
79014
79996
|
"-of",
|
|
79015
79997
|
"json",
|
|
79998
|
+
"--",
|
|
79016
79999
|
filePath
|
|
79017
80000
|
]);
|
|
79018
80001
|
return hasHevcStream(JSON.parse(stdout2));
|
|
@@ -79169,7 +80152,7 @@ async function lintProject(projectDir, entryFile) {
|
|
|
79169
80152
|
if (!entryFile && existsSync22(compositionsDir)) {
|
|
79170
80153
|
const collectHtmlFiles = (dir, rel) => {
|
|
79171
80154
|
const out = [];
|
|
79172
|
-
for (const entry of
|
|
80155
|
+
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
79173
80156
|
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
79174
80157
|
if (entry.isDirectory()) {
|
|
79175
80158
|
if (!rel && entry.name === "components") continue;
|
|
@@ -79230,7 +80213,7 @@ function lintProjectAudioFiles(projectDir, htmlSources) {
|
|
|
79230
80213
|
const findings = [];
|
|
79231
80214
|
let audioFiles;
|
|
79232
80215
|
try {
|
|
79233
|
-
audioFiles =
|
|
80216
|
+
audioFiles = readdirSync4(projectDir).filter(
|
|
79234
80217
|
(f3) => AUDIO_EXTENSIONS.has(extname3(f3).toLowerCase())
|
|
79235
80218
|
);
|
|
79236
80219
|
} catch {
|
|
@@ -79349,7 +80332,7 @@ function lintTextureMaskAssetNotFound(projectDir, htmlSources) {
|
|
|
79349
80332
|
function lintMultipleRootCompositions(projectDir) {
|
|
79350
80333
|
const findings = [];
|
|
79351
80334
|
try {
|
|
79352
|
-
const rootHtmlFiles =
|
|
80335
|
+
const rootHtmlFiles = readdirSync4(projectDir).filter(
|
|
79353
80336
|
(file) => file.endsWith(".html") && !file.startsWith("._")
|
|
79354
80337
|
);
|
|
79355
80338
|
const rootCompositions = [];
|
|
@@ -83972,13 +84955,13 @@ var init_htmlTemplate = __esm({
|
|
|
83972
84955
|
});
|
|
83973
84956
|
|
|
83974
84957
|
// ../engine/src/services/extractionCache.ts
|
|
83975
|
-
import { createHash as createHash2, randomUUID as
|
|
84958
|
+
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
83976
84959
|
import {
|
|
83977
84960
|
existsSync as existsSync13,
|
|
83978
84961
|
lstatSync as lstatSync2,
|
|
83979
84962
|
mkdirSync as mkdirSync6,
|
|
83980
|
-
readdirSync as
|
|
83981
|
-
renameSync as
|
|
84963
|
+
readdirSync as readdirSync5,
|
|
84964
|
+
renameSync as renameSync2,
|
|
83982
84965
|
rmSync as rmSync3,
|
|
83983
84966
|
statSync as statSync5,
|
|
83984
84967
|
utimesSync,
|
|
@@ -84020,7 +85003,7 @@ function lookupCacheEntry(rootDir, input2) {
|
|
|
84020
85003
|
return { entry: { dir, keyHash }, hit: complete };
|
|
84021
85004
|
}
|
|
84022
85005
|
function partialCacheEntryDir(entry) {
|
|
84023
|
-
return `${entry.dir}.partial-${process.pid}-${
|
|
85006
|
+
return `${entry.dir}.partial-${process.pid}-${randomUUID3().slice(0, 8)}`;
|
|
84024
85007
|
}
|
|
84025
85008
|
function isTargetExistsRenameError(err) {
|
|
84026
85009
|
const code = err.code;
|
|
@@ -84038,7 +85021,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
84038
85021
|
return { dir: partialDir, published: false };
|
|
84039
85022
|
}
|
|
84040
85023
|
try {
|
|
84041
|
-
|
|
85024
|
+
renameSync2(partialDir, entry.dir);
|
|
84042
85025
|
return { dir: entry.dir, published: true };
|
|
84043
85026
|
} catch (err) {
|
|
84044
85027
|
if (!isTargetExistsRenameError(err)) return { dir: partialDir, published: false };
|
|
@@ -84051,7 +85034,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
84051
85034
|
return { dir: partialDir, published: false };
|
|
84052
85035
|
}
|
|
84053
85036
|
try {
|
|
84054
|
-
|
|
85037
|
+
renameSync2(partialDir, entry.dir);
|
|
84055
85038
|
return { dir: entry.dir, published: true };
|
|
84056
85039
|
} catch {
|
|
84057
85040
|
return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
|
|
@@ -84080,7 +85063,7 @@ function directorySizeBytes(path2) {
|
|
|
84080
85063
|
let total = 0;
|
|
84081
85064
|
let children;
|
|
84082
85065
|
try {
|
|
84083
|
-
children =
|
|
85066
|
+
children = readdirSync5(path2);
|
|
84084
85067
|
} catch {
|
|
84085
85068
|
return 0;
|
|
84086
85069
|
}
|
|
@@ -84138,7 +85121,7 @@ function gcExtractionCache(rootDir, opts) {
|
|
|
84138
85121
|
try {
|
|
84139
85122
|
const now = Date.now();
|
|
84140
85123
|
const entries2 = [];
|
|
84141
|
-
for (const child of
|
|
85124
|
+
for (const child of readdirSync5(rootDir, { withFileTypes: true })) {
|
|
84142
85125
|
if (!child.isDirectory() || !isCacheLikeChild(child.name)) continue;
|
|
84143
85126
|
const entry = collectGcEntry(
|
|
84144
85127
|
join11(rootDir, child.name),
|
|
@@ -84168,7 +85151,7 @@ function rehydrateCacheEntry(entry, options) {
|
|
|
84168
85151
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
84169
85152
|
const framePaths = /* @__PURE__ */ new Map();
|
|
84170
85153
|
const suffix = `.${options.format}`;
|
|
84171
|
-
const files =
|
|
85154
|
+
const files = readdirSync5(entry.dir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(suffix)).sort();
|
|
84172
85155
|
files.forEach((file, idx) => {
|
|
84173
85156
|
framePaths.set(idx, join11(entry.dir, file));
|
|
84174
85157
|
});
|
|
@@ -84197,7 +85180,7 @@ var init_extractionCache = __esm({
|
|
|
84197
85180
|
});
|
|
84198
85181
|
|
|
84199
85182
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
84200
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync14, linkSync, mkdirSync as mkdirSync7, readdirSync as
|
|
85183
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync14, linkSync as linkSync2, mkdirSync as mkdirSync7, readdirSync as readdirSync6, rmSync as rmSync4 } from "fs";
|
|
84201
85184
|
import { isAbsolute as isAbsolute4, join as join12, posix as posix3, resolve as resolve10, sep as sep3 } from "path";
|
|
84202
85185
|
function isVideoFrameFormat(value) {
|
|
84203
85186
|
return typeof value === "string" && VIDEO_FRAME_FORMATS.includes(value);
|
|
@@ -84281,6 +85264,14 @@ function classifyVideoExtractionError(error) {
|
|
|
84281
85264
|
diagnostic
|
|
84282
85265
|
);
|
|
84283
85266
|
}
|
|
85267
|
+
if (error.kind === "invalid_payload") {
|
|
85268
|
+
return new VideoSourceExtractionError(
|
|
85269
|
+
"invalid_media",
|
|
85270
|
+
false,
|
|
85271
|
+
"Video source download returned a non-media payload",
|
|
85272
|
+
diagnostic
|
|
85273
|
+
);
|
|
85274
|
+
}
|
|
84284
85275
|
if (error.retryable) {
|
|
84285
85276
|
return new VideoSourceExtractionError(
|
|
84286
85277
|
"download_transient",
|
|
@@ -84578,7 +85569,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
84578
85569
|
);
|
|
84579
85570
|
}
|
|
84580
85571
|
const framePaths = /* @__PURE__ */ new Map();
|
|
84581
|
-
const files =
|
|
85572
|
+
const files = readdirSync6(videoOutputDir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(`.${format}`)).sort();
|
|
84582
85573
|
files.forEach((file, index) => {
|
|
84583
85574
|
framePaths.set(index, join12(videoOutputDir, file));
|
|
84584
85575
|
});
|
|
@@ -84755,7 +85746,7 @@ function resolveFrameFormat(metadata, requested) {
|
|
|
84755
85746
|
}
|
|
84756
85747
|
function extractedFrameFileNames(outputDir, format) {
|
|
84757
85748
|
const suffix = `.${format}`;
|
|
84758
|
-
return
|
|
85749
|
+
return readdirSync6(outputDir).filter((file) => file.startsWith(FRAME_FILENAME_PREFIX) && file.endsWith(suffix)).sort();
|
|
84759
85750
|
}
|
|
84760
85751
|
function extractedFramesFromDirectory(work, outputDir, srcPath, fps) {
|
|
84761
85752
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${work.format}`;
|
|
@@ -84779,7 +85770,7 @@ function frameFileName(frameNumber, format) {
|
|
|
84779
85770
|
}
|
|
84780
85771
|
function linkOrCopyFrame(src, dest) {
|
|
84781
85772
|
try {
|
|
84782
|
-
|
|
85773
|
+
linkSync2(src, dest);
|
|
84783
85774
|
} catch {
|
|
84784
85775
|
copyFileSync2(src, dest);
|
|
84785
85776
|
}
|
|
@@ -84964,7 +85955,8 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
84964
85955
|
downloadDir,
|
|
84965
85956
|
void 0,
|
|
84966
85957
|
signal,
|
|
84967
|
-
() => recordTransientRetries(1)
|
|
85958
|
+
() => recordTransientRetries(1),
|
|
85959
|
+
{ onTelemetry: writeUrlDownloadTelemetry }
|
|
84968
85960
|
);
|
|
84969
85961
|
}
|
|
84970
85962
|
if (!existsSync14(videoPath)) {
|
|
@@ -86021,7 +87013,7 @@ var init_videoFrameInjector = __esm({
|
|
|
86021
87013
|
});
|
|
86022
87014
|
|
|
86023
87015
|
// ../engine/src/services/audioVolumeEnvelope.ts
|
|
86024
|
-
import { readFileSync as readFileSync6, renameSync as
|
|
87016
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
86025
87017
|
import { randomBytes } from "crypto";
|
|
86026
87018
|
function parseWavLayout(buffer) {
|
|
86027
87019
|
if (buffer.length < 12 || buffer.toString("ascii", 0, 4) !== "RIFF") return null;
|
|
@@ -86083,7 +87075,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
|
|
|
86083
87075
|
}
|
|
86084
87076
|
const tempPath = `${wavPath}.${randomBytes(6).toString("hex")}.tmp`;
|
|
86085
87077
|
writeFileSync5(tempPath, buffer);
|
|
86086
|
-
|
|
87078
|
+
renameSync3(tempPath, wavPath);
|
|
86087
87079
|
return true;
|
|
86088
87080
|
} catch {
|
|
86089
87081
|
return false;
|
|
@@ -86224,15 +87216,17 @@ function probeFailure(message, elementId) {
|
|
|
86224
87216
|
detail: boundedDetail(`Audio probe failed for element ${elementId}: ${message}`)
|
|
86225
87217
|
};
|
|
86226
87218
|
}
|
|
86227
|
-
function downloadFailure(
|
|
86228
|
-
const
|
|
87219
|
+
function downloadFailure(error, elementId) {
|
|
87220
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
87221
|
+
const invalidSource = error instanceof UrlDownloadError ? error.kind === "http_not_found" || error.kind === "http_rejected" || error.kind === "invalid_payload" || error.kind === "cancelled" : /(?:invalid URL|only HTTPS|private\/reserved|HTTP (?:400|401|403|404|405|410|422)\b)/i.test(
|
|
86229
87222
|
message
|
|
86230
87223
|
);
|
|
87224
|
+
const retryable = error instanceof UrlDownloadError ? error.retryable : !invalidSource;
|
|
86231
87225
|
return {
|
|
86232
87226
|
stage: "download",
|
|
86233
87227
|
reason: "download_failed",
|
|
86234
87228
|
owner: invalidSource ? "user" : "system",
|
|
86235
|
-
retryable
|
|
87229
|
+
retryable,
|
|
86236
87230
|
elementId,
|
|
86237
87231
|
detail: boundedDetail(`Download failed for audio element ${elementId}: ${message}`)
|
|
86238
87232
|
};
|
|
@@ -86579,11 +87573,11 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
86579
87573
|
}
|
|
86580
87574
|
if (isHttpUrl(srcPath)) {
|
|
86581
87575
|
try {
|
|
86582
|
-
srcPath = await downloadToTemp(srcPath, workDir
|
|
87576
|
+
srcPath = await downloadToTemp(srcPath, workDir, void 0, signal, void 0, {
|
|
87577
|
+
onTelemetry: writeUrlDownloadTelemetry
|
|
87578
|
+
});
|
|
86583
87579
|
} catch (err) {
|
|
86584
|
-
failures.push(
|
|
86585
|
-
downloadFailure(err instanceof Error ? err.message : String(err), element.id)
|
|
86586
|
-
);
|
|
87580
|
+
failures.push(downloadFailure(err, element.id));
|
|
86587
87581
|
return;
|
|
86588
87582
|
}
|
|
86589
87583
|
}
|
|
@@ -86863,7 +87857,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
86863
87857
|
|
|
86864
87858
|
// ../engine/src/services/parallelCoordinator.ts
|
|
86865
87859
|
import { cpus, freemem } from "os";
|
|
86866
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync as
|
|
87860
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync as readdirSync7 } from "fs";
|
|
86867
87861
|
import { copyFile, readFile, rename } from "fs/promises";
|
|
86868
87862
|
import { join as join15 } from "path";
|
|
86869
87863
|
import { getHeapStatistics } from "v8";
|
|
@@ -87289,7 +88283,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
87289
88283
|
if (!existsSync16(task.outputDir)) {
|
|
87290
88284
|
continue;
|
|
87291
88285
|
}
|
|
87292
|
-
const files =
|
|
88286
|
+
const files = readdirSync7(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
87293
88287
|
const copyTasks = files.map(async (file) => {
|
|
87294
88288
|
const sourcePath = join15(task.outputDir, file);
|
|
87295
88289
|
const targetPath = join15(outputDir, file);
|
|
@@ -88804,7 +89798,7 @@ var init_shaderTransitions = __esm({
|
|
|
88804
89798
|
});
|
|
88805
89799
|
|
|
88806
89800
|
// ../engine/src/services/hdrCapture.ts
|
|
88807
|
-
import { existsSync as existsSync18, readdirSync as
|
|
89801
|
+
import { existsSync as existsSync18, readdirSync as readdirSync8 } from "fs";
|
|
88808
89802
|
import { join as join17 } from "path";
|
|
88809
89803
|
import { homedir as homedir3 } from "os";
|
|
88810
89804
|
function linearToPQ(L2) {
|
|
@@ -88923,7 +89917,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
88923
89917
|
function resolveHeadedChromePath() {
|
|
88924
89918
|
const baseDir = join17(homedir3(), ".cache", "puppeteer", "chrome");
|
|
88925
89919
|
if (!existsSync18(baseDir)) return void 0;
|
|
88926
|
-
const versions =
|
|
89920
|
+
const versions = readdirSync8(baseDir).sort().reverse();
|
|
88927
89921
|
for (const version2 of versions) {
|
|
88928
89922
|
const candidates = [
|
|
88929
89923
|
join17(
|
|
@@ -89086,6 +90080,7 @@ __export(src_exports, {
|
|
|
89086
90080
|
decodePng: () => decodePng,
|
|
89087
90081
|
decodePngToRgb48le: () => decodePngToRgb48le,
|
|
89088
90082
|
defaultExtractCacheDir: () => defaultExtractCacheDir,
|
|
90083
|
+
deriveBeginFrameProbeTimeTicks: () => deriveBeginFrameProbeTimeTicks,
|
|
89089
90084
|
detectGpuEncoder: () => detectGpuEncoder,
|
|
89090
90085
|
detectTransfer: () => detectTransfer,
|
|
89091
90086
|
diffGpuParityFrames: () => diffGpuParityFrames,
|
|
@@ -89105,6 +90100,7 @@ __export(src_exports, {
|
|
|
89105
90100
|
extractVideoFramesRange: () => extractVideoFramesRange,
|
|
89106
90101
|
extractVideoMetadata: () => extractVideoMetadata,
|
|
89107
90102
|
extractionFrameCountForDuration: () => extractionFrameCountForDuration,
|
|
90103
|
+
fetchPublicHttpsText: () => fetchPublicHttpsText,
|
|
89108
90104
|
float16ToPqRgb: () => float16ToPqRgb,
|
|
89109
90105
|
formatFfmpegError: () => formatFfmpegError,
|
|
89110
90106
|
getCapturePerfSummary: () => getCapturePerfSummary,
|
|
@@ -89178,6 +90174,7 @@ __export(src_exports, {
|
|
|
89178
90174
|
roundedRectAlpha: () => roundedRectAlpha,
|
|
89179
90175
|
runFfmpeg: () => runFfmpeg,
|
|
89180
90176
|
runVideoExtractionWithRetry: () => runVideoExtractionWithRetry,
|
|
90177
|
+
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
89181
90178
|
sampleRgb48le: () => sampleRgb48le,
|
|
89182
90179
|
scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
|
|
89183
90180
|
selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
|
|
@@ -89190,7 +90187,8 @@ __export(src_exports, {
|
|
|
89190
90187
|
validateEngineConfigSnapshot: () => validateEngineConfigSnapshot,
|
|
89191
90188
|
verifyDiskDrawElementSamples: () => verifyDiskDrawElementSamples,
|
|
89192
90189
|
verifyGpuParity: () => verifyGpuParity,
|
|
89193
|
-
writeCapturedFrame: () => writeCapturedFrame
|
|
90190
|
+
writeCapturedFrame: () => writeCapturedFrame,
|
|
90191
|
+
writeUrlDownloadTelemetry: () => writeUrlDownloadTelemetry
|
|
89194
90192
|
});
|
|
89195
90193
|
var init_src = __esm({
|
|
89196
90194
|
"../engine/src/index.ts"() {
|
|
@@ -89748,10 +90746,10 @@ var init_canary2 = __esm({
|
|
|
89748
90746
|
|
|
89749
90747
|
// src/telemetry/transport.ts
|
|
89750
90748
|
import { spawn as spawn5 } from "child_process";
|
|
89751
|
-
import { randomUUID as
|
|
90749
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
89752
90750
|
function enqueue(event, properties, distinctId) {
|
|
89753
90751
|
eventQueue.push({
|
|
89754
|
-
uuid:
|
|
90752
|
+
uuid: randomUUID4(),
|
|
89755
90753
|
event,
|
|
89756
90754
|
distinctId,
|
|
89757
90755
|
properties,
|
|
@@ -93231,12 +94229,12 @@ var init_ffmpeg = __esm({
|
|
|
93231
94229
|
});
|
|
93232
94230
|
|
|
93233
94231
|
// src/utils/download.ts
|
|
93234
|
-
import { createWriteStream as createWriteStream2, renameSync as
|
|
94232
|
+
import { createWriteStream as createWriteStream2, renameSync as renameSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
93235
94233
|
import { get as httpsGet } from "https";
|
|
93236
94234
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
93237
94235
|
function removePartialFile(path2) {
|
|
93238
94236
|
try {
|
|
93239
|
-
|
|
94237
|
+
unlinkSync2(path2);
|
|
93240
94238
|
} catch {
|
|
93241
94239
|
}
|
|
93242
94240
|
}
|
|
@@ -93267,7 +94265,7 @@ function downloadFile(url, dest, options = {}) {
|
|
|
93267
94265
|
const file = createWriteStream2(tmp);
|
|
93268
94266
|
responsePipelineStarted = true;
|
|
93269
94267
|
pipeline2(res, file).then(() => {
|
|
93270
|
-
|
|
94268
|
+
renameSync4(tmp, dest);
|
|
93271
94269
|
resolve77();
|
|
93272
94270
|
}).catch((err) => {
|
|
93273
94271
|
removePartialFile(tmp);
|
|
@@ -93500,10 +94498,10 @@ __export(transcribe_exports, {
|
|
|
93500
94498
|
wrapWhisperTimeoutError: () => wrapWhisperTimeoutError
|
|
93501
94499
|
});
|
|
93502
94500
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
93503
|
-
import { existsSync as existsSync25, readFileSync as readFileSync14, mkdirSync as mkdirSync12, unlinkSync as
|
|
94501
|
+
import { existsSync as existsSync25, readFileSync as readFileSync14, mkdirSync as mkdirSync12, unlinkSync as unlinkSync3 } from "fs";
|
|
93504
94502
|
import { join as join21, extname as extname5 } from "path";
|
|
93505
94503
|
import { tmpdir as tmpdir3 } from "os";
|
|
93506
|
-
import { randomUUID as
|
|
94504
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
93507
94505
|
function detectLanguage(whisperPath, modelPath2, wavPath) {
|
|
93508
94506
|
try {
|
|
93509
94507
|
const output = execFileSync5(whisperPath, ["--model", modelPath2, "--detect-language", wavPath], {
|
|
@@ -93573,6 +94571,7 @@ function getMediaDurationSeconds(filePath) {
|
|
|
93573
94571
|
"format=duration",
|
|
93574
94572
|
"-of",
|
|
93575
94573
|
"default=noprint_wrappers=1:nokey=1",
|
|
94574
|
+
"--",
|
|
93576
94575
|
filePath
|
|
93577
94576
|
],
|
|
93578
94577
|
{ encoding: "utf-8", timeout: 1e4 }
|
|
@@ -93644,7 +94643,7 @@ function isVideoFile(filePath) {
|
|
|
93644
94643
|
return VIDEO_EXTENSIONS.has(extname5(filePath).toLowerCase());
|
|
93645
94644
|
}
|
|
93646
94645
|
function tempWavPath() {
|
|
93647
|
-
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${
|
|
94646
|
+
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${randomUUID5()}.wav`);
|
|
93648
94647
|
}
|
|
93649
94648
|
function extractAudio(videoPath) {
|
|
93650
94649
|
const ffmpegPath = findFFmpeg();
|
|
@@ -93670,7 +94669,7 @@ function isWav16kMono(filePath) {
|
|
|
93670
94669
|
if (!ffprobePath) return false;
|
|
93671
94670
|
const raw = execFileSync5(
|
|
93672
94671
|
ffprobePath,
|
|
93673
|
-
["-v", "quiet", "-print_format", "json", "-show_streams", filePath],
|
|
94672
|
+
["-v", "quiet", "-print_format", "json", "-show_streams", "--", filePath],
|
|
93674
94673
|
{ encoding: "utf-8", timeout: 1e4 }
|
|
93675
94674
|
);
|
|
93676
94675
|
const parsed = JSON.parse(raw);
|
|
@@ -93802,7 +94801,7 @@ async function transcribe(inputPath, outputDir, options) {
|
|
|
93802
94801
|
const speechOnsetSeconds = detectSpeechOnset(wavPath);
|
|
93803
94802
|
if (wavPath !== inputPath) {
|
|
93804
94803
|
try {
|
|
93805
|
-
|
|
94804
|
+
unlinkSync3(wavPath);
|
|
93806
94805
|
} catch {
|
|
93807
94806
|
}
|
|
93808
94807
|
}
|
|
@@ -93872,7 +94871,7 @@ __export(normalize_exports, {
|
|
|
93872
94871
|
stripBeforeOnset: () => stripBeforeOnset,
|
|
93873
94872
|
wordsToCues: () => wordsToCues
|
|
93874
94873
|
});
|
|
93875
|
-
import { readFileSync as readFileSync15, readdirSync as
|
|
94874
|
+
import { readFileSync as readFileSync15, readdirSync as readdirSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
93876
94875
|
import { extname as extname6, join as join23 } from "path";
|
|
93877
94876
|
function detectFormat(filePath) {
|
|
93878
94877
|
const ext = extname6(filePath).toLowerCase();
|
|
@@ -94150,7 +95149,7 @@ function patchCaptionHtml(dir, words) {
|
|
|
94150
95149
|
const wordsJson = JSON.stringify(words, null, 2).replace(/\n/g, "\n ");
|
|
94151
95150
|
let htmlFiles;
|
|
94152
95151
|
try {
|
|
94153
|
-
htmlFiles =
|
|
95152
|
+
htmlFiles = readdirSync9(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join23(e3.parentPath, e3.name));
|
|
94154
95153
|
} catch {
|
|
94155
95154
|
return;
|
|
94156
95155
|
}
|
|
@@ -94640,9 +95639,9 @@ import { execFile as execFile3 } from "child_process";
|
|
|
94640
95639
|
import { createHash as createHash3 } from "crypto";
|
|
94641
95640
|
import {
|
|
94642
95641
|
existsSync as existsSync27,
|
|
94643
|
-
readdirSync as
|
|
95642
|
+
readdirSync as readdirSync10,
|
|
94644
95643
|
readFileSync as readFileSync18,
|
|
94645
|
-
renameSync as
|
|
95644
|
+
renameSync as renameSync5,
|
|
94646
95645
|
statSync as statSync8,
|
|
94647
95646
|
writeFileSync as writeFileSync11
|
|
94648
95647
|
} from "fs";
|
|
@@ -94655,7 +95654,7 @@ function isCoreSkill(name) {
|
|
|
94655
95654
|
function listFilesSorted(dir) {
|
|
94656
95655
|
const out = [];
|
|
94657
95656
|
const walk = (d2) => {
|
|
94658
|
-
for (const name of
|
|
95657
|
+
for (const name of readdirSync10(d2)) {
|
|
94659
95658
|
if (name === ".DS_Store") continue;
|
|
94660
95659
|
const p2 = join26(d2, name);
|
|
94661
95660
|
if (statSync8(p2).isDirectory()) walk(p2);
|
|
@@ -94681,7 +95680,7 @@ function hashSkillBundle(skillDir) {
|
|
|
94681
95680
|
return { hash: h3.digest("hex").slice(0, 16), files: files.length };
|
|
94682
95681
|
}
|
|
94683
95682
|
function buildManifest(skillsRoot, meta) {
|
|
94684
|
-
const names =
|
|
95683
|
+
const names = readdirSync10(skillsRoot).filter((n2) => existsSync27(join26(skillsRoot, n2, "SKILL.md"))).sort();
|
|
94685
95684
|
const skills = {};
|
|
94686
95685
|
for (const name of names) skills[name] = hashSkillBundle(join26(skillsRoot, name));
|
|
94687
95686
|
return { source: meta.source, skills };
|
|
@@ -94697,7 +95696,7 @@ function agentFromDir(dir) {
|
|
|
94697
95696
|
}
|
|
94698
95697
|
function listSubdirs(dir) {
|
|
94699
95698
|
try {
|
|
94700
|
-
return
|
|
95699
|
+
return readdirSync10(dir, { withFileTypes: true }).filter((e3) => e3.isDirectory() || e3.isSymbolicLink()).map((e3) => e3.name);
|
|
94701
95700
|
} catch {
|
|
94702
95701
|
return [];
|
|
94703
95702
|
}
|
|
@@ -94837,7 +95836,7 @@ function pruneOrphanedLockEntries(names, scope, opts = {}) {
|
|
|
94837
95836
|
const mode = statSync8(path2).mode & 511;
|
|
94838
95837
|
const tmp = `${path2}.tmp`;
|
|
94839
95838
|
writeFileSync11(tmp, JSON.stringify(lock, null, 2), { mode });
|
|
94840
|
-
|
|
95839
|
+
renameSync5(tmp, path2);
|
|
94841
95840
|
return pruned;
|
|
94842
95841
|
}
|
|
94843
95842
|
function findRepoManifest(cwd = process.cwd()) {
|
|
@@ -95053,7 +96052,7 @@ var init_agentDirs_generated = __esm({
|
|
|
95053
96052
|
});
|
|
95054
96053
|
|
|
95055
96054
|
// src/utils/skillsMirror.ts
|
|
95056
|
-
import { cpSync, existsSync as existsSync28, mkdirSync as mkdirSync13, readdirSync as
|
|
96055
|
+
import { cpSync, existsSync as existsSync28, mkdirSync as mkdirSync13, readdirSync as readdirSync11, rmSync as rmSync7, symlinkSync } from "fs";
|
|
95057
96056
|
import { homedir as homedir7 } from "os";
|
|
95058
96057
|
import { dirname as dirname11, isAbsolute as isAbsolute7, join as join27, relative as relative7 } from "path";
|
|
95059
96058
|
function resolveBases(home, env) {
|
|
@@ -95069,7 +96068,7 @@ function resolveBases(home, env) {
|
|
|
95069
96068
|
};
|
|
95070
96069
|
}
|
|
95071
96070
|
function listSkillDirs(store) {
|
|
95072
|
-
return
|
|
96071
|
+
return readdirSync11(store, { withFileTypes: true }).filter(
|
|
95073
96072
|
(e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync28(join27(store, e3.name, "SKILL.md"))
|
|
95074
96073
|
).map((e3) => e3.name);
|
|
95075
96074
|
}
|
|
@@ -97981,7 +98980,7 @@ var init_chunk_W2SBTCO2 = __esm({
|
|
|
97981
98980
|
}
|
|
97982
98981
|
});
|
|
97983
98982
|
|
|
97984
|
-
// ../studio-server/dist/chunk-
|
|
98983
|
+
// ../studio-server/dist/chunk-6H3V3WGJ.js
|
|
97985
98984
|
import { existsSync as existsSync33, statSync as statSync10 } from "fs";
|
|
97986
98985
|
import { relative as relative8, resolve as resolve19, sep as sep5 } from "path";
|
|
97987
98986
|
import { execFile as execFile5 } from "child_process";
|
|
@@ -98048,6 +99047,7 @@ async function probeMediaMetadata(filePath, runner = execFileRunner) {
|
|
|
98048
99047
|
"stream=codec_type,codec_name,profile,pix_fmt,color_space,color_transfer,color_primaries,bits_per_raw_sample:stream_disposition=attached_pic",
|
|
98049
99048
|
"-of",
|
|
98050
99049
|
"json",
|
|
99050
|
+
"--",
|
|
98051
99051
|
filePath
|
|
98052
99052
|
],
|
|
98053
99053
|
{ timeout: 15e3, maxBuffer: 1024 * 1024 }
|
|
@@ -98184,8 +99184,8 @@ async function scanProjectMediaCodecMap(projectDir, htmlSources, options = {}) {
|
|
|
98184
99184
|
return map;
|
|
98185
99185
|
}
|
|
98186
99186
|
var execFileRunner, VIDEO_EXT, IMAGE_EXT, AUDIO_EXT, ALPHA_PIX_FMT_RE, BROWSER_HOSTILE_CODECS, PROXY_VARIANT_CONFIG, defaultProbeCache, MAX_PROBE_CACHE_ENTRIES, VIDEO_SRC_RE, PROBE_CONCURRENCY2;
|
|
98187
|
-
var
|
|
98188
|
-
"../studio-server/dist/chunk-
|
|
99187
|
+
var init_chunk_6H3V3WGJ = __esm({
|
|
99188
|
+
"../studio-server/dist/chunk-6H3V3WGJ.js"() {
|
|
98189
99189
|
"use strict";
|
|
98190
99190
|
init_assets();
|
|
98191
99191
|
init_assetResolution();
|
|
@@ -98244,20 +99244,20 @@ var init_chunk_I2USK772 = __esm({
|
|
|
98244
99244
|
}
|
|
98245
99245
|
});
|
|
98246
99246
|
|
|
98247
|
-
// ../studio-server/dist/chunk-
|
|
99247
|
+
// ../studio-server/dist/chunk-ZPI6QXJH.js
|
|
98248
99248
|
import { spawn as spawn8 } from "child_process";
|
|
98249
|
-
import { createHash as createHash6, randomUUID as
|
|
99249
|
+
import { createHash as createHash6, randomUUID as randomUUID6 } from "crypto";
|
|
98250
99250
|
import {
|
|
98251
99251
|
existsSync as existsSync210,
|
|
98252
99252
|
mkdirSync as mkdirSync15,
|
|
98253
99253
|
realpathSync as realpathSync4,
|
|
98254
|
-
renameSync as
|
|
99254
|
+
renameSync as renameSync6,
|
|
98255
99255
|
statSync as statSync22,
|
|
98256
99256
|
unlinkSync as unlinkSync22,
|
|
98257
99257
|
utimesSync as utimesSync2
|
|
98258
99258
|
} from "fs";
|
|
98259
99259
|
import { basename as basename4, dirname as dirname14, isAbsolute as isAbsolute8, join as join29, relative as relative9, resolve as resolve20, sep as sep6 } from "path";
|
|
98260
|
-
import { existsSync as existsSync34, readdirSync as
|
|
99260
|
+
import { existsSync as existsSync34, readdirSync as readdirSync12, statSync as statSync11, unlinkSync as unlinkSync4 } from "fs";
|
|
98261
99261
|
import { extname as extname8, join as join30 } from "path";
|
|
98262
99262
|
function positiveEnvNumber(name, fallback) {
|
|
98263
99263
|
const parsed = Number(process.env[name]);
|
|
@@ -98283,7 +99283,7 @@ function shouldSkipSweep(cacheDir, now, minSweepIntervalMs) {
|
|
|
98283
99283
|
function readCacheInventory(cacheDir, protectedPaths, now, staleTempMs) {
|
|
98284
99284
|
const entries2 = [];
|
|
98285
99285
|
const staleTemps = [];
|
|
98286
|
-
for (const dirent of
|
|
99286
|
+
for (const dirent of readdirSync12(cacheDir, { withFileTypes: true })) {
|
|
98287
99287
|
if (!dirent.isFile()) continue;
|
|
98288
99288
|
const path2 = join30(cacheDir, dirent.name);
|
|
98289
99289
|
const stat3 = statSync11(path2);
|
|
@@ -98309,7 +99309,7 @@ function evictCacheEntries(entries2, staleTemps, now, maxIdleMs, maxBytes) {
|
|
|
98309
99309
|
let bytesAfter = bytesBefore;
|
|
98310
99310
|
const removed = [];
|
|
98311
99311
|
const remove2 = (entry, countsTowardBudget) => {
|
|
98312
|
-
|
|
99312
|
+
unlinkSync4(entry.path);
|
|
98313
99313
|
removed.push(entry.path);
|
|
98314
99314
|
if (countsTowardBudget) bytesAfter -= entry.size;
|
|
98315
99315
|
};
|
|
@@ -98570,10 +99570,10 @@ async function transcodeToCache(absoluteSourcePath, cachePath2, variant) {
|
|
|
98570
99570
|
if (existsSync210(cachePath2)) return cachePath2;
|
|
98571
99571
|
const cacheDir = dirname14(cachePath2);
|
|
98572
99572
|
mkdirSync15(cacheDir, { recursive: true });
|
|
98573
|
-
const tempPath = join29(cacheDir, `.tmp-${
|
|
99573
|
+
const tempPath = join29(cacheDir, `.tmp-${randomUUID6()}-${basename4(cachePath2)}`);
|
|
98574
99574
|
try {
|
|
98575
99575
|
await runFfmpeg2(absoluteSourcePath, tempPath, variant);
|
|
98576
|
-
|
|
99576
|
+
renameSync6(tempPath, cachePath2);
|
|
98577
99577
|
maintainProxyCache(cacheDir);
|
|
98578
99578
|
return cachePath2;
|
|
98579
99579
|
} finally {
|
|
@@ -98610,10 +99610,10 @@ async function resolveProxy(projectDir, absoluteSourcePath, variant = "h264") {
|
|
|
98610
99610
|
return promise;
|
|
98611
99611
|
}
|
|
98612
99612
|
var DEFAULT_MAX_BYTES, DEFAULT_STALE_TEMP_MS, DEFAULT_MIN_SWEEP_INTERVAL_MS, PROXY_EXTENSIONS, lastSweepAt, PROXY_PARAMS_VERSION, CACHE_DIR_NAME, MAX_CONCURRENT_TRANSCODES, MAX_QUEUED_TRANSCODES, STDERR_TAIL_MAX_CHARS, TRANSCODE_TIMEOUT_MS, FAILURE_CACHE_TTL_MS, MAX_FAILURE_CACHE_ENTRIES, DEFAULT_PROXY_WAIT_TIMEOUT_MS, ProxyTranscodeError, FfmpegUnavailableError, FfmpegMissingFilterError, ProxyCapacityError, ProxySourceOutsideProjectError, ProxyWaitTimeoutError, activeTranscodes, waitQueue, inFlight, failedTranscodes, hdrFilterCheck;
|
|
98613
|
-
var
|
|
98614
|
-
"../studio-server/dist/chunk-
|
|
99613
|
+
var init_chunk_ZPI6QXJH = __esm({
|
|
99614
|
+
"../studio-server/dist/chunk-ZPI6QXJH.js"() {
|
|
98615
99615
|
"use strict";
|
|
98616
|
-
|
|
99616
|
+
init_chunk_6H3V3WGJ();
|
|
98617
99617
|
init_ffBinaries();
|
|
98618
99618
|
DEFAULT_MAX_BYTES = 10 * 1024 * 1024 * 1024;
|
|
98619
99619
|
DEFAULT_STALE_TEMP_MS = 60 * 60 * 1e3;
|
|
@@ -98681,7 +99681,7 @@ var init_chunk_IQAVZUQP = __esm({
|
|
|
98681
99681
|
}
|
|
98682
99682
|
});
|
|
98683
99683
|
|
|
98684
|
-
// ../studio-server/dist/chunk-
|
|
99684
|
+
// ../studio-server/dist/chunk-LHYV3WLZ.js
|
|
98685
99685
|
import { resolve as resolve21 } from "path";
|
|
98686
99686
|
function isAutoProxyEnabled(adapter2) {
|
|
98687
99687
|
return adapter2.autoProxy !== false;
|
|
@@ -98728,11 +99728,11 @@ async function injectMediaCodecMap(html, adapter2, projectDir, compSrcPath, prob
|
|
|
98728
99728
|
if (!isAutoProxyEnabled(adapter2)) return html;
|
|
98729
99729
|
return injectMediaCodecMapIntoHtml(html, projectDir, [{ html, compSrcPath }], probeCache);
|
|
98730
99730
|
}
|
|
98731
|
-
var
|
|
98732
|
-
"../studio-server/dist/chunk-
|
|
99731
|
+
var init_chunk_LHYV3WLZ = __esm({
|
|
99732
|
+
"../studio-server/dist/chunk-LHYV3WLZ.js"() {
|
|
98733
99733
|
"use strict";
|
|
98734
|
-
|
|
98735
|
-
|
|
99734
|
+
init_chunk_ZPI6QXJH();
|
|
99735
|
+
init_chunk_6H3V3WGJ();
|
|
98736
99736
|
}
|
|
98737
99737
|
});
|
|
98738
99738
|
|
|
@@ -102421,7 +103421,7 @@ var init_gsapWriterAcorn = __esm({
|
|
|
102421
103421
|
|
|
102422
103422
|
// ../core/dist/fonts/systemFontLocator.js
|
|
102423
103423
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
102424
|
-
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as
|
|
103424
|
+
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync13, realpathSync as realpathSync5 } from "fs";
|
|
102425
103425
|
import { homedir as homedir9, platform as platform5 } from "os";
|
|
102426
103426
|
import { join as join31, resolve as resolve22 } from "path";
|
|
102427
103427
|
function getAllowedFontDirs() {
|
|
@@ -102516,7 +103516,7 @@ function collectFontFileEntries(dir, depth = 0) {
|
|
|
102516
103516
|
return [];
|
|
102517
103517
|
const entries2 = [];
|
|
102518
103518
|
try {
|
|
102519
|
-
for (const entry of
|
|
103519
|
+
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
102520
103520
|
const fullPath = join31(dir, entry.name);
|
|
102521
103521
|
if (entry.isDirectory()) {
|
|
102522
103522
|
entries2.push(...collectFontFileEntries(fullPath, depth + 1));
|
|
@@ -105455,7 +106455,7 @@ import { Hono as Hono2 } from "hono";
|
|
|
105455
106455
|
import { readFile as readFile2 } from "fs/promises";
|
|
105456
106456
|
import { join as join210 } from "path";
|
|
105457
106457
|
import { join as join32 } from "path";
|
|
105458
|
-
import { readdirSync as
|
|
106458
|
+
import { readdirSync as readdirSync14 } from "fs";
|
|
105459
106459
|
import { createHash as createHash7 } from "crypto";
|
|
105460
106460
|
import { lstatSync as lstatSync4, readFileSync as readFileSync21, readdirSync as readdirSync22 } from "fs";
|
|
105461
106461
|
import { extname as extname9, isAbsolute as isAbsolute9, relative as relative10, resolve as resolve23 } from "path";
|
|
@@ -105473,7 +106473,7 @@ import {
|
|
|
105473
106473
|
unlinkSync as unlinkSync23,
|
|
105474
106474
|
rmSync as rmSync22,
|
|
105475
106475
|
statSync as statSync12,
|
|
105476
|
-
renameSync as
|
|
106476
|
+
renameSync as renameSync7,
|
|
105477
106477
|
readdirSync as readdirSync42
|
|
105478
106478
|
} from "fs";
|
|
105479
106479
|
import { resolve as resolve32, dirname as dirname22, join as join62 } from "path";
|
|
@@ -105484,10 +106484,10 @@ import { spawnSync } from "child_process";
|
|
|
105484
106484
|
import { mkdtempSync as mkdtempSync3, rmSync as rmSync9, writeFileSync as writeFileSync22 } from "fs";
|
|
105485
106485
|
import { tmpdir as tmpdir4 } from "os";
|
|
105486
106486
|
import { basename as basename5, join as join42 } from "path";
|
|
105487
|
-
import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as readFileSync32, unlinkSync as
|
|
106487
|
+
import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as readFileSync32, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "fs";
|
|
105488
106488
|
import { Buffer as Buffer2 } from "buffer";
|
|
105489
106489
|
import { join as join52, relative as relative22 } from "path";
|
|
105490
|
-
import { createHash as createHash22, randomUUID as
|
|
106490
|
+
import { createHash as createHash22, randomUUID as randomUUID7 } from "crypto";
|
|
105491
106491
|
import { existsSync as existsSync37, readFileSync as readFileSync42, realpathSync as realpathSync6 } from "fs";
|
|
105492
106492
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
105493
106493
|
import { dirname as dirname15, relative as relative32, resolve as resolve24, sep as sep7 } from "path";
|
|
@@ -105532,7 +106532,7 @@ function isInHiddenOrVendorDir(relPath) {
|
|
|
105532
106532
|
}
|
|
105533
106533
|
function walkDir(dir, prefix = "") {
|
|
105534
106534
|
const files = [];
|
|
105535
|
-
for (const entry of
|
|
106535
|
+
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
105536
106536
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
105537
106537
|
if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel)) continue;
|
|
105538
106538
|
if (entry.isDirectory()) {
|
|
@@ -105838,6 +106838,7 @@ function validateUploadedMedia(filePath, runner = spawnSync) {
|
|
|
105838
106838
|
"stream=codec_type",
|
|
105839
106839
|
"-of",
|
|
105840
106840
|
"json",
|
|
106841
|
+
"--",
|
|
105841
106842
|
filePath
|
|
105842
106843
|
]);
|
|
105843
106844
|
if (result.error?.code === "ENOENT") {
|
|
@@ -105929,7 +106930,7 @@ function pruneBackups(backupDir, backupKey, keepPerFile) {
|
|
|
105929
106930
|
});
|
|
105930
106931
|
for (const file of matches2.slice(keep)) {
|
|
105931
106932
|
try {
|
|
105932
|
-
|
|
106933
|
+
unlinkSync5(file);
|
|
105933
106934
|
} catch {
|
|
105934
106935
|
}
|
|
105935
106936
|
}
|
|
@@ -105939,7 +106940,7 @@ function fileContentVersion(content) {
|
|
|
105939
106940
|
}
|
|
105940
106941
|
function createWriteToken(requestToken) {
|
|
105941
106942
|
const token = requestToken?.trim();
|
|
105942
|
-
return token && token.length <= 200 ? token :
|
|
106943
|
+
return token && token.length <= 200 ? token : randomUUID7();
|
|
105943
106944
|
}
|
|
105944
106945
|
function recordFileWriteReceipt(absPath, receipt) {
|
|
105945
106946
|
const now = Date.now();
|
|
@@ -108048,7 +109049,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
108048
109049
|
return c3.json({ error: "already exists" }, 409);
|
|
108049
109050
|
}
|
|
108050
109051
|
ensureDir(newAbs);
|
|
108051
|
-
|
|
109052
|
+
renameSync7(res.absPath, newAbs);
|
|
108052
109053
|
const updatedFiles = updateReferences(res.project.dir, res.filePath, body.newPath);
|
|
108053
109054
|
return c3.json({ ok: true, path: body.newPath, updatedReferences: updatedFiles });
|
|
108054
109055
|
});
|
|
@@ -109650,9 +110651,9 @@ var init_dist9 = __esm({
|
|
|
109650
110651
|
init_chunk_X62ASOGO();
|
|
109651
110652
|
init_chunk_VPA335OG();
|
|
109652
110653
|
init_chunk_W2SBTCO2();
|
|
109653
|
-
|
|
109654
|
-
|
|
109655
|
-
|
|
110654
|
+
init_chunk_LHYV3WLZ();
|
|
110655
|
+
init_chunk_ZPI6QXJH();
|
|
110656
|
+
init_chunk_6H3V3WGJ();
|
|
109656
110657
|
init_chunk_6XMC64FJ();
|
|
109657
110658
|
init_chunk_4ETS2LXI();
|
|
109658
110659
|
init_dist3();
|
|
@@ -110193,7 +111194,7 @@ __export(manager_exports2, {
|
|
|
110193
111194
|
withInstallLock: () => withInstallLock
|
|
110194
111195
|
});
|
|
110195
111196
|
import { execSync as execSync4, spawnSync as spawnSync2 } from "child_process";
|
|
110196
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readdirSync as
|
|
111197
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readdirSync as readdirSync15, rmSync as rmSync10, statSync as statSync13, utimesSync as utimesSync3 } from "fs";
|
|
110197
111198
|
import { basename as basename6 } from "path";
|
|
110198
111199
|
import { homedir as homedir11 } from "os";
|
|
110199
111200
|
import { join as join35 } from "path";
|
|
@@ -110392,7 +111393,7 @@ function findFromPuppeteerCache() {
|
|
|
110392
111393
|
if (!executable) return void 0;
|
|
110393
111394
|
let versions;
|
|
110394
111395
|
try {
|
|
110395
|
-
versions = [...
|
|
111396
|
+
versions = [...readdirSync15(PUPPETEER_CACHE_DIR)].sort(compareVersionDirsDescending);
|
|
110396
111397
|
} catch {
|
|
110397
111398
|
return void 0;
|
|
110398
111399
|
}
|
|
@@ -111093,7 +112094,7 @@ var init_logger = __esm({
|
|
|
111093
112094
|
// ../producer/src/services/fileServer.ts
|
|
111094
112095
|
import { Hono as Hono3 } from "hono";
|
|
111095
112096
|
import { serve as serve2 } from "@hono/node-server";
|
|
111096
|
-
import { existsSync as existsSync40, realpathSync as realpathSync7, statSync as statSync14, createReadStream as
|
|
112097
|
+
import { existsSync as existsSync40, realpathSync as realpathSync7, statSync as statSync14, createReadStream as createReadStream3 } from "fs";
|
|
111097
112098
|
import { readFile as readFile3 } from "fs/promises";
|
|
111098
112099
|
import { Readable as Readable2 } from "stream";
|
|
111099
112100
|
import { join as join36, extname as extname10, resolve as resolve27, sep as sep9 } from "path";
|
|
@@ -111490,7 +112491,7 @@ function createFileServer2(options) {
|
|
|
111490
112491
|
if (rangeRequest.kind === "satisfiable") {
|
|
111491
112492
|
const { start, end } = rangeRequest;
|
|
111492
112493
|
const length = end - start + 1;
|
|
111493
|
-
const stream2 =
|
|
112494
|
+
const stream2 = createReadStream3(filePath, { start, end });
|
|
111494
112495
|
const webStream2 = Readable2.toWeb(stream2);
|
|
111495
112496
|
return new Response(webStream2, {
|
|
111496
112497
|
status: 206,
|
|
@@ -111502,7 +112503,7 @@ function createFileServer2(options) {
|
|
|
111502
112503
|
}
|
|
111503
112504
|
});
|
|
111504
112505
|
}
|
|
111505
|
-
const stream =
|
|
112506
|
+
const stream = createReadStream3(filePath);
|
|
111506
112507
|
const webStream = Readable2.toWeb(stream);
|
|
111507
112508
|
return new Response(webStream, {
|
|
111508
112509
|
status: 200,
|
|
@@ -112144,8 +113145,8 @@ import {
|
|
|
112144
113145
|
mkdtempSync as mkdtempSync4,
|
|
112145
113146
|
openSync as openSync5,
|
|
112146
113147
|
readSync as readSync2,
|
|
112147
|
-
readdirSync as
|
|
112148
|
-
renameSync as
|
|
113148
|
+
readdirSync as readdirSync16,
|
|
113149
|
+
renameSync as renameSync8,
|
|
112149
113150
|
rmSync as rmSync12
|
|
112150
113151
|
} from "fs";
|
|
112151
113152
|
import { basename as basename9, dirname as dirname18, extname as extname11, join as join39, resolve as resolve29 } from "path";
|
|
@@ -112170,7 +113171,7 @@ function assertReadableNonEmptyFile(path2) {
|
|
|
112170
113171
|
function collectDirectoryFiles(root) {
|
|
112171
113172
|
const files = [];
|
|
112172
113173
|
const visit = (directory) => {
|
|
112173
|
-
for (const entry of
|
|
113174
|
+
for (const entry of readdirSync16(directory, { withFileTypes: true })) {
|
|
112174
113175
|
const path2 = join39(directory, entry.name);
|
|
112175
113176
|
if (entry.isDirectory()) visit(path2);
|
|
112176
113177
|
else if (entry.isFile()) files.push(path2);
|
|
@@ -112185,7 +113186,7 @@ var init_artifactTransaction = __esm({
|
|
|
112185
113186
|
"use strict";
|
|
112186
113187
|
defaultFileSystem = {
|
|
112187
113188
|
existsSync: existsSync43,
|
|
112188
|
-
renameSync:
|
|
113189
|
+
renameSync: renameSync8,
|
|
112189
113190
|
rmSync: rmSync12
|
|
112190
113191
|
};
|
|
112191
113192
|
ArtifactTransaction = class {
|
|
@@ -113444,9 +114445,11 @@ var init_ffprobe2 = __esm({
|
|
|
113444
114445
|
// ../producer/src/utils/urlDownloader.ts
|
|
113445
114446
|
var urlDownloader_exports = {};
|
|
113446
114447
|
__export(urlDownloader_exports, {
|
|
113447
|
-
assertPublicHttpsUrl: () => assertPublicHttpsUrl,
|
|
113448
114448
|
downloadToTemp: () => downloadToTemp,
|
|
113449
|
-
|
|
114449
|
+
fetchPublicHttpsText: () => fetchPublicHttpsText,
|
|
114450
|
+
isHttpUrl: () => isHttpUrl,
|
|
114451
|
+
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
114452
|
+
writeUrlDownloadTelemetry: () => writeUrlDownloadTelemetry
|
|
113450
114453
|
});
|
|
113451
114454
|
var init_urlDownloader2 = __esm({
|
|
113452
114455
|
"../producer/src/utils/urlDownloader.ts"() {
|
|
@@ -116632,7 +117635,7 @@ __export(fontCompression_exports, {
|
|
|
116632
117635
|
fontToDataUri: () => fontToDataUri
|
|
116633
117636
|
});
|
|
116634
117637
|
import { createHash as createHash10 } from "crypto";
|
|
116635
|
-
import { existsSync as existsSync44, mkdirSync as mkdirSync19, readFileSync as readFileSync26, renameSync as
|
|
117638
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync19, readFileSync as readFileSync26, renameSync as renameSync9, rmSync as rmSync13, writeFileSync as writeFileSync15 } from "fs";
|
|
116636
117639
|
import { homedir as homedir12, tmpdir as tmpdir5 } from "os";
|
|
116637
117640
|
import { dirname as dirname19, join as join41 } from "path";
|
|
116638
117641
|
async function compressToWoff2(input2) {
|
|
@@ -116663,7 +117666,7 @@ function cacheCompression(path2, compressed) {
|
|
|
116663
117666
|
try {
|
|
116664
117667
|
mkdirSync19(dirname19(path2), { recursive: true });
|
|
116665
117668
|
writeFileSync15(tmpPath, compressed, { flag: "wx", mode: 420 });
|
|
116666
|
-
|
|
117669
|
+
renameSync9(tmpPath, path2);
|
|
116667
117670
|
} catch {
|
|
116668
117671
|
} finally {
|
|
116669
117672
|
try {
|
|
@@ -117488,7 +118491,7 @@ import {
|
|
|
117488
118491
|
existsSync as existsSync46,
|
|
117489
118492
|
mkdirSync as mkdirSync21,
|
|
117490
118493
|
readFileSync as readFileSync28,
|
|
117491
|
-
renameSync as
|
|
118494
|
+
renameSync as renameSync10,
|
|
117492
118495
|
rmSync as rmSync14,
|
|
117493
118496
|
statSync as statSync15
|
|
117494
118497
|
} from "fs";
|
|
@@ -117661,7 +118664,7 @@ async function ensurePreparedWebm(input2) {
|
|
|
117661
118664
|
throw new Error("Animated GIF transcode produced an empty output");
|
|
117662
118665
|
}
|
|
117663
118666
|
if (!isUsableFile(input2.cachePath)) {
|
|
117664
|
-
|
|
118667
|
+
renameSync10(tmpPath, input2.cachePath);
|
|
117665
118668
|
} else {
|
|
117666
118669
|
rmSync14(tmpPath, { force: true });
|
|
117667
118670
|
}
|
|
@@ -117980,8 +118983,11 @@ var init_assetMediaType = __esm({
|
|
|
117980
118983
|
});
|
|
117981
118984
|
|
|
117982
118985
|
// ../producer/src/services/htmlCompiler.ts
|
|
117983
|
-
import { createReadStream as
|
|
118986
|
+
import { createReadStream as createReadStream4, existsSync as existsSync48, mkdirSync as mkdirSync23, readFileSync as readFileSync29 } from "fs";
|
|
117984
118987
|
import { join as join45, dirname as dirname21, resolve as resolve31, basename as basename10 } from "path";
|
|
118988
|
+
function logRemoteDownloadTelemetry(event) {
|
|
118989
|
+
defaultLogger.info("[Compiler] Remote asset download integrity", { ...event });
|
|
118990
|
+
}
|
|
117985
118991
|
function parseSubCompHtmlForValidity(html) {
|
|
117986
118992
|
return parseHTML(html).document;
|
|
117987
118993
|
}
|
|
@@ -118141,7 +119147,9 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
118141
119147
|
if (isHttpUrl(src)) {
|
|
118142
119148
|
if (!existsSync48(downloadDir)) mkdirSync23(downloadDir, { recursive: true });
|
|
118143
119149
|
try {
|
|
118144
|
-
filePath = await downloadToTemp(src, downloadDir
|
|
119150
|
+
filePath = await downloadToTemp(src, downloadDir, void 0, void 0, void 0, {
|
|
119151
|
+
onTelemetry: logRemoteDownloadTelemetry
|
|
119152
|
+
});
|
|
118145
119153
|
} catch {
|
|
118146
119154
|
return { duration: 0, resolvedPath: src };
|
|
118147
119155
|
}
|
|
@@ -118669,12 +119677,17 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
|
|
|
118669
119677
|
await Promise.all(
|
|
118670
119678
|
[...urlSet].map(async (url) => {
|
|
118671
119679
|
try {
|
|
118672
|
-
const localPath = await downloadToTemp(url, remoteDir
|
|
119680
|
+
const localPath = await downloadToTemp(url, remoteDir, void 0, void 0, void 0, {
|
|
119681
|
+
onTelemetry: logRemoteDownloadTelemetry
|
|
119682
|
+
});
|
|
118673
119683
|
urlToLocal.set(url, localPath);
|
|
118674
119684
|
} catch (err) {
|
|
118675
|
-
|
|
118676
|
-
|
|
118677
|
-
|
|
119685
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
119686
|
+
defaultLogger.warn(`[Compiler] ${warnLabel} \u2014 using original URL as fallback.`, {
|
|
119687
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119688
|
+
host: identity.host,
|
|
119689
|
+
error: err instanceof Error ? err.message : String(err)
|
|
119690
|
+
});
|
|
118678
119691
|
}
|
|
118679
119692
|
})
|
|
118680
119693
|
);
|
|
@@ -118705,7 +119718,7 @@ async function localizeRemoteMediaSources(html, downloadDir) {
|
|
|
118705
119718
|
urlSet,
|
|
118706
119719
|
html,
|
|
118707
119720
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118708
|
-
"Remote media download failed
|
|
119721
|
+
"Remote media download failed",
|
|
118709
119722
|
"Localized remote media source(s)"
|
|
118710
119723
|
);
|
|
118711
119724
|
}
|
|
@@ -118720,7 +119733,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
|
|
|
118720
119733
|
urlSet,
|
|
118721
119734
|
html,
|
|
118722
119735
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118723
|
-
"Remote image download failed
|
|
119736
|
+
"Remote image download failed",
|
|
118724
119737
|
"Localized remote image source(s)"
|
|
118725
119738
|
);
|
|
118726
119739
|
}
|
|
@@ -118735,7 +119748,7 @@ async function localizeRemoteBackgroundImages(html, downloadDir) {
|
|
|
118735
119748
|
urlSet,
|
|
118736
119749
|
html,
|
|
118737
119750
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118738
|
-
"Remote background-image download failed
|
|
119751
|
+
"Remote background-image download failed",
|
|
118739
119752
|
"Localized remote background-image(s)",
|
|
118740
119753
|
// Quoted url('..')/url("..") are rewritten by downloadAndRewriteUrls' default
|
|
118741
119754
|
// replaceAll; this handles the unquoted url(https://..) form.
|
|
@@ -118751,40 +119764,18 @@ function isGoogleFontsUrl(href) {
|
|
|
118751
119764
|
}
|
|
118752
119765
|
}
|
|
118753
119766
|
async function fetchExternalStylesheetCss(href) {
|
|
119767
|
+
const identity = safeDownloadUrlIdentity(href);
|
|
118754
119768
|
try {
|
|
118755
|
-
|
|
118756
|
-
|
|
118757
|
-
|
|
118758
|
-
}
|
|
118759
|
-
try {
|
|
118760
|
-
const response = await fetch(href, {
|
|
118761
|
-
signal: AbortSignal.timeout(15e3)
|
|
119769
|
+
return await fetchPublicHttpsText(href, {
|
|
119770
|
+
maxBytes: MAX_STYLESHEET_BYTES,
|
|
119771
|
+
timeoutMs: 15e3
|
|
118762
119772
|
});
|
|
118763
|
-
if (!response.ok) {
|
|
118764
|
-
defaultLogger.warn(
|
|
118765
|
-
`[Compiler] External stylesheet fetch failed for ${href} \u2014 HTTP ${response.status}`
|
|
118766
|
-
);
|
|
118767
|
-
return null;
|
|
118768
|
-
}
|
|
118769
|
-
const contentLength = response.headers.get("content-length");
|
|
118770
|
-
if (contentLength && parseInt(contentLength, 10) > MAX_STYLESHEET_BYTES) {
|
|
118771
|
-
defaultLogger.warn(
|
|
118772
|
-
`[Compiler] External stylesheet too large (${contentLength} bytes): ${href}`
|
|
118773
|
-
);
|
|
118774
|
-
return null;
|
|
118775
|
-
}
|
|
118776
|
-
const text2 = await response.text();
|
|
118777
|
-
if (text2.length > MAX_STYLESHEET_BYTES) {
|
|
118778
|
-
defaultLogger.warn(
|
|
118779
|
-
`[Compiler] External stylesheet too large (${text2.length} bytes): ${href}`
|
|
118780
|
-
);
|
|
118781
|
-
return null;
|
|
118782
|
-
}
|
|
118783
|
-
return text2;
|
|
118784
119773
|
} catch (err) {
|
|
118785
|
-
defaultLogger.warn(
|
|
118786
|
-
|
|
118787
|
-
|
|
119774
|
+
defaultLogger.warn("[Compiler] External stylesheet fetch failed \u2014 preserving link tag.", {
|
|
119775
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119776
|
+
host: identity.host,
|
|
119777
|
+
error: err instanceof Error ? err.message : String(err)
|
|
119778
|
+
});
|
|
118788
119779
|
return null;
|
|
118789
119780
|
}
|
|
118790
119781
|
}
|
|
@@ -118840,13 +119831,16 @@ async function inlineExternalFontStylesheets(html) {
|
|
|
118840
119831
|
if (css === null) continue;
|
|
118841
119832
|
const fontFaceBlocks = extractFontFaceBlocks(css);
|
|
118842
119833
|
if (fontFaceBlocks.length === 0) continue;
|
|
118843
|
-
const
|
|
119834
|
+
const identity = safeDownloadUrlIdentity(href);
|
|
119835
|
+
const inlineStyle = `<style>/* Inlined external font stylesheet */
|
|
118844
119836
|
${fontFaceBlocks.join("\n")}
|
|
118845
119837
|
</style>`;
|
|
118846
119838
|
result = result.replace(fullMatch, inlineStyle);
|
|
118847
|
-
defaultLogger.info(
|
|
118848
|
-
|
|
118849
|
-
|
|
119839
|
+
defaultLogger.info("[Compiler] Inlined external @font-face rule(s)", {
|
|
119840
|
+
count: fontFaceBlocks.length,
|
|
119841
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119842
|
+
host: identity.host
|
|
119843
|
+
});
|
|
118850
119844
|
}
|
|
118851
119845
|
return result;
|
|
118852
119846
|
}
|
|
@@ -118887,7 +119881,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
|
|
|
118887
119881
|
urlSet,
|
|
118888
119882
|
processed,
|
|
118889
119883
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118890
|
-
"Remote font download failed
|
|
119884
|
+
"Remote font download failed",
|
|
118891
119885
|
"Localized remote font face(s)",
|
|
118892
119886
|
(h3, url, relPath) => h3.replaceAll(`url(${url})`, `url("${relPath}")`)
|
|
118893
119887
|
);
|
|
@@ -118895,7 +119889,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
|
|
|
118895
119889
|
async function readLocalFont(absPath) {
|
|
118896
119890
|
const chunks = [];
|
|
118897
119891
|
let totalBytes = 0;
|
|
118898
|
-
for await (const chunk of
|
|
119892
|
+
for await (const chunk of createReadStream4(absPath)) {
|
|
118899
119893
|
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
118900
119894
|
totalBytes += buffer.length;
|
|
118901
119895
|
if (totalBytes > MAX_LOCAL_FONT_DATA_URI_BYTES) {
|
|
@@ -119799,9 +120793,9 @@ async function runProbeStage(input2) {
|
|
|
119799
120793
|
if (probeSession.launchCaptureMode === "beginframe") {
|
|
119800
120794
|
const probeTimeoutMs = Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) > 0 ? Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) : 3e4;
|
|
119801
120795
|
const livenessStart = Date.now();
|
|
119802
|
-
const probeTick =
|
|
119803
|
-
|
|
119804
|
-
probeSession.
|
|
120796
|
+
const probeTick = deriveBeginFrameProbeTimeTicks(
|
|
120797
|
+
probeSession.beginFrameTimeTicks,
|
|
120798
|
+
probeSession.beginFrameIntervalMs
|
|
119805
120799
|
);
|
|
119806
120800
|
const alive = await probeBeginFrameLiveness(
|
|
119807
120801
|
probeSession.page,
|
|
@@ -123319,7 +124313,7 @@ var init_gifEncodeArgs = __esm({
|
|
|
123319
124313
|
});
|
|
123320
124314
|
|
|
123321
124315
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
123322
|
-
import { copyFileSync as copyFileSync5, existsSync as existsSync53, mkdirSync as mkdirSync26, readdirSync as
|
|
124316
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync53, mkdirSync as mkdirSync26, readdirSync as readdirSync17, rmSync as rmSync16, statSync as statSync16 } from "fs";
|
|
123323
124317
|
import { dirname as dirname24, join as join59 } from "path";
|
|
123324
124318
|
function resolveGifLoop(loop) {
|
|
123325
124319
|
const resolved2 = loop ?? 0;
|
|
@@ -123330,7 +124324,7 @@ function resolveGifLoop(loop) {
|
|
|
123330
124324
|
}
|
|
123331
124325
|
async function encodeGifFromDir(framesDir, framePattern, outputPath, input2) {
|
|
123332
124326
|
const startTime = Date.now();
|
|
123333
|
-
const files =
|
|
124327
|
+
const files = readdirSync17(framesDir).filter((file) => file.match(/\.(jpg|jpeg|png)$/i));
|
|
123334
124328
|
const frameCount = files.length;
|
|
123335
124329
|
if (frameCount === 0) {
|
|
123336
124330
|
return {
|
|
@@ -123419,7 +124413,7 @@ async function runEncodeStage(input2) {
|
|
|
123419
124413
|
if (isPngSequence) {
|
|
123420
124414
|
updateJobStatus(job, "encoding", "Writing PNG sequence", 75, onProgress);
|
|
123421
124415
|
if (!existsSync53(outputPath)) mkdirSync26(outputPath, { recursive: true });
|
|
123422
|
-
const captured =
|
|
124416
|
+
const captured = readdirSync17(framesDir).filter((name) => name.endsWith(".png")).sort();
|
|
123423
124417
|
if (captured.length === 0) {
|
|
123424
124418
|
throw new Error(
|
|
123425
124419
|
`[Render] png-sequence output requested but no PNGs were captured to ${framesDir}`
|
|
@@ -123582,6 +124576,10 @@ function buildPadTrimAudioPlan(audioPath, outputPath, sourceDurationSeconds, tar
|
|
|
123582
124576
|
function formatSeconds(sec) {
|
|
123583
124577
|
return sec.toFixed(6);
|
|
123584
124578
|
}
|
|
124579
|
+
function sanitizeProbeFailure(reason, paths) {
|
|
124580
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
124581
|
+
return redactTelemetryString(redactKnownPaths(message, paths));
|
|
124582
|
+
}
|
|
123585
124583
|
async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
123586
124584
|
const probeVideo2 = input2.probeVideoFrameInfo ?? ((videoPath) => defaultProbeVideoFrameInfo(videoPath, input2.signal));
|
|
123587
124585
|
const probeAudio = input2.probeAudioInfo ?? defaultProbeAudioInfo;
|
|
@@ -123590,12 +124588,16 @@ async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
|
123590
124588
|
probeVideo2(input2.videoPath),
|
|
123591
124589
|
probeAudio(input2.audioPath, input2.signal)
|
|
123592
124590
|
]);
|
|
124591
|
+
const probePaths = [input2.videoPath, input2.audioPath, input2.outputPath];
|
|
123593
124592
|
if (videoResult.status === "rejected") {
|
|
123594
124593
|
return failResult(
|
|
123595
124594
|
input2.outputPath,
|
|
123596
124595
|
0,
|
|
123597
124596
|
audioResult.status === "fulfilled" ? audioResult.value.durationSeconds : 0,
|
|
123598
|
-
`audioPadTrim: failed to probe video: ${
|
|
124597
|
+
`audioPadTrim: failed to probe video: ${sanitizeProbeFailure(
|
|
124598
|
+
videoResult.reason,
|
|
124599
|
+
probePaths
|
|
124600
|
+
)}`
|
|
123599
124601
|
);
|
|
123600
124602
|
}
|
|
123601
124603
|
if (audioResult.status === "rejected") {
|
|
@@ -123603,7 +124605,10 @@ async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
|
123603
124605
|
input2.outputPath,
|
|
123604
124606
|
0,
|
|
123605
124607
|
0,
|
|
123606
|
-
`audioPadTrim: failed to probe audio: ${
|
|
124608
|
+
`audioPadTrim: failed to probe audio: ${sanitizeProbeFailure(
|
|
124609
|
+
audioResult.reason,
|
|
124610
|
+
probePaths
|
|
124611
|
+
)}`
|
|
123607
124612
|
);
|
|
123608
124613
|
}
|
|
123609
124614
|
const videoInfo = videoResult.value;
|
|
@@ -123678,6 +124683,7 @@ async function defaultProbeVideoFrameInfo(videoPath, signal) {
|
|
|
123678
124683
|
"stream=nb_frames,r_frame_rate",
|
|
123679
124684
|
"-of",
|
|
123680
124685
|
"json",
|
|
124686
|
+
"--",
|
|
123681
124687
|
videoPath
|
|
123682
124688
|
],
|
|
123683
124689
|
signal
|
|
@@ -123698,6 +124704,7 @@ async function defaultProbeVideoFrameInfo(videoPath, signal) {
|
|
|
123698
124704
|
"stream=nb_read_packets,r_frame_rate",
|
|
123699
124705
|
"-of",
|
|
123700
124706
|
"json",
|
|
124707
|
+
"--",
|
|
123701
124708
|
videoPath
|
|
123702
124709
|
],
|
|
123703
124710
|
signal
|
|
@@ -123737,7 +124744,10 @@ async function defaultRunFfmpeg(args, signal) {
|
|
|
123737
124744
|
};
|
|
123738
124745
|
}
|
|
123739
124746
|
async function runFfprobeJson(args, signal) {
|
|
123740
|
-
|
|
124747
|
+
if (!args.includes("--")) {
|
|
124748
|
+
throw new Error('[audioPadTrim] ffprobe args must terminate options with "--".');
|
|
124749
|
+
}
|
|
124750
|
+
const proc = spawn11(getFfprobeBinary(), args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
123741
124751
|
trackChildProcess(proc);
|
|
123742
124752
|
let stdout2 = "";
|
|
123743
124753
|
proc.stdout.on("data", (data2) => {
|
|
@@ -123755,7 +124765,9 @@ async function runFfprobeJson(args, signal) {
|
|
|
123755
124765
|
throw outcome.error ?? new Error(outcome.stderr);
|
|
123756
124766
|
}
|
|
123757
124767
|
if (outcome.reason !== "exit" || outcome.exitCode !== 0) {
|
|
123758
|
-
|
|
124768
|
+
const probed = args[args.length - 1];
|
|
124769
|
+
const scrubbed = redactKnownPaths(outcome.stderr, probed === void 0 ? [] : [probed]);
|
|
124770
|
+
throw new Error(`ffprobe ${outcome.reason}: ${redactTelemetryString(scrubbed, 2e3)}`);
|
|
123759
124771
|
}
|
|
123760
124772
|
try {
|
|
123761
124773
|
return JSON.parse(stdout2);
|
|
@@ -123768,6 +124780,7 @@ var init_audioPadTrim = __esm({
|
|
|
123768
124780
|
"../producer/src/services/render/audioPadTrim.ts"() {
|
|
123769
124781
|
"use strict";
|
|
123770
124782
|
init_src();
|
|
124783
|
+
init_dist3();
|
|
123771
124784
|
AUDIO_DURATION_TOLERANCE_SECONDS = 1e-3;
|
|
123772
124785
|
}
|
|
123773
124786
|
});
|
|
@@ -123845,7 +124858,7 @@ import {
|
|
|
123845
124858
|
mkdirSync as mkdirSync27,
|
|
123846
124859
|
mkdtempSync as mkdtempSync7,
|
|
123847
124860
|
readFileSync as readFileSync31,
|
|
123848
|
-
readdirSync as
|
|
124861
|
+
readdirSync as readdirSync18,
|
|
123849
124862
|
rmSync as rmSync18,
|
|
123850
124863
|
statSync as statSync17,
|
|
123851
124864
|
writeFileSync as writeFileSync17,
|
|
@@ -123855,7 +124868,7 @@ import {
|
|
|
123855
124868
|
import { tmpdir as tmpdir8 } from "os";
|
|
123856
124869
|
import { join as join60, dirname as dirname25, resolve as resolve33 } from "path";
|
|
123857
124870
|
import { totalmem as totalmem2 } from "os";
|
|
123858
|
-
import { randomUUID as
|
|
124871
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
123859
124872
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
123860
124873
|
function sampleDirectoryBytes(dir) {
|
|
123861
124874
|
let total = 0;
|
|
@@ -123865,7 +124878,7 @@ function sampleDirectoryBytes(dir) {
|
|
|
123865
124878
|
if (!current2) continue;
|
|
123866
124879
|
let entries2 = [];
|
|
123867
124880
|
try {
|
|
123868
|
-
entries2 =
|
|
124881
|
+
entries2 = readdirSync18(current2);
|
|
123869
124882
|
} catch {
|
|
123870
124883
|
continue;
|
|
123871
124884
|
}
|
|
@@ -124214,7 +125227,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
124214
125227
|
}
|
|
124215
125228
|
function createRenderJob(config) {
|
|
124216
125229
|
return {
|
|
124217
|
-
id:
|
|
125230
|
+
id: randomUUID8(),
|
|
124218
125231
|
config: {
|
|
124219
125232
|
...config,
|
|
124220
125233
|
fps: toFps(config.fps),
|
|
@@ -126607,7 +127620,7 @@ import {
|
|
|
126607
127620
|
mkdtempSync as mkdtempSync8,
|
|
126608
127621
|
writeFileSync as writeFileSync18,
|
|
126609
127622
|
rmSync as rmSync19,
|
|
126610
|
-
createReadStream as
|
|
127623
|
+
createReadStream as createReadStream5
|
|
126611
127624
|
} from "fs";
|
|
126612
127625
|
import { resolve as resolve35, dirname as dirname27, join as join64 } from "path";
|
|
126613
127626
|
import { tmpdir as tmpdir9 } from "os";
|
|
@@ -127166,7 +128179,7 @@ function createRenderHandlers(options = {}) {
|
|
|
127166
128179
|
return c3.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
127167
128180
|
}
|
|
127168
128181
|
const stats = statSync19(artifact.path);
|
|
127169
|
-
return new Response(
|
|
128182
|
+
return new Response(createReadStream5(artifact.path), {
|
|
127170
128183
|
headers: {
|
|
127171
128184
|
"content-type": "video/mp4",
|
|
127172
128185
|
"content-length": String(stats.size),
|
|
@@ -127437,7 +128450,7 @@ var init_planHash = __esm({
|
|
|
127437
128450
|
});
|
|
127438
128451
|
|
|
127439
128452
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
127440
|
-
import { existsSync as existsSync58, mkdirSync as mkdirSync29, readFileSync as readFileSync34, readdirSync as
|
|
128453
|
+
import { existsSync as existsSync58, mkdirSync as mkdirSync29, readFileSync as readFileSync34, readdirSync as readdirSync19, writeFileSync as writeFileSync19 } from "fs";
|
|
127441
128454
|
import { join as join65, relative as relative12, resolve as resolve36 } from "path";
|
|
127442
128455
|
function stripUndefined(value) {
|
|
127443
128456
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -127457,7 +128470,7 @@ function listPlanFiles(planDir) {
|
|
|
127457
128470
|
const results = [];
|
|
127458
128471
|
const rootResolved = resolve36(planDir);
|
|
127459
128472
|
function walk(dir) {
|
|
127460
|
-
const entries2 =
|
|
128473
|
+
const entries2 = readdirSync19(dir, { withFileTypes: true });
|
|
127461
128474
|
for (const entry of entries2) {
|
|
127462
128475
|
const full2 = join65(dir, entry.name);
|
|
127463
128476
|
if (entry.isDirectory()) {
|
|
@@ -127868,7 +128881,7 @@ var init_shared2 = __esm({
|
|
|
127868
128881
|
|
|
127869
128882
|
// ../producer/src/services/distributed/planSize.ts
|
|
127870
128883
|
import { createHash as createHash15 } from "crypto";
|
|
127871
|
-
import { lstatSync as lstatSync5, readdirSync as
|
|
128884
|
+
import { lstatSync as lstatSync5, readdirSync as readdirSync20 } from "fs";
|
|
127872
128885
|
import { extname as extname13, join as join67, relative as relative13 } from "path";
|
|
127873
128886
|
function hashComponent(value) {
|
|
127874
128887
|
return createHash15("sha256").update(value).digest("hex").slice(0, 12);
|
|
@@ -127950,7 +128963,7 @@ function recordFile(result, components, rootDir, rootKind, filePath) {
|
|
|
127950
128963
|
function walkRegularFiles(dir, visit) {
|
|
127951
128964
|
let entries2;
|
|
127952
128965
|
try {
|
|
127953
|
-
entries2 =
|
|
128966
|
+
entries2 = readdirSync20(dir, { withFileTypes: true });
|
|
127954
128967
|
} catch {
|
|
127955
128968
|
return;
|
|
127956
128969
|
}
|
|
@@ -128007,7 +129020,7 @@ var init_planSize = __esm({
|
|
|
128007
129020
|
});
|
|
128008
129021
|
|
|
128009
129022
|
// ../producer/src/services/distributed/plan.ts
|
|
128010
|
-
import { cpSync as cpSync3, existsSync as existsSync60, mkdirSync as mkdirSync30, renameSync as
|
|
129023
|
+
import { cpSync as cpSync3, existsSync as existsSync60, mkdirSync as mkdirSync30, renameSync as renameSync11, rmSync as rmSync20, writeFileSync as writeFileSync20 } from "fs";
|
|
128011
129024
|
import { join as join68, relative as relative14, sep as sep10 } from "path";
|
|
128012
129025
|
function applyDistributedAudioWarningPolicy(job, audioError, audioFailures = [], log2 = defaultLogger) {
|
|
128013
129026
|
const failureOwner = audioFailures.length === 0 ? void 0 : audioFailures.some((failure) => failure.owner === "system") ? "system" : "user";
|
|
@@ -128357,12 +129370,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
128357
129370
|
const videoFramesDst = join68(planDir, "video-frames");
|
|
128358
129371
|
if (existsSync60(videoFramesDst)) rmSync20(videoFramesDst, { recursive: true, force: true });
|
|
128359
129372
|
if (existsSync60(stagedVideoFrames)) {
|
|
128360
|
-
|
|
129373
|
+
renameSync11(stagedVideoFrames, videoFramesDst);
|
|
128361
129374
|
} else {
|
|
128362
129375
|
mkdirSync30(videoFramesDst, { recursive: true });
|
|
128363
129376
|
}
|
|
128364
129377
|
if (existsSync60(finalCompiledDir)) rmSync20(finalCompiledDir, { recursive: true, force: true });
|
|
128365
|
-
|
|
129378
|
+
renameSync11(compiledDir, finalCompiledDir);
|
|
128366
129379
|
const planVideosJson = buildPlanVideosJson({
|
|
128367
129380
|
videos: composition.videos,
|
|
128368
129381
|
compositionEnd: job.duration ?? Number.NaN,
|
|
@@ -128383,7 +129396,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
128383
129396
|
);
|
|
128384
129397
|
const planAudioPath = join68(planDir, PLAN_AUDIO_RELATIVE_PATH);
|
|
128385
129398
|
if (audioResult.hasAudio && existsSync60(audioResult.audioOutputPath)) {
|
|
128386
|
-
|
|
129399
|
+
renameSync11(audioResult.audioOutputPath, planAudioPath);
|
|
128387
129400
|
}
|
|
128388
129401
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
128389
129402
|
const { chunkCount, effectiveChunkSize } = resolveChunkPlan(
|
|
@@ -128609,10 +129622,10 @@ var init_planV2Layout = __esm({
|
|
|
128609
129622
|
import {
|
|
128610
129623
|
copyFileSync as copyFileSync7,
|
|
128611
129624
|
existsSync as existsSync61,
|
|
128612
|
-
linkSync as
|
|
129625
|
+
linkSync as linkSync3,
|
|
128613
129626
|
mkdirSync as mkdirSync31,
|
|
128614
129627
|
mkdtempSync as mkdtempSync9,
|
|
128615
|
-
renameSync as
|
|
129628
|
+
renameSync as renameSync12,
|
|
128616
129629
|
rmSync as rmSync21,
|
|
128617
129630
|
statSync as statSync20,
|
|
128618
129631
|
writeFileSync as writeFileSync21
|
|
@@ -128659,7 +129672,7 @@ var init_planV2Publisher = __esm({
|
|
|
128659
129672
|
throw new PlanV2IntegrityError(`output directory already exists: ${destinationDir}`);
|
|
128660
129673
|
}
|
|
128661
129674
|
this.destinationDir = destinationDir;
|
|
128662
|
-
this.#linkFile = options.linkFile ??
|
|
129675
|
+
this.#linkFile = options.linkFile ?? linkSync3;
|
|
128663
129676
|
mkdirSync31(dirname29(destinationDir), { recursive: true });
|
|
128664
129677
|
this.temporaryDir = mkdtempSync9(join70(dirname29(destinationDir), ".plan-v2-publish-"));
|
|
128665
129678
|
}
|
|
@@ -128683,7 +129696,7 @@ var init_planV2Publisher = __esm({
|
|
|
128683
129696
|
if (!canFallbackToCopy(error)) throw error;
|
|
128684
129697
|
copyFileSync7(blob.sourcePath, temporaryPath);
|
|
128685
129698
|
}
|
|
128686
|
-
|
|
129699
|
+
renameSync12(temporaryPath, destinationPath);
|
|
128687
129700
|
} finally {
|
|
128688
129701
|
rmSync21(stagingDir, { recursive: true, force: true });
|
|
128689
129702
|
}
|
|
@@ -128697,7 +129710,7 @@ var init_planV2Publisher = __esm({
|
|
|
128697
129710
|
}
|
|
128698
129711
|
}
|
|
128699
129712
|
writeFileSync21(join70(this.temporaryDir, "plan.json"), manifestBytes, "utf-8");
|
|
128700
|
-
|
|
129713
|
+
renameSync12(this.temporaryDir, this.destinationDir);
|
|
128701
129714
|
this.#committed = true;
|
|
128702
129715
|
}
|
|
128703
129716
|
async abort() {
|
|
@@ -128720,8 +129733,8 @@ import {
|
|
|
128720
129733
|
openSync as openSync7,
|
|
128721
129734
|
readFileSync as readFileSync36,
|
|
128722
129735
|
readSync as readSync4,
|
|
128723
|
-
readdirSync as
|
|
128724
|
-
renameSync as
|
|
129736
|
+
readdirSync as readdirSync21,
|
|
129737
|
+
renameSync as renameSync13,
|
|
128725
129738
|
rmSync as rmSync23,
|
|
128726
129739
|
statSync as statSync21,
|
|
128727
129740
|
writeFileSync as writeFileSync23
|
|
@@ -128758,7 +129771,7 @@ function listFiles(root) {
|
|
|
128758
129771
|
const files = [];
|
|
128759
129772
|
const rootResolved = resolve37(root);
|
|
128760
129773
|
function walk(dir) {
|
|
128761
|
-
for (const entry of
|
|
129774
|
+
for (const entry of readdirSync21(dir, { withFileTypes: true })) {
|
|
128762
129775
|
const absolutePath = join71(dir, entry.name);
|
|
128763
129776
|
if (entry.isDirectory()) {
|
|
128764
129777
|
walk(absolutePath);
|
|
@@ -128803,10 +129816,10 @@ function assertValidExtractionCacheCompleteSentinel(path2) {
|
|
|
128803
129816
|
function validateExtractionCacheCompleteSentinels(executionPlanDir) {
|
|
128804
129817
|
const videoRoot = join71(executionPlanDir, "video-frames");
|
|
128805
129818
|
if (!existsSync63(videoRoot)) return;
|
|
128806
|
-
for (const videoEntry of
|
|
129819
|
+
for (const videoEntry of readdirSync21(videoRoot, { withFileTypes: true })) {
|
|
128807
129820
|
if (!videoEntry.isDirectory()) continue;
|
|
128808
129821
|
const videoDir = join71(videoRoot, videoEntry.name);
|
|
128809
|
-
if (
|
|
129822
|
+
if (readdirSync21(videoDir).includes(EXTRACTION_CACHE_COMPLETE_SENTINEL)) {
|
|
128810
129823
|
const sentinelPath = join71(videoDir, EXTRACTION_CACHE_COMPLETE_SENTINEL);
|
|
128811
129824
|
assertValidExtractionCacheCompleteSentinel(sentinelPath);
|
|
128812
129825
|
}
|
|
@@ -128843,7 +129856,7 @@ function artifactTargets(path2, videoDependencies) {
|
|
|
128843
129856
|
function listVideoFramePaths(executionPlanDir, videos) {
|
|
128844
129857
|
return videos.extracted.map((video) => {
|
|
128845
129858
|
const outputDir = resolveExtractedVideoOutputDir(executionPlanDir, video.videoId);
|
|
128846
|
-
const frameNames =
|
|
129859
|
+
const frameNames = readdirSync21(outputDir).sort();
|
|
128847
129860
|
const framePaths = /* @__PURE__ */ new Map();
|
|
128848
129861
|
for (const frameName of frameNames) {
|
|
128849
129862
|
if (frameName === EXTRACTION_CACHE_COMPLETE_SENTINEL) {
|
|
@@ -128964,7 +129977,7 @@ function writeBlob(sourcePath, destinationPath) {
|
|
|
128964
129977
|
const temporaryPath = join71(temporaryDir, "blob");
|
|
128965
129978
|
try {
|
|
128966
129979
|
copyFileSync8(sourcePath, temporaryPath);
|
|
128967
|
-
|
|
129980
|
+
renameSync13(temporaryPath, destinationPath);
|
|
128968
129981
|
} finally {
|
|
128969
129982
|
rmSync23(temporaryDir, { recursive: true, force: true });
|
|
128970
129983
|
}
|
|
@@ -129056,7 +130069,7 @@ function createPlanV2FromExecutionPlan(executionPlanDir, planV2Dir) {
|
|
|
129056
130069
|
canonicalJsonStringify(publication.manifest),
|
|
129057
130070
|
"utf-8"
|
|
129058
130071
|
);
|
|
129059
|
-
|
|
130072
|
+
renameSync13(tempDir, planV2Dir);
|
|
129060
130073
|
return resultFromManifest(planV2Dir, publication.manifest);
|
|
129061
130074
|
} catch (error) {
|
|
129062
130075
|
rmSync23(tempDir, { recursive: true, force: true });
|
|
@@ -129310,7 +130323,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir) {
|
|
|
129310
130323
|
canonicalJsonStringify({ manifest, target }),
|
|
129311
130324
|
"utf-8"
|
|
129312
130325
|
);
|
|
129313
|
-
|
|
130326
|
+
renameSync13(tempDir, destinationDir);
|
|
129314
130327
|
} catch (error) {
|
|
129315
130328
|
rmSync23(tempDir, { recursive: true, force: true });
|
|
129316
130329
|
throw error;
|
|
@@ -129378,7 +130391,7 @@ import {
|
|
|
129378
130391
|
existsSync as existsSync64,
|
|
129379
130392
|
mkdirSync as mkdirSync34,
|
|
129380
130393
|
readFileSync as readFileSync37,
|
|
129381
|
-
readdirSync as
|
|
130394
|
+
readdirSync as readdirSync23,
|
|
129382
130395
|
rmSync as rmSync24,
|
|
129383
130396
|
statSync as statSync24,
|
|
129384
130397
|
writeFileSync as writeFileSync24
|
|
@@ -129589,7 +130602,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
129589
130602
|
`[assemble] png-sequence chunk must be a directory: ${chunkDir} (got a file)`
|
|
129590
130603
|
);
|
|
129591
130604
|
}
|
|
129592
|
-
const frames =
|
|
130605
|
+
const frames = readdirSync23(chunkDir).filter((name) => name.endsWith(".png")).sort();
|
|
129593
130606
|
if (frames.length === 0) {
|
|
129594
130607
|
throw new Error(`[assemble] png-sequence chunk has no frames: ${chunkDir}`);
|
|
129595
130608
|
}
|
|
@@ -129609,7 +130622,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
129609
130622
|
cpSync4(audioPath, sidecar);
|
|
129610
130623
|
}
|
|
129611
130624
|
let fileSize = 0;
|
|
129612
|
-
for (const name of
|
|
130625
|
+
for (const name of readdirSync23(outputPath)) {
|
|
129613
130626
|
try {
|
|
129614
130627
|
fileSize += statSync24(join73(outputPath, name)).size;
|
|
129615
130628
|
} catch {
|
|
@@ -129637,7 +130650,7 @@ var init_assemble = __esm({
|
|
|
129637
130650
|
|
|
129638
130651
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
129639
130652
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
129640
|
-
import { existsSync as existsSync65, mkdirSync as mkdirSync35, readFileSync as readFileSync38, readdirSync as
|
|
130653
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync35, readFileSync as readFileSync38, readdirSync as readdirSync24, rmSync as rmSync25, writeFileSync as writeFileSync25 } from "fs";
|
|
129641
130654
|
import { extname as extname14, join as join74 } from "path";
|
|
129642
130655
|
function validatePlanVideosForChunk(value) {
|
|
129643
130656
|
try {
|
|
@@ -129691,7 +130704,10 @@ async function runCaptureWithScreenshotFallback(input2) {
|
|
|
129691
130704
|
async function beginFrameSessionNeedsScreenshotFallback(session, probe = probeBeginFrameLiveness) {
|
|
129692
130705
|
if (session.launchCaptureMode !== "beginframe") return false;
|
|
129693
130706
|
const timeoutMs = Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) > 0 ? Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) : 3e4;
|
|
129694
|
-
const probeTick =
|
|
130707
|
+
const probeTick = deriveBeginFrameProbeTimeTicks(
|
|
130708
|
+
session.beginFrameTimeTicks,
|
|
130709
|
+
session.beginFrameIntervalMs
|
|
130710
|
+
);
|
|
129695
130711
|
return !await probe(session.page, timeoutMs, probeTick, session.beginFrameIntervalMs);
|
|
129696
130712
|
}
|
|
129697
130713
|
function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v1") {
|
|
@@ -129704,7 +130720,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
129704
130720
|
);
|
|
129705
130721
|
}
|
|
129706
130722
|
const ext = (extname14(v2.framePattern) || ".jpg").toLowerCase();
|
|
129707
|
-
const frames =
|
|
130723
|
+
const frames = readdirSync24(outputDir).filter((name) => name.toLowerCase().endsWith(ext)).sort();
|
|
129708
130724
|
const framePaths = /* @__PURE__ */ new Map();
|
|
129709
130725
|
for (let i2 = 0; i2 < frames.length; i2++) {
|
|
129710
130726
|
const frameName = frames[i2];
|
|
@@ -129734,7 +130750,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
129734
130750
|
}
|
|
129735
130751
|
function hashChunkOutput(outputPath, kind) {
|
|
129736
130752
|
if (kind === "file") return sha256Hex(readFileSync38(outputPath));
|
|
129737
|
-
const entries2 =
|
|
130753
|
+
const entries2 = readdirSync24(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
129738
130754
|
const lines = entries2.map(
|
|
129739
130755
|
(name) => `${name}\0${sha256Hex(readFileSync38(join74(outputPath, name)))}`
|
|
129740
130756
|
);
|
|
@@ -130259,7 +131275,7 @@ var init_planV2Execution = __esm({
|
|
|
130259
131275
|
});
|
|
130260
131276
|
|
|
130261
131277
|
// ../producer/src/services/distributed/projectHash.ts
|
|
130262
|
-
import { readdirSync as
|
|
131278
|
+
import { readdirSync as readdirSync25, readFileSync as readFileSync39 } from "fs";
|
|
130263
131279
|
import { createHash as createHash17 } from "crypto";
|
|
130264
131280
|
import { join as join76, relative as relative16 } from "path";
|
|
130265
131281
|
var init_projectHash = __esm({
|
|
@@ -130961,7 +131977,7 @@ __export(studioServer_exports, {
|
|
|
130961
131977
|
});
|
|
130962
131978
|
import { Hono as Hono5 } from "hono";
|
|
130963
131979
|
import { streamSSE as streamSSE4 } from "hono/streaming";
|
|
130964
|
-
import { existsSync as existsSync67, readFileSync as readFileSync40, writeFileSync as writeFileSync26, statSync as statSync25, unlinkSync as
|
|
131980
|
+
import { existsSync as existsSync67, readFileSync as readFileSync40, writeFileSync as writeFileSync26, statSync as statSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
130965
131981
|
import { resolve as resolve38, join as join78, basename as basename11 } from "path";
|
|
130966
131982
|
async function loadStudioProducer() {
|
|
130967
131983
|
return isDevMode() ? await Promise.resolve().then(() => (init_src2(), src_exports2)) : await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
@@ -131200,7 +132216,7 @@ function createStudioServer(options) {
|
|
|
131200
132216
|
async transformPreviewHtml({ html, project: project2 }) {
|
|
131201
132217
|
const { injectDeterministicFontFaces: injectDeterministicFontFaces2 } = await Promise.resolve().then(() => (init_deterministicFonts(), deterministicFonts_exports));
|
|
131202
132218
|
const { prepareAnimatedGifInputs: prepareAnimatedGifInputs2 } = await Promise.resolve().then(() => (init_animatedGifPrep(), animatedGifPrep_exports));
|
|
131203
|
-
const { downloadToTemp: downloadToTemp2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
|
|
132219
|
+
const { downloadToTemp: downloadToTemp2, writeUrlDownloadTelemetry: writeUrlDownloadTelemetry2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
|
|
131204
132220
|
const gifOutputDir = join78(project2.dir, ".hyperframes", "prepared-assets", "gif");
|
|
131205
132221
|
const gifDownloadDir = join78(project2.dir, ".hyperframes", "prepared-assets", "downloads");
|
|
131206
132222
|
const prepared = await prepareAnimatedGifInputs2(html, {
|
|
@@ -131209,7 +132225,13 @@ function createStudioServer(options) {
|
|
|
131209
132225
|
outputDir: gifOutputDir,
|
|
131210
132226
|
outputSrcPrefix: ".hyperframes/prepared-assets/gif",
|
|
131211
132227
|
cacheDir: gifOutputDir,
|
|
131212
|
-
sourceAssets: await downloadRemoteGifImageSources(
|
|
132228
|
+
sourceAssets: await downloadRemoteGifImageSources(
|
|
132229
|
+
html,
|
|
132230
|
+
gifDownloadDir,
|
|
132231
|
+
(url, destDir) => downloadToTemp2(url, destDir, void 0, void 0, void 0, {
|
|
132232
|
+
onTelemetry: writeUrlDownloadTelemetry2
|
|
132233
|
+
})
|
|
132234
|
+
)
|
|
131213
132235
|
});
|
|
131214
132236
|
return injectDeterministicFontFaces2(prepared.html);
|
|
131215
132237
|
},
|
|
@@ -131242,7 +132264,7 @@ function createStudioServer(options) {
|
|
|
131242
132264
|
for (const suffix of ["", ".meta.json"]) {
|
|
131243
132265
|
const fp = suffix ? opts.outputPath.replace(/\.(mp4|webm|mov)$/, suffix) : opts.outputPath;
|
|
131244
132266
|
try {
|
|
131245
|
-
if (existsSync67(fp))
|
|
132267
|
+
if (existsSync67(fp)) unlinkSync6(fp);
|
|
131246
132268
|
} catch {
|
|
131247
132269
|
}
|
|
131248
132270
|
}
|
|
@@ -131621,7 +132643,7 @@ import {
|
|
|
131621
132643
|
readFileSync as readFileSync41,
|
|
131622
132644
|
readlinkSync,
|
|
131623
132645
|
symlinkSync as symlinkSync3,
|
|
131624
|
-
unlinkSync as
|
|
132646
|
+
unlinkSync as unlinkSync7
|
|
131625
132647
|
} from "fs";
|
|
131626
132648
|
import { resolve as resolve39, dirname as dirname33, basename as basename12, join as join79 } from "path";
|
|
131627
132649
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
@@ -131955,7 +132977,7 @@ function linkProjectIntoStudioData(dir, projectsDir, projectName) {
|
|
|
131955
132977
|
try {
|
|
131956
132978
|
const stat3 = lstatSync7(symlinkPath);
|
|
131957
132979
|
if (stat3.isSymbolicLink() && resolve39(readlinkSync(symlinkPath)) !== resolve39(dir)) {
|
|
131958
|
-
|
|
132980
|
+
unlinkSync7(symlinkPath);
|
|
131959
132981
|
}
|
|
131960
132982
|
} catch {
|
|
131961
132983
|
}
|
|
@@ -131971,7 +132993,7 @@ function removeSymlinkOnExit(createdSymlink, symlinkPath) {
|
|
|
131971
132993
|
if (!createdSymlink) return;
|
|
131972
132994
|
process.on("exit", () => {
|
|
131973
132995
|
try {
|
|
131974
|
-
if (existsSync68(symlinkPath))
|
|
132996
|
+
if (existsSync68(symlinkPath)) unlinkSync7(symlinkPath);
|
|
131975
132997
|
} catch {
|
|
131976
132998
|
}
|
|
131977
132999
|
});
|
|
@@ -132541,7 +133563,7 @@ import {
|
|
|
132541
133563
|
cpSync as cpSync5,
|
|
132542
133564
|
writeFileSync as writeFileSync27,
|
|
132543
133565
|
readFileSync as readFileSync43,
|
|
132544
|
-
readdirSync as
|
|
133566
|
+
readdirSync as readdirSync26
|
|
132545
133567
|
} from "fs";
|
|
132546
133568
|
import { resolve as resolve40, basename as basename13, join as join80, dirname as dirname34 } from "path";
|
|
132547
133569
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
@@ -132561,7 +133583,7 @@ function probeVideo(filePath) {
|
|
|
132561
133583
|
if (!ffprobePath) return void 0;
|
|
132562
133584
|
const raw = execFileSync8(
|
|
132563
133585
|
ffprobePath,
|
|
132564
|
-
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filePath],
|
|
133586
|
+
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "--", filePath],
|
|
132565
133587
|
{ encoding: "utf-8", timeout: 15e3 }
|
|
132566
133588
|
);
|
|
132567
133589
|
const parsed = JSON.parse(raw);
|
|
@@ -132692,7 +133714,7 @@ function listHtmlFiles(dir) {
|
|
|
132692
133714
|
const files = [];
|
|
132693
133715
|
const ignoredDirs = /* @__PURE__ */ new Set([".git", "dist", "node_modules"]);
|
|
132694
133716
|
function walk(currentDir) {
|
|
132695
|
-
for (const entry of
|
|
133717
|
+
for (const entry of readdirSync26(currentDir, { withFileTypes: true })) {
|
|
132696
133718
|
const entryPath = join80(currentDir, entry.name);
|
|
132697
133719
|
if (entry.isDirectory()) {
|
|
132698
133720
|
if (!ignoredDirs.has(entry.name)) walk(entryPath);
|
|
@@ -132738,7 +133760,7 @@ function writeTailwindSupport(destDir) {
|
|
|
132738
133760
|
}
|
|
132739
133761
|
}
|
|
132740
133762
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
132741
|
-
const htmlFiles =
|
|
133763
|
+
const htmlFiles = readdirSync26(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join80(e3.parentPath, e3.name));
|
|
132742
133764
|
for (const file of htmlFiles) {
|
|
132743
133765
|
let content = readFileSync43(file, "utf-8");
|
|
132744
133766
|
if (videoFilename) {
|
|
@@ -132926,7 +133948,7 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
132926
133948
|
writeDefaultPackageJson(destDir, name);
|
|
132927
133949
|
const sharedDir = getSharedTemplateDir();
|
|
132928
133950
|
if (existsSync69(sharedDir)) {
|
|
132929
|
-
for (const entry of
|
|
133951
|
+
for (const entry of readdirSync26(sharedDir, { withFileTypes: true })) {
|
|
132930
133952
|
const src = join80(sharedDir, entry.name);
|
|
132931
133953
|
const dest = resolve40(destDir, entry.name);
|
|
132932
133954
|
if (entry.isFile() || entry.isSymbolicLink()) {
|
|
@@ -133145,7 +134167,7 @@ var init_init = __esm({
|
|
|
133145
134167
|
const templateId2 = exampleFlag ?? "blank";
|
|
133146
134168
|
const name2 = args.name ?? "my-video";
|
|
133147
134169
|
const destDir2 = resolve40(name2);
|
|
133148
|
-
if (existsSync69(destDir2) &&
|
|
134170
|
+
if (existsSync69(destDir2) && readdirSync26(destDir2).length > 0) {
|
|
133149
134171
|
console.error(c.error(`Directory already exists and is not empty: ${name2}`));
|
|
133150
134172
|
failCommand();
|
|
133151
134173
|
}
|
|
@@ -133226,7 +134248,7 @@ var init_init = __esm({
|
|
|
133226
134248
|
await patchTranscript(destDir2, transcriptFile2);
|
|
133227
134249
|
}
|
|
133228
134250
|
console.log(c.success(`Created ${c.accent(name2 + "/")}`));
|
|
133229
|
-
for (const f3 of
|
|
134251
|
+
for (const f3 of readdirSync26(destDir2).filter((f4) => !f4.startsWith("."))) {
|
|
133230
134252
|
console.log(` ${c.accent(f3)}`);
|
|
133231
134253
|
}
|
|
133232
134254
|
if (!skipSkills) {
|
|
@@ -133286,7 +134308,7 @@ var init_init = __esm({
|
|
|
133286
134308
|
name = nameResult;
|
|
133287
134309
|
}
|
|
133288
134310
|
const destDir = resolve40(name);
|
|
133289
|
-
if (existsSync69(destDir) &&
|
|
134311
|
+
if (existsSync69(destDir) && readdirSync26(destDir).length > 0) {
|
|
133290
134312
|
const overwrite = await ue({
|
|
133291
134313
|
message: `Directory ${c.accent(name)} already exists and is not empty. Overwrite?`,
|
|
133292
134314
|
initialValue: false
|
|
@@ -133418,7 +134440,7 @@ ${c.dim("Use --example blank for offline use.")}`
|
|
|
133418
134440
|
if (existsSync69(transcriptFile)) {
|
|
133419
134441
|
await patchTranscript(destDir, transcriptFile);
|
|
133420
134442
|
}
|
|
133421
|
-
const files =
|
|
134443
|
+
const files = readdirSync26(destDir);
|
|
133422
134444
|
Se(files.map((f3) => c.accent(f3)).join("\n"), c.success(`Created ${name}/`));
|
|
133423
134445
|
if (!skipSkills) {
|
|
133424
134446
|
await keepSkillsCurrent(destDir);
|
|
@@ -133882,14 +134904,14 @@ var init_catalog = __esm({
|
|
|
133882
134904
|
var init_mediaProxyPreview = __esm({
|
|
133883
134905
|
"../studio-server/dist/helpers/mediaProxyPreview.js"() {
|
|
133884
134906
|
"use strict";
|
|
133885
|
-
|
|
133886
|
-
|
|
133887
|
-
|
|
134907
|
+
init_chunk_LHYV3WLZ();
|
|
134908
|
+
init_chunk_ZPI6QXJH();
|
|
134909
|
+
init_chunk_6H3V3WGJ();
|
|
133888
134910
|
}
|
|
133889
134911
|
});
|
|
133890
134912
|
|
|
133891
134913
|
// src/utils/compositionServer.ts
|
|
133892
|
-
import { createReadStream as
|
|
134914
|
+
import { createReadStream as createReadStream6, existsSync as existsSync71, statSync as statSync26 } from "fs";
|
|
133893
134915
|
import { resolve as resolve44, dirname as dirname35 } from "path";
|
|
133894
134916
|
import { Readable as Readable3 } from "stream";
|
|
133895
134917
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
@@ -133937,7 +134959,7 @@ function buildRangeResponse(filePath, contentType, rangeHeader) {
|
|
|
133937
134959
|
const size = statSync26(filePath).size;
|
|
133938
134960
|
const last = size - 1;
|
|
133939
134961
|
const match = rangeHeader ? /^bytes=(\d*)-(\d*)$/.exec(rangeHeader.trim()) : null;
|
|
133940
|
-
const body = (start2, end2) => size === 0 ? null : Readable3.toWeb(
|
|
134962
|
+
const body = (start2, end2) => size === 0 ? null : Readable3.toWeb(createReadStream6(filePath, { start: start2, end: end2 }));
|
|
133941
134963
|
if (!match) {
|
|
133942
134964
|
return new Response(body(0, last), {
|
|
133943
134965
|
status: 200,
|
|
@@ -134004,8 +135026,8 @@ var init_compositionServer = __esm({
|
|
|
134004
135026
|
var init_proxyTranscoder = __esm({
|
|
134005
135027
|
"../studio-server/dist/helpers/proxyTranscoder.js"() {
|
|
134006
135028
|
"use strict";
|
|
134007
|
-
|
|
134008
|
-
|
|
135029
|
+
init_chunk_ZPI6QXJH();
|
|
135030
|
+
init_chunk_6H3V3WGJ();
|
|
134009
135031
|
}
|
|
134010
135032
|
});
|
|
134011
135033
|
|
|
@@ -134013,7 +135035,7 @@ var init_proxyTranscoder = __esm({
|
|
|
134013
135035
|
var init_mediaCodecMap = __esm({
|
|
134014
135036
|
"../studio-server/dist/helpers/mediaCodecMap.js"() {
|
|
134015
135037
|
"use strict";
|
|
134016
|
-
|
|
135038
|
+
init_chunk_6H3V3WGJ();
|
|
134017
135039
|
}
|
|
134018
135040
|
});
|
|
134019
135041
|
|
|
@@ -135591,7 +136613,7 @@ var init_auth = __esm({
|
|
|
135591
136613
|
});
|
|
135592
136614
|
|
|
135593
136615
|
// src/utils/projectLink.ts
|
|
135594
|
-
import { randomUUID as
|
|
136616
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
135595
136617
|
import { existsSync as existsSync75, mkdirSync as mkdirSync39, readFileSync as readFileSync46, writeFileSync as writeFileSync28 } from "fs";
|
|
135596
136618
|
import { homedir as homedir16 } from "os";
|
|
135597
136619
|
import { join as join83, resolve as resolve47 } from "path";
|
|
@@ -135642,7 +136664,7 @@ function ensureProjectId(absDir) {
|
|
|
135642
136664
|
const path2 = resolve47(absDir);
|
|
135643
136665
|
const existing = links[path2];
|
|
135644
136666
|
if (existing) return existing.projectId;
|
|
135645
|
-
const projectId =
|
|
136667
|
+
const projectId = randomUUID9();
|
|
135646
136668
|
links[path2] = { projectId, url: "" };
|
|
135647
136669
|
writeProjectLinks(links);
|
|
135648
136670
|
return projectId;
|
|
@@ -135680,7 +136702,7 @@ var init_projectLink = __esm({
|
|
|
135680
136702
|
|
|
135681
136703
|
// src/utils/publishProject.ts
|
|
135682
136704
|
import { basename as basename14, dirname as dirname37, join as join84, posix as posix5, relative as relative18, resolve as resolve48 } from "path";
|
|
135683
|
-
import { existsSync as existsSync76, readdirSync as
|
|
136705
|
+
import { existsSync as existsSync76, readdirSync as readdirSync27, readFileSync as readFileSync47, statSync as statSync27 } from "fs";
|
|
135684
136706
|
import AdmZip from "adm-zip";
|
|
135685
136707
|
import ignore2 from "ignore";
|
|
135686
136708
|
function isRecord8(value) {
|
|
@@ -135792,7 +136814,7 @@ function createProjectIgnore(rootDir) {
|
|
|
135792
136814
|
return matcher;
|
|
135793
136815
|
}
|
|
135794
136816
|
function collectProjectFiles(rootDir, currentDir, paths, matcher) {
|
|
135795
|
-
for (const entry of
|
|
136817
|
+
for (const entry of readdirSync27(currentDir, { withFileTypes: true })) {
|
|
135796
136818
|
if (shouldIgnoreSegment(entry.name)) continue;
|
|
135797
136819
|
const absolutePath = join84(currentDir, entry.name);
|
|
135798
136820
|
const relativePath = relative18(rootDir, absolutePath).replaceAll("\\", "/");
|
|
@@ -137495,6 +138517,7 @@ function probeWebmAlpha(filePath) {
|
|
|
137495
138517
|
"stream=codec_name:stream_tags=alpha_mode",
|
|
137496
138518
|
"-of",
|
|
137497
138519
|
"json",
|
|
138520
|
+
"--",
|
|
137498
138521
|
filePath
|
|
137499
138522
|
],
|
|
137500
138523
|
{ encoding: "utf-8", timeout: 15e3 }
|
|
@@ -138042,7 +139065,7 @@ __export(render_exports, {
|
|
|
138042
139065
|
renderLocal: () => renderLocal,
|
|
138043
139066
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
138044
139067
|
});
|
|
138045
|
-
import { mkdtempSync as mkdtempSync12, readdirSync as
|
|
139068
|
+
import { mkdtempSync as mkdtempSync12, readdirSync as readdirSync28, readFileSync as readFileSync53, statSync as statSync29, writeFileSync as writeFileSync30, rmSync as rmSync27 } from "fs";
|
|
138046
139069
|
import { freemem as freemem5, tmpdir as tmpdir12 } from "os";
|
|
138047
139070
|
import { resolve as resolve54, dirname as dirname41, join as join88, basename as basename16 } from "path";
|
|
138048
139071
|
import { execFileSync as execFileSync11, spawn as spawn15 } from "child_process";
|
|
@@ -138725,7 +139748,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds
|
|
|
138725
139748
|
isDirectory = stat3.isDirectory();
|
|
138726
139749
|
if (stat3.isDirectory()) {
|
|
138727
139750
|
let total = 0;
|
|
138728
|
-
for (const entry of
|
|
139751
|
+
for (const entry of readdirSync28(outputPath, { withFileTypes: true })) {
|
|
138729
139752
|
if (!entry.isFile()) continue;
|
|
138730
139753
|
try {
|
|
138731
139754
|
total += statSync29(join88(outputPath, entry.name)).size;
|
|
@@ -139141,7 +140164,7 @@ __export(staticProjectServer_exports, {
|
|
|
139141
140164
|
serveStaticProjectHtml: () => serveStaticProjectHtml
|
|
139142
140165
|
});
|
|
139143
140166
|
import { createServer as createServer2 } from "http";
|
|
139144
|
-
import { createReadStream as
|
|
140167
|
+
import { createReadStream as createReadStream7, existsSync as existsSync80, statSync as statSync30 } from "fs";
|
|
139145
140168
|
import { isAbsolute as isAbsolute14, relative as relative20, resolve as resolve55 } from "path";
|
|
139146
140169
|
function serveFileWithRange(filePath, rangeHeader, res, contentType = getMimeType(filePath)) {
|
|
139147
140170
|
const size = statSync30(filePath).size;
|
|
@@ -139167,7 +140190,7 @@ function serveFileWithRange(filePath, rangeHeader, res, contentType = getMimeTyp
|
|
|
139167
140190
|
headers["Content-Range"] = `bytes ${start}-${end}/${size}`;
|
|
139168
140191
|
}
|
|
139169
140192
|
headers["Content-Length"] = String(end - start + 1);
|
|
139170
|
-
const stream =
|
|
140193
|
+
const stream = createReadStream7(filePath, { start, end });
|
|
139171
140194
|
stream.on("open", () => {
|
|
139172
140195
|
res.writeHead(status, headers);
|
|
139173
140196
|
stream.pipe(res);
|
|
@@ -139709,7 +140732,7 @@ var init_motionAudit = __esm({
|
|
|
139709
140732
|
});
|
|
139710
140733
|
|
|
139711
140734
|
// src/utils/motionSpec.ts
|
|
139712
|
-
import { existsSync as existsSync81, readFileSync as readFileSync54, readdirSync as
|
|
140735
|
+
import { existsSync as existsSync81, readFileSync as readFileSync54, readdirSync as readdirSync29 } from "fs";
|
|
139713
140736
|
import { basename as basename17, join as join89 } from "path";
|
|
139714
140737
|
function isObject2(value) {
|
|
139715
140738
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -139753,7 +140776,7 @@ function parseMotionSpec(raw) {
|
|
|
139753
140776
|
}
|
|
139754
140777
|
function findMotionSpec(projectDir) {
|
|
139755
140778
|
if (!existsSync81(projectDir)) return null;
|
|
139756
|
-
const entries2 =
|
|
140779
|
+
const entries2 = readdirSync29(projectDir);
|
|
139757
140780
|
const sidecars = entries2.filter((name) => name.endsWith(".motion.json")).sort();
|
|
139758
140781
|
if (!sidecars[0]) return null;
|
|
139759
140782
|
if (sidecars.length === 1) return join89(projectDir, sidecars[0]);
|
|
@@ -143727,8 +144750,62 @@ function containsTimelineCall3(node, timelineVar) {
|
|
|
143727
144750
|
function rangeOf3(node) {
|
|
143728
144751
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
143729
144752
|
}
|
|
144753
|
+
function isSafeDefaultExpression3(node, earlierParams) {
|
|
144754
|
+
let safe = true;
|
|
144755
|
+
const visit = (current2, parent, key2) => {
|
|
144756
|
+
if (!isNode4(current2) || !safe) return;
|
|
144757
|
+
if (!SAFE_DEFAULT_NODES3.has(current2.type)) {
|
|
144758
|
+
safe = false;
|
|
144759
|
+
return;
|
|
144760
|
+
}
|
|
144761
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
144762
|
+
safe = false;
|
|
144763
|
+
return;
|
|
144764
|
+
}
|
|
144765
|
+
if (current2.type === "Identifier") {
|
|
144766
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot3(parent, key2) : false;
|
|
144767
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
144768
|
+
safe = false;
|
|
144769
|
+
}
|
|
144770
|
+
return;
|
|
144771
|
+
}
|
|
144772
|
+
for (const childKey of Object.keys(current2)) {
|
|
144773
|
+
if (SKIP_KEYS3.has(childKey)) continue;
|
|
144774
|
+
const child = current2[childKey];
|
|
144775
|
+
if (Array.isArray(child)) {
|
|
144776
|
+
for (const item of child) visit(item, current2, childKey);
|
|
144777
|
+
} else {
|
|
144778
|
+
visit(child, current2, childKey);
|
|
144779
|
+
}
|
|
144780
|
+
}
|
|
144781
|
+
};
|
|
144782
|
+
visit(node);
|
|
144783
|
+
return safe;
|
|
144784
|
+
}
|
|
144785
|
+
function supportedParam3(param, earlier) {
|
|
144786
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
144787
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
144788
|
+
if (!isSafeDefaultExpression3(param.right, earlier)) return null;
|
|
144789
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
144790
|
+
}
|
|
144791
|
+
function supportedParams3(fn) {
|
|
144792
|
+
if (SUPPORTED_PARAMS_CACHE3.has(fn)) return SUPPORTED_PARAMS_CACHE3.get(fn) ?? null;
|
|
144793
|
+
const params = [];
|
|
144794
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
144795
|
+
for (const param of fn.params ?? []) {
|
|
144796
|
+
const parsed = supportedParam3(param, earlier);
|
|
144797
|
+
if (!parsed) {
|
|
144798
|
+
SUPPORTED_PARAMS_CACHE3.set(fn, null);
|
|
144799
|
+
return null;
|
|
144800
|
+
}
|
|
144801
|
+
params.push(parsed);
|
|
144802
|
+
earlier.add(parsed.name);
|
|
144803
|
+
}
|
|
144804
|
+
SUPPORTED_PARAMS_CACHE3.set(fn, params);
|
|
144805
|
+
return params;
|
|
144806
|
+
}
|
|
143730
144807
|
function isShapeEligible3(fn) {
|
|
143731
|
-
return isFunctionNode6(fn) && fn.body?.type === "BlockStatement" &&
|
|
144808
|
+
return isFunctionNode6(fn) && fn.body?.type === "BlockStatement" && supportedParams3(fn) !== null;
|
|
143732
144809
|
}
|
|
143733
144810
|
function callsAny3(node, names) {
|
|
143734
144811
|
let hit = false;
|
|
@@ -143778,20 +144855,55 @@ function timelineBuildingNames3(candidates, timelineVar) {
|
|
|
143778
144855
|
function bump3(counts, key2) {
|
|
143779
144856
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
143780
144857
|
}
|
|
144858
|
+
function undefinedIdentifier3() {
|
|
144859
|
+
return { type: "Identifier", name: "undefined" };
|
|
144860
|
+
}
|
|
144861
|
+
function isExplicitUndefined3(node) {
|
|
144862
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
144863
|
+
}
|
|
144864
|
+
function resolveHelperBindings3(call, params) {
|
|
144865
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
144866
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
144867
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
144868
|
+
const param = params[i2];
|
|
144869
|
+
const arg = call.arguments?.[i2];
|
|
144870
|
+
if (arg && !isExplicitUndefined3(arg)) {
|
|
144871
|
+
bindings.set(param.name, arg);
|
|
144872
|
+
} else if (param.defaultExpression) {
|
|
144873
|
+
bindings.set(param.name, substituteParams3(cloneNode4(param.defaultExpression), bindings));
|
|
144874
|
+
} else {
|
|
144875
|
+
bindings.set(param.name, undefinedIdentifier3());
|
|
144876
|
+
}
|
|
144877
|
+
}
|
|
144878
|
+
return bindings;
|
|
144879
|
+
}
|
|
144880
|
+
function statementHelperCall3(node, names) {
|
|
144881
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
144882
|
+
const expression = node.expression;
|
|
144883
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
144884
|
+
return void 0;
|
|
144885
|
+
}
|
|
144886
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
144887
|
+
}
|
|
143781
144888
|
function safelyDroppable3(program, candidates) {
|
|
143782
144889
|
const names = new Set(candidates.keys());
|
|
143783
144890
|
const totalIds = /* @__PURE__ */ new Map();
|
|
143784
144891
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
144892
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
143785
144893
|
walkNodes3(program, (n2) => {
|
|
143786
144894
|
if (n2.type === "Identifier" && names.has(n2.name)) bump3(totalIds, n2.name);
|
|
143787
|
-
const
|
|
143788
|
-
if (
|
|
143789
|
-
|
|
143790
|
-
|
|
144895
|
+
const call = statementHelperCall3(n2, names);
|
|
144896
|
+
if (!call) return;
|
|
144897
|
+
bump3(stmtCalls, call.callee.name);
|
|
144898
|
+
const fn = candidates.get(call.callee.name);
|
|
144899
|
+
const params = fn && supportedParams3(fn);
|
|
144900
|
+
if (!params || !resolveHelperBindings3(call, params)) unbindable.add(call.callee.name);
|
|
143791
144901
|
});
|
|
143792
144902
|
const safe = /* @__PURE__ */ new Map();
|
|
143793
144903
|
for (const [name, fn] of candidates) {
|
|
143794
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
144904
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
144905
|
+
safe.set(name, fn);
|
|
144906
|
+
}
|
|
143795
144907
|
}
|
|
143796
144908
|
return safe;
|
|
143797
144909
|
}
|
|
@@ -143834,11 +144946,11 @@ function expandBody3(bodyStmts, bindings, prov, ctx) {
|
|
|
143834
144946
|
}
|
|
143835
144947
|
function inlineHelper3(call, ctx) {
|
|
143836
144948
|
const fn = ctx.helpers.get(call.callee.name);
|
|
143837
|
-
|
|
143838
|
-
|
|
143839
|
-
|
|
143840
|
-
|
|
143841
|
-
|
|
144949
|
+
if (!fn) return null;
|
|
144950
|
+
const params = supportedParams3(fn);
|
|
144951
|
+
if (!params) return null;
|
|
144952
|
+
const bindings = resolveHelperBindings3(call, params);
|
|
144953
|
+
if (!bindings) return null;
|
|
143842
144954
|
const prov = {
|
|
143843
144955
|
kind: "helper",
|
|
143844
144956
|
fn: call.callee.name,
|
|
@@ -145157,7 +146269,7 @@ function parseGsapScriptAcorn3(script) {
|
|
|
145157
146269
|
return { animations: [], timelineVar: "tl", preamble: "", postamble: "" };
|
|
145158
146270
|
}
|
|
145159
146271
|
}
|
|
145160
|
-
var recast3, import_parser4, PROPERTY_GROUPS6, PROP_TO_GROUP6, roundPercentage5, SKIP_KEYS3, FUNCTION_TYPES3, GSAP_METHODS6, MAX_DEPTH3, MAX_ITERS3, GSAP_METHODS23, QUERY_METHODS5, ITERATION_METHODS5, SCOPE_NODE_TYPES5, CONST_NODES4, MATH_FNS4, MATH_CONSTS4, BUILTIN_VAR_KEYS5, DROPPED_VAR_KEYS5, EXTRAS_KEYS5, PERCENTAGE_KEY_RE5, GSAP_DEFAULT_DURATION5;
|
|
146272
|
+
var recast3, import_parser4, PROPERTY_GROUPS6, PROP_TO_GROUP6, roundPercentage5, SKIP_KEYS3, FUNCTION_TYPES3, GSAP_METHODS6, MAX_DEPTH3, MAX_ITERS3, SAFE_DEFAULT_NODES3, SUPPORTED_PARAMS_CACHE3, GSAP_METHODS23, QUERY_METHODS5, ITERATION_METHODS5, SCOPE_NODE_TYPES5, CONST_NODES4, MATH_FNS4, MATH_CONSTS4, BUILTIN_VAR_KEYS5, DROPPED_VAR_KEYS5, EXTRAS_KEYS5, PERCENTAGE_KEY_RE5, GSAP_DEFAULT_DURATION5;
|
|
145161
146273
|
var init_gsapParserExports = __esm({
|
|
145162
146274
|
"../parsers/dist/gsapParserExports.js"() {
|
|
145163
146275
|
"use strict";
|
|
@@ -145187,6 +146299,23 @@ var init_gsapParserExports = __esm({
|
|
|
145187
146299
|
GSAP_METHODS6 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
145188
146300
|
MAX_DEPTH3 = 8;
|
|
145189
146301
|
MAX_ITERS3 = 512;
|
|
146302
|
+
SAFE_DEFAULT_NODES3 = /* @__PURE__ */ new Set([
|
|
146303
|
+
"ArrayExpression",
|
|
146304
|
+
"BinaryExpression",
|
|
146305
|
+
"ChainExpression",
|
|
146306
|
+
"ConditionalExpression",
|
|
146307
|
+
"Identifier",
|
|
146308
|
+
"Literal",
|
|
146309
|
+
"LogicalExpression",
|
|
146310
|
+
"MemberExpression",
|
|
146311
|
+
"ObjectExpression",
|
|
146312
|
+
"Property",
|
|
146313
|
+
"SpreadElement",
|
|
146314
|
+
"TemplateElement",
|
|
146315
|
+
"TemplateLiteral",
|
|
146316
|
+
"UnaryExpression"
|
|
146317
|
+
]);
|
|
146318
|
+
SUPPORTED_PARAMS_CACHE3 = /* @__PURE__ */ new WeakMap();
|
|
145190
146319
|
GSAP_METHODS23 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
145191
146320
|
QUERY_METHODS5 = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
145192
146321
|
ITERATION_METHODS5 = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
@@ -146555,7 +147684,7 @@ __export(info_exports, {
|
|
|
146555
147684
|
examples: () => examples16,
|
|
146556
147685
|
orientation: () => orientation
|
|
146557
147686
|
});
|
|
146558
|
-
import { readFileSync as readFileSync60, readdirSync as
|
|
147687
|
+
import { readFileSync as readFileSync60, readdirSync as readdirSync30, statSync as statSync33 } from "fs";
|
|
146559
147688
|
import { join as join98 } from "path";
|
|
146560
147689
|
function orientation(width, height) {
|
|
146561
147690
|
if (width > height) return "landscape";
|
|
@@ -146569,7 +147698,7 @@ function durationFromHtml(html, fallback) {
|
|
|
146569
147698
|
}
|
|
146570
147699
|
function totalSize(dir) {
|
|
146571
147700
|
let total = 0;
|
|
146572
|
-
for (const entry of
|
|
147701
|
+
for (const entry of readdirSync30(dir, { withFileTypes: true })) {
|
|
146573
147702
|
const path2 = join98(dir, entry.name);
|
|
146574
147703
|
if (entry.isDirectory()) {
|
|
146575
147704
|
total += totalSize(path2);
|
|
@@ -148018,7 +149147,7 @@ __export(synthesize_exports, {
|
|
|
148018
149147
|
synthesize: () => synthesize
|
|
148019
149148
|
});
|
|
148020
149149
|
import { execFileSync as execFileSync14 } from "child_process";
|
|
148021
|
-
import { existsSync as existsSync95, writeFileSync as writeFileSync38, mkdirSync as mkdirSync48, readdirSync as
|
|
149150
|
+
import { existsSync as existsSync95, writeFileSync as writeFileSync38, mkdirSync as mkdirSync48, readdirSync as readdirSync31, unlinkSync as unlinkSync8 } from "fs";
|
|
148022
149151
|
import { join as join104, dirname as dirname50, basename as basename20 } from "path";
|
|
148023
149152
|
import { homedir as homedir19 } from "os";
|
|
148024
149153
|
function ensureSynthScript() {
|
|
@@ -148027,10 +149156,10 @@ function ensureSynthScript() {
|
|
|
148027
149156
|
writeFileSync38(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
148028
149157
|
const currentName = basename20(SCRIPT_PATH);
|
|
148029
149158
|
try {
|
|
148030
|
-
for (const entry of
|
|
149159
|
+
for (const entry of readdirSync31(SCRIPT_DIR)) {
|
|
148031
149160
|
if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
|
|
148032
149161
|
try {
|
|
148033
|
-
|
|
149162
|
+
unlinkSync8(join104(SCRIPT_DIR, entry));
|
|
148034
149163
|
} catch {
|
|
148035
149164
|
}
|
|
148036
149165
|
}
|
|
@@ -148875,7 +150004,7 @@ __export(upgrade_exports, {
|
|
|
148875
150004
|
upgradeProjectPins: () => upgradeProjectPins
|
|
148876
150005
|
});
|
|
148877
150006
|
import { execFileSync as execFileSync16 } from "child_process";
|
|
148878
|
-
import { existsSync as existsSync99, readFileSync as readFileSync66, writeFileSync as writeFileSync39, renameSync as
|
|
150007
|
+
import { existsSync as existsSync99, readFileSync as readFileSync66, writeFileSync as writeFileSync39, renameSync as renameSync14 } from "fs";
|
|
148879
150008
|
import { resolve as resolve65 } from "path";
|
|
148880
150009
|
async function confirmUpgrade() {
|
|
148881
150010
|
const shouldUpgrade = await ue({ message: "Upgrade now?" });
|
|
@@ -148948,7 +150077,7 @@ async function upgradeProjectPins(dir, opts) {
|
|
|
148948
150077
|
const tmp = `${pkgPath}.tmp`;
|
|
148949
150078
|
writeFileSync39(tmp, `${JSON.stringify(raw, null, 2)}
|
|
148950
150079
|
`, "utf-8");
|
|
148951
|
-
|
|
150080
|
+
renameSync14(tmp, pkgPath);
|
|
148952
150081
|
}
|
|
148953
150082
|
return { changed: rewrite.changed, from: rewrite.fromVersions, to: latest, path: pkgPath };
|
|
148954
150083
|
}
|
|
@@ -149215,7 +150344,7 @@ __export(feedback_exports, {
|
|
|
149215
150344
|
default: () => feedback_default,
|
|
149216
150345
|
examples: () => examples26
|
|
149217
150346
|
});
|
|
149218
|
-
import { randomUUID as
|
|
150347
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
149219
150348
|
import { resolve as resolve66 } from "path";
|
|
149220
150349
|
import open from "open";
|
|
149221
150350
|
function normalizeComment(raw) {
|
|
@@ -149368,7 +150497,7 @@ var init_feedback2 = __esm({
|
|
|
149368
150497
|
}
|
|
149369
150498
|
const comment = normalizeComment(args.comment);
|
|
149370
150499
|
const doctorSummary = await getDoctorSummary();
|
|
149371
|
-
const feedbackId =
|
|
150500
|
+
const feedbackId = randomUUID10();
|
|
149372
150501
|
const config = readConfig();
|
|
149373
150502
|
const joinKeys = buildTelemetryJoinKeys({
|
|
149374
150503
|
feedbackId,
|
|
@@ -149593,7 +150722,7 @@ __export(contactSheet_exports, {
|
|
|
149593
150722
|
createSvgContactSheet: () => createSvgContactSheet
|
|
149594
150723
|
});
|
|
149595
150724
|
import sharp from "sharp";
|
|
149596
|
-
import { readdirSync as
|
|
150725
|
+
import { readdirSync as readdirSync33, readFileSync as readFileSync67, writeFileSync as writeFileSync40, unlinkSync as unlinkSync9, existsSync as existsSync100 } from "fs";
|
|
149597
150726
|
import { join as join106, extname as extname19, basename as basename21, dirname as dirname53 } from "path";
|
|
149598
150727
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
149599
150728
|
const {
|
|
@@ -149681,7 +150810,7 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
149681
150810
|
}
|
|
149682
150811
|
async function createScrollContactSheet(screenshotsDir, outputPath, budget = {}) {
|
|
149683
150812
|
if (!existsSync100(screenshotsDir)) return [];
|
|
149684
|
-
const scrollFiles =
|
|
150813
|
+
const scrollFiles = readdirSync33(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
149685
150814
|
if (scrollFiles.length === 0) return [];
|
|
149686
150815
|
const paths = scrollFiles.map((f3) => join106(screenshotsDir, f3));
|
|
149687
150816
|
const labels = scrollFiles.map((f3) => {
|
|
@@ -149698,7 +150827,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath, budget = {})
|
|
|
149698
150827
|
}
|
|
149699
150828
|
async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {}) {
|
|
149700
150829
|
if (!existsSync100(snapshotsDir)) return [];
|
|
149701
|
-
const snapshotFiles =
|
|
150830
|
+
const snapshotFiles = readdirSync33(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
149702
150831
|
if (snapshotFiles.length === 0) return [];
|
|
149703
150832
|
const paths = snapshotFiles.map((f3) => join106(snapshotsDir, f3));
|
|
149704
150833
|
const labels = snapshotFiles.map((f3) => {
|
|
@@ -149716,7 +150845,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {})
|
|
|
149716
150845
|
async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
149717
150846
|
if (!existsSync100(assetsDir)) return [];
|
|
149718
150847
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
149719
|
-
const assetFiles =
|
|
150848
|
+
const assetFiles = readdirSync33(assetsDir).filter((f3) => imageExts.has(extname19(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
149720
150849
|
if (assetFiles.length === 0) return [];
|
|
149721
150850
|
const paths = assetFiles.map((f3) => join106(assetsDir, f3));
|
|
149722
150851
|
return createContactSheetPages(paths, outputPath, {
|
|
@@ -149735,7 +150864,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
149735
150864
|
const seen = /* @__PURE__ */ new Set();
|
|
149736
150865
|
const svgPaths = [];
|
|
149737
150866
|
for (const dir of dirsToScan) {
|
|
149738
|
-
for (const f3 of
|
|
150867
|
+
for (const f3 of readdirSync33(dir).filter((f4) => f4.endsWith(".svg")).sort()) {
|
|
149739
150868
|
if (!seen.has(f3)) {
|
|
149740
150869
|
seen.add(f3);
|
|
149741
150870
|
svgPaths.push(join106(dir, f3));
|
|
@@ -149782,7 +150911,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
149782
150911
|
} finally {
|
|
149783
150912
|
for (const tmp of tmpPaths) {
|
|
149784
150913
|
try {
|
|
149785
|
-
|
|
150914
|
+
unlinkSync9(tmp);
|
|
149786
150915
|
} catch {
|
|
149787
150916
|
}
|
|
149788
150917
|
}
|
|
@@ -155954,7 +157083,7 @@ var require_node_domexception = __commonJS({
|
|
|
155954
157083
|
});
|
|
155955
157084
|
|
|
155956
157085
|
// ../../node_modules/.bun/fetch-blob@3.2.0/node_modules/fetch-blob/from.js
|
|
155957
|
-
import { statSync as statSync35, createReadStream as
|
|
157086
|
+
import { statSync as statSync35, createReadStream as createReadStream8, promises as fs3 } from "fs";
|
|
155958
157087
|
import { basename as basename23 } from "path";
|
|
155959
157088
|
var import_node_domexception, stat, blobFromSync, blobFrom, fileFrom, fileFromSync, fromBlob, fromFile, BlobDataItem;
|
|
155960
157089
|
var init_from = __esm({
|
|
@@ -156006,7 +157135,7 @@ var init_from = __esm({
|
|
|
156006
157135
|
if (mtimeMs > this.lastModified) {
|
|
156007
157136
|
throw new import_node_domexception.default("The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.", "NotReadableError");
|
|
156008
157137
|
}
|
|
156009
|
-
yield*
|
|
157138
|
+
yield* createReadStream8(this.#path, {
|
|
156010
157139
|
start: this.#start,
|
|
156011
157140
|
end: this.#start + this.size - 1
|
|
156012
157141
|
});
|
|
@@ -157673,7 +158802,7 @@ var require_gaxios = __commonJS({
|
|
|
157673
158802
|
var retry_js_1 = require_retry3();
|
|
157674
158803
|
var stream_1 = __require("stream");
|
|
157675
158804
|
var interceptor_js_1 = require_interceptor();
|
|
157676
|
-
var
|
|
158805
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
157677
158806
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
157678
158807
|
var Gaxios = class {
|
|
157679
158808
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -157946,7 +159075,7 @@ var require_gaxios = __commonJS({
|
|
|
157946
159075
|
*/
|
|
157947
159076
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
157948
159077
|
if (opts.multipart?.length) {
|
|
157949
|
-
const boundary = await
|
|
159078
|
+
const boundary = await randomUUID11();
|
|
157950
159079
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
157951
159080
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
157952
159081
|
} else if (shouldDirectlyPassData) {
|
|
@@ -189703,8 +190832,8 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
189703
190832
|
const snapshotDir = opts.outputDir ?? join107(projectDir, "snapshots");
|
|
189704
190833
|
mkdirSync49(snapshotDir, { recursive: true });
|
|
189705
190834
|
try {
|
|
189706
|
-
const { readdirSync:
|
|
189707
|
-
for (const file of
|
|
190835
|
+
const { readdirSync: readdirSync39 } = await import("fs");
|
|
190836
|
+
for (const file of readdirSync39(snapshotDir)) {
|
|
189708
190837
|
if (/\.(png|jpg|jpeg)$/i.test(file)) {
|
|
189709
190838
|
rmSync30(join107(snapshotDir, file), { force: true });
|
|
189710
190839
|
}
|
|
@@ -190159,6 +191288,7 @@ function probeMedia2(mediaPath, ffprobePath) {
|
|
|
190159
191288
|
"stream=color_space,color_transfer,color_primaries,pix_fmt,duration:format=duration",
|
|
190160
191289
|
"-of",
|
|
190161
191290
|
"json",
|
|
191291
|
+
"--",
|
|
190162
191292
|
mediaPath
|
|
190163
191293
|
], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "pipe"] });
|
|
190164
191294
|
const parsed = asRecord(JSON.parse(raw));
|
|
@@ -191614,7 +192744,7 @@ __export(compare_exports, {
|
|
|
191614
192744
|
parseCompareArgs: () => parseCompareArgs,
|
|
191615
192745
|
prepareCompareVariantProjects: () => prepareCompareVariantProjects
|
|
191616
192746
|
});
|
|
191617
|
-
import { cpSync as cpSync6, existsSync as existsSync105, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync17, renameSync as
|
|
192747
|
+
import { cpSync as cpSync6, existsSync as existsSync105, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync17, renameSync as renameSync15, rmSync as rmSync32, statSync as statSync36 } from "fs";
|
|
191618
192748
|
import { tmpdir as tmpdir17 } from "os";
|
|
191619
192749
|
import { basename as basename28, dirname as dirname55, extname as extname23, join as join110 } from "path";
|
|
191620
192750
|
function defaultLabelForPath(input2) {
|
|
@@ -191726,7 +192856,7 @@ function stageHtmlVariant(variant) {
|
|
|
191726
192856
|
});
|
|
191727
192857
|
const sourceName = basename28(variant.inputPath);
|
|
191728
192858
|
if (sourceName !== "index.html") {
|
|
191729
|
-
|
|
192859
|
+
renameSync15(join110(stagedDir, sourceName), join110(stagedDir, "index.html"));
|
|
191730
192860
|
}
|
|
191731
192861
|
return {
|
|
191732
192862
|
...variant,
|
|
@@ -192304,7 +193434,7 @@ __export(video_exports, {
|
|
|
192304
193434
|
runVideoMode: () => runVideoMode,
|
|
192305
193435
|
safeFilename: () => safeFilename
|
|
192306
193436
|
});
|
|
192307
|
-
import { createWriteStream as createWriteStream4, existsSync as existsSync106, mkdirSync as mkdirSync54, readFileSync as readFileSync71, unlinkSync as
|
|
193437
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync106, mkdirSync as mkdirSync54, readFileSync as readFileSync71, unlinkSync as unlinkSync10 } from "fs";
|
|
192308
193438
|
import { resolve as resolve71, join as join113, basename as basename29 } from "path";
|
|
192309
193439
|
async function streamToFile(url, destPath) {
|
|
192310
193440
|
const r2 = await safeFetch(url, {
|
|
@@ -192367,7 +193497,7 @@ async function streamToFile(url, destPath) {
|
|
|
192367
193497
|
file.destroy();
|
|
192368
193498
|
if (e3.code !== "EEXIST") {
|
|
192369
193499
|
try {
|
|
192370
|
-
|
|
193500
|
+
unlinkSync10(destPath);
|
|
192371
193501
|
} catch {
|
|
192372
193502
|
}
|
|
192373
193503
|
}
|
|
@@ -193726,7 +194856,7 @@ var init_designStyleExtractor = __esm({
|
|
|
193726
194856
|
});
|
|
193727
194857
|
|
|
193728
194858
|
// src/capture/fontMetadataExtractor.ts
|
|
193729
|
-
import { readdirSync as
|
|
194859
|
+
import { readdirSync as readdirSync34, readFileSync as readFileSync73, writeFileSync as writeFileSync46, existsSync as existsSync107 } from "fs";
|
|
193730
194860
|
import { join as join114 } from "path";
|
|
193731
194861
|
import * as fontkit from "fontkit";
|
|
193732
194862
|
function isFontCollection(value) {
|
|
@@ -193736,7 +194866,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
193736
194866
|
const files = [];
|
|
193737
194867
|
const unidentified = [];
|
|
193738
194868
|
if (existsSync107(fontsDir)) {
|
|
193739
|
-
const fontFiles =
|
|
194869
|
+
const fontFiles = readdirSync34(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
193740
194870
|
for (const filename of fontFiles) {
|
|
193741
194871
|
const fullPath = join114(fontsDir, filename);
|
|
193742
194872
|
const meta = readSingleFont(fullPath, filename);
|
|
@@ -194049,7 +195179,7 @@ var init_animationCataloger = __esm({
|
|
|
194049
195179
|
});
|
|
194050
195180
|
|
|
194051
195181
|
// src/capture/mediaCapture.ts
|
|
194052
|
-
import { mkdirSync as mkdirSync55, writeFileSync as writeFileSync47, readdirSync as
|
|
195182
|
+
import { mkdirSync as mkdirSync55, writeFileSync as writeFileSync47, readdirSync as readdirSync35, readFileSync as readFileSync74, statSync as statSync37 } from "fs";
|
|
194053
195183
|
import { join as join115, extname as extname25 } from "path";
|
|
194054
195184
|
function liveRemainingMs(budget, fallbackMs) {
|
|
194055
195185
|
return budget.remainingMs?.() ?? fallbackMs;
|
|
@@ -194118,7 +195248,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
194118
195248
|
const manifest = [];
|
|
194119
195249
|
const previewDir = join115(lottieDir, "previews");
|
|
194120
195250
|
mkdirSync55(previewDir, { recursive: true });
|
|
194121
|
-
for (const file of
|
|
195251
|
+
for (const file of readdirSync35(lottieDir)) {
|
|
194122
195252
|
if (!file.endsWith(".json")) continue;
|
|
194123
195253
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
194124
195254
|
try {
|
|
@@ -194434,7 +195564,7 @@ var init_mediaCapture = __esm({
|
|
|
194434
195564
|
});
|
|
194435
195565
|
|
|
194436
195566
|
// src/capture/contentExtractor.ts
|
|
194437
|
-
import { existsSync as existsSync108, readdirSync as
|
|
195567
|
+
import { existsSync as existsSync108, readdirSync as readdirSync36, statSync as statSync38, readFileSync as readFileSync75 } from "fs";
|
|
194438
195568
|
import { basename as basename30, join as join116 } from "path";
|
|
194439
195569
|
function resolveVisionPhaseCompletion(outcome, remainingMs) {
|
|
194440
195570
|
if (outcome.budgetExhausted || remainingMs <= 0) {
|
|
@@ -194673,7 +195803,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
194673
195803
|
return response.text?.trim() || "";
|
|
194674
195804
|
};
|
|
194675
195805
|
}
|
|
194676
|
-
const imageFiles =
|
|
195806
|
+
const imageFiles = readdirSync36(join116(outputDir, "assets")).filter(
|
|
194677
195807
|
(f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
|
|
194678
195808
|
);
|
|
194679
195809
|
const BATCH_SIZE = 20;
|
|
@@ -194735,12 +195865,12 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
194735
195865
|
);
|
|
194736
195866
|
const svgFiles = [];
|
|
194737
195867
|
const assetsDir = join116(outputDir, "assets");
|
|
194738
|
-
for (const f3 of
|
|
195868
|
+
for (const f3 of readdirSync36(assetsDir)) {
|
|
194739
195869
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
194740
195870
|
}
|
|
194741
195871
|
const svgsSubdir = join116(assetsDir, "svgs");
|
|
194742
195872
|
if (existsSync108(svgsSubdir)) {
|
|
194743
|
-
for (const f3 of
|
|
195873
|
+
for (const f3 of readdirSync36(svgsSubdir)) {
|
|
194744
195874
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
194745
195875
|
}
|
|
194746
195876
|
}
|
|
@@ -194840,7 +195970,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194840
195970
|
const fontLines = [];
|
|
194841
195971
|
const assetsPath = join116(outputDir, "assets");
|
|
194842
195972
|
try {
|
|
194843
|
-
for (const file of
|
|
195973
|
+
for (const file of readdirSync36(assetsPath)) {
|
|
194844
195974
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
194845
195975
|
const filePath = join116(assetsPath, file);
|
|
194846
195976
|
const stat3 = statSync38(filePath);
|
|
@@ -194872,7 +196002,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194872
196002
|
}
|
|
194873
196003
|
try {
|
|
194874
196004
|
const svgsPath = join116(assetsPath, "svgs");
|
|
194875
|
-
for (const file of
|
|
196005
|
+
for (const file of readdirSync36(svgsPath)) {
|
|
194876
196006
|
if (!file.endsWith(".svg")) continue;
|
|
194877
196007
|
const svgMatch = tokens.svgs.find(
|
|
194878
196008
|
(s2) => s2.label && file.includes(
|
|
@@ -194891,7 +196021,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194891
196021
|
}
|
|
194892
196022
|
try {
|
|
194893
196023
|
const fontsPath = join116(assetsPath, "fonts");
|
|
194894
|
-
for (const file of
|
|
196024
|
+
for (const file of readdirSync36(fontsPath)) {
|
|
194895
196025
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
194896
196026
|
}
|
|
194897
196027
|
} catch {
|
|
@@ -194934,7 +196064,7 @@ var agentPromptGenerator_exports = {};
|
|
|
194934
196064
|
__export(agentPromptGenerator_exports, {
|
|
194935
196065
|
generateAgentPrompt: () => generateAgentPrompt
|
|
194936
196066
|
});
|
|
194937
|
-
import { writeFileSync as writeFileSync48, readdirSync as
|
|
196067
|
+
import { writeFileSync as writeFileSync48, readdirSync as readdirSync37, existsSync as existsSync109 } from "fs";
|
|
194938
196068
|
import { join as join117 } from "path";
|
|
194939
196069
|
function inferColorRole(hex) {
|
|
194940
196070
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -194970,7 +196100,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
194970
196100
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
194971
196101
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
194972
196102
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
194973
|
-
const all =
|
|
196103
|
+
const all = readdirSync37(fullDir).filter((f3) => paginatedRe.test(f3)).map((f3) => ({ name: f3, page: parseInt(f3.match(paginatedRe)?.[1] ?? "0", 10) })).sort((a, b2) => a.page - b2.page).map((entry) => entry.name);
|
|
194974
196104
|
if (all.length === 0) return [];
|
|
194975
196105
|
if (all.length === 1) {
|
|
194976
196106
|
return [`| \`${dir}/${all[0]}\` | ${label2} |`];
|
|
@@ -196560,7 +197690,7 @@ __export(state_exports, {
|
|
|
196560
197690
|
stateFilePath: () => stateFilePath,
|
|
196561
197691
|
writeStackOutputs: () => writeStackOutputs
|
|
196562
197692
|
});
|
|
196563
|
-
import { existsSync as existsSync113, mkdirSync as mkdirSync58, readdirSync as
|
|
197693
|
+
import { existsSync as existsSync113, mkdirSync as mkdirSync58, readdirSync as readdirSync38, readFileSync as readFileSync77, rmSync as rmSync33, writeFileSync as writeFileSync53 } from "fs";
|
|
196564
197694
|
import { dirname as dirname56, join as join121 } from "path";
|
|
196565
197695
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
196566
197696
|
return join121(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -196587,7 +197717,7 @@ function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd())
|
|
|
196587
197717
|
function listStackNames(cwd = process.cwd()) {
|
|
196588
197718
|
const dir = join121(cwd, STATE_DIR_NAME);
|
|
196589
197719
|
if (!existsSync113(dir)) return [];
|
|
196590
|
-
return
|
|
197720
|
+
return readdirSync38(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
196591
197721
|
}
|
|
196592
197722
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
196593
197723
|
const stack = readStackOutputs(stackName, cwd);
|
|
@@ -199001,7 +200131,7 @@ var init_poll = __esm({
|
|
|
199001
200131
|
});
|
|
199002
200132
|
|
|
199003
200133
|
// src/cloud/download.ts
|
|
199004
|
-
import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync60, unlinkSync as
|
|
200134
|
+
import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync60, unlinkSync as unlinkSync11 } from "fs";
|
|
199005
200135
|
import { dirname as dirname58 } from "path";
|
|
199006
200136
|
async function downloadToFile(url, destPath, options = {}) {
|
|
199007
200137
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -199042,7 +200172,7 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
199042
200172
|
await closeFile(file);
|
|
199043
200173
|
if (errored) {
|
|
199044
200174
|
try {
|
|
199045
|
-
|
|
200175
|
+
unlinkSync11(destPath);
|
|
199046
200176
|
} catch {
|
|
199047
200177
|
}
|
|
199048
200178
|
}
|