@vosjs/studio-core 0.4.0 → 0.5.0
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/README.md +69 -52
- package/dist/index.d.ts +258 -6
- package/dist/index.js +474 -38
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -1099,7 +1099,7 @@ import {
|
|
|
1099
1099
|
lerpArray,
|
|
1100
1100
|
sample,
|
|
1101
1101
|
segmentRate as segmentRate2,
|
|
1102
|
-
sortKeyframes,
|
|
1102
|
+
sortKeyframes as sortKeyframes2,
|
|
1103
1103
|
sourceToTimeline as sourceToTimeline2,
|
|
1104
1104
|
splitBySpeed,
|
|
1105
1105
|
totalDuration
|
|
@@ -1107,27 +1107,33 @@ import {
|
|
|
1107
1107
|
import { timelineRuntimeCode as timelineRuntimeCode2 } from "@vosjs/timeline/bundle";
|
|
1108
1108
|
|
|
1109
1109
|
// src/layout.ts
|
|
1110
|
-
function computeCardLayout(frame, video, W, H) {
|
|
1110
|
+
function computeCardLayout(frame, video, W, H, zoomFocus) {
|
|
1111
1111
|
const s = H / 1080;
|
|
1112
1112
|
const pad = (frame.padding || 0) * s;
|
|
1113
|
+
const ins = frame.inset ?? {};
|
|
1114
|
+
const padL = ins.left == null ? pad : ins.left * W;
|
|
1115
|
+
const padR = ins.right == null ? pad : ins.right * W;
|
|
1116
|
+
const padT = ins.top == null ? pad : ins.top * H;
|
|
1117
|
+
const padB = ins.bottom == null ? pad : ins.bottom * H;
|
|
1113
1118
|
const bar = frame.browserBar;
|
|
1114
1119
|
const vw = video.width || 16;
|
|
1115
1120
|
const vh = video.height || 9;
|
|
1116
1121
|
const fitCover = frame.fit === "cover";
|
|
1117
1122
|
const cf = fitCover ? 1 : Math.min(1, W / H / (vw / vh));
|
|
1118
1123
|
const barH = bar.kind !== "none" ? (bar.height || 44) * s * cf : 0;
|
|
1119
|
-
const availW = Math.max(1, W -
|
|
1120
|
-
const availH = Math.max(1, H -
|
|
1124
|
+
const availW = Math.max(1, W - padL - padR);
|
|
1125
|
+
const availH = Math.max(1, H - padT - padB - barH);
|
|
1121
1126
|
if (fitCover) {
|
|
1122
1127
|
const sc2 = Math.max(availW / vw, availH / vh);
|
|
1123
1128
|
const dw2 = vw * sc2;
|
|
1124
1129
|
const dh2 = vh * sc2;
|
|
1125
|
-
const
|
|
1126
|
-
const
|
|
1127
|
-
const
|
|
1130
|
+
const follow = frame.focusFollow === "camera" && zoomFocus ? zoomFocus : null;
|
|
1131
|
+
const fcx = clamp013(follow ? follow.cx : frame.focus?.cx ?? 0.5);
|
|
1132
|
+
const fcy = clamp013(follow ? follow.cy : frame.focus?.cy ?? 0.5);
|
|
1133
|
+
const vTop = padT + barH;
|
|
1128
1134
|
const dx2 = Math.min(
|
|
1129
|
-
|
|
1130
|
-
Math.max(
|
|
1135
|
+
padL,
|
|
1136
|
+
Math.max(padL + availW - dw2, padL + availW / 2 - fcx * dw2)
|
|
1131
1137
|
);
|
|
1132
1138
|
const dy2 = Math.min(
|
|
1133
1139
|
vTop,
|
|
@@ -1140,8 +1146,8 @@ function computeCardLayout(frame, video, W, H) {
|
|
|
1140
1146
|
dy: dy2,
|
|
1141
1147
|
dw: dw2,
|
|
1142
1148
|
dh: dh2,
|
|
1143
|
-
cardX:
|
|
1144
|
-
cardY:
|
|
1149
|
+
cardX: padL,
|
|
1150
|
+
cardY: padT,
|
|
1145
1151
|
cardW: availW,
|
|
1146
1152
|
cardH: availH + barH
|
|
1147
1153
|
};
|
|
@@ -1149,8 +1155,8 @@ function computeCardLayout(frame, video, W, H) {
|
|
|
1149
1155
|
const sc = Math.min(availW / vw, availH / vh);
|
|
1150
1156
|
const dw = vw * sc;
|
|
1151
1157
|
const dh = vh * sc;
|
|
1152
|
-
const dx = (
|
|
1153
|
-
const dy = (
|
|
1158
|
+
const dx = padL + (availW - dw) / 2;
|
|
1159
|
+
const dy = padT + barH + (availH - dh) / 2;
|
|
1154
1160
|
return {
|
|
1155
1161
|
W,
|
|
1156
1162
|
H,
|
|
@@ -2741,6 +2747,117 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
|
|
|
2741
2747
|
|
|
2742
2748
|
}`;
|
|
2743
2749
|
|
|
2750
|
+
// src/lower/motion.ts
|
|
2751
|
+
import { sortKeyframes } from "@vosjs/timeline";
|
|
2752
|
+
var ENTRANCE_SECONDS = 1.2;
|
|
2753
|
+
var END_CARD_SECONDS = 2.5;
|
|
2754
|
+
var END_CARD_RECEDE = 0.7;
|
|
2755
|
+
var TILT_IN_POSE = [-9, 14];
|
|
2756
|
+
var PULL_OUT_LEVEL = 1.32;
|
|
2757
|
+
var HOLD_SOURCE_SPAN = 2e-3;
|
|
2758
|
+
function entranceSeconds(e) {
|
|
2759
|
+
if (!e || e.kind === "none") return 0;
|
|
2760
|
+
return Math.max(0.2, Math.min(3, e.seconds ?? ENTRANCE_SECONDS));
|
|
2761
|
+
}
|
|
2762
|
+
function withHolds(docSegments, rated) {
|
|
2763
|
+
const out = [];
|
|
2764
|
+
const pending = docSegments.filter((s) => typeof s.hold === "number" && s.hold > 0).map((s) => ({ out: s.out, hold: s.hold, used: false }));
|
|
2765
|
+
for (let i = 0; i < rated.length; i++) {
|
|
2766
|
+
const piece = rated[i];
|
|
2767
|
+
out.push(piece);
|
|
2768
|
+
const next = rated[i + 1];
|
|
2769
|
+
for (const p of pending) {
|
|
2770
|
+
if (p.used) continue;
|
|
2771
|
+
const endsHere = Math.abs(piece.out - p.out) < 1e-9;
|
|
2772
|
+
const nextContinues = next && Math.abs(next.in - p.out) < 1e-9 && next.out > p.out;
|
|
2773
|
+
if (endsHere && !nextContinues) {
|
|
2774
|
+
out.push({
|
|
2775
|
+
in: p.out - HOLD_SOURCE_SPAN,
|
|
2776
|
+
out: p.out,
|
|
2777
|
+
rate: HOLD_SOURCE_SPAN / p.hold
|
|
2778
|
+
});
|
|
2779
|
+
p.used = true;
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
return out;
|
|
2784
|
+
}
|
|
2785
|
+
function entranceTiltKeyframes(e) {
|
|
2786
|
+
const s = entranceSeconds(e);
|
|
2787
|
+
if (!s || e?.kind !== "tilt-in") return [];
|
|
2788
|
+
return [
|
|
2789
|
+
{ t: 0, value: [...TILT_IN_POSE], ease: "none" },
|
|
2790
|
+
{ t: s, value: [0, 0], ease: "power3.out" }
|
|
2791
|
+
];
|
|
2792
|
+
}
|
|
2793
|
+
function entranceZoomKeyframes(e) {
|
|
2794
|
+
const s = entranceSeconds(e);
|
|
2795
|
+
if (!s) return [];
|
|
2796
|
+
if (e?.kind === "pull-out")
|
|
2797
|
+
return [
|
|
2798
|
+
{ t: 0, value: [PULL_OUT_LEVEL, 0.5, 0.42], ease: "none" },
|
|
2799
|
+
{ t: s, value: [1, 0.5, 0.5], ease: "power3.out" }
|
|
2800
|
+
];
|
|
2801
|
+
return [
|
|
2802
|
+
{ t: 0, value: [1, 0.5, 0.5], ease: "none" },
|
|
2803
|
+
{ t: s, value: [1, 0.5, 0.5], ease: "none" }
|
|
2804
|
+
];
|
|
2805
|
+
}
|
|
2806
|
+
function prependEntrance(track, head) {
|
|
2807
|
+
if (!head.length) return track;
|
|
2808
|
+
const end = head[head.length - 1].t;
|
|
2809
|
+
const rest = (track?.keyframes ?? []).filter((k) => k.t > end + 0.1);
|
|
2810
|
+
return { keyframes: sortKeyframes([...head, ...rest]) };
|
|
2811
|
+
}
|
|
2812
|
+
function cardPoseTrack(e, endStart, endSeconds) {
|
|
2813
|
+
const keyframes = [];
|
|
2814
|
+
const s = entranceSeconds(e);
|
|
2815
|
+
if (s) {
|
|
2816
|
+
const from = e?.kind === "rise" ? [0.96, 0.08, 0.7] : e?.kind === "pull-out" ? [1, 0, 1] : [0.94, 0.05, 0.7];
|
|
2817
|
+
keyframes.push({ t: 0, value: from, ease: "none" });
|
|
2818
|
+
keyframes.push({ t: s, value: [1, 0, 1], ease: "power3.out" });
|
|
2819
|
+
}
|
|
2820
|
+
if (endStart !== null && endSeconds > 0) {
|
|
2821
|
+
const t0 = Math.max(endStart, s);
|
|
2822
|
+
keyframes.push({ t: t0, value: [1, 0, 1], ease: "none" });
|
|
2823
|
+
keyframes.push({
|
|
2824
|
+
t: t0 + Math.min(END_CARD_RECEDE, endSeconds * 0.4),
|
|
2825
|
+
value: [0.9, -0.02, 0.22],
|
|
2826
|
+
ease: "power2.out"
|
|
2827
|
+
});
|
|
2828
|
+
}
|
|
2829
|
+
if (!keyframes.length) return void 0;
|
|
2830
|
+
return { keyframes: sortKeyframes(keyframes) };
|
|
2831
|
+
}
|
|
2832
|
+
function expandEndCard(doc, outputDuration) {
|
|
2833
|
+
const card = doc.endCard;
|
|
2834
|
+
if (!card || !doc.segments.length) return { doc, endStart: null, seconds: 0 };
|
|
2835
|
+
const seconds = Math.max(1, Math.min(8, card.seconds ?? END_CARD_SECONDS));
|
|
2836
|
+
const segments = doc.segments.map(
|
|
2837
|
+
(s, i) => i === doc.segments.length - 1 ? { ...s, hold: (s.hold ?? 0) + seconds } : s
|
|
2838
|
+
);
|
|
2839
|
+
const endStart = outputDuration;
|
|
2840
|
+
const clips = [];
|
|
2841
|
+
const text = (id, body, preset, y, delay) => ({
|
|
2842
|
+
id,
|
|
2843
|
+
kind: "text",
|
|
2844
|
+
text: body,
|
|
2845
|
+
preset,
|
|
2846
|
+
start: endStart + delay,
|
|
2847
|
+
duration: Math.max(0.3, seconds - delay),
|
|
2848
|
+
transform: { x: 0.5, y, scale: 1, rotation: 0 },
|
|
2849
|
+
enter: "rise",
|
|
2850
|
+
exit: "none",
|
|
2851
|
+
align: "center",
|
|
2852
|
+
...card.ink ? { color: card.ink } : {}
|
|
2853
|
+
});
|
|
2854
|
+
if (card.headline?.trim()) clips.push(text("endcard-title", card.headline.trim(), "title", 0.44, 0.35));
|
|
2855
|
+
if (card.sub?.trim()) clips.push(text("endcard-sub", card.sub.trim(), "caption", 0.57, 0.5));
|
|
2856
|
+
if (card.wordmark?.trim()) clips.push(text("endcard-mark", card.wordmark.trim(), "label", 0.88, 0.65));
|
|
2857
|
+
const overlays = [...doc.overlays ?? [], ...clips];
|
|
2858
|
+
return { doc: { ...doc, segments, overlays }, endStart, seconds };
|
|
2859
|
+
}
|
|
2860
|
+
|
|
2744
2861
|
// src/lower/extractClicks.ts
|
|
2745
2862
|
import { segmentRate, sourceToTimeline } from "@vosjs/timeline";
|
|
2746
2863
|
var CLICK_FX_PRE = 0.06;
|
|
@@ -2845,7 +2962,7 @@ var CAM_PAN_EASE = ZOOM_PAN_EASE;
|
|
|
2845
2962
|
var PROGRAM_DURATION = 1;
|
|
2846
2963
|
function ratedSegments(doc) {
|
|
2847
2964
|
const segs = isRecordingDoc(doc) ? doc.segments.length ? doc.segments : [{ in: 0, out: doc.source.meta.durationMs / 1e3 }] : [{ in: 0, out: programDuration(doc) }];
|
|
2848
|
-
return splitBySpeed(segs, doc.speed ?? []);
|
|
2965
|
+
return withHolds(segs, splitBySpeed(segs, doc.speed ?? []));
|
|
2849
2966
|
}
|
|
2850
2967
|
function durationSec(doc, rated) {
|
|
2851
2968
|
const trimmed = totalDuration(rated);
|
|
@@ -2937,7 +3054,7 @@ function zoomTrackFromDoc(zoom, segments, style = ZOOM_STYLES[DEFAULT_ZOOM_STYLE
|
|
|
2937
3054
|
chained = false;
|
|
2938
3055
|
}
|
|
2939
3056
|
}
|
|
2940
|
-
return { keyframes:
|
|
3057
|
+
return { keyframes: sortKeyframes2(keyframes) };
|
|
2941
3058
|
}
|
|
2942
3059
|
function sameVec(a, b) {
|
|
2943
3060
|
return a.length === b.length && a.every((v, i) => Math.abs(v - b[i]) < 1e-6);
|
|
@@ -2978,7 +3095,7 @@ function tiltTrackFromDoc(tilt, segments, motion = {}) {
|
|
|
2978
3095
|
chained = false;
|
|
2979
3096
|
}
|
|
2980
3097
|
}
|
|
2981
|
-
return { keyframes:
|
|
3098
|
+
return { keyframes: sortKeyframes2(keyframes) };
|
|
2982
3099
|
}
|
|
2983
3100
|
function camRestPose(cam, W, H = 1080) {
|
|
2984
3101
|
const r = camBubbleRect(cam, W, H);
|
|
@@ -3020,7 +3137,7 @@ function camTrackFromDoc(cam, spans, segments, W, H = 1080) {
|
|
|
3020
3137
|
chained = false;
|
|
3021
3138
|
}
|
|
3022
3139
|
}
|
|
3023
|
-
return { keyframes:
|
|
3140
|
+
return { keyframes: sortKeyframes2(keyframes) };
|
|
3024
3141
|
}
|
|
3025
3142
|
function camRectFromPose(pose, cam, W, H = 1080) {
|
|
3026
3143
|
const s = H / 1080;
|
|
@@ -3060,7 +3177,7 @@ function motionTrack(base, keys, dur) {
|
|
|
3060
3177
|
spanEase(k.ease, MOTION_EASE)
|
|
3061
3178
|
);
|
|
3062
3179
|
}
|
|
3063
|
-
return { keyframes:
|
|
3180
|
+
return { keyframes: sortKeyframes2(keyframes) };
|
|
3064
3181
|
}
|
|
3065
3182
|
function overlayMotionBase(o) {
|
|
3066
3183
|
return [
|
|
@@ -3750,6 +3867,14 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
3750
3867
|
// strip is part of the card: it takes barH from the available height and the video
|
|
3751
3868
|
// sits below it \u2014 bar + video share the rounded clip and zoom together.
|
|
3752
3869
|
var pad = (frame.padding || 0) * s
|
|
3870
|
+
// Per-side placement (frame.inset: fractions of the frame, a negative side
|
|
3871
|
+
// bleeds the card past the edge) overrides the symmetric padding on the
|
|
3872
|
+
// sides it names; absent sides keep pad, so the old math falls out.
|
|
3873
|
+
var ipIns = frame.inset || {}
|
|
3874
|
+
var ipL = ipIns.left == null ? pad : ipIns.left * W
|
|
3875
|
+
var ipR = ipIns.right == null ? pad : ipIns.right * W
|
|
3876
|
+
var ipT = ipIns.top == null ? pad : ipIns.top * H
|
|
3877
|
+
var ipB = ipIns.bottom == null ? pad : ipIns.bottom * H
|
|
3753
3878
|
var bar = frame.browserBar || {}
|
|
3754
3879
|
// Window takes carry a viewport crop (drawImage source rect, capture px) that
|
|
3755
3880
|
// removes the real browser chrome \u2014 the card's source dims are then the CROP
|
|
@@ -3775,35 +3900,48 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
3775
3900
|
var fitCover = frame.fit === 'cover'
|
|
3776
3901
|
var cf = fitCover ? 1 : Math.min(1, (W / H) / (vw / vh))
|
|
3777
3902
|
var s2 = s * cf
|
|
3903
|
+
// current zoom \u2014 a standard keyframe track in OUTPUT time (hold + arrival pairs
|
|
3904
|
+
// expanded by the lowering), sampled with the shared deterministic interpolator.
|
|
3905
|
+
// Sampled here, before the rect math, so a cover crop can follow it.
|
|
3906
|
+
var lvl = 1, zx = 0.5, zy = 0.5
|
|
3907
|
+
var zt = d.zoomTrack
|
|
3908
|
+
if (zt && zt.keyframes && zt.keyframes.length) {
|
|
3909
|
+
var z = TL.sample(zt, t, TL.lerpArray)
|
|
3910
|
+
lvl = z[0]; zx = z[1]; zy = z[2]
|
|
3911
|
+
}
|
|
3778
3912
|
var barH = bar.kind && bar.kind !== 'none' ? (bar.height || 44) * s2 : 0
|
|
3779
|
-
var availW = Math.max(1, W -
|
|
3913
|
+
var availW = Math.max(1, W - ipL - ipR), availH = Math.max(1, H - ipT - ipB - barH)
|
|
3780
3914
|
var sc, dw, dh, dx, dy, cardX, cardY, cardW, cardH
|
|
3781
3915
|
if (fitCover) {
|
|
3782
3916
|
sc = Math.max(availW / vw, availH / vh)
|
|
3783
3917
|
dw = vw * sc; dh = vh * sc
|
|
3784
|
-
cardX =
|
|
3918
|
+
cardX = ipL; cardY = ipT; cardW = availW; cardH = availH + barH
|
|
3785
3919
|
var fcv = frame.focus || {}
|
|
3786
3920
|
var fcx = fcv.cx == null ? 0.5 : Math.max(0, Math.min(1, fcv.cx))
|
|
3787
3921
|
var fcy = fcv.cy == null ? 0.5 : Math.max(0, Math.min(1, fcv.cy))
|
|
3788
|
-
|
|
3922
|
+
// focusFollow: the crop keeps the camera's focus in frame (a 9:16 cut).
|
|
3923
|
+
if (frame.focusFollow === 'camera' && zt && zt.keyframes && zt.keyframes.length) { fcx = zx; fcy = zy }
|
|
3924
|
+
var vTop = ipT + barH
|
|
3789
3925
|
dx = Math.min(cardX, Math.max(cardX + availW - dw, cardX + availW / 2 - fcx * dw))
|
|
3790
3926
|
dy = Math.min(vTop, Math.max(vTop + availH - dh, vTop + availH / 2 - fcy * dh))
|
|
3791
3927
|
} else {
|
|
3792
3928
|
sc = Math.min(availW / vw, availH / vh)
|
|
3793
3929
|
dw = vw * sc; dh = vh * sc
|
|
3794
|
-
|
|
3930
|
+
// Centred inside the inset area (equal to (W - dw) / 2 when no side is
|
|
3931
|
+
// inset, the old formula).
|
|
3932
|
+
dx = ipL + (availW - dw) / 2; dy = ipT + barH + (availH - dh) / 2
|
|
3795
3933
|
cardX = dx; cardY = dy - barH; cardW = dw; cardH = dh + barH
|
|
3796
3934
|
}
|
|
3797
3935
|
var radius = (frame.radius || 0) * s2
|
|
3798
3936
|
var shadow = frame.shadow || 0
|
|
3799
|
-
|
|
3800
|
-
//
|
|
3801
|
-
//
|
|
3802
|
-
var
|
|
3803
|
-
var
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3937
|
+
// The shadow's colour (a #rrggbb; the strengths are its alpha) and the
|
|
3938
|
+
// optional tight CONTACT layer that makes a light card sit on a light
|
|
3939
|
+
// ground.
|
|
3940
|
+
var shC = frame.shadowContact || 0
|
|
3941
|
+
var shRgb = '0,0,0'
|
|
3942
|
+
var shHex = frame.shadowColor
|
|
3943
|
+
if (typeof shHex === 'string' && /^#[0-9a-fA-F]{6}$/.test(shHex)) {
|
|
3944
|
+
shRgb = parseInt(shHex.slice(1, 3), 16) + ',' + parseInt(shHex.slice(3, 5), 16) + ',' + parseInt(shHex.slice(5, 7), 16)
|
|
3807
3945
|
}
|
|
3808
3946
|
|
|
3809
3947
|
function rr(x, y, w, h, rd, cx) {
|
|
@@ -3822,12 +3960,21 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
3822
3960
|
// soft shadow behind the card (bar strip + video)
|
|
3823
3961
|
if (shadow > 0) {
|
|
3824
3962
|
c.save()
|
|
3825
|
-
c.shadowColor = 'rgba(
|
|
3963
|
+
c.shadowColor = 'rgba(' + shRgb + ',' + shadow + ')'
|
|
3826
3964
|
c.shadowBlur = 60 * s2; c.shadowOffsetY = 24 * s2
|
|
3827
3965
|
c.fillStyle = '#000'
|
|
3828
3966
|
rr(cardX, cardY, cardW, cardH, radius); c.fill()
|
|
3829
3967
|
c.restore()
|
|
3830
3968
|
}
|
|
3969
|
+
// contact shadow: tight and close, over the ambient layer
|
|
3970
|
+
if (shC > 0) {
|
|
3971
|
+
c.save()
|
|
3972
|
+
c.shadowColor = 'rgba(' + shRgb + ',' + shC + ')'
|
|
3973
|
+
c.shadowBlur = 10 * s2; c.shadowOffsetY = 3 * s2
|
|
3974
|
+
c.fillStyle = '#000'
|
|
3975
|
+
rr(cardX, cardY, cardW, cardH, radius); c.fill()
|
|
3976
|
+
c.restore()
|
|
3977
|
+
}
|
|
3831
3978
|
// video, then bar, clipped to the card's rounded corners. The bar draws
|
|
3832
3979
|
// AFTER the footage: under cover the video rect can overflow ABOVE the
|
|
3833
3980
|
// bar strip (a vertical crop), and bar-first let the footage paint over
|
|
@@ -4191,6 +4338,20 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
4191
4338
|
}
|
|
4192
4339
|
card.mesh.rotation.x = rx
|
|
4193
4340
|
card.mesh.rotation.y = ry
|
|
4341
|
+
// The card's pose through an entrance or an end card: [scale, dy,
|
|
4342
|
+
// opacity]; absent = the rest pose, exactly as before the track existed.
|
|
4343
|
+
var cpk = d.cardPoseTrack
|
|
4344
|
+
var cpH = card.mesh.geometry && card.mesh.geometry.parameters ? card.mesh.geometry.parameters.height : 0
|
|
4345
|
+
if (cpk && cpk.keyframes && cpk.keyframes.length && card.mesh.scale && card.mesh.position) {
|
|
4346
|
+
var cpv = TL.sample(cpk, t, TL.lerpArray)
|
|
4347
|
+
card.mesh.scale.x = cpv[0]; card.mesh.scale.y = cpv[0]
|
|
4348
|
+
card.mesh.position.y = cpv[1] * cpH
|
|
4349
|
+
if (card.mesh.material) card.mesh.material.opacity = cpv[2]
|
|
4350
|
+
} else if (card.mesh.scale && card.mesh.position && ((card.mesh.scale.x !== undefined && card.mesh.scale.x !== 1) || (card.mesh.position.y !== undefined && card.mesh.position.y !== 0))) {
|
|
4351
|
+
card.mesh.scale.x = 1; card.mesh.scale.y = 1
|
|
4352
|
+
card.mesh.position.y = 0
|
|
4353
|
+
if (card.mesh.material) card.mesh.material.opacity = 1
|
|
4354
|
+
}
|
|
4194
4355
|
var tilted = rx * rx + ry * ry > 1e-6
|
|
4195
4356
|
if (card.texture && card.texture.generateMipmaps !== tilted) {
|
|
4196
4357
|
var THREE2 = ctx.THREE
|
|
@@ -4372,7 +4533,10 @@ function studioLayerData(layers, duration) {
|
|
|
4372
4533
|
} : {}
|
|
4373
4534
|
};
|
|
4374
4535
|
}
|
|
4375
|
-
function lowerToComposition(
|
|
4536
|
+
function lowerToComposition(input) {
|
|
4537
|
+
const before = durationSec(input, ratedSegments(input));
|
|
4538
|
+
const expanded = expandEndCard(input, before);
|
|
4539
|
+
const doc = expanded.doc;
|
|
4376
4540
|
const rated = ratedSegments(doc);
|
|
4377
4541
|
const duration = durationSec(doc, rated);
|
|
4378
4542
|
const fx = doc.cursor.clickFx;
|
|
@@ -4445,15 +4609,33 @@ function lowerToComposition(doc) {
|
|
|
4445
4609
|
// intensities/colors become numbers HERE — ON_FRAME reads no registry).
|
|
4446
4610
|
...clickFxData(doc, rated),
|
|
4447
4611
|
// Rated segments so zoom spans land at their speed-adjusted output times.
|
|
4448
|
-
|
|
4612
|
+
// A pull-out entrance writes the track's head.
|
|
4613
|
+
zoomTrack: prependEntrance(
|
|
4614
|
+
zoomTrackFromDoc(zoomSpans, rated, zoomStyle),
|
|
4615
|
+
entranceZoomKeyframes(doc.frame.entrance)
|
|
4616
|
+
),
|
|
4449
4617
|
// Tilt spans: OUTPUT-time [rx, ry] degree track. The rest pose is
|
|
4450
4618
|
// FLAT — there is no static card tilt any more — and the motion constants
|
|
4451
4619
|
// come from the camera style's tilt personality ('drift' slows its
|
|
4452
4620
|
// leans, 'keynote' matches the zoom ramps). Omitted when the doc has no
|
|
4453
|
-
// spans — byte parity.
|
|
4454
|
-
|
|
4455
|
-
|
|
4456
|
-
|
|
4621
|
+
// spans and no tilt-in entrance — byte parity. The entrance is a
|
|
4622
|
+
// producer of this track, never a second pose.
|
|
4623
|
+
...(() => {
|
|
4624
|
+
const head = entranceTiltKeyframes(doc.frame.entrance);
|
|
4625
|
+
const spans = doc.tilt && doc.tilt.length ? tiltTrackFromDoc(doc.tilt, rated, zoomStyle.tilt) : void 0;
|
|
4626
|
+
const track = prependEntrance(spans, head);
|
|
4627
|
+
return track ? { tiltTrack: track } : {};
|
|
4628
|
+
})(),
|
|
4629
|
+
// The card's pose through the entrance and the end card: [scale, dy,
|
|
4630
|
+
// opacity] in output seconds. Absent when neither exists.
|
|
4631
|
+
...(() => {
|
|
4632
|
+
const track = cardPoseTrack(
|
|
4633
|
+
doc.frame.entrance,
|
|
4634
|
+
expanded.endStart,
|
|
4635
|
+
expanded.seconds
|
|
4636
|
+
);
|
|
4637
|
+
return track ? { cardPoseTrack: track } : {};
|
|
4638
|
+
})()
|
|
4457
4639
|
};
|
|
4458
4640
|
const entryData = {
|
|
4459
4641
|
lights: true,
|
|
@@ -5230,7 +5412,7 @@ function lowerProgramDoc(doc, opts = {}) {
|
|
|
5230
5412
|
|
|
5231
5413
|
// src/destinations.ts
|
|
5232
5414
|
var CHANNEL_SPECS_VERIFIED = "2026-08-04";
|
|
5233
|
-
var CHANNEL_SPECS_HASH = "
|
|
5415
|
+
var CHANNEL_SPECS_HASH = "e48926c22737b5dfaabf5cb33916a50a5eccd4b93498c2059a1468bd963a0a86";
|
|
5234
5416
|
var DESTINATIONS = [
|
|
5235
5417
|
{
|
|
5236
5418
|
id: "youtube-main-demo",
|
|
@@ -5248,6 +5430,13 @@ var DESTINATIONS = [
|
|
|
5248
5430
|
format: "mp4",
|
|
5249
5431
|
accepts: "mp4 (H.264+AAC)",
|
|
5250
5432
|
fit: "contain",
|
|
5433
|
+
text: "allowed",
|
|
5434
|
+
safe: {
|
|
5435
|
+
x: 0.05,
|
|
5436
|
+
y: 0.08,
|
|
5437
|
+
w: 0.9,
|
|
5438
|
+
h: 0.84
|
|
5439
|
+
},
|
|
5251
5440
|
notes: "Captions burned in. The same public upload serves the Chrome Web Store promo video and Product Hunt video (both take YouTube URLs only)."
|
|
5252
5441
|
},
|
|
5253
5442
|
{
|
|
@@ -5267,6 +5456,13 @@ var DESTINATIONS = [
|
|
|
5267
5456
|
format: "mp4",
|
|
5268
5457
|
accepts: "mp4 (H.264+AAC ONLY \u2014 HEVC/VP9/AV1 rejected)",
|
|
5269
5458
|
fit: "contain",
|
|
5459
|
+
text: "allowed",
|
|
5460
|
+
safe: {
|
|
5461
|
+
x: 0.05,
|
|
5462
|
+
y: 0.08,
|
|
5463
|
+
w: 0.9,
|
|
5464
|
+
h: 0.84
|
|
5465
|
+
},
|
|
5270
5466
|
notes: "30\u201360s plays best; 140s/512MB is the free-tier ceiling. 1:1 also allowed. Native upload, never a link post."
|
|
5271
5467
|
},
|
|
5272
5468
|
{
|
|
@@ -5285,6 +5481,13 @@ var DESTINATIONS = [
|
|
|
5285
5481
|
format: "mp4",
|
|
5286
5482
|
accepts: "mp4 (H.264+AAC)",
|
|
5287
5483
|
fit: "contain",
|
|
5484
|
+
text: "expected",
|
|
5485
|
+
safe: {
|
|
5486
|
+
x: 0.0833,
|
|
5487
|
+
y: 0.1979,
|
|
5488
|
+
w: 0.8333,
|
|
5489
|
+
h: 0.6042
|
|
5490
|
+
},
|
|
5288
5491
|
notes: "Critical text inside a centered ~900\xD71160 safe zone \u2014 platform chrome covers the rest. Serves YouTube Shorts and LinkedIn native vertical."
|
|
5289
5492
|
},
|
|
5290
5493
|
{
|
|
@@ -5304,6 +5507,13 @@ var DESTINATIONS = [
|
|
|
5304
5507
|
format: "mp4",
|
|
5305
5508
|
accepts: "mp4 (H.264)",
|
|
5306
5509
|
fit: "contain",
|
|
5510
|
+
text: "none",
|
|
5511
|
+
safe: {
|
|
5512
|
+
x: 0.05,
|
|
5513
|
+
y: 0.08,
|
|
5514
|
+
w: 0.9,
|
|
5515
|
+
h: 0.84
|
|
5516
|
+
},
|
|
5307
5517
|
notes: "\u226410MB is the free-plan attachment ceiling; two-pass target bitrate from duration."
|
|
5308
5518
|
},
|
|
5309
5519
|
{
|
|
@@ -5322,6 +5532,14 @@ var DESTINATIONS = [
|
|
|
5322
5532
|
format: "png",
|
|
5323
5533
|
accepts: "png|jpg",
|
|
5324
5534
|
fit: "cover",
|
|
5535
|
+
text: "expected",
|
|
5536
|
+
safe: {
|
|
5537
|
+
x: 0.05,
|
|
5538
|
+
y: 0.08,
|
|
5539
|
+
w: 0.9,
|
|
5540
|
+
h: 0.84
|
|
5541
|
+
},
|
|
5542
|
+
template: "split-cover",
|
|
5325
5543
|
notes: ""
|
|
5326
5544
|
},
|
|
5327
5545
|
{
|
|
@@ -5343,6 +5561,13 @@ var DESTINATIONS = [
|
|
|
5343
5561
|
format: "png",
|
|
5344
5562
|
accepts: "png|jpg",
|
|
5345
5563
|
fit: "cover",
|
|
5564
|
+
text: "none",
|
|
5565
|
+
safe: {
|
|
5566
|
+
x: 0,
|
|
5567
|
+
y: 0,
|
|
5568
|
+
w: 1,
|
|
5569
|
+
h: 1
|
|
5570
|
+
},
|
|
5346
5571
|
notes: "Real UX only \u2014 misleading listing images are a removal-grade violation. Full bleed, square corners."
|
|
5347
5572
|
},
|
|
5348
5573
|
{
|
|
@@ -5360,6 +5585,14 @@ var DESTINATIONS = [
|
|
|
5360
5585
|
format: "png",
|
|
5361
5586
|
accepts: "png|jpg",
|
|
5362
5587
|
fit: "cover",
|
|
5588
|
+
text: "none",
|
|
5589
|
+
safe: {
|
|
5590
|
+
x: 0,
|
|
5591
|
+
y: 0,
|
|
5592
|
+
w: 1,
|
|
5593
|
+
h: 1
|
|
5594
|
+
},
|
|
5595
|
+
template: "card-on-gradient",
|
|
5363
5596
|
notes: "Listings without one rank lower. No text; fill the region; subject centered."
|
|
5364
5597
|
},
|
|
5365
5598
|
{
|
|
@@ -5377,6 +5610,14 @@ var DESTINATIONS = [
|
|
|
5377
5610
|
format: "png",
|
|
5378
5611
|
accepts: "png|jpg",
|
|
5379
5612
|
fit: "cover",
|
|
5613
|
+
text: "allowed",
|
|
5614
|
+
safe: {
|
|
5615
|
+
x: 0.05,
|
|
5616
|
+
y: 0.08,
|
|
5617
|
+
w: 0.9,
|
|
5618
|
+
h: 0.84
|
|
5619
|
+
},
|
|
5620
|
+
template: "split-cover",
|
|
5380
5621
|
notes: "Carousel eligibility."
|
|
5381
5622
|
},
|
|
5382
5623
|
{
|
|
@@ -5393,6 +5634,13 @@ var DESTINATIONS = [
|
|
|
5393
5634
|
format: "png",
|
|
5394
5635
|
accepts: "png",
|
|
5395
5636
|
fit: "cover",
|
|
5637
|
+
text: "none",
|
|
5638
|
+
safe: {
|
|
5639
|
+
x: 0,
|
|
5640
|
+
y: 0,
|
|
5641
|
+
w: 1,
|
|
5642
|
+
h: 1
|
|
5643
|
+
},
|
|
5396
5644
|
notes: "96\xD796 art + 16px transparent padding."
|
|
5397
5645
|
},
|
|
5398
5646
|
{
|
|
@@ -5411,6 +5659,14 @@ var DESTINATIONS = [
|
|
|
5411
5659
|
format: "png",
|
|
5412
5660
|
accepts: "gif|png",
|
|
5413
5661
|
fit: "cover",
|
|
5662
|
+
text: "none",
|
|
5663
|
+
safe: {
|
|
5664
|
+
x: 0.06,
|
|
5665
|
+
y: 0.06,
|
|
5666
|
+
w: 0.88,
|
|
5667
|
+
h: 0.88
|
|
5668
|
+
},
|
|
5669
|
+
template: "card-on-gradient",
|
|
5414
5670
|
notes: "GIF animates on hover only \u2014 the first frame must stand alone."
|
|
5415
5671
|
},
|
|
5416
5672
|
{
|
|
@@ -5432,6 +5688,13 @@ var DESTINATIONS = [
|
|
|
5432
5688
|
format: "png",
|
|
5433
5689
|
accepts: "png|jpg|gif",
|
|
5434
5690
|
fit: "cover",
|
|
5691
|
+
text: "none",
|
|
5692
|
+
safe: {
|
|
5693
|
+
x: 0,
|
|
5694
|
+
y: 0,
|
|
5695
|
+
w: 1,
|
|
5696
|
+
h: 1
|
|
5697
|
+
},
|
|
5435
5698
|
notes: "First image is the hero."
|
|
5436
5699
|
},
|
|
5437
5700
|
{
|
|
@@ -5449,6 +5712,14 @@ var DESTINATIONS = [
|
|
|
5449
5712
|
format: "png",
|
|
5450
5713
|
accepts: "png|jpg",
|
|
5451
5714
|
fit: "cover",
|
|
5715
|
+
text: "allowed",
|
|
5716
|
+
safe: {
|
|
5717
|
+
x: 0.05,
|
|
5718
|
+
y: 0.08,
|
|
5719
|
+
w: 0.9,
|
|
5720
|
+
h: 0.84
|
|
5721
|
+
},
|
|
5722
|
+
template: "split-cover",
|
|
5452
5723
|
notes: ""
|
|
5453
5724
|
},
|
|
5454
5725
|
{
|
|
@@ -5466,6 +5737,14 @@ var DESTINATIONS = [
|
|
|
5466
5737
|
format: "png",
|
|
5467
5738
|
accepts: "png|jpg",
|
|
5468
5739
|
fit: "cover",
|
|
5740
|
+
text: "expected",
|
|
5741
|
+
safe: {
|
|
5742
|
+
x: 0.05,
|
|
5743
|
+
y: 0.08,
|
|
5744
|
+
w: 0.9,
|
|
5745
|
+
h: 0.84
|
|
5746
|
+
},
|
|
5747
|
+
template: "split-cover",
|
|
5469
5748
|
notes: "1080\xD71350 vertical also performs in the mobile feed."
|
|
5470
5749
|
},
|
|
5471
5750
|
{
|
|
@@ -5484,6 +5763,14 @@ var DESTINATIONS = [
|
|
|
5484
5763
|
format: "png",
|
|
5485
5764
|
accepts: "png|jpg",
|
|
5486
5765
|
fit: "cover",
|
|
5766
|
+
text: "expected",
|
|
5767
|
+
safe: {
|
|
5768
|
+
x: 0.05,
|
|
5769
|
+
y: 0.0238,
|
|
5770
|
+
w: 0.9,
|
|
5771
|
+
h: 0.9524
|
|
5772
|
+
},
|
|
5773
|
+
template: "split-cover",
|
|
5487
5774
|
notes: "Text in the center ~1080\xD7600. Set twitter:card=summary_large_image explicitly \u2014 og:image alone gets the small card."
|
|
5488
5775
|
},
|
|
5489
5776
|
{
|
|
@@ -5502,6 +5789,14 @@ var DESTINATIONS = [
|
|
|
5502
5789
|
format: "png",
|
|
5503
5790
|
accepts: "png|jpg",
|
|
5504
5791
|
fit: "cover",
|
|
5792
|
+
text: "expected",
|
|
5793
|
+
safe: {
|
|
5794
|
+
x: 0.0391,
|
|
5795
|
+
y: 0.0781,
|
|
5796
|
+
w: 0.9219,
|
|
5797
|
+
h: 0.8438
|
|
5798
|
+
},
|
|
5799
|
+
template: "card-on-gradient",
|
|
5505
5800
|
notes: "Key text \u226550px from every edge."
|
|
5506
5801
|
}
|
|
5507
5802
|
];
|
|
@@ -5556,6 +5851,131 @@ function studioAudioPlan(clips, duckEnv, duration, step = AUDIO_PLAN_STEP) {
|
|
|
5556
5851
|
return { duration, step, tracks };
|
|
5557
5852
|
}
|
|
5558
5853
|
|
|
5854
|
+
// src/look.ts
|
|
5855
|
+
var HOUSE_GRADIENT = "linear-gradient(135deg, #ff5148, #ffb03a)";
|
|
5856
|
+
var PLATE_GROUND = "#f0f2f4";
|
|
5857
|
+
var DARK_GROUND = "radial-gradient(ellipse at 82% 0%, #2a1d16, #07080b)";
|
|
5858
|
+
var LOOKS = {
|
|
5859
|
+
plate: {
|
|
5860
|
+
kind: "plate",
|
|
5861
|
+
ground: PLATE_GROUND,
|
|
5862
|
+
cardWidth: 0.84,
|
|
5863
|
+
headroom: 0.16,
|
|
5864
|
+
radius: 12,
|
|
5865
|
+
shadow: 0.22,
|
|
5866
|
+
shadowContact: 0.16,
|
|
5867
|
+
border: 0.08,
|
|
5868
|
+
borderColor: "#000000"
|
|
5869
|
+
},
|
|
5870
|
+
gradient: {
|
|
5871
|
+
kind: "gradient",
|
|
5872
|
+
ground: HOUSE_GRADIENT,
|
|
5873
|
+
cardWidth: 0.84,
|
|
5874
|
+
headroom: 0.16,
|
|
5875
|
+
radius: 12,
|
|
5876
|
+
shadow: 0.35,
|
|
5877
|
+
shadowContact: 0.2,
|
|
5878
|
+
border: 0
|
|
5879
|
+
},
|
|
5880
|
+
dark: {
|
|
5881
|
+
kind: "dark",
|
|
5882
|
+
ground: DARK_GROUND,
|
|
5883
|
+
cardWidth: 0.86,
|
|
5884
|
+
headroom: 0.14,
|
|
5885
|
+
radius: 12,
|
|
5886
|
+
shadow: 0.5,
|
|
5887
|
+
shadowContact: 0.3,
|
|
5888
|
+
shadowColor: "#000000",
|
|
5889
|
+
border: 0.12,
|
|
5890
|
+
borderColor: "#ffffff"
|
|
5891
|
+
}
|
|
5892
|
+
};
|
|
5893
|
+
var LOOK_KINDS = ["plate", "gradient", "dark"];
|
|
5894
|
+
function isLookKind(v) {
|
|
5895
|
+
return typeof v === "string" && LOOK_KINDS.includes(v);
|
|
5896
|
+
}
|
|
5897
|
+
function houseLook(kind) {
|
|
5898
|
+
return { ...LOOKS[kind] };
|
|
5899
|
+
}
|
|
5900
|
+
var HEX = /^#([0-9a-f]{6})$/i;
|
|
5901
|
+
function luma(hex) {
|
|
5902
|
+
const m = HEX.exec(hex.trim());
|
|
5903
|
+
if (!m) return null;
|
|
5904
|
+
const n = parseInt(m[1], 16);
|
|
5905
|
+
const r = n >> 16 & 255;
|
|
5906
|
+
const g = n >> 8 & 255;
|
|
5907
|
+
const b = n & 255;
|
|
5908
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
|
5909
|
+
}
|
|
5910
|
+
function lookKindForGround(bgA) {
|
|
5911
|
+
const l = bgA ? luma(bgA) : null;
|
|
5912
|
+
if (l === null) return "gradient";
|
|
5913
|
+
if (l >= 0.85) return "plate";
|
|
5914
|
+
if (l <= 0.2) return "dark";
|
|
5915
|
+
return "gradient";
|
|
5916
|
+
}
|
|
5917
|
+
function lookFromBrand(brand) {
|
|
5918
|
+
const b = brand ?? {};
|
|
5919
|
+
const kind = isLookKind(b.look) ? b.look : lookKindForGround(b.bgA);
|
|
5920
|
+
const look = houseLook(kind);
|
|
5921
|
+
if (kind === "plate" && b.bgB && HEX.test(b.bgB)) look.ground = b.bgB;
|
|
5922
|
+
if (kind === "gradient" && b.accent && b.bgC && HEX.test(b.accent)) {
|
|
5923
|
+
look.ground = `linear-gradient(135deg, ${b.accent}, ${b.bgC})`;
|
|
5924
|
+
}
|
|
5925
|
+
if (kind === "dark" && b.bgA && HEX.test(b.bgA)) {
|
|
5926
|
+
look.ground = `radial-gradient(ellipse at 82% 0%, ${mix(b.bgA, b.accent ?? "#ffffff", 0.18)}, ${b.bgA})`;
|
|
5927
|
+
}
|
|
5928
|
+
if (b.ground && b.ground.trim()) look.ground = b.ground.trim();
|
|
5929
|
+
return look;
|
|
5930
|
+
}
|
|
5931
|
+
function mix(a, b, t) {
|
|
5932
|
+
const pa = HEX.exec(a);
|
|
5933
|
+
const pb = HEX.exec(b);
|
|
5934
|
+
if (!pa || !pb) return a;
|
|
5935
|
+
const na = parseInt(pa[1], 16);
|
|
5936
|
+
const nb = parseInt(pb[1], 16);
|
|
5937
|
+
const ch = (sh) => {
|
|
5938
|
+
const x = na >> sh & 255;
|
|
5939
|
+
const y = nb >> sh & 255;
|
|
5940
|
+
return Math.round(x + (y - x) * t);
|
|
5941
|
+
};
|
|
5942
|
+
return `#${(ch(16) << 16 | ch(8) << 8 | ch(0)).toString(16).padStart(6, "0")}`;
|
|
5943
|
+
}
|
|
5944
|
+
function cardInset(look, frame, video, placement) {
|
|
5945
|
+
const R = frame.w / Math.max(1, frame.h);
|
|
5946
|
+
const V = video.w / Math.max(1, video.h);
|
|
5947
|
+
const cw = look.cardWidth;
|
|
5948
|
+
const ch = cw * R / V;
|
|
5949
|
+
const side = (1 - cw) / 2;
|
|
5950
|
+
if (placement === "card" && ch <= 1 - look.headroom) {
|
|
5951
|
+
const v = (1 - ch) / 2;
|
|
5952
|
+
return { left: side, right: side, top: v, bottom: v };
|
|
5953
|
+
}
|
|
5954
|
+
const top = look.headroom;
|
|
5955
|
+
const bottom = Math.min(-0.02, 1 - top - ch);
|
|
5956
|
+
return { left: side, right: side, top, bottom };
|
|
5957
|
+
}
|
|
5958
|
+
function applyLook(frame, look, size, video, placement) {
|
|
5959
|
+
const out = {
|
|
5960
|
+
...frame,
|
|
5961
|
+
background: look.ground,
|
|
5962
|
+
fit: "contain",
|
|
5963
|
+
inset: cardInset(look, size, video, placement),
|
|
5964
|
+
radius: look.radius,
|
|
5965
|
+
shadow: look.shadow,
|
|
5966
|
+
shadowContact: look.shadowContact,
|
|
5967
|
+
border: look.border
|
|
5968
|
+
};
|
|
5969
|
+
delete out.focus;
|
|
5970
|
+
if (look.shadowColor) out.shadowColor = look.shadowColor;
|
|
5971
|
+
else delete out.shadowColor;
|
|
5972
|
+
if (look.border > 0) {
|
|
5973
|
+
out.borderWidth = 1;
|
|
5974
|
+
out.borderColor = look.borderColor ?? "#000000";
|
|
5975
|
+
}
|
|
5976
|
+
return out;
|
|
5977
|
+
}
|
|
5978
|
+
|
|
5559
5979
|
// src/timeline/lanes.ts
|
|
5560
5980
|
import {
|
|
5561
5981
|
mapTime as mapTime2,
|
|
@@ -6831,6 +7251,7 @@ export {
|
|
|
6831
7251
|
CURSOR_IDLE_FADE_IN,
|
|
6832
7252
|
CURSOR_IDLE_FADE_OUT,
|
|
6833
7253
|
CURSOR_IDLE_HOLD,
|
|
7254
|
+
DARK_GROUND,
|
|
6834
7255
|
DEFAULT_BROWSER_BAR,
|
|
6835
7256
|
DEFAULT_CAM_POSE,
|
|
6836
7257
|
DEFAULT_CAM_STYLE,
|
|
@@ -6848,6 +7269,8 @@ export {
|
|
|
6848
7269
|
DIGEST_VERSION,
|
|
6849
7270
|
DOC_SCHEMA_VERSION,
|
|
6850
7271
|
DRAG_FIT_LEVEL,
|
|
7272
|
+
END_CARD_SECONDS,
|
|
7273
|
+
ENTRANCE_SECONDS,
|
|
6851
7274
|
EXPORT_RESOLUTION_OPTIONS,
|
|
6852
7275
|
EXPORT_SHORT_EDGE,
|
|
6853
7276
|
FOLLOW_RECENTER,
|
|
@@ -6855,6 +7278,8 @@ export {
|
|
|
6855
7278
|
FRAME_BORDER_COLOR_DEFAULT,
|
|
6856
7279
|
FRAME_BORDER_DEFAULT,
|
|
6857
7280
|
FRAME_BORDER_WIDTH_DEFAULT,
|
|
7281
|
+
HOUSE_GRADIENT,
|
|
7282
|
+
LOOK_KINDS,
|
|
6858
7283
|
MINIMAL_BAR_THEMES,
|
|
6859
7284
|
MOTION_DELTA,
|
|
6860
7285
|
MOTION_EASE,
|
|
@@ -6869,6 +7294,7 @@ export {
|
|
|
6869
7294
|
OVERLAY_SIZE_MIN,
|
|
6870
7295
|
OVERLAY_TRANSITION_DUR,
|
|
6871
7296
|
OVERLAY_Z,
|
|
7297
|
+
PLATE_GROUND,
|
|
6872
7298
|
PLAYBACK_ACTIVITY,
|
|
6873
7299
|
PROGRAM_RETIME,
|
|
6874
7300
|
REJECT_OVERLAP,
|
|
@@ -6912,6 +7338,7 @@ export {
|
|
|
6912
7338
|
ZOOM_STYLE_OPTIONS,
|
|
6913
7339
|
anchorKindOf,
|
|
6914
7340
|
anchorSourceDuration,
|
|
7341
|
+
applyLook,
|
|
6915
7342
|
aspectRatioValue,
|
|
6916
7343
|
audioLane,
|
|
6917
7344
|
backdropMedia,
|
|
@@ -6923,7 +7350,9 @@ export {
|
|
|
6923
7350
|
camRectFromPose,
|
|
6924
7351
|
camRestPose,
|
|
6925
7352
|
camTrackFromDoc,
|
|
7353
|
+
cardInset,
|
|
6926
7354
|
cardPointToScreen,
|
|
7355
|
+
cardPoseTrack,
|
|
6927
7356
|
clampCamFrac,
|
|
6928
7357
|
clampCamSize,
|
|
6929
7358
|
clampFocus,
|
|
@@ -6947,8 +7376,10 @@ export {
|
|
|
6947
7376
|
docToFullSpace,
|
|
6948
7377
|
duckCurve,
|
|
6949
7378
|
effectiveSegments,
|
|
7379
|
+
entranceSeconds,
|
|
6950
7380
|
envelopeAt,
|
|
6951
7381
|
envelopeValueAt,
|
|
7382
|
+
expandEndCard,
|
|
6952
7383
|
expectedFrameSize,
|
|
6953
7384
|
exportSizeFor,
|
|
6954
7385
|
extractClicks,
|
|
@@ -6956,13 +7387,17 @@ export {
|
|
|
6956
7387
|
followFocusEvents,
|
|
6957
7388
|
frameGeometry,
|
|
6958
7389
|
hexToRgbTriplet,
|
|
7390
|
+
houseLook,
|
|
6959
7391
|
idleGaps,
|
|
7392
|
+
isLookKind,
|
|
6960
7393
|
isMusicBed,
|
|
6961
7394
|
isPlayback,
|
|
6962
7395
|
isProgramDoc,
|
|
6963
7396
|
isRecordingDoc,
|
|
6964
7397
|
isRejected,
|
|
6965
7398
|
levelForFocusFraction,
|
|
7399
|
+
lookFromBrand,
|
|
7400
|
+
lookKindForGround,
|
|
6966
7401
|
lowerProgramDoc,
|
|
6967
7402
|
lowerStudioDoc,
|
|
6968
7403
|
lowerToComposition,
|
|
@@ -7024,6 +7459,7 @@ export {
|
|
|
7024
7459
|
videoLane,
|
|
7025
7460
|
voiceKey,
|
|
7026
7461
|
withBackdrop,
|
|
7462
|
+
withHolds,
|
|
7027
7463
|
withoutRejected,
|
|
7028
7464
|
wrapProgramLength,
|
|
7029
7465
|
zoomCoversRect,
|