paperlab 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/README.md +7 -5
  2. package/dist/{FxPostPass-M66QMVVC.js → FxPostPass-V6YDK4H2.js} +23 -5
  3. package/dist/FxPostPass-V6YDK4H2.js.map +1 -0
  4. package/dist/chunk-232SU3AQ.js +34 -0
  5. package/dist/chunk-232SU3AQ.js.map +1 -0
  6. package/dist/{chunk-GB6BMHC3.js → chunk-7WOGU2D4.js} +7 -19
  7. package/dist/{chunk-GB6BMHC3.js.map → chunk-7WOGU2D4.js.map} +1 -1
  8. package/dist/{chunk-MZCAN3AR.js → chunk-SVWWC5UL.js} +576 -160
  9. package/dist/chunk-SVWWC5UL.js.map +1 -0
  10. package/dist/{damageContract-DPF1YFLZ.d.cts → damageContract-nF1fgK7P.d.cts} +31 -3
  11. package/dist/{damageContract-DPF1YFLZ.d.ts → damageContract-nF1fgK7P.d.ts} +31 -3
  12. package/dist/fx.cjs +320 -91
  13. package/dist/fx.cjs.map +1 -1
  14. package/dist/fx.d.cts +81 -55
  15. package/dist/fx.d.ts +81 -55
  16. package/dist/fx.js +278 -48
  17. package/dist/fx.js.map +1 -1
  18. package/dist/index.cjs +606 -181
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +13 -5
  21. package/dist/index.d.ts +13 -5
  22. package/dist/index.js +17 -4
  23. package/dist/index.js.map +1 -1
  24. package/dist/{slots-C5PqY0Q5.d.cts → slots-D_EE8GXn.d.cts} +12 -0
  25. package/dist/{slots-C5PqY0Q5.d.ts → slots-D_EE8GXn.d.ts} +12 -0
  26. package/dist/stage.cjs +600 -188
  27. package/dist/stage.cjs.map +1 -1
  28. package/dist/stage.d.cts +1 -1
  29. package/dist/stage.d.ts +1 -1
  30. package/dist/stage.js +2 -2
  31. package/package.json +1 -1
  32. package/dist/FxPostPass-M66QMVVC.js.map +0 -1
  33. package/dist/chunk-7TLIWPGM.js +0 -36
  34. package/dist/chunk-7TLIWPGM.js.map +0 -1
  35. package/dist/chunk-MZCAN3AR.js.map +0 -1
package/dist/index.d.cts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import * as THREE from 'three';
4
- import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, M as MemoryConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, f as CreaseConfig, F as FieldPaperSlot, g as ContentConfig, h as PaperStatesInput, L as LightingName, i as FilmName, j as LightOverrides, k as BackdropConfig } from './slots-C5PqY0Q5.cjs';
5
- export { l as BackContentConfig, m as BehaviorConfig, n as ClothConfig, o as CoreStateName, p as CreaseConfigInput, q as DeformerInstanceConfig, r as LightOverridesInput, s as MemoryConfig, t as PaperEdge, u as PaperStates, v as PhysicsConfig, w as SceneConfig, x as StateDef, y as StateName, z as StateTransitionConfig, A as StripConfig, E as SurfaceConfig, W as WashConfig, G as backdropSchema, H as behaviorConfigSchema, I as clothConfigSchema, J as contentNames, K as contentSchemaFor, N as coreStateNames, O as creaseSchema, Q as lightSchema, R as lightingNames, T as memorySchema, U as paperConfigSchema, V as paperEdges, X as paperStatesSchema, Y as physicsNames, Z as sceneSchema, _ as stateDefSchema, $ as stockNames, a0 as stripConfigSchema, a1 as washSchema } from './slots-C5PqY0Q5.cjs';
6
- import { D as DamageSource } from './damageContract-DPF1YFLZ.cjs';
7
- export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-DPF1YFLZ.cjs';
4
+ import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, M as MemoryConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, f as CreaseConfig, F as FieldPaperSlot, g as ContentConfig, h as PaperStatesInput, L as LightingName, i as FilmName, j as LightOverrides, k as BackdropConfig } from './slots-D_EE8GXn.cjs';
5
+ export { l as BackContentConfig, m as BehaviorConfig, n as ClothConfig, o as CoreStateName, p as CreaseConfigInput, q as DeformerInstanceConfig, r as LightOverridesInput, s as MemoryConfig, t as PaperEdge, u as PaperStates, v as PhysicsConfig, w as SceneConfig, x as StateDef, y as StateName, z as StateTransitionConfig, A as StripConfig, E as SurfaceConfig, W as WashConfig, G as backdropSchema, H as behaviorConfigSchema, I as clothConfigSchema, J as contentNames, K as contentSchemaFor, N as coreStateNames, O as creaseSchema, Q as lightSchema, R as lightingNames, T as memorySchema, U as paperConfigSchema, V as paperEdges, X as paperStatesSchema, Y as physicsNames, Z as sceneSchema, _ as stateDefSchema, $ as stockNames, a0 as stripConfigSchema, a1 as washSchema } from './slots-D_EE8GXn.cjs';
6
+ import { D as DamageSource } from './damageContract-nF1fgK7P.cjs';
7
+ export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-nF1fgK7P.cjs';
8
8
  import { z } from 'zod';
9
9
 
10
10
  /**
@@ -1064,6 +1064,14 @@ interface PaperLightingProps {
1064
1064
  * `light.studio` if you want less of it.
1065
1065
  */
1066
1066
  environment?: boolean;
1067
+ /**
1068
+ * The damage the sheet is showing, for the light it gives off: a burn
1069
+ * whose source carries `firelight` dims this rig's key, fill and studio
1070
+ * light by `firelight.room` while it burns, and gives them back as it goes
1071
+ * out. Without one — or with no `firelight` on it — the rig is exactly as
1072
+ * set. See `DamageFirelight`.
1073
+ */
1074
+ damage?: DamageSource | null;
1067
1075
  }
1068
1076
  /**
1069
1077
  * A scene's lighting rig from one serialized name plus whatever the author
@@ -1072,7 +1080,7 @@ interface PaperLightingProps {
1072
1080
  * haze, and the contact shadow. Swap presets to restyle the same paper;
1073
1081
  * move the sliders to light it yourself.
1074
1082
  */
1075
- declare function PaperLighting({ preset, light, rig, floor, scale, reducedMotion, shadowMapSize, contactShadow, environment, }: PaperLightingProps): react.JSX.Element;
1083
+ declare function PaperLighting({ preset, light, rig, floor, scale, reducedMotion, shadowMapSize, contactShadow, environment, damage, }: PaperLightingProps): react.JSX.Element;
1076
1084
 
