hyperframes 0.6.54 → 0.6.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -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.6.
|
|
53
|
+
VERSION = true ? "0.6.56" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -3094,18 +3094,18 @@ function serializeValue(value) {
|
|
|
3094
3094
|
}
|
|
3095
3095
|
function serializeObject(obj) {
|
|
3096
3096
|
const entries2 = Object.entries(obj).map(([key2, value]) => {
|
|
3097
|
-
const
|
|
3098
|
-
return `${
|
|
3097
|
+
const safeKey2 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key2) ? key2 : JSON.stringify(key2);
|
|
3098
|
+
return `${safeKey2}: ${serializeValue(value)}`;
|
|
3099
3099
|
});
|
|
3100
3100
|
return `{ ${entries2.join(", ")} }`;
|
|
3101
3101
|
}
|
|
3102
3102
|
function serializeExtras(extras) {
|
|
3103
3103
|
return Object.entries(extras).map(([key2, value]) => {
|
|
3104
|
-
const
|
|
3105
|
-
return `${
|
|
3104
|
+
const safeKey2 = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key2) ? key2 : JSON.stringify(key2);
|
|
3105
|
+
return `${safeKey2}: ${serializeValue(value)}`;
|
|
3106
3106
|
}).join(", ");
|
|
3107
3107
|
}
|
|
3108
|
-
function
|
|
3108
|
+
function getAnimationsForElementId(animations, elementId) {
|
|
3109
3109
|
const selector = `#${elementId}`;
|
|
3110
3110
|
return animations.filter((a) => a.targetSelector === selector);
|
|
3111
3111
|
}
|
|
@@ -35082,7 +35082,7 @@ __export(gsapParser_exports, {
|
|
|
35082
35082
|
SUPPORTED_EASES: () => SUPPORTED_EASES,
|
|
35083
35083
|
SUPPORTED_PROPS: () => SUPPORTED_PROPS,
|
|
35084
35084
|
addAnimationToScript: () => addAnimationToScript,
|
|
35085
|
-
|
|
35085
|
+
getAnimationsForElementId: () => getAnimationsForElementId,
|
|
35086
35086
|
gsapAnimationsToKeyframes: () => gsapAnimationsToKeyframes,
|
|
35087
35087
|
keyframesToGsapAnimations: () => keyframesToGsapAnimations,
|
|
35088
35088
|
parseGsapScript: () => parseGsapScript,
|
|
@@ -35156,6 +35156,112 @@ function resolveNode(node, scope) {
|
|
|
35156
35156
|
function extractLiteralValue(node, scope) {
|
|
35157
35157
|
return resolveNode(node, scope);
|
|
35158
35158
|
}
|
|
35159
|
+
function selectorFromQueryCall(node, scope) {
|
|
35160
|
+
if (node?.type !== "CallExpression") return null;
|
|
35161
|
+
const callee = node.callee;
|
|
35162
|
+
if (callee?.type !== "MemberExpression" || callee.property?.type !== "Identifier") return null;
|
|
35163
|
+
const method = callee.property.name;
|
|
35164
|
+
const argValue = resolveNode(node.arguments?.[0], scope);
|
|
35165
|
+
if (typeof argValue !== "string" || argValue.length === 0) return null;
|
|
35166
|
+
if (QUERY_METHODS.has(method) || method === "toArray") return argValue;
|
|
35167
|
+
if (method === "getElementById") return `#${argValue}`;
|
|
35168
|
+
return null;
|
|
35169
|
+
}
|
|
35170
|
+
function enclosingScopeNode(path2) {
|
|
35171
|
+
let p2 = path2?.parentPath;
|
|
35172
|
+
while (p2) {
|
|
35173
|
+
if (SCOPE_NODE_TYPES.has(p2.node?.type)) return p2.node;
|
|
35174
|
+
p2 = p2.parentPath;
|
|
35175
|
+
}
|
|
35176
|
+
return null;
|
|
35177
|
+
}
|
|
35178
|
+
function scopeChainOf(path2) {
|
|
35179
|
+
const chain = [];
|
|
35180
|
+
let p2 = path2;
|
|
35181
|
+
while (p2) {
|
|
35182
|
+
if (SCOPE_NODE_TYPES.has(p2.node?.type)) chain.push(p2.node);
|
|
35183
|
+
p2 = p2.parentPath;
|
|
35184
|
+
}
|
|
35185
|
+
return chain;
|
|
35186
|
+
}
|
|
35187
|
+
function addBinding(bindings, scopeNode, name, selector) {
|
|
35188
|
+
let scoped = bindings.get(scopeNode);
|
|
35189
|
+
if (!scoped) {
|
|
35190
|
+
scoped = /* @__PURE__ */ new Map();
|
|
35191
|
+
bindings.set(scopeNode, scoped);
|
|
35192
|
+
}
|
|
35193
|
+
if (!scoped.has(name)) scoped.set(name, selector);
|
|
35194
|
+
}
|
|
35195
|
+
function collectTargetBindings(ast, scope) {
|
|
35196
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
35197
|
+
recast.types.visit(ast, {
|
|
35198
|
+
visitVariableDeclarator(path2) {
|
|
35199
|
+
const name = path2.node.id?.name;
|
|
35200
|
+
const selector = selectorFromQueryCall(path2.node.init, scope);
|
|
35201
|
+
if (name && selector !== null) addBinding(bindings, enclosingScopeNode(path2), name, selector);
|
|
35202
|
+
this.traverse(path2);
|
|
35203
|
+
},
|
|
35204
|
+
visitAssignmentExpression(path2) {
|
|
35205
|
+
const left = path2.node.left;
|
|
35206
|
+
const selector = selectorFromQueryCall(path2.node.right, scope);
|
|
35207
|
+
if (left?.type === "Identifier" && selector !== null) {
|
|
35208
|
+
addBinding(bindings, enclosingScopeNode(path2), left.name, selector);
|
|
35209
|
+
}
|
|
35210
|
+
this.traverse(path2);
|
|
35211
|
+
}
|
|
35212
|
+
});
|
|
35213
|
+
recast.types.visit(ast, {
|
|
35214
|
+
visitCallExpression(path2) {
|
|
35215
|
+
const node = path2.node;
|
|
35216
|
+
const callee = node.callee;
|
|
35217
|
+
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && ITERATION_METHODS.has(callee.property.name)) {
|
|
35218
|
+
const collectionSelector = resolveCollectionSelector(callee.object, path2, scope, bindings);
|
|
35219
|
+
const fn = node.arguments?.[0];
|
|
35220
|
+
const param = fn?.params?.[0];
|
|
35221
|
+
if (collectionSelector && param?.type === "Identifier" && isFunctionNode(fn)) {
|
|
35222
|
+
addBinding(bindings, fn, param.name, collectionSelector);
|
|
35223
|
+
}
|
|
35224
|
+
}
|
|
35225
|
+
this.traverse(path2);
|
|
35226
|
+
}
|
|
35227
|
+
});
|
|
35228
|
+
return bindings;
|
|
35229
|
+
}
|
|
35230
|
+
function isFunctionNode(node) {
|
|
35231
|
+
return node?.type === "ArrowFunctionExpression" || node?.type === "FunctionExpression" || node?.type === "FunctionDeclaration";
|
|
35232
|
+
}
|
|
35233
|
+
function resolveCollectionSelector(node, callPath, scope, bindings) {
|
|
35234
|
+
if (node?.type === "Identifier") return lookupBinding(node.name, callPath, bindings);
|
|
35235
|
+
if (node?.type === "CallExpression") return selectorFromQueryCall(node, scope);
|
|
35236
|
+
return null;
|
|
35237
|
+
}
|
|
35238
|
+
function lookupBinding(name, path2, bindings) {
|
|
35239
|
+
for (const scopeNode of scopeChainOf(path2)) {
|
|
35240
|
+
const selector = bindings.get(scopeNode)?.get(name);
|
|
35241
|
+
if (selector !== void 0) return selector;
|
|
35242
|
+
}
|
|
35243
|
+
return null;
|
|
35244
|
+
}
|
|
35245
|
+
function resolveTargetSelector(node, path2, scope, bindings) {
|
|
35246
|
+
if (!node) return null;
|
|
35247
|
+
if (node.type === "StringLiteral" || node.type === "Literal") {
|
|
35248
|
+
return typeof node.value === "string" ? node.value : null;
|
|
35249
|
+
}
|
|
35250
|
+
if (node.type === "Identifier") {
|
|
35251
|
+
return lookupBinding(node.name, path2, bindings);
|
|
35252
|
+
}
|
|
35253
|
+
if (node.type === "CallExpression") {
|
|
35254
|
+
return selectorFromQueryCall(node, scope);
|
|
35255
|
+
}
|
|
35256
|
+
if (node.type === "ArrayExpression") {
|
|
35257
|
+
const parts = node.elements.map((el) => resolveTargetSelector(el, path2, scope, bindings)).filter((s2) => typeof s2 === "string" && s2.length > 0);
|
|
35258
|
+
return parts.length > 0 ? parts.join(", ") : null;
|
|
35259
|
+
}
|
|
35260
|
+
if (node.type === "MemberExpression" && node.object?.type === "Identifier") {
|
|
35261
|
+
return lookupBinding(node.object.name, path2, bindings);
|
|
35262
|
+
}
|
|
35263
|
+
return null;
|
|
35264
|
+
}
|
|
35159
35265
|
function objectExpressionToRecord(node, scope) {
|
|
35160
35266
|
const result = {};
|
|
35161
35267
|
if (node?.type !== "ObjectExpression") return result;
|
|
@@ -35199,13 +35305,20 @@ function findTimelineVar(ast) {
|
|
|
35199
35305
|
});
|
|
35200
35306
|
return { timelineVar, timelineCount };
|
|
35201
35307
|
}
|
|
35202
|
-
function
|
|
35308
|
+
function isTimelineRootedCall(callNode, timelineVar) {
|
|
35309
|
+
let obj = callNode.callee?.object;
|
|
35310
|
+
while (obj?.type === "CallExpression") {
|
|
35311
|
+
obj = obj.callee?.object;
|
|
35312
|
+
}
|
|
35313
|
+
return obj?.type === "Identifier" && obj.name === timelineVar;
|
|
35314
|
+
}
|
|
35315
|
+
function findAllTweenCalls(ast, timelineVar, scope, targetBindings) {
|
|
35203
35316
|
const results = [];
|
|
35204
35317
|
recast.types.visit(ast, {
|
|
35205
35318
|
visitCallExpression(path2) {
|
|
35206
35319
|
const node = path2.node;
|
|
35207
35320
|
const callee = node.callee;
|
|
35208
|
-
if (callee?.type === "MemberExpression" && callee.
|
|
35321
|
+
if (callee?.type === "MemberExpression" && callee.property?.type === "Identifier" && isTimelineRootedCall(node, timelineVar)) {
|
|
35209
35322
|
const method = callee.property.name;
|
|
35210
35323
|
if (!GSAP_METHODS.has(method)) {
|
|
35211
35324
|
this.traverse(path2);
|
|
@@ -35216,8 +35329,7 @@ function findAllTweenCalls(ast, timelineVar) {
|
|
|
35216
35329
|
this.traverse(path2);
|
|
35217
35330
|
return;
|
|
35218
35331
|
}
|
|
35219
|
-
const
|
|
35220
|
-
const selectorValue = selectorArg.type === "StringLiteral" || selectorArg.type === "Literal" ? String(selectorArg.value) : null;
|
|
35332
|
+
const selectorValue = resolveTargetSelector(args[0], path2, scope, targetBindings);
|
|
35221
35333
|
if (!selectorValue) {
|
|
35222
35334
|
this.traverse(path2);
|
|
35223
35335
|
return;
|
|
@@ -35316,14 +35428,25 @@ function assignStableIds(anims) {
|
|
|
35316
35428
|
return { ...anim, id };
|
|
35317
35429
|
});
|
|
35318
35430
|
}
|
|
35431
|
+
function parseGsapAst(script) {
|
|
35432
|
+
const ast = parseScript(script);
|
|
35433
|
+
const scope = collectScopeBindings(ast);
|
|
35434
|
+
const targetBindings = collectTargetBindings(ast, scope);
|
|
35435
|
+
const detection = findTimelineVar(ast);
|
|
35436
|
+
const timelineVar = detection.timelineVar ?? "tl";
|
|
35437
|
+
const calls = findAllTweenCalls(ast, timelineVar, scope, targetBindings);
|
|
35438
|
+
const animations = assignStableIds(calls.map((call) => tweenCallToAnimation(call, scope)));
|
|
35439
|
+
const located = animations.map((animation, i2) => ({
|
|
35440
|
+
id: animation.id,
|
|
35441
|
+
call: calls[i2],
|
|
35442
|
+
animation
|
|
35443
|
+
}));
|
|
35444
|
+
return { ast, scope, timelineVar, detection, located };
|
|
35445
|
+
}
|
|
35319
35446
|
function parseGsapScript(script) {
|
|
35320
35447
|
try {
|
|
35321
|
-
const
|
|
35322
|
-
const
|
|
35323
|
-
const detection = findTimelineVar(ast);
|
|
35324
|
-
const timelineVar = detection.timelineVar ?? "tl";
|
|
35325
|
-
const calls = findAllTweenCalls(ast, timelineVar);
|
|
35326
|
-
const animations = assignStableIds(calls.map((call) => tweenCallToAnimation(call, scope)));
|
|
35448
|
+
const { detection, timelineVar, located } = parseGsapAst(script);
|
|
35449
|
+
const animations = located.map((l) => l.animation);
|
|
35327
35450
|
const timelineMatch = script.match(
|
|
35328
35451
|
new RegExp(
|
|
35329
35452
|
`^[\\s\\S]*?(?:const|let|var)\\s+${timelineVar}\\s*=\\s*gsap\\.timeline\\s*\\([^)]*\\)\\s*;?`
|
|
@@ -35348,52 +35471,203 @@ function parseGsapScript(script) {
|
|
|
35348
35471
|
return { animations: [], timelineVar: "tl", preamble: "", postamble: "" };
|
|
35349
35472
|
}
|
|
35350
35473
|
}
|
|
35351
|
-
function
|
|
35352
|
-
|
|
35474
|
+
function valueToCode(value) {
|
|
35475
|
+
if (typeof value === "string" && value.startsWith("__raw:")) return value.slice(6);
|
|
35476
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
35477
|
+
return String(value);
|
|
35353
35478
|
}
|
|
35354
|
-
function
|
|
35355
|
-
|
|
35356
|
-
|
|
35357
|
-
|
|
35358
|
-
|
|
35479
|
+
function safeKey(key2) {
|
|
35480
|
+
return /^[A-Za-z_$][\w$]*$/.test(key2) ? key2 : JSON.stringify(key2);
|
|
35481
|
+
}
|
|
35482
|
+
function parseExpr(code) {
|
|
35483
|
+
return parseScript(`__hf__ = ${code};`).program.body[0].expression.right;
|
|
35484
|
+
}
|
|
35485
|
+
function propKeyName(prop2) {
|
|
35486
|
+
return prop2?.key?.name ?? prop2?.key?.value;
|
|
35487
|
+
}
|
|
35488
|
+
function isObjectProperty(prop2) {
|
|
35489
|
+
return prop2?.type === "ObjectProperty" || prop2?.type === "Property";
|
|
35490
|
+
}
|
|
35491
|
+
function isEditablePropertyKey(key2) {
|
|
35492
|
+
return !BUILTIN_VAR_KEYS.has(key2) && !DROPPED_VAR_KEYS.has(key2) && !EXTRAS_KEYS.has(key2);
|
|
35493
|
+
}
|
|
35494
|
+
function makeObjectProperty(key2, value) {
|
|
35495
|
+
const obj = parseExpr(`{ ${safeKey(key2)}: ${valueToCode(value)} }`);
|
|
35496
|
+
return obj.properties[0];
|
|
35497
|
+
}
|
|
35498
|
+
function setVarsKey(varsArg, key2, value) {
|
|
35499
|
+
if (varsArg?.type !== "ObjectExpression") return;
|
|
35500
|
+
const existing = varsArg.properties.find(
|
|
35501
|
+
(p2) => isObjectProperty(p2) && propKeyName(p2) === key2
|
|
35359
35502
|
);
|
|
35360
|
-
|
|
35361
|
-
|
|
35362
|
-
|
|
35503
|
+
if (existing) {
|
|
35504
|
+
existing.value = parseExpr(valueToCode(value));
|
|
35505
|
+
} else {
|
|
35506
|
+
varsArg.properties.push(makeObjectProperty(key2, value));
|
|
35507
|
+
}
|
|
35508
|
+
}
|
|
35509
|
+
function reconcileEditableProperties(varsArg, newProps) {
|
|
35510
|
+
if (varsArg?.type !== "ObjectExpression") return;
|
|
35511
|
+
varsArg.properties = varsArg.properties.filter((p2) => {
|
|
35512
|
+
if (!isObjectProperty(p2)) return true;
|
|
35513
|
+
const key2 = propKeyName(p2);
|
|
35514
|
+
if (typeof key2 !== "string") return true;
|
|
35515
|
+
if (!isEditablePropertyKey(key2)) return true;
|
|
35516
|
+
return key2 in newProps;
|
|
35363
35517
|
});
|
|
35518
|
+
for (const [key2, value] of Object.entries(newProps)) {
|
|
35519
|
+
setVarsKey(varsArg, key2, value);
|
|
35520
|
+
}
|
|
35521
|
+
}
|
|
35522
|
+
function applyUpdatesToCall(call, updates) {
|
|
35523
|
+
if (updates.properties) reconcileEditableProperties(call.varsArg, updates.properties);
|
|
35524
|
+
if (updates.fromProperties && call.method === "fromTo") {
|
|
35525
|
+
reconcileEditableProperties(call.fromArg, updates.fromProperties);
|
|
35526
|
+
}
|
|
35527
|
+
if (updates.duration !== void 0) setVarsKey(call.varsArg, "duration", updates.duration);
|
|
35528
|
+
if (updates.ease !== void 0) setVarsKey(call.varsArg, "ease", updates.ease);
|
|
35529
|
+
if (updates.position !== void 0) {
|
|
35530
|
+
const posIdx = call.method === "fromTo" ? 3 : 2;
|
|
35531
|
+
call.node.arguments[posIdx] = parseExpr(valueToCode(updates.position));
|
|
35532
|
+
}
|
|
35533
|
+
}
|
|
35534
|
+
function findStatementPath(path2) {
|
|
35535
|
+
let p2 = path2;
|
|
35536
|
+
while (p2) {
|
|
35537
|
+
if (p2.node?.type === "ExpressionStatement") return p2;
|
|
35538
|
+
p2 = p2.parentPath;
|
|
35539
|
+
}
|
|
35540
|
+
return null;
|
|
35541
|
+
}
|
|
35542
|
+
function buildTweenStatementCode(timelineVar, anim) {
|
|
35543
|
+
const selector = JSON.stringify(anim.targetSelector);
|
|
35544
|
+
const props = { ...anim.properties };
|
|
35545
|
+
if (anim.method !== "set" && anim.duration !== void 0) props.duration = anim.duration;
|
|
35546
|
+
if (anim.ease) props.ease = anim.ease;
|
|
35547
|
+
const entries2 = Object.entries(props).map(([k2, v2]) => `${safeKey(k2)}: ${valueToCode(v2)}`);
|
|
35548
|
+
if (anim.extras) {
|
|
35549
|
+
for (const [k2, v2] of Object.entries(anim.extras)) {
|
|
35550
|
+
entries2.push(`${safeKey(k2)}: ${valueToCode(v2)}`);
|
|
35551
|
+
}
|
|
35552
|
+
}
|
|
35553
|
+
const objCode = `{ ${entries2.join(", ")} }`;
|
|
35554
|
+
const posCode = valueToCode(
|
|
35555
|
+
typeof anim.position === "number" ? anim.position : anim.position ?? 0
|
|
35556
|
+
);
|
|
35557
|
+
if (anim.method === "fromTo") {
|
|
35558
|
+
const fromEntries = Object.entries(anim.fromProperties ?? {}).map(
|
|
35559
|
+
([k2, v2]) => `${safeKey(k2)}: ${valueToCode(v2)}`
|
|
35560
|
+
);
|
|
35561
|
+
const fromCode = `{ ${fromEntries.join(", ")} }`;
|
|
35562
|
+
return `${timelineVar}.fromTo(${selector}, ${fromCode}, ${objCode}, ${posCode});`;
|
|
35563
|
+
}
|
|
35564
|
+
return `${timelineVar}.${anim.method}(${selector}, ${objCode}, ${posCode});`;
|
|
35565
|
+
}
|
|
35566
|
+
function updateAnimationInScript(script, animationId, updates) {
|
|
35567
|
+
let parsed;
|
|
35568
|
+
try {
|
|
35569
|
+
parsed = parseGsapAst(script);
|
|
35570
|
+
} catch (e3) {
|
|
35571
|
+
console.warn("[gsap-parser] updateAnimationInScript parse failed:", e3);
|
|
35572
|
+
return script;
|
|
35573
|
+
}
|
|
35574
|
+
const target = parsed.located.find((l) => l.id === animationId);
|
|
35575
|
+
if (!target) return script;
|
|
35576
|
+
applyUpdatesToCall(target.call, updates);
|
|
35577
|
+
return recast.print(parsed.ast).code;
|
|
35364
35578
|
}
|
|
35365
35579
|
function addAnimationToScript(script, animation) {
|
|
35366
|
-
|
|
35367
|
-
|
|
35580
|
+
let parsed;
|
|
35581
|
+
try {
|
|
35582
|
+
parsed = parseGsapAst(script);
|
|
35583
|
+
} catch (e3) {
|
|
35584
|
+
console.warn("[gsap-parser] addAnimationToScript parse failed:", e3);
|
|
35585
|
+
return { script, id: "" };
|
|
35586
|
+
}
|
|
35587
|
+
if (parsed.located.length === 0 && parsed.detection.timelineVar === null) {
|
|
35588
|
+
return { script, id: "" };
|
|
35589
|
+
}
|
|
35368
35590
|
const id = `anim-${Date.now()}`;
|
|
35369
|
-
const
|
|
35370
|
-
const
|
|
35371
|
-
|
|
35372
|
-
|
|
35373
|
-
|
|
35374
|
-
|
|
35375
|
-
|
|
35376
|
-
|
|
35377
|
-
}
|
|
35591
|
+
const statementCode = buildTweenStatementCode(parsed.timelineVar, animation);
|
|
35592
|
+
const newStatement = parseScript(statementCode).program.body[0];
|
|
35593
|
+
const lastCall = parsed.located[parsed.located.length - 1]?.call;
|
|
35594
|
+
const anchorPath = lastCall ? findStatementPath(lastCall.path) : findTimelineDeclarationPath(parsed.ast, parsed.timelineVar);
|
|
35595
|
+
if (anchorPath) {
|
|
35596
|
+
anchorPath.insertAfter(newStatement);
|
|
35597
|
+
} else {
|
|
35598
|
+
parsed.ast.program.body.push(newStatement);
|
|
35599
|
+
}
|
|
35600
|
+
return { script: recast.print(parsed.ast).code, id };
|
|
35378
35601
|
}
|
|
35379
|
-
function
|
|
35380
|
-
|
|
35381
|
-
|
|
35382
|
-
|
|
35383
|
-
|
|
35384
|
-
|
|
35385
|
-
|
|
35602
|
+
function findTimelineDeclarationPath(ast, timelineVar) {
|
|
35603
|
+
let found = null;
|
|
35604
|
+
recast.types.visit(ast, {
|
|
35605
|
+
visitVariableDeclaration(path2) {
|
|
35606
|
+
if (found) return false;
|
|
35607
|
+
for (const decl of path2.node.declarations ?? []) {
|
|
35608
|
+
if (decl.id?.name === timelineVar && isGsapTimelineCall(decl.init)) {
|
|
35609
|
+
found = path2;
|
|
35610
|
+
return false;
|
|
35611
|
+
}
|
|
35612
|
+
}
|
|
35613
|
+
this.traverse(path2);
|
|
35614
|
+
}
|
|
35615
|
+
});
|
|
35616
|
+
return found;
|
|
35617
|
+
}
|
|
35618
|
+
function findChainParentCall(stmtNode, targetNode) {
|
|
35619
|
+
let found = null;
|
|
35620
|
+
recast.types.visit(stmtNode, {
|
|
35621
|
+
visitCallExpression(p2) {
|
|
35622
|
+
if (found) return false;
|
|
35623
|
+
if (p2.node.callee?.type === "MemberExpression" && p2.node.callee.object === targetNode) {
|
|
35624
|
+
found = p2.node;
|
|
35625
|
+
return false;
|
|
35626
|
+
}
|
|
35627
|
+
this.traverse(p2);
|
|
35628
|
+
}
|
|
35386
35629
|
});
|
|
35630
|
+
return found;
|
|
35387
35631
|
}
|
|
35388
|
-
|
|
35632
|
+
function removeAnimationFromScript(script, animationId) {
|
|
35633
|
+
let parsed;
|
|
35634
|
+
try {
|
|
35635
|
+
parsed = parseGsapAst(script);
|
|
35636
|
+
} catch (e3) {
|
|
35637
|
+
console.warn("[gsap-parser] removeAnimationFromScript parse failed:", e3);
|
|
35638
|
+
return script;
|
|
35639
|
+
}
|
|
35640
|
+
const target = parsed.located.find((l) => l.id === animationId);
|
|
35641
|
+
if (!target) return script;
|
|
35642
|
+
const node = target.call.node;
|
|
35643
|
+
const stmtPath = findStatementPath(target.call.path);
|
|
35644
|
+
if (!stmtPath) return script;
|
|
35645
|
+
const parentCall = findChainParentCall(stmtPath.node, node);
|
|
35646
|
+
if (parentCall) {
|
|
35647
|
+
parentCall.callee.object = node.callee.object;
|
|
35648
|
+
} else if (node.callee?.object?.type === "CallExpression") {
|
|
35649
|
+
stmtPath.node.expression = node.callee.object;
|
|
35650
|
+
} else {
|
|
35651
|
+
stmtPath.prune();
|
|
35652
|
+
}
|
|
35653
|
+
return recast.print(parsed.ast).code;
|
|
35654
|
+
}
|
|
35655
|
+
var recast, import_parser, GSAP_METHODS, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS;
|
|
35389
35656
|
var init_gsapParser = __esm({
|
|
35390
35657
|
"../core/src/parsers/gsapParser.ts"() {
|
|
35391
35658
|
"use strict";
|
|
35392
35659
|
recast = __toESM(require_main2(), 1);
|
|
35393
35660
|
import_parser = __toESM(require_lib(), 1);
|
|
35394
35661
|
init_gsapSerialize();
|
|
35395
|
-
init_gsapSerialize();
|
|
35396
35662
|
GSAP_METHODS = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
35663
|
+
QUERY_METHODS = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
35664
|
+
ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
35665
|
+
SCOPE_NODE_TYPES = /* @__PURE__ */ new Set([
|
|
35666
|
+
"Program",
|
|
35667
|
+
"FunctionDeclaration",
|
|
35668
|
+
"FunctionExpression",
|
|
35669
|
+
"ArrowFunctionExpression"
|
|
35670
|
+
]);
|
|
35397
35671
|
BUILTIN_VAR_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "delay"]);
|
|
35398
35672
|
DROPPED_VAR_KEYS = /* @__PURE__ */ new Set(["keyframes", "onComplete", "onStart", "onUpdate", "onRepeat"]);
|
|
35399
35673
|
EXTRAS_KEYS = /* @__PURE__ */ new Set([
|
|
@@ -37086,122 +37360,51 @@ function readRegisteredTimelineCompositionId(script) {
|
|
|
37086
37360
|
const match = script.match(WINDOW_TIMELINE_ASSIGN_PATTERN);
|
|
37087
37361
|
return match?.[1] || null;
|
|
37088
37362
|
}
|
|
37363
|
+
function unwrapRaw(value) {
|
|
37364
|
+
if (typeof value === "number") return value;
|
|
37365
|
+
if (typeof value !== "string") return void 0;
|
|
37366
|
+
const code = value.startsWith("__raw:") ? value.slice(6) : value;
|
|
37367
|
+
return code.replace(/^\s*["']|["']\s*$/g, "");
|
|
37368
|
+
}
|
|
37369
|
+
function extrasNumber(value) {
|
|
37370
|
+
const unwrapped = unwrapRaw(value);
|
|
37371
|
+
const numeric = typeof unwrapped === "number" ? unwrapped : Number(unwrapped);
|
|
37372
|
+
return Number.isFinite(numeric) ? numeric : 0;
|
|
37373
|
+
}
|
|
37374
|
+
function synthesizeWindowRaw(timelineVar, anim) {
|
|
37375
|
+
const entries2 = Object.entries(anim.properties).map(([k2, v2]) => {
|
|
37376
|
+
if (typeof v2 === "string" && v2.startsWith("__raw:")) return `${k2}: ${v2.slice(6)}`;
|
|
37377
|
+
return `${k2}: ${typeof v2 === "string" ? JSON.stringify(v2) : v2}`;
|
|
37378
|
+
});
|
|
37379
|
+
if (anim.duration !== void 0) entries2.push(`duration: ${anim.duration}`);
|
|
37380
|
+
if (anim.ease) entries2.push(`ease: ${JSON.stringify(anim.ease)}`);
|
|
37381
|
+
const pos = typeof anim.position === "number" ? anim.position : JSON.stringify(anim.position);
|
|
37382
|
+
return `${timelineVar}.${anim.method}("${anim.targetSelector}", { ${entries2.join(", ")} }, ${pos})`;
|
|
37383
|
+
}
|
|
37089
37384
|
async function extractGsapWindows(script) {
|
|
37090
37385
|
if (!/gsap\.timeline/.test(script)) return [];
|
|
37091
37386
|
const parseGsapScript2 = await loadParseGsapScript();
|
|
37092
37387
|
const parsed = parseGsapScript2(script);
|
|
37093
37388
|
if (parsed.animations.length === 0) return [];
|
|
37094
37389
|
const windows = [];
|
|
37095
|
-
const
|
|
37096
|
-
const methodPattern = new RegExp(
|
|
37097
|
-
`${timelineVar}\\.(set|to|from|fromTo)\\s*\\(([^)]+(?:\\{[^}]*\\}[^)]*)+)\\)`,
|
|
37098
|
-
"g"
|
|
37099
|
-
);
|
|
37100
|
-
let match;
|
|
37101
|
-
let index = 0;
|
|
37102
|
-
while ((match = methodPattern.exec(script)) !== null && index < parsed.animations.length) {
|
|
37103
|
-
const raw = match[0];
|
|
37104
|
-
const args = match[2] ?? "";
|
|
37105
|
-
if (!/^\s*["']/.test(args)) continue;
|
|
37106
|
-
const meta = parseGsapWindowMeta(match[1] ?? "", args);
|
|
37107
|
-
const animation = parsed.animations[index];
|
|
37108
|
-
index += 1;
|
|
37109
|
-
if (!animation) continue;
|
|
37390
|
+
for (const animation of parsed.animations) {
|
|
37110
37391
|
if (typeof animation.position !== "number") continue;
|
|
37392
|
+
const repeat = extrasNumber(animation.extras?.repeat);
|
|
37393
|
+
const cycleCount = repeat > 0 ? repeat + 1 : 1;
|
|
37394
|
+
const effectiveDuration = animation.method === "set" ? 0 : (animation.duration ?? 0) * cycleCount;
|
|
37111
37395
|
windows.push({
|
|
37112
37396
|
targetSelector: animation.targetSelector,
|
|
37113
37397
|
position: animation.position,
|
|
37114
|
-
end: animation.position +
|
|
37115
|
-
properties:
|
|
37116
|
-
propertyValues:
|
|
37117
|
-
overwriteAuto:
|
|
37118
|
-
method:
|
|
37119
|
-
raw
|
|
37398
|
+
end: animation.position + effectiveDuration,
|
|
37399
|
+
properties: Object.keys(animation.properties),
|
|
37400
|
+
propertyValues: animation.properties,
|
|
37401
|
+
overwriteAuto: unwrapRaw(animation.extras?.overwrite) === "auto",
|
|
37402
|
+
method: animation.method,
|
|
37403
|
+
raw: synthesizeWindowRaw(parsed.timelineVar, animation)
|
|
37120
37404
|
});
|
|
37121
37405
|
}
|
|
37122
37406
|
return windows;
|
|
37123
37407
|
}
|
|
37124
|
-
function parseGsapWindowMeta(method, argsStr) {
|
|
37125
|
-
const emptyMeta = {
|
|
37126
|
-
effectiveDuration: 0,
|
|
37127
|
-
properties: [],
|
|
37128
|
-
propertyValues: {},
|
|
37129
|
-
overwriteAuto: false
|
|
37130
|
-
};
|
|
37131
|
-
const selectorMatch = argsStr.match(/^\s*["']([^"']+)["']\s*,/);
|
|
37132
|
-
if (!selectorMatch) return emptyMeta;
|
|
37133
|
-
const afterSelector = argsStr.slice(selectorMatch[0].length);
|
|
37134
|
-
let properties = {};
|
|
37135
|
-
let fromProperties = {};
|
|
37136
|
-
if (method === "fromTo") {
|
|
37137
|
-
const firstBrace = afterSelector.indexOf("{");
|
|
37138
|
-
const firstEnd = findMatchingBrace(afterSelector, firstBrace);
|
|
37139
|
-
if (firstBrace !== -1 && firstEnd !== -1) {
|
|
37140
|
-
fromProperties = parseLooseObjectLiteral(afterSelector.slice(firstBrace, firstEnd + 1));
|
|
37141
|
-
const secondPart = afterSelector.slice(firstEnd + 1);
|
|
37142
|
-
const secondBrace = secondPart.indexOf("{");
|
|
37143
|
-
const secondEnd = findMatchingBrace(secondPart, secondBrace);
|
|
37144
|
-
if (secondBrace !== -1 && secondEnd !== -1) {
|
|
37145
|
-
properties = parseLooseObjectLiteral(secondPart.slice(secondBrace, secondEnd + 1));
|
|
37146
|
-
}
|
|
37147
|
-
}
|
|
37148
|
-
} else {
|
|
37149
|
-
const braceStart = afterSelector.indexOf("{");
|
|
37150
|
-
const braceEnd = findMatchingBrace(afterSelector, braceStart);
|
|
37151
|
-
if (braceStart !== -1 && braceEnd !== -1) {
|
|
37152
|
-
properties = parseLooseObjectLiteral(afterSelector.slice(braceStart, braceEnd + 1));
|
|
37153
|
-
}
|
|
37154
|
-
}
|
|
37155
|
-
const duration = numberValue(properties.duration) || 0;
|
|
37156
|
-
const repeat = numberValue(properties.repeat) || 0;
|
|
37157
|
-
const cycleCount = repeat > 0 ? repeat + 1 : 1;
|
|
37158
|
-
const effectiveDuration = duration * cycleCount;
|
|
37159
|
-
const overwriteAuto = stringValue(properties.overwrite) === "auto";
|
|
37160
|
-
const propertyNames = /* @__PURE__ */ new Set();
|
|
37161
|
-
for (const key2 of Object.keys(fromProperties)) {
|
|
37162
|
-
if (!META_GSAP_KEYS.has(key2)) propertyNames.add(key2);
|
|
37163
|
-
}
|
|
37164
|
-
for (const key2 of Object.keys(properties)) {
|
|
37165
|
-
if (!META_GSAP_KEYS.has(key2)) propertyNames.add(key2);
|
|
37166
|
-
}
|
|
37167
|
-
return {
|
|
37168
|
-
effectiveDuration: method === "set" ? 0 : effectiveDuration,
|
|
37169
|
-
properties: [...propertyNames],
|
|
37170
|
-
propertyValues: properties,
|
|
37171
|
-
overwriteAuto
|
|
37172
|
-
};
|
|
37173
|
-
}
|
|
37174
|
-
function parseLooseObjectLiteral(source) {
|
|
37175
|
-
const result = {};
|
|
37176
|
-
const cleaned = source.replace(/^\{|\}$/g, "").trim();
|
|
37177
|
-
if (!cleaned) return result;
|
|
37178
|
-
const propertyPattern = /(\w+)\s*:\s*("[^"]*"|'[^']*'|true|false|-?[\d.]+|[a-zA-Z_][\w.]*)/g;
|
|
37179
|
-
let match;
|
|
37180
|
-
while ((match = propertyPattern.exec(cleaned)) !== null) {
|
|
37181
|
-
const key2 = match[1];
|
|
37182
|
-
const rawValue = match[2];
|
|
37183
|
-
if (!key2 || rawValue == null) continue;
|
|
37184
|
-
if (rawValue.startsWith('"') && rawValue.endsWith('"') || rawValue.startsWith("'") && rawValue.endsWith("'")) {
|
|
37185
|
-
result[key2] = rawValue.slice(1, -1);
|
|
37186
|
-
continue;
|
|
37187
|
-
}
|
|
37188
|
-
const numeric = Number(rawValue);
|
|
37189
|
-
result[key2] = Number.isFinite(numeric) ? numeric : rawValue;
|
|
37190
|
-
}
|
|
37191
|
-
return result;
|
|
37192
|
-
}
|
|
37193
|
-
function findMatchingBrace(source, startIndex) {
|
|
37194
|
-
if (startIndex < 0) return -1;
|
|
37195
|
-
let depth = 0;
|
|
37196
|
-
for (let i2 = startIndex; i2 < source.length; i2++) {
|
|
37197
|
-
if (source[i2] === "{") depth += 1;
|
|
37198
|
-
else if (source[i2] === "}") {
|
|
37199
|
-
depth -= 1;
|
|
37200
|
-
if (depth === 0) return i2;
|
|
37201
|
-
}
|
|
37202
|
-
}
|
|
37203
|
-
return -1;
|
|
37204
|
-
}
|
|
37205
37408
|
function numberValue(value) {
|
|
37206
37409
|
if (typeof value === "number") return value;
|
|
37207
37410
|
if (typeof value === "string" && value.trim()) {
|
|
@@ -37341,12 +37544,11 @@ function cssTransformToGsapProps(cssTransform) {
|
|
|
37341
37544
|
}
|
|
37342
37545
|
return parts.length > 0 ? parts.join(", ") : null;
|
|
37343
37546
|
}
|
|
37344
|
-
var
|
|
37547
|
+
var SCENE_BOUNDARY_EPSILON_SECONDS, gsapRules;
|
|
37345
37548
|
var init_gsap = __esm({
|
|
37346
37549
|
"../core/src/lint/rules/gsap.ts"() {
|
|
37347
37550
|
"use strict";
|
|
37348
37551
|
init_utils2();
|
|
37349
|
-
META_GSAP_KEYS = /* @__PURE__ */ new Set(["duration", "ease", "repeat", "yoyo", "overwrite", "delay"]);
|
|
37350
37552
|
SCENE_BOUNDARY_EPSILON_SECONDS = 0.05;
|
|
37351
37553
|
gsapRules = [
|
|
37352
37554
|
// overlapping_gsap_tweens + gsap_animates_clip_element + unscoped_gsap_selector
|
|
@@ -42355,7 +42557,7 @@ __export(src_exports, {
|
|
|
42355
42557
|
generateGsapTimelineScript: () => generateGsapTimelineScript,
|
|
42356
42558
|
generateHyperframesHtml: () => generateHyperframesHtml,
|
|
42357
42559
|
generateHyperframesStyles: () => generateHyperframesStyles,
|
|
42358
|
-
|
|
42560
|
+
getAnimationsForElementId: () => getAnimationsForElementId,
|
|
42359
42561
|
getDefaultStageZoom: () => getDefaultStageZoom,
|
|
42360
42562
|
getHyperframeRuntimeScript: () => getHyperframeRuntimeScript,
|
|
42361
42563
|
getStageStyles: () => getStageStyles,
|
|
@@ -58183,7 +58385,12 @@ function updateReferences(projectDir, oldPath, newPath) {
|
|
|
58183
58385
|
}
|
|
58184
58386
|
function extractGsapScriptBlock(html) {
|
|
58185
58387
|
const { document: document2 } = parseHTML(html);
|
|
58186
|
-
const scripts =
|
|
58388
|
+
const scripts = [
|
|
58389
|
+
...document2.querySelectorAll("script:not([src])"),
|
|
58390
|
+
...Array.from(document2.querySelectorAll("template")).flatMap(
|
|
58391
|
+
(tmpl) => Array.from(tmpl.querySelectorAll("script:not([src])"))
|
|
58392
|
+
)
|
|
58393
|
+
];
|
|
58187
58394
|
for (const script of scripts) {
|
|
58188
58395
|
const content = script.textContent || "";
|
|
58189
58396
|
if (content.includes("gsap.timeline") || content.includes(".set(") || content.includes(".to(")) {
|
|
@@ -66719,6 +66926,101 @@ var init_videoFrameInjector = __esm({
|
|
|
66719
66926
|
}
|
|
66720
66927
|
});
|
|
66721
66928
|
|
|
66929
|
+
// ../engine/src/services/audioVolumeEnvelope.ts
|
|
66930
|
+
import { readFileSync as readFileSync22, renameSync as renameSync3, writeFileSync as writeFileSync14 } from "fs";
|
|
66931
|
+
import { randomBytes } from "crypto";
|
|
66932
|
+
function parseWavLayout(buffer) {
|
|
66933
|
+
if (buffer.length < 12 || buffer.toString("ascii", 0, 4) !== "RIFF") return null;
|
|
66934
|
+
if (buffer.toString("ascii", 8, 12) !== "WAVE") return null;
|
|
66935
|
+
let offset = 12;
|
|
66936
|
+
let fmt = null;
|
|
66937
|
+
let data = null;
|
|
66938
|
+
while (offset + 8 <= buffer.length) {
|
|
66939
|
+
const chunkId = buffer.toString("ascii", offset, offset + 4);
|
|
66940
|
+
const chunkSize = buffer.readUInt32LE(offset + 4);
|
|
66941
|
+
const body = offset + 8;
|
|
66942
|
+
if (chunkId === "fmt " && body + 16 <= buffer.length) {
|
|
66943
|
+
if (buffer.readUInt16LE(body) !== PCM_FORMAT) return null;
|
|
66944
|
+
fmt = {
|
|
66945
|
+
numChannels: buffer.readUInt16LE(body + 2),
|
|
66946
|
+
sampleRate: buffer.readUInt32LE(body + 4),
|
|
66947
|
+
bitsPerSample: buffer.readUInt16LE(body + 14)
|
|
66948
|
+
};
|
|
66949
|
+
} else if (chunkId === "data") {
|
|
66950
|
+
data = { offset: body, size: Math.min(chunkSize, buffer.length - body) };
|
|
66951
|
+
}
|
|
66952
|
+
offset = body + chunkSize + chunkSize % 2;
|
|
66953
|
+
}
|
|
66954
|
+
if (!fmt || !data) return null;
|
|
66955
|
+
if (fmt.bitsPerSample !== SUPPORTED_BITS || fmt.numChannels < 1) return null;
|
|
66956
|
+
return {
|
|
66957
|
+
numChannels: fmt.numChannels,
|
|
66958
|
+
sampleRate: fmt.sampleRate,
|
|
66959
|
+
dataOffset: data.offset,
|
|
66960
|
+
dataSize: data.size
|
|
66961
|
+
};
|
|
66962
|
+
}
|
|
66963
|
+
function toRelativeEnvelope(keyframes, trackStart, baseVolume) {
|
|
66964
|
+
const points = keyframes.filter((k2) => Number.isFinite(k2.time) && Number.isFinite(k2.volume)).map((k2) => ({
|
|
66965
|
+
time: Math.max(0, k2.time - trackStart),
|
|
66966
|
+
volume: Math.max(0, Math.min(1, k2.volume))
|
|
66967
|
+
})).sort((a, b2) => a.time - b2.time);
|
|
66968
|
+
const deduped = [];
|
|
66969
|
+
for (const point of points) {
|
|
66970
|
+
const previous = deduped.at(-1);
|
|
66971
|
+
if (previous && Math.abs(previous.time - point.time) < 1e-9) previous.volume = point.volume;
|
|
66972
|
+
else deduped.push(point);
|
|
66973
|
+
}
|
|
66974
|
+
if (deduped.length === 0) return deduped;
|
|
66975
|
+
if (deduped[0].time > 0) {
|
|
66976
|
+
deduped.unshift({ time: 0, volume: Math.max(0, Math.min(1, baseVolume)) });
|
|
66977
|
+
}
|
|
66978
|
+
return deduped;
|
|
66979
|
+
}
|
|
66980
|
+
function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
|
|
66981
|
+
const envelope = toRelativeEnvelope(keyframes, trackStart, baseVolume);
|
|
66982
|
+
if (envelope.length === 0) return false;
|
|
66983
|
+
try {
|
|
66984
|
+
const buffer = readFileSync22(wavPath);
|
|
66985
|
+
const layout2 = parseWavLayout(buffer);
|
|
66986
|
+
if (!layout2) return false;
|
|
66987
|
+
const { numChannels, sampleRate, dataOffset, dataSize } = layout2;
|
|
66988
|
+
const bytesPerSample = SUPPORTED_BITS / 8;
|
|
66989
|
+
const frameBytes = numChannels * bytesPerSample;
|
|
66990
|
+
const frameCount = Math.floor(dataSize / frameBytes);
|
|
66991
|
+
let segment = 0;
|
|
66992
|
+
for (let frame = 0; frame < frameCount; frame += 1) {
|
|
66993
|
+
const time = frame / sampleRate;
|
|
66994
|
+
while (segment < envelope.length - 2 && time >= envelope[segment + 1].time) segment += 1;
|
|
66995
|
+
const a = envelope[segment];
|
|
66996
|
+
const b2 = envelope[segment + 1] ?? a;
|
|
66997
|
+
const span = b2.time - a.time;
|
|
66998
|
+
const progress = span <= 0 ? 0 : Math.min(1, Math.max(0, (time - a.time) / span));
|
|
66999
|
+
const gain = a.volume + (b2.volume - a.volume) * progress;
|
|
67000
|
+
const base = dataOffset + frame * frameBytes;
|
|
67001
|
+
for (let channel = 0; channel < numChannels; channel += 1) {
|
|
67002
|
+
const at3 = base + channel * bytesPerSample;
|
|
67003
|
+
const scaled = Math.round(buffer.readInt16LE(at3) * gain);
|
|
67004
|
+
buffer.writeInt16LE(scaled < -32768 ? -32768 : scaled > 32767 ? 32767 : scaled, at3);
|
|
67005
|
+
}
|
|
67006
|
+
}
|
|
67007
|
+
const tempPath = `${wavPath}.${randomBytes(6).toString("hex")}.tmp`;
|
|
67008
|
+
writeFileSync14(tempPath, buffer);
|
|
67009
|
+
renameSync3(tempPath, wavPath);
|
|
67010
|
+
return true;
|
|
67011
|
+
} catch {
|
|
67012
|
+
return false;
|
|
67013
|
+
}
|
|
67014
|
+
}
|
|
67015
|
+
var PCM_FORMAT, SUPPORTED_BITS;
|
|
67016
|
+
var init_audioVolumeEnvelope = __esm({
|
|
67017
|
+
"../engine/src/services/audioVolumeEnvelope.ts"() {
|
|
67018
|
+
"use strict";
|
|
67019
|
+
PCM_FORMAT = 1;
|
|
67020
|
+
SUPPORTED_BITS = 16;
|
|
67021
|
+
}
|
|
67022
|
+
});
|
|
67023
|
+
|
|
66722
67024
|
// ../engine/src/services/audioMixer.ts
|
|
66723
67025
|
import { existsSync as existsSync27, mkdirSync as mkdirSync16, rmSync as rmSync6 } from "fs";
|
|
66724
67026
|
import { isAbsolute as isAbsolute6, join as join29, dirname as dirname10 } from "path";
|
|
@@ -66732,10 +67034,47 @@ function formatFilterNumber(value) {
|
|
|
66732
67034
|
function escapeExpressionCommas(expression) {
|
|
66733
67035
|
return expression.replace(/\\/g, "\\\\").replace(/,/g, "\\,");
|
|
66734
67036
|
}
|
|
66735
|
-
function
|
|
67037
|
+
function simplifyVolumeKeyframes(keyframes) {
|
|
67038
|
+
if (keyframes.length < 3) return keyframes;
|
|
67039
|
+
const keep = new Array(keyframes.length).fill(false);
|
|
67040
|
+
keep[0] = true;
|
|
67041
|
+
keep[keyframes.length - 1] = true;
|
|
67042
|
+
const stack = [[0, keyframes.length - 1]];
|
|
67043
|
+
while (stack.length > 0) {
|
|
67044
|
+
const [startIndex, endIndex] = stack.pop();
|
|
67045
|
+
const start = keyframes[startIndex];
|
|
67046
|
+
const end = keyframes[endIndex];
|
|
67047
|
+
const span = end.time - start.time;
|
|
67048
|
+
let maxDistance = VOLUME_SIMPLIFY_EPSILON;
|
|
67049
|
+
let splitIndex = -1;
|
|
67050
|
+
for (let i2 = startIndex + 1; i2 < endIndex; i2 += 1) {
|
|
67051
|
+
const point = keyframes[i2];
|
|
67052
|
+
const interpolated = span === 0 ? start.volume : start.volume + (end.volume - start.volume) * (point.time - start.time) / span;
|
|
67053
|
+
const distance = Math.abs(point.volume - interpolated);
|
|
67054
|
+
if (distance > maxDistance) {
|
|
67055
|
+
maxDistance = distance;
|
|
67056
|
+
splitIndex = i2;
|
|
67057
|
+
}
|
|
67058
|
+
}
|
|
67059
|
+
if (splitIndex !== -1) {
|
|
67060
|
+
keep[splitIndex] = true;
|
|
67061
|
+
stack.push([startIndex, splitIndex], [splitIndex, endIndex]);
|
|
67062
|
+
}
|
|
67063
|
+
}
|
|
67064
|
+
const simplified = keyframes.filter((_, i2) => keep[i2]);
|
|
67065
|
+
if (simplified.length <= MAX_VOLUME_SEGMENTS) return simplified;
|
|
67066
|
+
const step = (simplified.length - 1) / (MAX_VOLUME_SEGMENTS - 1);
|
|
67067
|
+
const sampled = [];
|
|
67068
|
+
for (let i2 = 0; i2 < MAX_VOLUME_SEGMENTS; i2 += 1) {
|
|
67069
|
+
const point = simplified[Math.round(i2 * step)];
|
|
67070
|
+
if (sampled.length === 0 || point.time > sampled.at(-1).time) sampled.push(point);
|
|
67071
|
+
}
|
|
67072
|
+
return sampled;
|
|
67073
|
+
}
|
|
67074
|
+
function buildVolumeExpression(track, ignoreKeyframes = false) {
|
|
66736
67075
|
const trimDuration = track.end - track.start;
|
|
66737
67076
|
const staticVolume = clampVolume(track.volume);
|
|
66738
|
-
const keyframes = (track.volumeKeyframes ?? []).filter((keyframe) => Number.isFinite(keyframe.time) && Number.isFinite(keyframe.volume)).map((keyframe) => ({
|
|
67077
|
+
const keyframes = (ignoreKeyframes ? [] : track.volumeKeyframes ?? []).filter((keyframe) => Number.isFinite(keyframe.time) && Number.isFinite(keyframe.volume)).map((keyframe) => ({
|
|
66739
67078
|
time: Math.max(0, Math.min(trimDuration, keyframe.time - track.start)),
|
|
66740
67079
|
volume: clampVolume(keyframe.volume)
|
|
66741
67080
|
})).sort((a, b2) => a.time - b2.time);
|
|
@@ -66752,13 +67091,14 @@ function buildVolumeExpression(track) {
|
|
|
66752
67091
|
deduped.push(keyframe);
|
|
66753
67092
|
}
|
|
66754
67093
|
}
|
|
66755
|
-
|
|
66756
|
-
|
|
67094
|
+
const simplified = simplifyVolumeKeyframes(deduped);
|
|
67095
|
+
if (simplified.length === 1) {
|
|
67096
|
+
return `volume=${formatFilterNumber(simplified[0].volume)}`;
|
|
66757
67097
|
}
|
|
66758
|
-
let expression = formatFilterNumber(
|
|
66759
|
-
for (let i2 =
|
|
66760
|
-
const current =
|
|
66761
|
-
const next =
|
|
67098
|
+
let expression = formatFilterNumber(simplified.at(-1).volume);
|
|
67099
|
+
for (let i2 = simplified.length - 2; i2 >= 0; i2 -= 1) {
|
|
67100
|
+
const current = simplified[i2];
|
|
67101
|
+
const next = simplified[i2 + 1];
|
|
66762
67102
|
const currentTime = formatFilterNumber(current.time);
|
|
66763
67103
|
const nextTime = formatFilterNumber(next.time);
|
|
66764
67104
|
const currentVolume = formatFilterNumber(current.volume);
|
|
@@ -66926,38 +67266,49 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
66926
67266
|
}
|
|
66927
67267
|
const outputDir = dirname10(outputPath);
|
|
66928
67268
|
if (!existsSync27(outputDir)) mkdirSync16(outputDir, { recursive: true });
|
|
66929
|
-
const
|
|
66930
|
-
|
|
66931
|
-
|
|
66932
|
-
|
|
66933
|
-
|
|
66934
|
-
|
|
66935
|
-
|
|
66936
|
-
|
|
66937
|
-
|
|
66938
|
-
|
|
66939
|
-
|
|
66940
|
-
|
|
66941
|
-
|
|
66942
|
-
|
|
66943
|
-
|
|
66944
|
-
|
|
66945
|
-
|
|
66946
|
-
|
|
66947
|
-
|
|
66948
|
-
|
|
66949
|
-
|
|
66950
|
-
|
|
66951
|
-
|
|
66952
|
-
|
|
66953
|
-
|
|
66954
|
-
|
|
66955
|
-
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66959
|
-
|
|
66960
|
-
|
|
67269
|
+
const buildArgs = (ignoreAutomation) => {
|
|
67270
|
+
const inputs = [];
|
|
67271
|
+
const filterParts = [];
|
|
67272
|
+
tracks.forEach((track, i2) => {
|
|
67273
|
+
inputs.push("-i", track.srcPath);
|
|
67274
|
+
const delayMs = Math.round(track.start * 1e3);
|
|
67275
|
+
const trimDuration = track.end - track.start;
|
|
67276
|
+
const volumeFilter = buildVolumeExpression(track, ignoreAutomation);
|
|
67277
|
+
filterParts.push(
|
|
67278
|
+
`[${i2}:a]atrim=0:${trimDuration},${volumeFilter},adelay=${delayMs}|${delayMs},apad=whole_dur=${totalDuration}[a${i2}]`
|
|
67279
|
+
);
|
|
67280
|
+
});
|
|
67281
|
+
const mixInputs = tracks.map((_, i2) => `[a${i2}]`).join("");
|
|
67282
|
+
const weights = tracks.map(() => "1").join(" ");
|
|
67283
|
+
const mixFilter = `${mixInputs}amix=inputs=${tracks.length}:duration=longest:dropout_transition=0:normalize=0:weights='${weights}'[mixed]`;
|
|
67284
|
+
const postMixGainFilter = `[mixed]volume=${masterOutputGain}[out]`;
|
|
67285
|
+
const fullFilter = [...filterParts, mixFilter, postMixGainFilter].join(";");
|
|
67286
|
+
return [
|
|
67287
|
+
...inputs,
|
|
67288
|
+
"-filter_complex",
|
|
67289
|
+
fullFilter,
|
|
67290
|
+
"-map",
|
|
67291
|
+
"[out]",
|
|
67292
|
+
"-acodec",
|
|
67293
|
+
"aac",
|
|
67294
|
+
"-b:a",
|
|
67295
|
+
"192k",
|
|
67296
|
+
"-t",
|
|
67297
|
+
String(totalDuration),
|
|
67298
|
+
"-y",
|
|
67299
|
+
outputPath
|
|
67300
|
+
];
|
|
67301
|
+
};
|
|
67302
|
+
let result = await runFfmpeg(buildArgs(false), { signal, timeout: ffmpegProcessTimeout });
|
|
67303
|
+
let degradedAutomation = false;
|
|
67304
|
+
const hasAutomation = tracks.some((track) => (track.volumeKeyframes?.length ?? 0) > 0);
|
|
67305
|
+
if (!result.success && !signal?.aborted && hasAutomation) {
|
|
67306
|
+
const retry = await runFfmpeg(buildArgs(true), { signal, timeout: ffmpegProcessTimeout });
|
|
67307
|
+
if (retry.success) {
|
|
67308
|
+
result = retry;
|
|
67309
|
+
degradedAutomation = true;
|
|
67310
|
+
}
|
|
67311
|
+
}
|
|
66961
67312
|
if (signal?.aborted) {
|
|
66962
67313
|
return {
|
|
66963
67314
|
success: false,
|
|
@@ -66980,7 +67331,8 @@ async function mixAudioTracks(tracks, outputPath, totalDuration, signal, config)
|
|
|
66980
67331
|
success: true,
|
|
66981
67332
|
outputPath,
|
|
66982
67333
|
durationMs: result.durationMs,
|
|
66983
|
-
tracksProcessed: tracks.length
|
|
67334
|
+
tracksProcessed: tracks.length,
|
|
67335
|
+
error: degradedAutomation ? "Volume automation exceeded this ffmpeg build's expression limits; rendered at base volume" : void 0
|
|
66984
67336
|
};
|
|
66985
67337
|
}
|
|
66986
67338
|
async function processCompositionAudio(elements, baseDir, workDir, outputPath, totalDuration, signal, config, compiledDir) {
|
|
@@ -67052,6 +67404,15 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
67052
67404
|
}
|
|
67053
67405
|
audioSrcPath = trimmedPath;
|
|
67054
67406
|
}
|
|
67407
|
+
let bakedEnvelope = false;
|
|
67408
|
+
if (element.volumeKeyframes && element.volumeKeyframes.length > 0) {
|
|
67409
|
+
bakedEnvelope = applyVolumeEnvelopeToWav(
|
|
67410
|
+
audioSrcPath,
|
|
67411
|
+
element.volumeKeyframes,
|
|
67412
|
+
element.start,
|
|
67413
|
+
element.volume ?? 1
|
|
67414
|
+
);
|
|
67415
|
+
}
|
|
67055
67416
|
tracks.push({
|
|
67056
67417
|
id: element.id,
|
|
67057
67418
|
srcPath: audioSrcPath,
|
|
@@ -67059,8 +67420,9 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
67059
67420
|
end: element.end,
|
|
67060
67421
|
mediaStart: element.mediaStart,
|
|
67061
67422
|
duration: element.end - element.start,
|
|
67062
|
-
|
|
67063
|
-
|
|
67423
|
+
// Gain is already in the samples when baked, so mix at unity.
|
|
67424
|
+
volume: bakedEnvelope ? 1 : element.volume ?? 1,
|
|
67425
|
+
volumeKeyframes: bakedEnvelope ? void 0 : element.volumeKeyframes
|
|
67064
67426
|
});
|
|
67065
67427
|
} catch (err) {
|
|
67066
67428
|
errors.push(`Error: ${element.id} \u2014 ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -67078,6 +67440,7 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
67078
67440
|
error: errors.length > 0 ? `Warnings: ${errors.join(", ")}` : mixResult.error
|
|
67079
67441
|
};
|
|
67080
67442
|
}
|
|
67443
|
+
var MAX_VOLUME_SEGMENTS, VOLUME_SIMPLIFY_EPSILON;
|
|
67081
67444
|
var init_audioMixer = __esm({
|
|
67082
67445
|
"../engine/src/services/audioMixer.ts"() {
|
|
67083
67446
|
"use strict";
|
|
@@ -67088,6 +67451,9 @@ var init_audioMixer = __esm({
|
|
|
67088
67451
|
init_runFfmpeg();
|
|
67089
67452
|
init_htmlTemplate();
|
|
67090
67453
|
init_videoFrameExtractor();
|
|
67454
|
+
init_audioVolumeEnvelope();
|
|
67455
|
+
MAX_VOLUME_SEGMENTS = 32;
|
|
67456
|
+
VOLUME_SIMPLIFY_EPSILON = 5e-3;
|
|
67091
67457
|
}
|
|
67092
67458
|
});
|
|
67093
67459
|
|
|
@@ -67400,7 +67766,7 @@ var init_parallelCoordinator = __esm({
|
|
|
67400
67766
|
// ../engine/src/services/fileServer.ts
|
|
67401
67767
|
import { Hono as Hono2 } from "hono";
|
|
67402
67768
|
import { serve } from "@hono/node-server";
|
|
67403
|
-
import { readFileSync as
|
|
67769
|
+
import { readFileSync as readFileSync23, existsSync as existsSync29, statSync as statSync9 } from "fs";
|
|
67404
67770
|
import { join as join31, extname as extname7 } from "path";
|
|
67405
67771
|
function createFileServer(options) {
|
|
67406
67772
|
const { projectDir, compiledDir, port = 0, stripEmbeddedRuntime = true } = options;
|
|
@@ -67422,11 +67788,11 @@ function createFileServer(options) {
|
|
|
67422
67788
|
const ext = extname7(filePath).toLowerCase();
|
|
67423
67789
|
const contentType = MIME_TYPES2[ext] || "application/octet-stream";
|
|
67424
67790
|
if (ext === ".html") {
|
|
67425
|
-
const rawHtml =
|
|
67791
|
+
const rawHtml = readFileSync23(filePath, "utf-8");
|
|
67426
67792
|
const html = relativePath === "index.html" ? injectScriptsIntoHtml(rawHtml, headScripts, bodyScripts, stripEmbeddedRuntime) : rawHtml;
|
|
67427
67793
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
67428
67794
|
}
|
|
67429
|
-
const content =
|
|
67795
|
+
const content = readFileSync23(filePath);
|
|
67430
67796
|
return new Response(content, {
|
|
67431
67797
|
status: 200,
|
|
67432
67798
|
headers: { "Content-Type": contentType }
|
|
@@ -69145,7 +69511,7 @@ __export(deterministicFonts_exports, {
|
|
|
69145
69511
|
iterateFontFamilyDeclarations: () => iterateFontFamilyDeclarations,
|
|
69146
69512
|
parseFontFamilyValue: () => parseFontFamilyValue
|
|
69147
69513
|
});
|
|
69148
|
-
import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as
|
|
69514
|
+
import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync24, writeFileSync as writeFileSync15 } from "fs";
|
|
69149
69515
|
import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
|
|
69150
69516
|
import { join as join33 } from "path";
|
|
69151
69517
|
function parseFontFamilyValue(value) {
|
|
@@ -69329,7 +69695,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
69329
69695
|
continue;
|
|
69330
69696
|
}
|
|
69331
69697
|
const buffer = Buffer.from(await fontRes.arrayBuffer());
|
|
69332
|
-
|
|
69698
|
+
writeFileSync15(cachePath2, buffer);
|
|
69333
69699
|
} catch (err) {
|
|
69334
69700
|
if (err instanceof FontFetchError) throw err;
|
|
69335
69701
|
if (options.failClosedFontFetch) {
|
|
@@ -69338,7 +69704,7 @@ async function fetchGoogleFont(familyName, options) {
|
|
|
69338
69704
|
continue;
|
|
69339
69705
|
}
|
|
69340
69706
|
}
|
|
69341
|
-
const fontBytes =
|
|
69707
|
+
const fontBytes = readFileSync24(cachePath2);
|
|
69342
69708
|
const dataUri = `data:font/woff2;base64,${fontBytes.toString("base64")}`;
|
|
69343
69709
|
faces.push({ weight, style, dataUri });
|
|
69344
69710
|
}
|
|
@@ -69538,7 +69904,7 @@ var init_deterministicFonts = __esm({
|
|
|
69538
69904
|
|
|
69539
69905
|
// ../producer/src/services/hyperframeRuntimeLoader.ts
|
|
69540
69906
|
import { createHash as createHash6 } from "crypto";
|
|
69541
|
-
import { existsSync as existsSync32, readFileSync as
|
|
69907
|
+
import { existsSync as existsSync32, readFileSync as readFileSync25 } from "fs";
|
|
69542
69908
|
import { dirname as dirname11, resolve as resolve16 } from "path";
|
|
69543
69909
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
69544
69910
|
function resolveHyperframeManifestPath() {
|
|
@@ -69567,7 +69933,7 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
69567
69933
|
`[HyperframeRuntimeLoader] Missing manifest at ${manifestPath}. Build core runtime artifacts before rendering.`
|
|
69568
69934
|
);
|
|
69569
69935
|
}
|
|
69570
|
-
const manifestRaw =
|
|
69936
|
+
const manifestRaw = readFileSync25(manifestPath, "utf8");
|
|
69571
69937
|
const manifest = JSON.parse(manifestRaw);
|
|
69572
69938
|
const runtimeFileName = manifest.artifacts?.iife;
|
|
69573
69939
|
if (!runtimeFileName || !manifest.sha256) {
|
|
@@ -69579,7 +69945,7 @@ function resolveVerifiedHyperframeRuntime() {
|
|
|
69579
69945
|
if (!existsSync32(runtimePath)) {
|
|
69580
69946
|
throw new Error(`[HyperframeRuntimeLoader] Missing runtime artifact at ${runtimePath}.`);
|
|
69581
69947
|
}
|
|
69582
|
-
const runtimeSource =
|
|
69948
|
+
const runtimeSource = readFileSync25(runtimePath, "utf8");
|
|
69583
69949
|
const runtimeSha = createHash6("sha256").update(runtimeSource, "utf8").digest("hex");
|
|
69584
69950
|
if (runtimeSha !== manifest.sha256) {
|
|
69585
69951
|
throw new Error(
|
|
@@ -69618,7 +69984,7 @@ var init_hyperframeRuntimeLoader = __esm({
|
|
|
69618
69984
|
// ../producer/src/services/fileServer.ts
|
|
69619
69985
|
import { Hono as Hono3 } from "hono";
|
|
69620
69986
|
import { serve as serve2 } from "@hono/node-server";
|
|
69621
|
-
import { readFileSync as
|
|
69987
|
+
import { readFileSync as readFileSync26, existsSync as existsSync33, realpathSync, statSync as statSync10 } from "fs";
|
|
69622
69988
|
import { join as join34, extname as extname8, resolve as resolve17, sep as sep5 } from "path";
|
|
69623
69989
|
function isPathInside(child, parent, options = {}) {
|
|
69624
69990
|
const { resolveSymlinks = false, pathModule } = options;
|
|
@@ -69813,7 +70179,7 @@ function createFileServer2(options) {
|
|
|
69813
70179
|
const ext = extname8(filePath).toLowerCase();
|
|
69814
70180
|
const contentType = MIME_TYPES3[ext] || "application/octet-stream";
|
|
69815
70181
|
if (ext === ".html") {
|
|
69816
|
-
const rawHtml =
|
|
70182
|
+
const rawHtml = readFileSync26(filePath, "utf-8");
|
|
69817
70183
|
const isIndex = relativePath === "index.html";
|
|
69818
70184
|
let html = rawHtml;
|
|
69819
70185
|
if (preHeadScripts.length > 0) {
|
|
@@ -69822,7 +70188,7 @@ function createFileServer2(options) {
|
|
|
69822
70188
|
html = isIndex ? injectScriptsIntoHtml(html, headScripts, bodyScripts, stripEmbeddedRuntime) : html;
|
|
69823
70189
|
return c3.text(html, 200, { "Content-Type": contentType });
|
|
69824
70190
|
}
|
|
69825
|
-
const content =
|
|
70191
|
+
const content = readFileSync26(filePath);
|
|
69826
70192
|
return new Response(content, {
|
|
69827
70193
|
status: 200,
|
|
69828
70194
|
headers: { "Content-Type": contentType }
|
|
@@ -70169,7 +70535,7 @@ var init_paths = __esm({
|
|
|
70169
70535
|
});
|
|
70170
70536
|
|
|
70171
70537
|
// ../producer/src/services/render/shared.ts
|
|
70172
|
-
import { copyFileSync as copyFileSync2, cpSync, existsSync as existsSync34, mkdirSync as mkdirSync19, symlinkSync, writeFileSync as
|
|
70538
|
+
import { copyFileSync as copyFileSync2, cpSync, existsSync as existsSync34, mkdirSync as mkdirSync19, symlinkSync, writeFileSync as writeFileSync16 } from "fs";
|
|
70173
70539
|
import { basename as basename4, dirname as dirname12, isAbsolute as isAbsolute7, join as join36, relative as relative5, resolve as resolve18 } from "path";
|
|
70174
70540
|
function projectBrowserEndToCompositionTimeline(existingStart, browserStart, browserEnd) {
|
|
70175
70541
|
return browserEnd + (existingStart - browserStart);
|
|
@@ -70208,11 +70574,11 @@ function resolveDeviceScaleFactor(input2) {
|
|
|
70208
70574
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
70209
70575
|
const compileDir = join36(workDir, "compiled");
|
|
70210
70576
|
mkdirSync19(compileDir, { recursive: true });
|
|
70211
|
-
|
|
70577
|
+
writeFileSync16(join36(compileDir, "index.html"), compiled.html, "utf-8");
|
|
70212
70578
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
70213
70579
|
const outPath = join36(compileDir, srcPath);
|
|
70214
70580
|
mkdirSync19(dirname12(outPath), { recursive: true });
|
|
70215
|
-
|
|
70581
|
+
writeFileSync16(outPath, html, "utf-8");
|
|
70216
70582
|
}
|
|
70217
70583
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
70218
70584
|
const outPath = resolve18(join36(compileDir, relativePath));
|
|
@@ -70246,7 +70612,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
70246
70612
|
renderModeHints: compiled.renderModeHints,
|
|
70247
70613
|
hasShaderTransitions: compiled.hasShaderTransitions
|
|
70248
70614
|
};
|
|
70249
|
-
|
|
70615
|
+
writeFileSync16(join36(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
70250
70616
|
}
|
|
70251
70617
|
}
|
|
70252
70618
|
function applyRenderModeHints(alreadyForced, compiled, log2 = defaultLogger) {
|
|
@@ -70926,7 +71292,7 @@ var init_urlDownloader2 = __esm({
|
|
|
70926
71292
|
});
|
|
70927
71293
|
|
|
70928
71294
|
// ../producer/src/services/htmlCompiler.ts
|
|
70929
|
-
import { readFileSync as
|
|
71295
|
+
import { readFileSync as readFileSync27, existsSync as existsSync35, mkdirSync as mkdirSync20 } from "fs";
|
|
70930
71296
|
import { join as join38, dirname as dirname13, resolve as resolve19 } from "path";
|
|
70931
71297
|
function dedupeElementsById(elements) {
|
|
70932
71298
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -71084,7 +71450,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
71084
71450
|
if (!existsSync35(filePath)) {
|
|
71085
71451
|
continue;
|
|
71086
71452
|
}
|
|
71087
|
-
const rawSubHtml =
|
|
71453
|
+
const rawSubHtml = readFileSync27(filePath, "utf-8");
|
|
71088
71454
|
const nestedVisited = new Set(visited);
|
|
71089
71455
|
nestedVisited.add(filePath);
|
|
71090
71456
|
workItems.push({ srcPath, absoluteStart, absoluteEnd, filePath, rawSubHtml, nestedVisited });
|
|
@@ -71270,7 +71636,7 @@ function inlineSubCompositions2(html, subCompositions, projectDir) {
|
|
|
71270
71636
|
if (!compHtml) {
|
|
71271
71637
|
const filePath = resolve19(projectDir, srcPath);
|
|
71272
71638
|
if (existsSync35(filePath)) {
|
|
71273
|
-
compHtml =
|
|
71639
|
+
compHtml = readFileSync27(filePath, "utf-8");
|
|
71274
71640
|
}
|
|
71275
71641
|
}
|
|
71276
71642
|
return compHtml;
|
|
@@ -71428,9 +71794,9 @@ function collectExternalAssets(html, projectDir) {
|
|
|
71428
71794
|
return null;
|
|
71429
71795
|
}
|
|
71430
71796
|
if (!existsSync35(absPath)) return null;
|
|
71431
|
-
const
|
|
71432
|
-
externalAssets.set(
|
|
71433
|
-
return
|
|
71797
|
+
const safeKey2 = toExternalAssetKey(absPath);
|
|
71798
|
+
externalAssets.set(safeKey2, absPath);
|
|
71799
|
+
return safeKey2;
|
|
71434
71800
|
}
|
|
71435
71801
|
const { document: document2 } = parseHTML(html);
|
|
71436
71802
|
for (const el of document2.querySelectorAll("[src], [href]")) {
|
|
@@ -71486,7 +71852,7 @@ function rewriteUnresolvableGsapToCdn(html, projectDir) {
|
|
|
71486
71852
|
);
|
|
71487
71853
|
}
|
|
71488
71854
|
async function compileForRender(projectDir, htmlPath, downloadDir, options = {}) {
|
|
71489
|
-
const rawHtml = rewriteUnresolvableGsapToCdn(
|
|
71855
|
+
const rawHtml = rewriteUnresolvableGsapToCdn(readFileSync27(htmlPath, "utf-8"), projectDir);
|
|
71490
71856
|
const { html: compiledHtml, unresolvedCompositions } = await compileHtmlFile(
|
|
71491
71857
|
rawHtml,
|
|
71492
71858
|
projectDir,
|
|
@@ -72727,7 +73093,7 @@ var init_hdrImageTransferCache = __esm({
|
|
|
72727
73093
|
});
|
|
72728
73094
|
|
|
72729
73095
|
// ../producer/src/services/render/stages/captureHdrResources.ts
|
|
72730
|
-
import { mkdirSync as mkdirSync21, openSync, readFileSync as
|
|
73096
|
+
import { mkdirSync as mkdirSync21, openSync, readFileSync as readFileSync28, statSync as statSync11 } from "fs";
|
|
72731
73097
|
import { join as join43 } from "path";
|
|
72732
73098
|
function planHdrResources(args) {
|
|
72733
73099
|
const { composition, nativeHdrVideoIds, nativeHdrImageIds, projectDir, compiledDir } = args;
|
|
@@ -72872,7 +73238,7 @@ function decodeHdrImageBuffers(args) {
|
|
|
72872
73238
|
const out = /* @__PURE__ */ new Map();
|
|
72873
73239
|
for (const [imageId, srcPath] of hdrImageSrcPaths) {
|
|
72874
73240
|
try {
|
|
72875
|
-
const decoded = decodePngToRgb48le(
|
|
73241
|
+
const decoded = decodePngToRgb48le(readFileSync28(srcPath));
|
|
72876
73242
|
const layout2 = prep.hdrExtractionDims.get(imageId);
|
|
72877
73243
|
const fitInfo = prep.hdrImageFitInfo.get(imageId);
|
|
72878
73244
|
if (layout2 && (layout2.width !== decoded.width || layout2.height !== decoded.height)) {
|
|
@@ -73143,7 +73509,7 @@ var init_captureHdrFrameShared = __esm({
|
|
|
73143
73509
|
});
|
|
73144
73510
|
|
|
73145
73511
|
// ../producer/src/services/render/stages/captureHdrSequentialLoop.ts
|
|
73146
|
-
import { writeFileSync as
|
|
73512
|
+
import { writeFileSync as writeFileSync17 } from "fs";
|
|
73147
73513
|
import { join as join44 } from "path";
|
|
73148
73514
|
async function runSequentialLayeredFrameLoop(input2) {
|
|
73149
73515
|
const {
|
|
@@ -73264,7 +73630,7 @@ async function runSequentialLayeredFrameLoop(input2) {
|
|
|
73264
73630
|
await compositeHdrFrame(hdrCompositeCtx, normalCanvas, time, stackingInfo, void 0, i2);
|
|
73265
73631
|
addHdrTiming(hdrPerf, "normalCompositeMs", timingStart);
|
|
73266
73632
|
if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
|
|
73267
|
-
|
|
73633
|
+
writeFileSync17(
|
|
73268
73634
|
join44(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
|
|
73269
73635
|
normalCanvas
|
|
73270
73636
|
);
|
|
@@ -73494,7 +73860,7 @@ var init_shaderTransitionWorkerPool = __esm({
|
|
|
73494
73860
|
});
|
|
73495
73861
|
|
|
73496
73862
|
// ../producer/src/services/render/stages/captureHdrHybridLoop.ts
|
|
73497
|
-
import { writeFileSync as
|
|
73863
|
+
import { writeFileSync as writeFileSync18 } from "fs";
|
|
73498
73864
|
import { join as join46 } from "path";
|
|
73499
73865
|
async function runHybridLayeredFrameLoop(input2) {
|
|
73500
73866
|
const {
|
|
@@ -73689,7 +74055,7 @@ async function runHybridLayeredFrameLoop(input2) {
|
|
|
73689
74055
|
await compositeHdrFrame(wctx, canvas, time, stackingInfo, void 0, i2);
|
|
73690
74056
|
addHdrTiming(hdrPerf, "normalCompositeMs", timingStart);
|
|
73691
74057
|
if (debugDumpEnabled && debugDumpDir && i2 % 30 === 0) {
|
|
73692
|
-
|
|
74058
|
+
writeFileSync18(
|
|
73693
74059
|
join46(debugDumpDir, `frame_${String(i2).padStart(4, "0")}_final_rgb48le.bin`),
|
|
73694
74060
|
canvas
|
|
73695
74061
|
);
|
|
@@ -74189,13 +74555,13 @@ var init_assembleStage = __esm({
|
|
|
74189
74555
|
import {
|
|
74190
74556
|
existsSync as existsSync40,
|
|
74191
74557
|
mkdirSync as mkdirSync24,
|
|
74192
|
-
readFileSync as
|
|
74558
|
+
readFileSync as readFileSync29,
|
|
74193
74559
|
readSync,
|
|
74194
74560
|
closeSync,
|
|
74195
74561
|
readdirSync as readdirSync16,
|
|
74196
74562
|
rmSync as rmSync9,
|
|
74197
74563
|
statSync as statSync12,
|
|
74198
|
-
writeFileSync as
|
|
74564
|
+
writeFileSync as writeFileSync19,
|
|
74199
74565
|
copyFileSync as copyFileSync4,
|
|
74200
74566
|
appendFileSync
|
|
74201
74567
|
} from "fs";
|
|
@@ -74796,7 +75162,7 @@ async function compositeHdrFrame(ctx, canvas, time, fullStacking, elementFilter,
|
|
|
74796
75162
|
const after2 = countNonZeroRgb48(canvas);
|
|
74797
75163
|
const dumpName = `frame_${String(debugFrameIndex).padStart(4, "0")}_layer_${String(layerIdx).padStart(2, "0")}_dom.png`;
|
|
74798
75164
|
const dumpPath = join49(debugDumpDir, dumpName);
|
|
74799
|
-
|
|
75165
|
+
writeFileSync19(dumpPath, domPng);
|
|
74800
75166
|
log2.info("[diag] dom layer blit", {
|
|
74801
75167
|
frame: debugFrameIndex,
|
|
74802
75168
|
layerIdx,
|
|
@@ -74926,7 +75292,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
74926
75292
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
74927
75293
|
}
|
|
74928
75294
|
assertNotAborted();
|
|
74929
|
-
const rawEntry =
|
|
75295
|
+
const rawEntry = readFileSync29(htmlPath, "utf-8");
|
|
74930
75296
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
74931
75297
|
const wrapperPath = join49(workDir, "standalone-entry.html");
|
|
74932
75298
|
const projectIndexPath = join49(projectDir, "index.html");
|
|
@@ -74936,7 +75302,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
74936
75302
|
);
|
|
74937
75303
|
}
|
|
74938
75304
|
const standaloneHtml = extractStandaloneEntryFromIndex(
|
|
74939
|
-
|
|
75305
|
+
readFileSync29(projectIndexPath, "utf-8"),
|
|
74940
75306
|
entryFile
|
|
74941
75307
|
);
|
|
74942
75308
|
if (!standaloneHtml) {
|
|
@@ -74944,7 +75310,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
74944
75310
|
`Entry file "${entryFile}" is not mounted from index.html via data-composition-src, so it cannot be rendered independently.`
|
|
74945
75311
|
);
|
|
74946
75312
|
}
|
|
74947
|
-
|
|
75313
|
+
writeFileSync19(wrapperPath, standaloneHtml, "utf-8");
|
|
74948
75314
|
htmlPath = wrapperPath;
|
|
74949
75315
|
log2.info("Extracted standalone entry from index.html host context", {
|
|
74950
75316
|
entryFile
|
|
@@ -75331,7 +75697,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
75331
75697
|
job.perfSummary = perfSummary;
|
|
75332
75698
|
if (job.config.debug) {
|
|
75333
75699
|
try {
|
|
75334
|
-
|
|
75700
|
+
writeFileSync19(perfOutputPath, JSON.stringify(perfSummary, null, 2), "utf-8");
|
|
75335
75701
|
} catch (err) {
|
|
75336
75702
|
log2.debug("Failed to write perf summary", {
|
|
75337
75703
|
perfOutputPath,
|
|
@@ -75468,7 +75834,7 @@ var init_config3 = __esm({
|
|
|
75468
75834
|
});
|
|
75469
75835
|
|
|
75470
75836
|
// ../producer/src/services/hyperframeLint.ts
|
|
75471
|
-
import { existsSync as existsSync41, readFileSync as
|
|
75837
|
+
import { existsSync as existsSync41, readFileSync as readFileSync30, statSync as statSync13 } from "fs";
|
|
75472
75838
|
import { resolve as resolve21, join as join50 } from "path";
|
|
75473
75839
|
function isStringRecord(value) {
|
|
75474
75840
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -75511,7 +75877,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
75511
75877
|
if (existsSync41(absoluteEntryPath) && statSync13(absoluteEntryPath).isFile()) {
|
|
75512
75878
|
return {
|
|
75513
75879
|
entryFile,
|
|
75514
|
-
html:
|
|
75880
|
+
html: readFileSync30(absoluteEntryPath, "utf-8"),
|
|
75515
75881
|
source: "projectDir"
|
|
75516
75882
|
};
|
|
75517
75883
|
}
|
|
@@ -75610,7 +75976,7 @@ import {
|
|
|
75610
75976
|
mkdirSync as mkdirSync25,
|
|
75611
75977
|
statSync as statSync14,
|
|
75612
75978
|
mkdtempSync as mkdtempSync2,
|
|
75613
|
-
writeFileSync as
|
|
75979
|
+
writeFileSync as writeFileSync20,
|
|
75614
75980
|
rmSync as rmSync10,
|
|
75615
75981
|
createReadStream
|
|
75616
75982
|
} from "fs";
|
|
@@ -75669,7 +76035,7 @@ async function prepareRenderBody(body) {
|
|
|
75669
76035
|
}
|
|
75670
76036
|
const tempRoot = process.env.PRODUCER_TMP_PROJECT_DIR || tmpdir4();
|
|
75671
76037
|
const tempProjectDir = mkdtempSync2(join51(tempRoot, "producer-project-"));
|
|
75672
|
-
|
|
76038
|
+
writeFileSync20(join51(tempProjectDir, "index.html"), htmlContent, "utf-8");
|
|
75673
76039
|
return {
|
|
75674
76040
|
prepared: {
|
|
75675
76041
|
input: {
|
|
@@ -76161,7 +76527,7 @@ var init_planHash = __esm({
|
|
|
76161
76527
|
});
|
|
76162
76528
|
|
|
76163
76529
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
76164
|
-
import { existsSync as existsSync43, mkdirSync as mkdirSync26, readFileSync as
|
|
76530
|
+
import { existsSync as existsSync43, mkdirSync as mkdirSync26, readFileSync as readFileSync31, readdirSync as readdirSync17, writeFileSync as writeFileSync21 } from "fs";
|
|
76165
76531
|
import { join as join52, relative as relative6, resolve as resolve23 } from "path";
|
|
76166
76532
|
function stripUndefined(value) {
|
|
76167
76533
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -76204,11 +76570,11 @@ function collectPlanAssetShas(planDir) {
|
|
|
76204
76570
|
const assets = [];
|
|
76205
76571
|
for (const file of files) {
|
|
76206
76572
|
if (file.planRelativePath === COMPILED_INDEX_RELATIVE_PATH) {
|
|
76207
|
-
compositionHtml =
|
|
76573
|
+
compositionHtml = readFileSync31(file.absolutePath);
|
|
76208
76574
|
continue;
|
|
76209
76575
|
}
|
|
76210
76576
|
if (HASH_EXCLUDED_PLAN_FILES.has(file.planRelativePath)) continue;
|
|
76211
|
-
const bytes =
|
|
76577
|
+
const bytes = readFileSync31(file.absolutePath);
|
|
76212
76578
|
assets.push({ path: file.planRelativePath, sha256: sha256Hex(bytes) });
|
|
76213
76579
|
}
|
|
76214
76580
|
if (compositionHtml === null) {
|
|
@@ -76227,8 +76593,8 @@ function recomputePlanHashFromPlanDir(planDir) {
|
|
|
76227
76593
|
if (!existsSync43(encoderJsonPath)) {
|
|
76228
76594
|
throw new Error(`[freezePlan] meta/encoder.json missing: ${encoderJsonPath}`);
|
|
76229
76595
|
}
|
|
76230
|
-
const planJson = JSON.parse(
|
|
76231
|
-
const encoderConfigCanonicalJson =
|
|
76596
|
+
const planJson = JSON.parse(readFileSync31(planJsonPath, "utf-8"));
|
|
76597
|
+
const encoderConfigCanonicalJson = readFileSync31(encoderJsonPath, "utf-8");
|
|
76232
76598
|
const { compositionHtml, assets } = collectPlanAssetShas(planDir);
|
|
76233
76599
|
return computePlanHash({
|
|
76234
76600
|
compositionHtml,
|
|
@@ -76258,7 +76624,7 @@ async function freezePlan(input2) {
|
|
|
76258
76624
|
}
|
|
76259
76625
|
const metaDir = join52(planDir, "meta");
|
|
76260
76626
|
if (!existsSync43(metaDir)) mkdirSync26(metaDir, { recursive: true });
|
|
76261
|
-
|
|
76627
|
+
writeFileSync21(
|
|
76262
76628
|
join52(metaDir, "composition.json"),
|
|
76263
76629
|
`${JSON.stringify(composition, null, 2)}
|
|
76264
76630
|
`,
|
|
@@ -76266,8 +76632,8 @@ async function freezePlan(input2) {
|
|
|
76266
76632
|
);
|
|
76267
76633
|
const encoderForCanonical = stripUndefined(encoder);
|
|
76268
76634
|
const encoderConfigCanonicalJson = canonicalJsonStringify(encoderForCanonical);
|
|
76269
|
-
|
|
76270
|
-
|
|
76635
|
+
writeFileSync21(join52(metaDir, "encoder.json"), encoderConfigCanonicalJson, "utf-8");
|
|
76636
|
+
writeFileSync21(join52(metaDir, "chunks.json"), `${JSON.stringify(chunks, null, 2)}
|
|
76271
76637
|
`, "utf-8");
|
|
76272
76638
|
const { compositionHtml, assets } = collectPlanAssetShas(planDir);
|
|
76273
76639
|
const planHash = computePlanHash({
|
|
@@ -76291,7 +76657,7 @@ async function freezePlan(input2) {
|
|
|
76291
76657
|
hasAudio
|
|
76292
76658
|
};
|
|
76293
76659
|
const planJsonPath = join52(planDir, "plan.json");
|
|
76294
|
-
|
|
76660
|
+
writeFileSync21(planJsonPath, `${JSON.stringify(planJson, null, 2)}
|
|
76295
76661
|
`, "utf-8");
|
|
76296
76662
|
return { planJsonPath, planHash };
|
|
76297
76663
|
}
|
|
@@ -76399,7 +76765,7 @@ var init_runtimeEnvSnapshot = __esm({
|
|
|
76399
76765
|
// ../producer/src/services/distributed/shared.ts
|
|
76400
76766
|
import { execFile as execFileCallback } from "child_process";
|
|
76401
76767
|
import { dirname as dirname17, join as join53 } from "path";
|
|
76402
|
-
import { existsSync as existsSync44, readFileSync as
|
|
76768
|
+
import { existsSync as existsSync44, readFileSync as readFileSync32 } from "fs";
|
|
76403
76769
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
76404
76770
|
import { promisify as promisify2 } from "util";
|
|
76405
76771
|
async function readFfmpegVersion() {
|
|
@@ -76439,7 +76805,7 @@ function readProducerVersion() {
|
|
|
76439
76805
|
const candidate = join53(current, "package.json");
|
|
76440
76806
|
if (existsSync44(candidate)) {
|
|
76441
76807
|
try {
|
|
76442
|
-
const pkg = JSON.parse(
|
|
76808
|
+
const pkg = JSON.parse(readFileSync32(candidate, "utf-8"));
|
|
76443
76809
|
if (pkg.name === "@hyperframes/producer" && typeof pkg.version === "string") {
|
|
76444
76810
|
cachedProducerVersion = pkg.version;
|
|
76445
76811
|
return pkg.version;
|
|
@@ -76473,10 +76839,10 @@ import {
|
|
|
76473
76839
|
existsSync as existsSync45,
|
|
76474
76840
|
mkdirSync as mkdirSync27,
|
|
76475
76841
|
readdirSync as readdirSync18,
|
|
76476
|
-
renameSync as
|
|
76842
|
+
renameSync as renameSync4,
|
|
76477
76843
|
rmSync as rmSync11,
|
|
76478
76844
|
statSync as statSync15,
|
|
76479
|
-
writeFileSync as
|
|
76845
|
+
writeFileSync as writeFileSync22
|
|
76480
76846
|
} from "fs";
|
|
76481
76847
|
import { join as join54, relative as relative7, sep as sep6 } from "path";
|
|
76482
76848
|
function formatBytes(bytes) {
|
|
@@ -76756,12 +77122,12 @@ async function plan(projectDir, config, planDir) {
|
|
|
76756
77122
|
const videoFramesDst = join54(planDir, "video-frames");
|
|
76757
77123
|
if (existsSync45(videoFramesDst)) rmSync11(videoFramesDst, { recursive: true, force: true });
|
|
76758
77124
|
if (existsSync45(stagedVideoFrames)) {
|
|
76759
|
-
|
|
77125
|
+
renameSync4(stagedVideoFrames, videoFramesDst);
|
|
76760
77126
|
} else {
|
|
76761
77127
|
mkdirSync27(videoFramesDst, { recursive: true });
|
|
76762
77128
|
}
|
|
76763
77129
|
if (existsSync45(finalCompiledDir)) rmSync11(finalCompiledDir, { recursive: true, force: true });
|
|
76764
|
-
|
|
77130
|
+
renameSync4(compiledDir, finalCompiledDir);
|
|
76765
77131
|
const planVideosJson = {
|
|
76766
77132
|
videos: composition.videos,
|
|
76767
77133
|
extracted: (extractResult.extractionResult?.extracted ?? []).map((ext) => ({
|
|
@@ -76774,14 +77140,14 @@ async function plan(projectDir, config, planDir) {
|
|
|
76774
77140
|
}))
|
|
76775
77141
|
};
|
|
76776
77142
|
mkdirSync27(join54(planDir, "meta"), { recursive: true });
|
|
76777
|
-
|
|
77143
|
+
writeFileSync22(
|
|
76778
77144
|
join54(planDir, PLAN_VIDEOS_META_RELATIVE_PATH),
|
|
76779
77145
|
JSON.stringify(planVideosJson, null, 2),
|
|
76780
77146
|
"utf-8"
|
|
76781
77147
|
);
|
|
76782
77148
|
const planAudioPath = join54(planDir, "audio.aac");
|
|
76783
77149
|
if (audioResult.hasAudio && existsSync45(audioResult.audioOutputPath)) {
|
|
76784
|
-
|
|
77150
|
+
renameSync4(audioResult.audioOutputPath, planAudioPath);
|
|
76785
77151
|
}
|
|
76786
77152
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
76787
77153
|
const { chunkCount, effectiveChunkSize } = resolveChunkPlan(
|
|
@@ -76918,8 +77284,8 @@ var init_plan = __esm({
|
|
|
76918
77284
|
});
|
|
76919
77285
|
|
|
76920
77286
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
76921
|
-
import { randomBytes } from "crypto";
|
|
76922
|
-
import { existsSync as existsSync46, mkdirSync as mkdirSync28, readFileSync as
|
|
77287
|
+
import { randomBytes as randomBytes2 } from "crypto";
|
|
77288
|
+
import { existsSync as existsSync46, mkdirSync as mkdirSync28, readFileSync as readFileSync33, readdirSync as readdirSync19, rmSync as rmSync12, writeFileSync as writeFileSync23 } from "fs";
|
|
76923
77289
|
import { extname as extname9, join as join55 } from "path";
|
|
76924
77290
|
function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
76925
77291
|
const result = [];
|
|
@@ -76958,10 +77324,10 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos) {
|
|
|
76958
77324
|
return result;
|
|
76959
77325
|
}
|
|
76960
77326
|
function hashChunkOutput(outputPath, kind) {
|
|
76961
|
-
if (kind === "file") return sha256Hex(
|
|
77327
|
+
if (kind === "file") return sha256Hex(readFileSync33(outputPath));
|
|
76962
77328
|
const entries2 = readdirSync19(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
76963
77329
|
const lines = entries2.map(
|
|
76964
|
-
(name) => `${name}\0${sha256Hex(
|
|
77330
|
+
(name) => `${name}\0${sha256Hex(readFileSync33(join55(outputPath, name)))}`
|
|
76965
77331
|
);
|
|
76966
77332
|
return sha256Hex(lines.join("\0"));
|
|
76967
77333
|
}
|
|
@@ -76985,14 +77351,14 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
76985
77351
|
);
|
|
76986
77352
|
}
|
|
76987
77353
|
}
|
|
76988
|
-
const plan2 = JSON.parse(
|
|
76989
|
-
const encoder = JSON.parse(
|
|
76990
|
-
const chunks = JSON.parse(
|
|
77354
|
+
const plan2 = JSON.parse(readFileSync33(planJsonPath, "utf-8"));
|
|
77355
|
+
const encoder = JSON.parse(readFileSync33(encoderJsonPath, "utf-8"));
|
|
77356
|
+
const chunks = JSON.parse(readFileSync33(chunksJsonPath, "utf-8"));
|
|
76991
77357
|
const videosJsonPath = join55(planDir, PLAN_VIDEOS_META_RELATIVE_PATH);
|
|
76992
77358
|
let planVideos = null;
|
|
76993
77359
|
if (existsSync46(videosJsonPath)) {
|
|
76994
77360
|
try {
|
|
76995
|
-
planVideos = JSON.parse(
|
|
77361
|
+
planVideos = JSON.parse(readFileSync33(videosJsonPath, "utf-8"));
|
|
76996
77362
|
} catch (err) {
|
|
76997
77363
|
throw new RenderChunkValidationError(
|
|
76998
77364
|
MISSING_PLAN_ARTIFACT,
|
|
@@ -77074,7 +77440,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
77074
77440
|
rebuildExtractedFramesFromPlanDir(planDir, planVideos.extracted)
|
|
77075
77441
|
)
|
|
77076
77442
|
) : null;
|
|
77077
|
-
const workDir = `${outputChunkPath}.work.${process.pid}.${
|
|
77443
|
+
const workDir = `${outputChunkPath}.work.${process.pid}.${randomBytes2(4).toString("hex")}`;
|
|
77078
77444
|
mkdirSync28(workDir, { recursive: true });
|
|
77079
77445
|
const framesDir = join55(workDir, "captured-frames");
|
|
77080
77446
|
mkdirSync28(framesDir, { recursive: true });
|
|
@@ -77205,7 +77571,7 @@ async function renderChunk(planDir, chunkIndex, outputChunkPath) {
|
|
|
77205
77571
|
producerVersion: plan2.producerVersion,
|
|
77206
77572
|
ffmpegVersion
|
|
77207
77573
|
};
|
|
77208
|
-
|
|
77574
|
+
writeFileSync23(perfPath, `${JSON.stringify(perfPayload2, null, 2)}
|
|
77209
77575
|
`, "utf-8");
|
|
77210
77576
|
try {
|
|
77211
77577
|
rmSync12(workDir, { recursive: true, force: true });
|
|
@@ -77468,11 +77834,11 @@ import {
|
|
|
77468
77834
|
cpSync as cpSync3,
|
|
77469
77835
|
existsSync as existsSync47,
|
|
77470
77836
|
mkdirSync as mkdirSync29,
|
|
77471
|
-
readFileSync as
|
|
77837
|
+
readFileSync as readFileSync34,
|
|
77472
77838
|
readdirSync as readdirSync20,
|
|
77473
77839
|
rmSync as rmSync13,
|
|
77474
77840
|
statSync as statSync16,
|
|
77475
|
-
writeFileSync as
|
|
77841
|
+
writeFileSync as writeFileSync24
|
|
77476
77842
|
} from "fs";
|
|
77477
77843
|
import { dirname as dirname18, join as join56 } from "path";
|
|
77478
77844
|
async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
@@ -77488,8 +77854,8 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
77488
77854
|
if (!existsSync47(chunksJsonPath)) {
|
|
77489
77855
|
throw new Error(`[assemble] planDir missing meta/chunks.json: ${chunksJsonPath}`);
|
|
77490
77856
|
}
|
|
77491
|
-
const plan2 = JSON.parse(
|
|
77492
|
-
const chunks = JSON.parse(
|
|
77857
|
+
const plan2 = JSON.parse(readFileSync34(planJsonPath, "utf-8"));
|
|
77858
|
+
const chunks = JSON.parse(readFileSync34(chunksJsonPath, "utf-8"));
|
|
77493
77859
|
if (chunkPaths.length !== chunks.length) {
|
|
77494
77860
|
throw new Error(
|
|
77495
77861
|
`[assemble] chunkPaths length (${chunkPaths.length}) does not match chunks.json length (${chunks.length}). Adapters must pass one path per chunk, ordered by index.`
|
|
@@ -77526,7 +77892,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
77526
77892
|
} else {
|
|
77527
77893
|
const concatListPath = join56(workDir, "concat-list.txt");
|
|
77528
77894
|
const concatBody = chunkPaths.map((path2) => `file '${path2.replace(/'/g, "'\\''")}'`).join("\n");
|
|
77529
|
-
|
|
77895
|
+
writeFileSync24(concatListPath, `${concatBody}
|
|
77530
77896
|
`, "utf-8");
|
|
77531
77897
|
const concatArgs = [
|
|
77532
77898
|
"-r",
|
|
@@ -77560,7 +77926,7 @@ async function assemble(planDir, chunkPaths, audioPath, outputPath, options) {
|
|
|
77560
77926
|
if (!existsSync47(encoderJsonPath)) {
|
|
77561
77927
|
throw new Error(`[assemble] planDir missing meta/encoder.json: ${encoderJsonPath}`);
|
|
77562
77928
|
}
|
|
77563
|
-
const encoderJson = JSON.parse(
|
|
77929
|
+
const encoderJson = JSON.parse(readFileSync34(encoderJsonPath, "utf-8"));
|
|
77564
77930
|
if (encoderJson.encoder === "libx265-software") {
|
|
77565
77931
|
throw new Error(
|
|
77566
77932
|
`[assemble] cfr=true is not yet supported with codec: "h265". The cfr re-encode pass uses libx264 and would silently transcode the h265 chunks. Either disable cfr or render with codec: "h264".`
|
|
@@ -77821,7 +78187,7 @@ __export(studioServer_exports, {
|
|
|
77821
78187
|
});
|
|
77822
78188
|
import { Hono as Hono5 } from "hono";
|
|
77823
78189
|
import { streamSSE as streamSSE3 } from "hono/streaming";
|
|
77824
|
-
import { existsSync as existsSync48, readFileSync as
|
|
78190
|
+
import { existsSync as existsSync48, readFileSync as readFileSync35, writeFileSync as writeFileSync25, statSync as statSync17 } from "fs";
|
|
77825
78191
|
import { resolve as resolve24, join as join57, basename as basename5 } from "path";
|
|
77826
78192
|
function resolveDistDir() {
|
|
77827
78193
|
return resolveStudioBundle().dir;
|
|
@@ -77870,7 +78236,7 @@ function readStudioManualEditManifestContent(projectDir) {
|
|
|
77870
78236
|
const manifestPath = join57(projectDir, STUDIO_MANUAL_EDITS_PATH2);
|
|
77871
78237
|
if (!existsSync48(manifestPath)) return "";
|
|
77872
78238
|
try {
|
|
77873
|
-
return
|
|
78239
|
+
return readFileSync35(manifestPath, "utf-8");
|
|
77874
78240
|
} catch {
|
|
77875
78241
|
return "";
|
|
77876
78242
|
}
|
|
@@ -77935,7 +78301,7 @@ async function closeThumbnailBrowser() {
|
|
|
77935
78301
|
async function loadPreviewServerBuildSignature() {
|
|
77936
78302
|
const runtimeSignature = await loadRuntimeSourceSignature();
|
|
77937
78303
|
const studioBundle = resolveStudioBundle();
|
|
77938
|
-
const studioIndex = studioBundle.available && existsSync48(studioBundle.indexPath) ?
|
|
78304
|
+
const studioIndex = studioBundle.available && existsSync48(studioBundle.indexPath) ? readFileSync35(studioBundle.indexPath, "utf-8") : "";
|
|
77939
78305
|
return hashSignatureParts([
|
|
77940
78306
|
VERSION,
|
|
77941
78307
|
runtimeSignature,
|
|
@@ -78029,7 +78395,7 @@ function createStudioServer(options) {
|
|
|
78029
78395
|
state.status = "complete";
|
|
78030
78396
|
state.progress = 100;
|
|
78031
78397
|
const metaPath = opts.outputPath.replace(/\.(mp4|webm|mov)$/, ".meta.json");
|
|
78032
|
-
|
|
78398
|
+
writeFileSync25(
|
|
78033
78399
|
metaPath,
|
|
78034
78400
|
JSON.stringify({ status: "complete", durationMs: Date.now() - startTime })
|
|
78035
78401
|
);
|
|
@@ -78040,7 +78406,7 @@ function createStudioServer(options) {
|
|
|
78040
78406
|
emitStudioRenderError(opts, Date.now() - startTime, state.stage, err);
|
|
78041
78407
|
try {
|
|
78042
78408
|
const metaPath = opts.outputPath.replace(/\.(mp4|webm|mov)$/, ".meta.json");
|
|
78043
|
-
|
|
78409
|
+
writeFileSync25(metaPath, JSON.stringify({ status: "failed" }));
|
|
78044
78410
|
} catch {
|
|
78045
78411
|
}
|
|
78046
78412
|
}
|
|
@@ -78125,19 +78491,19 @@ function createStudioServer(options) {
|
|
|
78125
78491
|
async installRegistryBlock(opts) {
|
|
78126
78492
|
const { resolveItem: resolveItem2 } = await Promise.resolve().then(() => (init_resolver(), resolver_exports));
|
|
78127
78493
|
const { installItem: installItem2 } = await Promise.resolve().then(() => (init_installer(), installer_exports));
|
|
78128
|
-
const { readFileSync:
|
|
78494
|
+
const { readFileSync: readFileSync58, writeFileSync: writeFileSync40, existsSync: existsSync81 } = await import("fs");
|
|
78129
78495
|
const { join: join91 } = await import("path");
|
|
78130
78496
|
const item = await resolveItem2(opts.blockName);
|
|
78131
78497
|
const { written } = await installItem2(item, { destDir: opts.project.dir });
|
|
78132
78498
|
const indexPath = join91(opts.project.dir, "index.html");
|
|
78133
78499
|
if (existsSync81(indexPath)) {
|
|
78134
|
-
const indexHtml =
|
|
78500
|
+
const indexHtml = readFileSync58(indexPath, "utf-8");
|
|
78135
78501
|
const hostW = indexHtml.match(/data-width="(\d+)"/)?.[1];
|
|
78136
78502
|
const hostH = indexHtml.match(/data-height="(\d+)"/)?.[1];
|
|
78137
78503
|
if (hostW && hostH) {
|
|
78138
78504
|
for (const absPath of written) {
|
|
78139
78505
|
if (!absPath.endsWith(".html")) continue;
|
|
78140
|
-
let content =
|
|
78506
|
+
let content = readFileSync58(absPath, "utf-8");
|
|
78141
78507
|
content = content.replace(
|
|
78142
78508
|
/(<meta\s+name="viewport"\s+content="width=)\d+(,\s*height=)\d+/i,
|
|
78143
78509
|
`$1${hostW}$2${hostH}`
|
|
@@ -78151,7 +78517,7 @@ function createStudioServer(options) {
|
|
|
78151
78517
|
return match;
|
|
78152
78518
|
}
|
|
78153
78519
|
);
|
|
78154
|
-
|
|
78520
|
+
writeFileSync40(absPath, content, "utf-8");
|
|
78155
78521
|
}
|
|
78156
78522
|
}
|
|
78157
78523
|
}
|
|
@@ -78178,7 +78544,7 @@ function createStudioServer(options) {
|
|
|
78178
78544
|
});
|
|
78179
78545
|
app.get("/api/runtime.js", (c3) => {
|
|
78180
78546
|
const serve4 = async () => {
|
|
78181
|
-
const runtimeSource = await loadRuntimeSource() ?? (existsSync48(runtimePath) ?
|
|
78547
|
+
const runtimeSource = await loadRuntimeSource() ?? (existsSync48(runtimePath) ? readFileSync35(runtimePath, "utf-8") : null);
|
|
78182
78548
|
if (!runtimeSource) return c3.text("runtime not available", 404);
|
|
78183
78549
|
return c3.body(runtimeSource, 200, {
|
|
78184
78550
|
"Content-Type": "text/javascript",
|
|
@@ -78226,7 +78592,7 @@ function createStudioServer(options) {
|
|
|
78226
78592
|
const serveStudioStaticFile = (c3) => {
|
|
78227
78593
|
const filePath = resolve24(studioDir, c3.req.path.slice(1));
|
|
78228
78594
|
if (!existsSync48(filePath) || !statSync17(filePath).isFile()) return c3.text("not found", 404);
|
|
78229
|
-
const content =
|
|
78595
|
+
const content = readFileSync35(filePath);
|
|
78230
78596
|
return new Response(content, {
|
|
78231
78597
|
headers: { "Content-Type": getMimeType(filePath), "Cache-Control": "no-store" }
|
|
78232
78598
|
});
|
|
@@ -78302,7 +78668,7 @@ function createStudioServer(options) {
|
|
|
78302
78668
|
500
|
|
78303
78669
|
);
|
|
78304
78670
|
}
|
|
78305
|
-
let html =
|
|
78671
|
+
let html = readFileSync35(indexPath, "utf-8");
|
|
78306
78672
|
const envScript = buildRuntimeEnvScript();
|
|
78307
78673
|
if (envScript) {
|
|
78308
78674
|
html = html.replace("<head>", `<head>${envScript}`);
|
|
@@ -78817,8 +79183,8 @@ import {
|
|
|
78817
79183
|
mkdirSync as mkdirSync31,
|
|
78818
79184
|
copyFileSync as copyFileSync5,
|
|
78819
79185
|
cpSync as cpSync4,
|
|
78820
|
-
writeFileSync as
|
|
78821
|
-
readFileSync as
|
|
79186
|
+
writeFileSync as writeFileSync26,
|
|
79187
|
+
readFileSync as readFileSync36,
|
|
78822
79188
|
readdirSync as readdirSync21
|
|
78823
79189
|
} from "fs";
|
|
78824
79190
|
import { resolve as resolve26, basename as basename7, join as join59, dirname as dirname20 } from "path";
|
|
@@ -78922,7 +79288,7 @@ function buildPackageScripts() {
|
|
|
78922
79288
|
function writeDefaultPackageJson(destDir, projectName) {
|
|
78923
79289
|
const packageJsonPath = resolve26(destDir, "package.json");
|
|
78924
79290
|
if (existsSync50(packageJsonPath)) return;
|
|
78925
|
-
|
|
79291
|
+
writeFileSync26(
|
|
78926
79292
|
packageJsonPath,
|
|
78927
79293
|
`${JSON.stringify(
|
|
78928
79294
|
{
|
|
@@ -78983,14 +79349,14 @@ ${html}`;
|
|
|
78983
79349
|
}
|
|
78984
79350
|
function writeTailwindSupport(destDir) {
|
|
78985
79351
|
for (const file of listHtmlFiles(destDir)) {
|
|
78986
|
-
const html =
|
|
78987
|
-
|
|
79352
|
+
const html = readFileSync36(file, "utf-8");
|
|
79353
|
+
writeFileSync26(file, injectTailwindBrowserScript(html), "utf-8");
|
|
78988
79354
|
}
|
|
78989
79355
|
}
|
|
78990
79356
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
78991
79357
|
const htmlFiles = readdirSync21(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join59(e3.parentPath, e3.name));
|
|
78992
79358
|
for (const file of htmlFiles) {
|
|
78993
|
-
let content =
|
|
79359
|
+
let content = readFileSync36(file, "utf-8");
|
|
78994
79360
|
if (videoFilename) {
|
|
78995
79361
|
content = content.replaceAll("__VIDEO_SRC__", videoFilename);
|
|
78996
79362
|
} else {
|
|
@@ -79001,7 +79367,7 @@ function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
|
79001
79367
|
}
|
|
79002
79368
|
const dur = durationSeconds ? String(Math.round(durationSeconds * 100) / 100) : "10";
|
|
79003
79369
|
content = content.replaceAll("__VIDEO_DURATION__", dur);
|
|
79004
|
-
|
|
79370
|
+
writeFileSync26(file, content, "utf-8");
|
|
79005
79371
|
}
|
|
79006
79372
|
}
|
|
79007
79373
|
async function patchTranscript(dir, transcriptPath) {
|
|
@@ -79095,7 +79461,7 @@ async function handleVideoFile(videoPath, destDir, interactive) {
|
|
|
79095
79461
|
function applyResolutionPreset(destDir, resolution) {
|
|
79096
79462
|
const { width, height } = CANVAS_DIMENSIONS[resolution];
|
|
79097
79463
|
for (const file of listHtmlFiles(destDir)) {
|
|
79098
|
-
let html =
|
|
79464
|
+
let html = readFileSync36(file, "utf-8");
|
|
79099
79465
|
let changed = false;
|
|
79100
79466
|
const dataWidthRe = /(data-width=)["'](\d+)["']/g;
|
|
79101
79467
|
if (dataWidthRe.test(html)) {
|
|
@@ -79137,7 +79503,7 @@ function applyResolutionPreset(destDir, resolution) {
|
|
|
79137
79503
|
html = html.replace(viewportRe, `$1width=${width}, height=${height}`);
|
|
79138
79504
|
changed = true;
|
|
79139
79505
|
}
|
|
79140
|
-
if (changed)
|
|
79506
|
+
if (changed) writeFileSync26(file, html, "utf-8");
|
|
79141
79507
|
}
|
|
79142
79508
|
}
|
|
79143
79509
|
async function scaffoldProject(destDir, name, templateId, localVideoName, durationSeconds, tailwind = false, resolution) {
|
|
@@ -79151,7 +79517,7 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
79151
79517
|
patchVideoSrc(destDir, localVideoName, durationSeconds);
|
|
79152
79518
|
if (tailwind) writeTailwindSupport(destDir);
|
|
79153
79519
|
if (resolution) applyResolutionPreset(destDir, resolution);
|
|
79154
|
-
|
|
79520
|
+
writeFileSync26(
|
|
79155
79521
|
resolve26(destDir, "meta.json"),
|
|
79156
79522
|
JSON.stringify(
|
|
79157
79523
|
{
|
|
@@ -80090,7 +80456,7 @@ __export(play_exports, {
|
|
|
80090
80456
|
default: () => play_default,
|
|
80091
80457
|
examples: () => examples5
|
|
80092
80458
|
});
|
|
80093
|
-
import { existsSync as existsSync53, readFileSync as
|
|
80459
|
+
import { existsSync as existsSync53, readFileSync as readFileSync37 } from "fs";
|
|
80094
80460
|
import { resolve as resolve30, dirname as dirname21 } from "path";
|
|
80095
80461
|
function commandDir() {
|
|
80096
80462
|
return dirname21(new URL(import.meta.url).pathname);
|
|
@@ -80257,13 +80623,13 @@ var init_play = __esm({
|
|
|
80257
80623
|
const { createAdaptorServer } = await import("@hono/node-server");
|
|
80258
80624
|
const app = new Hono6();
|
|
80259
80625
|
app.get("/player.js", (ctx) => {
|
|
80260
|
-
return ctx.body(
|
|
80626
|
+
return ctx.body(readFileSync37(playerPath, "utf-8"), 200, {
|
|
80261
80627
|
"Content-Type": "application/javascript",
|
|
80262
80628
|
"Cache-Control": "no-cache"
|
|
80263
80629
|
});
|
|
80264
80630
|
});
|
|
80265
80631
|
app.get("/runtime.js", (ctx) => {
|
|
80266
|
-
return ctx.body(
|
|
80632
|
+
return ctx.body(readFileSync37(runtimePath, "utf-8"), 200, {
|
|
80267
80633
|
"Content-Type": "application/javascript",
|
|
80268
80634
|
"Cache-Control": "no-cache"
|
|
80269
80635
|
});
|
|
@@ -80273,7 +80639,7 @@ var init_play = __esm({
|
|
|
80273
80639
|
const filePath = resolve30(project.dir, reqPath);
|
|
80274
80640
|
if (!filePath.startsWith(project.dir)) return ctx.text("Forbidden", 403);
|
|
80275
80641
|
if (!existsSync53(filePath)) return ctx.text("Not found", 404);
|
|
80276
|
-
const content =
|
|
80642
|
+
const content = readFileSync37(filePath, "utf-8");
|
|
80277
80643
|
if (filePath.endsWith(".html")) {
|
|
80278
80644
|
const injected = injectRuntime(content);
|
|
80279
80645
|
return ctx.html(injected);
|
|
@@ -80292,7 +80658,7 @@ var init_play = __esm({
|
|
|
80292
80658
|
mp3: "audio/mpeg",
|
|
80293
80659
|
wav: "audio/wav"
|
|
80294
80660
|
};
|
|
80295
|
-
return ctx.body(
|
|
80661
|
+
return ctx.body(readFileSync37(filePath), 200, {
|
|
80296
80662
|
"Content-Type": types4[ext] ?? "application/octet-stream"
|
|
80297
80663
|
});
|
|
80298
80664
|
});
|
|
@@ -80354,7 +80720,7 @@ var init_play = __esm({
|
|
|
80354
80720
|
|
|
80355
80721
|
// src/utils/publishProject.ts
|
|
80356
80722
|
import { basename as basename9, join as join60, relative as relative9 } from "path";
|
|
80357
|
-
import { readdirSync as readdirSync22, readFileSync as
|
|
80723
|
+
import { readdirSync as readdirSync22, readFileSync as readFileSync38, statSync as statSync19 } from "fs";
|
|
80358
80724
|
import AdmZip from "adm-zip";
|
|
80359
80725
|
function isRecord2(value) {
|
|
80360
80726
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -80473,7 +80839,7 @@ function createPublishArchive(projectDir) {
|
|
|
80473
80839
|
}
|
|
80474
80840
|
const archive = new AdmZip();
|
|
80475
80841
|
for (const filePath of filePaths) {
|
|
80476
|
-
archive.addFile(filePath,
|
|
80842
|
+
archive.addFile(filePath, readFileSync38(join60(projectDir, filePath)));
|
|
80477
80843
|
}
|
|
80478
80844
|
return {
|
|
80479
80845
|
buffer: archive.toBuffer(),
|
|
@@ -80701,9 +81067,9 @@ var init_dom = __esm({
|
|
|
80701
81067
|
});
|
|
80702
81068
|
|
|
80703
81069
|
// src/utils/variables.ts
|
|
80704
|
-
import { readFileSync as
|
|
81070
|
+
import { readFileSync as readFileSync39 } from "fs";
|
|
80705
81071
|
import { resolve as resolve32 } from "path";
|
|
80706
|
-
function parseVariablesArg(inline, filePath, readFile = (p2) =>
|
|
81072
|
+
function parseVariablesArg(inline, filePath, readFile = (p2) => readFileSync39(resolve32(p2), "utf8")) {
|
|
80707
81073
|
if (inline != null && filePath != null) {
|
|
80708
81074
|
return { ok: false, error: { kind: "conflict" } };
|
|
80709
81075
|
}
|
|
@@ -80786,7 +81152,7 @@ function validateVariablesAgainstProject(indexPath, values) {
|
|
|
80786
81152
|
function loadProjectVariableSchema(indexPath) {
|
|
80787
81153
|
let html;
|
|
80788
81154
|
try {
|
|
80789
|
-
html =
|
|
81155
|
+
html = readFileSync39(indexPath, "utf8");
|
|
80790
81156
|
} catch {
|
|
80791
81157
|
return [];
|
|
80792
81158
|
}
|
|
@@ -81050,7 +81416,7 @@ __export(render_exports, {
|
|
|
81050
81416
|
renderLocal: () => renderLocal,
|
|
81051
81417
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
81052
81418
|
});
|
|
81053
|
-
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as
|
|
81419
|
+
import { mkdirSync as mkdirSync32, readdirSync as readdirSync23, readFileSync as readFileSync40, statSync as statSync20, writeFileSync as writeFileSync27, rmSync as rmSync14 } from "fs";
|
|
81054
81420
|
import { cpus as cpus4, freemem as freemem4, tmpdir as tmpdir5 } from "os";
|
|
81055
81421
|
import { resolve as resolve33, dirname as dirname22, join as join62, basename as basename11 } from "path";
|
|
81056
81422
|
import { execFileSync as execFileSync6, spawn as spawn13 } from "child_process";
|
|
@@ -81111,7 +81477,7 @@ function ensureDockerImage(version, quiet) {
|
|
|
81111
81477
|
const dockerfilePath = resolveDockerfilePath();
|
|
81112
81478
|
const tmpDir = join62(tmpdir5(), `hyperframes-docker-${Date.now()}`);
|
|
81113
81479
|
mkdirSync32(tmpDir, { recursive: true });
|
|
81114
|
-
|
|
81480
|
+
writeFileSync27(join62(tmpDir, "Dockerfile"), readFileSync40(dockerfilePath));
|
|
81115
81481
|
try {
|
|
81116
81482
|
execFileSync6(
|
|
81117
81483
|
"docker",
|
|
@@ -81976,7 +82342,7 @@ var init_lint3 = __esm({
|
|
|
81976
82342
|
|
|
81977
82343
|
// src/utils/staticProjectServer.ts
|
|
81978
82344
|
import { createServer } from "http";
|
|
81979
|
-
import { existsSync as existsSync55, readFileSync as
|
|
82345
|
+
import { existsSync as existsSync55, readFileSync as readFileSync41 } from "fs";
|
|
81980
82346
|
import { isAbsolute as isAbsolute9, relative as relative10, resolve as resolve34 } from "path";
|
|
81981
82347
|
async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Failed to bind local HTTP server") {
|
|
81982
82348
|
const server = createServer((req, res) => {
|
|
@@ -81995,7 +82361,7 @@ async function serveStaticProjectHtml(projectDir, html, bindErrorMessage = "Fail
|
|
|
81995
82361
|
}
|
|
81996
82362
|
if (existsSync55(filePath)) {
|
|
81997
82363
|
res.writeHead(200, { "Content-Type": getMimeType(filePath) });
|
|
81998
|
-
res.end(
|
|
82364
|
+
res.end(readFileSync41(filePath));
|
|
81999
82365
|
return;
|
|
82000
82366
|
}
|
|
82001
82367
|
res.writeHead(404);
|
|
@@ -82171,7 +82537,7 @@ __export(layout_exports, {
|
|
|
82171
82537
|
default: () => layout_default,
|
|
82172
82538
|
examples: () => examples9
|
|
82173
82539
|
});
|
|
82174
|
-
import { existsSync as existsSync56, readFileSync as
|
|
82540
|
+
import { existsSync as existsSync56, readFileSync as readFileSync42 } from "fs";
|
|
82175
82541
|
import { dirname as dirname23, join as join63 } from "path";
|
|
82176
82542
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
82177
82543
|
async function getCompositionDuration2(page) {
|
|
@@ -82322,7 +82688,7 @@ function loadLayoutAuditScript() {
|
|
|
82322
82688
|
join63(__dirname2, "commands", "layout-audit.browser.js")
|
|
82323
82689
|
];
|
|
82324
82690
|
for (const candidate of candidates) {
|
|
82325
|
-
if (existsSync56(candidate)) return
|
|
82691
|
+
if (existsSync56(candidate)) return readFileSync42(candidate, "utf-8");
|
|
82326
82692
|
}
|
|
82327
82693
|
throw new Error("Missing layout audit browser script");
|
|
82328
82694
|
}
|
|
@@ -82530,7 +82896,7 @@ __export(info_exports, {
|
|
|
82530
82896
|
default: () => info_default,
|
|
82531
82897
|
examples: () => examples11
|
|
82532
82898
|
});
|
|
82533
|
-
import { readFileSync as
|
|
82899
|
+
import { readFileSync as readFileSync43, readdirSync as readdirSync24, statSync as statSync21 } from "fs";
|
|
82534
82900
|
import { join as join64 } from "path";
|
|
82535
82901
|
function totalSize(dir) {
|
|
82536
82902
|
let total = 0;
|
|
@@ -82567,7 +82933,7 @@ var init_info = __esm({
|
|
|
82567
82933
|
},
|
|
82568
82934
|
async run({ args }) {
|
|
82569
82935
|
const project = resolveProject(args.dir);
|
|
82570
|
-
const html =
|
|
82936
|
+
const html = readFileSync43(project.indexPath, "utf-8");
|
|
82571
82937
|
ensureDOMParser();
|
|
82572
82938
|
const parsed = parseHtml(html);
|
|
82573
82939
|
const tracks = new Set(parsed.elements.map((el) => el.zIndex));
|
|
@@ -82625,7 +82991,7 @@ __export(compositions_exports, {
|
|
|
82625
82991
|
examples: () => examples12,
|
|
82626
82992
|
parseSubComposition: () => parseSubComposition
|
|
82627
82993
|
});
|
|
82628
|
-
import { existsSync as existsSync57, readFileSync as
|
|
82994
|
+
import { existsSync as existsSync57, readFileSync as readFileSync44 } from "fs";
|
|
82629
82995
|
import { resolve as resolve35, dirname as dirname24 } from "path";
|
|
82630
82996
|
function countRenderableDescendants(root) {
|
|
82631
82997
|
return Array.from(root.querySelectorAll("*")).filter(
|
|
@@ -82660,7 +83026,7 @@ function parseCompositions(html, baseDir) {
|
|
|
82660
83026
|
if (compositionSrc) {
|
|
82661
83027
|
const subPath = resolve35(baseDir, compositionSrc);
|
|
82662
83028
|
if (existsSync57(subPath)) {
|
|
82663
|
-
const subHtml =
|
|
83029
|
+
const subHtml = readFileSync44(subPath, "utf-8");
|
|
82664
83030
|
const subInfo = parseSubComposition(subHtml, id, width, height);
|
|
82665
83031
|
compositions.push({ ...subInfo, source: compositionSrc });
|
|
82666
83032
|
return;
|
|
@@ -82763,7 +83129,7 @@ var init_compositions = __esm({
|
|
|
82763
83129
|
},
|
|
82764
83130
|
async run({ args }) {
|
|
82765
83131
|
const project = resolveProject(args.dir);
|
|
82766
|
-
const html =
|
|
83132
|
+
const html = readFileSync44(project.indexPath, "utf-8");
|
|
82767
83133
|
ensureDOMParser();
|
|
82768
83134
|
const compositions = parseCompositions(html, dirname24(project.indexPath));
|
|
82769
83135
|
if (compositions.length === 0) {
|
|
@@ -83891,7 +84257,7 @@ __export(transcribe_exports2, {
|
|
|
83891
84257
|
default: () => transcribe_default,
|
|
83892
84258
|
examples: () => examples16
|
|
83893
84259
|
});
|
|
83894
|
-
import { existsSync as existsSync61, writeFileSync as
|
|
84260
|
+
import { existsSync as existsSync61, writeFileSync as writeFileSync28 } from "fs";
|
|
83895
84261
|
import { resolve as resolve38, join as join67, extname as extname11, dirname as dirname25 } from "path";
|
|
83896
84262
|
async function importTranscript(inputPath, dir, json) {
|
|
83897
84263
|
const { loadTranscript: loadTranscript2, patchCaptionHtml: patchCaptionHtml2 } = await Promise.resolve().then(() => (init_normalize(), normalize_exports));
|
|
@@ -83901,7 +84267,7 @@ async function importTranscript(inputPath, dir, json) {
|
|
|
83901
84267
|
process.exit(1);
|
|
83902
84268
|
}
|
|
83903
84269
|
const outPath = join67(dir, "transcript.json");
|
|
83904
|
-
|
|
84270
|
+
writeFileSync28(outPath, JSON.stringify(words, null, 2));
|
|
83905
84271
|
patchCaptionHtml2(dir, words);
|
|
83906
84272
|
if (json) {
|
|
83907
84273
|
console.log(
|
|
@@ -83936,7 +84302,7 @@ async function transcribeAudio(inputPath, dir, opts) {
|
|
|
83936
84302
|
);
|
|
83937
84303
|
}
|
|
83938
84304
|
}
|
|
83939
|
-
|
|
84305
|
+
writeFileSync28(result.transcriptPath, JSON.stringify(words, null, 2));
|
|
83940
84306
|
patchCaptionHtml2(dir, words);
|
|
83941
84307
|
if (opts.json) {
|
|
83942
84308
|
console.log(
|
|
@@ -84144,7 +84510,7 @@ __export(synthesize_exports, {
|
|
|
84144
84510
|
synthesize: () => synthesize
|
|
84145
84511
|
});
|
|
84146
84512
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
84147
|
-
import { existsSync as existsSync63, writeFileSync as
|
|
84513
|
+
import { existsSync as existsSync63, writeFileSync as writeFileSync29, mkdirSync as mkdirSync35, readdirSync as readdirSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
84148
84514
|
import { join as join69, dirname as dirname26, basename as basename12 } from "path";
|
|
84149
84515
|
import { homedir as homedir11 } from "os";
|
|
84150
84516
|
function findPython() {
|
|
@@ -84183,7 +84549,7 @@ function hasPythonPackage(python, pkg) {
|
|
|
84183
84549
|
function ensureSynthScript() {
|
|
84184
84550
|
if (!existsSync63(SCRIPT_PATH)) {
|
|
84185
84551
|
mkdirSync35(SCRIPT_DIR, { recursive: true });
|
|
84186
|
-
|
|
84552
|
+
writeFileSync29(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
84187
84553
|
const currentName = basename12(SCRIPT_PATH);
|
|
84188
84554
|
try {
|
|
84189
84555
|
for (const entry of readdirSync25(SCRIPT_DIR)) {
|
|
@@ -84310,7 +84676,7 @@ __export(tts_exports, {
|
|
|
84310
84676
|
default: () => tts_default,
|
|
84311
84677
|
examples: () => examples17
|
|
84312
84678
|
});
|
|
84313
|
-
import { existsSync as existsSync64, readFileSync as
|
|
84679
|
+
import { existsSync as existsSync64, readFileSync as readFileSync45 } from "fs";
|
|
84314
84680
|
import { resolve as resolve39, extname as extname12 } from "path";
|
|
84315
84681
|
function listVoices(json) {
|
|
84316
84682
|
const rows = BUNDLED_VOICES.map((v2) => ({ ...v2, defaultLang: inferLangFromVoiceId(v2.id) }));
|
|
@@ -84421,7 +84787,7 @@ var init_tts = __esm({
|
|
|
84421
84787
|
let text;
|
|
84422
84788
|
const maybeFile = resolve39(args.input);
|
|
84423
84789
|
if (existsSync64(maybeFile) && extname12(maybeFile).toLowerCase() === ".txt") {
|
|
84424
|
-
text =
|
|
84790
|
+
text = readFileSync45(maybeFile, "utf-8").trim();
|
|
84425
84791
|
if (!text) {
|
|
84426
84792
|
console.error(c2.error("File is empty."));
|
|
84427
84793
|
process.exit(1);
|
|
@@ -84513,7 +84879,7 @@ __export(docs_exports, {
|
|
|
84513
84879
|
default: () => docs_default,
|
|
84514
84880
|
examples: () => examples18
|
|
84515
84881
|
});
|
|
84516
|
-
import { readFileSync as
|
|
84882
|
+
import { readFileSync as readFileSync46, existsSync as existsSync65 } from "fs";
|
|
84517
84883
|
import { resolve as resolve40, dirname as dirname27, join as join70 } from "path";
|
|
84518
84884
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
84519
84885
|
function docsDir() {
|
|
@@ -84623,7 +84989,7 @@ var init_docs = __esm({
|
|
|
84623
84989
|
console.error(c2.error(`Doc file not found: ${filePath}`));
|
|
84624
84990
|
process.exit(1);
|
|
84625
84991
|
}
|
|
84626
|
-
const content =
|
|
84992
|
+
const content = readFileSync46(filePath, "utf-8");
|
|
84627
84993
|
console.log();
|
|
84628
84994
|
renderMarkdown(content);
|
|
84629
84995
|
}
|
|
@@ -85176,7 +85542,7 @@ __export(validate_exports, {
|
|
|
85176
85542
|
default: () => validate_default,
|
|
85177
85543
|
shouldIgnoreRequestFailure: () => shouldIgnoreRequestFailure
|
|
85178
85544
|
});
|
|
85179
|
-
import { existsSync as existsSync66, readFileSync as
|
|
85545
|
+
import { existsSync as existsSync66, readFileSync as readFileSync47 } from "fs";
|
|
85180
85546
|
import { join as join71, dirname as dirname28 } from "path";
|
|
85181
85547
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
85182
85548
|
function shouldIgnoreRequestFailure(url, errorText) {
|
|
@@ -85233,7 +85599,7 @@ function loadContrastAuditScript() {
|
|
|
85233
85599
|
join71(__dirname3, "commands", "contrast-audit.browser.js")
|
|
85234
85600
|
];
|
|
85235
85601
|
for (const candidate of candidates) {
|
|
85236
|
-
if (existsSync66(candidate)) return
|
|
85602
|
+
if (existsSync66(candidate)) return readFileSync47(candidate, "utf-8");
|
|
85237
85603
|
}
|
|
85238
85604
|
throw new Error("Missing contrast audit browser script");
|
|
85239
85605
|
}
|
|
@@ -85253,7 +85619,7 @@ async function validateInBrowser(projectDir, opts) {
|
|
|
85253
85619
|
const filePath = join71(projectDir, decodeURIComponent(url));
|
|
85254
85620
|
if (existsSync66(filePath)) {
|
|
85255
85621
|
res.writeHead(200, { "Content-Type": getMimeType2(filePath) });
|
|
85256
|
-
res.end(
|
|
85622
|
+
res.end(readFileSync47(filePath));
|
|
85257
85623
|
return;
|
|
85258
85624
|
}
|
|
85259
85625
|
res.writeHead(404);
|
|
@@ -85455,7 +85821,7 @@ __export(contactSheet_exports, {
|
|
|
85455
85821
|
createSvgContactSheet: () => createSvgContactSheet
|
|
85456
85822
|
});
|
|
85457
85823
|
import sharp from "sharp";
|
|
85458
|
-
import { readdirSync as readdirSync26, readFileSync as
|
|
85824
|
+
import { readdirSync as readdirSync26, readFileSync as readFileSync48, writeFileSync as writeFileSync30, unlinkSync as unlinkSync7, existsSync as existsSync67 } from "fs";
|
|
85459
85825
|
import { join as join72, extname as extname13, basename as basename13, dirname as dirname29 } from "path";
|
|
85460
85826
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
85461
85827
|
const {
|
|
@@ -85606,12 +85972,12 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir) {
|
|
|
85606
85972
|
const svgPath = svgPaths[i2];
|
|
85607
85973
|
const tmpPath = join72(tmpDir, `.thumb-${i2}.png`);
|
|
85608
85974
|
try {
|
|
85609
|
-
const svgBuf =
|
|
85975
|
+
const svgBuf = readFileSync48(svgPath);
|
|
85610
85976
|
const thumb = await sharp(svgBuf).resize(thumbSize, thumbSize, {
|
|
85611
85977
|
fit: "contain",
|
|
85612
85978
|
background: { r: 245, g: 245, b: 245, alpha: 1 }
|
|
85613
85979
|
}).flatten({ background: { r: 245, g: 245, b: 245 } }).png().toBuffer();
|
|
85614
|
-
|
|
85980
|
+
writeFileSync30(tmpPath, thumb);
|
|
85615
85981
|
tmpPaths.push(tmpPath);
|
|
85616
85982
|
labels.push(svgFileNames[i2].replace(".svg", ""));
|
|
85617
85983
|
} catch {
|
|
@@ -106390,7 +106756,7 @@ var require_websocket = __commonJS({
|
|
|
106390
106756
|
var http4 = __require("http");
|
|
106391
106757
|
var net2 = __require("net");
|
|
106392
106758
|
var tls = __require("tls");
|
|
106393
|
-
var { randomBytes:
|
|
106759
|
+
var { randomBytes: randomBytes4, createHash: createHash9 } = __require("crypto");
|
|
106394
106760
|
var { Duplex, Readable: Readable3 } = __require("stream");
|
|
106395
106761
|
var { URL: URL2 } = __require("url");
|
|
106396
106762
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -106920,7 +107286,7 @@ var require_websocket = __commonJS({
|
|
|
106920
107286
|
}
|
|
106921
107287
|
}
|
|
106922
107288
|
const defaultPort = isSecure ? 443 : 80;
|
|
106923
|
-
const key2 =
|
|
107289
|
+
const key2 = randomBytes4(16).toString("base64");
|
|
106924
107290
|
const request = isSecure ? https2.request : http4.request;
|
|
106925
107291
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
106926
107292
|
let perMessageDeflate;
|
|
@@ -126164,7 +126530,7 @@ __export(snapshot_exports, {
|
|
|
126164
126530
|
examples: () => examples23
|
|
126165
126531
|
});
|
|
126166
126532
|
import { spawn as spawn15 } from "child_process";
|
|
126167
|
-
import { existsSync as existsSync68, mkdtempSync as mkdtempSync3, readFileSync as
|
|
126533
|
+
import { existsSync as existsSync68, mkdtempSync as mkdtempSync3, readFileSync as readFileSync49, mkdirSync as mkdirSync36, rmSync as rmSync15, writeFileSync as writeFileSync31 } from "fs";
|
|
126168
126534
|
import { tmpdir as tmpdir6 } from "os";
|
|
126169
126535
|
import { resolve as resolve41, join as join73, relative as relative11, isAbsolute as isAbsolute10 } from "path";
|
|
126170
126536
|
async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDecoder = false) {
|
|
@@ -126210,7 +126576,7 @@ async function extractVideoFrameToBuffer(videoPath, timeSeconds, useVp9AlphaDeco
|
|
|
126210
126576
|
}
|
|
126211
126577
|
);
|
|
126212
126578
|
if (result.code !== 0 || result.timedOut || !existsSync68(outPath)) return null;
|
|
126213
|
-
return
|
|
126579
|
+
return readFileSync49(outPath);
|
|
126214
126580
|
} finally {
|
|
126215
126581
|
try {
|
|
126216
126582
|
rmSync15(tmp, { recursive: true, force: true });
|
|
@@ -126547,7 +126913,7 @@ ${c2.success("\u25C7")} ${paths.length} snapshots saved to snapshots/`);
|
|
|
126547
126913
|
const filename = p2.replace("snapshots/", "");
|
|
126548
126914
|
const filePath = join73(snapshotDir, filename);
|
|
126549
126915
|
if (!existsSync68(filePath)) return { filename, desc: "file not found" };
|
|
126550
|
-
const raw =
|
|
126916
|
+
const raw = readFileSync49(filePath);
|
|
126551
126917
|
let imageData;
|
|
126552
126918
|
let mimeType = "image/png";
|
|
126553
126919
|
if (sharpFn) {
|
|
@@ -126584,7 +126950,7 @@ ${c2.success("\u25C7")} ${paths.length} snapshots saved to snapshots/`);
|
|
|
126584
126950
|
}
|
|
126585
126951
|
}
|
|
126586
126952
|
const descPath = join73(snapshotDir, "descriptions.md");
|
|
126587
|
-
|
|
126953
|
+
writeFileSync31(descPath, descriptions.join("\n"));
|
|
126588
126954
|
console.log(` ${c2.dim("descriptions.md")} (Gemini frame analysis)`);
|
|
126589
126955
|
}
|
|
126590
126956
|
} catch (descErr) {
|
|
@@ -126604,7 +126970,7 @@ ${c2.error("\u2717")} Snapshot failed: ${msg}`);
|
|
|
126604
126970
|
});
|
|
126605
126971
|
|
|
126606
126972
|
// src/capture/assetDownloader.ts
|
|
126607
|
-
import { writeFileSync as
|
|
126973
|
+
import { writeFileSync as writeFileSync32, mkdirSync as mkdirSync37 } from "fs";
|
|
126608
126974
|
import { join as join74, extname as extname14 } from "path";
|
|
126609
126975
|
async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks) {
|
|
126610
126976
|
const assetsDir = join74(outputDir, "assets");
|
|
@@ -126628,7 +126994,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
126628
126994
|
const name = `${finalSlug}.svg`;
|
|
126629
126995
|
const localPath = `assets/svgs/${name}`;
|
|
126630
126996
|
try {
|
|
126631
|
-
|
|
126997
|
+
writeFileSync32(join74(outputDir, localPath), svg.outerHTML, "utf-8");
|
|
126632
126998
|
assets.push({ url: "", localPath, type: "svg" });
|
|
126633
126999
|
} catch {
|
|
126634
127000
|
}
|
|
@@ -126641,7 +127007,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
126641
127007
|
const localPath = `assets/${name}`;
|
|
126642
127008
|
const buffer = await fetchBuffer(icon.href);
|
|
126643
127009
|
if (buffer) {
|
|
126644
|
-
|
|
127010
|
+
writeFileSync32(join74(outputDir, localPath), buffer);
|
|
126645
127011
|
assets.push({ url: icon.href, localPath, type: "favicon" });
|
|
126646
127012
|
break;
|
|
126647
127013
|
}
|
|
@@ -126698,7 +127064,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
126698
127064
|
const name = `${slug}${ext}`;
|
|
126699
127065
|
usedNames.add(slug);
|
|
126700
127066
|
const localPath = `assets/${name}`;
|
|
126701
|
-
|
|
127067
|
+
writeFileSync32(join74(outputDir, localPath), buffer);
|
|
126702
127068
|
assets.push({ url, localPath, type: "image" });
|
|
126703
127069
|
imgIdx++;
|
|
126704
127070
|
} catch {
|
|
@@ -126711,7 +127077,7 @@ async function downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks)
|
|
|
126711
127077
|
const localPath = `assets/og-image${ext}`;
|
|
126712
127078
|
const buffer = await fetchBuffer(tokens.ogImage);
|
|
126713
127079
|
if (buffer && buffer.length > 5e3) {
|
|
126714
|
-
|
|
127080
|
+
writeFileSync32(join74(outputDir, localPath), buffer);
|
|
126715
127081
|
assets.push({ url: tokens.ogImage, localPath, type: "image" });
|
|
126716
127082
|
}
|
|
126717
127083
|
} catch {
|
|
@@ -126774,7 +127140,7 @@ async function downloadAndRewriteFonts(css, outputDir) {
|
|
|
126774
127140
|
const relativePath = `assets/fonts/${filename}`;
|
|
126775
127141
|
const buffer = await fetchBuffer(fontUrl);
|
|
126776
127142
|
if (buffer) {
|
|
126777
|
-
|
|
127143
|
+
writeFileSync32(localPath, buffer);
|
|
126778
127144
|
rewritten = rewritten.split(fontUrl).join(relativePath);
|
|
126779
127145
|
familyCounts.set(family, familyCount + 1);
|
|
126780
127146
|
count++;
|
|
@@ -127741,7 +128107,7 @@ var init_designStyleExtractor = __esm({
|
|
|
127741
128107
|
});
|
|
127742
128108
|
|
|
127743
128109
|
// src/capture/fontMetadataExtractor.ts
|
|
127744
|
-
import { readdirSync as readdirSync27, readFileSync as
|
|
128110
|
+
import { readdirSync as readdirSync27, readFileSync as readFileSync50, writeFileSync as writeFileSync33, existsSync as existsSync69 } from "fs";
|
|
127745
128111
|
import { join as join75 } from "path";
|
|
127746
128112
|
import * as fontkit from "fontkit";
|
|
127747
128113
|
function isFontCollection(value) {
|
|
@@ -127775,7 +128141,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
127775
128141
|
tool: "fontkit"
|
|
127776
128142
|
}
|
|
127777
128143
|
};
|
|
127778
|
-
|
|
128144
|
+
writeFileSync33(outputPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
127779
128145
|
return manifest;
|
|
127780
128146
|
}
|
|
127781
128147
|
function readSingleFont(fullPath, filename) {
|
|
@@ -127791,7 +128157,7 @@ function readSingleFont(fullPath, filename) {
|
|
|
127791
128157
|
identified: false
|
|
127792
128158
|
};
|
|
127793
128159
|
try {
|
|
127794
|
-
const buf =
|
|
128160
|
+
const buf = readFileSync50(fullPath);
|
|
127795
128161
|
const created = fontkit.create(buf);
|
|
127796
128162
|
const font = isFontCollection(created) ? created.fonts[0] : created;
|
|
127797
128163
|
if (!font) return empty;
|
|
@@ -128047,7 +128413,7 @@ var init_animationCataloger = __esm({
|
|
|
128047
128413
|
});
|
|
128048
128414
|
|
|
128049
128415
|
// src/capture/mediaCapture.ts
|
|
128050
|
-
import { mkdirSync as mkdirSync38, writeFileSync as
|
|
128416
|
+
import { mkdirSync as mkdirSync38, writeFileSync as writeFileSync34, readdirSync as readdirSync28, readFileSync as readFileSync51, statSync as statSync24 } from "fs";
|
|
128051
128417
|
import { join as join76 } from "path";
|
|
128052
128418
|
async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
128053
128419
|
let savedCount = 0;
|
|
@@ -128081,7 +128447,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
|
128081
128447
|
const hash2 = buf.toString("base64").slice(0, 100);
|
|
128082
128448
|
if (savedHashes.has(hash2)) continue;
|
|
128083
128449
|
savedHashes.add(hash2);
|
|
128084
|
-
|
|
128450
|
+
writeFileSync34(join76(lottieDir, `animation-${savedCount}.lottie`), buf);
|
|
128085
128451
|
savedCount++;
|
|
128086
128452
|
continue;
|
|
128087
128453
|
}
|
|
@@ -128099,7 +128465,7 @@ async function saveLottieAnimations(discoveredLotties, lottieDir) {
|
|
|
128099
128465
|
} catch {
|
|
128100
128466
|
continue;
|
|
128101
128467
|
}
|
|
128102
|
-
|
|
128468
|
+
writeFileSync34(join76(lottieDir, `animation-${savedCount}.json`), jsonData, "utf-8");
|
|
128103
128469
|
savedCount++;
|
|
128104
128470
|
}
|
|
128105
128471
|
} catch {
|
|
@@ -128114,7 +128480,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
128114
128480
|
for (const file of readdirSync28(lottieDir)) {
|
|
128115
128481
|
if (!file.endsWith(".json")) continue;
|
|
128116
128482
|
try {
|
|
128117
|
-
const raw = JSON.parse(
|
|
128483
|
+
const raw = JSON.parse(readFileSync51(join76(lottieDir, file), "utf-8"));
|
|
128118
128484
|
const fr = raw.fr || 30;
|
|
128119
128485
|
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
|
|
128120
128486
|
const previewName = file.replace(".json", "-preview.png");
|
|
@@ -128124,7 +128490,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
128124
128490
|
try {
|
|
128125
128491
|
previewPage = await chromeBrowser.newPage();
|
|
128126
128492
|
await previewPage.setViewport({ width: 400, height: 400 });
|
|
128127
|
-
const animData = JSON.parse(
|
|
128493
|
+
const animData = JSON.parse(readFileSync51(join76(lottieDir, file), "utf-8"));
|
|
128128
128494
|
const midFrame = Math.floor(((raw.op || 0) - (raw.ip || 0)) * 0.3);
|
|
128129
128495
|
await previewPage.setContent(
|
|
128130
128496
|
`<!DOCTYPE html>
|
|
@@ -128177,7 +128543,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir) {
|
|
|
128177
128543
|
}
|
|
128178
128544
|
}
|
|
128179
128545
|
if (manifest.length > 0) {
|
|
128180
|
-
|
|
128546
|
+
writeFileSync34(
|
|
128181
128547
|
join76(outputDir, "extracted", "lottie-manifest.json"),
|
|
128182
128548
|
JSON.stringify(manifest, null, 2),
|
|
128183
128549
|
"utf-8"
|
|
@@ -128286,7 +128652,7 @@ async function captureVideoManifest(page, outputDir, progress) {
|
|
|
128286
128652
|
});
|
|
128287
128653
|
}
|
|
128288
128654
|
if (videoManifest.length > 0) {
|
|
128289
|
-
|
|
128655
|
+
writeFileSync34(
|
|
128290
128656
|
join76(outputDir, "extracted", "video-manifest.json"),
|
|
128291
128657
|
JSON.stringify(videoManifest, null, 2),
|
|
128292
128658
|
"utf-8"
|
|
@@ -128303,7 +128669,7 @@ var init_mediaCapture = __esm({
|
|
|
128303
128669
|
});
|
|
128304
128670
|
|
|
128305
128671
|
// src/capture/contentExtractor.ts
|
|
128306
|
-
import { existsSync as existsSync70, readdirSync as readdirSync29, statSync as statSync25, readFileSync as
|
|
128672
|
+
import { existsSync as existsSync70, readdirSync as readdirSync29, statSync as statSync25, readFileSync as readFileSync52 } from "fs";
|
|
128307
128673
|
import { join as join77 } from "path";
|
|
128308
128674
|
async function detectLibraries(page, capturedShaders) {
|
|
128309
128675
|
let detectedLibraries = [];
|
|
@@ -128436,7 +128802,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
128436
128802
|
const filePath = join77(outputDir, "assets", file);
|
|
128437
128803
|
const stat3 = statSync25(filePath);
|
|
128438
128804
|
if (stat3.size > 4e6) return { file, caption: "" };
|
|
128439
|
-
const buffer =
|
|
128805
|
+
const buffer = readFileSync52(filePath);
|
|
128440
128806
|
const base64 = buffer.toString("base64");
|
|
128441
128807
|
const ext = file.split(".").pop()?.toLowerCase() || "png";
|
|
128442
128808
|
const mimeType = ext === "jpg" ? "image/jpeg" : `image/${ext}`;
|
|
@@ -128492,7 +128858,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings) {
|
|
|
128492
128858
|
const results = await Promise.allSettled(
|
|
128493
128859
|
batch.map(async ({ relPath }) => {
|
|
128494
128860
|
const filePath = join77(assetsDir, relPath);
|
|
128495
|
-
let svgText =
|
|
128861
|
+
let svgText = readFileSync52(filePath, "utf-8");
|
|
128496
128862
|
if (svgText.length > MAX_SVG_CHARS) {
|
|
128497
128863
|
svgText = svgText.slice(0, MAX_SVG_CHARS) + "\n<!-- truncated -->";
|
|
128498
128864
|
}
|
|
@@ -128610,7 +128976,7 @@ var agentPromptGenerator_exports = {};
|
|
|
128610
128976
|
__export(agentPromptGenerator_exports, {
|
|
128611
128977
|
generateAgentPrompt: () => generateAgentPrompt
|
|
128612
128978
|
});
|
|
128613
|
-
import { writeFileSync as
|
|
128979
|
+
import { writeFileSync as writeFileSync35, readdirSync as readdirSync30, existsSync as existsSync71 } from "fs";
|
|
128614
128980
|
import { join as join78 } from "path";
|
|
128615
128981
|
function inferColorRole(hex) {
|
|
128616
128982
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -128630,9 +128996,9 @@ function inferColorRole(hex) {
|
|
|
128630
128996
|
}
|
|
128631
128997
|
function generateAgentPrompt(outputDir, url, tokens, _animations, hasScreenshot, hasLottie, hasShaders, _catalogedAssets, _detectedLibraries) {
|
|
128632
128998
|
const prompt = buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders);
|
|
128633
|
-
|
|
128634
|
-
|
|
128635
|
-
|
|
128999
|
+
writeFileSync35(join78(outputDir, "AGENTS.md"), prompt, "utf-8");
|
|
129000
|
+
writeFileSync35(join78(outputDir, "CLAUDE.md"), prompt, "utf-8");
|
|
129001
|
+
writeFileSync35(join78(outputDir, ".cursorrules"), prompt, "utf-8");
|
|
128636
129002
|
}
|
|
128637
129003
|
function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShaders) {
|
|
128638
129004
|
const title = tokens.title || new URL(url).hostname.replace(/^www\./, "");
|
|
@@ -128745,7 +129111,7 @@ var init_agentPromptGenerator = __esm({
|
|
|
128745
129111
|
});
|
|
128746
129112
|
|
|
128747
129113
|
// src/capture/scaffolding.ts
|
|
128748
|
-
import { existsSync as existsSync72, writeFileSync as
|
|
129114
|
+
import { existsSync as existsSync72, writeFileSync as writeFileSync36, readFileSync as readFileSync53 } from "fs";
|
|
128749
129115
|
import { join as join79, resolve as resolve42 } from "path";
|
|
128750
129116
|
function loadEnvFile(startDir) {
|
|
128751
129117
|
try {
|
|
@@ -128753,7 +129119,7 @@ function loadEnvFile(startDir) {
|
|
|
128753
129119
|
for (let i2 = 0; i2 < 5; i2++) {
|
|
128754
129120
|
const envPath = resolve42(dir, ".env");
|
|
128755
129121
|
try {
|
|
128756
|
-
const envContent =
|
|
129122
|
+
const envContent = readFileSync53(envPath, "utf-8");
|
|
128757
129123
|
for (const line of envContent.split("\n")) {
|
|
128758
129124
|
const trimmed = line.trim();
|
|
128759
129125
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -128775,7 +129141,7 @@ async function generateProjectScaffold(outputDir, url, tokens, animationCatalog,
|
|
|
128775
129141
|
const metaPath = join79(outputDir, "meta.json");
|
|
128776
129142
|
if (!existsSync72(metaPath)) {
|
|
128777
129143
|
const hostname = new URL(url).hostname.replace(/^www\./, "");
|
|
128778
|
-
|
|
129144
|
+
writeFileSync36(
|
|
128779
129145
|
metaPath,
|
|
128780
129146
|
JSON.stringify({ id: hostname + "-video", name: tokens.title || hostname }, null, 2),
|
|
128781
129147
|
"utf-8"
|
|
@@ -128810,7 +129176,7 @@ var screenshotCapture_exports = {};
|
|
|
128810
129176
|
__export(screenshotCapture_exports, {
|
|
128811
129177
|
captureScrollScreenshots: () => captureScrollScreenshots
|
|
128812
129178
|
});
|
|
128813
|
-
import { writeFileSync as
|
|
129179
|
+
import { writeFileSync as writeFileSync37, mkdirSync as mkdirSync39 } from "fs";
|
|
128814
129180
|
import { join as join80 } from "path";
|
|
128815
129181
|
async function captureScrollScreenshots(page, outputDir) {
|
|
128816
129182
|
const screenshotsDir = join80(outputDir, "screenshots");
|
|
@@ -128907,7 +129273,7 @@ async function captureScrollScreenshots(page, outputDir) {
|
|
|
128907
129273
|
const filename = `scroll-${String(Math.min(pct, 100)).padStart(3, "0")}.png`;
|
|
128908
129274
|
const filePath = join80(screenshotsDir, filename);
|
|
128909
129275
|
const buffer = await page.screenshot({ type: "png" });
|
|
128910
|
-
|
|
129276
|
+
writeFileSync37(filePath, buffer);
|
|
128911
129277
|
filePaths.push(`screenshots/${filename}`);
|
|
128912
129278
|
}
|
|
128913
129279
|
await page.evaluate(`window.scrollTo(0, 0)`);
|
|
@@ -129180,7 +129546,7 @@ var capture_exports = {};
|
|
|
129180
129546
|
__export(capture_exports, {
|
|
129181
129547
|
captureWebsite: () => captureWebsite
|
|
129182
129548
|
});
|
|
129183
|
-
import { mkdirSync as mkdirSync40, writeFileSync as
|
|
129549
|
+
import { mkdirSync as mkdirSync40, writeFileSync as writeFileSync38, existsSync as existsSync73 } from "fs";
|
|
129184
129550
|
import { join as join81 } from "path";
|
|
129185
129551
|
async function captureWebsite(opts, onProgress) {
|
|
129186
129552
|
const {
|
|
@@ -129375,7 +129741,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
129375
129741
|
return true;
|
|
129376
129742
|
});
|
|
129377
129743
|
capturedShaders = unique;
|
|
129378
|
-
|
|
129744
|
+
writeFileSync38(
|
|
129379
129745
|
join81(outputDir, "extracted", "shaders.json"),
|
|
129380
129746
|
JSON.stringify(unique, null, 2),
|
|
129381
129747
|
"utf-8"
|
|
@@ -129390,7 +129756,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
129390
129756
|
...tokens,
|
|
129391
129757
|
svgs: tokens.svgs.map(({ outerHTML: _, ...rest }) => rest)
|
|
129392
129758
|
};
|
|
129393
|
-
|
|
129759
|
+
writeFileSync38(
|
|
129394
129760
|
join81(outputDir, "extracted", "tokens.json"),
|
|
129395
129761
|
JSON.stringify(tokensForDisk, null, 2),
|
|
129396
129762
|
"utf-8"
|
|
@@ -129398,7 +129764,7 @@ async function captureWebsite(opts, onProgress) {
|
|
|
129398
129764
|
progress("style", "Extracting design styles...");
|
|
129399
129765
|
try {
|
|
129400
129766
|
const designStyles = await extractDesignStyles(page1);
|
|
129401
|
-
|
|
129767
|
+
writeFileSync38(
|
|
129402
129768
|
join81(outputDir, "extracted", "design-styles.json"),
|
|
129403
129769
|
JSON.stringify(designStyles, null, 2),
|
|
129404
129770
|
"utf-8"
|
|
@@ -129502,7 +129868,7 @@ ${err.stack}` : String(err);
|
|
|
129502
129868
|
scrollTriggeredElements: (animationCatalog.scrollTargets || []).length,
|
|
129503
129869
|
representativeAnimations: representativeAnims
|
|
129504
129870
|
};
|
|
129505
|
-
|
|
129871
|
+
writeFileSync38(
|
|
129506
129872
|
join81(outputDir, "extracted", "animations.json"),
|
|
129507
129873
|
JSON.stringify(leanCatalog, null, 2),
|
|
129508
129874
|
"utf-8"
|
|
@@ -129514,14 +129880,14 @@ ${err.stack}` : String(err);
|
|
|
129514
129880
|
assets = await downloadAssets(tokens, outputDir, catalogedAssets, faviconLinks);
|
|
129515
129881
|
}
|
|
129516
129882
|
if (visibleTextContent) {
|
|
129517
|
-
|
|
129883
|
+
writeFileSync38(join81(outputDir, "extracted", "visible-text.txt"), visibleTextContent, "utf-8");
|
|
129518
129884
|
}
|
|
129519
129885
|
const geminiCaptions = await captionImagesWithGemini(outputDir, progress, warnings);
|
|
129520
129886
|
progress("design", "Generating asset descriptions...");
|
|
129521
129887
|
try {
|
|
129522
129888
|
const lines = generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCaptions);
|
|
129523
129889
|
if (lines.length > 0) {
|
|
129524
|
-
|
|
129890
|
+
writeFileSync38(
|
|
129525
129891
|
join81(outputDir, "extracted", "asset-descriptions.md"),
|
|
129526
129892
|
"# Asset Descriptions\n\nOne line per file. Read this instead of opening every image individually.\n\n" + lines.map((l) => "- " + l).join("\n") + "\n",
|
|
129527
129893
|
"utf-8"
|
|
@@ -129753,11 +130119,11 @@ var init_capture2 = __esm({
|
|
|
129753
130119
|
} catch (err) {
|
|
129754
130120
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
129755
130121
|
try {
|
|
129756
|
-
const { mkdirSync: mkdirSync44, writeFileSync:
|
|
130122
|
+
const { mkdirSync: mkdirSync44, writeFileSync: writeFileSync40 } = await import("fs");
|
|
129757
130123
|
mkdirSync44(outputDir, { recursive: true });
|
|
129758
130124
|
const isTimeout = /timeout|timed out/i.test(errMsg);
|
|
129759
130125
|
const reason = isTimeout ? "Page navigation timed out \u2014 the site may be blocking headless browsers or requires authentication." : `Capture failed: ${errMsg}`;
|
|
129760
|
-
|
|
130126
|
+
writeFileSync40(
|
|
129761
130127
|
`${outputDir}/BLOCKED.md`,
|
|
129762
130128
|
`# Capture Failed
|
|
129763
130129
|
|
|
@@ -129800,7 +130166,7 @@ __export(state_exports, {
|
|
|
129800
130166
|
stateFilePath: () => stateFilePath,
|
|
129801
130167
|
writeStackOutputs: () => writeStackOutputs
|
|
129802
130168
|
});
|
|
129803
|
-
import { existsSync as existsSync74, mkdirSync as mkdirSync41, readdirSync as readdirSync31, readFileSync as
|
|
130169
|
+
import { existsSync as existsSync74, mkdirSync as mkdirSync41, readdirSync as readdirSync31, readFileSync as readFileSync54, rmSync as rmSync16, writeFileSync as writeFileSync39 } from "fs";
|
|
129804
130170
|
import { dirname as dirname30, join as join82 } from "path";
|
|
129805
130171
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
129806
130172
|
return join82(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -129808,14 +130174,14 @@ function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
|
129808
130174
|
function writeStackOutputs(outputs, cwd = process.cwd()) {
|
|
129809
130175
|
const path2 = stateFilePath(outputs.stackName, cwd);
|
|
129810
130176
|
mkdirSync41(dirname30(path2), { recursive: true });
|
|
129811
|
-
|
|
130177
|
+
writeFileSync39(path2, JSON.stringify(outputs, null, 2) + "\n");
|
|
129812
130178
|
return path2;
|
|
129813
130179
|
}
|
|
129814
130180
|
function readStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
129815
130181
|
const path2 = stateFilePath(stackName, cwd);
|
|
129816
130182
|
if (!existsSync74(path2)) return null;
|
|
129817
130183
|
try {
|
|
129818
|
-
return JSON.parse(
|
|
130184
|
+
return JSON.parse(readFileSync54(path2, "utf-8"));
|
|
129819
130185
|
} catch {
|
|
129820
130186
|
return null;
|
|
129821
130187
|
}
|
|
@@ -130137,14 +130503,14 @@ var init_sites = __esm({
|
|
|
130137
130503
|
});
|
|
130138
130504
|
|
|
130139
130505
|
// src/commands/lambda/_dimensions.ts
|
|
130140
|
-
import { readFileSync as
|
|
130506
|
+
import { readFileSync as readFileSync55 } from "fs";
|
|
130141
130507
|
import { join as join85 } from "path";
|
|
130142
130508
|
function warnOnDimensionMismatch(args) {
|
|
130143
130509
|
if (args.quiet) return;
|
|
130144
130510
|
if (args.outputResolution) return;
|
|
130145
130511
|
let html;
|
|
130146
130512
|
try {
|
|
130147
|
-
html =
|
|
130513
|
+
html = readFileSync55(join85(args.projectDir, "index.html"), "utf-8");
|
|
130148
130514
|
} catch {
|
|
130149
130515
|
return;
|
|
130150
130516
|
}
|
|
@@ -130313,7 +130679,7 @@ __export(render_batch_exports, {
|
|
|
130313
130679
|
runRenderBatch: () => runRenderBatch,
|
|
130314
130680
|
runWithConcurrencyLimit: () => runWithConcurrencyLimit
|
|
130315
130681
|
});
|
|
130316
|
-
import { existsSync as existsSync79, readFileSync as
|
|
130682
|
+
import { existsSync as existsSync79, readFileSync as readFileSync56 } from "fs";
|
|
130317
130683
|
import { join as join87, resolve as resolvePath3 } from "path";
|
|
130318
130684
|
async function loadSDK3() {
|
|
130319
130685
|
return import("@hyperframes/aws-lambda/sdk");
|
|
@@ -130465,7 +130831,7 @@ function makePlaceholderSiteHandle(siteId, bucketName) {
|
|
|
130465
130831
|
};
|
|
130466
130832
|
}
|
|
130467
130833
|
function parseBatchFile(path2) {
|
|
130468
|
-
const raw =
|
|
130834
|
+
const raw = readFileSync56(path2, "utf8");
|
|
130469
130835
|
const lines = raw.split(/\r?\n/);
|
|
130470
130836
|
const out = [];
|
|
130471
130837
|
for (let i2 = 0; i2 < lines.length; i2++) {
|
|
@@ -130659,7 +131025,7 @@ __export(policies_exports, {
|
|
|
130659
131025
|
runPolicies: () => runPolicies,
|
|
130660
131026
|
validatePolicy: () => validatePolicy
|
|
130661
131027
|
});
|
|
130662
|
-
import { readFileSync as
|
|
131028
|
+
import { readFileSync as readFileSync57 } from "fs";
|
|
130663
131029
|
function allRequiredActions() {
|
|
130664
131030
|
const set = /* @__PURE__ */ new Set();
|
|
130665
131031
|
for (const group of Object.values(REQUIRED_ACTIONS)) {
|
|
@@ -130765,7 +131131,7 @@ async function runPolicies(args) {
|
|
|
130765
131131
|
}
|
|
130766
131132
|
}
|
|
130767
131133
|
function validatePolicy(policyPath) {
|
|
130768
|
-
const raw =
|
|
131134
|
+
const raw = readFileSync57(policyPath, "utf-8");
|
|
130769
131135
|
const parsed = JSON.parse(raw);
|
|
130770
131136
|
const statements = Array.isArray(parsed.Statement) ? parsed.Statement : parsed.Statement ? [
|
|
130771
131137
|
parsed.Statement
|
|
@@ -131875,14 +132241,14 @@ var init_client3 = __esm({
|
|
|
131875
132241
|
});
|
|
131876
132242
|
|
|
131877
132243
|
// src/auth/pkce.ts
|
|
131878
|
-
import { createHash as createHash8, randomBytes as
|
|
132244
|
+
import { createHash as createHash8, randomBytes as randomBytes3 } from "crypto";
|
|
131879
132245
|
function generatePkcePair() {
|
|
131880
|
-
const verifier = base64UrlEncode(
|
|
132246
|
+
const verifier = base64UrlEncode(randomBytes3(VERIFIER_BYTES));
|
|
131881
132247
|
const challenge = base64UrlEncode(createHash8("sha256").update(verifier).digest());
|
|
131882
132248
|
return { verifier, challenge, method: "S256" };
|
|
131883
132249
|
}
|
|
131884
132250
|
function generateState() {
|
|
131885
|
-
return base64UrlEncode(
|
|
132251
|
+
return base64UrlEncode(randomBytes3(32));
|
|
131886
132252
|
}
|
|
131887
132253
|
function base64UrlEncode(buf) {
|
|
131888
132254
|
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
@@ -134571,10 +134937,10 @@ if (rootVersionRequested) {
|
|
|
134571
134937
|
process.exit(0);
|
|
134572
134938
|
}
|
|
134573
134939
|
try {
|
|
134574
|
-
const { readFileSync:
|
|
134940
|
+
const { readFileSync: readFileSync58 } = await import("fs");
|
|
134575
134941
|
const { resolve: resolve46 } = await import("path");
|
|
134576
134942
|
const envPath = resolve46(process.cwd(), ".env");
|
|
134577
|
-
const envContent =
|
|
134943
|
+
const envContent = readFileSync58(envPath, "utf-8");
|
|
134578
134944
|
for (const rawLine of envContent.split("\n")) {
|
|
134579
134945
|
let line = rawLine.trim();
|
|
134580
134946
|
if (!line || line.startsWith("#")) continue;
|