paperlab 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -7
- package/dist/{chunk-LUKNPQ3S.js → chunk-YQFQT3AH.js} +3321 -757
- package/dist/chunk-YQFQT3AH.js.map +1 -0
- package/dist/index.cjs +3374 -773
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -3
- package/dist/index.d.ts +61 -3
- package/dist/index.js +48 -3
- package/dist/index.js.map +1 -1
- package/dist/{slots-DbJQfwVd.d.cts → slots-BAVzglHw.d.cts} +124 -3
- package/dist/{slots-DbJQfwVd.d.ts → slots-BAVzglHw.d.ts} +124 -3
- package/dist/stage.cjs +3513 -955
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.cts +1 -1
- package/dist/stage.d.ts +1 -1
- package/dist/stage.js +3 -2
- package/dist/stage.js.map +1 -1
- package/package.json +10 -10
- package/dist/chunk-LUKNPQ3S.js.map +0 -1
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 // 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"]}
|
|
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'\nimport { CANVAS_SHADOWS } from './scene/shadows'\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={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 {config.scene.floor.roughness >= 1 ? (\n // Chalk: all the way matte, no highlight at all. A standard material,\n // even at full roughness, turns into a mirror of the key at a grazing\n // angle, which drew a bright band across a black set.\n <meshLambertMaterial color={config.scene.floor.color} />\n ) : (\n <meshStandardMaterial\n color={config.scene.floor.color}\n roughness={config.scene.floor.roughness}\n />\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: 'lift: part-way, rolled back flat',\n stack: [\n { type: 'lift', options: { angle: 145, front: 0.45, radius: 0.05, flap: 180, tension: 0, release: 0 } },\n ],\n sheet: { width: 0.8, height: 0.5 },\n t: 0,\n },\n {\n // Past the arc into the straight run, with the glue holding: the fillet\n // on the stuck side and the tightened bend both have to agree.\n name: 'lift: held flap under tension',\n stack: [\n {\n type: 'lift',\n options: { angle: -30, front: 0.7, radius: 0.08, flap: 120, tension: 0.8, release: 0 },\n },\n ],\n sheet: { width: 1, height: 1.4 },\n t: 0,\n },\n {\n name: 'lift: released and springing away',\n stack: [\n { type: 'lift', options: { angle: 90, front: 1, radius: 0.04, flap: 168, tension: 0, release: 0.6 } },\n ],\n sheet: { width: 0.6, height: 0.6 },\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"]}
|
|
@@ -23,13 +23,13 @@ declare const sheetSchema: z.ZodObject<{
|
|
|
23
23
|
type SheetConfig = z.infer<typeof sheetSchema>;
|
|
24
24
|
declare const stockNames: readonly ["printer", "thermal", "kraft", "newsprint", "vellum", "photo-gloss", "sticker"];
|
|
25
25
|
declare const stockSchema: z.ZodEnum<{
|
|
26
|
+
sticker: "sticker";
|
|
26
27
|
printer: "printer";
|
|
27
28
|
thermal: "thermal";
|
|
28
29
|
kraft: "kraft";
|
|
29
30
|
newsprint: "newsprint";
|
|
30
31
|
vellum: "vellum";
|
|
31
32
|
"photo-gloss": "photo-gloss";
|
|
32
|
-
sticker: "sticker";
|
|
33
33
|
}>;
|
|
34
34
|
type StockName = z.infer<typeof stockSchema>;
|
|
35
35
|
/**
|
|
@@ -924,8 +924,13 @@ declare const surfaceSchema: z.ZodObject<{
|
|
|
924
924
|
}>>;
|
|
925
925
|
}, z.core.$strip>>;
|
|
926
926
|
}, z.core.$strip>>;
|
|
927
|
+
dieCut: z.ZodOptional<z.ZodObject<{
|
|
928
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
929
|
+
color: z.ZodDefault<z.ZodString>;
|
|
930
|
+
}, z.core.$strip>>;
|
|
927
931
|
}, z.core.$strip>;
|
|
928
932
|
type SurfaceConfig = z.infer<typeof surfaceSchema>;
|
|
933
|
+
type DieCutConfig = NonNullable<SurfaceConfig['dieCut']>;
|
|
929
934
|
type SurfaceConfigInput = z.input<typeof surfaceSchema>;
|
|
930
935
|
type PaperEdge = (typeof paperEdges)[number];
|
|
931
936
|
/**
|
|
@@ -1060,6 +1065,19 @@ declare const behaviorConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1060
1065
|
curl: z.ZodDefault<z.ZodNumber>;
|
|
1061
1066
|
drape: z.ZodDefault<z.ZodNumber>;
|
|
1062
1067
|
type: z.ZodLiteral<"ribbon">;
|
|
1068
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1069
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
1070
|
+
corner: z.ZodDefault<z.ZodEnum<{
|
|
1071
|
+
"top-left": "top-left";
|
|
1072
|
+
"top-right": "top-right";
|
|
1073
|
+
"bottom-left": "bottom-left";
|
|
1074
|
+
"bottom-right": "bottom-right";
|
|
1075
|
+
}>>;
|
|
1076
|
+
skew: z.ZodDefault<z.ZodNumber>;
|
|
1077
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
1078
|
+
radius: z.ZodDefault<z.ZodNumber>;
|
|
1079
|
+
flap: z.ZodDefault<z.ZodNumber>;
|
|
1080
|
+
type: z.ZodLiteral<"sticker">;
|
|
1063
1081
|
}, z.core.$strip>], "type">;
|
|
1064
1082
|
type BehaviorConfig = z.infer<typeof behaviorConfigSchema>;
|
|
1065
1083
|
type BehaviorConfigInput = z.input<typeof behaviorConfigSchema>;
|
|
@@ -1289,6 +1307,65 @@ type SceneConfig = z.infer<typeof sceneSchema>;
|
|
|
1289
1307
|
type SceneConfigInput = z.input<typeof sceneSchema>;
|
|
1290
1308
|
type LightingName = (typeof lightingNames)[number];
|
|
1291
1309
|
type FilmName = (typeof filmNames)[number];
|
|
1310
|
+
/**
|
|
1311
|
+
* Another sticker already on the object — scenery for the one that peels.
|
|
1312
|
+
*
|
|
1313
|
+
* Stuck down for good: they wrap, take the skin's texture and cast nothing,
|
|
1314
|
+
* and they are there so the sticker you peel is one of a collection rather
|
|
1315
|
+
* than alone on a bare object.
|
|
1316
|
+
*/
|
|
1317
|
+
declare const mountStickerSchema: z.ZodObject<{
|
|
1318
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
1319
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1320
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1321
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1322
|
+
src: z.ZodDefault<z.ZodString>;
|
|
1323
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
1324
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
1325
|
+
}, z.core.$strip>;
|
|
1326
|
+
type MountStickerConfig = z.infer<typeof mountStickerSchema>;
|
|
1327
|
+
declare const mountObjectNames: readonly ["lemon", "model"];
|
|
1328
|
+
/**
|
|
1329
|
+
* The thing the sheet is stuck to.
|
|
1330
|
+
*
|
|
1331
|
+
* Without one, a sheet floats in space — which is what paper does in every
|
|
1332
|
+
* other preset. With one, the sheet is a sticker: laid onto the object's
|
|
1333
|
+
* surface along geodesics so it hugs the curve, pressed into its texture
|
|
1334
|
+
* while it is stuck, and every behavior worked out flat is carried onto the
|
|
1335
|
+
* curve (`mount/wrap.ts`). A peel on a lemon is a peel on a table, wrapped.
|
|
1336
|
+
*
|
|
1337
|
+
* `lemon` is built, not loaded: the library ships no assets and fetches
|
|
1338
|
+
* none. `model` is any glTF binary you host or upload, normalised to `size`.
|
|
1339
|
+
*/
|
|
1340
|
+
declare const mountSchema: z.ZodObject<{
|
|
1341
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1342
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1343
|
+
press: z.ZodDefault<z.ZodNumber>;
|
|
1344
|
+
reveal: z.ZodDefault<z.ZodNumber>;
|
|
1345
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
1346
|
+
stickers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1347
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
1348
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1349
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1350
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1351
|
+
src: z.ZodDefault<z.ZodString>;
|
|
1352
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
1353
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
1354
|
+
}, z.core.$strip>>>;
|
|
1355
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1356
|
+
object: z.ZodDefault<z.ZodEnum<{
|
|
1357
|
+
lemon: "lemon";
|
|
1358
|
+
model: "model";
|
|
1359
|
+
}>>;
|
|
1360
|
+
model: z.ZodDefault<z.ZodString>;
|
|
1361
|
+
size: z.ZodDefault<z.ZodNumber>;
|
|
1362
|
+
tilt: z.ZodDefault<z.ZodNumber>;
|
|
1363
|
+
spin: z.ZodDefault<z.ZodNumber>;
|
|
1364
|
+
color: z.ZodDefault<z.ZodString>;
|
|
1365
|
+
pores: z.ZodDefault<z.ZodNumber>;
|
|
1366
|
+
}, z.core.$strip>;
|
|
1367
|
+
type MountConfig = z.infer<typeof mountSchema>;
|
|
1368
|
+
type MountConfigInput = z.input<typeof mountSchema>;
|
|
1292
1369
|
/**
|
|
1293
1370
|
* A state is a set of parameter overrides on the base preset — never a
|
|
1294
1371
|
* separate preset. The base stays the single source of truth; states are
|
|
@@ -1341,13 +1418,13 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
1341
1418
|
cornerRadius: z.ZodDefault<z.ZodNumber>;
|
|
1342
1419
|
}, z.core.$strip>>;
|
|
1343
1420
|
stock: z.ZodDefault<z.ZodEnum<{
|
|
1421
|
+
sticker: "sticker";
|
|
1344
1422
|
printer: "printer";
|
|
1345
1423
|
thermal: "thermal";
|
|
1346
1424
|
kraft: "kraft";
|
|
1347
1425
|
newsprint: "newsprint";
|
|
1348
1426
|
vellum: "vellum";
|
|
1349
1427
|
"photo-gloss": "photo-gloss";
|
|
1350
|
-
sticker: "sticker";
|
|
1351
1428
|
}>>;
|
|
1352
1429
|
content: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1353
1430
|
type: z.ZodLiteral<"blank">;
|
|
@@ -2115,6 +2192,19 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2115
2192
|
curl: z.ZodDefault<z.ZodNumber>;
|
|
2116
2193
|
drape: z.ZodDefault<z.ZodNumber>;
|
|
2117
2194
|
type: z.ZodLiteral<"ribbon">;
|
|
2195
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2196
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
2197
|
+
corner: z.ZodDefault<z.ZodEnum<{
|
|
2198
|
+
"top-left": "top-left";
|
|
2199
|
+
"top-right": "top-right";
|
|
2200
|
+
"bottom-left": "bottom-left";
|
|
2201
|
+
"bottom-right": "bottom-right";
|
|
2202
|
+
}>>;
|
|
2203
|
+
skew: z.ZodDefault<z.ZodNumber>;
|
|
2204
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
2205
|
+
radius: z.ZodDefault<z.ZodNumber>;
|
|
2206
|
+
flap: z.ZodDefault<z.ZodNumber>;
|
|
2207
|
+
type: z.ZodLiteral<"sticker">;
|
|
2118
2208
|
}, z.core.$strip>], "type">>;
|
|
2119
2209
|
deformers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2120
2210
|
type: z.ZodString;
|
|
@@ -2168,6 +2258,10 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2168
2258
|
}>>;
|
|
2169
2259
|
}, z.core.$strip>>;
|
|
2170
2260
|
}, z.core.$strip>>;
|
|
2261
|
+
dieCut: z.ZodOptional<z.ZodObject<{
|
|
2262
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
2263
|
+
color: z.ZodDefault<z.ZodString>;
|
|
2264
|
+
}, z.core.$strip>>;
|
|
2171
2265
|
}, z.core.$strip>>;
|
|
2172
2266
|
memory: z.ZodPrefault<z.ZodObject<{
|
|
2173
2267
|
set: z.ZodOptional<z.ZodNumber>;
|
|
@@ -2287,6 +2381,33 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2287
2381
|
}, z.core.$strip>>>;
|
|
2288
2382
|
pickThreshold: z.ZodDefault<z.ZodNumber>;
|
|
2289
2383
|
}, z.core.$strip>>;
|
|
2384
|
+
mount: z.ZodOptional<z.ZodObject<{
|
|
2385
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
2386
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
2387
|
+
press: z.ZodDefault<z.ZodNumber>;
|
|
2388
|
+
reveal: z.ZodDefault<z.ZodNumber>;
|
|
2389
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
2390
|
+
stickers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
2391
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
2392
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
2393
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
2394
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
2395
|
+
src: z.ZodDefault<z.ZodString>;
|
|
2396
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
2397
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
2398
|
+
}, z.core.$strip>>>;
|
|
2399
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
2400
|
+
object: z.ZodDefault<z.ZodEnum<{
|
|
2401
|
+
lemon: "lemon";
|
|
2402
|
+
model: "model";
|
|
2403
|
+
}>>;
|
|
2404
|
+
model: z.ZodDefault<z.ZodString>;
|
|
2405
|
+
size: z.ZodDefault<z.ZodNumber>;
|
|
2406
|
+
tilt: z.ZodDefault<z.ZodNumber>;
|
|
2407
|
+
spin: z.ZodDefault<z.ZodNumber>;
|
|
2408
|
+
color: z.ZodDefault<z.ZodString>;
|
|
2409
|
+
pores: z.ZodDefault<z.ZodNumber>;
|
|
2410
|
+
}, z.core.$strip>>;
|
|
2290
2411
|
}, z.core.$strip>;
|
|
2291
2412
|
type PaperConfig = z.infer<typeof paperConfigSchema>;
|
|
2292
2413
|
type PaperConfigInput = z.input<typeof paperConfigSchema>;
|
|
@@ -2306,4 +2427,4 @@ interface FieldPaperSlot {
|
|
|
2306
2427
|
states?: PaperStatesInput;
|
|
2307
2428
|
}
|
|
2308
2429
|
|
|
2309
|
-
export {
|
|
2430
|
+
export { mountStickerSchema as $, type SceneConfig as A, type BehaviorConfigInput as B, type ContentConfigInput as C, type DeformerInstanceConfigInput as D, type StateDef as E, type FieldPaperSlot as F, type StateName as G, type StateTransitionConfig as H, type StripConfig as I, type SurfaceConfig as J, backdropSchema as K, type LightingName as L, type MemoryConfigInput as M, behaviorConfigSchema as N, clothConfigSchema as O, type PaperConfig as P, contentNames as Q, contentSchemaFor as R, type SheetConfig as S, coreStateNames as T, creaseSchema as U, lightSchema as V, type WashConfig as W, lightingNames as X, memorySchema as Y, mountObjectNames as Z, mountSchema as _, type PaperConfigInput as a, paperConfigSchema as a0, paperEdges as a1, paperStatesSchema as a2, physicsNames as a3, sceneSchema as a4, stateDefSchema as a5, stockNames as a6, stripConfigSchema as a7, washSchema as a8, type StockName as b, type SurfaceConfigInput as c, type SceneConfigInput as d, type PhysicsConfigInput as e, type MountConfigInput as f, type CreaseConfig as g, type ContentConfig as h, type PaperStatesInput as i, type FilmName as j, type LightOverrides as k, type BackdropConfig as l, type BackContentConfig as m, type BehaviorConfig as n, type ClothConfig as o, type CoreStateName as p, type CreaseConfigInput as q, type DeformerInstanceConfig as r, type DieCutConfig as s, type LightOverridesInput as t, type MemoryConfig as u, type MountConfig as v, type MountStickerConfig as w, type PaperEdge as x, type PaperStates as y, type PhysicsConfig as z };
|
|
@@ -23,13 +23,13 @@ declare const sheetSchema: z.ZodObject<{
|
|
|
23
23
|
type SheetConfig = z.infer<typeof sheetSchema>;
|
|
24
24
|
declare const stockNames: readonly ["printer", "thermal", "kraft", "newsprint", "vellum", "photo-gloss", "sticker"];
|
|
25
25
|
declare const stockSchema: z.ZodEnum<{
|
|
26
|
+
sticker: "sticker";
|
|
26
27
|
printer: "printer";
|
|
27
28
|
thermal: "thermal";
|
|
28
29
|
kraft: "kraft";
|
|
29
30
|
newsprint: "newsprint";
|
|
30
31
|
vellum: "vellum";
|
|
31
32
|
"photo-gloss": "photo-gloss";
|
|
32
|
-
sticker: "sticker";
|
|
33
33
|
}>;
|
|
34
34
|
type StockName = z.infer<typeof stockSchema>;
|
|
35
35
|
/**
|
|
@@ -924,8 +924,13 @@ declare const surfaceSchema: z.ZodObject<{
|
|
|
924
924
|
}>>;
|
|
925
925
|
}, z.core.$strip>>;
|
|
926
926
|
}, z.core.$strip>>;
|
|
927
|
+
dieCut: z.ZodOptional<z.ZodObject<{
|
|
928
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
929
|
+
color: z.ZodDefault<z.ZodString>;
|
|
930
|
+
}, z.core.$strip>>;
|
|
927
931
|
}, z.core.$strip>;
|
|
928
932
|
type SurfaceConfig = z.infer<typeof surfaceSchema>;
|
|
933
|
+
type DieCutConfig = NonNullable<SurfaceConfig['dieCut']>;
|
|
929
934
|
type SurfaceConfigInput = z.input<typeof surfaceSchema>;
|
|
930
935
|
type PaperEdge = (typeof paperEdges)[number];
|
|
931
936
|
/**
|
|
@@ -1060,6 +1065,19 @@ declare const behaviorConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
1060
1065
|
curl: z.ZodDefault<z.ZodNumber>;
|
|
1061
1066
|
drape: z.ZodDefault<z.ZodNumber>;
|
|
1062
1067
|
type: z.ZodLiteral<"ribbon">;
|
|
1068
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1069
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
1070
|
+
corner: z.ZodDefault<z.ZodEnum<{
|
|
1071
|
+
"top-left": "top-left";
|
|
1072
|
+
"top-right": "top-right";
|
|
1073
|
+
"bottom-left": "bottom-left";
|
|
1074
|
+
"bottom-right": "bottom-right";
|
|
1075
|
+
}>>;
|
|
1076
|
+
skew: z.ZodDefault<z.ZodNumber>;
|
|
1077
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
1078
|
+
radius: z.ZodDefault<z.ZodNumber>;
|
|
1079
|
+
flap: z.ZodDefault<z.ZodNumber>;
|
|
1080
|
+
type: z.ZodLiteral<"sticker">;
|
|
1063
1081
|
}, z.core.$strip>], "type">;
|
|
1064
1082
|
type BehaviorConfig = z.infer<typeof behaviorConfigSchema>;
|
|
1065
1083
|
type BehaviorConfigInput = z.input<typeof behaviorConfigSchema>;
|
|
@@ -1289,6 +1307,65 @@ type SceneConfig = z.infer<typeof sceneSchema>;
|
|
|
1289
1307
|
type SceneConfigInput = z.input<typeof sceneSchema>;
|
|
1290
1308
|
type LightingName = (typeof lightingNames)[number];
|
|
1291
1309
|
type FilmName = (typeof filmNames)[number];
|
|
1310
|
+
/**
|
|
1311
|
+
* Another sticker already on the object — scenery for the one that peels.
|
|
1312
|
+
*
|
|
1313
|
+
* Stuck down for good: they wrap, take the skin's texture and cast nothing,
|
|
1314
|
+
* and they are there so the sticker you peel is one of a collection rather
|
|
1315
|
+
* than alone on a bare object.
|
|
1316
|
+
*/
|
|
1317
|
+
declare const mountStickerSchema: z.ZodObject<{
|
|
1318
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
1319
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1320
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1321
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1322
|
+
src: z.ZodDefault<z.ZodString>;
|
|
1323
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
1324
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
1325
|
+
}, z.core.$strip>;
|
|
1326
|
+
type MountStickerConfig = z.infer<typeof mountStickerSchema>;
|
|
1327
|
+
declare const mountObjectNames: readonly ["lemon", "model"];
|
|
1328
|
+
/**
|
|
1329
|
+
* The thing the sheet is stuck to.
|
|
1330
|
+
*
|
|
1331
|
+
* Without one, a sheet floats in space — which is what paper does in every
|
|
1332
|
+
* other preset. With one, the sheet is a sticker: laid onto the object's
|
|
1333
|
+
* surface along geodesics so it hugs the curve, pressed into its texture
|
|
1334
|
+
* while it is stuck, and every behavior worked out flat is carried onto the
|
|
1335
|
+
* curve (`mount/wrap.ts`). A peel on a lemon is a peel on a table, wrapped.
|
|
1336
|
+
*
|
|
1337
|
+
* `lemon` is built, not loaded: the library ships no assets and fetches
|
|
1338
|
+
* none. `model` is any glTF binary you host or upload, normalised to `size`.
|
|
1339
|
+
*/
|
|
1340
|
+
declare const mountSchema: z.ZodObject<{
|
|
1341
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1342
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1343
|
+
press: z.ZodDefault<z.ZodNumber>;
|
|
1344
|
+
reveal: z.ZodDefault<z.ZodNumber>;
|
|
1345
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
1346
|
+
stickers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1347
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
1348
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1349
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
1350
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
1351
|
+
src: z.ZodDefault<z.ZodString>;
|
|
1352
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
1353
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
1354
|
+
}, z.core.$strip>>>;
|
|
1355
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
1356
|
+
object: z.ZodDefault<z.ZodEnum<{
|
|
1357
|
+
lemon: "lemon";
|
|
1358
|
+
model: "model";
|
|
1359
|
+
}>>;
|
|
1360
|
+
model: z.ZodDefault<z.ZodString>;
|
|
1361
|
+
size: z.ZodDefault<z.ZodNumber>;
|
|
1362
|
+
tilt: z.ZodDefault<z.ZodNumber>;
|
|
1363
|
+
spin: z.ZodDefault<z.ZodNumber>;
|
|
1364
|
+
color: z.ZodDefault<z.ZodString>;
|
|
1365
|
+
pores: z.ZodDefault<z.ZodNumber>;
|
|
1366
|
+
}, z.core.$strip>;
|
|
1367
|
+
type MountConfig = z.infer<typeof mountSchema>;
|
|
1368
|
+
type MountConfigInput = z.input<typeof mountSchema>;
|
|
1292
1369
|
/**
|
|
1293
1370
|
* A state is a set of parameter overrides on the base preset — never a
|
|
1294
1371
|
* separate preset. The base stays the single source of truth; states are
|
|
@@ -1341,13 +1418,13 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
1341
1418
|
cornerRadius: z.ZodDefault<z.ZodNumber>;
|
|
1342
1419
|
}, z.core.$strip>>;
|
|
1343
1420
|
stock: z.ZodDefault<z.ZodEnum<{
|
|
1421
|
+
sticker: "sticker";
|
|
1344
1422
|
printer: "printer";
|
|
1345
1423
|
thermal: "thermal";
|
|
1346
1424
|
kraft: "kraft";
|
|
1347
1425
|
newsprint: "newsprint";
|
|
1348
1426
|
vellum: "vellum";
|
|
1349
1427
|
"photo-gloss": "photo-gloss";
|
|
1350
|
-
sticker: "sticker";
|
|
1351
1428
|
}>>;
|
|
1352
1429
|
content: z.ZodDefault<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1353
1430
|
type: z.ZodLiteral<"blank">;
|
|
@@ -2115,6 +2192,19 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2115
2192
|
curl: z.ZodDefault<z.ZodNumber>;
|
|
2116
2193
|
drape: z.ZodDefault<z.ZodNumber>;
|
|
2117
2194
|
type: z.ZodLiteral<"ribbon">;
|
|
2195
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
2196
|
+
progress: z.ZodDefault<z.ZodNumber>;
|
|
2197
|
+
corner: z.ZodDefault<z.ZodEnum<{
|
|
2198
|
+
"top-left": "top-left";
|
|
2199
|
+
"top-right": "top-right";
|
|
2200
|
+
"bottom-left": "bottom-left";
|
|
2201
|
+
"bottom-right": "bottom-right";
|
|
2202
|
+
}>>;
|
|
2203
|
+
skew: z.ZodDefault<z.ZodNumber>;
|
|
2204
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
2205
|
+
radius: z.ZodDefault<z.ZodNumber>;
|
|
2206
|
+
flap: z.ZodDefault<z.ZodNumber>;
|
|
2207
|
+
type: z.ZodLiteral<"sticker">;
|
|
2118
2208
|
}, z.core.$strip>], "type">>;
|
|
2119
2209
|
deformers: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2120
2210
|
type: z.ZodString;
|
|
@@ -2168,6 +2258,10 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2168
2258
|
}>>;
|
|
2169
2259
|
}, z.core.$strip>>;
|
|
2170
2260
|
}, z.core.$strip>>;
|
|
2261
|
+
dieCut: z.ZodOptional<z.ZodObject<{
|
|
2262
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
2263
|
+
color: z.ZodDefault<z.ZodString>;
|
|
2264
|
+
}, z.core.$strip>>;
|
|
2171
2265
|
}, z.core.$strip>>;
|
|
2172
2266
|
memory: z.ZodPrefault<z.ZodObject<{
|
|
2173
2267
|
set: z.ZodOptional<z.ZodNumber>;
|
|
@@ -2287,6 +2381,33 @@ declare const paperConfigSchema: z.ZodObject<{
|
|
|
2287
2381
|
}, z.core.$strip>>>;
|
|
2288
2382
|
pickThreshold: z.ZodDefault<z.ZodNumber>;
|
|
2289
2383
|
}, z.core.$strip>>;
|
|
2384
|
+
mount: z.ZodOptional<z.ZodObject<{
|
|
2385
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
2386
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
2387
|
+
press: z.ZodDefault<z.ZodNumber>;
|
|
2388
|
+
reveal: z.ZodDefault<z.ZodNumber>;
|
|
2389
|
+
tack: z.ZodDefault<z.ZodNumber>;
|
|
2390
|
+
stickers: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
2391
|
+
margin: z.ZodDefault<z.ZodNumber>;
|
|
2392
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
2393
|
+
elevation: z.ZodDefault<z.ZodNumber>;
|
|
2394
|
+
roll: z.ZodDefault<z.ZodNumber>;
|
|
2395
|
+
src: z.ZodDefault<z.ZodString>;
|
|
2396
|
+
width: z.ZodDefault<z.ZodNumber>;
|
|
2397
|
+
height: z.ZodDefault<z.ZodNumber>;
|
|
2398
|
+
}, z.core.$strip>>>;
|
|
2399
|
+
azimuth: z.ZodDefault<z.ZodNumber>;
|
|
2400
|
+
object: z.ZodDefault<z.ZodEnum<{
|
|
2401
|
+
lemon: "lemon";
|
|
2402
|
+
model: "model";
|
|
2403
|
+
}>>;
|
|
2404
|
+
model: z.ZodDefault<z.ZodString>;
|
|
2405
|
+
size: z.ZodDefault<z.ZodNumber>;
|
|
2406
|
+
tilt: z.ZodDefault<z.ZodNumber>;
|
|
2407
|
+
spin: z.ZodDefault<z.ZodNumber>;
|
|
2408
|
+
color: z.ZodDefault<z.ZodString>;
|
|
2409
|
+
pores: z.ZodDefault<z.ZodNumber>;
|
|
2410
|
+
}, z.core.$strip>>;
|
|
2290
2411
|
}, z.core.$strip>;
|
|
2291
2412
|
type PaperConfig = z.infer<typeof paperConfigSchema>;
|
|
2292
2413
|
type PaperConfigInput = z.input<typeof paperConfigSchema>;
|
|
@@ -2306,4 +2427,4 @@ interface FieldPaperSlot {
|
|
|
2306
2427
|
states?: PaperStatesInput;
|
|
2307
2428
|
}
|
|
2308
2429
|
|
|
2309
|
-
export {
|
|
2430
|
+
export { mountStickerSchema as $, type SceneConfig as A, type BehaviorConfigInput as B, type ContentConfigInput as C, type DeformerInstanceConfigInput as D, type StateDef as E, type FieldPaperSlot as F, type StateName as G, type StateTransitionConfig as H, type StripConfig as I, type SurfaceConfig as J, backdropSchema as K, type LightingName as L, type MemoryConfigInput as M, behaviorConfigSchema as N, clothConfigSchema as O, type PaperConfig as P, contentNames as Q, contentSchemaFor as R, type SheetConfig as S, coreStateNames as T, creaseSchema as U, lightSchema as V, type WashConfig as W, lightingNames as X, memorySchema as Y, mountObjectNames as Z, mountSchema as _, type PaperConfigInput as a, paperConfigSchema as a0, paperEdges as a1, paperStatesSchema as a2, physicsNames as a3, sceneSchema as a4, stateDefSchema as a5, stockNames as a6, stripConfigSchema as a7, washSchema as a8, type StockName as b, type SurfaceConfigInput as c, type SceneConfigInput as d, type PhysicsConfigInput as e, type MountConfigInput as f, type CreaseConfig as g, type ContentConfig as h, type PaperStatesInput as i, type FilmName as j, type LightOverrides as k, type BackdropConfig as l, type BackContentConfig as m, type BehaviorConfig as n, type ClothConfig as o, type CoreStateName as p, type CreaseConfigInput as q, type DeformerInstanceConfig as r, type DieCutConfig as s, type LightOverridesInput as t, type MemoryConfig as u, type MountConfig as v, type MountStickerConfig as w, type PaperEdge as x, type PaperStates as y, type PhysicsConfig as z };
|