1077
1085
  /**
1078
1086
  * What is behind the sheet.
package/dist/index.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import * as THREE from 'three';
4
- import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, M as MemoryConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, f as CreaseConfig, F as FieldPaperSlot, g as ContentConfig, h as PaperStatesInput, L as LightingName, i as FilmName, j as LightOverrides, k as BackdropConfig } from './slots-C5PqY0Q5.js';
5
- export { l as BackContentConfig, m as BehaviorConfig, n as ClothConfig, o as CoreStateName, p as CreaseConfigInput, q as DeformerInstanceConfig, r as LightOverridesInput, s as MemoryConfig, t as PaperEdge, u as PaperStates, v as PhysicsConfig, w as SceneConfig, x as StateDef, y as StateName, z as StateTransitionConfig, A as StripConfig, E as SurfaceConfig, W as WashConfig, G as backdropSchema, H as behaviorConfigSchema, I as clothConfigSchema, J as contentNames, K as contentSchemaFor, N as coreStateNames, O as creaseSchema, Q as lightSchema, R as lightingNames, T as memorySchema, U as paperConfigSchema, V as paperEdges, X as paperStatesSchema, Y as physicsNames, Z as sceneSchema, _ as stateDefSchema, $ as stockNames, a0 as stripConfigSchema, a1 as washSchema } from './slots-C5PqY0Q5.js';
6
- import { D as DamageSource } from './damageContract-DPF1YFLZ.js';
7
- export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-DPF1YFLZ.js';
4
+ import { P as PaperConfig, a as PaperConfigInput, S as SheetConfig, b as StockName, C as ContentConfigInput, B as BehaviorConfigInput, D as DeformerInstanceConfigInput, c as SurfaceConfigInput, M as MemoryConfigInput, d as SceneConfigInput, e as PhysicsConfigInput, f as CreaseConfig, F as FieldPaperSlot, g as ContentConfig, h as PaperStatesInput, L as LightingName, i as FilmName, j as LightOverrides, k as BackdropConfig } from './slots-D_EE8GXn.js';
5
+ export { l as BackContentConfig, m as BehaviorConfig, n as ClothConfig, o as CoreStateName, p as CreaseConfigInput, q as DeformerInstanceConfig, r as LightOverridesInput, s as MemoryConfig, t as PaperEdge, u as PaperStates, v as PhysicsConfig, w as SceneConfig, x as StateDef, y as StateName, z as StateTransitionConfig, A as StripConfig, E as SurfaceConfig, W as WashConfig, G as backdropSchema, H as behaviorConfigSchema, I as clothConfigSchema, J as contentNames, K as contentSchemaFor, N as coreStateNames, O as creaseSchema, Q as lightSchema, R as lightingNames, T as memorySchema, U as paperConfigSchema, V as paperEdges, X as paperStatesSchema, Y as physicsNames, Z as sceneSchema, _ as stateDefSchema, $ as stockNames, a0 as stripConfigSchema, a1 as washSchema } from './slots-D_EE8GXn.js';
6
+ import { D as DamageSource } from './damageContract-nF1fgK7P.js';
7
+ export { a as DAMAGE_CHANNELS, b as DAMAGE_LOOK_DEFAULTS, c as DamageLook } from './damageContract-nF1fgK7P.js';
8
8
  import { z } from 'zod';
9
9
 
10
10
  /**
@@ -1064,6 +1064,14 @@ interface PaperLightingProps {
1064
1064
  * `light.studio` if you want less of it.
1065
1065
  */
1066
1066
  environment?: boolean;
1067
+ /**
1068
+ * The damage the sheet is showing, for the light it gives off: a burn
1069
+ * whose source carries `firelight` dims this rig's key, fill and studio
1070
+ * light by `firelight.room` while it burns, and gives them back as it goes
1071
+ * out. Without one — or with no `firelight` on it — the rig is exactly as
1072
+ * set. See `DamageFirelight`.
1073
+ */
1074
+ damage?: DamageSource | null;
1067
1075
  }
1068
1076
  /**
1069
1077
  * A scene's lighting rig from one serialized name plus whatever the author
@@ -1072,7 +1080,7 @@ interface PaperLightingProps {
1072
1080
  * haze, and the contact shadow. Swap presets to restyle the same paper;
1073
1081
  * move the sliders to light it yourself.
1074
1082
  */
1075
- declare function PaperLighting({ preset, light, rig, floor, scale, reducedMotion, shadowMapSize, contactShadow, environment, }: PaperLightingProps): react.JSX.Element;
1083
+ declare function PaperLighting({ preset, light, rig, floor, scale, reducedMotion, shadowMapSize, contactShadow, environment, damage, }: PaperLightingProps): react.JSX.Element;
1076
1084
 
1077
1085
  /**
1078
1086
  * What is behind the sheet.
package/dist/index.js CHANGED
@@ -79,11 +79,11 @@ import {
79
79
  useResolvedConfig,
80
80
  washSchema,
81
81
  wrapLines
82
- } from "./chunk-MZCAN3AR.js";
82
+ } from "./chunk-SVWWC5UL.js";
83
83
  import {
84
84
  DAMAGE_CHANNELS,
85
85
  DAMAGE_LOOK_DEFAULTS
86
- } from "./chunk-7TLIWPGM.js";
86
+ } from "./chunk-232SU3AQ.js";
87
87
 
88
88
  // src/Paper.tsx
89
89
  import { Canvas } from "@react-three/fiber";
@@ -100,11 +100,24 @@ var Paper = forwardRef(function Paper2({ children, className, style, ...meshProp
100
100
  {
101
101
  preset: config.scene.lighting,
102
102
  light: config.scene.light,
103
- floor: -1.05,
103
+ floor: config.scene.floor.enabled ? config.scene.floor.y : -1.05,
104
104
  scale: 8,
105
- reducedMotion: meshProps.reducedMotion
105
+ reducedMotion: meshProps.reducedMotion,
106
+ damage: meshProps.damage
106
107
  }
107
108
  ),
109
+ config.scene.floor.enabled && // Dark, matte and large enough to leave no edge in frame: what the
110
+ // fire's light pools on, and what the paper it cuts loose lands on.
111
+ /* @__PURE__ */ jsxs("mesh", { "rotation-x": -Math.PI / 2, position: [0, config.scene.floor.y, 0], receiveShadow: true, children: [
112
+ /* @__PURE__ */ jsx("planeGeometry", { args: [40, 40] }),
113
+ /* @__PURE__ */ jsx(
114
+ "meshStandardMaterial",
115
+ {
116
+ color: config.scene.floor.color,
117
+ roughness: config.scene.floor.roughness
118
+ }
119
+ )
120
+ ] }),
108
121
  /* @__PURE__ */ jsx(PaperMesh, { ref, ...meshProps }),
109
122
  children,
