fablecut 1.13.0 → 1.15.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/CLAUDE.md +802 -16
- package/README.md +71 -7
- package/analyze.js +161 -9
- package/app.js +3905 -258
- package/comp.js +195 -0
- package/delivery.js +779 -0
- package/edit-ops.js +50 -18
- package/export-jobs.js +9 -5
- package/frame-cache.js +49 -0
- package/frame-stats.js +267 -0
- package/index.html +282 -72
- package/library/README.md +2 -0
- package/library/elements/logo-placeholder.svg +12 -0
- package/mcp-server.js +324 -656
- package/media-lib.js +287 -0
- package/media-probe.js +88 -0
- package/motion.js +803 -0
- package/package.json +1 -1
- package/paths.js +33 -3
- package/project-ops.js +1290 -0
- package/proxy.js +180 -0
- package/server.js +517 -15
- package/style.css +534 -20
- package/templates.js +576 -0
package/package.json
CHANGED
package/paths.js
CHANGED
|
@@ -32,8 +32,15 @@ const MEDIA_DIR = path.join(DATA_DIR, "media");
|
|
|
32
32
|
const EXPORTS_DIR = path.join(DATA_DIR, "exports");
|
|
33
33
|
const ANALYSIS_DIR = path.join(DATA_DIR, "analysis");
|
|
34
34
|
const LIBRARY_DIR = path.join(DATA_DIR, "library");
|
|
35
|
+
/* Grabs of single frames / contact sheets (GET /api/frame). Disposable render
|
|
36
|
+
cache, so it lives inside analysis/ rather than becoming a fifth top-level
|
|
37
|
+
folder users have to think about. */
|
|
38
|
+
const FRAMES_DIR = path.join(ANALYSIS_DIR, "frames");
|
|
39
|
+
/* Proxies (light copies of heavy footage the editor plays while editing).
|
|
40
|
+
A regenerable cache too, so also inside analysis/. */
|
|
41
|
+
const PROXIES_DIR = path.join(ANALYSIS_DIR, "proxies");
|
|
35
42
|
const PROJECT_FILE = path.join(DATA_DIR, "project.json");
|
|
36
|
-
const LIBRARY_SUBDIRS = ["sfx", "elements", "svg", "fonts"];
|
|
43
|
+
const LIBRARY_SUBDIRS = ["sfx", "elements", "svg", "fonts", "presets", "templates"];
|
|
37
44
|
|
|
38
45
|
/* The asset library ships with the repo but users also drop their own files in
|
|
39
46
|
(library/sfx is gitignored precisely for that). When the data dir is split
|
|
@@ -92,15 +99,38 @@ function superseded(rel, file) {
|
|
|
92
99
|
/* Create the writable tree. Safe to call from both servers; whoever runs first
|
|
93
100
|
wins and the other no-ops. */
|
|
94
101
|
function ensureDirs() {
|
|
95
|
-
for (const d of [DATA_DIR, MEDIA_DIR, EXPORTS_DIR, ANALYSIS_DIR])
|
|
102
|
+
for (const d of [DATA_DIR, MEDIA_DIR, EXPORTS_DIR, ANALYSIS_DIR, FRAMES_DIR, PROXIES_DIR])
|
|
96
103
|
fs.mkdirSync(d, { recursive: true });
|
|
97
104
|
for (const d of LIBRARY_SUBDIRS)
|
|
98
105
|
fs.mkdirSync(path.join(LIBRARY_DIR, d), { recursive: true });
|
|
99
106
|
seedLibrary();
|
|
100
107
|
}
|
|
101
108
|
|
|
109
|
+
/* Saved animation presets and templates: one JSON file each in library/presets/
|
|
110
|
+
and library/templates/ (templates.js validates them). Unreadable files are skipped. */
|
|
111
|
+
function readSaved(kind) {
|
|
112
|
+
const dir = path.join(LIBRARY_DIR, kind);
|
|
113
|
+
let names = [];
|
|
114
|
+
try { names = fs.readdirSync(dir).filter((f) => f.toLowerCase().endsWith(".json")).sort(); } catch { return []; }
|
|
115
|
+
const out = [];
|
|
116
|
+
for (const f of names) {
|
|
117
|
+
try { out.push({ file: f, data: JSON.parse(fs.readFileSync(path.join(dir, f), "utf8").replace(new RegExp("^\\uFEFF"), "")) }); } catch { }
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
}
|
|
121
|
+
function writeSaved(kind, id, data) {
|
|
122
|
+
const dir = path.join(LIBRARY_DIR, kind);
|
|
123
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
124
|
+
const file = path.join(dir, String(id).replace(/[^a-z0-9-]+/gi, "-").slice(0, 60) + ".json");
|
|
125
|
+
// tmp + rename, like the project file: a crash mid-write never leaves half a preset
|
|
126
|
+
const tmp = `${file}.${crypto.randomUUID()}.tmp`; // unique: the editor and the MCP server may save at once
|
|
127
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n");
|
|
128
|
+
fs.renameSync(tmp, file);
|
|
129
|
+
return file;
|
|
130
|
+
}
|
|
131
|
+
|
|
102
132
|
module.exports = {
|
|
103
133
|
APP_DIR, DATA_DIR, SPLIT,
|
|
104
134
|
MEDIA_DIR, EXPORTS_DIR, ANALYSIS_DIR, LIBRARY_DIR, PROJECT_FILE,
|
|
105
|
-
LIBRARY_SUBDIRS, ensureDirs,
|
|
135
|
+
LIBRARY_SUBDIRS, FRAMES_DIR, PROXIES_DIR, ensureDirs, readSaved, writeSaved,
|
|
106
136
|
};
|