rtistree 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/CHANGELOG.md +15 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/THIRD_PARTY_NOTICES.md +25 -0
- package/dist/art-direction.d.ts +77 -0
- package/dist/art-direction.js +186 -0
- package/dist/art-direction.js.map +1 -0
- package/dist/artifacts.d.ts +24 -0
- package/dist/artifacts.js +49 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/assets.d.ts +16 -0
- package/dist/assets.js +96 -0
- package/dist/assets.js.map +1 -0
- package/dist/benchmark.d.ts +76 -0
- package/dist/benchmark.js +118 -0
- package/dist/benchmark.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +300 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands.d.ts +5315 -0
- package/dist/commands.js +591 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +20 -0
- package/dist/components.js +98 -0
- package/dist/components.js.map +1 -0
- package/dist/construction.d.ts +53 -0
- package/dist/construction.js +80 -0
- package/dist/construction.js.map +1 -0
- package/dist/critique.d.ts +44 -0
- package/dist/critique.js +45 -0
- package/dist/critique.js.map +1 -0
- package/dist/detail.d.ts +5 -0
- package/dist/detail.js +52 -0
- package/dist/detail.js.map +1 -0
- package/dist/document.d.ts +64 -0
- package/dist/document.js +56 -0
- package/dist/document.js.map +1 -0
- package/dist/export.d.ts +405 -0
- package/dist/export.js +344 -0
- package/dist/export.js.map +1 -0
- package/dist/font-inspection.d.ts +8 -0
- package/dist/font-inspection.js +34 -0
- package/dist/font-inspection.js.map +1 -0
- package/dist/graphics.d.ts +9 -0
- package/dist/graphics.js +72 -0
- package/dist/graphics.js.map +1 -0
- package/dist/history-storage.d.ts +10 -0
- package/dist/history-storage.js +59 -0
- package/dist/history-storage.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/layout.d.ts +18 -0
- package/dist/layout.js +155 -0
- package/dist/layout.js.map +1 -0
- package/dist/loader.d.ts +9 -0
- package/dist/loader.js +108 -0
- package/dist/loader.js.map +1 -0
- package/dist/mcp.d.ts +4 -0
- package/dist/mcp.js +223 -0
- package/dist/mcp.js.map +1 -0
- package/dist/merge.d.ts +6 -0
- package/dist/merge.js +49 -0
- package/dist/merge.js.map +1 -0
- package/dist/native.d.ts +3 -0
- package/dist/native.js +6 -0
- package/dist/native.js.map +1 -0
- package/dist/paint.d.ts +9 -0
- package/dist/paint.js +331 -0
- package/dist/paint.js.map +1 -0
- package/dist/path-edit.d.ts +20 -0
- package/dist/path-edit.js +30 -0
- package/dist/path-edit.js.map +1 -0
- package/dist/pdf-output.d.ts +21 -0
- package/dist/pdf-output.js +297 -0
- package/dist/pdf-output.js.map +1 -0
- package/dist/pipeline.d.ts +39 -0
- package/dist/pipeline.js +227 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/print-scene.d.ts +490 -0
- package/dist/print-scene.js +55 -0
- package/dist/print-scene.js.map +1 -0
- package/dist/production-workflow.d.ts +251 -0
- package/dist/production-workflow.js +335 -0
- package/dist/production-workflow.js.map +1 -0
- package/dist/program-worker.d.ts +1 -0
- package/dist/program-worker.js +31 -0
- package/dist/program-worker.js.map +1 -0
- package/dist/program.d.ts +85 -0
- package/dist/program.js +246 -0
- package/dist/program.js.map +1 -0
- package/dist/project-config.d.ts +91 -0
- package/dist/project-config.js +187 -0
- package/dist/project-config.js.map +1 -0
- package/dist/project.d.ts +897 -0
- package/dist/project.js +347 -0
- package/dist/project.js.map +1 -0
- package/dist/raster-edit.d.ts +61 -0
- package/dist/raster-edit.js +91 -0
- package/dist/raster-edit.js.map +1 -0
- package/dist/raster-studio.d.ts +84 -0
- package/dist/raster-studio.js +236 -0
- package/dist/raster-studio.js.map +1 -0
- package/dist/render.d.ts +79 -0
- package/dist/render.js +437 -0
- package/dist/render.js.map +1 -0
- package/dist/rich-text.d.ts +10 -0
- package/dist/rich-text.js +56 -0
- package/dist/rich-text.js.map +1 -0
- package/dist/schema.d.ts +1912 -0
- package/dist/schema.js +571 -0
- package/dist/schema.js.map +1 -0
- package/dist/spatial.d.ts +10 -0
- package/dist/spatial.js +29 -0
- package/dist/spatial.js.map +1 -0
- package/dist/studio-reference.d.ts +153 -0
- package/dist/studio-reference.js +39 -0
- package/dist/studio-reference.js.map +1 -0
- package/dist/svg.d.ts +5 -0
- package/dist/svg.js +315 -0
- package/dist/svg.js.map +1 -0
- package/dist/techniques.d.ts +74 -0
- package/dist/techniques.js +164 -0
- package/dist/techniques.js.map +1 -0
- package/dist/verify.d.ts +36 -0
- package/dist/verify.js +277 -0
- package/dist/verify.js.map +1 -0
- package/dist/viewport.d.ts +3 -0
- package/dist/viewport.js +71 -0
- package/dist/viewport.js.map +1 -0
- package/dist/workflow.d.ts +53 -0
- package/dist/workflow.js +66 -0
- package/dist/workflow.js.map +1 -0
- package/docs/agent-art-workflow.md +201 -0
- package/docs/agent-setup.md +83 -0
- package/docs/atelier.md +117 -0
- package/docs/cli-reference.md +61 -0
- package/docs/decisions/001-runtime-and-renderer.md +35 -0
- package/docs/decisions/002-composable-scenes-and-history.md +28 -0
- package/docs/decisions/003-editing-refinement-and-agent-validation.md +45 -0
- package/docs/decisions/004-print-production-and-projects.md +19 -0
- package/docs/decisions/005-programmable-digital-art.md +15 -0
- package/docs/decisions/006-staged-2d-art-production.md +13 -0
- package/docs/decisions/007-foundation-first-art-direction.md +13 -0
- package/docs/decisions/008-agent-onboarding-and-trial-lessons.md +48 -0
- package/docs/engine-overview.md +174 -0
- package/docs/evolution.md +179 -0
- package/docs/getting-started.md +107 -0
- package/docs/next-milestone.md +61 -0
- package/docs/previews/a3-production.json +36 -0
- package/docs/previews/benchmark.json +42 -0
- package/docs/previews/landscape.png +0 -0
- package/docs/previews/performance.json +24 -0
- package/docs/previews/poster.png +0 -0
- package/docs/production.md +107 -0
- package/docs/releasing.md +60 -0
- package/docs/scene-format.md +126 -0
- package/docs/studio.md +108 -0
- package/examples/hello/README.md +14 -0
- package/examples/hello/refine.json +10 -0
- package/examples/hello/render.mjs +9 -0
- package/examples/hello/scene.json +19 -0
- package/licenses/DM-Serif-Display-OFL.txt +93 -0
- package/licenses/Inter-OFL.txt +93 -0
- package/package.json +84 -0
- package/schemas/authoring.schema.json +2177 -0
- package/schemas/brief.schema.json +57 -0
- package/schemas/command.schema.json +3154 -0
- package/schemas/construction.schema.json +159 -0
- package/schemas/critique.schema.json +101 -0
- package/schemas/document.schema.json +41 -0
- package/schemas/export.schema.json +89 -0
- package/schemas/fragment.schema.json +1861 -0
- package/schemas/patch.schema.json +3177 -0
- package/schemas/pipeline.schema.json +205 -0
- package/schemas/production.schema.json +452 -0
- package/schemas/program.schema.json +152 -0
- package/schemas/project.schema.json +115 -0
- package/schemas/raster-read.schema.json +42 -0
- package/schemas/raster-write.schema.json +75 -0
- package/schemas/scene.schema.json +2014 -0
package/dist/project.js
ADDED
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import { stringify } from 'yaml';
|
|
2
|
+
import { resolveProject, projectPath } from './project-config.js';
|
|
3
|
+
import { readJournal, compressJournal } from './history-storage.js';
|
|
4
|
+
import { mergeSource } from './merge.js';
|
|
5
|
+
import { validateCritique } from './critique.js';
|
|
6
|
+
import { writeArtifact } from './artifacts.js';
|
|
7
|
+
import { mkdir, open, readFile, unlink } from 'node:fs/promises';
|
|
8
|
+
import { basename, dirname, join } from 'node:path';
|
|
9
|
+
import { canonical, localAssetPath, sceneHash, sha256 } from './assets.js';
|
|
10
|
+
import { writeSceneBundle } from './artifacts.js';
|
|
11
|
+
import { applyCommand, commandScopes, patchSchema } from './commands.js';
|
|
12
|
+
import { flattenResolved, intersects, resolveLayout } from './layout.js';
|
|
13
|
+
import { loadScene } from './loader.js';
|
|
14
|
+
import { defaultRenderer } from './render.js';
|
|
15
|
+
import { boundsSchema, parseScene } from './schema.js';
|
|
16
|
+
import { measureLocality, verifyRendered } from './verify.js';
|
|
17
|
+
function missing(error) {
|
|
18
|
+
return error.code === 'ENOENT';
|
|
19
|
+
}
|
|
20
|
+
export class Project {
|
|
21
|
+
source;
|
|
22
|
+
renderer;
|
|
23
|
+
config;
|
|
24
|
+
constructor(source, renderer = defaultRenderer, config) {
|
|
25
|
+
this.source = source;
|
|
26
|
+
this.renderer = renderer;
|
|
27
|
+
this.config = config;
|
|
28
|
+
}
|
|
29
|
+
static async open(file, renderer = defaultRenderer) {
|
|
30
|
+
const resolved = await resolveProject(file);
|
|
31
|
+
return new Project(await loadScene(resolved.file), renderer, resolved.config);
|
|
32
|
+
}
|
|
33
|
+
get root() {
|
|
34
|
+
return this.source.root;
|
|
35
|
+
}
|
|
36
|
+
get outputDirectory() {
|
|
37
|
+
return this.config
|
|
38
|
+
? projectPath(this.root, this.config.output_dir)
|
|
39
|
+
: join(this.root, 'renders');
|
|
40
|
+
}
|
|
41
|
+
get journal() {
|
|
42
|
+
return join(this.root, 'history', `${basename(this.source.file)}.operations.jsonl`);
|
|
43
|
+
}
|
|
44
|
+
async state(allowSourceChange = false) {
|
|
45
|
+
// Re-read authoring files on every request, including long-lived MCP sessions.
|
|
46
|
+
const current = await loadScene(this.source.file), sourceHash = sceneHash(current.scene);
|
|
47
|
+
const raw = await readJournal(this.journal);
|
|
48
|
+
if (raw && !raw.endsWith('\n'))
|
|
49
|
+
throw new Error('History has an incomplete final record. Restore the journal from backup before editing.');
|
|
50
|
+
const initial = raw
|
|
51
|
+
? (JSON.parse(raw.split('\n')[0]).baseline ?? current.scene)
|
|
52
|
+
: current.scene;
|
|
53
|
+
const state = {
|
|
54
|
+
sourceHash: sceneHash(initial),
|
|
55
|
+
baseline: initial,
|
|
56
|
+
incoming: current.scene,
|
|
57
|
+
scene: initial,
|
|
58
|
+
undo: [],
|
|
59
|
+
redo: [],
|
|
60
|
+
entries: [],
|
|
61
|
+
};
|
|
62
|
+
for (const line of raw.split('\n').filter(Boolean)) {
|
|
63
|
+
const entry = JSON.parse(line);
|
|
64
|
+
const { hash, ...payload } = entry;
|
|
65
|
+
if (sha256(canonical(payload)) !== hash)
|
|
66
|
+
throw new Error('History integrity check failed');
|
|
67
|
+
if (entry.kind === 'rebase') {
|
|
68
|
+
if (!entry.baseline || sceneHash(entry.baseline) !== entry.source_hash)
|
|
69
|
+
throw new Error('Invalid rebase baseline');
|
|
70
|
+
state.baseline = parseScene(entry.baseline);
|
|
71
|
+
state.sourceHash = entry.source_hash;
|
|
72
|
+
}
|
|
73
|
+
else if (entry.source_hash !== state.sourceHash)
|
|
74
|
+
throw new Error('History source chain is inconsistent');
|
|
75
|
+
if (entry.sequence !== state.entries.length + 1 ||
|
|
76
|
+
entry.previous_hash !== (state.entries.at(-1)?.hash ?? null) ||
|
|
77
|
+
entry.before_hash !== sceneHash(state.scene))
|
|
78
|
+
throw new Error('History chain is inconsistent');
|
|
79
|
+
const after = parseScene(entry.after);
|
|
80
|
+
if (sceneHash(after) !== entry.after_hash)
|
|
81
|
+
throw new Error('History state hash mismatch');
|
|
82
|
+
if (entry.kind === 'apply' || entry.kind === 'rebase') {
|
|
83
|
+
state.undo.push(state.scene);
|
|
84
|
+
state.redo = [];
|
|
85
|
+
}
|
|
86
|
+
else if (entry.kind === 'undo') {
|
|
87
|
+
const previous = state.undo.pop();
|
|
88
|
+
if (!previous || sceneHash(previous) !== entry.after_hash)
|
|
89
|
+
throw new Error('Invalid undo record');
|
|
90
|
+
state.redo.push(state.scene);
|
|
91
|
+
}
|
|
92
|
+
else if (entry.kind === 'redo') {
|
|
93
|
+
const next = state.redo.pop();
|
|
94
|
+
if (!next || sceneHash(next) !== entry.after_hash)
|
|
95
|
+
throw new Error('Invalid redo record');
|
|
96
|
+
state.undo.push(state.scene);
|
|
97
|
+
}
|
|
98
|
+
else
|
|
99
|
+
throw new Error('Unknown history record');
|
|
100
|
+
state.scene = after;
|
|
101
|
+
state.entries.push(entry);
|
|
102
|
+
}
|
|
103
|
+
if (!allowSourceChange && state.sourceHash !== sourceHash)
|
|
104
|
+
throw new Error('Authoring files changed after edits were recorded. Run rebase to merge source changes, or restore the original source.');
|
|
105
|
+
const last = state.entries.at(-1);
|
|
106
|
+
if (last) {
|
|
107
|
+
await this.checkAssets(state.scene, last.asset_hashes);
|
|
108
|
+
for (const [id, font] of Object.entries(state.scene.fonts ?? {})) {
|
|
109
|
+
if (last.font_hashes &&
|
|
110
|
+
sha256(await readFile(await localAssetPath(this.root, font.source))) !==
|
|
111
|
+
last.font_hashes[`custom:${id}`])
|
|
112
|
+
throw new Error(`Font changed since the recorded edit: ${id}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return state;
|
|
116
|
+
}
|
|
117
|
+
async checkAssets(scene, expected) {
|
|
118
|
+
if (!expected)
|
|
119
|
+
throw new Error('History record is missing asset provenance');
|
|
120
|
+
for (const [id, asset] of Object.entries(scene.assets)) {
|
|
121
|
+
const bytes = await readFile(await localAssetPath(this.root, asset.source));
|
|
122
|
+
if (sha256(bytes) !== expected[id])
|
|
123
|
+
throw new Error(`Asset changed since the recorded edit: ${id}. Restore the original asset to reproduce this history.`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async scene() {
|
|
127
|
+
return (await this.state()).scene;
|
|
128
|
+
}
|
|
129
|
+
async history() {
|
|
130
|
+
return (await this.state()).entries;
|
|
131
|
+
}
|
|
132
|
+
async render(options = {}) {
|
|
133
|
+
return this.renderer.render(await this.scene(), this.root, options);
|
|
134
|
+
}
|
|
135
|
+
async verify() {
|
|
136
|
+
const scene = await this.scene();
|
|
137
|
+
return verifyRendered(scene, this.root, this.renderer);
|
|
138
|
+
}
|
|
139
|
+
async recordCritique(raw) {
|
|
140
|
+
const scene = await this.scene(), render = await this.renderer.render(scene, this.root), critique = validateCritique(raw, scene, render);
|
|
141
|
+
await writeArtifact(join(this.root, 'verification', `${basename(this.source.file)}.${render.evidence.scene.hash.slice(7)}.critique.json`), JSON.stringify(critique, null, 2) + '\n');
|
|
142
|
+
return critique;
|
|
143
|
+
}
|
|
144
|
+
async critique() {
|
|
145
|
+
const scene = await this.scene(), render = await this.renderer.render(scene, this.root);
|
|
146
|
+
try {
|
|
147
|
+
return validateCritique(JSON.parse(await readFile(join(this.root, 'verification', `${basename(this.source.file)}.${render.evidence.scene.hash.slice(7)}.critique.json`), 'utf8')), scene, render);
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
if (missing(e))
|
|
151
|
+
return null;
|
|
152
|
+
throw e;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async inspect() {
|
|
156
|
+
const state = await this.state(), nodes = flattenResolved(resolveLayout(state.scene));
|
|
157
|
+
return {
|
|
158
|
+
version: state.scene.version,
|
|
159
|
+
hash: sceneHash(state.scene),
|
|
160
|
+
canvas: state.scene.canvas,
|
|
161
|
+
source_files: (await loadScene(this.source.file)).files,
|
|
162
|
+
assets: state.scene.assets,
|
|
163
|
+
history: { entries: state.entries.length, undo: state.undo.length, redo: state.redo.length },
|
|
164
|
+
layers: nodes.map((n) => ({
|
|
165
|
+
id: n.layer.id,
|
|
166
|
+
type: n.layer.type,
|
|
167
|
+
role: n.layer.role,
|
|
168
|
+
visible: n.visible,
|
|
169
|
+
opacity: n.layer.opacity,
|
|
170
|
+
bounds: n.bounds,
|
|
171
|
+
world_bounds: n.worldBounds,
|
|
172
|
+
children: n.children.map((c) => c.layer.id),
|
|
173
|
+
operations: n.layer.operations.length,
|
|
174
|
+
tiles: n.layer.tiles.length,
|
|
175
|
+
regions: n.layer.regions?.map((r) => ({
|
|
176
|
+
id: r.id,
|
|
177
|
+
bounds: r.bounds,
|
|
178
|
+
scale: r.scale,
|
|
179
|
+
resolution: [Math.ceil(r.bounds[2] * r.scale), Math.ceil(r.bounds[3] * r.scale)],
|
|
180
|
+
})),
|
|
181
|
+
})),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async inspectLayer(id) {
|
|
185
|
+
const scene = await this.scene(), node = flattenResolved(resolveLayout(scene)).find((n) => n.layer.id === id);
|
|
186
|
+
if (!node)
|
|
187
|
+
throw new Error(`Unknown layer: ${id}`);
|
|
188
|
+
return { layer: node.layer, bounds: node.bounds, world_bounds: node.worldBounds };
|
|
189
|
+
}
|
|
190
|
+
async inspectRegion(raw) {
|
|
191
|
+
const bounds = boundsSchema.parse(raw), scene = await this.scene(), render = await this.renderer.render(scene, this.root, { region: bounds });
|
|
192
|
+
const counts = new Map();
|
|
193
|
+
let total = 0, sum = 0;
|
|
194
|
+
for (let i = 0; i < render.pixels.length; i += 4) {
|
|
195
|
+
if (!render.pixels[i + 3])
|
|
196
|
+
continue;
|
|
197
|
+
const rgb = [0, 1, 2].map((c) => Math.min(255, Math.round(render.pixels[i + c] / 32) * 32));
|
|
198
|
+
const key = '#' + rgb.map((c) => c.toString(16).padStart(2, '0')).join('');
|
|
199
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
200
|
+
sum +=
|
|
201
|
+
(0.2126 * render.pixels[i] +
|
|
202
|
+
0.7152 * render.pixels[i + 1] +
|
|
203
|
+
0.0722 * render.pixels[i + 2]) /
|
|
204
|
+
255;
|
|
205
|
+
total++;
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
bounds,
|
|
209
|
+
layers: flattenResolved(resolveLayout(scene))
|
|
210
|
+
.filter((n) => intersects(bounds, n.worldBounds))
|
|
211
|
+
.map((n) => ({ id: n.layer.id, role: n.layer.role, bounds: n.worldBounds })),
|
|
212
|
+
dominant_colours: [...counts]
|
|
213
|
+
.sort((a, b) => b[1] - a[1])
|
|
214
|
+
.slice(0, 8)
|
|
215
|
+
.map(([colour, pixels]) => ({ colour, pixels })),
|
|
216
|
+
mean_luma: total ? sum / total : 0,
|
|
217
|
+
render,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
async transaction(kind, reason, patch) {
|
|
221
|
+
await mkdir(join(this.root, 'history'), { recursive: true });
|
|
222
|
+
const lockPath = `${this.journal}.lock`;
|
|
223
|
+
let lock;
|
|
224
|
+
try {
|
|
225
|
+
lock = await open(lockPath, 'wx');
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
if (error.code === 'EEXIST')
|
|
229
|
+
throw new Error(`Project is locked: ${lockPath}. If a writer crashed, remove this lock only after confirming no writer is active.`);
|
|
230
|
+
throw error;
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
await lock.writeFile(JSON.stringify({ pid: process.pid, created: new Date().toISOString() }));
|
|
234
|
+
const state = await this.state(kind === 'rebase'), beforeHash = sceneHash(state.scene);
|
|
235
|
+
if (patch?.expected_hash && patch.expected_hash !== beforeHash)
|
|
236
|
+
throw new Error('Stale scene hash: inspect again before applying edits');
|
|
237
|
+
let after = state.scene;
|
|
238
|
+
const locality = [];
|
|
239
|
+
if (kind === 'rebase') {
|
|
240
|
+
after = parseScene(mergeSource(state.baseline, state.scene, state.incoming));
|
|
241
|
+
}
|
|
242
|
+
else if (kind === 'apply') {
|
|
243
|
+
for (const command of patch.commands) {
|
|
244
|
+
const next = applyCommand(after, command), scopes = commandScopes(command, after, next);
|
|
245
|
+
if (scopes.length) {
|
|
246
|
+
const evidence = measureLocality(await this.renderer.render(after, this.root), await this.renderer.render(next, this.root), scopes);
|
|
247
|
+
if (evidence.outside_changed_pixels)
|
|
248
|
+
throw new Error(`Edit rejected: ${evidence.outside_changed_pixels} pixels changed outside its scope. Target the enclosing group after its effects, or remove the dependent mask.`);
|
|
249
|
+
locality.push(evidence);
|
|
250
|
+
}
|
|
251
|
+
after = next;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const next = kind === 'undo' ? state.undo.at(-1) : state.redo.at(-1);
|
|
256
|
+
if (!next)
|
|
257
|
+
throw new Error(`Nothing to ${kind}`);
|
|
258
|
+
after = next;
|
|
259
|
+
}
|
|
260
|
+
// Validate renderability and pin asset provenance before committing.
|
|
261
|
+
const rendered = await this.renderer.render(after, this.root);
|
|
262
|
+
await this.checkAssets(after, rendered.evidence.assets);
|
|
263
|
+
const sourceNow = await loadScene(this.source.file), sourceHash = sceneHash(sourceNow.scene);
|
|
264
|
+
if (sourceHash !== (kind === 'rebase' ? sceneHash(state.incoming) : state.sourceHash))
|
|
265
|
+
throw new Error('Source changed during transaction');
|
|
266
|
+
const payload = {
|
|
267
|
+
sequence: state.entries.length + 1,
|
|
268
|
+
kind,
|
|
269
|
+
reason,
|
|
270
|
+
timestamp: new Date().toISOString(),
|
|
271
|
+
source_hash: sourceHash,
|
|
272
|
+
before_hash: beforeHash,
|
|
273
|
+
after_hash: sceneHash(after),
|
|
274
|
+
previous_hash: state.entries.at(-1)?.hash ?? null,
|
|
275
|
+
commands: patch?.commands ?? [],
|
|
276
|
+
asset_hashes: rendered.evidence.assets,
|
|
277
|
+
font_hashes: rendered.evidence.fonts,
|
|
278
|
+
...(kind === 'rebase'
|
|
279
|
+
? { baseline: state.incoming }
|
|
280
|
+
: state.entries.length === 0
|
|
281
|
+
? { baseline: state.baseline }
|
|
282
|
+
: {}),
|
|
283
|
+
after,
|
|
284
|
+
locality,
|
|
285
|
+
};
|
|
286
|
+
const entry = { ...payload, hash: sha256(canonical(payload)) };
|
|
287
|
+
const journal = await open(this.journal, 'a');
|
|
288
|
+
try {
|
|
289
|
+
await journal.writeFile(JSON.stringify(entry) + '\n');
|
|
290
|
+
await journal.sync();
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
await journal.close();
|
|
294
|
+
}
|
|
295
|
+
return entry;
|
|
296
|
+
}
|
|
297
|
+
finally {
|
|
298
|
+
await lock.close();
|
|
299
|
+
await unlink(lockPath);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async apply(raw) {
|
|
303
|
+
const patch = patchSchema.parse(raw);
|
|
304
|
+
return this.transaction('apply', patch.reason, patch);
|
|
305
|
+
}
|
|
306
|
+
async undo(reason = 'Undo the previous edit') {
|
|
307
|
+
return this.transaction('undo', reason);
|
|
308
|
+
}
|
|
309
|
+
async redo(reason = 'Redo the previous edit') {
|
|
310
|
+
return this.transaction('redo', reason);
|
|
311
|
+
}
|
|
312
|
+
async rebase(reason = 'Merge nonconflicting authoring changes') {
|
|
313
|
+
return this.transaction('rebase', reason);
|
|
314
|
+
}
|
|
315
|
+
async compactHistory() {
|
|
316
|
+
await mkdir(join(this.root, 'history'), { recursive: true });
|
|
317
|
+
const lockPath = `${this.journal}.lock`, lock = await open(lockPath, 'wx');
|
|
318
|
+
try {
|
|
319
|
+
await this.state();
|
|
320
|
+
return await compressJournal(this.journal);
|
|
321
|
+
}
|
|
322
|
+
finally {
|
|
323
|
+
await lock.close();
|
|
324
|
+
await unlink(lockPath);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
async exportScene(file) {
|
|
328
|
+
await writeSceneBundle(await this.scene(), this.root, file);
|
|
329
|
+
if (this.config) {
|
|
330
|
+
const config = structuredClone(this.config);
|
|
331
|
+
config.scene = basename(file);
|
|
332
|
+
for (const preset of Object.values(config.presets)) {
|
|
333
|
+
if (!preset.profile)
|
|
334
|
+
continue;
|
|
335
|
+
const bytes = await readFile(await localAssetPath(this.root, preset.profile));
|
|
336
|
+
const hash = sha256(bytes);
|
|
337
|
+
if (preset.profile_hash && preset.profile_hash !== hash)
|
|
338
|
+
throw new Error('ICC profile hash mismatch');
|
|
339
|
+
preset.profile = join('profiles', `${hash.slice(7)}.icc`);
|
|
340
|
+
preset.profile_hash = hash;
|
|
341
|
+
await writeArtifact(join(dirname(file), preset.profile), bytes);
|
|
342
|
+
}
|
|
343
|
+
await writeArtifact(join(dirname(file), 'rtistree.yaml'), stringify(config));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAsB,MAAM,qBAAqB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAuB,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAAc,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAwD,MAAM,aAAa,CAAC;AACpG,OAAO,EAAE,YAAY,EAAE,UAAU,EAA2B,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,cAAc,EAAyB,MAAM,aAAa,CAAC;AA4BrF,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAQ,KAA+B,CAAC,IAAI,KAAK,QAAQ,CAAC;AAC5D,CAAC;AACD,MAAM,OAAO,OAAO;IAEP,MAAM;IACN,QAAQ;IACR,MAAM;IAHjB,YACW,MAAmB,EACnB,QAAQ,GAAa,eAAe,EACpC,MAAsB;sBAFtB,MAAM;wBACN,QAAQ;sBACR,MAAM;IACd,CAAC;IACJ,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,QAAQ,GAAa,eAAe;QAClE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,OAAO,CAAC,MAAM,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC1B,CAAC;IACD,IAAI,eAAe;QACjB,OAAO,IAAI,CAAC,MAAM;YAChB,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC;YAChD,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACtF,CAAC;IACO,KAAK,CAAC,KAAK,CAAC,iBAAiB,GAAG,KAAK;QAC3C,+EAA+E;QAC/E,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAC/C,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC5B,MAAM,IAAI,KAAK,CACb,yFAAyF,CAC1F,CAAC;QACJ,MAAM,OAAO,GAAG,GAAG;YACjB,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAkB,CAAC,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC;YAC/E,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;QAClB,MAAM,KAAK,GAAU;YACnB,UAAU,EAAE,SAAS,CAAC,OAAO,CAAC;YAC9B,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,OAAO,CAAC,KAAK;YACvB,KAAK,EAAE,OAAO;YACd,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,EAAE;YACR,OAAO,EAAE,EAAE;SACZ,CAAC;QACF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAiB,CAAC;YAC/C,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC;YACnC,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;YAC3F,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,WAAW;oBACpE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;gBAC7C,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC5C,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC;YACvC,CAAC;iBAAM,IAAI,KAAK,CAAC,WAAW,KAAK,KAAK,CAAC,UAAU;gBAC/C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC1D,IACE,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAC3C,KAAK,CAAC,aAAa,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;gBAC5D,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;gBAE5C,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,SAAS,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC1F,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC7B,KAAK,CAAC,IAAI,GAAG,EAAE,CAAC;YAClB,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBAClC,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC,UAAU;oBACvD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBACzC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;iBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,UAAU;oBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBAC1F,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;;gBAAM,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;YACjD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;YACpB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,iBAAiB,IAAI,KAAK,CAAC,UAAU,KAAK,UAAU;YACvD,MAAM,IAAI,KAAK,CACb,wHAAwH,CACzH,CAAC;QACJ,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAClC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;YACvD,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;gBACjE,IACE,IAAI,CAAC,WAAW;oBAChB,MAAM,CAAC,MAAM,QAAQ,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;wBAClE,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,CAAC;oBAElC,MAAM,IAAI,KAAK,CAAC,yCAAyC,EAAE,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACO,KAAK,CAAC,WAAW,CAAC,KAAY,EAAE,QAAgC;QACtE,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC7E,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CACb,0CAA0C,EAAE,yDAAyD,CACtG,CAAC;QACN,CAAC;IACH,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC;IACD,KAAK,CAAC,OAAO;QACX,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACtC,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,OAAO,GAAkB,EAAE;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACtE,CAAC;IACD,KAAK,CAAC,MAAM;QACV,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;IACD,KAAK,CAAC,cAAc,CAAC,GAAY;QAC/B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,EAC9B,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EACrD,QAAQ,GAAG,gBAAgB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,aAAa,CACjB,IAAI,CACF,IAAI,CAAC,IAAI,EACT,cAAc,EACd,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CACrF,EACD,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CACzC,CAAC;QACF,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,KAAK,CAAC,QAAQ;QACZ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,EAC9B,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC;YACH,OAAO,gBAAgB,CACrB,IAAI,CAAC,KAAK,CACR,MAAM,QAAQ,CACZ,IAAI,CACF,IAAI,CAAC,IAAI,EACT,cAAc,EACd,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CACrF,EACD,MAAM,CACP,CACF,EACD,KAAK,EACL,MAAM,CACP,CAAC;QACJ,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,OAAO,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC5B,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;IACD,KAAK,CAAC,OAAO;QACX,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,EAC9B,KAAK,GAAG,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QACtD,OAAO;YACL,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO;YAC5B,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC;YAC5B,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC1B,YAAY,EAAE,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK;YACvD,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;YAC1B,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE;YAC5F,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACxB,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE;gBACd,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;gBAClB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI;gBAClB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO;gBACxB,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,YAAY,EAAE,CAAC,CAAC,WAAW;gBAC3B,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3C,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM;gBACrC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM;gBAC3B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACpC,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,MAAM,EAAE,CAAC,CAAC,MAAM;oBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,UAAU,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;iBACjF,CAAC,CAAC;aACJ,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,YAAY,CAAC,EAAU;QAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,EAC9B,IAAI,GAAG,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACnD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC;IACpF,CAAC;IACD,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,EACpC,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,EAC1B,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,IAAI,KAAK,GAAG,CAAC,EACX,GAAG,GAAG,CAAC,CAAC;QACV,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;gBAAE,SAAS;YACpC,MAAM,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YAC7F,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3E,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,GAAG;gBACD,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE;oBACzB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE;oBAC9B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;oBACjC,GAAG,CAAC;YACN,KAAK,EAAE,CAAC;QACV,CAAC;QACD,OAAO;YACL,MAAM;YACN,MAAM,EAAE,eAAe,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;iBAC1C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;iBAChD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YAC9E,gBAAgB,EAAE,CAAC,GAAG,MAAM,CAAC;iBAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;iBAC3B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iBACX,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAClD,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAClC,MAAM;SACP,CAAC;IACJ,CAAC;IACO,KAAK,CAAC,WAAW,CACvB,IAA0B,EAC1B,MAAc,EACd,KAAa;QAEb,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,OAAO,CAAC;QACxC,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;gBACpD,MAAM,IAAI,KAAK,CACb,sBAAsB,QAAQ,oFAAoF,CACnH,CAAC;YACJ,MAAM,KAAK,CAAC;QACd,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;YAC9F,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,EAC/C,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,KAAK,EAAE,aAAa,IAAI,KAAK,CAAC,aAAa,KAAK,UAAU;gBAC5D,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC3E,IAAI,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;YACxB,MAAM,QAAQ,GAAuB,EAAE,CAAC;YACxC,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtB,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/E,CAAC;iBAAM,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;gBAC5B,KAAK,MAAM,OAAO,IAAI,KAAM,CAAC,QAAQ,EAAE,CAAC;oBACtC,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,EACvC,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;oBAC/C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;wBAClB,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,EAC5C,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,EAC3C,MAAM,CACP,CAAC;wBACF,IAAI,QAAQ,CAAC,sBAAsB;4BACjC,MAAM,IAAI,KAAK,CACb,kBAAkB,QAAQ,CAAC,sBAAsB,gHAAgH,CAClK,CAAC;wBACJ,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC1B,CAAC;oBACD,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrE,IAAI,CAAC,IAAI;oBAAE,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;gBACjD,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;YACD,qEAAqE;YACrE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9D,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EACjD,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,UAAU,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;gBACnF,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YAEvD,MAAM,OAAO,GAA+B;gBAC1C,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;gBAClC,IAAI;gBACJ,MAAM;gBACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,UAAU;gBACvB,WAAW,EAAE,UAAU;gBACvB,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC;gBAC5B,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,IAAI;gBACjD,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,EAAE;gBAC/B,YAAY,EAAE,QAAQ,CAAC,QAAQ,CAAC,MAAM;gBACtC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,KAAK;gBACpC,GAAG,CAAC,IAAI,KAAK,QAAQ;oBACnB,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;oBAC9B,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;wBAC1B,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;wBAC9B,CAAC,CAAC,EAAE,CAAC;gBACT,KAAK;gBACL,QAAQ;aACT,CAAC;YACF,MAAM,KAAK,GAAG,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;YAC/D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;gBACtD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YACvB,CAAC;oBAAS,CAAC;gBACT,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,KAAK,CAAC,GAAY;QACtB,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,wBAAwB;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,wBAAwB;QAC1C,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,wCAAwC;QAC5D,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IACD,KAAK,CAAC,cAAc;QAClB,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,OAAO,OAAO,EACrC,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;YACnB,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,MAAM,gBAAgB,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5C,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC9B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,SAAS;gBAC9B,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,MAAM,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC9E,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,YAAY,KAAK,IAAI;oBACrD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBAC/C,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC1D,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC;gBAC3B,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;YAClE,CAAC;YACD,MAAM,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { Project } from './project.js';
|
|
3
|
+
export declare const rasterReadSchema: z.ZodObject<{
|
|
4
|
+
bounds: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
|
|
5
|
+
target: z.ZodOptional<z.ZodString>;
|
|
6
|
+
}, z.core.$strict>;
|
|
7
|
+
export declare const rasterWriteSchema: z.ZodObject<{
|
|
8
|
+
target: z.ZodString;
|
|
9
|
+
region_id: z.ZodString;
|
|
10
|
+
source: z.ZodString;
|
|
11
|
+
bounds: z.ZodTuple<[z.ZodNumber, z.ZodNumber, z.ZodNumber, z.ZodNumber], null>;
|
|
12
|
+
space: z.ZodDefault<z.ZodEnum<{
|
|
13
|
+
canvas: "canvas";
|
|
14
|
+
layer: "layer";
|
|
15
|
+
}>>;
|
|
16
|
+
composite: z.ZodDefault<z.ZodEnum<{
|
|
17
|
+
over: "over";
|
|
18
|
+
replace: "replace";
|
|
19
|
+
}>>;
|
|
20
|
+
expected_hash: z.ZodString;
|
|
21
|
+
reason: z.ZodString;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
export declare function readRasterRegion(project: Project, raw: unknown): Promise<{
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
colour_space: 'srgb';
|
|
27
|
+
quality: string;
|
|
28
|
+
region?: import("./schema.js").Bounds;
|
|
29
|
+
layer?: string;
|
|
30
|
+
png_hash: string;
|
|
31
|
+
excluded_layers?: string[];
|
|
32
|
+
canvas_transform?: import("./layout.js").Matrix;
|
|
33
|
+
image: string;
|
|
34
|
+
evidence: string;
|
|
35
|
+
statistics: {
|
|
36
|
+
rasterized_layers: number;
|
|
37
|
+
cached_layers: number;
|
|
38
|
+
cache_bytes: number;
|
|
39
|
+
viewport_pixels?: number;
|
|
40
|
+
};
|
|
41
|
+
asset: {
|
|
42
|
+
source: string;
|
|
43
|
+
hash: string;
|
|
44
|
+
};
|
|
45
|
+
scene_hash: string;
|
|
46
|
+
bounds: [number, number, number, number];
|
|
47
|
+
target: string | undefined;
|
|
48
|
+
space: string;
|
|
49
|
+
encoding: string;
|
|
50
|
+
render: import("./render.js").RenderResult;
|
|
51
|
+
}>;
|
|
52
|
+
export declare function writeRasterRegion(project: Project, raw: unknown): Promise<{
|
|
53
|
+
scene_hash: string;
|
|
54
|
+
sequence: number;
|
|
55
|
+
locality: import("./verify.js").LocalityEvidence[];
|
|
56
|
+
asset: {
|
|
57
|
+
source: string;
|
|
58
|
+
hash: string;
|
|
59
|
+
};
|
|
60
|
+
region_id: string;
|
|
61
|
+
}>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { join, relative } from 'node:path';
|
|
4
|
+
import sharp from 'sharp';
|
|
5
|
+
import { boundsSchema, flattenLayers } from './schema.js';
|
|
6
|
+
import { localAssetPath, sceneHash, sha256 } from './assets.js';
|
|
7
|
+
import { writeArtifact, writeRender } from './artifacts.js';
|
|
8
|
+
export const rasterReadSchema = z.strictObject({
|
|
9
|
+
bounds: boundsSchema,
|
|
10
|
+
target: z.string().optional(),
|
|
11
|
+
});
|
|
12
|
+
export const rasterWriteSchema = z.strictObject({
|
|
13
|
+
target: z.string(),
|
|
14
|
+
region_id: z.string().regex(/^[a-zA-Z][a-zA-Z0-9_-]{0,79}$/),
|
|
15
|
+
source: z.string(),
|
|
16
|
+
bounds: boundsSchema,
|
|
17
|
+
space: z.enum(['canvas', 'layer']).default('canvas'),
|
|
18
|
+
composite: z.enum(['replace', 'over']).default('replace'),
|
|
19
|
+
expected_hash: z.string(),
|
|
20
|
+
reason: z.string().min(1),
|
|
21
|
+
});
|
|
22
|
+
export async function readRasterRegion(project, raw) {
|
|
23
|
+
const options = rasterReadSchema.parse(raw), scene = await project.scene();
|
|
24
|
+
const render = await project.renderer.render(scene, project.root, {
|
|
25
|
+
layer: options.target,
|
|
26
|
+
region: options.bounds,
|
|
27
|
+
cache: false,
|
|
28
|
+
regionMode: 'full',
|
|
29
|
+
});
|
|
30
|
+
const path = join(project.outputDirectory, `region-${render.evidence.render.png_hash.slice(7)}.png`);
|
|
31
|
+
const artifact = await writeRender(path, render);
|
|
32
|
+
return {
|
|
33
|
+
...artifact,
|
|
34
|
+
asset: { source: relative(project.root, path), hash: render.evidence.render.png_hash },
|
|
35
|
+
scene_hash: sceneHash(scene),
|
|
36
|
+
bounds: options.bounds,
|
|
37
|
+
target: options.target,
|
|
38
|
+
space: 'canvas',
|
|
39
|
+
encoding: 'PNG, straight RGBA on decode; 8-bit sRGB',
|
|
40
|
+
render,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export async function writeRasterRegion(project, raw) {
|
|
44
|
+
const options = rasterWriteSchema.parse(raw), scene = await project.scene();
|
|
45
|
+
if (sceneHash(scene) !== options.expected_hash)
|
|
46
|
+
throw new Error('Stale scene hash');
|
|
47
|
+
if (!options.bounds.every(Number.isInteger))
|
|
48
|
+
throw new Error('Dense patches require integer bounds');
|
|
49
|
+
const bytes = await readFile(await localAssetPath(project.root, options.source));
|
|
50
|
+
if (bytes.length > 64 * 1024 * 1024)
|
|
51
|
+
throw new Error('Dense patch exceeds 64 MiB');
|
|
52
|
+
const metadata = await sharp(bytes, { limitInputPixels: 16 * 1024 * 1024 }).metadata();
|
|
53
|
+
if (metadata.format !== 'png' ||
|
|
54
|
+
metadata.width !== options.bounds[2] ||
|
|
55
|
+
metadata.height !== options.bounds[3])
|
|
56
|
+
throw new Error('Dense patch must be a PNG matching the exact region dimensions');
|
|
57
|
+
const hash = sha256(bytes), source = join('raster', `${hash.slice(7)}.png`), id = `patch_${hash.slice(7, 39)}`;
|
|
58
|
+
const layer = flattenLayers(scene.layers).find((l) => l.id === options.target);
|
|
59
|
+
if (!layer)
|
|
60
|
+
throw new Error('Unknown patch target');
|
|
61
|
+
await writeArtifact(join(project.root, source), bytes);
|
|
62
|
+
const entry = await project.apply({
|
|
63
|
+
expected_hash: options.expected_hash,
|
|
64
|
+
reason: options.reason,
|
|
65
|
+
commands: [
|
|
66
|
+
{ type: 'registerAsset', id, asset: { source, hash } },
|
|
67
|
+
{
|
|
68
|
+
type: layer.regions?.some((r) => r.id === options.region_id)
|
|
69
|
+
? 'updateRegion'
|
|
70
|
+
: 'promoteRegion',
|
|
71
|
+
target: options.target,
|
|
72
|
+
region: {
|
|
73
|
+
id: options.region_id,
|
|
74
|
+
source: id,
|
|
75
|
+
bounds: options.bounds,
|
|
76
|
+
space: options.space,
|
|
77
|
+
scale: 1,
|
|
78
|
+
composite: options.composite,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
scene_hash: entry.after_hash,
|
|
85
|
+
sequence: entry.sequence,
|
|
86
|
+
locality: entry.locality,
|
|
87
|
+
asset: { source, hash },
|
|
88
|
+
region_id: options.region_id,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=raster-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster-edit.js","sourceRoot":"","sources":["../src/raster-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { resolveConstruction } from './construction.js';
|
|
2
|
+
import { type Canvas } from './native.js';
|
|
3
|
+
export type RGBA = [number, number, number, number];
|
|
4
|
+
export interface PixelSurface {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
data: Uint8ClampedArray;
|
|
8
|
+
}
|
|
9
|
+
export type EdgeMode = 'transparent' | 'clamp' | 'repeat';
|
|
10
|
+
export declare const clamp: (x: number, lo?: number, hi?: number) => number;
|
|
11
|
+
export declare const mix: (a: number, b: number, t: number) => number;
|
|
12
|
+
export declare const smoothstep: (a: number, b: number, x: number) => number;
|
|
13
|
+
export declare const repeat: (x: number, period: number) => number;
|
|
14
|
+
export declare function randomGenerator(seed: number): () => number;
|
|
15
|
+
/** Coordinate-addressed noise is independent of traversal order. */
|
|
16
|
+
export declare function noise2D(x: number, y: number, seed?: number): number;
|
|
17
|
+
export declare function fbm(x: number, y: number, seed?: number, octaves?: number): number;
|
|
18
|
+
/** Pixel centres are integer coordinates; interpolate premultiplied colour to avoid dark fringes. */
|
|
19
|
+
export declare function sample(s: PixelSurface, x: number, y: number, edge?: EdgeMode): RGBA;
|
|
20
|
+
export interface BrushPoint {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
pressure?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface BrushOptions {
|
|
26
|
+
radius: number;
|
|
27
|
+
colour: string;
|
|
28
|
+
hardness?: number;
|
|
29
|
+
opacity?: number;
|
|
30
|
+
spacing?: number;
|
|
31
|
+
scatter?: number;
|
|
32
|
+
}
|
|
33
|
+
export type Vector3 = [number, number, number];
|
|
34
|
+
export declare function heightNormal(height: (x: number, y: number) => number, x: number, y: number, strength?: number, step?: number): Vector3;
|
|
35
|
+
export declare function lightSurface(normal: Vector3, base: RGBA, options?: {
|
|
36
|
+
light?: Vector3;
|
|
37
|
+
ambient?: number;
|
|
38
|
+
diffuse?: number;
|
|
39
|
+
specular?: number;
|
|
40
|
+
shininess?: number;
|
|
41
|
+
}): RGBA;
|
|
42
|
+
/** A synchronous authoring API. Programs return one Canvas; scene playback uses its baked PNG. */
|
|
43
|
+
export declare function createRasterStudio(width: number, height: number, seed: number, inputs?: Record<string, Canvas>): {
|
|
44
|
+
width: number;
|
|
45
|
+
height: number;
|
|
46
|
+
seed: number;
|
|
47
|
+
techniques: {
|
|
48
|
+
mix: (a: string, b: string, t: number) => string;
|
|
49
|
+
atmosphere: (a: string, b: string, t: number) => string;
|
|
50
|
+
stroke(canvas: Canvas, points: BrushPoint[], options: import("./techniques.js").PaintOptions): Canvas;
|
|
51
|
+
glaze(canvas: Canvas, colour: string, opacity?: number): Canvas;
|
|
52
|
+
weave(canvas: Canvas, options?: {
|
|
53
|
+
spacing?: number;
|
|
54
|
+
opacity?: number;
|
|
55
|
+
colour?: string;
|
|
56
|
+
}): Canvas;
|
|
57
|
+
};
|
|
58
|
+
guides: typeof resolveConstruction;
|
|
59
|
+
path: (data: string) => import("@napi-rs/canvas").Path2D;
|
|
60
|
+
canvas: (w?: number, h?: number) => Canvas;
|
|
61
|
+
pixels: (c: Canvas) => PixelSurface;
|
|
62
|
+
put: (c: Canvas, p: PixelSurface) => Canvas;
|
|
63
|
+
raster: (fn: (x: number, y: number) => RGBA, w?: number, h?: number) => Canvas;
|
|
64
|
+
warp: (source: Canvas, coordinates: (x: number, y: number) => [number, number], edge?: EdgeMode, w?: number, h?: number) => Canvas;
|
|
65
|
+
sample: typeof sample;
|
|
66
|
+
brush: (c: Canvas, points: BrushPoint[], options: BrushOptions) => Canvas;
|
|
67
|
+
random: () => number;
|
|
68
|
+
clamp: typeof clamp;
|
|
69
|
+
mix: typeof mix;
|
|
70
|
+
smoothstep: typeof smoothstep;
|
|
71
|
+
repeat: typeof repeat;
|
|
72
|
+
normal: typeof heightNormal;
|
|
73
|
+
light: typeof lightSurface;
|
|
74
|
+
noise: (x: number, y: number, salt?: number) => number;
|
|
75
|
+
fbm: (x: number, y: number, octaves?: number, salt?: number) => number;
|
|
76
|
+
polar: (x: number, y: number, cx?: number, cy?: number) => {
|
|
77
|
+
radius: number;
|
|
78
|
+
angle: number;
|
|
79
|
+
};
|
|
80
|
+
input: (name: string) => Canvas;
|
|
81
|
+
displace: (source: Canvas, field: (x: number, y: number) => [number, number], amount?: number, edge?: EdgeMode) => Canvas;
|
|
82
|
+
blur: (source: Canvas, radius: number) => Canvas;
|
|
83
|
+
};
|
|
84
|
+
export type RasterStudio = ReturnType<typeof createRasterStudio>;
|