110
123
  /* @__PURE__ */ jsx(ReleaseContextOnUnmount, {})
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Paper.tsx","../src/config/field-export.ts","../src/field/parity.ts"],"sourcesContent":["import { Canvas } from '@react-three/fiber'\nimport { forwardRef, useMemo } from 'react'\nimport { PaperMesh, useResolvedConfig, type PaperHandle, type PaperMeshProps } from './PaperMesh'\nimport { PaperFallback, PaperMirror, supportsWebGL } from './a11y'\nimport { PaperLighting } from './scene/PaperLighting'\nimport { PaperBackdrop } from './scene/backdrop'\nimport { ReleaseContextOnUnmount } from './scene/release'\n\nexport interface PaperProps extends PaperMeshProps {\n /** Extra children rendered inside the canvas (lights are provided). */\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * `<Paper />` owns its own `<Canvas>` and fills its parent container —\n * the parent must have a height. Use `<PaperMesh />` inside an existing\n * R3F scene instead.\n *\n * Ships with its accessibility layer: a hidden DOM mirror of the content,\n * `prefers-reduced-motion` support, and a flat DOM fallback when WebGL is\n * unavailable.\n */\nexport const Paper = forwardRef<PaperHandle, PaperProps>(function Paper(\n { children, className, style, ...meshProps },\n ref,\n) {\n // Keyed on every prop resolveConfig reads — a content/stock/behavior change\n // must refresh the fallback, mirror, and lighting, not just the mesh.\n const config = useResolvedConfig(meshProps)\n const webgl = useMemo(() => (typeof window === 'undefined' ? true : supportsWebGL()), [])\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n {webgl ? (\n <Canvas shadows camera={{ position: [0, 0.35, 2.4], fov: 40 }} dpr={[1, 2]}>\n <PaperBackdrop backdrop={config.scene.backdrop} />\n <PaperLighting\n preset={config.scene.lighting}\n // The overrides, which this component was resolving without: a\n // preset whose scene said \"studio, but dimmer\" rendered as plain\n // studio here while the editor showed the dimmer one.\n light={config.scene.light}\n floor={-1.05}\n scale={8}\n reducedMotion={meshProps.reducedMotion}\n />\n <PaperMesh ref={ref} {...meshProps} />\n {children}\n <ReleaseContextOnUnmount />\n </Canvas>\n ) : (\n <PaperFallback config={config} />\n )}\n <PaperMirror config={config} />\n </div>\n )\n})\n","import {\n sceneSchema,\n type ContentConfig,\n type PaperConfig,\n type PaperStatesInput,\n type SceneConfigInput,\n} from './schema'\nimport { diffConfig } from './diff'\nimport { AGENT_PAYLOAD_VERSION } from './agent-payload'\nimport { getLayout } from '../field/layouts'\n\n/**\n * Field-mode export. Every preset a field references is INLINED as a const —\n * receivers don't have the sender's local preset library. Same fixed payload\n * anatomy as the single-paper export, same version.\n */\n\nexport interface FieldExportPaper {\n /** Display name of the preset this slot uses (const naming + description). */\n presetName: string\n /** The RESOLVED preset config (user presets included — nothing to fetch). */\n preset: PaperConfig\n content?: ContentConfig\n /** Per-slot state overrides (slot 3's hover deeper than slot 4's). */\n states?: PaperStatesInput\n}\n\nexport interface FieldExportZone {\n id: string\n accept?: string[]\n bounds: { position: [number, number, number]; size: [number, number] }\n highlight?: 'none' | 'glow' | 'outline'\n}\n\nexport interface FieldExportInput {\n layout: string\n layoutOptions?: Record<string, unknown>\n motion?: { driver?: 'autoplay' | 'drag' | 'none'; speed?: number }\n entrance?: { type?: 'rise' | 'scatter' | 'none'; stagger?: number; duration?: number }\n papers: FieldExportPaper[]\n /** How the gallery is lit. Omitted means the schema's own default rig. */\n scene?: SceneConfigInput\n /** Drop zones — exported as `<DropZone>` children with an onPlace stub. */\n zones?: FieldExportZone[]\n}\n\nconst MOTION_DEFAULTS = { driver: 'autoplay', speed: 0.5 }\nconst ENTRANCE_DEFAULTS = { type: 'rise', stagger: 0.06, duration: 0.9 }\n\nfunction camel(name: string): string {\n const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c: string) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, '')\n const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`\n return safe.charAt(0).toLowerCase() + safe.slice(1)\n}\n\ninterface DistinctPreset {\n varName: string\n presetName: string\n preset: PaperConfig\n}\n\n/** Distinct presets in slot order, with collision-safe const names. */\nexport function distinctFieldPresets(input: FieldExportInput): DistinctPreset[] {\n const byKey = new Map<string, DistinctPreset>()\n const usedNames = new Set<string>()\n for (const paper of input.papers) {\n const key = JSON.stringify(paper.preset)\n if (byKey.has(key)) continue\n let varName = camel(paper.presetName)\n while (usedNames.has(varName)) varName += '2'\n usedNames.add(varName)\n byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset })\n }\n return [...byKey.values()]\n}\n\n/**\n * The entries that differ from the defaults.\n *\n * Compared STRUCTURALLY rather than by reference. Most of what passes\n * through here is numbers and strings, where the two agree — but a layout\n * option holding an array, or a scene holding a nested rig, is never\n * reference-equal to the default it was copied from, so those exported a\n * prop that said exactly what the default already said.\n */\nfunction nonDefault<T extends Record<string, unknown>>(\n value: T | undefined,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value ?? {})) {\n if (v === undefined) continue\n const same = v === defaults[k] || JSON.stringify(v) === JSON.stringify(defaults[k])\n if (!same) out[k] = v\n }\n return out\n}\n\n/** The layout/motion/entrance props of the export, defaults stripped. */\nexport function diffFieldProps(input: FieldExportInput): Record<string, unknown> {\n const out: Record<string, unknown> = { layout: input.layout }\n const layout = getLayout(input.layout)\n const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults as Record<string, unknown>)\n if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions\n const motion = nonDefault(input.motion, MOTION_DEFAULTS)\n if (Object.keys(motion).length > 0) out.motion = motion\n const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS)\n if (Object.keys(entrance).length > 0) out.entrance = entrance\n // Resolved through the schema before comparing, so an input naming only\n // `lighting` is judged against a whole default rig rather than a\n // half-filled one.\n const scene = nonDefault(\n sceneSchema.parse(input.scene ?? {}) as unknown as Record<string, unknown>,\n sceneSchema.parse({}) as unknown as Record<string, unknown>,\n )\n if (Object.keys(scene).length > 0) out.scene = scene\n return out\n}\n\nconst LAYOUT_PHRASES: Record<string, string> = {\n ring: 'a ring you can see around',\n fan: 'a fanned swatch deck hinged at one corner',\n spread: 'a stack slid sideways, each sheet bowing further than the last',\n pile: 'a heap on a desk, the sheets underneath pressed flat',\n wall: 'a pinned studio wall of sheets, none hanging quite square',\n spill: 'a dropped stack caught mid-air, each sheet bent its own way',\n sweep: 'a specimen chart of one sheet at every stage of its deformation',\n book: 'an open book, its pages splayed from a shared spine',\n accordion: 'one continuous strip folded into a concertina',\n rack: 'prints stood in a row and leaning back against a wall',\n sheet: 'a stamp-block grid on a shared backing sheet',\n}\n\n/** The one-line visual an agent verifies after `npm run dev`. */\nexport function describeFieldConfig(input: FieldExportInput): string {\n const n = input.papers.length\n const stateful = input.papers.some((p) => p.preset.states || p.states)\n const zones = input.zones ?? []\n const parts: string[] = []\n\n if (input.layout === 'sheet') {\n const rows = Number(input.layoutOptions?.rows ?? 2)\n const columns = Number(input.layoutOptions?.columns ?? 5)\n parts.push(`a ${rows}×${columns} sheet of papers on a shared backing`)\n } else {\n const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`\n parts.push(`${n} papers arranged in ${layoutPhrase}`)\n }\n\n const driver = input.motion?.driver ?? 'autoplay'\n if (stateful) {\n // Stateful fields render static and interactive — the motion driver is moot.\n parts.push('hovering peels/reacts per paper (interaction states)')\n if (zones.length > 0) {\n parts.push(\n `dragging one past its tear threshold detaches it to carry to the ${zones\n .map((z) => z.id)\n .join(' or ')} zone (release elsewhere flutters it back)`,\n )\n }\n } else {\n if (driver === 'autoplay') parts.push('slowly orbiting on their own')\n if (driver === 'drag') parts.push('draggable sideways with the pointer')\n if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? 's' : ''}`)\n }\n\n const distinct = distinctFieldPresets(input)\n if (distinct.length > 1) {\n parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(', ')})`)\n }\n return parts.join(', ')\n}\n\n/** Component source shared by the JSX snippet and the agent payload. */\nexport function buildFieldComponentSource(input: FieldExportInput): string {\n const distinct = distinctFieldPresets(input)\n const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]))\n\n // `satisfies` (not `as const`) — const-asserted arrays turn readonly and\n // stop matching the library's input types.\n const consts = distinct\n .map(\n (d) =>\n `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`,\n )\n .join('\\n\\n')\n\n const slots = input.papers\n .map((paper) => {\n const varName = varByKey.get(JSON.stringify(paper.preset))!\n const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : ''\n const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : ''\n return ` { preset: ${varName}${content}${states} },`\n })\n .join('\\n')\n\n const props = Object.entries(diffFieldProps(input))\n .map(([key, value]) =>\n typeof value === 'string' ? ` ${key}=\"${value}\"` : ` ${key}={${JSON.stringify(value)}}`,\n )\n .join('\\n')\n\n const zones = input.zones ?? []\n const zoneImport = zones.length > 0 ? ', DropZone' : ''\n const zoneChildren = zones\n .map((zone) => {\n const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : ''\n const highlight = zone.highlight && zone.highlight !== 'glow' ? ` highlight=\"${zone.highlight}\"` : ''\n return ` <DropZone\n id=\"${zone.id}\"${accept}\n bounds={${JSON.stringify(zone.bounds)}}${highlight}\n onPlace={(paper, zone) => {\n // First-run smoke test — you should see this in the console on drop:\n console.log(paper.presetName, '→', zone.id)\n // Then replace it: stamp a postmark, advance the flow, persist the placement, …\n }}\n />`\n })\n .join('\\n')\n\n if (zones.length === 0) {\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n />\n )\n}`\n }\n\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n >\n${zoneChildren}\n </PaperField>\n )\n}`\n}\n\n/** The self-contained field integration brief — one paste into a coding agent. */\nexport function buildFieldAgentPayload(input: FieldExportInput): string {\n return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/PaperGallery.tsx\\` (or the\n project's component convention). It is self-contained — every preset it\n uses is inlined, and it owns its own <Canvas>:\n\n\\`\\`\\`tsx\n${buildFieldComponentSource(input)}\n\\`\\`\\`\n\n3. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.\n\n4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.\n If the canvas is blank, the parent container almost certainly has no height —\n give it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the preset values; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","import * as THREE from 'three'\nimport type { DeformerInstance, SheetDims } from '../deformers/types'\nimport { displacePoint } from '../deformers/compose'\nimport { getDeformer } from '../deformers/registry'\nimport { buildDisplacementGLSL } from './compose'\n\n/**\n * Golden-vector parity: the JS (hero) and GLSL (field) implementations of a\n * deformer must produce identical displacements. This harness evaluates the\n * GLSL path on the real GPU — the stack's displacement functions run in a\n * fragment shader over an N×N grid, rendered to a float target and read\n * back — then epsilon-compares against the JS path. Browser-only (WebGL2);\n * driven by tools/parity.mjs in CI.\n */\n\nconst GRID = 48\n/** highp float + sin/cos implementation differences across GPUs. */\nexport const PARITY_EPSILON = 5e-4\n\nexport interface ParityCase {\n name: string\n stack: DeformerInstance[]\n sheet: SheetDims\n t: number\n}\n\nexport interface ParityResult {\n name: string\n maxError: number\n pass: boolean\n}\n\n/** One case per deformer feature worth guarding, both easy and adversarial. */\nexport const parityCases: ParityCase[] = [\n {\n name: 'roll: defaults',\n stack: [{ type: 'roll', options: { angle: 90, boundary: 0, radius: 0.12, thickness: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'roll: tight receipt roll, rolling down',\n stack: [{ type: 'roll', options: { angle: 270, boundary: -0.4, radius: 0.07, thickness: 0.006 } }],\n sheet: { width: 1, height: 2.6 },\n t: 0,\n },\n {\n name: 'curl: bottom-right peel',\n stack: [{ type: 'curl', options: { corner: 'bottom-right', amount: 0.45, radius: 0.2, skew: 0 } }],\n sheet: { width: 1.5, height: 1 },\n t: 0,\n },\n {\n name: 'curl: skewed top-left',\n stack: [{ type: 'curl', options: { corner: 'top-left', amount: 0.7, radius: 0.3, skew: 15 } }],\n sheet: { width: 1, height: 1 },\n t: 0,\n },\n {\n name: 'bend: positive arc at an angle',\n stack: [{ type: 'bend', options: { curvature: 1.2, angle: 33 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n /**\n * The gentle end, which nothing used to cover: the gate only ever tried\n * |curvature| ≥ 0.6, and `photo-print` — the field starter preset — bends\n * at 0.35. That band is where the arc's float32 evaluation loses its\n * cancellation, and where the two paths were 6e-4 apart until `bend` was\n * rewritten in cancellation-free form. Keep a case down here.\n */\n name: 'bend: barely-there arc (the band photo-print lives in)',\n stack: [{ type: 'bend', options: { curvature: 0.35, angle: 0 } }],\n sheet: { width: 1.2, height: 0.9 },\n t: 0,\n },\n {\n name: 'bend: the gentlest arc the schema allows',\n stack: [{ type: 'bend', options: { curvature: 0.02, angle: 61 } }],\n sheet: { width: 2, height: 2.6 },\n t: 0,\n },\n {\n name: 'bend: negative arc',\n stack: [{ type: 'bend', options: { curvature: -0.8, angle: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: 90° hinge',\n stack: [{ type: 'fold', options: { angle: 90, offset: 0, foldAngle: 90, radius: 0.06 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: deep fold, travelling down',\n stack: [{ type: 'fold', options: { angle: 270, offset: 0.2, foldAngle: 165, radius: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'wave: free ripple at t=1.234',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.05, wavelength: 0.5, speed: 1, angle: 20, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1 },\n t: 1.234,\n },\n {\n name: 'wave: pinned top at t=2.5',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.04, wavelength: 0.4, speed: 1.5, angle: 80, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.2, height: 1.5 },\n t: 2.5,\n },\n {\n name: 'drape: banner hung from the top',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.17, folds: 5, falloff: 1.6, irregular: 0.45, gather: 0.5, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.5, height: 8.5 },\n t: 0,\n },\n {\n name: 'drape: deep irregular folds pinned at the bottom',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.55, folds: 11, falloff: 0.4, irregular: 1, gather: 1, pinnedEdge: 'bottom' },\n },\n ],\n sheet: { width: 2.2, height: 3 },\n t: 0,\n },\n {\n name: 'crumple: defaults',\n stack: [{ type: 'crumple', options: { amount: 0.35, scale: 3, pull: 0.4, seed: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n // The adversarial one. `fract` is a sawtooth, so the two halves disagree\n // hardest where a crease lands exactly on a sample — a fine scale and a\n // seed whose fold directions are near-axis puts the most creases in\n // reach of the grid.\n name: 'crumple: fully crushed, fine creases, off-axis seed',\n stack: [{ type: 'crumple', options: { amount: 1, scale: 7.5, pull: 1, seed: 5 } }],\n sheet: { width: 1.3, height: 0.9 },\n t: 0,\n },\n {\n // Crush then curl, which is the order the crumple BEHAVIOR stacks them:\n // the creases have to be placed on the flat sheet, not on a bent one.\n name: 'stacked: crumple ∘ bend (the crumple behavior)',\n stack: [\n { type: 'crumple', options: { amount: 0.62, scale: 3.3, pull: 0.5, seed: 2 } },\n { type: 'bend', options: { curvature: 0.31, angle: 35 } },\n ],\n sheet: { width: 1.1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: letter-fold pair (fold ∘ fold)',\n stack: [\n { type: 'fold', options: { angle: 270, offset: 0.2333, foldAngle: 120, radius: 0.05 } },\n { type: 'fold', options: { angle: 90, offset: 0.2333, foldAngle: 100, radius: 0.08 } },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: bend ∘ roll ∘ wave',\n stack: [\n { type: 'bend', options: { curvature: 0.6, angle: 0 } },\n { type: 'roll', options: { angle: 90, boundary: 0.1, radius: 0.15, thickness: 0 } },\n {\n type: 'wave',\n options: { amplitude: 0.02, wavelength: 0.6, speed: 0.7, angle: 45, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0.8,\n },\n]\n\nfunction buildParityFragment(stack: DeformerInstance[], sheet: SheetDims): string {\n const composed = buildDisplacementGLSL(stack, sheet)\n return /* glsl */ `#version 300 es\nprecision highp float;\nuniform float uPlTime;\nuniform float uPlBias;\n${composed.functionsSrc}\n${composed.displaceSrc}\nout vec4 outColor;\nvoid main() {\n vec2 uv = (gl_FragCoord.xy - 0.5) / float(${GRID - 1});\n vec3 p = vec3((uv - 0.5) * uSheet, 0.0);\n outColor = vec4(plDisplace(p, uv, uPlTime, uPlBias), 1.0);\n}\n`\n}\n\nconst VERT = `#version 300 es\nin vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n const shader = gl.createShader(type)!\n gl.shaderSource(shader, src)\n gl.compileShader(shader)\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(`[paperlab parity] shader compile failed: ${gl.getShaderInfoLog(shader)}`)\n }\n return shader\n}\n\nfunction runCaseOnGPU(gl: WebGL2RenderingContext, c: ParityCase, bias = 1): Float32Array {\n const composed = buildDisplacementGLSL(c.stack, c.sheet)\n const program = gl.createProgram()!\n gl.attachShader(program, compile(gl, gl.VERTEX_SHADER, VERT))\n gl.attachShader(program, compile(gl, gl.FRAGMENT_SHADER, buildParityFragment(c.stack, c.sheet)))\n gl.linkProgram(program)\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(`[paperlab parity] link failed: ${gl.getProgramInfoLog(program)}`)\n }\n // biome-ignore lint/correctness/useHookAtTopLevel: WebGL's gl.useProgram, not a React hook\n gl.useProgram(program)\n\n for (const [name, value] of Object.entries(composed.uniforms)) {\n const loc = gl.getUniformLocation(program, name)\n if (!loc) continue\n if (typeof value === 'number') gl.uniform1f(loc, value)\n else if (value.length === 2) gl.uniform2f(loc, value[0]!, value[1]!)\n else if (value.length === 3) gl.uniform3f(loc, value[0]!, value[1]!, value[2]!)\n else gl.uniform4f(loc, value[0]!, value[1]!, value[2]!, value[3]!)\n }\n const timeLoc = gl.getUniformLocation(program, 'uPlTime')\n if (timeLoc) gl.uniform1f(timeLoc, c.t)\n const biasLoc = gl.getUniformLocation(program, 'uPlBias')\n if (biasLoc) gl.uniform1f(biasLoc, bias)\n\n const quad = gl.createBuffer()!\n gl.bindBuffer(gl.ARRAY_BUFFER, quad)\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW)\n const posLoc = gl.getAttribLocation(program, 'aPos')\n gl.enableVertexAttribArray(posLoc)\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\n\n const tex = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, tex)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, GRID, GRID, 0, gl.RGBA, gl.FLOAT, null)\n const fbo = gl.createFramebuffer()!\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)\n gl.viewport(0, 0, GRID, GRID)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n\n const out = new Float32Array(GRID * GRID * 4)\n gl.readPixels(0, 0, GRID, GRID, gl.RGBA, gl.FLOAT, out)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n return out\n}\n\n/**\n * The bias contract, checked on the GPU: a stack of strength-bearing\n * deformers must go completely flat at bias 0, and a stack of deformers that\n * opt out (roll) must ignore bias entirely. Parity alone can't catch this —\n * it only ever evaluates bias 1.\n */\nfunction runBiasCases(gl: WebGL2RenderingContext): ParityResult[] {\n const results: ParityResult[] = []\n for (const c of parityCases) {\n const strengths = c.stack.map((i) => getDeformer(i.type).glsl?.strength !== undefined)\n // Mixed stacks flatten only partway — nothing crisp to assert.\n if (!strengths.every((h) => h === strengths[0])) continue\n const scales = strengths[0]\n\n const at0 = runCaseOnGPU(gl, c, 0)\n const reference = scales ? null : runCaseOnGPU(gl, c, 1)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const i4 = (row * GRID + col) * 4\n // At bias 0 a scaling stack collapses onto the flat sheet; an opted-out\n // stack must land exactly where bias 1 put it.\n const ex = reference ? reference[i4]! : (col / (GRID - 1) - 0.5) * c.sheet.width\n const ey = reference ? reference[i4 + 1]! : (row / (GRID - 1) - 0.5) * c.sheet.height\n const ez = reference ? reference[i4 + 2]! : 0\n maxError = Math.max(\n maxError,\n Math.abs(at0[i4]! - ex),\n Math.abs(at0[i4 + 1]! - ey),\n Math.abs(at0[i4 + 2]! - ez),\n )\n }\n }\n results.push({\n name: `bias: ${c.name} → ${scales ? 'flat at 0' : 'ignores bias'}`,\n maxError,\n pass: maxError < PARITY_EPSILON,\n })\n }\n return results\n}\n\n/** Run every parity case. Requires a WebGL2 context with float render targets. */\nexport function runParityHarness(canvas?: HTMLCanvasElement): ParityResult[] {\n const cnv = canvas ?? document.createElement('canvas')\n const gl = cnv.getContext('webgl2')\n if (!gl) throw new Error('[paperlab parity] WebGL2 unavailable')\n if (!gl.getExtension('EXT_color_buffer_float')) {\n throw new Error('[paperlab parity] EXT_color_buffer_float unavailable')\n }\n\n const point = new THREE.Vector3()\n const parity = parityCases.map((c) => {\n const gpu = runCaseOnGPU(gl, c)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const u = col / (GRID - 1)\n const v = row / (GRID - 1)\n point.set((u - 0.5) * c.sheet.width, (v - 0.5) * c.sheet.height, 0)\n displacePoint(point, u, v, c.stack, { t: c.t, sheet: c.sheet })\n const i4 = (row * GRID + col) * 4\n maxError = Math.max(\n maxError,\n Math.abs(gpu[i4]! - point.x),\n Math.abs(gpu[i4 + 1]! - point.y),\n Math.abs(gpu[i4 + 2]! - point.z),\n )\n }\n }\n return { name: c.name, maxError, pass: maxError < PARITY_EPSILON }\n })\n return [...parity, ...runBiasCases(gl)]\n}\n"],"mappings":"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","names":["Paper"]}
1
+ {"version":3,"sources":["../src/Paper.tsx","../src/config/field-export.ts","../src/field/parity.ts"],"sourcesContent":["import { Canvas } from '@react-three/fiber'\nimport { forwardRef, useMemo } from 'react'\nimport { PaperMesh, useResolvedConfig, type PaperHandle, type PaperMeshProps } from './PaperMesh'\nimport { PaperFallback, PaperMirror, supportsWebGL } from './a11y'\nimport { PaperLighting } from './scene/PaperLighting'\nimport { PaperBackdrop } from './scene/backdrop'\nimport { ReleaseContextOnUnmount } from './scene/release'\n\nexport interface PaperProps extends PaperMeshProps {\n /** Extra children rendered inside the canvas (lights are provided). */\n children?: React.ReactNode\n className?: string\n style?: React.CSSProperties\n}\n\n/**\n * `<Paper />` owns its own `<Canvas>` and fills its parent container —\n * the parent must have a height. Use `<PaperMesh />` inside an existing\n * R3F scene instead.\n *\n * Ships with its accessibility layer: a hidden DOM mirror of the content,\n * `prefers-reduced-motion` support, and a flat DOM fallback when WebGL is\n * unavailable.\n */\nexport const Paper = forwardRef<PaperHandle, PaperProps>(function Paper(\n { children, className, style, ...meshProps },\n ref,\n) {\n // Keyed on every prop resolveConfig reads — a content/stock/behavior change\n // must refresh the fallback, mirror, and lighting, not just the mesh.\n const config = useResolvedConfig(meshProps)\n const webgl = useMemo(() => (typeof window === 'undefined' ? true : supportsWebGL()), [])\n\n return (\n <div className={className} style={{ width: '100%', height: '100%', ...style }}>\n {webgl ? (\n <Canvas shadows camera={{ position: [0, 0.35, 2.4], fov: 40 }} dpr={[1, 2]}>\n <PaperBackdrop backdrop={config.scene.backdrop} />\n <PaperLighting\n preset={config.scene.lighting}\n // The overrides, which this component was resolving without: a\n // preset whose scene said \"studio, but dimmer\" rendered as plain\n // studio here while the editor showed the dimmer one.\n light={config.scene.light}\n // One floor height, shared: the ground the shadow falls on is the\n // ground a sheet lands on.\n floor={config.scene.floor.enabled ? config.scene.floor.y : -1.05}\n scale={8}\n reducedMotion={meshProps.reducedMotion}\n // A burn bright enough to light the room says so on its source.\n damage={meshProps.damage}\n />\n {config.scene.floor.enabled && (\n // Dark, matte and large enough to leave no edge in frame: what the\n // fire's light pools on, and what the paper it cuts loose lands on.\n <mesh rotation-x={-Math.PI / 2} position={[0, config.scene.floor.y, 0]} receiveShadow>\n <planeGeometry args={[40, 40]} />\n <meshStandardMaterial\n color={config.scene.floor.color}\n roughness={config.scene.floor.roughness}\n />\n </mesh>\n )}\n <PaperMesh ref={ref} {...meshProps} />\n {children}\n <ReleaseContextOnUnmount />\n </Canvas>\n ) : (\n <PaperFallback config={config} />\n )}\n <PaperMirror config={config} />\n </div>\n )\n})\n","import {\n sceneSchema,\n type ContentConfig,\n type PaperConfig,\n type PaperStatesInput,\n type SceneConfigInput,\n} from './schema'\nimport { diffConfig } from './diff'\nimport { AGENT_PAYLOAD_VERSION } from './agent-payload'\nimport { getLayout } from '../field/layouts'\n\n/**\n * Field-mode export. Every preset a field references is INLINED as a const —\n * receivers don't have the sender's local preset library. Same fixed payload\n * anatomy as the single-paper export, same version.\n */\n\nexport interface FieldExportPaper {\n /** Display name of the preset this slot uses (const naming + description). */\n presetName: string\n /** The RESOLVED preset config (user presets included — nothing to fetch). */\n preset: PaperConfig\n content?: ContentConfig\n /** Per-slot state overrides (slot 3's hover deeper than slot 4's). */\n states?: PaperStatesInput\n}\n\nexport interface FieldExportZone {\n id: string\n accept?: string[]\n bounds: { position: [number, number, number]; size: [number, number] }\n highlight?: 'none' | 'glow' | 'outline'\n}\n\nexport interface FieldExportInput {\n layout: string\n layoutOptions?: Record<string, unknown>\n motion?: { driver?: 'autoplay' | 'drag' | 'none'; speed?: number }\n entrance?: { type?: 'rise' | 'scatter' | 'none'; stagger?: number; duration?: number }\n papers: FieldExportPaper[]\n /** How the gallery is lit. Omitted means the schema's own default rig. */\n scene?: SceneConfigInput\n /** Drop zones — exported as `<DropZone>` children with an onPlace stub. */\n zones?: FieldExportZone[]\n}\n\nconst MOTION_DEFAULTS = { driver: 'autoplay', speed: 0.5 }\nconst ENTRANCE_DEFAULTS = { type: 'rise', stagger: 0.06, duration: 0.9 }\n\nfunction camel(name: string): string {\n const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c: string) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, '')\n const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`\n return safe.charAt(0).toLowerCase() + safe.slice(1)\n}\n\ninterface DistinctPreset {\n varName: string\n presetName: string\n preset: PaperConfig\n}\n\n/** Distinct presets in slot order, with collision-safe const names. */\nexport function distinctFieldPresets(input: FieldExportInput): DistinctPreset[] {\n const byKey = new Map<string, DistinctPreset>()\n const usedNames = new Set<string>()\n for (const paper of input.papers) {\n const key = JSON.stringify(paper.preset)\n if (byKey.has(key)) continue\n let varName = camel(paper.presetName)\n while (usedNames.has(varName)) varName += '2'\n usedNames.add(varName)\n byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset })\n }\n return [...byKey.values()]\n}\n\n/**\n * The entries that differ from the defaults.\n *\n * Compared STRUCTURALLY rather than by reference. Most of what passes\n * through here is numbers and strings, where the two agree — but a layout\n * option holding an array, or a scene holding a nested rig, is never\n * reference-equal to the default it was copied from, so those exported a\n * prop that said exactly what the default already said.\n */\nfunction nonDefault<T extends Record<string, unknown>>(\n value: T | undefined,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value ?? {})) {\n if (v === undefined) continue\n const same = v === defaults[k] || JSON.stringify(v) === JSON.stringify(defaults[k])\n if (!same) out[k] = v\n }\n return out\n}\n\n/** The layout/motion/entrance props of the export, defaults stripped. */\nexport function diffFieldProps(input: FieldExportInput): Record<string, unknown> {\n const out: Record<string, unknown> = { layout: input.layout }\n const layout = getLayout(input.layout)\n const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults as Record<string, unknown>)\n if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions\n const motion = nonDefault(input.motion, MOTION_DEFAULTS)\n if (Object.keys(motion).length > 0) out.motion = motion\n const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS)\n if (Object.keys(entrance).length > 0) out.entrance = entrance\n // Resolved through the schema before comparing, so an input naming only\n // `lighting` is judged against a whole default rig rather than a\n // half-filled one.\n const scene = nonDefault(\n sceneSchema.parse(input.scene ?? {}) as unknown as Record<string, unknown>,\n sceneSchema.parse({}) as unknown as Record<string, unknown>,\n )\n if (Object.keys(scene).length > 0) out.scene = scene\n return out\n}\n\nconst LAYOUT_PHRASES: Record<string, string> = {\n ring: 'a ring you can see around',\n fan: 'a fanned swatch deck hinged at one corner',\n spread: 'a stack slid sideways, each sheet bowing further than the last',\n pile: 'a heap on a desk, the sheets underneath pressed flat',\n wall: 'a pinned studio wall of sheets, none hanging quite square',\n spill: 'a dropped stack caught mid-air, each sheet bent its own way',\n sweep: 'a specimen chart of one sheet at every stage of its deformation',\n book: 'an open book, its pages splayed from a shared spine',\n accordion: 'one continuous strip folded into a concertina',\n rack: 'prints stood in a row and leaning back against a wall',\n sheet: 'a stamp-block grid on a shared backing sheet',\n}\n\n/** The one-line visual an agent verifies after `npm run dev`. */\nexport function describeFieldConfig(input: FieldExportInput): string {\n const n = input.papers.length\n const stateful = input.papers.some((p) => p.preset.states || p.states)\n const zones = input.zones ?? []\n const parts: string[] = []\n\n if (input.layout === 'sheet') {\n const rows = Number(input.layoutOptions?.rows ?? 2)\n const columns = Number(input.layoutOptions?.columns ?? 5)\n parts.push(`a ${rows}×${columns} sheet of papers on a shared backing`)\n } else {\n const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`\n parts.push(`${n} papers arranged in ${layoutPhrase}`)\n }\n\n const driver = input.motion?.driver ?? 'autoplay'\n if (stateful) {\n // Stateful fields render static and interactive — the motion driver is moot.\n parts.push('hovering peels/reacts per paper (interaction states)')\n if (zones.length > 0) {\n parts.push(\n `dragging one past its tear threshold detaches it to carry to the ${zones\n .map((z) => z.id)\n .join(' or ')} zone (release elsewhere flutters it back)`,\n )\n }\n } else {\n if (driver === 'autoplay') parts.push('slowly orbiting on their own')\n if (driver === 'drag') parts.push('draggable sideways with the pointer')\n if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? 's' : ''}`)\n }\n\n const distinct = distinctFieldPresets(input)\n if (distinct.length > 1) {\n parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(', ')})`)\n }\n return parts.join(', ')\n}\n\n/** Component source shared by the JSX snippet and the agent payload. */\nexport function buildFieldComponentSource(input: FieldExportInput): string {\n const distinct = distinctFieldPresets(input)\n const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]))\n\n // `satisfies` (not `as const`) — const-asserted arrays turn readonly and\n // stop matching the library's input types.\n const consts = distinct\n .map(\n (d) =>\n `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`,\n )\n .join('\\n\\n')\n\n const slots = input.papers\n .map((paper) => {\n const varName = varByKey.get(JSON.stringify(paper.preset))!\n const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : ''\n const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : ''\n return ` { preset: ${varName}${content}${states} },`\n })\n .join('\\n')\n\n const props = Object.entries(diffFieldProps(input))\n .map(([key, value]) =>\n typeof value === 'string' ? ` ${key}=\"${value}\"` : ` ${key}={${JSON.stringify(value)}}`,\n )\n .join('\\n')\n\n const zones = input.zones ?? []\n const zoneImport = zones.length > 0 ? ', DropZone' : ''\n const zoneChildren = zones\n .map((zone) => {\n const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : ''\n const highlight = zone.highlight && zone.highlight !== 'glow' ? ` highlight=\"${zone.highlight}\"` : ''\n return ` <DropZone\n id=\"${zone.id}\"${accept}\n bounds={${JSON.stringify(zone.bounds)}}${highlight}\n onPlace={(paper, zone) => {\n // First-run smoke test — you should see this in the console on drop:\n console.log(paper.presetName, '→', zone.id)\n // Then replace it: stamp a postmark, advance the flow, persist the placement, …\n }}\n />`\n })\n .join('\\n')\n\n if (zones.length === 0) {\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n />\n )\n}`\n }\n\n return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'\n\n${consts}\n\nconst papers: FieldPaperSlot[] = [\n${slots}\n]\n\nexport function PaperGallery() {\n return (\n <PaperField\n papers={papers}\n${props}\n >\n${zoneChildren}\n </PaperField>\n )\n}`\n}\n\n/** The self-contained field integration brief — one paste into a coding agent. */\nexport function buildFieldAgentPayload(input: FieldExportInput): string {\n return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})\n\n1. Install the dependencies:\n\n npm i paperlab three @react-three/fiber gsap\n\n2. Create the component below as \\`components/PaperGallery.tsx\\` (or the\n project's component convention). It is self-contained — every preset it\n uses is inlined, and it owns its own <Canvas>:\n\n\\`\\`\\`tsx\n${buildFieldComponentSource(input)}\n\\`\\`\\`\n\n3. Sizing: the component fills its parent container. Place it where I ask;\n give the parent an explicit height.\n\n4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.\n If the canvas is blank, the parent container almost certainly has no height —\n give it one (this is the classic React Three Fiber integration bug, not a\n paperlab bug).\n\nConstraints: don't modify the preset values; three >= 0.160 and React 19 are\nrequired; the component needs no props.`\n}\n","import * as THREE from 'three'\nimport type { DeformerInstance, SheetDims } from '../deformers/types'\nimport { displacePoint } from '../deformers/compose'\nimport { getDeformer } from '../deformers/registry'\nimport { buildDisplacementGLSL } from './compose'\n\n/**\n * Golden-vector parity: the JS (hero) and GLSL (field) implementations of a\n * deformer must produce identical displacements. This harness evaluates the\n * GLSL path on the real GPU — the stack's displacement functions run in a\n * fragment shader over an N×N grid, rendered to a float target and read\n * back — then epsilon-compares against the JS path. Browser-only (WebGL2);\n * driven by tools/parity.mjs in CI.\n */\n\nconst GRID = 48\n/** highp float + sin/cos implementation differences across GPUs. */\nexport const PARITY_EPSILON = 5e-4\n\nexport interface ParityCase {\n name: string\n stack: DeformerInstance[]\n sheet: SheetDims\n t: number\n}\n\nexport interface ParityResult {\n name: string\n maxError: number\n pass: boolean\n}\n\n/** One case per deformer feature worth guarding, both easy and adversarial. */\nexport const parityCases: ParityCase[] = [\n {\n name: 'roll: defaults',\n stack: [{ type: 'roll', options: { angle: 90, boundary: 0, radius: 0.12, thickness: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'roll: tight receipt roll, rolling down',\n stack: [{ type: 'roll', options: { angle: 270, boundary: -0.4, radius: 0.07, thickness: 0.006 } }],\n sheet: { width: 1, height: 2.6 },\n t: 0,\n },\n {\n name: 'curl: bottom-right peel',\n stack: [{ type: 'curl', options: { corner: 'bottom-right', amount: 0.45, radius: 0.2, skew: 0 } }],\n sheet: { width: 1.5, height: 1 },\n t: 0,\n },\n {\n name: 'curl: skewed top-left',\n stack: [{ type: 'curl', options: { corner: 'top-left', amount: 0.7, radius: 0.3, skew: 15 } }],\n sheet: { width: 1, height: 1 },\n t: 0,\n },\n {\n name: 'bend: positive arc at an angle',\n stack: [{ type: 'bend', options: { curvature: 1.2, angle: 33 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n /**\n * The gentle end, which nothing used to cover: the gate only ever tried\n * |curvature| ≥ 0.6, and `photo-print` — the field starter preset — bends\n * at 0.35. That band is where the arc's float32 evaluation loses its\n * cancellation, and where the two paths were 6e-4 apart until `bend` was\n * rewritten in cancellation-free form. Keep a case down here.\n */\n name: 'bend: barely-there arc (the band photo-print lives in)',\n stack: [{ type: 'bend', options: { curvature: 0.35, angle: 0 } }],\n sheet: { width: 1.2, height: 0.9 },\n t: 0,\n },\n {\n name: 'bend: the gentlest arc the schema allows',\n stack: [{ type: 'bend', options: { curvature: 0.02, angle: 61 } }],\n sheet: { width: 2, height: 2.6 },\n t: 0,\n },\n {\n name: 'bend: negative arc',\n stack: [{ type: 'bend', options: { curvature: -0.8, angle: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: 90° hinge',\n stack: [{ type: 'fold', options: { angle: 90, offset: 0, foldAngle: 90, radius: 0.06 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'fold: deep fold, travelling down',\n stack: [{ type: 'fold', options: { angle: 270, offset: 0.2, foldAngle: 165, radius: 0.04 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'wave: free ripple at t=1.234',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.05, wavelength: 0.5, speed: 1, angle: 20, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1 },\n t: 1.234,\n },\n {\n name: 'wave: pinned top at t=2.5',\n stack: [\n {\n type: 'wave',\n options: { amplitude: 0.04, wavelength: 0.4, speed: 1.5, angle: 80, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.2, height: 1.5 },\n t: 2.5,\n },\n {\n name: 'drape: banner hung from the top',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.17, folds: 5, falloff: 1.6, irregular: 0.45, gather: 0.5, pinnedEdge: 'top' },\n },\n ],\n sheet: { width: 1.5, height: 8.5 },\n t: 0,\n },\n {\n name: 'drape: deep irregular folds pinned at the bottom',\n stack: [\n {\n type: 'drape',\n options: { amplitude: 0.55, folds: 11, falloff: 0.4, irregular: 1, gather: 1, pinnedEdge: 'bottom' },\n },\n ],\n sheet: { width: 2.2, height: 3 },\n t: 0,\n },\n {\n name: 'crumple: defaults',\n stack: [{ type: 'crumple', options: { amount: 0.35, scale: 3, pull: 0.4, seed: 0 } }],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n // The adversarial one. `fract` is a sawtooth, so the two halves disagree\n // hardest where a crease lands exactly on a sample — a fine scale and a\n // seed whose fold directions are near-axis puts the most creases in\n // reach of the grid.\n name: 'crumple: fully crushed, fine creases, off-axis seed',\n stack: [{ type: 'crumple', options: { amount: 1, scale: 7.5, pull: 1, seed: 5 } }],\n sheet: { width: 1.3, height: 0.9 },\n t: 0,\n },\n {\n // Crush then curl, which is the order the crumple BEHAVIOR stacks them:\n // the creases have to be placed on the flat sheet, not on a bent one.\n name: 'stacked: crumple ∘ bend (the crumple behavior)',\n stack: [\n { type: 'crumple', options: { amount: 0.62, scale: 3.3, pull: 0.5, seed: 2 } },\n { type: 'bend', options: { curvature: 0.31, angle: 35 } },\n ],\n sheet: { width: 1.1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: letter-fold pair (fold ∘ fold)',\n stack: [\n { type: 'fold', options: { angle: 270, offset: 0.2333, foldAngle: 120, radius: 0.05 } },\n { type: 'fold', options: { angle: 90, offset: 0.2333, foldAngle: 100, radius: 0.08 } },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'stacked: bend ∘ roll ∘ wave',\n stack: [\n { type: 'bend', options: { curvature: 0.6, angle: 0 } },\n { type: 'roll', options: { angle: 90, boundary: 0.1, radius: 0.15, thickness: 0 } },\n {\n type: 'wave',\n options: { amplitude: 0.02, wavelength: 0.6, speed: 0.7, angle: 45, pinnedEdge: 'none' },\n },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0.8,\n },\n]\n\nfunction buildParityFragment(stack: DeformerInstance[], sheet: SheetDims): string {\n const composed = buildDisplacementGLSL(stack, sheet)\n return /* glsl */ `#version 300 es\nprecision highp float;\nuniform float uPlTime;\nuniform float uPlBias;\n${composed.functionsSrc}\n${composed.displaceSrc}\nout vec4 outColor;\nvoid main() {\n vec2 uv = (gl_FragCoord.xy - 0.5) / float(${GRID - 1});\n vec3 p = vec3((uv - 0.5) * uSheet, 0.0);\n outColor = vec4(plDisplace(p, uv, uPlTime, uPlBias), 1.0);\n}\n`\n}\n\nconst VERT = `#version 300 es\nin vec2 aPos;\nvoid main() { gl_Position = vec4(aPos, 0.0, 1.0); }\n`\n\nfunction compile(gl: WebGL2RenderingContext, type: number, src: string): WebGLShader {\n const shader = gl.createShader(type)!\n gl.shaderSource(shader, src)\n gl.compileShader(shader)\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n throw new Error(`[paperlab parity] shader compile failed: ${gl.getShaderInfoLog(shader)}`)\n }\n return shader\n}\n\nfunction runCaseOnGPU(gl: WebGL2RenderingContext, c: ParityCase, bias = 1): Float32Array {\n const composed = buildDisplacementGLSL(c.stack, c.sheet)\n const program = gl.createProgram()!\n gl.attachShader(program, compile(gl, gl.VERTEX_SHADER, VERT))\n gl.attachShader(program, compile(gl, gl.FRAGMENT_SHADER, buildParityFragment(c.stack, c.sheet)))\n gl.linkProgram(program)\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error(`[paperlab parity] link failed: ${gl.getProgramInfoLog(program)}`)\n }\n // biome-ignore lint/correctness/useHookAtTopLevel: WebGL's gl.useProgram, not a React hook\n gl.useProgram(program)\n\n for (const [name, value] of Object.entries(composed.uniforms)) {\n const loc = gl.getUniformLocation(program, name)\n if (!loc) continue\n if (typeof value === 'number') gl.uniform1f(loc, value)\n else if (value.length === 2) gl.uniform2f(loc, value[0]!, value[1]!)\n else if (value.length === 3) gl.uniform3f(loc, value[0]!, value[1]!, value[2]!)\n else gl.uniform4f(loc, value[0]!, value[1]!, value[2]!, value[3]!)\n }\n const timeLoc = gl.getUniformLocation(program, 'uPlTime')\n if (timeLoc) gl.uniform1f(timeLoc, c.t)\n const biasLoc = gl.getUniformLocation(program, 'uPlBias')\n if (biasLoc) gl.uniform1f(biasLoc, bias)\n\n const quad = gl.createBuffer()!\n gl.bindBuffer(gl.ARRAY_BUFFER, quad)\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 3, -1, -1, 3]), gl.STATIC_DRAW)\n const posLoc = gl.getAttribLocation(program, 'aPos')\n gl.enableVertexAttribArray(posLoc)\n gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0)\n\n const tex = gl.createTexture()!\n gl.bindTexture(gl.TEXTURE_2D, tex)\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA32F, GRID, GRID, 0, gl.RGBA, gl.FLOAT, null)\n const fbo = gl.createFramebuffer()!\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)\n gl.viewport(0, 0, GRID, GRID)\n gl.drawArrays(gl.TRIANGLES, 0, 3)\n\n const out = new Float32Array(GRID * GRID * 4)\n gl.readPixels(0, 0, GRID, GRID, gl.RGBA, gl.FLOAT, out)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null)\n return out\n}\n\n/**\n * The bias contract, checked on the GPU: a stack of strength-bearing\n * deformers must go completely flat at bias 0, and a stack of deformers that\n * opt out (roll) must ignore bias entirely. Parity alone can't catch this —\n * it only ever evaluates bias 1.\n */\nfunction runBiasCases(gl: WebGL2RenderingContext): ParityResult[] {\n const results: ParityResult[] = []\n for (const c of parityCases) {\n const strengths = c.stack.map((i) => getDeformer(i.type).glsl?.strength !== undefined)\n // Mixed stacks flatten only partway — nothing crisp to assert.\n if (!strengths.every((h) => h === strengths[0])) continue\n const scales = strengths[0]\n\n const at0 = runCaseOnGPU(gl, c, 0)\n const reference = scales ? null : runCaseOnGPU(gl, c, 1)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const i4 = (row * GRID + col) * 4\n // At bias 0 a scaling stack collapses onto the flat sheet; an opted-out\n // stack must land exactly where bias 1 put it.\n const ex = reference ? reference[i4]! : (col / (GRID - 1) - 0.5) * c.sheet.width\n const ey = reference ? reference[i4 + 1]! : (row / (GRID - 1) - 0.5) * c.sheet.height\n const ez = reference ? reference[i4 + 2]! : 0\n maxError = Math.max(\n maxError,\n Math.abs(at0[i4]! - ex),\n Math.abs(at0[i4 + 1]! - ey),\n Math.abs(at0[i4 + 2]! - ez),\n )\n }\n }\n results.push({\n name: `bias: ${c.name} → ${scales ? 'flat at 0' : 'ignores bias'}`,\n maxError,\n pass: maxError < PARITY_EPSILON,\n })\n }\n return results\n}\n\n/** Run every parity case. Requires a WebGL2 context with float render targets. */\nexport function runParityHarness(canvas?: HTMLCanvasElement): ParityResult[] {\n const cnv = canvas ?? document.createElement('canvas')\n const gl = cnv.getContext('webgl2')\n if (!gl) throw new Error('[paperlab parity] WebGL2 unavailable')\n if (!gl.getExtension('EXT_color_buffer_float')) {\n throw new Error('[paperlab parity] EXT_color_buffer_float unavailable')\n }\n\n const point = new THREE.Vector3()\n const parity = parityCases.map((c) => {\n const gpu = runCaseOnGPU(gl, c)\n let maxError = 0\n for (let row = 0; row < GRID; row++) {\n for (let col = 0; col < GRID; col++) {\n const u = col / (GRID - 1)\n const v = row / (GRID - 1)\n point.set((u - 0.5) * c.sheet.width, (v - 0.5) * c.sheet.height, 0)\n displacePoint(point, u, v, c.stack, { t: c.t, sheet: c.sheet })\n const i4 = (row * GRID + col) * 4\n maxError = Math.max(\n maxError,\n Math.abs(gpu[i4]! - point.x),\n Math.abs(gpu[i4 + 1]! - point.y),\n Math.abs(gpu[i4 + 2]! - point.z),\n )\n }\n }\n return { name: c.name, maxError, pass: maxError < PARITY_EPSILON }\n })\n return [...parity, ...runBiasCases(gl)]\n}\n"],"mappings":"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","names":["Paper"]}
@@ -1252,6 +1252,12 @@ declare const sceneSchema: z.ZodObject<{
1252
1252
  raking: "raking";
1253
1253
  lightbox: "lightbox";
1254
1254
  }>>;
1255
+ floor: z.ZodPrefault<z.ZodObject<{
1256
+ enabled: z.ZodDefault<z.ZodBoolean>;
1257
+ color: z.ZodDefault<z.ZodString>;
1258
+ y: z.ZodDefault<z.ZodNumber>;
1259
+ roughness: z.ZodDefault<z.ZodNumber>;
1260
+ }, z.core.$strip>>;
1255
1261
  backdrop: z.ZodOptional<z.ZodObject<{
1256
1262
  color: z.ZodDefault<z.ZodString>;
1257
1263
  image: z.ZodDefault<z.ZodString>;
@@ -2235,6 +2241,12 @@ declare const paperConfigSchema: z.ZodObject<{
2235
2241
  raking: "raking";
2236
2242
  lightbox: "lightbox";
2237
2243
  }>>;
2244
+ floor: z.ZodPrefault<z.ZodObject<{
2245
+ enabled: z.ZodDefault<z.ZodBoolean>;
2246
+ color: z.ZodDefault<z.ZodString>;
2247
+ y: z.ZodDefault<z.ZodNumber>;
2248
+ roughness: z.ZodDefault<z.ZodNumber>;
2249
+ }, z.core.$strip>>;
2238
2250
  backdrop: z.ZodOptional<z.ZodObject<{
2239
2251
  color: z.ZodDefault<z.ZodString>;
2240
2252
  image: z.ZodDefault<z.ZodString>;
@@ -1252,6 +1252,12 @@ declare const sceneSchema: z.ZodObject<{
1252
1252
  raking: "raking";
1253
1253
  lightbox: "lightbox";
1254
1254
  }>>;
1255
+ floor: z.ZodPrefault<z.ZodObject<{
1256
+ enabled: z.ZodDefault<z.ZodBoolean>;
1257
+ color: z.ZodDefault<z.ZodString>;
1258
+ y: z.ZodDefault<z.ZodNumber>;
1259
+ roughness: z.ZodDefault<z.ZodNumber>;
1260
+ }, z.core.$strip>>;
1255
1261
  backdrop: z.ZodOptional<z.ZodObject<{
1256
1262
  color: z.ZodDefault<z.ZodString>;
1257
1263
  image: z.ZodDefault<z.ZodString>;
@@ -2235,6 +2241,12 @@ declare const paperConfigSchema: z.ZodObject<{
2235
2241
  raking: "raking";
2236
2242
  lightbox: "lightbox";
2237
2243
  }>>;
2244
+ floor: z.ZodPrefault<z.ZodObject<{
2245
+ enabled: z.ZodDefault<z.ZodBoolean>;
2246
+ color: z.ZodDefault<z.ZodString>;
2247
+ y: z.ZodDefault<z.ZodNumber>;
2248
+ roughness: z.ZodDefault<z.ZodNumber>;
2249
+ }, z.core.$strip>>;
2238
2250
  backdrop: z.ZodOptional<z.ZodObject<{
2239
2251
  color: z.ZodDefault<z.ZodString>;
2240
2252
  image: z.ZodDefault<z.ZodString>;