flomotion 0.0.0-stage → 0.2.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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +56 -2
- package/dist/bin.mjs +5951 -0
- package/dist/chunks/chunk-AVP5XX4G.mjs +25050 -0
- package/dist/chunks/chunk-IUSYVGP6.mjs +122 -0
- package/dist/chunks/chunk-JCLRAREG.mjs +218 -0
- package/dist/chunks/chunk-QG2MOGKO.mjs +4193 -0
- package/dist/chunks/lock-MLQUU7X3.mjs +29 -0
- package/dist/components.mjs +580 -0
- package/dist/core.mjs +340 -0
- package/dist/hooks.mjs +66 -0
- package/dist/jsx-dev-runtime.mjs +13 -0
- package/dist/jsx-runtime.mjs +11 -0
- package/docs/components/Adjustment.md +74 -0
- package/docs/components/Animate.md +45 -0
- package/docs/components/Audio.md +56 -0
- package/docs/components/B.md +22 -0
- package/docs/components/Blur.md +30 -0
- package/docs/components/Captions.md +207 -0
- package/docs/components/Card.md +105 -0
- package/docs/components/Center.md +80 -0
- package/docs/components/Chart.md +115 -0
- package/docs/components/Chip.md +104 -0
- package/docs/components/Circle.md +88 -0
- package/docs/components/Clip.md +104 -0
- package/docs/components/CodeBlock.md +103 -0
- package/docs/components/ColorGrade.md +75 -0
- package/docs/components/Composition.md +40 -0
- package/docs/components/Counter.md +216 -0
- package/docs/components/Cursor.md +94 -0
- package/docs/components/Curves.md +29 -0
- package/docs/components/DropShadow.md +42 -0
- package/docs/components/Enter.md +54 -0
- package/docs/components/Exit.md +54 -0
- package/docs/components/Font.md +41 -0
- package/docs/components/Fonts.md +22 -0
- package/docs/components/GlassCard.md +105 -0
- package/docs/components/Glitch.md +39 -0
- package/docs/components/Glow.md +36 -0
- package/docs/components/Grain.md +45 -0
- package/docs/components/Grid.md +101 -0
- package/docs/components/Group.md +79 -0
- package/docs/components/Highlight.md +31 -0
- package/docs/components/Hitstop.md +33 -0
- package/docs/components/I.md +22 -0
- package/docs/components/Image.md +89 -0
- package/docs/components/Impact.md +45 -0
- package/docs/components/Keyframes.md +37 -0
- package/docs/components/Line.md +95 -0
- package/docs/components/Look.md +34 -0
- package/docs/components/Marker.md +26 -0
- package/docs/components/Mask.md +48 -0
- package/docs/components/Matte.md +35 -0
- package/docs/components/Path.md +100 -0
- package/docs/components/Polygon.md +93 -0
- package/docs/components/Precomp.md +79 -0
- package/docs/components/ProgressRing.md +110 -0
- package/docs/components/Pulse.md +39 -0
- package/docs/components/PunchZoom.md +36 -0
- package/docs/components/README.md +115 -0
- package/docs/components/RGBSplit.md +39 -0
- package/docs/components/Rect.md +91 -0
- package/docs/components/RoundRect.md +91 -0
- package/docs/components/SafeArea.md +80 -0
- package/docs/components/Scene.md +77 -0
- package/docs/components/Sequence.md +77 -0
- package/docs/components/Shake.md +48 -0
- package/docs/components/Slam.md +51 -0
- package/docs/components/Sound.md +42 -0
- package/docs/components/Span.md +36 -0
- package/docs/components/SplitText.md +218 -0
- package/docs/components/SquashStretch.md +39 -0
- package/docs/components/Stack.md +97 -0
- package/docs/components/Stagger.md +80 -0
- package/docs/components/Strike.md +31 -0
- package/docs/components/Stroke.md +33 -0
- package/docs/components/Svg.md +89 -0
- package/docs/components/Text.md +195 -0
- package/docs/components/TextAnimator.md +57 -0
- package/docs/components/Theme.md +34 -0
- package/docs/components/Thud.md +45 -0
- package/docs/components/Title.md +195 -0
- package/docs/components/Track.md +39 -0
- package/docs/components/UIMock.md +107 -0
- package/docs/components/Underline.md +31 -0
- package/docs/components/Video.md +104 -0
- package/docs/components/Vignette.md +45 -0
- package/docs/components/Voiceover.md +32 -0
- package/docs/components/WhipPan.md +48 -0
- package/docs/components/Wobble.md +39 -0
- package/docs/gate2-manual-checklist.md +89 -0
- package/docs/hyperframes-notes.md +149 -0
- package/docs/later.md +20 -0
- package/docs/spec.md +147 -0
- package/package.json +46 -4
- package/skills/motion-studio/SKILL.md +87 -0
- package/skills/motion-studio/examples/saas-promo/README.md +7 -0
- package/skills/motion-studio/examples/saas-promo/make-assets.sh +42 -0
- package/skills/motion-studio/examples/saas-promo/project.tsx +545 -0
- package/skills/motion-studio/looks/kinetic.json +89 -0
- package/skills/motion-studio/looks/kinetic.scene.tsx +196 -0
- package/skills/motion-studio/looks/minimal.json +91 -0
- package/skills/motion-studio/looks/minimal.scene.tsx +163 -0
- package/skills/motion-studio/looks/sketch.json +83 -0
- package/skills/motion-studio/looks/sketch.scene.tsx +180 -0
- package/skills/motion-studio/references/components.md +5574 -0
- package/skills/motion-studio/references/motion.md +73 -0
- package/skills/motion-studio/references/review.md +32 -0
- package/skills/motion-studio/references/saas-promo.md +29 -0
- package/skills/motion-studio/references/sound.md +47 -0
- package/skills/motion-studio/references/typography.md +50 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// packages/core/src/errors.ts
|
|
9
|
+
var CodeCutError = class extends Error {
|
|
10
|
+
code;
|
|
11
|
+
fix;
|
|
12
|
+
details;
|
|
13
|
+
constructor(code, message, opts = {}) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "CodeCutError";
|
|
16
|
+
this.code = code;
|
|
17
|
+
this.fix = opts.fix;
|
|
18
|
+
this.details = opts.details;
|
|
19
|
+
}
|
|
20
|
+
toJSON() {
|
|
21
|
+
return { code: this.code, message: this.message, fix: this.fix, details: this.details };
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var isCodeCutError = (e) => e instanceof CodeCutError;
|
|
25
|
+
|
|
26
|
+
// packages/core/src/ast/node.ts
|
|
27
|
+
var isNode = (x) => typeof x === "object" && x !== null && x.$cc === 1;
|
|
28
|
+
var FRAGMENT = "Fragment";
|
|
29
|
+
function flattenChildren(input, out = []) {
|
|
30
|
+
if (input === void 0 || input === null || input === false || input === true) return out;
|
|
31
|
+
if (Array.isArray(input)) {
|
|
32
|
+
for (const c of input) flattenChildren(c, out);
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
if (isNode(input)) {
|
|
36
|
+
if (input.name === FRAGMENT) {
|
|
37
|
+
for (const c of input.children) out.push(c);
|
|
38
|
+
} else {
|
|
39
|
+
out.push(input);
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
if (typeof input === "string" || typeof input === "number") {
|
|
44
|
+
out.push(input);
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
throw new TypeError(`Unsupported child of type ${typeof input}`);
|
|
48
|
+
}
|
|
49
|
+
function walk(node, fn, parent = null, index = 0) {
|
|
50
|
+
fn(node, parent, index);
|
|
51
|
+
node.children.forEach((c, i) => {
|
|
52
|
+
if (isNode(c)) walk(c, fn, node, i);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function findById(root, id) {
|
|
56
|
+
let hit = null;
|
|
57
|
+
walk(root, (n, p, i) => {
|
|
58
|
+
if (!hit && n.props.id === id) hit = { node: n, parent: p, index: i };
|
|
59
|
+
});
|
|
60
|
+
return hit;
|
|
61
|
+
}
|
|
62
|
+
function cloneNode(n) {
|
|
63
|
+
return {
|
|
64
|
+
$cc: 1,
|
|
65
|
+
name: n.name,
|
|
66
|
+
props: cloneValue(n.props),
|
|
67
|
+
children: n.children.map((c) => isNode(c) ? cloneNode(c) : c)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function cloneValue(v) {
|
|
71
|
+
if (Array.isArray(v)) return v.map(cloneValue);
|
|
72
|
+
if (v && typeof v === "object") {
|
|
73
|
+
return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, cloneValue(x)]));
|
|
74
|
+
}
|
|
75
|
+
return v;
|
|
76
|
+
}
|
|
77
|
+
function serializeNode(n) {
|
|
78
|
+
return {
|
|
79
|
+
name: n.name,
|
|
80
|
+
props: JSON.parse(
|
|
81
|
+
JSON.stringify(
|
|
82
|
+
n.props,
|
|
83
|
+
(_k, v) => typeof v === "function" ? { $expr: Function.prototype.toString.call(v) } : v
|
|
84
|
+
)
|
|
85
|
+
),
|
|
86
|
+
children: n.children.map((c) => isNode(c) ? serializeNode(c) : c)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// packages/core/src/jsx/runtime.ts
|
|
91
|
+
function build(type, props) {
|
|
92
|
+
if (typeof type === "function") return type(props);
|
|
93
|
+
if (typeof type === "symbol") {
|
|
94
|
+
return { $cc: 1, name: FRAGMENT, props: {}, children: flattenChildren(props.children) };
|
|
95
|
+
}
|
|
96
|
+
throw new CodeCutError("unknown_component", `Unknown element <${String(type)}>`, {
|
|
97
|
+
fix: "Only components created with defineComponent/defineEffect can be used as JSX tags."
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
function jsx(type, props, _key) {
|
|
101
|
+
return build(type, props ?? {});
|
|
102
|
+
}
|
|
103
|
+
var jsxs = jsx;
|
|
104
|
+
var jsxDEV = jsx;
|
|
105
|
+
var Fragment = /* @__PURE__ */ Symbol.for("codecut.fragment");
|
|
106
|
+
|
|
107
|
+
export {
|
|
108
|
+
__export,
|
|
109
|
+
CodeCutError,
|
|
110
|
+
isCodeCutError,
|
|
111
|
+
isNode,
|
|
112
|
+
FRAGMENT,
|
|
113
|
+
flattenChildren,
|
|
114
|
+
walk,
|
|
115
|
+
findById,
|
|
116
|
+
cloneNode,
|
|
117
|
+
serializeNode,
|
|
118
|
+
jsx,
|
|
119
|
+
jsxs,
|
|
120
|
+
jsxDEV,
|
|
121
|
+
Fragment
|
|
122
|
+
};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
CODECUT_DIR,
|
|
4
|
+
classifyFontLicense,
|
|
5
|
+
emptyLedger,
|
|
6
|
+
upsertEntry
|
|
7
|
+
} from "./chunk-AVP5XX4G.mjs";
|
|
8
|
+
import {
|
|
9
|
+
CodeCutError
|
|
10
|
+
} from "./chunk-IUSYVGP6.mjs";
|
|
11
|
+
|
|
12
|
+
// packages/render/src/fonts/lock.ts
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "node:fs";
|
|
14
|
+
import { dirname, join } from "node:path";
|
|
15
|
+
|
|
16
|
+
// packages/render/src/fonts/inspect.ts
|
|
17
|
+
import { createHash } from "node:crypto";
|
|
18
|
+
import { readFileSync } from "node:fs";
|
|
19
|
+
import { extname } from "node:path";
|
|
20
|
+
import * as fontkit from "fontkit";
|
|
21
|
+
var sha256 = (buf) => createHash("sha256").update(buf).digest("hex");
|
|
22
|
+
var formatOf = (path) => {
|
|
23
|
+
switch (extname(path).toLowerCase()) {
|
|
24
|
+
case ".woff2":
|
|
25
|
+
return "woff2";
|
|
26
|
+
case ".woff":
|
|
27
|
+
return "woff";
|
|
28
|
+
case ".otf":
|
|
29
|
+
return "opentype";
|
|
30
|
+
default:
|
|
31
|
+
return "truetype";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
var cache = /* @__PURE__ */ new Map();
|
|
35
|
+
function inspectFont(path) {
|
|
36
|
+
const buf = readFileSync(path);
|
|
37
|
+
const key = sha256(buf);
|
|
38
|
+
const hit = cache.get(key);
|
|
39
|
+
if (hit) return hit;
|
|
40
|
+
const raw = fontkit.create(buf);
|
|
41
|
+
const font = raw.fonts ? raw.fonts[0] : raw;
|
|
42
|
+
const lic = [font.license, font.licenseURL, font.copyright].filter(Boolean).join(" \n ");
|
|
43
|
+
const cls = classifyFontLicense(lic);
|
|
44
|
+
const axes = {};
|
|
45
|
+
for (const [tag, a] of Object.entries(
|
|
46
|
+
font.variationAxes ?? {}
|
|
47
|
+
))
|
|
48
|
+
axes[tag] = [a.min, a.max];
|
|
49
|
+
const info = {
|
|
50
|
+
family: font.familyName ?? "",
|
|
51
|
+
fullName: font.fullName ?? "",
|
|
52
|
+
license: {
|
|
53
|
+
license: cls.license,
|
|
54
|
+
url: font.licenseURL || void 0,
|
|
55
|
+
attributionRequired: false,
|
|
56
|
+
commercialOk: cls.commercialOk,
|
|
57
|
+
copyright: font.copyright || void 0
|
|
58
|
+
},
|
|
59
|
+
variable: Object.keys(axes).length > 0,
|
|
60
|
+
axes,
|
|
61
|
+
weight: font["OS/2"]?.usWeightClass,
|
|
62
|
+
italic: !!(font["OS/2"]?.fsSelection?.italic || /italic/i.test(font.subfamilyName ?? "")),
|
|
63
|
+
glyphs: (cp) => !!font.hasGlyphForCodePoint?.(cp)
|
|
64
|
+
};
|
|
65
|
+
cache.set(key, info);
|
|
66
|
+
return info;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// packages/render/src/fonts/lock.ts
|
|
70
|
+
var lockPath = (root) => join(root, CODECUT_DIR, "fonts.lock.json");
|
|
71
|
+
var ledgerPath = (root) => join(root, CODECUT_DIR, "ledger.json");
|
|
72
|
+
var layoutCachePath = (root) => join(root, CODECUT_DIR, "layout-cache.json");
|
|
73
|
+
function readJson(path, fallback) {
|
|
74
|
+
try {
|
|
75
|
+
return JSON.parse(readFileSync2(path, "utf8"));
|
|
76
|
+
} catch {
|
|
77
|
+
return fallback;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function writeJson(path, value) {
|
|
81
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
82
|
+
writeFileSync(path, JSON.stringify(value, null, 2) + "\n");
|
|
83
|
+
}
|
|
84
|
+
var readLock = (root) => readJson(lockPath(root), { version: 1, fonts: {} });
|
|
85
|
+
var readLedger = (root) => readJson(ledgerPath(root), emptyLedger());
|
|
86
|
+
var declHash = (d) => sha256(
|
|
87
|
+
JSON.stringify({
|
|
88
|
+
f: d.family,
|
|
89
|
+
s: d.source,
|
|
90
|
+
w: d.weights,
|
|
91
|
+
st: d.styles,
|
|
92
|
+
v: d.variable,
|
|
93
|
+
a: d.axes,
|
|
94
|
+
sub: d.subsets,
|
|
95
|
+
ur: d.unicodeRange
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
function lockEntry(decl, r) {
|
|
99
|
+
return {
|
|
100
|
+
family: decl.family,
|
|
101
|
+
source: decl.source,
|
|
102
|
+
declHash: declHash(decl),
|
|
103
|
+
route: r.route,
|
|
104
|
+
variable: r.variable,
|
|
105
|
+
axes: r.axes,
|
|
106
|
+
license: r.license.license,
|
|
107
|
+
files: r.files.map((f) => ({
|
|
108
|
+
path: f.rel,
|
|
109
|
+
hash: f.hash,
|
|
110
|
+
weight: f.weight,
|
|
111
|
+
style: f.style,
|
|
112
|
+
unicodeRange: f.unicodeRange,
|
|
113
|
+
format: f.format,
|
|
114
|
+
subset: f.subset
|
|
115
|
+
}))
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
function recordLedger(root, decl, r) {
|
|
119
|
+
let ledger = readLedger(root);
|
|
120
|
+
for (const f of r.files.length ? r.files : [void 0]) {
|
|
121
|
+
ledger = upsertEntry(ledger, {
|
|
122
|
+
source: r.route === "local" ? "local" : r.route === "url" ? "url" : "google-fonts",
|
|
123
|
+
kind: "font",
|
|
124
|
+
id: f ? `${decl.id}:${f.subset ?? f.style}:${f.hash.slice(0, 8)}` : decl.id,
|
|
125
|
+
family: decl.family,
|
|
126
|
+
file: f?.rel ?? "",
|
|
127
|
+
hash: f?.hash ?? "",
|
|
128
|
+
license: r.license.license,
|
|
129
|
+
url: r.url,
|
|
130
|
+
attributionRequired: r.license.attributionRequired,
|
|
131
|
+
commercialOk: r.license.commercialOk,
|
|
132
|
+
title: decl.family
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
writeJson(ledgerPath(root), ledger);
|
|
136
|
+
}
|
|
137
|
+
function resolveFromLock(root, decl, lock = readLock(root)) {
|
|
138
|
+
const system = decl.source === "system";
|
|
139
|
+
const e = lock.fonts[decl.id];
|
|
140
|
+
if (system) {
|
|
141
|
+
return {
|
|
142
|
+
id: decl.id,
|
|
143
|
+
family: decl.family,
|
|
144
|
+
files: [],
|
|
145
|
+
fallback: decl.fallback ?? [],
|
|
146
|
+
source: "system",
|
|
147
|
+
variable: !!decl.variable
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
if (!e) {
|
|
151
|
+
throw new CodeCutError(
|
|
152
|
+
"font_error",
|
|
153
|
+
`Font "${decl.id}" (${decl.family}) is not in .codecut/fonts.lock.json`,
|
|
154
|
+
{ fix: "Run `codecut fonts sync` to download and lock it." }
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
if (e.declHash !== declHash(decl)) {
|
|
158
|
+
throw new CodeCutError("font_error", `Font "${decl.id}" changed since it was locked`, {
|
|
159
|
+
fix: "Run `codecut fonts sync` to refresh the lock for the new declaration."
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const files = [];
|
|
163
|
+
for (const f of e.files) {
|
|
164
|
+
const abs = join(root, f.path);
|
|
165
|
+
if (!existsSync(abs)) {
|
|
166
|
+
throw new CodeCutError("font_error", `Font "${decl.id}": file ${f.path} is missing`, {
|
|
167
|
+
fix: "Restore the file or run `codecut fonts sync`.",
|
|
168
|
+
details: { id: decl.id, path: f.path }
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
const hash = sha256(readFileSync2(abs));
|
|
172
|
+
if (hash !== f.hash) {
|
|
173
|
+
throw new CodeCutError(
|
|
174
|
+
"font_error",
|
|
175
|
+
`Font "${decl.id}": ${f.path} changed on disk (hash mismatch)`,
|
|
176
|
+
{
|
|
177
|
+
fix: "If the change is intended, run `codecut fonts sync --update-lock`.",
|
|
178
|
+
details: { id: decl.id, path: f.path, expected: f.hash, actual: hash }
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
files.push({
|
|
183
|
+
path: f.path,
|
|
184
|
+
weight: f.weight,
|
|
185
|
+
style: f.style,
|
|
186
|
+
hash: f.hash,
|
|
187
|
+
unicodeRange: f.unicodeRange,
|
|
188
|
+
format: f.format
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
id: decl.id,
|
|
193
|
+
family: decl.family,
|
|
194
|
+
files,
|
|
195
|
+
fallback: decl.fallback ?? [],
|
|
196
|
+
source: decl.source === "google" ? "google" : /^https?:/.test(decl.source) ? "url" : "local",
|
|
197
|
+
variable: e.variable,
|
|
198
|
+
axes: e.axes,
|
|
199
|
+
license: e.license
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export {
|
|
204
|
+
sha256,
|
|
205
|
+
formatOf,
|
|
206
|
+
inspectFont,
|
|
207
|
+
lockPath,
|
|
208
|
+
ledgerPath,
|
|
209
|
+
layoutCachePath,
|
|
210
|
+
readJson,
|
|
211
|
+
writeJson,
|
|
212
|
+
readLock,
|
|
213
|
+
readLedger,
|
|
214
|
+
declHash,
|
|
215
|
+
lockEntry,
|
|
216
|
+
recordLedger,
|
|
217
|
+
resolveFromLock
|
|
218
|
+
};
|