@osmo.inc/cli-linux-arm64 0.1.23 → 0.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/studio.js +5058 -930
- package/package.json +1 -1
- package/release.json +32 -32
- package/runtime/apps/native/tools/compile.mjs +22 -4
- package/runtime/packages/render-protocol/src/film-catalog.json +2543 -0
- package/runtime/packages/render-protocol/src/film-resources.mjs +91 -0
- package/runtime/packages/render-protocol/src/film-store.node.mjs +220 -0
- package/runtime/packages/scene/scripts/sync-film.mjs +8 -0
- package/runtime/packages/scene/scripts/validate-strict.mjs +14 -4
- package/runtime/packages/scene/scripts/verify-export-resolution.mjs +67 -0
- package/runtime/packages/scene/scripts/verify-film.mjs +66 -0
- package/runtime/packages/scene/src/effect-schemas.d.mts +246 -0
- package/runtime/packages/scene/src/effect-schemas.mjs +136 -0
- package/runtime/packages/scene/src/effects.ts +23 -6
- package/runtime/packages/scene/src/elements.ts +15 -3
- package/runtime/packages/scene/src/evaluate.ts +88 -12
- package/runtime/packages/scene/src/film-catalog.generated.ts +3 -0
- package/runtime/packages/scene/src/film.ts +39 -0
- package/runtime/packages/scene/src/index.ts +6 -2
- package/runtime/packages/scene/src/knob-schema.ts +5 -2
- package/runtime/packages/scene/src/metadata.d.mts +2 -1
- package/runtime/packages/scene/src/metadata.mjs +4 -4
- package/runtime/packages/scene/src/motion-blur.ts +30 -0
- package/src/starter/scene.tsx +1 -1
- package/studio/src/app.css +1 -1
- package/studio/src/app.js +197 -179
- package/studio/src/engine_bg.wasm +0 -0
- package/studio/src/preview-worker.js +33 -0
- package/studio/src/stretch-worklet-Z4ADHTIR.mjs +1 -0
- package/third-party/braw/BlackmagicRawAPI.h +1137 -0
- package/third-party/braw/README.md +7 -0
- package/third-party/cargo/block-buffer@0.10.4/Cargo.toml +32 -0
- package/third-party/cargo/block-buffer@0.10.4/LICENSE-APACHE +201 -0
- package/third-party/cargo/block-buffer@0.10.4/LICENSE-MIT +25 -0
- package/third-party/cargo/cc@1.4.5/Cargo.toml +89 -0
- package/third-party/cargo/cc@1.4.5/LICENSE-APACHE +201 -0
- package/third-party/cargo/cc@1.4.5/LICENSE-MIT +25 -0
- package/third-party/cargo/cpufeatures@0.2.17/Cargo.toml +71 -0
- package/third-party/cargo/cpufeatures@0.2.17/LICENSE-APACHE +201 -0
- package/third-party/cargo/cpufeatures@0.2.17/LICENSE-MIT +25 -0
- package/third-party/cargo/crypto-common@0.1.7/Cargo.toml +62 -0
- package/third-party/cargo/crypto-common@0.1.7/LICENSE-APACHE +201 -0
- package/third-party/cargo/crypto-common@0.1.7/LICENSE-MIT +25 -0
- package/third-party/cargo/digest@0.10.7/Cargo.toml +70 -0
- package/third-party/cargo/digest@0.10.7/LICENSE-APACHE +201 -0
- package/third-party/cargo/digest@0.10.7/LICENSE-MIT +25 -0
- package/third-party/cargo/find-msvc-tools@0.1.12/Cargo.toml +49 -0
- package/third-party/cargo/find-msvc-tools@0.1.12/LICENSE-APACHE +201 -0
- package/third-party/cargo/find-msvc-tools@0.1.12/LICENSE-MIT +25 -0
- package/third-party/cargo/generic-array@0.14.7/Cargo.toml +75 -0
- package/third-party/cargo/generic-array@0.14.7/LICENSE +21 -0
- package/third-party/cargo/sha2@0.10.9/Cargo.toml +90 -0
- package/third-party/cargo/sha2@0.10.9/LICENSE-APACHE +201 -0
- package/third-party/cargo/sha2@0.10.9/LICENSE-MIT +27 -0
- package/third-party/cargo/shlex@2.0.1/Cargo.toml +51 -0
- package/third-party/cargo/shlex@2.0.1/LICENSE-APACHE +13 -0
- package/third-party/cargo/shlex@2.0.1/LICENSE-MIT +21 -0
- package/third-party/cargo/typenum@1.20.1/Cargo.toml +75 -0
- package/third-party/cargo/typenum@1.20.1/LICENSE +1 -0
- package/third-party/cargo/typenum@1.20.1/LICENSE-APACHE +201 -0
- package/third-party/cargo/typenum@1.20.1/LICENSE-MIT +21 -0
- package/third-party/film/camera-COLOUR-LICENSE +11 -0
- package/third-party/film/camera-CONFIG-LICENSE +26 -0
- package/third-party/film/camera-LICENSE +26 -0
- package/third-party/film/camera-metadata.json +344 -0
- package/third-party/film/provenance.json +7 -0
- package/third-party/inventory.json +162 -0
- package/third-party/npm/signalsmith-stretch@1.3.2/package.json +26 -0
- package/third-party/npm/signalsmith-stretch@1.3.2/signalsmith-stretch-1.3.2-LICENSE.txt +21 -0
- package/vendor/osmo-lite +0 -0
- package/vendor/osmo-scene-0.1.0.tgz +0 -0
- package/vendor/platform.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {resolveMotionBlur, shutterFrames, type ResolvedMotionBlur} from "./motion-blur.js";
|
|
1
2
|
import { evaluateTextAnimation, type EvaluatedTextAnimation } from "./text-animation.js";
|
|
2
3
|
import { readMask, maskSourceIndex } from "./mask.mjs";
|
|
3
4
|
import { clipFields, clipTiming, isClipPrimitive } from "./clip.mjs";
|
|
@@ -106,6 +107,8 @@ export interface TextNode extends BaseNode {
|
|
|
106
107
|
letterSpacing: number;
|
|
107
108
|
}
|
|
108
109
|
export interface MediaNode extends BaseNode {
|
|
110
|
+
originalSrc?: string;
|
|
111
|
+
originalSourceFile?: string;
|
|
109
112
|
type: "image" | "video" | "audio";
|
|
110
113
|
src: string;
|
|
111
114
|
sourceFile?: string;
|
|
@@ -148,6 +151,11 @@ export interface EvaluatedCamera {
|
|
|
148
151
|
fov: number;
|
|
149
152
|
}
|
|
150
153
|
export interface EvaluatedScene extends FrameContext {
|
|
154
|
+
motionBlur?: ResolvedMotionBlur;
|
|
155
|
+
motionSamples?: EvaluatedScene[];
|
|
156
|
+
/** Back-to-front root indices. Keep children in source order for stable editor paths.
|
|
157
|
+
* Presence opts into track stacking and group-local backdrop scopes. */
|
|
158
|
+
paintOrder?: number[];
|
|
151
159
|
controls?: KnobDescription;
|
|
152
160
|
effects?: EvaluatedEffect[];
|
|
153
161
|
camera?: EvaluatedCamera;
|
|
@@ -224,13 +232,34 @@ function isElement(value: unknown): value is Element {
|
|
|
224
232
|
export function evaluateFrame(root: Element, frame: number): EvaluatedScene {
|
|
225
233
|
return evaluateScene(root, frame);
|
|
226
234
|
}
|
|
235
|
+
/** Render evaluation keeps the integer center frame for editor geometry. */
|
|
236
|
+
export function evaluateMotionFrame(root: Element, frame: number): EvaluatedScene {
|
|
237
|
+
const center = evaluateFrame(root, frame);
|
|
238
|
+
if (!center.motionBlur) return center;
|
|
239
|
+
function validate(nodes: SceneNode[]) {
|
|
240
|
+
for (const node of nodes) {
|
|
241
|
+
// Hosts hold video footage at the center frame for the exposure.
|
|
242
|
+
// Models still need their own temporal sampling implementation.
|
|
243
|
+
if (node.type === 'model')
|
|
244
|
+
throw new Error('Motion blur does not support Model layers; use motionBlur={false}');
|
|
245
|
+
if (node.type === 'composition') validate(node.scene.children);
|
|
246
|
+
else if ('children' in node) validate(node.children as SceneNode[]);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
validate(center.children);
|
|
250
|
+
center.motionSamples = shutterFrames(frame, center.totalFrames, center.motionBlur)
|
|
251
|
+
.map(at => evaluateScene(root, at, {subframe: true}, 0, undefined, center));
|
|
252
|
+
for (const sample of center.motionSamples) validate(sample.children);
|
|
253
|
+
// Do not retain another exposure recursively through imported compositions.
|
|
254
|
+
return center;
|
|
255
|
+
}
|
|
227
256
|
interface SceneBindings {
|
|
228
257
|
values?: Record<string, unknown>;
|
|
229
258
|
scope: KnobScope;
|
|
230
259
|
time: number;
|
|
231
260
|
sourceFile?: string;
|
|
232
261
|
}
|
|
233
|
-
function evaluateScene(root: Element, frame: number, clock?: Partial<ClockContext>, depth = 0, instance?: SceneBindings): EvaluatedScene {
|
|
262
|
+
function evaluateScene(root: Element, frame: number, clock?: Partial<ClockContext>, depth = 0, instance?: SceneBindings, exposureCenter?: EvaluatedScene): EvaluatedScene {
|
|
234
263
|
if (depth > 32) throw new Error("Scene nesting exceeds 32 levels");
|
|
235
264
|
if (!isElement(root) || (root.type !== Scene && root.type !== "scene")) {
|
|
236
265
|
throw new Error(
|
|
@@ -241,10 +270,14 @@ function evaluateScene(root: Element, frame: number, clock?: Partial<ClockContex
|
|
|
241
270
|
checkProps(
|
|
242
271
|
p,
|
|
243
272
|
"Scene",
|
|
244
|
-
["width", "height", "duration", "fps", "background", "children", "effects", "tracks", "knobs", "values"],
|
|
273
|
+
["width", "height", "duration", "fps", "background", "children", "effects", "tracks", "knobs", "values", "stacking", "motionBlur"],
|
|
245
274
|
false,
|
|
246
275
|
);
|
|
276
|
+
const motionBlur = resolveMotionBlur(p.motionBlur);
|
|
277
|
+
if (depth > 0 && motionBlur) throw new Error("Set motionBlur on the root Scene; nested exposures are not supported");
|
|
247
278
|
const tracks = readSceneTracks(p.tracks);
|
|
279
|
+
if (p.stacking !== undefined && p.stacking !== "source" && p.stacking !== "tracks")
|
|
280
|
+
throw new Error('Scene.stacking must be "tracks" or "source"');
|
|
248
281
|
const width = positive(p.width, "Scene.width");
|
|
249
282
|
const height = positive(p.height, "Scene.height");
|
|
250
283
|
if (![width,height].every(v=>Number.isInteger(v)&&v<=8192)) throw new Error("Scene dimensions must be whole pixels, at most 8192 per side");
|
|
@@ -301,7 +334,14 @@ function evaluateScene(root: Element, frame: number, clock?: Partial<ClockContex
|
|
|
301
334
|
}
|
|
302
335
|
}
|
|
303
336
|
collect(p.children);
|
|
304
|
-
const
|
|
337
|
+
const sampling: TrackSampling | undefined = exposureCenter ? {
|
|
338
|
+
tracks,
|
|
339
|
+
context: {...context, frame: exposureCenter.frame, time: exposureCenter.time, subframe: undefined},
|
|
340
|
+
scope: p.knobs !== undefined && exposureCenter.controls
|
|
341
|
+
? [{set: p.knobs as import("./knobs.js").KnobSet, description: exposureCenter.controls}]
|
|
342
|
+
: scope,
|
|
343
|
+
} : undefined;
|
|
344
|
+
const evaluatedChildren = isolateGroups(visit(children, context, depth, scope, sampling)
|
|
305
345
|
.filter(node => node.track === undefined || !tracks[node.track]?.hidden));
|
|
306
346
|
function checkPlacement(nodes: SceneNode[], parent: string) {
|
|
307
347
|
for (const n of nodes) {
|
|
@@ -320,12 +360,15 @@ function evaluateScene(root: Element, frame: number, clock?: Partial<ClockContex
|
|
|
320
360
|
}
|
|
321
361
|
return {
|
|
322
362
|
type: "scene",
|
|
363
|
+
...(motionBlur ? {motionBlur} : {}),
|
|
323
364
|
...(camera ? { camera } : {}),
|
|
324
365
|
...context,
|
|
325
366
|
totalFrames,
|
|
326
367
|
background: color(resolve(p.background ?? "transparent", context.time, scope), "Scene.background"),
|
|
327
368
|
...(controls ? {controls} : {}),
|
|
328
369
|
...(p.effects === undefined ? {} : { effects: evaluateEffects(p.effects, context.time, root.sourceFile, v => isKnobRef(v) ? resolveKnob(v, scope) : v) }),
|
|
370
|
+
...(p.stacking === "tracks" ? {paintOrder: evaluatedChildren.map((_, i) => i)
|
|
371
|
+
.sort((a, b) => (evaluatedChildren[b].track ?? 0) - (evaluatedChildren[a].track ?? 0))} : {}),
|
|
329
372
|
children: evaluatedChildren,
|
|
330
373
|
};
|
|
331
374
|
}
|
|
@@ -355,7 +398,7 @@ function evaluateCamera(
|
|
|
355
398
|
return { position, z, target, fov };
|
|
356
399
|
}
|
|
357
400
|
|
|
358
|
-
interface ClockContext extends FrameContext { offset?: number; windowStart?: number; windowEnd?: number; }
|
|
401
|
+
interface ClockContext extends FrameContext { subframe?: boolean; offset?: number; windowStart?: number; windowEnd?: number; }
|
|
359
402
|
|
|
360
403
|
// Evaluation-only state: do not serialize editor controls into render snapshots.
|
|
361
404
|
const soloGroups = new WeakSet<SceneNode>();
|
|
@@ -396,11 +439,18 @@ function vectorMask(child: Element): Element {
|
|
|
396
439
|
return {...child, props:p};
|
|
397
440
|
}
|
|
398
441
|
|
|
442
|
+
interface TrackSampling {
|
|
443
|
+
tracks: ReturnType<typeof readSceneTracks>;
|
|
444
|
+
context: ClockContext;
|
|
445
|
+
scope: KnobScope;
|
|
446
|
+
}
|
|
447
|
+
|
|
399
448
|
function visit(
|
|
400
449
|
child: unknown,
|
|
401
450
|
context: ClockContext,
|
|
402
451
|
depth: number,
|
|
403
452
|
scope: KnobScope = [],
|
|
453
|
+
sampling?: TrackSampling,
|
|
404
454
|
): SceneNode[] {
|
|
405
455
|
if (depth > 256)
|
|
406
456
|
throw new Error(
|
|
@@ -409,7 +459,7 @@ function visit(
|
|
|
409
459
|
if (child === null || child === undefined || typeof child === "boolean")
|
|
410
460
|
return [];
|
|
411
461
|
if (Array.isArray(child))
|
|
412
|
-
return child.flatMap((c) => visit(c, context, depth + 1, scope));
|
|
462
|
+
return child.flatMap((c) => visit(c, context, depth + 1, scope, sampling));
|
|
413
463
|
if (!isElement(child))
|
|
414
464
|
throw new Error(
|
|
415
465
|
"Scene children must be components; put text inside <Text>",
|
|
@@ -427,6 +477,11 @@ function visit(
|
|
|
427
477
|
[Camera, "camera"],
|
|
428
478
|
]);
|
|
429
479
|
const type = builtins.get(child.type) ?? child.type;
|
|
480
|
+
// Freeze the whole authored clip before local timing, knobs, procedural children,
|
|
481
|
+
// and visibility are evaluated. It still advances normally between output frames.
|
|
482
|
+
const track = child.props.track;
|
|
483
|
+
if (sampling && (type === "video" || (typeof track === "number" && sampling.tracks[track]?.motionBlur === false)))
|
|
484
|
+
return visit(child, sampling.context, depth, sampling.scope);
|
|
430
485
|
// Hidden layers remain in the authored document, but contribute no evaluated
|
|
431
486
|
// nodes, layout space, hit targets, or descendant media.
|
|
432
487
|
if (typeof type !== "function" && child.props.hidden !== undefined) {
|
|
@@ -455,7 +510,8 @@ function visit(
|
|
|
455
510
|
return Math.round(value);
|
|
456
511
|
};
|
|
457
512
|
const viewport = {...source,props:{...source.props,width:dimension('width'),height:dimension('height')}};
|
|
458
|
-
const
|
|
513
|
+
const center = sampling ? visit(child, sampling.context, depth, sampling.scope)[0] as CompositionNode | undefined : undefined;
|
|
514
|
+
const scene = evaluateScene(viewport, 0, {time, frame:time*context.fps, fps:context.fps, subframe:context.subframe, offset, windowStart:start, windowEnd:end}, depth+1, {values:p.values as Record<string,unknown> | undefined, scope, time:localTime, sourceFile:child.sourceFile}, center?.scene);
|
|
459
515
|
const active = context.time >= timing.start && context.time < timing.start + Math.min(timing.duration, sourceDuration-trim);
|
|
460
516
|
readGroupLabel(p.label); readGroupPlayback(p);
|
|
461
517
|
const node: CompositionNode = {type:'composition',width:scene.width,height:scene.height,scene,
|
|
@@ -476,9 +532,17 @@ function visit(
|
|
|
476
532
|
active = context.time >= start && context.time < start + duration;
|
|
477
533
|
const offset = (context.offset ?? 0) + start;
|
|
478
534
|
const time = Math.max(0, Math.min(duration - 1e-9, context.time - start));
|
|
479
|
-
context = { ...context, time, frame: Math.floor(time * context.fps), duration, offset,
|
|
535
|
+
context = { ...context, time, frame: context.subframe ? time * context.fps : Math.floor(time * context.fps), duration, offset,
|
|
480
536
|
windowStart: Math.max(context.windowStart ?? 0, offset),
|
|
481
537
|
windowEnd: Math.min(context.windowEnd ?? Infinity, offset + duration) };
|
|
538
|
+
if (sampling) {
|
|
539
|
+
const center = sampling.context;
|
|
540
|
+
const centerOffset = (center.offset ?? 0) + start;
|
|
541
|
+
const centerTime = Math.max(0, Math.min(duration - 1e-9, center.time - start));
|
|
542
|
+
sampling = {...sampling, context: {...center, time: centerTime, frame: Math.floor(centerTime * center.fps), duration, offset: centerOffset,
|
|
543
|
+
windowStart: Math.max(center.windowStart ?? 0, centerOffset),
|
|
544
|
+
windowEnd: Math.min(center.windowEnd ?? Infinity, centerOffset + duration)}};
|
|
545
|
+
}
|
|
482
546
|
}
|
|
483
547
|
let controls: KnobDescription | undefined;
|
|
484
548
|
if (type === "group") {
|
|
@@ -488,10 +552,15 @@ function visit(
|
|
|
488
552
|
if (!isKnobSet(child.props.knobs)) throw new Error("Group.knobs must be a defineKnobs declaration");
|
|
489
553
|
controls = evaluateKnobs(child.props.knobs, child.props.values, context.time, scope, {sourceFile:child.sourceFile, valueSources:child.valueSources});
|
|
490
554
|
scope = [...scope, { set: child.props.knobs, description: controls }];
|
|
555
|
+
if (sampling) {
|
|
556
|
+
const centerControls = evaluateKnobs(child.props.knobs, child.props.values, sampling.context.time, sampling.scope,
|
|
557
|
+
{sourceFile: child.sourceFile, valueSources: child.valueSources});
|
|
558
|
+
sampling = {...sampling, scope: [...sampling.scope, {set: child.props.knobs, description: centerControls}]};
|
|
559
|
+
}
|
|
491
560
|
} else if (child.props.values !== undefined) throw new Error("Group.values requires Group.knobs");
|
|
492
561
|
}
|
|
493
562
|
// Asset controls carry their authoring file through all forwarding scopes.
|
|
494
|
-
const assetSource = (prop: "src" | "font") => {
|
|
563
|
+
const assetSource = (prop: "src" | "font" | "originalSrc") => {
|
|
495
564
|
const ref = child.props[prop];
|
|
496
565
|
const asset = isKnobRef(ref) ? resolveKnobAsset(ref, scope) : undefined;
|
|
497
566
|
if (asset && asset.kind !== (prop === "font" ? "font" : type))
|
|
@@ -504,7 +573,7 @@ function visit(
|
|
|
504
573
|
]));
|
|
505
574
|
if (typeof type === "function") {
|
|
506
575
|
const result: Child = type(Object.freeze(props), context);
|
|
507
|
-
const nodes = visit(result, context, depth + 1, scope);
|
|
576
|
+
const nodes = visit(result, context, depth + 1, scope, sampling);
|
|
508
577
|
// A keyed custom component owns a fragment scope, preserving its identity
|
|
509
578
|
// independently of repeated child keys inside other component instances.
|
|
510
579
|
if (child.key !== undefined)
|
|
@@ -519,7 +588,7 @@ function visit(
|
|
|
519
588
|
return nodes;
|
|
520
589
|
}
|
|
521
590
|
if (type === "fragment") {
|
|
522
|
-
const children = visit(props.children, context, depth + 1, scope);
|
|
591
|
+
const children = visit(props.children, context, depth + 1, scope, sampling);
|
|
523
592
|
return child.key === undefined
|
|
524
593
|
? children
|
|
525
594
|
: [{ type: "group", key: child.key, transform: transform({}), children }];
|
|
@@ -652,7 +721,7 @@ function visit(
|
|
|
652
721
|
let maskIndex = -1;
|
|
653
722
|
if (sources) for (const [i, source] of sources.entries()) {
|
|
654
723
|
const isMask = i === sourceIndex;
|
|
655
|
-
const evaluated = visit(isMask && mask!.mode === "vector" ? vectorMask(source) : source, context, depth + 1, scope);
|
|
724
|
+
const evaluated = visit(isMask && mask!.mode === "vector" ? vectorMask(source) : source, context, depth + 1, scope, sampling);
|
|
656
725
|
if (isMask) {
|
|
657
726
|
// Removing a hidden matte also removes its masking operation.
|
|
658
727
|
if (evaluated.length === 0) continue;
|
|
@@ -697,7 +766,7 @@ function visit(
|
|
|
697
766
|
rounding: number(props.rounding ?? 0, "Group.rounding", 0),
|
|
698
767
|
clip: props.clip !== false,
|
|
699
768
|
...(props.clip === true ? { clipEffects: true } : {}),
|
|
700
|
-
children: isolateGroups(sources ? children : visit(props.children, context, depth + 1, scope)),
|
|
769
|
+
children: isolateGroups(sources ? children : visit(props.children, context, depth + 1, scope, sampling)),
|
|
701
770
|
...(mask && maskIndex >= 0 ? {mask:{index:maskIndex,mode:mask.mode,invert:mask.invert}} : {}),
|
|
702
771
|
};
|
|
703
772
|
if (props.solo) soloGroups.add(node);
|
|
@@ -738,6 +807,7 @@ function visit(
|
|
|
738
807
|
type,
|
|
739
808
|
[
|
|
740
809
|
"src",
|
|
810
|
+
...(type === "video" ? ["originalSrc"] : []),
|
|
741
811
|
...(visual ? ["width", "height", "fit", "rounding"] : []),
|
|
742
812
|
...(timed
|
|
743
813
|
? ["start", "duration", "trimIn", "playbackRate", "volume"]
|
|
@@ -757,6 +827,12 @@ function visit(
|
|
|
757
827
|
src: props.src,
|
|
758
828
|
...(assetSource("src") ? { sourceFile: assetSource("src") } : {}),
|
|
759
829
|
};
|
|
830
|
+
if (type === "video" && props.originalSrc !== undefined) {
|
|
831
|
+
if (typeof props.originalSrc !== "string" || !props.originalSrc.trim() || /^[a-z]+:|[\x00-\x1f]/i.test(props.originalSrc))
|
|
832
|
+
throw new Error("Video.originalSrc: expected a local file path");
|
|
833
|
+
node.originalSrc = props.originalSrc;
|
|
834
|
+
node.originalSourceFile = assetSource("originalSrc") ?? child.sourceFile;
|
|
835
|
+
}
|
|
760
836
|
if (visual)
|
|
761
837
|
Object.assign(node, {
|
|
762
838
|
width: positive(props.width, `${type}.width`),
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// Generated by scripts/sync-film.mjs; do not edit.
|
|
2
|
+
export const FILM_STOCKS = [{"number":1,"id":"stock/Vision3/Default/50D.fbfilmneg","hash":"1bec2446ee43b88c53f2","sha256":"ddecdecdb915dfea695ce91245e6a40f0b5a0232e7719be0b59d9f6cb3a70b2a","kind":"stock","collection":"motion picture","group":"","label":"50d","tables":{"logc4":{"hash":"1bec2446ee43b88c53f2-logc4","sha256":"1460c599d4d36fc3849c31762d6a45f18a5e24cf1cae566e11d2c26ceeee4267"},"slog3cine":{"hash":"1bec2446ee43b88c53f2-slog3cine","sha256":"8f535c0b4ccd76bf0ee272b4b1e77b2c30053ba2cecb7b5d7a1f2cfe0e051529"}}},{"number":2,"id":"stock/Vision3/Default/200T.fbfilmneg","hash":"ecc51cfd5a5cede9cbae","sha256":"3f619d5aa84d49ededf451721f716aa6f5c8bfdc57bbbe6e3cc9bcf62d276749","kind":"stock","collection":"motion picture","group":"","label":"200t","tables":{"logc4":{"hash":"ecc51cfd5a5cede9cbae-logc4","sha256":"a9ed9ea417cf51e92d46500c2c7d51876dee9e475430a2c06cc76c1723ada7ec"},"slog3cine":{"hash":"ecc51cfd5a5cede9cbae-slog3cine","sha256":"0c78e273ff7cfcbade740c4477bc1c138b88fcf1410db65c092ec32bbde59fbf"}}},{"number":3,"id":"stock/Vision3/Default/250D.fbfilmneg","hash":"20ca38314cfd587b78fc","sha256":"20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811","kind":"stock","collection":"motion picture","group":"","label":"250d","tables":{"logc4":{"hash":"20ca38314cfd587b78fc-logc4","sha256":"a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"},"slog3cine":{"hash":"20ca38314cfd587b78fc-slog3cine","sha256":"01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"}}},{"number":4,"id":"stock/Vision3/Default/500T.fbfilmneg","hash":"f10310ad81957c25fc48","sha256":"35101b3d7bbdf914b940aacaedc7aeab2755080147f144444c78437f8788c033","kind":"stock","collection":"motion picture","group":"","label":"500t","tables":{"logc4":{"hash":"f10310ad81957c25fc48-logc4","sha256":"55592fe58ff6f4ac4e6151ac293198bcf9e41079e10780872ff4bf1220a8e2f0"},"slog3cine":{"hash":"f10310ad81957c25fc48-slog3cine","sha256":"c8a4dd3b841e15630d0267a96afeeb821102ac9b2e5a20dc1e9a5ec53d707725"}}},{"number":5,"id":"stock/Expired/Vision2/Vision2 50D - 5201.fbfilmneg","hash":"7ddd94e5d0799d57d43c","sha256":"396988be0b3e7ce76a8dd12d998f6e681cc43c5bcc8caf34195c11e653c77745","kind":"stock","collection":"discontinued","group":"","label":"vision2 50d","tables":{"logc4":{"hash":"7ddd94e5d0799d57d43c-logc4","sha256":"5d4ab49669ef118375aa741b46be69a91ddd44fd4a422ffb864cb4f28c452b06"},"slog3cine":{"hash":"7ddd94e5d0799d57d43c-slog3cine","sha256":"db5cedad66e2909127c6c1f15d82fbc89ea3280f7ce9ef6bf9a177ae2102d4d1"}}},{"number":6,"id":"stock/Expired/Vision2/Vision2 200T - 5217.fbfilmneg","hash":"4580449bf3580df15a24","sha256":"1c1f2014d17bf771d2a6f00bf8f59b5f10d1f236566bccc3c8dd45f54e3ad360","kind":"stock","collection":"discontinued","group":"","label":"vision2 200t","tables":{"logc4":{"hash":"4580449bf3580df15a24-logc4","sha256":"3f3a5594427517540a19236f93714471307976951bceac909ea92387dabd9399"},"slog3cine":{"hash":"4580449bf3580df15a24-slog3cine","sha256":"2b35ad024b27259ee9f7c0ca954e2bca5ef1579527138a53ba59a65399945bd5"}}},{"number":7,"id":"stock/Expired/Vision2/Vision2 250D - 5205.fbfilmneg","hash":"219833e83f5b03cca36c","sha256":"be5dc3517c210da399293202de6a2296d2306c98afa4394af0b639c7bc97d858","kind":"stock","collection":"discontinued","group":"","label":"vision2 250d","tables":{"logc4":{"hash":"219833e83f5b03cca36c-logc4","sha256":"0776f6c9b404bb79f7bf47bb4629c29b73ef944bf9e8eb7773f0b2411f02a5ca"},"slog3cine":{"hash":"219833e83f5b03cca36c-slog3cine","sha256":"993769f0c92debbd346406054afda65cfe220f1680186cb1b007b7031de71730"}}},{"number":8,"id":"stock/Expired/Vision2/Vision2 500T - 5260 5218.fbfilmneg","hash":"bea529b58c1d7367060b","sha256":"1894699667db0e7ae7902a0bdf3cf63d422c9600a5be18c3160b371417c03e8d","kind":"stock","collection":"discontinued","group":"","label":"vision2 500t","tables":{"logc4":{"hash":"bea529b58c1d7367060b-logc4","sha256":"08a7de80a3d436b78cc36250fd7ac4c929050b3738e6826dbaa4024bf4aa6367"},"slog3cine":{"hash":"bea529b58c1d7367060b-slog3cine","sha256":"168857a78f1c0c4c17745b8602108407fc2e307ece0f1486d4416a9090946ff3"}}},{"number":9,"id":"stock/Expired/Vision/Vision 250D - 5246.fbfilmneg","hash":"5dbbbe0bc3402ac432ef","sha256":"55ca19c348d6c8c6adfb07f6ccfd9e1891f06c6373fffe2964b45a0828872adc","kind":"stock","collection":"discontinued","group":"","label":"vision 250d","tables":{"logc4":{"hash":"5dbbbe0bc3402ac432ef-logc4","sha256":"1eefbb8c9b168f76c2ca6838e13480b41781200a91040dbb40c20db94b4f9b02"},"slog3cine":{"hash":"5dbbbe0bc3402ac432ef-slog3cine","sha256":"93870ed95db1793d22db1fbd3e92572d4728e7251de57851138d78e9859fdeae"}}},{"number":10,"id":"stock/Expired/Vision/Vision 500T - 5279.fbfilmneg","hash":"651bc5d68b55c63d2209","sha256":"ebc7605bc69f3843275c4441eab2149d8698a75f4d5b29249df5f00bb4a4b216","kind":"stock","collection":"discontinued","group":"","label":"vision 500t","tables":{"logc4":{"hash":"651bc5d68b55c63d2209-logc4","sha256":"7f8fc4223eb54ffbb492bdaa8d80adbca125e82f4e67f867c443ebd6d9b6ac32"},"slog3cine":{"hash":"651bc5d68b55c63d2209-slog3cine","sha256":"cbbdefec443780cf601796a6e766145368fc5d02ad8ee7deb86c7c5885006748"}}},{"number":11,"id":"stock/Expired/EXR/EXR 100T - 5248.fbfilmneg","hash":"b408aaad6a6b268cc31f","sha256":"c89b9e24496d2cfb637829bf7441170901526df8fbecc0feb0872be1b1b0bcca","kind":"stock","collection":"discontinued","group":"","label":"exr 100t","tables":{"logc4":{"hash":"b408aaad6a6b268cc31f-logc4","sha256":"5416b18636ee7a0f24d6dd59e996b6bdf17f8ded5649b1df07cc6bb8d10b612f"},"slog3cine":{"hash":"b408aaad6a6b268cc31f-slog3cine","sha256":"32d474f721c26c74ab9c6b042fc19da9f4e1254cfe2fb986376ead354c4413c4"}}},{"number":12,"id":"stock/Expired/EXR/EXR 50D - 5245.fbfilmneg","hash":"dbfcf75f65364f300865","sha256":"ab35fa37e82dd216c772f7f1c6621c55d2360e6a22bfbf81b626f6ef19a7c316","kind":"stock","collection":"discontinued","group":"","label":"exr 50d","tables":{"logc4":{"hash":"dbfcf75f65364f300865-logc4","sha256":"6244d992d217cf445a755d6960aaef7d12c571c82fc891d3f151dda1958c3d79"},"slog3cine":{"hash":"dbfcf75f65364f300865-slog3cine","sha256":"d69e50ecbe59f222a4c0747c1f3b014b7aa1acae2de19190b7a08508eac35c7b"}}},{"number":13,"id":"stock/Expired/EXR/EXR 500T - 5298.fbfilmneg","hash":"b48affdfe23da47091f9","sha256":"30b7cd4e6e280844101034e9a7e40c521541c78e2c3daf8a9e52e778846ac941","kind":"stock","collection":"discontinued","group":"","label":"exr 500t","tables":{"logc4":{"hash":"b48affdfe23da47091f9-logc4","sha256":"54004242f20d22bc68622e1be479fcc41685a4137fa0f46c7e4ba41122d48f6f"},"slog3cine":{"hash":"b48affdfe23da47091f9-slog3cine","sha256":"4c0195829c042b101aed9c26f601d4f09f2104654101272408c62a8d680b9ca6"}}},{"number":14,"id":"stock/Expired/Eterna/Eterna 250D - 8563.fbfilmneg","hash":"ef47355ccc6c71d56c07","sha256":"d0293c0409df012218f53cec44332680e5544cea8f9306596598cd8c7a9ac6b4","kind":"stock","collection":"discontinued","group":"","label":"eterna 250d","tables":{"logc4":{"hash":"ef47355ccc6c71d56c07-logc4","sha256":"85328a7b6dc2b5746ba70101d063be859fa791347b568e719fb18b46d6e75d61"},"slog3cine":{"hash":"ef47355ccc6c71d56c07-slog3cine","sha256":"a8e5fedbd3801a857ee23f9eac28c76f13ce85b8633a6d136eec15be9291ef76"}}},{"number":15,"id":"stock/Expired/Eterna/Eterna 500T - 8573.fbfilmneg","hash":"03e20bcdbf816cbc2705","sha256":"267c62f7ca7a02dc9e917e6ead14f30600fc0868565fb004cc8c69ca75abd8c8","kind":"stock","collection":"discontinued","group":"","label":"eterna 500t","tables":{"logc4":{"hash":"03e20bcdbf816cbc2705-logc4","sha256":"3c4fb57d4a35addd93c7c3f1877e9b45aa40219e6976db22afcba8cd23921de8"},"slog3cine":{"hash":"03e20bcdbf816cbc2705-slog3cine","sha256":"9c1db859909ae4f100d52aecbf2f3a7b896c7db441bda24b70da13c67024d703"}}},{"number":16,"id":"stock/Expired/Eterna Vivid/Eterna Vivid 250D - 8546.fbfilmneg","hash":"19e71cdeaec2f28d22ed","sha256":"bfe8e64339b9b9b8bf43d94dda6c92889c818d9d7b435903a87c0ae4cc80d741","kind":"stock","collection":"discontinued","group":"","label":"eterna vivid 250d","tables":{"logc4":{"hash":"19e71cdeaec2f28d22ed-logc4","sha256":"a2021b3cf8df60d5cd5aa194aa941f0c88ed0551065929d2989874da3d63156c"},"slog3cine":{"hash":"19e71cdeaec2f28d22ed-slog3cine","sha256":"536e038df383269259af2c757bfeca5899c9b037d7182663383eb8c34d7e286c"}}},{"number":17,"id":"stock/Expired/Super-F/Super-F 64D - 8621.fbfilmneg","hash":"e9a41978b31155132d19","sha256":"2c240c8049050818df417169f422a4cf4d88734103ddaab23f7550d409327b64","kind":"stock","collection":"discontinued","group":"","label":"super-f 64d","tables":{"logc4":{"hash":"e9a41978b31155132d19-logc4","sha256":"74ee43f73c8c961022502325542e3489a4767da1d8c640f744515acba70582f3"},"slog3cine":{"hash":"e9a41978b31155132d19-slog3cine","sha256":"6ffde4f76a9a6e207946610fc44702927d1af53c3780c291c9631e3b04d3f803"}}},{"number":18,"id":"stock/Expired/Other/Reala 500D - 8592.fbfilmneg","hash":"b5a5b1d2f15133dbbd40","sha256":"fcb024fd39012665dde3f2cedfce48fbb686863d3f4f7d02e334e3d5bfe37f88","kind":"stock","collection":"discontinued","group":"","label":"reala 500d","tables":{"logc4":{"hash":"b5a5b1d2f15133dbbd40-logc4","sha256":"d4b026a232a67622e5d7a75f3d71d1cfa5f890e2c5b7457bc97027e822649538"},"slog3cine":{"hash":"b5a5b1d2f15133dbbd40-slog3cine","sha256":"fef3e60b41ba6b7246ac4d4f6afd8f370f27e2cc8bb8000a7ea1f782b12e0311"}}},{"number":19,"id":"stock/Expired/Other/Plus-X - 5231.fbfilmneg","hash":"01646d0ebdea130feeb0","sha256":"95df160d3412192d6d840ae9a79008ad0880d60772a069b1a2c730886324fd63","kind":"stock","collection":"discontinued","group":"","label":"plus-x","tables":{"logc4":{"hash":"01646d0ebdea130feeb0-logc4","sha256":"2edfcfe37f61ecd3aa471628fc730b6bf76b7c536e346ea3680730c57f1de71f"},"slog3cine":{"hash":"01646d0ebdea130feeb0-slog3cine","sha256":"97476d0a31a72eb7b5f08f79100f7442f243726b16d9d3879d87c3337bd65b01"}}},{"number":20,"id":"stock/EktachromeCross/Default/Ektachrome.fbfilmneg","hash":"ea4a6fc70e60b72de85d","sha256":"682527e690a30717568a08b588a1ae13ec09b39b1b9c2904029cf0be0b706b3b","kind":"stock","collection":"lab process","group":"","label":"ektachrome cross process","tables":{"logc4":{"hash":"ea4a6fc70e60b72de85d-logc4","sha256":"6dfae05dea7b59c73ec19b73c4246fc9a1affb598eae92e207011778edf142fe"},"slog3cine":{"hash":"ea4a6fc70e60b72de85d-slog3cine","sha256":"b7163211d24ca6cf130b2ca23eca0bdc6f7e72784ce0d17767eca1f5a50f03c3"}}},{"number":21,"id":"stock/BleachBypass/Default/Bleach Bypass Full.fbfilmneg","hash":"ebf8e027214208da802d","sha256":"bc69f0ef78bba9221302f73c0dbdd956c775e40bb5aa65833159d896756ad282","kind":"stock","collection":"lab process","group":"","label":"bleach bypass full","tables":{"logc4":{"hash":"ebf8e027214208da802d-logc4","sha256":"e14326889b137b2cdede1ababe0bbcf41a35900ff842460b5a47ca3e75bdf92e"},"slog3cine":{"hash":"ebf8e027214208da802d-slog3cine","sha256":"e0909c31f58a340e1d3c2987d795f6345ffb79223bb3d032efc5c1ec30720a47"}}},{"number":22,"id":"stock/BleachBypass/Default/Bleach Bypass Half.fbfilmneg","hash":"33279d836190f8d0ac43","sha256":"9ae0fa355f54cc772368d28cdc1ba342388d5855297d5bcf0f6b058bbe36eb8d","kind":"stock","collection":"lab process","group":"","label":"bleach bypass 50%","tables":{"logc4":{"hash":"33279d836190f8d0ac43-logc4","sha256":"632993d0b36a6320172d4b19a109ce90450b8cd3d79d575850fc4e2f9af7bfef"},"slog3cine":{"hash":"33279d836190f8d0ac43-slog3cine","sha256":"3ff5b18d862575c8203d49a93edf04af53b4e6b56b651845e582ceb27705cbdb"}}},{"number":23,"id":"stock/BleachBypass/Default/Bleach Bypass 30%.fbfilmneg","hash":"362fe9e15e5b3e8a3712","sha256":"efda5afdd954b7a0dc51edbf47e7bc1c03b5f98153f947872a6ec7f111810186","kind":"stock","collection":"lab process","group":"","label":"bleach bypass 30%","tables":{"logc4":{"hash":"362fe9e15e5b3e8a3712-logc4","sha256":"ad78fd6b96ee1375d45dff4fc0fb6aaee067714fe0635cec7dc2c379127dddac"},"slog3cine":{"hash":"362fe9e15e5b3e8a3712-slog3cine","sha256":"79234637f94187208a77aa9f4d7dfe8e04b50a44cba8a6912dc4fec923e602e3"}}},{"number":24,"id":"stock/PhotoColor/Portrait/Pro 400H.fbfilmneg","hash":"9702f45a667b36529557","sha256":"6780a9fa3b04624eaaed4e2a9c5f55654fda4d7999663fd5c4c5b217ad90bc9b","kind":"stock","collection":"color negative","group":"portrait","label":"pro 400h","tables":{"logc4":{"hash":"9702f45a667b36529557-logc4","sha256":"6472860b63370f6627ca3d928b7b1089631d59a94f2ba6e912b7212c8063700a"},"slog3cine":{"hash":"9702f45a667b36529557-slog3cine","sha256":"db42b57a3a401eae0a994290ab77970924c3a99456c96a2c7ca2b58e7db63337"}}},{"number":25,"id":"stock/PhotoColor/Portrait/Portra 160.fbfilmneg","hash":"1c7192956b1166b7dc57","sha256":"8ea8c14ba4e1007883cf721af01945acc1e9b895c3d73849258f1bedbcdfbfc4","kind":"stock","collection":"color negative","group":"portrait","label":"portra 160","tables":{"logc4":{"hash":"1c7192956b1166b7dc57-logc4","sha256":"2128360480122aece81f0042d1d5ef7de07a4044027d5527074cb5031f6db050"},"slog3cine":{"hash":"1c7192956b1166b7dc57-slog3cine","sha256":"517456d35e73cbbfb680ad65c81fae66221ee1777d014f45a57d6c28caae3cf5"}}},{"number":26,"id":"stock/PhotoColor/Portrait/Portra 400.fbfilmneg","hash":"307d051c9f3a84b9cd47","sha256":"560a83d5a265933aab77d1834b12741d1d3602f686fcf0e26739a5abe209f1af","kind":"stock","collection":"color negative","group":"portrait","label":"portra 400","tables":{"logc4":{"hash":"307d051c9f3a84b9cd47-logc4","sha256":"ad235ea9c8b5d5f60756ff021d11c1bd16d3ffa9755ae4f008759dd505d315d5"},"slog3cine":{"hash":"307d051c9f3a84b9cd47-slog3cine","sha256":"8531cf2e1e42931ac1c46c4910fd7dc006ce6805716fa19ace268831b9070204"}}},{"number":27,"id":"stock/PhotoColor/Portrait/Portra 800.fbfilmneg","hash":"50617f9a14935e1dc16a","sha256":"3ae27d6e659eabc89f1eb56c7c30f6afa43dc92c9798c1edcc3eb33e3a2a2cea","kind":"stock","collection":"color negative","group":"portrait","label":"portra 800","tables":{"logc4":{"hash":"50617f9a14935e1dc16a-logc4","sha256":"fdabfb438877c1c24d1d837050793c34cbe8b7c32f8393e58e4d4db85642ae97"},"slog3cine":{"hash":"50617f9a14935e1dc16a-slog3cine","sha256":"c9478032369a0522aee17cd53c0ff411b22274fe1eae3c0fd64a8939296df373"}}},{"number":28,"id":"stock/PhotoColor/Classic/Superia 400.fbfilmneg","hash":"2bf389827db8fc7409b2","sha256":"e05e8b7de7e3c5b2bca868cf55f5357ba164e2a0cb92f231e1816ac78d4204d8","kind":"stock","collection":"color negative","group":"classic","label":"superia 400","tables":{"logc4":{"hash":"2bf389827db8fc7409b2-logc4","sha256":"58e8b1aa84365274e80a31882b4c8369b43708f38b6a1df18d286c0aedda71a0"},"slog3cine":{"hash":"2bf389827db8fc7409b2-slog3cine","sha256":"54a109b35168024a2e603eaf04a7bb851520e8dade1a8d0c565567df69132263"}}},{"number":29,"id":"stock/PhotoColor/Classic/ColorPlus 200.fbfilmneg","hash":"0bf9634cd9251686f2f1","sha256":"dd24df8d9f1b90c021fef1ad4064351a07bea394c1ae2a5f35e8d37219418400","kind":"stock","collection":"color negative","group":"classic","label":"colorplus 200","tables":{"logc4":{"hash":"0bf9634cd9251686f2f1-logc4","sha256":"bc9932eedc61df8af664831228dfe9217065a9f734fc99bb4097317dcec83a12"},"slog3cine":{"hash":"0bf9634cd9251686f2f1-slog3cine","sha256":"47f03ccdb9e440e95993f98542d3cca6e7701b51c5db807647b54dde67213ef0"}}},{"number":30,"id":"stock/PhotoColor/Classic/Gold 200.fbfilmneg","hash":"15f259e9968a7c0f40c5","sha256":"5639e09392aa3edc58151cab69d7371ffd38c1bccf12e808716b1ceee4583e18","kind":"stock","collection":"color negative","group":"classic","label":"gold 200","tables":{"logc4":{"hash":"15f259e9968a7c0f40c5-logc4","sha256":"9ada80fd0827c34c9101aea7be5305dd944afe52e824183c988f13850dc8cb1a"},"slog3cine":{"hash":"15f259e9968a7c0f40c5-slog3cine","sha256":"af1b22b0bdadf271477f597a5d61bdf2c54c4f5580be7b418f233beaa53ff366"}}},{"number":31,"id":"stock/PhotoColor/Classic/UltraMax 400.fbfilmneg","hash":"0f1546383584ffbf0c6d","sha256":"581336e3b530df7534468f4db97746b3b5cf16ff9b9ff8fce09f6f7e6bf52794","kind":"stock","collection":"color negative","group":"classic","label":"ultramax 400","tables":{"logc4":{"hash":"0f1546383584ffbf0c6d-logc4","sha256":"60da1e43f7c1bdd8d1960369326c788696049a206cf5105cad455aadb3784e98"},"slog3cine":{"hash":"0f1546383584ffbf0c6d-slog3cine","sha256":"ae9fc1afb3356465fbe7f808187dbaec1b0a80b1d2f5e9c217af09aeda8dbc2e"}}},{"number":32,"id":"stock/PhotoColor/Classic/Fujicolor 200.fbfilmneg","hash":"614d18ad0fa6cbb3b310","sha256":"1827564e621ab41a6cc573fbe6e8e44a506ef4f4f9f22b9858bcd2866f898f5e","kind":"stock","collection":"color negative","group":"classic","label":"fujicolor 200","tables":{"logc4":{"hash":"614d18ad0fa6cbb3b310-logc4","sha256":"e4e949e1e6a94238d4424b0ab66cc3f7747534a2cb37c41226b8b9b64325de4e"},"slog3cine":{"hash":"614d18ad0fa6cbb3b310-slog3cine","sha256":"8e0e999a508e9e7c388c3339fd36e805a8d76d0163b5f3140b713f90130407fa"}}},{"number":33,"id":"stock/PhotoColor/Vivid/Ektar 100.fbfilmneg","hash":"37b39e23eeed891943a2","sha256":"6d917845ad42af0069a90c9411ad92e888e801672d7808a60368177ab05004f8","kind":"stock","collection":"color negative","group":"vivid","label":"ektar 100","tables":{"logc4":{"hash":"37b39e23eeed891943a2-logc4","sha256":"b9e1c78fb15f5cfdae9fe3a3dd88c485e36df3a14724deb56f3c98eebb849a6e"},"slog3cine":{"hash":"37b39e23eeed891943a2-slog3cine","sha256":"8d0676ddc23c99cc0a709e16e8c6bfcc27084fbf15f9748674997dd9c553f23e"}}},{"number":34,"id":"stock/PhotoColor/Vivid/Lomo Color 100.fbfilmneg","hash":"28c58b21901ffafb8026","sha256":"18e50eb5f6e0c820be78d434776d57d29c979493d6b054298b5a856391db304d","kind":"stock","collection":"color negative","group":"vivid","label":"lomo color 100","tables":{"logc4":{"hash":"28c58b21901ffafb8026-logc4","sha256":"1cb3597192dc02aaeb3b6d2f18cb3053786acc7ed006854e817b155e3506975b"},"slog3cine":{"hash":"28c58b21901ffafb8026-slog3cine","sha256":"73c928d02509d1f1d1efab6dc32b924e0854db599c2f4d500c9f27dcb90ffb94"}}},{"number":35,"id":"stock/PhotoColor/Vivid/Aerocolor 100.fbfilmneg","hash":"a673d3c69731d85b86c4","sha256":"828872cf3851e56027d84381c7aebd3c4f3ec4fe6bb083e90d89ee13d8271623","kind":"stock","collection":"color negative","group":"vivid","label":"aerocolor 100","tables":{"logc4":{"hash":"a673d3c69731d85b86c4-logc4","sha256":"449f3b65f8618469ed9e8b2cd51e46b758e95f77d54d61742d2ce4cd61e18e54"},"slog3cine":{"hash":"a673d3c69731d85b86c4-slog3cine","sha256":"ef86ceab34e252299e0897b0220c5d8b7ac4f042529ad57cb8e456bae6a03c93"}}},{"number":36,"id":"stock/PhotoColor/Vivid/Phoenix.fbfilmneg","hash":"e7d7536754674c35aa49","sha256":"1cabbd28e88f4c8bee4e0011232d6a217c870848476c702c0518a8ac46d9682d","kind":"stock","collection":"color negative","group":"vivid","label":"phoenix","tables":{"logc4":{"hash":"e7d7536754674c35aa49-logc4","sha256":"f0d46d982eb5488daf6b92e3d021053466ac063cf384141bcba90790c8428715"},"slog3cine":{"hash":"e7d7536754674c35aa49-slog3cine","sha256":"383720b40b78db0de52b70caa7959ebdf34f2044c5017abf4e32dedacc25a161"}}},{"number":37,"id":"stock/PhotoColor/Cine/CineStill 800T.fbfilmneg","hash":"0b8e1ff254ee8e2a45c1","sha256":"6732af8710649bb4887110caa4fe552e83fa61dc4a1b1e19a7794181416b0f1a","kind":"stock","collection":"color negative","group":"cinestill","label":"cinestill 800t","tables":{"logc4":{"hash":"0b8e1ff254ee8e2a45c1-logc4","sha256":"77ff93b03b695ab2dc588605cbe41604a7a7deaaa85b6b1c53eead74dd535f70"},"slog3cine":{"hash":"0b8e1ff254ee8e2a45c1-slog3cine","sha256":"fa7bc0eef6a4b68c3c76ca17fbd5d117be5134f4d3eea9f148af0162b2855368"}}},{"number":38,"id":"stock/PhotoColor/Cine/CineStill 400D.fbfilmneg","hash":"069f33c0011b2c68718a","sha256":"b451c0a3f32b7d32ef409cffb511db023223beb602a60e6a6caff1c4ac1ea490","kind":"stock","collection":"color negative","group":"cinestill","label":"cinestill 400d","tables":{"logc4":{"hash":"069f33c0011b2c68718a-logc4","sha256":"63ee60ec1749e781785b679b33986c0be287b2198980bef946dfc6c5389dede8"},"slog3cine":{"hash":"069f33c0011b2c68718a-slog3cine","sha256":"2de7348f29263ba2428789a421cc9fd1cf6e4ab9ca381bde0c2d69981c45acc0"}}},{"number":39,"id":"stock/PhotoColor/Cine/CineStill 50D.fbfilmneg","hash":"8cf8926463e3e909a835","sha256":"a681cd2f758ec66171a0b8494ed4f5d496599e69da7cc49103868efbf806113a","kind":"stock","collection":"color negative","group":"cinestill","label":"cinestill 50d","tables":{"logc4":{"hash":"8cf8926463e3e909a835-logc4","sha256":"ee105a5a5cfbef1a10b065092ffd630b764067e70a0548866a7d0cefdf06aa7c"},"slog3cine":{"hash":"8cf8926463e3e909a835-slog3cine","sha256":"1fb2f9bc4aa487e0575637b005b685f0d87ab3a6a1e16d1491b284bd50f8863f"}}},{"number":40,"id":"stock/PhotoColor/Stylized/Ektachrome C41.fbfilmneg","hash":"b0402bf8f5591e219177","sha256":"2616ac31325d743c0212edfe81fe01ffb61a173db393baacfc7ef4053ffdafa9","kind":"stock","collection":"color negative","group":"specialty","label":"ektachrome c41","tables":{"logc4":{"hash":"b0402bf8f5591e219177-logc4","sha256":"94e041fb3c7face91aa01f3601c4996dc9fe57284f1af3b3014bfc2eff46871e"},"slog3cine":{"hash":"b0402bf8f5591e219177-slog3cine","sha256":"3fa275094cf2349b51351e1393dd1a1ceb87304fc2715e3044c7c4f1604d2d39"}}},{"number":41,"id":"stock/PhotoColor/Stylized/Purple XR.fbfilmneg","hash":"fc75a210efb408479f7c","sha256":"025d1a543fe3bb58ea9488ca0504bb544ec4af55769066a5b06979ddd5e5ec7e","kind":"stock","collection":"color negative","group":"specialty","label":"purple xr","tables":{"logc4":{"hash":"fc75a210efb408479f7c-logc4","sha256":"373e08ba3c2af5e8a850f8430fc2f91656df2981e20423a2f27e3635a7fdb6c3"},"slog3cine":{"hash":"fc75a210efb408479f7c-slog3cine","sha256":"f0b5ebcac3206c4235e45be5eeef099cf1e61edca8b809dfce6d18cbcc3a604f"}}},{"number":42,"id":"stock/PhotoColor/Stylized/Redscale XR.fbfilmneg","hash":"b478a4b37293e1cd7271","sha256":"78230c65977e7415c914caa1c4f3196b08f8d82be4d45502a31092e1067dd471","kind":"stock","collection":"color negative","group":"specialty","label":"redscale xr","tables":{"logc4":{"hash":"b478a4b37293e1cd7271-logc4","sha256":"8a362587350be2f87f777449fd44816a64f5a5866236b8f1919a9e685270ac36"},"slog3cine":{"hash":"b478a4b37293e1cd7271-slog3cine","sha256":"8cd5ce8f841f901d50b87fde5588fe1c151da5ce7381810b5ea4a382745f2551"}}},{"number":43,"id":"stock/PhotoColor/Stylized/XP2 400.fbfilmneg","hash":"21bc8e616c71bdd3dc26","sha256":"c44c6b2fdd8c6cbeca0c2793d70c07ae2edad1468d548787a1a45f673009eaf6","kind":"stock","collection":"color negative","group":"specialty","label":"xp2 400","tables":{"logc4":{"hash":"21bc8e616c71bdd3dc26-logc4","sha256":"fa2466898ff33948a53624f5b3124f810abf8d3dddb6e2c9f406820150b80453"},"slog3cine":{"hash":"21bc8e616c71bdd3dc26-slog3cine","sha256":"3ee1772a45afd64c91e07ee378ce0c5ea8c48036a50d87e5579e84a696123e0f"}}},{"number":44,"id":"stock/PhotoBW/Classic/HP5 400.fbfilmneg","hash":"14cf96e62ee81f239566","sha256":"be24f71bb06129ab0553cc70b9831b7b16311576d26d6fe26d3b5b3a68d132d7","kind":"stock","collection":"black and white negative","group":"classic","label":"hp5 400","tables":{"logc4":{"hash":"14cf96e62ee81f239566-logc4","sha256":"a73c789501877a27a9c0ed42a62b1f5a1b40fea3bb8e0829bef5419429457642"},"slog3cine":{"hash":"14cf96e62ee81f239566-slog3cine","sha256":"b66dcb2d948d919eb31d58a5b0de1a9388fbc5d774261ba051b33110b6143b6e"}}},{"number":45,"id":"stock/PhotoBW/Classic/Delta 400.fbfilmneg","hash":"7f87b4fbfed571ae7362","sha256":"03fc29256153562a77243787c8220b7454a97b2c4f528cd81d64fc6570a9dd80","kind":"stock","collection":"black and white negative","group":"classic","label":"delta 400","tables":{"logc4":{"hash":"7f87b4fbfed571ae7362-logc4","sha256":"c7588b4c108a6bd168f8f0dffdf4ff408b7b9d090f12ee305cfd982c9da9f5c7"},"slog3cine":{"hash":"7f87b4fbfed571ae7362-slog3cine","sha256":"fee7f970c5d007acd33b3cdf5bb909d3da1f9edd144ff7bff70d42d742345091"}}},{"number":46,"id":"stock/PhotoBW/Classic/T-MAX 400.fbfilmneg","hash":"f5ba00a6e5039e797f4c","sha256":"28a7a45815962a43997cd77ccbde1322f75c30d4727cda74f8e20cadeb10e97d","kind":"stock","collection":"black and white negative","group":"classic","label":"t-max 400","tables":{"logc4":{"hash":"f5ba00a6e5039e797f4c-logc4","sha256":"d43d7aee516569f54c5853ea6af6d27604ee107f9368af389a1e41edf81d5ea8"},"slog3cine":{"hash":"f5ba00a6e5039e797f4c-slog3cine","sha256":"5122aaa711ed16d99d904173cb7489fe5dd10af2cd98eee8e719206d5cd0ef84"}}},{"number":47,"id":"stock/PhotoBW/Classic/Tri-X 400.fbfilmneg","hash":"ed440fc1337cdfdc86e3","sha256":"55702591f916cec4bc2ca90a76a52996eae449b84937f161f7f91080d311223c","kind":"stock","collection":"black and white negative","group":"classic","label":"tri-x 400","tables":{"logc4":{"hash":"ed440fc1337cdfdc86e3-logc4","sha256":"cbbc87cc7829d04d00b60a75bbbff66226c2051f2746b83e72c4cc6f33fa2044"},"slog3cine":{"hash":"ed440fc1337cdfdc86e3-slog3cine","sha256":"66a7e7fb3649918dd77492369ed5f657bb8ca35e50ddfdf4efab0e930f83e166"}}},{"number":48,"id":"stock/PhotoBW/Retro/Fomapan 400.fbfilmneg","hash":"0bb5ef0935f2d6fb31d2","sha256":"fbc0c0e6db037c58b7dd5cd52c4836c1fb7bd9ccd77293dc9d49c30fc69a8e9a","kind":"stock","collection":"black and white negative","group":"retro","label":"fomapan 400","tables":{"logc4":{"hash":"0bb5ef0935f2d6fb31d2-logc4","sha256":"b9989889e9be17ad1619acfa68d0fe2e2d90a727123b825d074e57c8918f5686"},"slog3cine":{"hash":"0bb5ef0935f2d6fb31d2-slog3cine","sha256":"b5f49e0a48f59512a50ec7db512f164dc5667b96b3598cb8a4f561ed1da0dbe7"}}},{"number":49,"id":"stock/PhotoBW/High ISO/T-MAX 3200.fbfilmneg","hash":"1571a8b82ac80b2bf7ff","sha256":"95da1d2edddf50bc8698b09f212c19c297cf36a8304e7c90c9e2be85f2cce8bd","kind":"stock","collection":"black and white negative","group":"fast","label":"t-max 3200","tables":{"logc4":{"hash":"1571a8b82ac80b2bf7ff-logc4","sha256":"ecfbbd8b79983078cb853574b9264597bd2f7cc8f446ab8a4507ce5aadaa9095"},"slog3cine":{"hash":"1571a8b82ac80b2bf7ff-slog3cine","sha256":"de9fe45107208cf18db3108470b81e74c06354dac0db624066800e06af3aea4f"}}},{"number":50,"id":"stock/PhotoBW/High ISO/Delta 3200.fbfilmneg","hash":"4c340b0c7f42d917e66f","sha256":"8295d557f4e4eca9711e21334b83fde2b4b03a2765d1ef23309b6f2a7917a917","kind":"stock","collection":"black and white negative","group":"fast","label":"delta 3200","tables":{"logc4":{"hash":"4c340b0c7f42d917e66f-logc4","sha256":"0450330fe2cf6c85bbb22d5e6d4dea923219a91f8a753317f6f3e234e22dcaa3"},"slog3cine":{"hash":"4c340b0c7f42d917e66f-slog3cine","sha256":"17282b8d8c236a0bcca6d948c0bb211bb4c257a1913201da10283bc179224765"}}},{"number":51,"id":"stock/PhotoBW/Low ISO/Acros 100II.fbfilmneg","hash":"cbd839be59a0a508fb8f","sha256":"cb63d53e511569b86600a08053f0dbf503e0a6d8fd2deeb59d4298e5af96cc1e","kind":"stock","collection":"black and white negative","group":"slow","label":"acros 100ii","tables":{"logc4":{"hash":"cbd839be59a0a508fb8f-logc4","sha256":"9e7612d978dcf69f0b8f516c792da24417d32db52f421c7477caaf69bbbfeded"},"slog3cine":{"hash":"cbd839be59a0a508fb8f-slog3cine","sha256":"4cc57b907828362c0bb59e93660e234318c329e7b831d2f0016ac381397b4324"}}},{"number":52,"id":"stock/PhotoBW/Low ISO/FP4 125.fbfilmneg","hash":"ec4978838b35b503bf0c","sha256":"6e65df53d13f683fbd1fe2c48039252a3b3f6e6175c2155d4ad69f809bf7bfd9","kind":"stock","collection":"black and white negative","group":"slow","label":"fp4 125","tables":{"logc4":{"hash":"ec4978838b35b503bf0c-logc4","sha256":"f10003f5126bac5ae8275a9934c6a19b2ddd8c6de9513006a23456cf32f21d2a"},"slog3cine":{"hash":"ec4978838b35b503bf0c-slog3cine","sha256":"61fcceebd980eff5fc7bc5230d19a3d29bc2c987d3b109099d3231d71b6f512e"}}},{"number":53,"id":"stock/PhotoBW/Low ISO/T-MAX 100.fbfilmneg","hash":"8d4afdf51b4abcc95c69","sha256":"458146bb6a8bf7f0ecec71d28f9254c726560f88e9eca53efaa66cecc900d265","kind":"stock","collection":"black and white negative","group":"slow","label":"t-max 100","tables":{"logc4":{"hash":"8d4afdf51b4abcc95c69-logc4","sha256":"20196bd247cfab9f9e6d9cbb79972650ecfe439fe8de0c08bea56834a7a6f785"},"slog3cine":{"hash":"8d4afdf51b4abcc95c69-slog3cine","sha256":"1cec3a29383a51b914827634cb7265b1f3cb5a654750df1c4fdecea773efc1f4"}}},{"number":54,"id":"stock/PhotoBW/Low ISO/PanF 50.fbfilmneg","hash":"d66760fc9df2eef31948","sha256":"435301549b1f67756fb5c199ba433d103bed9a255c19f9dac95a17658539e522","kind":"stock","collection":"black and white negative","group":"slow","label":"pan f 50","tables":{"logc4":{"hash":"d66760fc9df2eef31948-logc4","sha256":"090407f5d39f3a275a89503aaedaa155061381de63b57041fcfe113216178421"},"slog3cine":{"hash":"d66760fc9df2eef31948-slog3cine","sha256":"c42f69cb8d6989255ffbefc2df46e583aeedf5105af77f2a226ca458864c6ec3"}}},{"number":55,"id":"stock/PhotoBW/Low ISO/CineStill XX 250.fbfilmneg","hash":"93509be7dd8e65c2b385","sha256":"57a95c33826127d995ae1789952dc5c5a7089e69f2f36e429a70e6712e27da56","kind":"stock","collection":"black and white negative","group":"slow","label":"cinestill xx 250","tables":{"logc4":{"hash":"93509be7dd8e65c2b385-logc4","sha256":"b2ea65f23778b570d8e6db3ec96f3a17184d3b38fc2e1f12932c1ca543bafff4"},"slog3cine":{"hash":"93509be7dd8e65c2b385-slog3cine","sha256":"8d5af6e18b8fc41c298a12b43e721a3c3a1a6520ae9d7cf4b60f14c2b362aefa"}}},{"number":56,"id":"stock/PhotoBW/High Contrast/Delta 100.fbfilmneg","hash":"830844c886c0e9bf833d","sha256":"721afdd1bc074111c6ddbde9347bd3698d73046d74613323b6895614f4b5d66b","kind":"stock","collection":"black and white negative","group":"high contrast","label":"delta 100","tables":{"logc4":{"hash":"830844c886c0e9bf833d-logc4","sha256":"d445ef21910889ab36db1313cd5ea4773b735af0e4d129508734db6b9ab7bff6"},"slog3cine":{"hash":"830844c886c0e9bf833d-slog3cine","sha256":"c59104a255b7ad0b10756f31af9126792a5add203eeca0fcbd63cfa82678d001"}}},{"number":57,"id":"stock/PhotoBW/High Contrast/Ortho 80.fbfilmneg","hash":"fe924a23dc3c01cfbfa3","sha256":"d91a0999eb4aa341c152ad989ef7979cefba4276f0436cea63bf9a55496b6373","kind":"stock","collection":"black and white negative","group":"high contrast","label":"ortho 80","tables":{"logc4":{"hash":"fe924a23dc3c01cfbfa3-logc4","sha256":"bba5d2a83f2e7cf0bd9da591b3f594deacb12931bab92ea227db66c72f294aed"},"slog3cine":{"hash":"fe924a23dc3c01cfbfa3-slog3cine","sha256":"6e3120cf56a56b1978087eb29c15c815b30ee33f30bb6a9a6744bb04bd7ac708"}}},{"number":58,"id":"stock/PhotoBW/High Contrast/Monolit 3 (Ortho).fbfilmneg","hash":"0b3664d1c804807a2a86","sha256":"7328dc985f64a6280d70fea7a5e0e22a0dd0ad68218ac718ca4c59bf8d5c255a","kind":"stock","collection":"black and white negative","group":"high contrast","label":"monolit 3 ortho","tables":{"logc4":{"hash":"0b3664d1c804807a2a86-logc4","sha256":"ed98e07b03d98df513a38c9067fa5107c3f3a21e203ded87dc80b21d31667436"},"slog3cine":{"hash":"0b3664d1c804807a2a86-slog3cine","sha256":"abd8e16c295a571af61aa564c0b728041019059fba49a7066168af98c327c9db"}}},{"number":59,"id":"stock/PhotoReversal/Default/Ektachrome 100.fbfilmneg","hash":"df3fa738d2990c6895ac","sha256":"2d647cace6241dacda9262c2218bdd5b5b6f4f2508836c80d3a308e903ce3d30","kind":"stock","collection":"slide film","group":"","label":"ektachrome 100","tables":{"logc4":{"hash":"df3fa738d2990c6895ac-logc4","sha256":"defbdaaacbb12f107c2b23f0cc65900d160279c71c7433a8dd34aeccad778ac2"},"slog3cine":{"hash":"df3fa738d2990c6895ac-slog3cine","sha256":"87b4b1ad94a2b321c6fe297f788515ede8171b72d76d43b0eef31f089e699e59"}}},{"number":60,"id":"stock/PhotoReversal/Default/Velvia 100.fbfilmneg","hash":"6c8e2ae3d5460b683667","sha256":"ccc8c446c5bc5eb0cb85520a7cbe1cb9678c374ebfc19f1ebdd23f13f145e300","kind":"stock","collection":"slide film","group":"","label":"velvia 100","tables":{"logc4":{"hash":"6c8e2ae3d5460b683667-logc4","sha256":"0fbac2290d9968b5365e898404ba826cebb5a7f49aa64f52d347273300fc8b60"},"slog3cine":{"hash":"6c8e2ae3d5460b683667-slog3cine","sha256":"dbb272749e76e10f541f9e20b42103e9d4f46d1ac3ec959b71781379ddeea1d9"}}},{"number":61,"id":"stock/PhotoReversal/Default/Velvia 50.fbfilmneg","hash":"7be6303ad7f58d4d373e","sha256":"d11507543860e9a75a293a85b254926467dd811359081893fab78726aa776f0c","kind":"stock","collection":"slide film","group":"","label":"velvia 50","tables":{"logc4":{"hash":"7be6303ad7f58d4d373e-logc4","sha256":"b31c4bd661051c1ef4a3bd063e29b4256617348dc3f9abb11840b311ea98b9e7"},"slog3cine":{"hash":"7be6303ad7f58d4d373e-slog3cine","sha256":"3834b7ef7f8a2db7c05c073aaa17e2f3d39d3d1d0a5fd84485f095070a8b138a"}}},{"number":62,"id":"stock/PhotoReversal/Default/Provia 100F.fbfilmneg","hash":"0b0c68912f7e500ce1f6","sha256":"63fa05e22bfc0b51e740072761a34474310105f4835dfe5bbc63a5e9dd67545c","kind":"stock","collection":"slide film","group":"","label":"provia 100f","tables":{"logc4":{"hash":"0b0c68912f7e500ce1f6-logc4","sha256":"ad2d4366ff909654c74f87ae53e6d3cd12b2cbd46b0a9aea5289769f361ea3bd"},"slog3cine":{"hash":"0b0c68912f7e500ce1f6-slog3cine","sha256":"ed523ed814a280e7b8a6bfd847a020c5e94a2788727ec4915186feb8c3d838d7"}}},{"number":63,"id":"stock/PhotoReversal/Default/Instax Color.fbfilmneg","hash":"3ccea9e523a25f683011","sha256":"96c7c5ade8b9e41303353903a31aceebc3ba0106d53e1c33d5caace2a8faf2b4","kind":"stock","collection":"slide film","group":"","label":"instax color","tables":{"logc4":{"hash":"3ccea9e523a25f683011-logc4","sha256":"3f698af32a6f5159cdc7b0e474d6f21fbb8d82d3cec9cd1d88e46e72d2343874"},"slog3cine":{"hash":"3ccea9e523a25f683011-slog3cine","sha256":"7485f4e2117bf608fb7486669abeef80fd82e69cc2655ef44bcbfe77ee3e6e30"}}},{"number":64,"id":"stock/PhotoReversal/Default/Instax Monochrome.fbfilmneg","hash":"91377ee33a6217f78b21","sha256":"39b20deccce70a71aef34b6c8bab022ab65434f4930b75ce8567ed20552c1195","kind":"stock","collection":"slide film","group":"","label":"instax monochrome","tables":{"logc4":{"hash":"91377ee33a6217f78b21-logc4","sha256":"0fbdb7ba979642d8120d1e128be595ea324f76b21dc94b41cab5b965e9da9129"},"slog3cine":{"hash":"91377ee33a6217f78b21-slog3cine","sha256":"2089188df2505e26533408861d2d318ad24e27551d183d7dba98f8ec3e00637f"}}},{"number":65,"id":"look/1 Clean & Commercial/video.fblook","hash":"d5f23a096058cd3cc682","sha256":"0fb2859c9d4aa45886725e7851e5187080db2198da76ec44a9ebd7935a24c922","kind":"look","collection":"commercial","group":"","label":"broadcast","tables":{"logc4":{"hash":"d5f23a096058cd3cc682-logc4","sha256":"6447fc2fcef830696e8eb869ad90b5da0b8c23b22144b8917c1f72899f985d13"},"slog3cine":{"hash":"d5f23a096058cd3cc682-slog3cine","sha256":"88efe861f730a7fe3f6ce3d7a4336e48b82ba1a341353952341fdfbb2677a42b"}}},{"number":66,"id":"look/1 Clean & Commercial/cine_like.fblook","hash":"b994bde23b45792033f2","sha256":"ce975f810fa67de34197725a0abad1935a19849296249a9262f0050dd60aca63","kind":"look","collection":"commercial","group":"","label":"cinema","tables":{"logc4":{"hash":"b994bde23b45792033f2-logc4","sha256":"68ff591cd0efd313885e8c1d8e16b7ce7d46f0957fe407c85a24145bafd186a2"},"slog3cine":{"hash":"b994bde23b45792033f2-slog3cine","sha256":"d04a7968a97932f4b5d232ba4e87bbc1e075d0438332f545af1a4cc9b9607d6c"}}},{"number":67,"id":"look/1 Clean & Commercial/telecine_like.fblook","hash":"dafa166447af00368af8","sha256":"a614e60718037a3fa7cab21d0663e54f31480f9339a985361c8f83429ea68fa4","kind":"look","collection":"commercial","group":"","label":"dailies","tables":{"logc4":{"hash":"dafa166447af00368af8-logc4","sha256":"e2d76bccaf1e8873819e497dcd31c59f13d3b6b779b55b38837b8515008f05e3"},"slog3cine":{"hash":"dafa166447af00368af8-slog3cine","sha256":"3bccc724b7bfb1f59556d161a5617d8d6c1212e52a0af36bf1ce64d2e13c97af"}}},{"number":68,"id":"look/1 Clean & Commercial/cine_like_beauty.fblook","hash":"664dcc1e5ff63b7a3602","sha256":"c69f05c7774dc8e22db7741a4cae19ada672e656550e014c3c5bd3f8dc5bfae2","kind":"look","collection":"commercial","group":"","label":"beauty","tables":{"logc4":{"hash":"664dcc1e5ff63b7a3602-logc4","sha256":"98af8cf53cb5d5b5d16b42aef52017c99fe7fa7d15d9bfad5015a7c873243604"},"slog3cine":{"hash":"664dcc1e5ff63b7a3602-slog3cine","sha256":"1c2000e5567bdb056274ef81e6f3103e9adc58027f37d7cc1e8a1c8202ecfa9f"}}},{"number":69,"id":"look/1 Clean & Commercial/cine_like_pop.fblook","hash":"d32059d2b20806c100ce","sha256":"043cb70e56bd75c87f074568d5da9c04f8641d8e79dbd5a3a0dd3bc6d4d65eea","kind":"look","collection":"commercial","group":"","label":"product","tables":{"logc4":{"hash":"d32059d2b20806c100ce-logc4","sha256":"606f83ad1ac58d3196c3755398f5dff0f47b5ce71fd62cd0811120707a72d9be"},"slog3cine":{"hash":"d32059d2b20806c100ce-slog3cine","sha256":"388e426bcea5c52d46e99ccdaa511c1d19700034069f00d43968c554b9241e3e"}}},{"number":70,"id":"look/1 Clean & Commercial/photo_like_pop.fblook","hash":"ec965532f423dcebf743","sha256":"0fbac8c797145f6d06ccca198be486aac883b0528dd46b46352e62351ef6b651","kind":"look","collection":"commercial","group":"","label":"packshot","tables":{"logc4":{"hash":"ec965532f423dcebf743-logc4","sha256":"d501699d3776a72addaff1f3e9d86b2ae29348674ce6d1aa7d2a3e6d7068d9f2"},"slog3cine":{"hash":"ec965532f423dcebf743-slog3cine","sha256":"c3b4759c95b26e0d98646a9a89400cac757f3e35fe4bfe4049b7e489860845a3"}}},{"number":71,"id":"look/2 Idealized 35mm/standard.fblook","hash":"7a74db9c3c4b3bb33627","sha256":"20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811","kind":"look","collection":"35mm negative","group":"","label":"standard","tables":{"logc4":{"hash":"7a74db9c3c4b3bb33627-logc4","sha256":"a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"},"slog3cine":{"hash":"7a74db9c3c4b3bb33627-slog3cine","sha256":"01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"}}},{"number":72,"id":"look/2 Idealized 35mm/extended.fblook","hash":"8620eb33a2388c072557","sha256":"2e606fb12130af9ac49336fd83bbf123577ad3683dc2a7cebf3ca5abf24fb772","kind":"look","collection":"35mm negative","group":"","label":"latitude","tables":{"logc4":{"hash":"8620eb33a2388c072557-logc4","sha256":"2fbac3933b5214d5aa38034c2767a4a7162ee97ea8abc6798b58b000a3deac4e"},"slog3cine":{"hash":"8620eb33a2388c072557-slog3cine","sha256":"eebf4d3d7cd0bdd1dce965fe7da02c685a7c888aa86b4451ad87c93def7eabab"}}},{"number":73,"id":"look/2 Idealized 35mm/rich.fblook","hash":"4da55be1202c100cd58d","sha256":"b2bb8f07d3541ea7172f6fac5bbfbe12f0e041599a7d64f802365589f8f7f102","kind":"look","collection":"35mm negative","group":"","label":"dense","tables":{"logc4":{"hash":"4da55be1202c100cd58d-logc4","sha256":"e5f97cc9c7ece67fdf8f103dbe95cc0e1bcff44d1abeb9d914dd2a3246d4f4c0"},"slog3cine":{"hash":"4da55be1202c100cd58d-slog3cine","sha256":"cbf5d14eee61c9585d949face1c2b1da282cffa66c60b075db1f65d155145d70"}}},{"number":74,"id":"look/2 Idealized 35mm/neutral.fblook","hash":"4b71ed8e0c53638831fd","sha256":"03fc174fbe34b4d9bbc0896db235c507800711bab17d1a06bea486d13543cfe1","kind":"look","collection":"35mm negative","group":"","label":"neutral","tables":{"logc4":{"hash":"4b71ed8e0c53638831fd-logc4","sha256":"4a5bc48f0bb70e2caac2ac9bdf037fae731adf2358f9eb87fb5e87274f40d8ab"},"slog3cine":{"hash":"4b71ed8e0c53638831fd-slog3cine","sha256":"11fd83e422bf130962551bbdc137514cbf94c6fdbefbdb71e8320e9f4455b7ef"}}},{"number":75,"id":"look/2 Idealized 35mm/proimage.fblook","hash":"de8ad75a1a2cae5af794","sha256":"9d40662d863b147c16b765ce344dfd9ef30b3535ecdee46fb805980764761d0e","kind":"look","collection":"35mm negative","group":"","label":"restrained","tables":{"logc4":{"hash":"de8ad75a1a2cae5af794-logc4","sha256":"5e78226b6e20d0f3ca3232f071bae57a76d1fdaf5ece3637a4849b6ff3a15d3a"},"slog3cine":{"hash":"de8ad75a1a2cae5af794-slog3cine","sha256":"fd141039022eaf0680870df7977f2f2f2ca708a00a1bbec37eee5525859b4772"}}},{"number":76,"id":"look/2 Idealized 35mm/reversal.fblook","hash":"1b5ef1413df1448377a5","sha256":"085c64e8656bdc72f6df3ea87cbdc3cecad5ea2822ef7bdbf785f1a0b5ec6af4","kind":"look","collection":"35mm negative","group":"","label":"reversal","tables":{"logc4":{"hash":"1b5ef1413df1448377a5-logc4","sha256":"26f045fe3350c28e5c869318e05a08fbad34d254cfd01e6a43c58590a387cca7"},"slog3cine":{"hash":"1b5ef1413df1448377a5-slog3cine","sha256":"3e7bdda5552525ff585f6485161d735b87669d2a7b51dfaa9ce45fc65bbe05fe"}}},{"number":77,"id":"look/3 Full 35mm/full.fblook","hash":"bde7a8dae9f0029c08a7","sha256":"7a1ed86c0b48c9eab14cdc78864380c11ee7d80d2e7520748cd64fdccd18d922","kind":"look","collection":"35mm print","group":"","label":"answer print","tables":{"logc4":{"hash":"bde7a8dae9f0029c08a7-logc4","sha256":"35b0e18b70d51fc7ef711d579daa41ba089d46e017e144d2ff2d0a4ac50fe875"},"slog3cine":{"hash":"bde7a8dae9f0029c08a7-slog3cine","sha256":"616e96e27643fd36122aa01a598ba703ed4dda1a27b6c5336d93e12516600e55"}}},{"number":78,"id":"look/3 Full 35mm/telecine.fblook","hash":"e3069ca7edaf6e8a6871","sha256":"d4c1cc26898c7fb3a28d4c9f309ae77a86c2b0690c1abaf1abbcdfc2cf0bd656","kind":"look","collection":"35mm print","group":"","label":"telecine","tables":{"logc4":{"hash":"e3069ca7edaf6e8a6871-logc4","sha256":"047c850627c7b61646557dce1e1b3a9bf0b98a2da844d2bd7e57127e4feed76a"},"slog3cine":{"hash":"e3069ca7edaf6e8a6871-slog3cine","sha256":"f6f0ac7f8fe900484f598e803a6a6f88da6705f747a426552aba5a11a9edb59c"}}},{"number":79,"id":"look/3 Full 35mm/tungsten.fblook","hash":"793e629dd23f07625a52","sha256":"ae60b8cdbefcd0b6809e89c6267f42dda5354b919f434c16d5603859e07a94b5","kind":"look","collection":"35mm print","group":"","label":"tungsten","tables":{"logc4":{"hash":"793e629dd23f07625a52-logc4","sha256":"f12a449cf02d547d67b7ce97dc5a54848dd70dd4fcb2f8989fe66536dc492b5f"},"slog3cine":{"hash":"793e629dd23f07625a52-slog3cine","sha256":"e9935030e4d08ee0756c8415473486069edbf270278fcc58373f67cc46734488"}}},{"number":80,"id":"look/3 Full 35mm/warm.fblook","hash":"d1afcf1071126af0ea36","sha256":"4f3d64b8f49481c34c6d75eda843a0966b6d4bfd20fe12456aba81553def5b93","kind":"look","collection":"35mm print","group":"","label":"warm print","tables":{"logc4":{"hash":"d1afcf1071126af0ea36-logc4","sha256":"c6d6605131784961e58a035a50cb62d45a4fdc1ae3fb1cb14123f73caa20be86"},"slog3cine":{"hash":"d1afcf1071126af0ea36-slog3cine","sha256":"a4661000ab05dbe7c124e8708eea42158a1fe09eb2920c9d03f91a82c9ebf8fe"}}},{"number":81,"id":"look/3 Full 35mm/bleach.fblook","hash":"e332d3996f57fbaae72b","sha256":"a7c9159808c235f331dd44d6dbce638ae5000c4605de0413f316f1918b8ca602","kind":"look","collection":"35mm print","group":"","label":"silver retention","tables":{"logc4":{"hash":"e332d3996f57fbaae72b-logc4","sha256":"57d4e5e0b52bd2e219bac8e02a503eda4f3b000c9c793a70bad2dad48ac2350a"},"slog3cine":{"hash":"e332d3996f57fbaae72b-slog3cine","sha256":"db5735b664e15cfbdfda63b0773008d11f170394fc0538cad450ce2398eb3a9b"}}},{"number":82,"id":"look/3 Full 35mm/chill.fblook","hash":"ea2011e1dd170763346c","sha256":"1f852c23916f35a53101922aa97bf1496a7bbf497227dd5adaa05041686e3c5f","kind":"look","collection":"35mm print","group":"","label":"cool print","tables":{"logc4":{"hash":"ea2011e1dd170763346c-logc4","sha256":"11a174a275ba60484b3cf46912331b861c8299e8418e727c709c96cddf9ef9a4"},"slog3cine":{"hash":"ea2011e1dd170763346c-slog3cine","sha256":"8007cf44ab45aab5de5a9c00d605b540c71fcdf0bf544b312011885c012072a5"}}},{"number":83,"id":"look/4 16mm/standard_16mm.fblook","hash":"c925caba596086362636","sha256":"20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811","kind":"look","collection":"16mm","group":"","label":"documentary","tables":{"logc4":{"hash":"c925caba596086362636-logc4","sha256":"a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"},"slog3cine":{"hash":"c925caba596086362636-slog3cine","sha256":"01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"}}},{"number":84,"id":"look/4 16mm/spicy.fblook","hash":"96722d8fea88d16f44e6","sha256":"cf977b4ad1d284d543a620a06a948bbf3c18e9c1a422a51212f5450806526ece","kind":"look","collection":"16mm","group":"","label":"saturated","tables":{"logc4":{"hash":"96722d8fea88d16f44e6-logc4","sha256":"569ac53061295652bc0ffb15470b11bdaa2d451461bde0dd49c43f4e0c95ed8f"},"slog3cine":{"hash":"96722d8fea88d16f44e6-slog3cine","sha256":"38325af0627c9b6b488e0989204f93942bf24361370422cda84fde669b3ec8c6"}}},{"number":85,"id":"look/4 16mm/notmoonlight.fblook","hash":"1bc5b2876e983f9abd58","sha256":"c8154c6b3299af6b4b8f6250a39b7baf80f8c20ef462086272a05a41fdc12ca2","kind":"look","collection":"16mm","group":"","label":"day for night","tables":{"logc4":{"hash":"1bc5b2876e983f9abd58-logc4","sha256":"55450587e41a53b2fbfd9ee6e0f55ae423d8b03b7567e34edac9df209bcb134d"},"slog3cine":{"hash":"1bc5b2876e983f9abd58-slog3cine","sha256":"595c89c6617ecd8152aeb0584339cd3f66a8c454491c8b2f96c6760423a947de"}}},{"number":86,"id":"look/4 16mm/flat scan.fblook","hash":"6bbded22dcdba51d1da0","sha256":"de67d8f582c5f011b459b592d9312cb9c4036b71774edecbe2023a9fbd2925e0","kind":"look","collection":"16mm","group":"","label":"flat scan","tables":{"logc4":{"hash":"6bbded22dcdba51d1da0-logc4","sha256":"072fb36276368fabb7128af202c5b0657a40ce7be32efd5c2f8eb03cfa0bd64d"},"slog3cine":{"hash":"6bbded22dcdba51d1da0-slog3cine","sha256":"ca084c654162c9b8588cfe1bae67c62c07875215fc91e4e71840f9956a468165"}}},{"number":87,"id":"look/4 16mm/indie scan.fblook","hash":"4dc360d9777f84b038c7","sha256":"d3c645f393e5f63812b8067fbfe5dcd032ec71b051ab9a255371ee0c877e2e86","kind":"look","collection":"16mm","group":"","label":"indie","tables":{"logc4":{"hash":"4dc360d9777f84b038c7-logc4","sha256":"5ded82c763469d7cd28af7e6f4f0c64a28869f6f119bd8fcc51fc09a1a89765c"},"slog3cine":{"hash":"4dc360d9777f84b038c7-slog3cine","sha256":"ce5c2e35d511c2d76416540bd997bdf99ac45e7f59a2bdd808026718244ac97a"}}},{"number":88,"id":"look/4 16mm/scrubs.fblook","hash":"354181100a0eb296a46f","sha256":"28a392ffe91ed0e6f87daee6b3c177d4b6b3a3442705023db0b88ddefe634062","kind":"look","collection":"16mm","group":"","label":"tape transfer","tables":{"logc4":{"hash":"354181100a0eb296a46f-logc4","sha256":"7955fc62f1b935b7b931a7cc1e7e45f18390bb5c9a8319e4cf6d41555f013130"},"slog3cine":{"hash":"354181100a0eb296a46f-slog3cine","sha256":"00e458e1de34b8270dabbaa6011b4e665264fa174ad4bdbcd62463467140ad55"}}},{"number":89,"id":"look/5 8mm/typical.fblook","hash":"1748cb5dba4ee4b6cf14","sha256":"20059ea05ff21a9f8a1c3443d49b1a817308d6832803d052d74bbe89b8ffd811","kind":"look","collection":"super 8","group":"","label":"home movie","tables":{"logc4":{"hash":"1748cb5dba4ee4b6cf14-logc4","sha256":"a6c0a44e2b3f33ad0a76eff8fb4f7d434eeecf55fe45cfb4be426808e17eb62f"},"slog3cine":{"hash":"1748cb5dba4ee4b6cf14-slog3cine","sha256":"01aec00b6c2e7b4e9acedcb9ba7f07f314739601aa435b261c394a3324f99daf"}}},{"number":90,"id":"look/5 8mm/lifted.fblook","hash":"07093d8ade0bf83ababf","sha256":"c8b4ba2c0b9d40400832dc2ea15fad3d6c59f460760fb06ca1c7dfb423baaa2b","kind":"look","collection":"super 8","group":"","label":"projected","tables":{"logc4":{"hash":"07093d8ade0bf83ababf-logc4","sha256":"1e8e4bd55dad23965b66280ae930f5746a04e8f4e0a2927886deef72223a878f"},"slog3cine":{"hash":"07093d8ade0bf83ababf-slog3cine","sha256":"c368965baa62e868b97def41776a4d59f9f9c6e91aae6f7314de479123daae03"}}},{"number":91,"id":"look/5 8mm/fuzz.fblook","hash":"9a27ce046063628613a9","sha256":"d0bd619c3bc55eeb041827d3bd1c60b0b86e8d53af718cd218a5a9315a24f963","kind":"look","collection":"super 8","group":"","label":"diffused","tables":{"logc4":{"hash":"9a27ce046063628613a9-logc4","sha256":"edf8f4dbbe936d873b3c10e7cf14cd46f2758e609ce572e1e51f6a9812ca4681"},"slog3cine":{"hash":"9a27ce046063628613a9-slog3cine","sha256":"518b88dbaf5f21ac573fbbd2aed291a7c475cb1b6fe242571ca36792e11dd830"}}},{"number":92,"id":"look/5 8mm/summer.fblook","hash":"df4643ebdb04850d6940","sha256":"ebe014ec3af62081e5dc8ec1fea489d3e687ea7d839913e1a0a1cc44158d0fe7","kind":"look","collection":"super 8","group":"","label":"sun faded","tables":{"logc4":{"hash":"df4643ebdb04850d6940-logc4","sha256":"2a0cfdad26f2ba0b5206fdd639f11e66ced0bac7332305a8c2c2de1c37adc117"},"slog3cine":{"hash":"df4643ebdb04850d6940-slog3cine","sha256":"ff766044f1326586b1e3d194069f846ddf1ff8d3919560a066df78555f6686f9"}}},{"number":93,"id":"look/5 8mm/trash.fblook","hash":"b5d4f1f8790caa0124ba","sha256":"f694f45d12b4ed77f66e08697bb7171db9c7712e638bc3d714501e1d902fc292","kind":"look","collection":"super 8","group":"","label":"found footage","tables":{"logc4":{"hash":"b5d4f1f8790caa0124ba-logc4","sha256":"d8fe007fa0192692e7758517f809841cb747977b65be8c9b24f7a13e78367b32"},"slog3cine":{"hash":"b5d4f1f8790caa0124ba-slog3cine","sha256":"a806dfdd5ed162238e29bc967c7fe9993949feb22f47a90d6744285d1d80a5dd"}}},{"number":94,"id":"look/Pastel & Low-Contrast/easy.fblook","hash":"d5f75230b10228ebc4e5","sha256":"d3d7c350f28b78a55fcaf9a6e4146147b46e16f5daf3f691d0a7b354e2379e9d","kind":"look","collection":"low contrast","group":"","label":"overcast","tables":{"logc4":{"hash":"d5f75230b10228ebc4e5-logc4","sha256":"34cc0eaf73144a77b473c90a005c218df1c02b3216e4b99a359eaab269e4edd0"},"slog3cine":{"hash":"d5f75230b10228ebc4e5-slog3cine","sha256":"48a59dba191609fe68d2412972b42769fd4b2010eaa12523c321c73c1fea939a"}}},{"number":95,"id":"look/Pastel & Low-Contrast/wes_2.fblook","hash":"e4441dc735a9ba2007f0","sha256":"dd532aafd868c9a2f7279969c5d5799e56a27354fc3cec61de5bd0b6e427e9d4","kind":"look","collection":"low contrast","group":"","label":"pastel","tables":{"logc4":{"hash":"e4441dc735a9ba2007f0-logc4","sha256":"95b33caeadf9416196c4226214a40a58fe80a89592f971186113bffc2d8015ff"},"slog3cine":{"hash":"e4441dc735a9ba2007f0-slog3cine","sha256":"a30cf208e29c9cb3e49dbfbe5b93ba6c619e87e0ec3658383b161664851f6721"}}},{"number":96,"id":"look/Pastel & Low-Contrast/log.fblook","hash":"28f04ac4b5617492a043","sha256":"fd5e0f3f0145f92a1bf93e84e0d591d5abd4393f4ae1d40d9af6494d14c4d1db","kind":"look","collection":"low contrast","group":"","label":"marine layer","tables":{"logc4":{"hash":"28f04ac4b5617492a043-logc4","sha256":"089a6fa621544921fed07adbae2c276b68bf6a2e5872d772b8dbb66d4a4e3698"},"slog3cine":{"hash":"28f04ac4b5617492a043-slog3cine","sha256":"dc328a0b45a16f628c77e33b1e0d816cd0a4bb7b776f1cdb6e7001e062840371"}}},{"number":97,"id":"look/Pastel & Low-Contrast/warmie.fblook","hash":"96d755f0b92fba69ec40","sha256":"957e3d8f434a3c16aefb107d6d134eb200b4590a249b6e7371926c228355df15","kind":"look","collection":"low contrast","group":"","label":"golden","tables":{"logc4":{"hash":"96d755f0b92fba69ec40-logc4","sha256":"c8b97b4bc89dd817ff6f3e91e4205687bdaab9de21c0f85df20cd6e9c5419ea7"},"slog3cine":{"hash":"96d755f0b92fba69ec40-slog3cine","sha256":"716ceac0e80cc23dd5a0ddb4c7b9cf1000e6af2d8ca4d51a24a70310e3b65f18"}}},{"number":98,"id":"look/Still Photography/portrait_c.fblook","hash":"21f566ca8d150a57fda9","sha256":"cadc9bbb04df1c77613620c37d6d063f21752fad6e7cd1276fe881df12989754","kind":"look","collection":"photographic","group":"","label":"portrait","tables":{"logc4":{"hash":"21f566ca8d150a57fda9-logc4","sha256":"eb9058f52554f3eebbb8ba275b8b041cf19ab7d80dc87666d697fecd8358d15f"},"slog3cine":{"hash":"21f566ca8d150a57fda9-slog3cine","sha256":"86bf919e57805addd0fde53181eb59910a748ebc286ae2439efb809c8bd3e8f6"}}},{"number":99,"id":"look/Still Photography/slide.fblook","hash":"cdc85a160ee50230fd9f","sha256":"4c12fa6ad360f02bba2f00619ceb0e9cb17c39bcc9e090cf25732636d1fb79b0","kind":"look","collection":"photographic","group":"","label":"slide","tables":{"logc4":{"hash":"cdc85a160ee50230fd9f-logc4","sha256":"2108dc78393d5c341dd7abd195e62490725a60625d275294287e0a201ff0c5f5"},"slog3cine":{"hash":"cdc85a160ee50230fd9f-slog3cine","sha256":"8680b5b1dd1d57eaf28fe400a11db2acc1a431e609b1ad68601c5909cbe645fd"}}},{"number":100,"id":"look/Still Photography/pushed.fblook","hash":"db580ae8d4e13222988d","sha256":"f63f4d39793f807b2e4720ec64e262ebcfc5d5398a73c9752899c91de518e7c8","kind":"look","collection":"photographic","group":"","label":"push two","tables":{"logc4":{"hash":"db580ae8d4e13222988d-logc4","sha256":"12b2c21f021bf3b48679cb57dafc5f50f32479c0f28dd7e1a6bcf8f9d969e000"},"slog3cine":{"hash":"db580ae8d4e13222988d-slog3cine","sha256":"ab554e3fa554b3fff17c8a50204b803834f6f1b39d2b2192b2e5c0ce633681a3"}}},{"number":101,"id":"look/Still Photography/remjet_a.fblook","hash":"0bfdbdc03660c69b2d61","sha256":"313550933e02336035dee847373d198963026a8fdb30d5ce7c8a3deee013dbd4","kind":"look","collection":"photographic","group":"","label":"halation","tables":{"logc4":{"hash":"0bfdbdc03660c69b2d61-logc4","sha256":"094d1ee2e487a63f1dd3f5f9e8b013566add055c52df7ad74e9c9b76443c83a5"},"slog3cine":{"hash":"0bfdbdc03660c69b2d61-slog3cine","sha256":"c78da8f059f5825ecee525747f6ae1964ba77dcf877670e6a201704b30eae9f1"}}},{"number":102,"id":"look/Still Photography/punchy.fblook","hash":"366a5666efe55a758980","sha256":"ef951fdd857f8ac8997fc918d8344038e0fd974904e048d0e555b36d71c256bb","kind":"look","collection":"photographic","group":"","label":"flash","tables":{"logc4":{"hash":"366a5666efe55a758980-logc4","sha256":"c09d98a4c3b5ae1c4ca93a319993352bed1c07344547f49537998fb12c3f1f65"},"slog3cine":{"hash":"366a5666efe55a758980-slog3cine","sha256":"d51784c05addd44e1a1fe254a49b1caed57565dba239f671165ac4777d9719d6"}}},{"number":103,"id":"look/Iconic Looks/seven.fblook","hash":"e3cdb2cbc9079391543e","sha256":"e9aaaf7f96d9e7adf9c7e48537ab780b77574ff8d7121c9613678badd0fb237e","kind":"look","collection":"reference","group":"","label":"fluorescent","tables":{"logc4":{"hash":"e3cdb2cbc9079391543e-logc4","sha256":"655a011cab20767a28ef26720ef2416bdcd7e1afe6ba713bc7f537739c84c43d"},"slog3cine":{"hash":"e3cdb2cbc9079391543e-slog3cine","sha256":"20a2076ceccf0b2215709ff2c55f1d1e7c1bc55b98ced8a2f4e605ede82aa50e"}}},{"number":104,"id":"look/Iconic Looks/the_wrestler.fblook","hash":"1c837b47572c211e376e","sha256":"e607e9d9f20cc52c6db1f010f1aa69341e43aba0c9207438b99dbda54ef05f82","kind":"look","collection":"reference","group":"","label":"grit","tables":{"logc4":{"hash":"1c837b47572c211e376e-logc4","sha256":"4bc54f353deb9ad6e668d9efd7c27fea53ed39524c490c12d7fedc0d9b961087"},"slog3cine":{"hash":"1c837b47572c211e376e-slog3cine","sha256":"3e9caf59518b92abcdf978aae27c84a12f323514a1abb42c4fb1df3801bee34b"}}},{"number":105,"id":"look/Iconic Looks/euphoria.fblook","hash":"b3b5fb4a2d1e7795d48b","sha256":"529ece7d8991ac4dee8df844fdbda943a095d113a8c810c623f86ace7a283162","kind":"look","collection":"reference","group":"","label":"neon","tables":{"logc4":{"hash":"b3b5fb4a2d1e7795d48b-logc4","sha256":"2f8ab2afb9ae2d22cdf4a465ada05969f4aec39a45c04aecd79df203239b3c32"},"slog3cine":{"hash":"b3b5fb4a2d1e7795d48b-slog3cine","sha256":"2d02bc2f9613888da17b35e2ea9bbaea43cad53acf7a06ffa8e6db5229e82114"}}},{"number":106,"id":"look/Iconic Looks/minority_report.fblook","hash":"2f15c11407d3a10053a5","sha256":"a178374748c605d43b5fcbac39a542491a039f21de7fc8dbf0291bddd5615f76","kind":"look","collection":"reference","group":"","label":"clinical","tables":{"logc4":{"hash":"2f15c11407d3a10053a5-logc4","sha256":"1d4f86741bbb20b0bcb3671b5e7c2d9034448c0885916450b2c47b9e337fa2b4"},"slog3cine":{"hash":"2f15c11407d3a10053a5-slog3cine","sha256":"f0c6500e39beef6d1baffa9f6a8841408134cd81af78e59581869eaeb192bf3e"}}},{"number":107,"id":"look/Iconic Looks/orange_and_teal.fblook","hash":"69467c32c23d52d88afa","sha256":"5029c787be90d68ee97c8b139c2d3004d36dd756dabc418dd66005364d51bac7","kind":"look","collection":"reference","group":"","label":"orange and teal","tables":{"logc4":{"hash":"69467c32c23d52d88afa-logc4","sha256":"1cabef428a1e57442ee22fe848ef384ff68c0ba4d60711fc196151d247a77db0"},"slog3cine":{"hash":"69467c32c23d52d88afa-slog3cine","sha256":"226fbc06457541bbe57de13204c6264fe57cb201a2b913baf43a603be4439abf"}}},{"number":108,"id":"look/Iconic Looks/amelie.fblook","hash":"f04c4b3553463dae85f0","sha256":"b8585ceec58f795976c83ba948859b704984de8b0ded1561b996f35a5e4a3d5e","kind":"look","collection":"reference","group":"","label":"warm green","tables":{"logc4":{"hash":"f04c4b3553463dae85f0-logc4","sha256":"6b6aa04a9d8daa313348c8d4f0c76903e6e2e9ee2d6c4f882e83ecb36b095818"},"slog3cine":{"hash":"f04c4b3553463dae85f0-slog3cine","sha256":"fc5b77ebf930c64364ce506655d45f77dea10561fe00602456da704ef38c83f6"}}},{"number":109,"id":"look/Iconic Looks/kingdom.fblook","hash":"ad8a751daf364dab2622","sha256":"e10ef6f84df98f34d93ff655ec0ea307a99b6d48e7579ab96fbf192a512a4de4","kind":"look","collection":"reference","group":"","label":"storybook","tables":{"logc4":{"hash":"ad8a751daf364dab2622-logc4","sha256":"19877a0fd5f7a0435f6faed9d1911d3aa922ee25211e80a488cbb765e431af2e"},"slog3cine":{"hash":"ad8a751daf364dab2622-slog3cine","sha256":"af472ac796684391ecb8bdea35d10b1b6c768a4dc3d977983b886011392b1c46"}}},{"number":110,"id":"look/Iconic Looks/fincher.fblook","hash":"33a6846cc763bf518e06","sha256":"b3f9d6ba2d6e43a52dac4675e511886f633d8f36ecbc983f5385ff17768fbb1d","kind":"look","collection":"reference","group":"","label":"tobacco","tables":{"logc4":{"hash":"33a6846cc763bf518e06-logc4","sha256":"c3200dfc6266440dcdf08de03258899eb7a83fc3904073ec1c24d5e15b6321d1"},"slog3cine":{"hash":"33a6846cc763bf518e06-slog3cine","sha256":"7780f6a0bd386253e1e4817867bd74c10317bc62ef795f3605d85a4d177a1e56"}}},{"number":111,"id":"look/Vintage Cinema/sergio.fblook","hash":"70d72ce15d3955091bda","sha256":"e5e8b1cd458eefc7053e563a7ecbd240e9f8ab93a15e2bfcb30711a264f112a8","kind":"look","collection":"period","group":"","label":"dust","tables":{"logc4":{"hash":"70d72ce15d3955091bda-logc4","sha256":"e8fb2adab0791394d7d97c27f95a7598bbc7c14b904796dfa717b5487edbb268"},"slog3cine":{"hash":"70d72ce15d3955091bda-slog3cine","sha256":"0be7bd7049d4bc3079eaafa0f3e2760e23079ab3769174a152545ace350c02b5"}}},{"number":112,"id":"look/Vintage Cinema/smoke.fblook","hash":"c14dda43a784de7c3700","sha256":"bd228142081fed590d816ece1f96afbbcd09ffa0a9384ab617e39f001e9a9f26","kind":"look","collection":"period","group":"","label":"smoke","tables":{"logc4":{"hash":"c14dda43a784de7c3700-logc4","sha256":"1bd1133c5f9a3d67edb80cc8c3eeac088463fcb0825374b9c50b6355367787e7"},"slog3cine":{"hash":"c14dda43a784de7c3700-slog3cine","sha256":"7311df0d0e2503dafd1152d4d75448cc55737bc839dfc60d55036f6e51d129b1"}}},{"number":113,"id":"look/Vintage Cinema/telecine_1999.fblook","hash":"99f762c374bf4514bf8a","sha256":"5bf6721bf3d2a5af6e1b2f12917e6531fe1d6e6d991690ca69f7d17fa9d2a05e","kind":"look","collection":"period","group":"","label":"late nineties","tables":{"logc4":{"hash":"99f762c374bf4514bf8a-logc4","sha256":"b8b5762a0204998d1ab145a3adf5ff4dfd3721839895cd52fa63ba0341d34c16"},"slog3cine":{"hash":"99f762c374bf4514bf8a-slog3cine","sha256":"a375f840d9548de46e9b5549259eaca6a7373ed4cbe3fa1b7cbaa7f18739490b"}}},{"number":114,"id":"look/Vintage Cinema/old1.fblook","hash":"505498bd2c1c0304488c","sha256":"e8a4dd595c46a9304b4ef0853477ca2c52193dbdc27dd357f420422241f90829","kind":"look","collection":"period","group":"","label":"seventies","tables":{"logc4":{"hash":"505498bd2c1c0304488c-logc4","sha256":"c748b60aa640501b02f16c6294d3cff09a93e69683da8dfb8bffeaf9bd6562c7"},"slog3cine":{"hash":"505498bd2c1c0304488c-slog3cine","sha256":"d49cd5bf76fd27e5cb7cdd0a9da41bf9c77e20edb27f498c979e2413c51024a7"}}},{"number":115,"id":"look/Vintage Cinema/old2.fblook","hash":"4618354776df37902ba5","sha256":"64b749b9860d9fe2b898ce9a802e51cffb227fbead70f3c22ec14a43a37fefb6","kind":"look","collection":"period","group":"","label":"faded print","tables":{"logc4":{"hash":"4618354776df37902ba5-logc4","sha256":"bece3d02ab6a53cb805ce828c5dbee48042a43037bafa9a456fcd92445826f58"},"slog3cine":{"hash":"4618354776df37902ba5-slog3cine","sha256":"4ec5404d85f8aea3a727c43bd676f40a3467d266ef63ff060c1457aab5aca9de"}}},{"number":116,"id":"look/Black & White/nice pan.fblook","hash":"eb80fb6951b9b1abf2e1","sha256":"61f5620c43ae6467e15f978d45c997a22e9582c924e387855df87800bfe0716f","kind":"look","collection":"black and white","group":"","label":"panchromatic","tables":{"logc4":{"hash":"eb80fb6951b9b1abf2e1-logc4","sha256":"9df05346e03df176a8c25f982172564227a5bf64c0a291ba5e7df5b32e4c5ed8"},"slog3cine":{"hash":"eb80fb6951b9b1abf2e1-slog3cine","sha256":"e7e1110999730f5b124c20d1e2bf59779131c5f9a168b95f9354bcab58be83c2"}}},{"number":117,"id":"look/Black & White/citizen kane.fblook","hash":"937b5b8d569c6a0c3677","sha256":"fe82d9cacbe8de3feb8da64b51b8f0bd5dee0df82df5fba69fe8eb0e4ba365b5","kind":"look","collection":"black and white","group":"","label":"studio era","tables":{"logc4":{"hash":"937b5b8d569c6a0c3677-logc4","sha256":"30c34728ab7af0e857b3e8506b10b7fc24632201bd5bbef6848cbbef479a0e12"},"slog3cine":{"hash":"937b5b8d569c6a0c3677-slog3cine","sha256":"ab5a46426a84d9df85c6ecf744bc574d4b9876f91b5dc8bde2fb545d779fc3ee"}}},{"number":118,"id":"look/Black & White/glamour.fblook","hash":"020d6dbc263a98761a7b","sha256":"d908f9d739668ac9dfa4670143aa5e91865988cd80cf0fb6fd56a8d52b1e9627","kind":"look","collection":"black and white","group":"","label":"soft key","tables":{"logc4":{"hash":"020d6dbc263a98761a7b-logc4","sha256":"fe136199906b80c26d186c1f2985c9e5d43bcbc27be1073d48107a8e396a12e8"},"slog3cine":{"hash":"020d6dbc263a98761a7b-slog3cine","sha256":"dc4593ad9edd785a87022cb093ed5f9ce0d6bfe854104fa18ef3ef1c24dbdf2a"}}},{"number":119,"id":"look/Black & White/old.fblook","hash":"a10ab4ab9e0473d20fb4","sha256":"b5bce10d22c0b6d978c0da8698b1ff383ea3b1914c26eb4c8bee8acf33731e57","kind":"look","collection":"black and white","group":"","label":"nitrate","tables":{"logc4":{"hash":"a10ab4ab9e0473d20fb4-logc4","sha256":"1a4769c3b7243cad95f7c1cf554ff0665f0b01aeff9d79e64a811b176f551f29"},"slog3cine":{"hash":"a10ab4ab9e0473d20fb4-slog3cine","sha256":"f8569bc223dab55686246f01500a4b3d1dfa8709653c6db2148151a9014471ea"}}},{"number":120,"id":"look/Black & White/Sepia.fblook","hash":"c995c945c090bca69166","sha256":"2f6b862650994c68f045ade4d3d7795305b93459241d5a6999226d1183a37d12","kind":"look","collection":"black and white","group":"","label":"toned","tables":{"logc4":{"hash":"c995c945c090bca69166-logc4","sha256":"9756502d6f8a25fe8a1a83610015aec49b2c1ad59ca12bb65993464b6d117389"},"slog3cine":{"hash":"c995c945c090bca69166-slog3cine","sha256":"0ae84e1a4d37befc5c88d108d1b5accd6cf05a2d9ec94109c660d54f4818548e"}}},{"number":121,"id":"look/Black & White/nice ortho.fblook","hash":"9387a3c737cc0fd101d2","sha256":"a7e9e24bc246b84ce6f3a3fa8abfbcb62c90867870f5167dec542f090ef79faf","kind":"look","collection":"black and white","group":"","label":"orthochromatic","tables":{"logc4":{"hash":"9387a3c737cc0fd101d2-logc4","sha256":"b9d941f8d575b7072acebe563aca04ce4c1e81536adc035e8887173165f6dbd7"},"slog3cine":{"hash":"9387a3c737cc0fd101d2-slog3cine","sha256":"0989dafc139e58fd8ba2f1a4118be36e7383c919f7f201bdc8d3056467adb889"}}},{"number":122,"id":"look/Black & White/mono.fblook","hash":"4692285fd84f9d250d3b","sha256":"4e7b206ac61649cfd7cfb834e983f92e0d0f7c025565d4853b7cae853b25c77b","kind":"look","collection":"black and white","group":"","label":"hard contrast","tables":{"logc4":{"hash":"4692285fd84f9d250d3b-logc4","sha256":"f4fb0446043c7f8d74d48785ec076feef717284625a34f53409335e375eec77d"},"slog3cine":{"hash":"4692285fd84f9d250d3b-slog3cine","sha256":"eb5ccd8c5773b5c4e94154f1e69e2ae64be438e9f7df2d3f91ec82ac237bb36e"}}},{"number":123,"id":"look/Extreme Looks/phoneix.fblook","hash":"2b3e96623a2b3dc3c616","sha256":"f2562ddd4716330e4b71118c4ec907f56c631dc66bf1ac060d87234b637b4cb0","kind":"look","collection":"experimental","group":"","label":"burnout","tables":{"logc4":{"hash":"2b3e96623a2b3dc3c616-logc4","sha256":"d961fe54aeaea1be1612b00d819e55d6345461cd45f13d3388c1bbb115aaec8c"},"slog3cine":{"hash":"2b3e96623a2b3dc3c616-slog3cine","sha256":"769c9381843200a7fe00146f66d5c04d20fb1f750fb6ef0f52e9bfa789097118"}}},{"number":124,"id":"look/Extreme Looks/purp.fblook","hash":"02af9ff3db82f755c7df","sha256":"342979d459fc3d15387fe56c77e2b213b163e923078dfcdeb1419a55391b17ee","kind":"look","collection":"experimental","group":"","label":"violet","tables":{"logc4":{"hash":"02af9ff3db82f755c7df-logc4","sha256":"1b55fad5fa9b1f28cbe35093a409a0263e1f6184dc821b2bb0218c16fcc82c32"},"slog3cine":{"hash":"02af9ff3db82f755c7df-slog3cine","sha256":"9a6f2f114cf859435795ca240ce16eaf52219b2ba0da6cee7254809cbc0bd93b"}}},{"number":125,"id":"look/Extreme Looks/blasted.fblook","hash":"7d599929461225300cae","sha256":"fd51c12e64fbd6526e256d0fcc9a00a1bf487914a802b0377032bee28778befa","kind":"look","collection":"experimental","group":"","label":"overexposed","tables":{"logc4":{"hash":"7d599929461225300cae-logc4","sha256":"cd64d9c2bac509a7e359cec3729b8626812a377744e6b6102c891126904c45e9"},"slog3cine":{"hash":"7d599929461225300cae-slog3cine","sha256":"fa575c421c5bf845e62e370f0bc139496c8f9fadeafef965058711ecdfa8797c"}}},{"number":126,"id":"look/Extreme Looks/instacolor.fblook","hash":"028ee89f15bdd058347f","sha256":"fce844465246ea55f465a99d18b22ca4a97257df08245f58706a87eaf11ed4d2","kind":"look","collection":"experimental","group":"","label":"instant","tables":{"logc4":{"hash":"028ee89f15bdd058347f-logc4","sha256":"da46549a5ad5ba3cc1f321e289e732d792a3b1791c46ce58ab24c3243f76510d"},"slog3cine":{"hash":"028ee89f15bdd058347f-slog3cine","sha256":"1dd7e2b03e37e46189cdf2e724946733a90c964db606e839ba5d9278d7ba0ed8"}}}];
|
|
3
|
+
export const FILM_CAMERAS = ["Studio (automatic)","Arri LogC EI800 | Arri Wide Gamut","Arri LogC4 | Arri Wide Gamut 4","Sony S-Log3 | S-Gamut3.Cine","Sony S-Log3 | S-Gamut3","Rec.709 | Gamma 2.4","Linear | ARRI Wide Gamut 3","DaVinci Wide Gamut Intermediate","ACEScct","ACEScc","ACEScg","ACES2065-1","ADX10","Apple Log | Rec.2020","BMDFilm Gen 5 | BMD Wide Gamut","Canon Log 2 | Cinema Gamut (D55)","Canon Log 3 | Cinema Gamut (D55)","DJI D-Log | D-Gamut","Panasonic V-Log | V-Gamut","RED Log3G10 | REDWideGamutRGB","Sony Venice S-Log3 | S-Gamut3","Sony Venice S-Log3 | S-Gamut3.Cine","sRGB | Rec.709","Camera Rec.709","Linear | ARRI Wide Gamut 4","Linear | Rec.709","Linear | Rec.2020","Linear | DaVinci Wide Gamut","Linear | BMD Wide Gamut Gen 5","Fuji F-Log | Rec.2020","Fuji F-Log2 | Rec.2020","Fuji F-Log2 C | F-Gamut C","Nikon N-Log | Rec.2020","Leica L-Log | Rec.2020","P3 D65 | Gamma 2.4","Rec.2020 | Gamma 2.4"] as const;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { defineEffect, type EffectOptions, type EffectBindings, type EffectFactory, type EvaluatedEffect } from './effects.js';
|
|
2
|
+
import type { MotionValue } from './motion.js';
|
|
3
|
+
import { FILM_STOCKS, FILM_CAMERAS } from './film-catalog.generated.js';
|
|
4
|
+
export { FILM_STOCKS, FILM_CAMERAS };
|
|
5
|
+
|
|
6
|
+
import {filmKnobs, FILM_GROUPS} from './effect-schemas.mjs';
|
|
7
|
+
export const FILM_KNOBS = filmKnobs(FILM_STOCKS, FILM_CAMERAS);
|
|
8
|
+
|
|
9
|
+
function evaluateFilm(v: Readonly<Record<string, MotionValue>>): EvaluatedEffect {
|
|
10
|
+
const stock = FILM_STOCKS.find(s => s.id === v.stock) ?? FILM_STOCKS.find(s => s.label === v.stock);
|
|
11
|
+
if (!stock) throw new Error(`Unknown film stock: ${v.stock}`);
|
|
12
|
+
const camera = FILM_CAMERAS.findIndex(n => n === v.cameraProfile);
|
|
13
|
+
if (camera < 0) throw new Error(`Unknown film input profile: ${v.cameraProfile}`);
|
|
14
|
+
for (const [name, knob] of Object.entries(FILM_KNOBS)) {
|
|
15
|
+
if (knob.type === 'number' && (typeof v[name] !== 'number' || (v[name] as number) < knob.min || (v[name] as number) > knob.max))
|
|
16
|
+
throw new Error(`Film ${name}: expected ${knob.min} through ${knob.max}`);
|
|
17
|
+
}
|
|
18
|
+
if (!Number.isInteger(v.seed)) throw new Error('Film seed must be an integer');
|
|
19
|
+
const controls = ['strength','exposure','warmth','tint','contrast','saturation','lift','gamma','print','grain','grainSaturation','grainSoftness','grainRoughness','halation','halationRadius','looksGrain','looksHalation'].map(n => v[n] as number);
|
|
20
|
+
controls.push(['35mm', '16mm', '8mm'].indexOf(v.gauge as string), v.seed as number, v.textureFps as number, camera);
|
|
21
|
+
const table = camera === 2 ? stock.tables.logc4 : camera === 3 || camera === 4 ? stock.tables.slog3cine : stock;
|
|
22
|
+
return { padding: [0,0,0,0], film: `film:${table.hash}`, uniforms: {}, uniformData: [...controls, ...Array(128-controls.length).fill(0)] };
|
|
23
|
+
}
|
|
24
|
+
const base = defineEffect({ padding: 0, knobs: filmKnobs(FILM_STOCKS, FILM_CAMERAS, true), groups: FILM_GROUPS, code: 'fn effect(uv: vec2f, time: f32) -> vec4f { return eng_input(uv); }' });
|
|
25
|
+
/** Multi-pass film color, measured grain and halation. Works on Video, Group and Scene. */
|
|
26
|
+
export const film: EffectFactory<typeof FILM_KNOBS> = Object.assign(
|
|
27
|
+
(values: EffectBindings<typeof FILM_KNOBS> = {}, options: EffectOptions = {}) => {
|
|
28
|
+
// Resolve convenient literal aliases before schema validation; the inspector
|
|
29
|
+
// keeps one canonical choice per stock. Animated choices use canonical IDs.
|
|
30
|
+
let bindings = values;
|
|
31
|
+
if (typeof values.stock === 'string' && !FILM_STOCKS.some(s => s.id === values.stock)) {
|
|
32
|
+
const matches = FILM_STOCKS.filter(s => s.label === values.stock);
|
|
33
|
+
if (matches.length !== 1) throw new Error(`Unknown or ambiguous film stock: ${values.stock}`);
|
|
34
|
+
bindings = {...values, stock: matches[0].id};
|
|
35
|
+
}
|
|
36
|
+
return Object.freeze({ ...base(bindings, options), evaluateBuiltin: evaluateFilm });
|
|
37
|
+
},
|
|
38
|
+
{ definition: base.definition },
|
|
39
|
+
);
|
|
@@ -46,7 +46,7 @@ export type {
|
|
|
46
46
|
MotionDefinition,
|
|
47
47
|
Motions,
|
|
48
48
|
} from "./motion.js";
|
|
49
|
-
export { evaluateFrame } from "./evaluate.js";
|
|
49
|
+
export { evaluateFrame, evaluateMotionFrame } from "./evaluate.js";
|
|
50
50
|
export type {
|
|
51
51
|
EvaluatedScene,
|
|
52
52
|
EvaluatedCamera,
|
|
@@ -63,7 +63,8 @@ export type {
|
|
|
63
63
|
} from "./evaluate.js";
|
|
64
64
|
|
|
65
65
|
export { defineEffect, describeEffect, blur, grain } from "./effects.js";
|
|
66
|
-
export
|
|
66
|
+
export { film, FILM_KNOBS, FILM_STOCKS, FILM_CAMERAS } from "./film.js";
|
|
67
|
+
export type { EffectPadding, Knob, KnobGroup, Knobs, KnobValues, EffectDefinition, EffectOptions, EffectBindings, EffectFactory, EffectInstance, EvaluatedEffect } from "./effects.js";
|
|
67
68
|
|
|
68
69
|
export { defineKnobs, describeKnobs } from "./knobs.js";
|
|
69
70
|
export type { KnobRef, KnobSet, KnobBindings, KnobDescription } from "./knobs.js";
|
|
@@ -71,3 +72,6 @@ export type { KnobRef, KnobSet, KnobBindings, KnobDescription } from "./knobs.js
|
|
|
71
72
|
export type { TextAnimation, TextAnimationStyle } from "./text-animation.js";
|
|
72
73
|
|
|
73
74
|
export type { AssetKind, AssetPath } from "./assets.js";
|
|
75
|
+
|
|
76
|
+
export {resolveMotionBlur, shutterFrames} from "./motion-blur.js";
|
|
77
|
+
export type {MotionBlurSettings, ResolvedMotionBlur} from "./motion-blur.js";
|
|
@@ -15,6 +15,8 @@ interface Control {
|
|
|
15
15
|
export type Knob = Control & (
|
|
16
16
|
| {
|
|
17
17
|
type: "number";
|
|
18
|
+
/** Integer values; editor-created animation uses discrete steps. */
|
|
19
|
+
integer?: boolean;
|
|
18
20
|
default: number;
|
|
19
21
|
/** Positive drag/slider increment, e.g. 0.1 or 1. Does not quantize animation. */
|
|
20
22
|
step: number;
|
|
@@ -59,7 +61,7 @@ export function freeze<T>(value: T): T {
|
|
|
59
61
|
|
|
60
62
|
export function validateKnobValue(knob: Knob, value: unknown, name: string) {
|
|
61
63
|
switch (knob.type) {
|
|
62
|
-
case "number": if (!finite(value)) fail(`${name}: expected a finite number`); break;
|
|
64
|
+
case "number": if (!finite(value)) fail(`${name}: expected a finite number`); if (knob.integer && !Number.isInteger(value)) fail(`${name}: expected an integer`); break;
|
|
63
65
|
case "boolean": if (typeof value !== "boolean") fail(`${name}: expected a boolean`); break;
|
|
64
66
|
case "asset": if (!validAssetPath(knob.kind, value)) fail(`${name}: expected a local ${knob.kind} asset path`); break;
|
|
65
67
|
case "text": if (typeof value !== "string") fail(`${name}: expected text`); break;
|
|
@@ -100,12 +102,13 @@ export function validateKnobSchema(knobs: Knobs, inputGroups: Readonly<Record<st
|
|
|
100
102
|
}
|
|
101
103
|
for (const [name, knob] of Object.entries(knobs)) {
|
|
102
104
|
if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(name) || !record(knob)) fail(`invalid knob ${name}`);
|
|
103
|
-
const extras = knob.type === "number" ? ["min", "max", "step"] : knob.type === "asset" ? ["kind"] : ["select", "multiselect"].includes(knob.type) ? ["options"] : [];
|
|
105
|
+
const extras = knob.type === "number" ? ["min", "max", "step", "integer"] : knob.type === "asset" ? ["kind"] : ["select", "multiselect"].includes(knob.type) ? ["options"] : [];
|
|
104
106
|
keys(knob, ["type", "default", "label", "group", "visibleWhen", ...extras], name);
|
|
105
107
|
if (!["number", "color", "text", "boolean", "select", "multiselect", "asset"].includes(knob.type)) fail(`${name}: unknown knob type`);
|
|
106
108
|
if (knob.label !== undefined && typeof knob.label !== "string") fail(`${name}.label: expected text`);
|
|
107
109
|
if (knob.group !== undefined && !Object.hasOwn(groups, knob.group)) fail(`${name}: unknown group ${knob.group}`);
|
|
108
110
|
if (knob.type === "number") {
|
|
111
|
+
if (knob.integer !== undefined && typeof knob.integer !== "boolean") fail(`${name}.integer: expected boolean`);
|
|
109
112
|
if (!finite(knob.step) || knob.step <= 0) fail(`${name}: step must be positive`);
|
|
110
113
|
for (const bound of [knob.min, knob.max]) if (bound !== undefined && !finite(bound)) fail(`${name}: invalid bound`);
|
|
111
114
|
if (knob.min !== undefined && knob.max !== undefined && knob.min >= knob.max) fail(`${name}: min must be below max`);
|
|
@@ -7,12 +7,13 @@ export function readGroupPlayback(props: {
|
|
|
7
7
|
solo: boolean;
|
|
8
8
|
};
|
|
9
9
|
/** Optional lane metadata indexed by the same 0–99 numbers as clip.track.
|
|
10
|
-
* @param {unknown} value @returns {Record<number, {label?: string, hidden?: boolean, solo?: boolean, muted?: boolean}>} */
|
|
10
|
+
* @param {unknown} value @returns {Record<number, {label?: string, hidden?: boolean, solo?: boolean, muted?: boolean, motionBlur?: boolean}>} */
|
|
11
11
|
export function readSceneTracks(value: unknown): Record<number, {
|
|
12
12
|
label?: string;
|
|
13
13
|
hidden?: boolean;
|
|
14
14
|
solo?: boolean;
|
|
15
15
|
muted?: boolean;
|
|
16
|
+
motionBlur?: boolean;
|
|
16
17
|
}>;
|
|
17
18
|
/** Effective playback state without removing nodes or changing their identity.
|
|
18
19
|
* @param {ReturnType<typeof readSceneTracks>} tracks @param {number | undefined} track */
|