@hyperframes/parsers 0.8.49 → 0.8.51
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/assetResolution.d.ts +3 -1
- package/dist/assetResolution.js +24 -2
- package/dist/assetResolution.js.map +1 -1
- package/dist/compositionDuration.d.ts +19 -0
- package/dist/compositionDuration.js +22 -0
- package/dist/compositionDuration.js.map +1 -0
- package/dist/gsapParser.d.ts +2 -2
- package/dist/gsapParser.js.map +1 -1
- package/dist/gsapParserAcorn.d.ts +2 -2
- package/dist/gsapParserAcorn.js +71 -21
- package/dist/gsapParserAcorn.js.map +1 -1
- package/dist/gsapParserExports.d.ts +1 -1
- package/dist/gsapParserExports.js +71 -21
- package/dist/gsapParserExports.js.map +1 -1
- package/dist/{gsapSerialize-QZcXUoVf.d.ts → gsapSerialize-b8lNzSbI.d.ts} +2 -0
- package/dist/gsapWriterAcorn.d.ts +1 -1
- package/dist/gsapWriterAcorn.js +30 -8
- package/dist/gsapWriterAcorn.js.map +1 -1
- package/dist/index.d.ts +38 -7
- package/dist/index.js +440 -40
- package/dist/index.js.map +1 -1
- package/dist/mediaDuration.d.ts +48 -0
- package/dist/mediaDuration.js +104 -0
- package/dist/mediaDuration.js.map +1 -0
- package/dist/mediaDurationFixtures.d.ts +14 -0
- package/dist/mediaDurationFixtures.js +84 -0
- package/dist/mediaDurationFixtures.js.map +1 -0
- package/dist/topLevelElements.d.ts +22 -0
- package/dist/topLevelElements.js +40 -0
- package/dist/topLevelElements.js.map +1 -0
- package/package.json +18 -2
package/dist/index.js
CHANGED
|
@@ -494,7 +494,16 @@ import * as acorn from "acorn";
|
|
|
494
494
|
import * as acornWalk from "acorn-walk";
|
|
495
495
|
|
|
496
496
|
// src/gsapInline.ts
|
|
497
|
-
var SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
497
|
+
var SKIP_KEYS = /* @__PURE__ */ new Set([
|
|
498
|
+
"type",
|
|
499
|
+
"start",
|
|
500
|
+
"end",
|
|
501
|
+
"loc",
|
|
502
|
+
"range",
|
|
503
|
+
"__hfProvenance",
|
|
504
|
+
"__hfOrder",
|
|
505
|
+
"__hfSiteStart"
|
|
506
|
+
]);
|
|
498
507
|
var FUNCTION_TYPES = /* @__PURE__ */ new Set([
|
|
499
508
|
"ArrowFunctionExpression",
|
|
500
509
|
"FunctionExpression",
|
|
@@ -597,6 +606,9 @@ function isTimelineRooted(call, timelineVar) {
|
|
|
597
606
|
if (timelineRootName(call) !== timelineVar) return false;
|
|
598
607
|
return call.callee?.property?.type === "Identifier" && GSAP_METHODS.has(call.callee.property.name);
|
|
599
608
|
}
|
|
609
|
+
function isAddLabelCall(call, timelineVar) {
|
|
610
|
+
return timelineRootName(call) === timelineVar && call.callee?.property?.name === "addLabel";
|
|
611
|
+
}
|
|
600
612
|
function containsTimelineCall(node, timelineVar) {
|
|
601
613
|
let found = false;
|
|
602
614
|
walkNodes(node, (n) => {
|
|
@@ -803,12 +815,17 @@ function bodyStatements(node) {
|
|
|
803
815
|
}
|
|
804
816
|
function tagTimelineCalls(stmts, prov, ctx) {
|
|
805
817
|
for (const stmt of stmts) {
|
|
818
|
+
const calls = [];
|
|
806
819
|
walkNodes(stmt, (n) => {
|
|
807
|
-
if (n.type === "CallExpression" && isTimelineRooted(n, ctx.timelineVar))
|
|
808
|
-
|
|
809
|
-
n.__hfOrder = ctx.order.n++;
|
|
810
|
-
}
|
|
820
|
+
if (n.type === "CallExpression" && (isTimelineRooted(n, ctx.timelineVar) || isAddLabelCall(n, ctx.timelineVar)))
|
|
821
|
+
calls.push(n);
|
|
811
822
|
});
|
|
823
|
+
calls.sort((a, b) => a.callee.property.start - b.callee.property.start);
|
|
824
|
+
for (const n of calls) {
|
|
825
|
+
tagProvenance(n, { ...prov });
|
|
826
|
+
n.__hfOrder = ctx.order.n++;
|
|
827
|
+
n.__hfSiteStart = ctx.rootStart;
|
|
828
|
+
}
|
|
812
829
|
}
|
|
813
830
|
}
|
|
814
831
|
function expandBody(bodyStmts, bindings, prov, ctx) {
|
|
@@ -995,10 +1012,14 @@ function inlineComputedTimelines(ast, timelineVar, resolve) {
|
|
|
995
1012
|
resolve,
|
|
996
1013
|
depth: 0,
|
|
997
1014
|
site: { n: 0 },
|
|
998
|
-
order: { n: 0 }
|
|
1015
|
+
order: { n: 0 },
|
|
1016
|
+
rootStart: 0
|
|
999
1017
|
};
|
|
1000
1018
|
const body = (ast.body ?? []).filter((stmt) => !isHelperDecl(stmt, helpers));
|
|
1001
|
-
ast.body =
|
|
1019
|
+
ast.body = body.flatMap((stmt) => {
|
|
1020
|
+
ctx.rootStart = stmt.start;
|
|
1021
|
+
return expandStatements([stmt], ctx);
|
|
1022
|
+
});
|
|
1002
1023
|
}
|
|
1003
1024
|
|
|
1004
1025
|
// src/gsapParserAcorn.ts
|
|
@@ -1416,6 +1437,14 @@ function objectExpressionToRecord(node, scope, source) {
|
|
|
1416
1437
|
function isGsapTimelineCall(node) {
|
|
1417
1438
|
return node?.type === "CallExpression" && node.callee?.type === "MemberExpression" && node.callee.object?.name === "gsap" && node.callee.property?.name === "timeline";
|
|
1418
1439
|
}
|
|
1440
|
+
function hasUnknownDuration(varsNode, scope) {
|
|
1441
|
+
if (!varsNode) return false;
|
|
1442
|
+
if (varsNode.type !== "ObjectExpression") return true;
|
|
1443
|
+
const props = varsNode.properties ?? [];
|
|
1444
|
+
if (props.some((p) => p.type === "SpreadElement")) return true;
|
|
1445
|
+
const prop = props.find((p) => isObjectProperty(p) && propKeyName(p) === "duration");
|
|
1446
|
+
return prop !== void 0 && typeof resolveNode(prop.value, scope) !== "number";
|
|
1447
|
+
}
|
|
1419
1448
|
function staticMemberKey(node) {
|
|
1420
1449
|
if (!node || node.type !== "MemberExpression") return null;
|
|
1421
1450
|
if (node.computed) {
|
|
@@ -1457,7 +1486,10 @@ function extractTimelineDefaults(callNode, scope) {
|
|
|
1457
1486
|
const key = propKeyName(prop);
|
|
1458
1487
|
const val = resolveNode(prop.value, scope);
|
|
1459
1488
|
if (key === "ease" && typeof val === "string") result.ease = val;
|
|
1460
|
-
if (key === "duration"
|
|
1489
|
+
if (key === "duration") {
|
|
1490
|
+
if (typeof val === "number") result.duration = val;
|
|
1491
|
+
else result.durationUnresolved = true;
|
|
1492
|
+
}
|
|
1461
1493
|
}
|
|
1462
1494
|
return Object.keys(result).length > 0 ? result : void 0;
|
|
1463
1495
|
}
|
|
@@ -1832,6 +1864,7 @@ function tweenCallToAnimation(call, scope, source, identifierBindings) {
|
|
|
1832
1864
|
if (duration === void 0 && keyframesData) {
|
|
1833
1865
|
duration = computeKeyframesTotalDuration(call.varsArg, scope, source);
|
|
1834
1866
|
}
|
|
1867
|
+
const durationUnresolved = call.method !== "set" && duration === void 0 && hasUnknownDuration(call.varsArg, scope);
|
|
1835
1868
|
let selector = call.selector;
|
|
1836
1869
|
let targetIdentity;
|
|
1837
1870
|
if (selector === "__unresolved__") {
|
|
@@ -1879,6 +1912,7 @@ function tweenCallToAnimation(call, scope, source, identifierBindings) {
|
|
|
1879
1912
|
if (keyframesData) anim.keyframes = keyframesData;
|
|
1880
1913
|
if (motionPathResult) anim.arcPath = motionPathResult.arcPath;
|
|
1881
1914
|
if (hasUnresolvedKeyframes) anim.hasUnresolvedKeyframes = true;
|
|
1915
|
+
if (durationUnresolved) anim.durationUnresolved = true;
|
|
1882
1916
|
if (selector === "__unresolved__") anim.hasUnresolvedSelector = true;
|
|
1883
1917
|
if (provenance) anim.provenance = provenance;
|
|
1884
1918
|
return anim;
|
|
@@ -2002,8 +2036,9 @@ function applyTimelineDefaults(anims, defaults) {
|
|
|
2002
2036
|
if (!defaults) return;
|
|
2003
2037
|
for (const anim of anims) {
|
|
2004
2038
|
if (anim.method === "set") continue;
|
|
2005
|
-
if (anim.duration === void 0 &&
|
|
2006
|
-
anim.duration = defaults.duration;
|
|
2039
|
+
if (anim.duration === void 0 && !anim.durationUnresolved) {
|
|
2040
|
+
if (defaults.duration !== void 0) anim.duration = defaults.duration;
|
|
2041
|
+
else if (defaults.durationUnresolved) anim.durationUnresolved = true;
|
|
2007
2042
|
}
|
|
2008
2043
|
if (anim.ease === void 0 && defaults.ease !== void 0) {
|
|
2009
2044
|
anim.ease = defaults.ease;
|
|
@@ -2036,12 +2071,14 @@ function resolveAnimStart(anim, cursor, prevStart, labels) {
|
|
|
2036
2071
|
function resolveTimelinePositions(anims, labelDefs = []) {
|
|
2037
2072
|
let cursor = 0;
|
|
2038
2073
|
let prevStart = 0;
|
|
2074
|
+
let cursorKnown = true;
|
|
2039
2075
|
const labels = /* @__PURE__ */ new Map();
|
|
2040
2076
|
let labelIdx = 0;
|
|
2041
2077
|
const sortedLabels = [...labelDefs].sort((a, b) => a.order - b.order);
|
|
2042
2078
|
const defineLabel = (def) => {
|
|
2043
2079
|
let value;
|
|
2044
2080
|
if (typeof def.position === "number") value = def.position;
|
|
2081
|
+
else if (!cursorKnown) return;
|
|
2045
2082
|
else if (typeof def.position === "string") {
|
|
2046
2083
|
value = resolveLabelPosition(def.position, labels, cursor) ?? cursor;
|
|
2047
2084
|
} else value = cursor;
|
|
@@ -2057,7 +2094,9 @@ function resolveTimelinePositions(anims, labelDefs = []) {
|
|
|
2057
2094
|
return;
|
|
2058
2095
|
}
|
|
2059
2096
|
const duration = anim.method === "set" ? 0 : anim.duration ?? GSAP_DEFAULT_DURATION;
|
|
2060
|
-
const
|
|
2097
|
+
const readsCursor = anim.implicitPosition || typeof anim.position !== "number";
|
|
2098
|
+
const start = cursorKnown || !readsCursor ? resolveAnimStart(anim, cursor, prevStart, labels) : null;
|
|
2099
|
+
if (start == null || anim.durationUnresolved) cursorKnown = false;
|
|
2061
2100
|
if (start != null) {
|
|
2062
2101
|
anim.resolvedStart = Math.max(0, start);
|
|
2063
2102
|
prevStart = anim.resolvedStart;
|
|
@@ -2067,7 +2106,15 @@ function resolveTimelinePositions(anims, labelDefs = []) {
|
|
|
2067
2106
|
while (labelIdx < sortedLabels.length) defineLabel(sortedLabels[labelIdx++]);
|
|
2068
2107
|
}
|
|
2069
2108
|
function collectAddLabelDefs(ast, ref, scope, sortedCalls) {
|
|
2070
|
-
const
|
|
2109
|
+
const callKeys = sortedCalls.map((c) => ({
|
|
2110
|
+
site: callSiteStart(c),
|
|
2111
|
+
order: c.node.__hfOrder
|
|
2112
|
+
}));
|
|
2113
|
+
const comesAfter = (site, order, labelSite, labelOrder) => {
|
|
2114
|
+
if (site === void 0) return false;
|
|
2115
|
+
if (site !== labelSite) return site > labelSite;
|
|
2116
|
+
return (order ?? -Infinity) > (labelOrder ?? -Infinity);
|
|
2117
|
+
};
|
|
2071
2118
|
const defs = [];
|
|
2072
2119
|
acornWalk.simple(ast, {
|
|
2073
2120
|
// fallow-ignore-next-line complexity
|
|
@@ -2081,12 +2128,11 @@ function collectAddLabelDefs(ast, ref, scope, sortedCalls) {
|
|
|
2081
2128
|
if (!name) return;
|
|
2082
2129
|
const posVal = resolveNode(node.arguments?.[1], scope);
|
|
2083
2130
|
const position = typeof posVal === "number" || typeof posVal === "string" ? posVal : void 0;
|
|
2084
|
-
const
|
|
2131
|
+
const labelStart = node.__hfSiteStart ?? callee.property?.start;
|
|
2132
|
+
const labelOrder = node.__hfOrder;
|
|
2085
2133
|
let order = sortedCalls.length;
|
|
2086
|
-
if (
|
|
2087
|
-
order =
|
|
2088
|
-
(l) => l && (l.line > labelLoc.line || l.line === labelLoc.line && l.column > labelLoc.column)
|
|
2089
|
-
);
|
|
2134
|
+
if (labelStart !== void 0) {
|
|
2135
|
+
order = callKeys.findIndex((k) => comesAfter(k.site, k.order, labelStart, labelOrder));
|
|
2090
2136
|
if (order === -1) order = sortedCalls.length;
|
|
2091
2137
|
}
|
|
2092
2138
|
defs.push({ name, position, order });
|
|
@@ -2100,13 +2146,17 @@ function compareByLoc(a, b) {
|
|
|
2100
2146
|
if (!aLoc || !bLoc) return 0;
|
|
2101
2147
|
return aLoc.line - bLoc.line || aLoc.column - bLoc.column;
|
|
2102
2148
|
}
|
|
2149
|
+
function callSiteStart(call) {
|
|
2150
|
+
return call.node.__hfSiteStart ?? call.node.callee?.property?.start;
|
|
2151
|
+
}
|
|
2103
2152
|
function compareCallOrder(a, b) {
|
|
2153
|
+
const aSite = callSiteStart(a);
|
|
2154
|
+
const bSite = callSiteStart(b);
|
|
2155
|
+
if (aSite !== void 0 && bSite !== void 0 && aSite !== bSite) return aSite - bSite;
|
|
2104
2156
|
const ao = a.node.__hfOrder;
|
|
2105
2157
|
const bo = b.node.__hfOrder;
|
|
2106
|
-
if (ao
|
|
2107
|
-
|
|
2108
|
-
if (bo === void 0) return 1;
|
|
2109
|
-
return ao - bo;
|
|
2158
|
+
if (ao !== void 0 && bo !== void 0) return ao - bo;
|
|
2159
|
+
return compareByLoc(a, b);
|
|
2110
2160
|
}
|
|
2111
2161
|
function sortBySourcePosition(calls) {
|
|
2112
2162
|
calls.sort(compareCallOrder);
|
|
@@ -3428,6 +3478,7 @@ function checkOutputResolutionCompatibility(input) {
|
|
|
3428
3478
|
|
|
3429
3479
|
// src/gsapUnroll.ts
|
|
3430
3480
|
import * as acorn2 from "acorn";
|
|
3481
|
+
import * as acornWalk3 from "acorn-walk";
|
|
3431
3482
|
import MagicString2 from "magic-string";
|
|
3432
3483
|
function propEntries(props) {
|
|
3433
3484
|
return Object.entries(props).map(([k, v]) => `${safeJsKey(k)}: ${serializeValue(v)}`);
|
|
@@ -3486,37 +3537,140 @@ function enclosingTopLevel(statements, start, end) {
|
|
|
3486
3537
|
}
|
|
3487
3538
|
return null;
|
|
3488
3539
|
}
|
|
3489
|
-
function
|
|
3490
|
-
if (stmt.type === "FunctionDeclaration") return
|
|
3491
|
-
|
|
3492
|
-
|
|
3540
|
+
function declaresFunction(stmt) {
|
|
3541
|
+
if (stmt.type === "FunctionDeclaration") return true;
|
|
3542
|
+
return stmt.type === "VariableDeclaration" && (stmt.declarations ?? []).some((d) => isFunctionNode(d.init));
|
|
3543
|
+
}
|
|
3544
|
+
function declaredNames(stmt) {
|
|
3545
|
+
if (stmt.type === "FunctionDeclaration") return stmt.id?.name ? [stmt.id.name] : [];
|
|
3546
|
+
if (stmt.type !== "VariableDeclaration") return [];
|
|
3547
|
+
return (stmt.declarations ?? []).flatMap((d) => d.id?.name ? [d.id.name] : []);
|
|
3548
|
+
}
|
|
3549
|
+
function mentionsIdentifier(text, name) {
|
|
3550
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3551
|
+
return new RegExp(`(?<![\\p{ID_Continue}$])${escaped}(?![\\p{ID_Continue}$])`, "u").test(text);
|
|
3552
|
+
}
|
|
3553
|
+
function unreferencedHelperDecls(statements, script, unrolled, helperNames) {
|
|
3554
|
+
let live = statements.filter((stmt) => !unrolled.has(stmt));
|
|
3555
|
+
const dead = [];
|
|
3556
|
+
for (let changed = true; changed; ) {
|
|
3557
|
+
changed = false;
|
|
3558
|
+
for (const decl of live) {
|
|
3559
|
+
const names = declaredNames(decl);
|
|
3560
|
+
if (names.length === 0 || !names.every((n) => helperNames.has(n))) continue;
|
|
3561
|
+
const others = live.filter((s) => s !== decl).map((s) => script.slice(s.start, s.end));
|
|
3562
|
+
if (names.some((n) => others.some((text) => mentionsIdentifier(text, n)))) continue;
|
|
3563
|
+
dead.push(decl);
|
|
3564
|
+
live = live.filter((s) => s !== decl);
|
|
3565
|
+
changed = true;
|
|
3566
|
+
}
|
|
3493
3567
|
}
|
|
3494
|
-
return
|
|
3568
|
+
return dead;
|
|
3495
3569
|
}
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3570
|
+
var EFFECT_NODES = /* @__PURE__ */ new Set([
|
|
3571
|
+
"CallExpression",
|
|
3572
|
+
"NewExpression",
|
|
3573
|
+
"UpdateExpression",
|
|
3574
|
+
"AssignmentExpression"
|
|
3575
|
+
]);
|
|
3576
|
+
function containsEffect(node) {
|
|
3577
|
+
let hit = false;
|
|
3578
|
+
acornWalk3.full(node, (n) => {
|
|
3579
|
+
if (EFFECT_NODES.has(n.type)) hit = true;
|
|
3580
|
+
});
|
|
3581
|
+
return hit;
|
|
3582
|
+
}
|
|
3583
|
+
function isPureTweenChain(expr, timelineVar) {
|
|
3584
|
+
let node = expr;
|
|
3585
|
+
while (node?.type === "CallExpression") {
|
|
3586
|
+
if (!isTimelineRooted(node, timelineVar) || node.arguments.some(containsEffect)) return false;
|
|
3587
|
+
node = node.callee?.object;
|
|
3588
|
+
}
|
|
3589
|
+
return node?.type === "Identifier";
|
|
3590
|
+
}
|
|
3591
|
+
var blockStatements = (block) => block?.type === "BlockStatement" ? block.body : block ? [block] : [];
|
|
3592
|
+
function forEachBody(call) {
|
|
3593
|
+
const callback = call.callee?.property?.name === "forEach" ? call.arguments[0] : null;
|
|
3594
|
+
return callback?.body ? blockStatements(callback.body) : null;
|
|
3595
|
+
}
|
|
3596
|
+
function calledBody(call, helpers) {
|
|
3597
|
+
if (call?.type !== "CallExpression") return null;
|
|
3598
|
+
if (call.callee?.type !== "Identifier") return forEachBody(call);
|
|
3599
|
+
return helpers.get(call.callee.name) ?? null;
|
|
3600
|
+
}
|
|
3601
|
+
function bodyOf(stmt, helpers) {
|
|
3602
|
+
if (stmt.type === "ExpressionStatement") return calledBody(stmt.expression, helpers);
|
|
3603
|
+
return stmt.body ? blockStatements(stmt.body) : null;
|
|
3604
|
+
}
|
|
3605
|
+
function onlyAddsTweens(stmts, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
3606
|
+
if (seen.has(stmts)) return false;
|
|
3607
|
+
seen.add(stmts);
|
|
3608
|
+
return stmts.every((stmt) => {
|
|
3609
|
+
if (stmt.type === "VariableDeclaration") return !containsEffect(stmt);
|
|
3610
|
+
if (stmt.type === "ExpressionStatement" && isPureTweenChain(stmt.expression, ctx.timelineVar)) {
|
|
3611
|
+
return true;
|
|
3612
|
+
}
|
|
3613
|
+
const nested = bodyOf(stmt, ctx.helpers);
|
|
3614
|
+
return nested !== null && onlyAddsTweens(nested, ctx, seen);
|
|
3615
|
+
});
|
|
3616
|
+
}
|
|
3617
|
+
function declaredFunctions(stmt) {
|
|
3618
|
+
if (stmt.type === "FunctionDeclaration") {
|
|
3619
|
+
return stmt.id?.name ? [[stmt.id.name, blockStatements(stmt.body)]] : [];
|
|
3620
|
+
}
|
|
3621
|
+
if (stmt.type !== "VariableDeclaration") return [];
|
|
3622
|
+
return stmt.declarations.filter((d) => d.id?.name && isFunctionNode(d.init)).map((d) => [d.id.name, blockStatements(d.init.body)]);
|
|
3623
|
+
}
|
|
3624
|
+
var collectHelperBodies = (statements) => new Map(statements.flatMap(declaredFunctions));
|
|
3625
|
+
function dropStatementsUnsafeToUnroll(byStatement, ctx) {
|
|
3626
|
+
for (const [stmt, anims] of byStatement) {
|
|
3627
|
+
const unknownTiming = anims.some(
|
|
3628
|
+
(a) => a.durationUnresolved || a.resolvedStart === void 0 || a.hasUnresolvedSelector
|
|
3629
|
+
);
|
|
3630
|
+
const bodyStmts = unknownTiming ? null : bodyOf(stmt, ctx.helpers);
|
|
3631
|
+
if (bodyStmts === null || !onlyAddsTweens(bodyStmts, ctx)) byStatement.delete(stmt);
|
|
3632
|
+
}
|
|
3633
|
+
}
|
|
3634
|
+
function groupByTopLevelStatement(computed, statements) {
|
|
3501
3635
|
const byStatement = /* @__PURE__ */ new Map();
|
|
3502
3636
|
const helperNames = /* @__PURE__ */ new Set();
|
|
3503
3637
|
for (const anim of computed) {
|
|
3504
|
-
if (anim.provenance?.fn) helperNames.add(anim.provenance.fn);
|
|
3505
3638
|
const [s, e] = anim.provenance.sourceRange;
|
|
3506
3639
|
const stmt = enclosingTopLevel(statements, s, e);
|
|
3640
|
+
if (stmt && declaresFunction(stmt)) return null;
|
|
3507
3641
|
if (!stmt) continue;
|
|
3642
|
+
if (anim.provenance?.fn) helperNames.add(anim.provenance.fn);
|
|
3508
3643
|
const list = byStatement.get(stmt) ?? [];
|
|
3509
3644
|
list.push(anim);
|
|
3510
3645
|
byStatement.set(stmt, list);
|
|
3511
3646
|
}
|
|
3647
|
+
return { byStatement, helperNames };
|
|
3648
|
+
}
|
|
3649
|
+
function unrollComputedTimeline(script) {
|
|
3650
|
+
const parsed = parseGsapScriptAcorn(script);
|
|
3651
|
+
const computed = parsed.animations.filter((a) => isComputed(a) && a.provenance?.sourceRange);
|
|
3652
|
+
if (computed.length === 0) return script;
|
|
3653
|
+
const statements = topLevelStatements(script);
|
|
3654
|
+
const grouped = groupByTopLevelStatement(computed, statements);
|
|
3655
|
+
if (!grouped) return script;
|
|
3656
|
+
const { byStatement, helperNames } = grouped;
|
|
3657
|
+
dropStatementsUnsafeToUnroll(byStatement, {
|
|
3658
|
+
timelineVar: parsed.timelineVar,
|
|
3659
|
+
helpers: collectHelperBodies(statements)
|
|
3660
|
+
});
|
|
3512
3661
|
if (byStatement.size === 0) return script;
|
|
3513
3662
|
const ms = new MagicString2(script);
|
|
3514
3663
|
for (const [stmt, anims] of byStatement) {
|
|
3515
3664
|
const literals = anims.map((a) => serializeTweenStatement(parsed.timelineVar, a)).join("\n");
|
|
3516
3665
|
ms.overwrite(stmt.start, stmt.end, literals);
|
|
3517
3666
|
}
|
|
3518
|
-
for (const
|
|
3519
|
-
|
|
3667
|
+
for (const decl of unreferencedHelperDecls(
|
|
3668
|
+
statements,
|
|
3669
|
+
script,
|
|
3670
|
+
new Set(byStatement.keys()),
|
|
3671
|
+
helperNames
|
|
3672
|
+
)) {
|
|
3673
|
+
ms.remove(decl.start, decl.end);
|
|
3520
3674
|
}
|
|
3521
3675
|
return ms.toString();
|
|
3522
3676
|
}
|
|
@@ -3526,6 +3680,235 @@ var HTML_BODY_CSS_WIDTH_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?width:\s*)(\d+)px
|
|
|
3526
3680
|
var HTML_BODY_CSS_HEIGHT_FIRST_RE = /(html\s*,\s*body\s*\{[^}]*?height:\s*)(\d+)px([^}]*?width:\s*)(\d+)px/i;
|
|
3527
3681
|
var VIEWPORT_META_SIZE_RE = /(<meta[^>]*name=["']viewport["'][^>]*content=["']width=)(\d+)(,\s*height=)(\d+)/i;
|
|
3528
3682
|
|
|
3683
|
+
// src/topLevelElements.ts
|
|
3684
|
+
var NON_RENDERED_TAGS = /* @__PURE__ */ new Set(["script", "style", "template", "noscript", "link", "meta"]);
|
|
3685
|
+
var MEDIA_TAGS = /* @__PURE__ */ new Set(["video", "audio", "img"]);
|
|
3686
|
+
var TRACK_KINDS = ["video", "audio", "captions", "graphics"];
|
|
3687
|
+
function isSubCompositionHost(node) {
|
|
3688
|
+
return node.attrs["data-composition-src"] !== void 0 || node.attrs["data-composition-id"] !== void 0;
|
|
3689
|
+
}
|
|
3690
|
+
function isTimedElement(node) {
|
|
3691
|
+
const { attrs } = node;
|
|
3692
|
+
return attrs["data-start"] !== void 0 || attrs["data-track-index"] !== void 0 && attrs["data-duration"] !== void 0 || MEDIA_TAGS.has(node.tag.toLowerCase());
|
|
3693
|
+
}
|
|
3694
|
+
function topLevelElements(root) {
|
|
3695
|
+
const rows = [];
|
|
3696
|
+
const visit = (node) => {
|
|
3697
|
+
if (NON_RENDERED_TAGS.has(node.tag.toLowerCase())) return;
|
|
3698
|
+
if (isSubCompositionHost(node) || isTimedElement(node)) rows.push(node);
|
|
3699
|
+
else node.children.forEach(visit);
|
|
3700
|
+
};
|
|
3701
|
+
root.children.forEach(visit);
|
|
3702
|
+
return rows;
|
|
3703
|
+
}
|
|
3704
|
+
function trackKindOf(node) {
|
|
3705
|
+
const explicit = node.attrs["data-track-kind"]?.trim().toLowerCase();
|
|
3706
|
+
if (explicit && TRACK_KINDS.includes(explicit))
|
|
3707
|
+
return { kind: explicit, source: "attribute" };
|
|
3708
|
+
const tag = node.tag.toLowerCase();
|
|
3709
|
+
if (tag === "video" || tag === "audio") return { kind: tag, source: "tag" };
|
|
3710
|
+
if (isSubCompositionHost(node)) {
|
|
3711
|
+
const legacy = node.attrs["data-composition-id"] === "captions" || /(?:^|\s)caption[-_]/.test(node.attrs.class ?? "");
|
|
3712
|
+
return legacy ? { kind: "captions", source: "legacy-captions" } : { kind: "graphics", source: "sub-composition" };
|
|
3713
|
+
}
|
|
3714
|
+
return { kind: "graphics", source: "tag" };
|
|
3715
|
+
}
|
|
3716
|
+
|
|
3717
|
+
// src/timingMismatches.ts
|
|
3718
|
+
import { parseHTML as parseHTML2 } from "linkedom";
|
|
3719
|
+
var EPSILON = 0.05;
|
|
3720
|
+
var NON_RENDERED = /* @__PURE__ */ new Set(["script", "style", "template", "noscript", "link", "meta"]);
|
|
3721
|
+
var toNode = (el) => ({
|
|
3722
|
+
tag: el.tagName,
|
|
3723
|
+
attrs: Object.fromEntries(Array.from(el.attributes, (a) => [a.name, a.value])),
|
|
3724
|
+
children: Array.from(el.children, toNode),
|
|
3725
|
+
el
|
|
3726
|
+
});
|
|
3727
|
+
var numeric = (value) => {
|
|
3728
|
+
if (value == null || value.trim() === "") return null;
|
|
3729
|
+
const n = Number(value);
|
|
3730
|
+
return Number.isFinite(n) ? n : null;
|
|
3731
|
+
};
|
|
3732
|
+
function queryAll(root, selector) {
|
|
3733
|
+
try {
|
|
3734
|
+
return Array.from(root.querySelectorAll(selector));
|
|
3735
|
+
} catch {
|
|
3736
|
+
return [];
|
|
3737
|
+
}
|
|
3738
|
+
}
|
|
3739
|
+
var unresolvedReason = (anim) => {
|
|
3740
|
+
if (anim.durationUnresolved) return "duration";
|
|
3741
|
+
if (anim.resolvedStart === void 0) return "position";
|
|
3742
|
+
return anim.extras?.stagger === void 0 ? null : "stagger";
|
|
3743
|
+
};
|
|
3744
|
+
function rowMembership(root) {
|
|
3745
|
+
const rows = topLevelElements(toNode(root));
|
|
3746
|
+
const rowEls = new Set(rows.map((r) => r.el));
|
|
3747
|
+
const insideRow = /* @__PURE__ */ new Set();
|
|
3748
|
+
for (const row of rows) {
|
|
3749
|
+
insideRow.add(row.el);
|
|
3750
|
+
for (const d of Array.from(row.el.querySelectorAll("*"))) insideRow.add(d);
|
|
3751
|
+
}
|
|
3752
|
+
return { rowEls, insideRow };
|
|
3753
|
+
}
|
|
3754
|
+
var attrNumber = (el, name) => numeric(el.getAttribute(name));
|
|
3755
|
+
function windowFinding(el, selector, anim, start, end) {
|
|
3756
|
+
const dataStart = attrNumber(el, "data-start");
|
|
3757
|
+
const duration = attrNumber(el, "data-duration");
|
|
3758
|
+
if (dataStart === null) return null;
|
|
3759
|
+
const dataEnd = duration === null ? null : dataStart + duration;
|
|
3760
|
+
const beforeStart = anim.method !== "set" && start < dataStart - EPSILON;
|
|
3761
|
+
const afterEnd = dataEnd !== null && start > dataEnd + EPSILON;
|
|
3762
|
+
if (!beforeStart && !afterEnd) return null;
|
|
3763
|
+
const elementId = el.getAttribute("id");
|
|
3764
|
+
return {
|
|
3765
|
+
kind: "tween-outside-window",
|
|
3766
|
+
selector,
|
|
3767
|
+
elementId,
|
|
3768
|
+
dataStart,
|
|
3769
|
+
dataEnd,
|
|
3770
|
+
tweenStart: start,
|
|
3771
|
+
tweenEnd: end
|
|
3772
|
+
};
|
|
3773
|
+
}
|
|
3774
|
+
var tweenEnd = (anim) => anim.resolvedStart + (anim.method === "set" ? 0 : anim.duration ?? 0.5);
|
|
3775
|
+
function checkTarget(el, selector, anim, layout, report) {
|
|
3776
|
+
if (!layout.insideRow.has(el)) {
|
|
3777
|
+
if (!NON_RENDERED.has(el.tagName.toLowerCase())) {
|
|
3778
|
+
report.findings.push({
|
|
3779
|
+
kind: "animated-without-timing",
|
|
3780
|
+
selector,
|
|
3781
|
+
elementId: el.getAttribute("id")
|
|
3782
|
+
});
|
|
3783
|
+
}
|
|
3784
|
+
return;
|
|
3785
|
+
}
|
|
3786
|
+
if (!layout.rowEls.has(el) || isSubCompositionHost(toNode(el))) return;
|
|
3787
|
+
if (el.hasAttribute("data-start") && attrNumber(el, "data-start") === null) {
|
|
3788
|
+
report.unresolved.push({ selector, reason: "start-attribute" });
|
|
3789
|
+
return;
|
|
3790
|
+
}
|
|
3791
|
+
const found = windowFinding(el, selector, anim, anim.resolvedStart, tweenEnd(anim));
|
|
3792
|
+
if (found) report.findings.push(found);
|
|
3793
|
+
}
|
|
3794
|
+
function checkTween(anim, root, layout, seenUntimed, report) {
|
|
3795
|
+
const selector = anim.targetSelector;
|
|
3796
|
+
const targets = queryAll(root, selector).filter((el) => el !== root);
|
|
3797
|
+
const reason = unresolvedReason(anim);
|
|
3798
|
+
if (reason) {
|
|
3799
|
+
if (targets.length > 0) report.unresolved.push({ selector, reason });
|
|
3800
|
+
return null;
|
|
3801
|
+
}
|
|
3802
|
+
for (const el of targets) {
|
|
3803
|
+
const loose = !layout.insideRow.has(el);
|
|
3804
|
+
if (loose && seenUntimed.has(el)) continue;
|
|
3805
|
+
if (loose) seenUntimed.add(el);
|
|
3806
|
+
checkTarget(el, selector, anim, layout, report);
|
|
3807
|
+
}
|
|
3808
|
+
return tweenEnd(anim);
|
|
3809
|
+
}
|
|
3810
|
+
function timingMismatches(html) {
|
|
3811
|
+
const report = { findings: [], unresolved: [] };
|
|
3812
|
+
const { document } = parseHTML2(html);
|
|
3813
|
+
const root = document.querySelector("[data-composition-id]");
|
|
3814
|
+
if (!root) return report;
|
|
3815
|
+
const layout = rowMembership(root);
|
|
3816
|
+
const seenUntimed = /* @__PURE__ */ new Set();
|
|
3817
|
+
const scripts = Array.from(document.querySelectorAll("script:not([src])"));
|
|
3818
|
+
const anims = scripts.flatMap((s) => parseGsapScriptAcorn(s.textContent ?? "").animations);
|
|
3819
|
+
const ends = anims.filter((anim) => !anim.global && !anim.hasUnresolvedSelector).map((anim) => checkTween(anim, root, layout, seenUntimed, report));
|
|
3820
|
+
const timelineEnd = Math.max(0, ...ends.filter((e) => e !== null));
|
|
3821
|
+
const rootDuration = attrNumber(root, "data-duration");
|
|
3822
|
+
if (rootDuration !== null && timelineEnd > rootDuration + EPSILON) {
|
|
3823
|
+
report.findings.push({ kind: "timeline-exceeds-root-duration", rootDuration, timelineEnd });
|
|
3824
|
+
}
|
|
3825
|
+
return report;
|
|
3826
|
+
}
|
|
3827
|
+
|
|
3828
|
+
// src/mediaDuration.ts
|
|
3829
|
+
var nonNegative = (raw) => {
|
|
3830
|
+
const value = parseNumeric(raw);
|
|
3831
|
+
return value !== null && value >= 0 ? value : null;
|
|
3832
|
+
};
|
|
3833
|
+
function readMediaOffsetSeconds(getAttr) {
|
|
3834
|
+
return nonNegative(getAttr("data-playback-start")) ?? nonNegative(getAttr("data-media-start")) ?? 0;
|
|
3835
|
+
}
|
|
3836
|
+
var MIN_PLAYBACK_RATE = 0.1;
|
|
3837
|
+
var MAX_PLAYBACK_RATE = 10;
|
|
3838
|
+
function clampPlaybackRate(raw) {
|
|
3839
|
+
return Number.isFinite(raw) && raw > 0 ? Math.max(MIN_PLAYBACK_RATE, Math.min(MAX_PLAYBACK_RATE, raw)) : 1;
|
|
3840
|
+
}
|
|
3841
|
+
function readPlaybackRate(getAttr, fallback = 1) {
|
|
3842
|
+
const authored = Number.parseFloat(getAttr("data-playback-rate") ?? "");
|
|
3843
|
+
return clampPlaybackRate(Number.isFinite(authored) && authored > 0 ? authored : fallback);
|
|
3844
|
+
}
|
|
3845
|
+
function readDataDurationSeconds(getAttr) {
|
|
3846
|
+
const duration = parseNumeric(getAttr("data-duration"));
|
|
3847
|
+
return duration !== null && duration > 0 ? duration : null;
|
|
3848
|
+
}
|
|
3849
|
+
function readAuthoredDurationSeconds(getAttr, startSeconds) {
|
|
3850
|
+
const duration = readDataDurationSeconds(getAttr);
|
|
3851
|
+
if (duration !== null) return duration;
|
|
3852
|
+
const end = parseNumeric(getAttr("data-end"));
|
|
3853
|
+
return end !== null ? end - startSeconds : null;
|
|
3854
|
+
}
|
|
3855
|
+
var DEFAULT_IMAGE_TIMELINE_DURATION_SECONDS = 3;
|
|
3856
|
+
function resolveNaturalDurationSeconds(sourceDurationSeconds, mediaStartSeconds, playbackRate) {
|
|
3857
|
+
if (!Number.isFinite(sourceDurationSeconds)) return null;
|
|
3858
|
+
const remaining = Math.max(0, sourceDurationSeconds - mediaStartSeconds);
|
|
3859
|
+
return remaining / clampPlaybackRate(playbackRate);
|
|
3860
|
+
}
|
|
3861
|
+
function resolveMediaDuration(input) {
|
|
3862
|
+
const { tag, authoredDurationSeconds, sourceDurationSeconds, mediaStartSeconds, playbackRate } = input;
|
|
3863
|
+
if (authoredDurationSeconds !== null && authoredDurationSeconds > 0) {
|
|
3864
|
+
return { seconds: authoredDurationSeconds, source: "authored" };
|
|
3865
|
+
}
|
|
3866
|
+
if (tag === "img") {
|
|
3867
|
+
return { seconds: DEFAULT_IMAGE_TIMELINE_DURATION_SECONDS, source: "default" };
|
|
3868
|
+
}
|
|
3869
|
+
if (sourceDurationSeconds === null) {
|
|
3870
|
+
return { seconds: null, source: "pending", reason: "source duration not yet probed" };
|
|
3871
|
+
}
|
|
3872
|
+
const seconds = resolveNaturalDurationSeconds(
|
|
3873
|
+
sourceDurationSeconds,
|
|
3874
|
+
mediaStartSeconds,
|
|
3875
|
+
playbackRate
|
|
3876
|
+
);
|
|
3877
|
+
if (seconds === null) {
|
|
3878
|
+
return { seconds: null, source: "pending", reason: "source reported a non-finite duration" };
|
|
3879
|
+
}
|
|
3880
|
+
return { seconds, source: "media" };
|
|
3881
|
+
}
|
|
3882
|
+
var PENDING_MEDIA_DURATION_READERS = [
|
|
3883
|
+
"core/src/runtime/init.ts (visibility end, clock, seek, WebAudio scheduling)",
|
|
3884
|
+
"core/src/compiler/timingCompiler.ts compileTag",
|
|
3885
|
+
"core/src/compiler/htmlCompiler.ts compileHtml",
|
|
3886
|
+
"producer/src/services/htmlCompiler.ts resolveMediaDuration",
|
|
3887
|
+
"engine/src/services/videoFrameExtractor.ts (extraction window)",
|
|
3888
|
+
"engine/src/services/audioMixer.ts",
|
|
3889
|
+
"parsers/src/htmlParser.ts (defaults to 5s, reads only data-media-start)",
|
|
3890
|
+
"studio (timelineDOM.ts, timelineElementHelpers.ts, useTimelineSyncCallbacks.ts)"
|
|
3891
|
+
];
|
|
3892
|
+
|
|
3893
|
+
// src/compositionDuration.ts
|
|
3894
|
+
var isPositiveFinite = (value) => value !== null && Number.isFinite(value) && value > 0;
|
|
3895
|
+
function resolveCompositionDuration(input) {
|
|
3896
|
+
const pendingClips = input.clipEndsSeconds.filter((end) => end === null).length;
|
|
3897
|
+
if (isPositiveFinite(input.authoredDurationSeconds)) {
|
|
3898
|
+
return { seconds: input.authoredDurationSeconds, source: "authored", pendingClips };
|
|
3899
|
+
}
|
|
3900
|
+
const known = input.clipEndsSeconds.filter(isPositiveFinite);
|
|
3901
|
+
if (known.length > 0) {
|
|
3902
|
+
return { seconds: Math.max(...known), source: "derived", pendingClips };
|
|
3903
|
+
}
|
|
3904
|
+
return {
|
|
3905
|
+
seconds: null,
|
|
3906
|
+
source: "unresolved",
|
|
3907
|
+
pendingClips,
|
|
3908
|
+
reason: pendingClips > 0 ? "every clip's length is still pending" : "no authored duration and no clip with a length"
|
|
3909
|
+
};
|
|
3910
|
+
}
|
|
3911
|
+
|
|
3529
3912
|
// src/utils/urlPath.ts
|
|
3530
3913
|
function decodeUrlPathVariants(path) {
|
|
3531
3914
|
const variants = [path];
|
|
@@ -3539,7 +3922,7 @@ function decodeUrlPathVariants(path) {
|
|
|
3539
3922
|
|
|
3540
3923
|
// src/variableUsage.ts
|
|
3541
3924
|
import * as acorn3 from "acorn";
|
|
3542
|
-
import * as
|
|
3925
|
+
import * as acornWalk4 from "acorn-walk";
|
|
3543
3926
|
function isGetVariablesCallee(callee) {
|
|
3544
3927
|
if (callee?.type === "Identifier") return callee.name === "getVariables";
|
|
3545
3928
|
if (callee?.type === "MemberExpression" && !callee.computed) {
|
|
@@ -3616,7 +3999,7 @@ function scanVariableUsage(scriptText) {
|
|
|
3616
3999
|
return { usedIds: [], scanIncomplete: true };
|
|
3617
4000
|
}
|
|
3618
4001
|
const aliases = /* @__PURE__ */ new Set();
|
|
3619
|
-
|
|
4002
|
+
acornWalk4.ancestor(ast, {
|
|
3620
4003
|
CallExpression(node, _, ancestors) {
|
|
3621
4004
|
if (!isGetVariablesCallee(node.callee)) return;
|
|
3622
4005
|
const parent = ancestors[ancestors.length - 2];
|
|
@@ -3625,7 +4008,7 @@ function scanVariableUsage(scriptText) {
|
|
|
3625
4008
|
}
|
|
3626
4009
|
});
|
|
3627
4010
|
if (aliases.size > 0) {
|
|
3628
|
-
|
|
4011
|
+
acornWalk4.ancestor(ast, {
|
|
3629
4012
|
// fallow-ignore-next-line complexity
|
|
3630
4013
|
Identifier(node, _, ancestors) {
|
|
3631
4014
|
if (!aliases.has(String(node.name))) return;
|
|
@@ -3643,7 +4026,7 @@ function scanVariableUsage(scriptText) {
|
|
|
3643
4026
|
|
|
3644
4027
|
// src/mediaSrcMutation.ts
|
|
3645
4028
|
import * as acorn4 from "acorn";
|
|
3646
|
-
import * as
|
|
4029
|
+
import * as acornWalk5 from "acorn-walk";
|
|
3647
4030
|
function parseProgram2(script) {
|
|
3648
4031
|
try {
|
|
3649
4032
|
return acorn4.parse(script, { ecmaVersion: "latest", sourceType: "script" });
|
|
@@ -3678,7 +4061,7 @@ function extractMediaSrcMutations(script) {
|
|
|
3678
4061
|
try {
|
|
3679
4062
|
const ast = parseProgram2(script);
|
|
3680
4063
|
const bindings = /* @__PURE__ */ new Map();
|
|
3681
|
-
|
|
4064
|
+
acornWalk5.simple(ast, {
|
|
3682
4065
|
VariableDeclarator(node) {
|
|
3683
4066
|
if (node.id?.type !== "Identifier") return;
|
|
3684
4067
|
const selector = lookupSelector(node.init, bindings);
|
|
@@ -3686,7 +4069,7 @@ function extractMediaSrcMutations(script) {
|
|
|
3686
4069
|
}
|
|
3687
4070
|
});
|
|
3688
4071
|
const mutations = [];
|
|
3689
|
-
|
|
4072
|
+
acornWalk5.simple(ast, {
|
|
3690
4073
|
AssignmentExpression(node) {
|
|
3691
4074
|
if (node.operator !== "=" || memberName(node.left) !== "src") return;
|
|
3692
4075
|
const selector = lookupSelector(node.left.object, bindings);
|
|
@@ -3830,6 +4213,7 @@ export {
|
|
|
3830
4213
|
ClipTimingWriteError,
|
|
3831
4214
|
CompositionHtmlParseError,
|
|
3832
4215
|
DEFAULT_DURATIONS,
|
|
4216
|
+
DEFAULT_IMAGE_TIMELINE_DURATION_SECONDS,
|
|
3833
4217
|
DERIVED_TIMING_ATTRIBUTES,
|
|
3834
4218
|
EXCLUDED_TAGS,
|
|
3835
4219
|
FONT_ALIAS_KEYS,
|
|
@@ -3837,6 +4221,9 @@ export {
|
|
|
3837
4221
|
HTML_BODY_CSS_HEIGHT_FIRST_RE,
|
|
3838
4222
|
HTML_BODY_CSS_WIDTH_FIRST_RE,
|
|
3839
4223
|
LEGACY_TIMING_ATTRIBUTES,
|
|
4224
|
+
MAX_PLAYBACK_RATE,
|
|
4225
|
+
MIN_PLAYBACK_RATE,
|
|
4226
|
+
PENDING_MEDIA_DURATION_READERS,
|
|
3840
4227
|
PROPERTY_GROUPS,
|
|
3841
4228
|
SPRING_PRESETS,
|
|
3842
4229
|
SUPPORTED_EASES,
|
|
@@ -3847,6 +4234,7 @@ export {
|
|
|
3847
4234
|
addElementToHtml,
|
|
3848
4235
|
checkOutputResolutionCompatibility,
|
|
3849
4236
|
checkSubCompositionUsability,
|
|
4237
|
+
clampPlaybackRate,
|
|
3850
4238
|
classifyPropertyGroup,
|
|
3851
4239
|
classifyTweenPropertyGroup,
|
|
3852
4240
|
decodeUrlPathVariants,
|
|
@@ -3863,7 +4251,9 @@ export {
|
|
|
3863
4251
|
isCompositionTemplate,
|
|
3864
4252
|
isMediaElement,
|
|
3865
4253
|
isStudioHoldSet,
|
|
4254
|
+
isSubCompositionHost,
|
|
3866
4255
|
isTextElement,
|
|
4256
|
+
isTimedElement,
|
|
3867
4257
|
keyframesToGsapAnimations,
|
|
3868
4258
|
mintHfId,
|
|
3869
4259
|
normalizeResolutionFlag,
|
|
@@ -3873,14 +4263,24 @@ export {
|
|
|
3873
4263
|
parseNumeric,
|
|
3874
4264
|
parseStartExpression,
|
|
3875
4265
|
queryByAttr,
|
|
4266
|
+
readAuthoredDurationSeconds,
|
|
3876
4267
|
readClipTiming,
|
|
4268
|
+
readDataDurationSeconds,
|
|
4269
|
+
readMediaOffsetSeconds,
|
|
4270
|
+
readPlaybackRate,
|
|
3877
4271
|
removeElementFromHtml,
|
|
3878
4272
|
removeElementWithGsapCascade,
|
|
3879
4273
|
resolveAliasDisplayName,
|
|
4274
|
+
resolveCompositionDuration,
|
|
4275
|
+
resolveMediaDuration,
|
|
4276
|
+
resolveNaturalDurationSeconds,
|
|
3880
4277
|
resolveResolutionFlagPair,
|
|
3881
4278
|
scanVariableUsage,
|
|
3882
4279
|
serializeGsapAnimations,
|
|
3883
4280
|
suggestMatchingPreset,
|
|
4281
|
+
timingMismatches,
|
|
4282
|
+
topLevelElements,
|
|
4283
|
+
trackKindOf,
|
|
3884
4284
|
unrollComputedTimeline,
|
|
3885
4285
|
updateElementInHtml,
|
|
3886
4286
|
validateCompositionGsap,
|