@pixerate/editor 0.115.0 → 0.116.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 (117) hide show
  1. package/THIRD_PARTY_NOTICES.md +3 -0
  2. package/dist/animation-editor/index.cjs +54 -54
  3. package/dist/animation-editor/index.d.cts +2 -2
  4. package/dist/animation-editor/index.d.ts +2 -2
  5. package/dist/animation-editor/index.js +2 -2
  6. package/dist/{chunk-DFQEX3AM.cjs → chunk-2UT4GXYA.cjs} +133 -8
  7. package/dist/chunk-2UT4GXYA.cjs.map +1 -0
  8. package/dist/{chunk-VXR7XWMF.js → chunk-7LNZAWSJ.js} +437 -41
  9. package/dist/chunk-7LNZAWSJ.js.map +1 -0
  10. package/dist/{chunk-LKCYANMW.js → chunk-ARQ7PQ6Q.js} +129 -4
  11. package/dist/chunk-ARQ7PQ6Q.js.map +1 -0
  12. package/dist/chunk-COAMRKVI.cjs +159 -0
  13. package/dist/chunk-COAMRKVI.cjs.map +1 -0
  14. package/dist/{chunk-C6C5PDKU.js → chunk-D53KSJUV.js} +3 -322
  15. package/dist/chunk-D53KSJUV.js.map +1 -0
  16. package/dist/chunk-D53VQGEJ.js +3262 -0
  17. package/dist/chunk-D53VQGEJ.js.map +1 -0
  18. package/dist/chunk-EJVDBITD.cjs +501 -0
  19. package/dist/chunk-EJVDBITD.cjs.map +1 -0
  20. package/dist/{chunk-LPLCWZTM.cjs → chunk-FODKPD44.cjs} +555 -159
  21. package/dist/chunk-FODKPD44.cjs.map +1 -0
  22. package/dist/chunk-HOCPSFGA.cjs +3262 -0
  23. package/dist/chunk-HOCPSFGA.cjs.map +1 -0
  24. package/dist/chunk-IPFRWILU.js +1908 -0
  25. package/dist/chunk-IPFRWILU.js.map +1 -0
  26. package/dist/{chunk-FV5AXTSF.cjs → chunk-JSSBHMMU.cjs} +36 -188
  27. package/dist/chunk-JSSBHMMU.cjs.map +1 -0
  28. package/dist/chunk-LF4WOZXZ.js +159 -0
  29. package/dist/chunk-LF4WOZXZ.js.map +1 -0
  30. package/dist/{chunk-26PGXHY7.cjs → chunk-M7O4BJRH.cjs} +36 -36
  31. package/dist/{chunk-26PGXHY7.cjs.map → chunk-M7O4BJRH.cjs.map} +1 -1
  32. package/dist/chunk-N3467VD6.js +501 -0
  33. package/dist/chunk-N3467VD6.js.map +1 -0
  34. package/dist/{chunk-ST7E3NEE.cjs → chunk-PAOWHJ5O.cjs} +18 -337
  35. package/dist/chunk-PAOWHJ5O.cjs.map +1 -0
  36. package/dist/{chunk-XICA4PVO.js → chunk-SEBYNBHW.js} +10 -10
  37. package/dist/chunk-SMJGE7HM.cjs +1908 -0
  38. package/dist/chunk-SMJGE7HM.cjs.map +1 -0
  39. package/dist/{chunk-MMVHBKMM.js → chunk-T2P5TIZ6.js} +2 -2
  40. package/dist/{chunk-FGW5OWJ4.js → chunk-VJUML33I.js} +4 -156
  41. package/dist/chunk-VJUML33I.js.map +1 -0
  42. package/dist/{chunk-I7FQBWMQ.cjs → chunk-ZYZGEILO.cjs} +239 -239
  43. package/dist/{chunk-I7FQBWMQ.cjs.map → chunk-ZYZGEILO.cjs.map} +1 -1
  44. package/dist/export/index.cjs +4 -2
  45. package/dist/export/index.cjs.map +1 -1
  46. package/dist/export/index.js +5 -3
  47. package/dist/{export-BJE8T0YA.d.cts → export-BXxSGBCq.d.cts} +2 -2
  48. package/dist/{export-Con3UKkm.d.ts → export-Dm44YUvS.d.ts} +2 -2
  49. package/dist/export-Dv0-ZVrV.d.cts +501 -0
  50. package/dist/export-Dv0-ZVrV.d.ts +501 -0
  51. package/dist/{retouch-Do6tBs2H.d.ts → flow-BMtHAmg4.d.ts} +561 -2
  52. package/dist/{retouch-Bxkuc0KH.d.cts → flow-COCB42TP.d.cts} +561 -2
  53. package/dist/image-editor/index.cjs +957 -795
  54. package/dist/image-editor/index.cjs.map +1 -1
  55. package/dist/image-editor/index.d.cts +6 -6
  56. package/dist/image-editor/index.d.ts +6 -6
  57. package/dist/image-editor/index.js +180 -18
  58. package/dist/image-editor/index.js.map +1 -1
  59. package/dist/index.cjs +4 -2
  60. package/dist/index.cjs.map +1 -1
  61. package/dist/index.js +5 -3
  62. package/dist/index.js.map +1 -1
  63. package/dist/kernel-wasm-WYCGNZR4.js +10 -0
  64. package/dist/kernel-wasm-WYCGNZR4.js.map +1 -0
  65. package/dist/kernel-wasm-YPVAEMVN.cjs +10 -0
  66. package/dist/kernel-wasm-YPVAEMVN.cjs.map +1 -0
  67. package/dist/paint/index.cjs +165 -3
  68. package/dist/paint/index.cjs.map +1 -1
  69. package/dist/paint/index.d.cts +225 -3
  70. package/dist/paint/index.d.ts +225 -3
  71. package/dist/paint/index.js +166 -4
  72. package/dist/paint-editor/index.cjs +4690 -845
  73. package/dist/paint-editor/index.cjs.map +1 -1
  74. package/dist/paint-editor/index.d.cts +1525 -277
  75. package/dist/paint-editor/index.d.ts +1525 -277
  76. package/dist/paint-editor/index.js +4560 -715
  77. package/dist/paint-editor/index.js.map +1 -1
  78. package/dist/raster/index.cjs +4 -3
  79. package/dist/raster/index.cjs.map +1 -1
  80. package/dist/raster/index.js +10 -9
  81. package/dist/{svg-BnRj0q8i.d.cts → svg-CVdFc80-.d.cts} +2 -2
  82. package/dist/{svg-CmmBFfGT.d.ts → svg-DlEuhwoX.d.ts} +2 -2
  83. package/dist/{types-1SUQKDAw.d.ts → types-CDLGhAZp.d.ts} +40 -2
  84. package/dist/{types-yINF17Ta.d.cts → types-Tfly4Aya.d.cts} +40 -2
  85. package/dist/vector/index.cjs +1897 -975
  86. package/dist/vector/index.cjs.map +1 -1
  87. package/dist/vector/index.d.cts +292 -32
  88. package/dist/vector/index.d.ts +292 -32
  89. package/dist/vector/index.js +928 -6
  90. package/dist/vector/index.js.map +1 -1
  91. package/dist/video-editor/index.cjs +502 -2165
  92. package/dist/video-editor/index.cjs.map +1 -1
  93. package/dist/video-editor/index.d.cts +3 -501
  94. package/dist/video-editor/index.d.ts +3 -501
  95. package/dist/video-editor/index.js +151 -1814
  96. package/dist/video-editor/index.js.map +1 -1
  97. package/package.json +1 -1
  98. package/skills/pixerate-image-editor/references/photoshop-files.md +7 -3
  99. package/skills/pixerate-vector/SKILL.md +3 -0
  100. package/dist/chunk-C6C5PDKU.js.map +0 -1
  101. package/dist/chunk-DFQEX3AM.cjs.map +0 -1
  102. package/dist/chunk-FGW5OWJ4.js.map +0 -1
  103. package/dist/chunk-FV5AXTSF.cjs.map +0 -1
  104. package/dist/chunk-GX332W2C.js +0 -181
  105. package/dist/chunk-GX332W2C.js.map +0 -1
  106. package/dist/chunk-LKCYANMW.js.map +0 -1
  107. package/dist/chunk-LPLCWZTM.cjs.map +0 -1
  108. package/dist/chunk-MUUXNRU4.cjs +0 -181
  109. package/dist/chunk-MUUXNRU4.cjs.map +0 -1
  110. package/dist/chunk-ST7E3NEE.cjs.map +0 -1
  111. package/dist/chunk-TCKIXI46.cjs +0 -1136
  112. package/dist/chunk-TCKIXI46.cjs.map +0 -1
  113. package/dist/chunk-UBIXVXPR.js +0 -1136
  114. package/dist/chunk-UBIXVXPR.js.map +0 -1
  115. package/dist/chunk-VXR7XWMF.js.map +0 -1
  116. /package/dist/{chunk-XICA4PVO.js.map → chunk-SEBYNBHW.js.map} +0 -0
  117. /package/dist/{chunk-MMVHBKMM.js.map → chunk-T2P5TIZ6.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { a as BlendMode, R as RasterRect, i as TileKey, Y as Pigment } from './surface-Cn30xIV6.cjs';
1
+ import { a as BlendMode, R as RasterRect, i as TileKey, Y as Pigment, j as TiledSurface } from './surface-Cn30xIV6.cjs';
2
2
 
3
3
  /**
4
4
  * The brush engine (a subset of photocraft's `crates/paint`): a computed round tip with size,
@@ -700,4 +700,563 @@ declare function rgbaViewOfGrey(target: PaintTileTarget): {
700
700
  flush(): void;
701
701
  };
702
702
 
703
- export { cleanMixer as $, type PixelSource as A, type BrushSettings as B, CoverageMap as C, type Dab as D, EMPTY_MIXER_LOAD as E, RETOUCH_SAMPLES as F, RegionPixelSource as G, type RetouchDabEffect as H, RetouchDabStroke as I, type RetouchSample as J, SPOT_HEAL_TYPES as K, type SmudgeDab as L, type MixerSettings as M, SmudgeTip as N, type SpotHealType as O, type PaintTileTarget as P, TileMedium as Q, type RgbTriple as R, type SmudgeSettings as S, TONE_RANGES as T, type TileMediumOptions as U, TilePixelSource as V, type ToneRange as W, applyRetouchToTile as X, applyStrokeToTile as Y, blendRadius as Z, blenderDab as _, type MixingModel as a, coverageTileCoord as a0, createBlenderScratch as a1, dabCoverage as a2, dabRect as a3, dodgeBurn as a4, dodgeBurnCurve as a5, exchangeRates as a6, healPixels as a7, loadMixer as a8, luma as a9, mixerRates as aa, normalizeBlender as ab, normalizeBrush as ac, normalizeMixer as ad, normalizeRetouch as ae, normalizeSmudge as af, perDabStrength as ag, rasterizeDab as ah, readSourceRegion as ai, rgbaViewOfGrey as aj, saturationOf as ak, smoothPoints as al, smudgeEffect as am, sponge as an, spongeEffect as ao, spotHealPixels as ap, spotHealWindow as aq, tipFalloff as ar, tipReach as as, tipShape as at, toneOf as au, walkDabs as av, type BlenderSettings as b, type StrokePoint as c, type MixerLoad as d, MAX_BRUSH_SIZE as e, type RetouchSettings as f, StrokeCoverage as g, type MixerTarget as h, MixerStroke as i, type RetouchApply as j, type RetouchPaint as k, type StrokeApply as l, type BlenderScratch as m, DEFAULT_BLENDER as n, DEFAULT_BRUSH as o, DEFAULT_MIXER as p, DEFAULT_RETOUCH as q, DEFAULT_SMUDGE as r, DabWalker as s, type ExchangeRates as t, MIXER_DRAIN as u, MIXER_PICKUP_RATE as v, MIXING_MODELS as w, PaintExchange as x, type PaintMedium as y, type PaintSample as z };
703
+ /**
704
+ * The wet-media model: water and pigment on paper, simulated per cell on 256 px tiles.
705
+ *
706
+ * Written from the published literature only (no code, presets or textures from any product):
707
+ *
708
+ * - **Water** is a D2Q9 lattice Boltzmann fluid with BGK collision, τ = 3ν + ½ (any LBM text, e.g.
709
+ * Krüger et al., *The Lattice Boltzmann Method*, 2017). Streaming uses partial bounce-back with a
710
+ * blocking factor from the paper fibres, and the wet front is *pinned* until the water behind it
711
+ * is deep enough: Chu & Tai, "MoXi: Real-Time Ink Dispersion in Absorbent Paper", SIGGRAPH 2005.
712
+ * Tilt and flow maps are a velocity-shift force, with |u| capped at `U_MAX` cells per step.
713
+ * - **Paper** soaks water up until it holds its capacity, and damp paper stops pinning the front
714
+ * (wet-in-wet). Water evaporates faster in a band along the wet front (an "edge" field, 1 at the
715
+ * front and fading over a few cells inwards, as Curtis et al. blur the wet-area mask), so water
716
+ * flows out to the edge and carries pigment there: edge darkening.
717
+ * - **Pigment** (Curtis et al., "Computer-Generated Watercolor", SIGGRAPH 1997) is suspended in the
718
+ * water, advected with a first-order upwind finite-volume flux (it conserves pigment and never
719
+ * goes negative while |u| ≤ ¼), spreads a little between wet cells (bleed), settles into the
720
+ * paper (more in grain valleys: granulation; more at the wet edge: edge darkening), is lifted
721
+ * back by water (more where water arrives: blooms), and settles completely where a cell dries.
722
+ * - **Colour** is Kubelka-Munk: each cell carries pigment as absorption `K` per channel (linear
723
+ * R, G, B) plus one scattering `S`, so mixes are exactly linear (two-constant KM, `K = Σ cᵢKᵢ`,
724
+ * `S = Σ cᵢSᵢ`) and transparent washes multiply like glazes. A colour becomes `K` and `S` with the
725
+ * same two-flux formulas as the shipped pigment model (`K/S = (1 − R)² / 2R`).
726
+ *
727
+ * `stepCellsTs` in `kernel.ts` is the specification of one step, in exact f32 arithmetic. The
728
+ * WebAssembly SIMD kernel (`assembly/wet.ts`) is a lane-for-lane port of it and gives the same bits,
729
+ * so the simulation is deterministic across browsers, kernels and worker counts.
730
+ */
731
+ /** Tile side in cells (the raster tile size). */
732
+ declare const WET_TILE = 256;
733
+ /** A tile slot's side: the tile plus a one-cell halo on each side. */
734
+ declare const SLOT_SIDE = 258;
735
+ /** Floats per plane of a slot. */
736
+ declare const PLANE: number;
737
+ declare const PLANE_BYTES: number;
738
+ /** Planes in each ping-ponged set: f0..f8, depth, velocity, paper water, 4 pigment channels, edge. */
739
+ declare const SET_PLANES = 18;
740
+ declare const P_RHO = 9;
741
+ declare const P_UX = 10;
742
+ declare const P_UY = 11;
743
+ /** Water held in the paper. */
744
+ declare const P_SW = 12;
745
+ /** Suspended pigment: K red, K green, K blue, S. */
746
+ declare const P_P0 = 13;
747
+ /** Edge: 1 at the wet front, fading over a few cells into the wet area (0 where dry). */
748
+ declare const P_EDGE = 17;
749
+ /** Single (not ping-ponged) planes, after the two sets. */
750
+ declare const P_D0: number;
751
+ declare const P_H: number;
752
+ declare const P_FX: number;
753
+ declare const P_FY: number;
754
+ declare const SLOT_PLANES: number;
755
+ declare const SLOT_BYTES: number;
756
+ /** Pigment channels per cell. */
757
+ declare const PIGMENT_CHANNELS = 4;
758
+ /** D2Q9 lattice velocities: 0 rest, 1–4 axis (E, S, W, N in screen space), 5–8 diagonals. */
759
+ declare const EX: readonly [0, 1, 0, -1, 0, 1, -1, -1, 1];
760
+ declare const EY: readonly [0, 0, 1, 0, -1, 1, 1, -1, -1];
761
+ declare const OPP: readonly [0, 3, 4, 1, 2, 7, 8, 5, 6];
762
+ declare const W9: readonly [number, number, number, number, number, number, number, number, number];
763
+ /** Water shallower than this counts as dry. */
764
+ declare const DRY_EPS = 0.001;
765
+ /** Fluid speed cap in cells per step: keeps the LBM low-Mach and the pigment flux CFL-stable. */
766
+ declare const U_MAX = 0.25;
767
+ /** A tile's wet cells within this many cells of an edge wake the neighbouring tile. */
768
+ declare const STRIP = 64;
769
+ /** Steps per batch at most: the wake-up strip stays ahead of anything that moves a cell a step. */
770
+ declare const MAX_BATCH = 32;
771
+ /** Dry tiles are baked and freed only on steps that are multiples of this (so it is deterministic). */
772
+ declare const FREE_INTERVAL = 32;
773
+ /** Per-tile flag bits a step returns. */
774
+ declare const FLAG_ALIVE = 1;
775
+ declare const FLAG_LEFT = 2;
776
+ declare const FLAG_RIGHT = 4;
777
+ declare const FLAG_TOP = 8;
778
+ declare const FLAG_BOTTOM = 16;
779
+ declare const FLAG_WET = 32;
780
+ /** f32 parameters per lane (one per wet layer). */
781
+ declare const PARAM_FLOATS = 32;
782
+ /** Index of each packed parameter (the kernels read these offsets). */
783
+ declare const PARAM: {
784
+ readonly omega: 0;
785
+ readonly tau: 1;
786
+ readonly evap: 2;
787
+ readonly edgeEvap: 3;
788
+ readonly mobility: 4;
789
+ readonly depRate: 5;
790
+ readonly pickup: 6;
791
+ readonly absorption: 7;
792
+ readonly invCap: 8;
793
+ readonly blockScale: 9;
794
+ readonly rough: 10;
795
+ readonly pinT: 11;
796
+ readonly gx: 12;
797
+ readonly gy: 13;
798
+ readonly flowK: 14;
799
+ readonly granulation: 15;
800
+ readonly edgeDep: 16;
801
+ readonly bloom: 17;
802
+ readonly paperEvap: 18;
803
+ readonly hasFlow: 19;
804
+ readonly bleed: 20;
805
+ };
806
+ /**
807
+ * A wet layer's settings, each 0..1 unless noted. The paper's absorption, permeability and
808
+ * roughness come from the paper, not from here.
809
+ */
810
+ interface WetParams {
811
+ /** How thick the water is: 0 runny (ink) .. 1 very thick (oil). Default 0.3 (watercolour). */
812
+ viscosity: number;
813
+ /** How fast the water dries: 0 never .. 1 very fast. Default 0.45. */
814
+ evaporation: number;
815
+ /** Darker, crisper edges where a wash dries: 0 none .. 1 strong. Default 0.5. */
816
+ edgeDarkening: number;
817
+ /** How heavy the pigment is: heavy pigment travels less and settles sooner. Default 0.3. */
818
+ pigmentWeight: number;
819
+ /** How much pigment collects in the paper's valleys. Default 0.4. */
820
+ granulation: number;
821
+ /** How readily water lifts settled pigment back up (re-wetting). Default 0.2. */
822
+ pickup: number;
823
+ /** How fast suspended pigment settles into the paper (staining). Default 0.2. */
824
+ fixture: number;
825
+ /** Blooms (backruns): water flowing into a drying wash pushes its pigment out. Default 0.4. */
826
+ bloom: number;
827
+ /** Colour bleed: pigment spreading between touching wet areas. Default 0.3. */
828
+ bleed: number;
829
+ }
830
+ declare const DEFAULT_WET_PARAMS: Readonly<WetParams>;
831
+ declare const WET_PARAM_KEYS: (keyof WetParams)[];
832
+ /** The paper as wet media read it (all 0..1; from the paint editor's paper settings). */
833
+ interface WetPaper {
834
+ absorption: number;
835
+ permeability: number;
836
+ roughness: number;
837
+ }
838
+ declare const DEFAULT_WET_PAPER: Readonly<WetPaper>;
839
+ /** Canvas tilt (shared by every wet layer): water runs downhill. */
840
+ interface WetTilt {
841
+ /** Degrees from flat, 0 (flat) .. 90 (upright). */
842
+ angle: number;
843
+ /** Which way is downhill, degrees clockwise from canvas down (0 = towards the bottom edge). */
844
+ direction: number;
845
+ }
846
+ declare const FLAT: Readonly<WetTilt>;
847
+ /** Settings with every field in range; missing fields come from `base`. */
848
+ declare function normalizeWetParams(raw?: Partial<WetParams>, base?: WetParams): WetParams;
849
+ declare function normalizeTilt(raw?: Partial<WetTilt>, base?: WetTilt): WetTilt;
850
+ /** Kinematic viscosity (lattice units) for `viscosity` 0..1: 0.02 .. 1.5, exponential. */
851
+ declare function latticeViscosity(v: number): number;
852
+ /** Water a cell of paper holds when saturated, in depth units. */
853
+ declare const PAPER_CAPACITY = 0.08;
854
+ /** Largest tilt acceleration (cells per step²), at 90°. */
855
+ declare const MAX_TILT_ACCEL = 0.025;
856
+ /** Packs a lane's settings into the f32 block the kernels read. `flowStrength` 0 turns the flow map off. */
857
+ declare function packWetParams(params: WetParams, paper: WetPaper, tilt: WetTilt, flowStrength: number, out?: Float32Array<ArrayBuffer>): Float32Array;
858
+ /** Flag bits for a wet (or alive) cell at tile-local (lx, ly): which neighbours it wakes. */
859
+ declare function edgeBits(lx: number, ly: number): number;
860
+
861
+ /**
862
+ * Loading the wet-media WebAssembly kernel and its Web Workers.
863
+ *
864
+ * - The kernel is two small modules (shared memory for workers, ordinary memory for one thread),
865
+ * embedded base64 in `kernel-wasm.ts`, which is only ever imported dynamically, so bundlers split
866
+ * it into its own chunk and nothing loads until the first wet stroke.
867
+ * - Workers run from a Blob URL of `wetWorkerMain`'s source: no extra file for the host to serve
868
+ * and no bundler configuration. They share one `WebAssembly.Memory`, which needs
869
+ * `SharedArrayBuffer`, which browsers only give cross-origin isolated pages (COOP `same-origin`
870
+ * plus COEP `require-corp` or `credentialless`). Without it the kernel runs on one thread.
871
+ * - Everything here is optional: without WebAssembly SIMD the TypeScript kernel runs, with the same
872
+ * results (only slower).
873
+ */
874
+ /** What the wet engine can use here, and why not when it cannot. */
875
+ interface WetSupport {
876
+ /** WebAssembly with SIMD. */
877
+ simd: boolean;
878
+ /** `SharedArrayBuffer` and shared wasm memory (cross-origin isolation in browsers). */
879
+ sharedMemory: boolean;
880
+ /** Web Workers. */
881
+ workers: boolean;
882
+ /** Logical cores reported (`navigator.hardwareConcurrency`, 1 when unknown). */
883
+ cores: number;
884
+ /** A sentence for the user when wet paint will run slower than it could, else `null`. */
885
+ message: string | null;
886
+ }
887
+ /** Compiles the kernel (`shared`: the shared-memory variant). Cached; loads the chunk once. */
888
+ declare function loadWetKernel(shared: boolean): Promise<WebAssembly.Module>;
889
+ /** Whether shared wasm memory can be made here. */
890
+ declare function canShareMemory(): boolean;
891
+ /** Whether this runtime validates WebAssembly SIMD (checked against the kernel itself). */
892
+ declare function wetSimdSupported(): Promise<boolean>;
893
+ /** What the wet engine can use (SIMD is only known after `wetSimdSupported`). */
894
+ declare function wetSupport(simd?: boolean): WetSupport;
895
+ /** The layout numbers a worker needs. */
896
+ interface WetWorkerLayout {
897
+ ctl: number;
898
+ params: number;
899
+ table: number;
900
+ list: number;
901
+ flags: number;
902
+ last: number;
903
+ slots: number;
904
+ slotBytes: number;
905
+ perLane: number;
906
+ tilesX: number;
907
+ tilesY: number;
908
+ keys: number;
909
+ }
910
+ /** A pool of workers stepping one shared memory together. */
911
+ declare class WetWorkerPool {
912
+ private readonly workers;
913
+ private readonly url;
914
+ private constructor();
915
+ get size(): number;
916
+ /** Starts `count` workers on `memory` (shared) with the shared kernel. Rejects if any fails. */
917
+ static create(count: number, module: WebAssembly.Module, memory: WebAssembly.Memory, layout: WetWorkerLayout): Promise<WetWorkerPool>;
918
+ /** Runs `steps` steps over the active list in shared memory; resolves when every worker is done. */
919
+ run(steps: number): Promise<void>;
920
+ destroy(): void;
921
+ }
922
+
923
+ /**
924
+ * `WetWorld`: the wet-media simulation of one canvas. It holds up to `MAX_WET_LANES` wet layers
925
+ * ("lanes"), each a sparse set of 256 px tile slots in one `WebAssembly.Memory`, and steps all of
926
+ * them together.
927
+ *
928
+ * - **Kernels.** It starts on the TypeScript kernel at once and switches to the WebAssembly SIMD
929
+ * kernel (in Web Workers when the page is cross-origin isolated, else on this thread) as soon as
930
+ * that has loaded. The kernels give identical bits, so the switch never changes the painting.
931
+ * - **Determinism.** Time is counted in steps (`clock`), never in wall time. Batches never cross a
932
+ * multiple of `FREE_INTERVAL` and are at most `MAX_BATCH` steps, tiles wake up when anything
933
+ * alive comes within `STRIP` cells of their edge (so earlier or later wake-ups change nothing),
934
+ * and dry tiles are baked and freed only on multiples of `FREE_INTERVAL`, judged by their state
935
+ * at that step. So the result depends only on the edits and the steps at which they were made,
936
+ * not on frame rate, batch sizes, worker counts or the browser.
937
+ * - **Edits** (dabs, water, drying, blowing, blending, smudging, blotting, re-wetting) run on this
938
+ * thread between batches; while a batch runs (`busy`) they throw, so callers queue them.
939
+ * - **Display.** Each lane has a `base` surface: the layer's pixels under the wet paint. `display`
940
+ * gives the base with every live tile shaded (`filmPixel`), as an ordinary RGBA surface for the
941
+ * compositor. Tiles that dry are baked into the base and their slots freed.
942
+ */
943
+
944
+ /** Wet layers a world can hold at once. */
945
+ declare const MAX_WET_LANES = 8;
946
+ /** Tile slots at most (about 3.8 GB, inside wasm32's 4 GB). Water reaching a tile past this is lost. */
947
+ declare const MAX_WET_SLOTS = 352;
948
+ /** A flow map: a vector per document pixel, in cells per step² at strength 1. */
949
+ type WetFlowField = (x: number, y: number) => readonly [number, number];
950
+ /** The paper as the simulation reads it. */
951
+ interface WetPaperInput extends WetPaper {
952
+ /** Grain height 0..1 at a document position (the paper's wet height map). */
953
+ heightAt(x: number, y: number): number;
954
+ /** Paper colour, sRGB bytes. */
955
+ color: readonly [number, number, number];
956
+ }
957
+ type WetKernelKind = 'typescript' | 'wasm' | 'wasm-threads';
958
+ interface WetBackendInfo {
959
+ kind: WetKernelKind;
960
+ /** Threads stepping the simulation. */
961
+ threads: number;
962
+ /** Why it runs slower than it could, or `null`. */
963
+ message: string | null;
964
+ }
965
+ interface WetWorldOptions {
966
+ /** Which kernel: `auto` (default: the fastest available), or force `typescript` / `wasm` (one thread). */
967
+ kernel?: 'auto' | 'typescript' | 'wasm';
968
+ /** Worker threads for the wasm kernel: `auto` (default: cores − 1, at most 10) or a number (0: none). */
969
+ threads?: number | 'auto';
970
+ }
971
+ interface WetLaneOptions {
972
+ params?: Partial<WetParams>;
973
+ /** The layer's pixels under the wet paint (default empty). */
974
+ base?: TiledSurface;
975
+ flow?: WetFlowField | null;
976
+ /** Flow map strength (default 1 when a flow map is given). */
977
+ flowStrength?: number;
978
+ }
979
+ /** Totals for one wet layer. */
980
+ interface WetLaneStats {
981
+ /** Tiles being simulated. */
982
+ activeTiles: number;
983
+ /** Cells with surface water (at least `DRY_EPS` deep). */
984
+ wetCells: number;
985
+ /** Water on the surface plus in the paper, in cell-depth units. */
986
+ water: number;
987
+ /** Suspended plus settled pigment mass (sum of the four channels). */
988
+ pigment: number;
989
+ /** Document rectangle of the wet cells, or `null` when nothing is wet. */
990
+ wetBounds: RasterRect | null;
991
+ }
992
+ /** A copy of the whole simulation (for undo). */
993
+ interface WetSnapshot {
994
+ readonly clock: number;
995
+ readonly tilt: WetTilt;
996
+ readonly lanes: ReadonlyArray<{
997
+ id: string;
998
+ index: number;
999
+ params: WetParams;
1000
+ flow: WetFlowField | null;
1001
+ flowStrength: number;
1002
+ base: TiledSurface;
1003
+ }>;
1004
+ /** Per active key: the current set and the deposit planes; and its last flags. */
1005
+ readonly slots: ReadonlyMap<number, {
1006
+ planes: Float32Array;
1007
+ last: number;
1008
+ }>;
1009
+ /** Bytes held. */
1010
+ readonly bytes: number;
1011
+ }
1012
+ /** Thrown for edits while a batch is running, and for bad arguments. */
1013
+ declare class WetWorldError extends Error {
1014
+ constructor(message: string);
1015
+ }
1016
+ interface Layout extends WetWorkerLayout {
1017
+ width: number;
1018
+ height: number;
1019
+ }
1020
+ declare class WetWorld {
1021
+ readonly width: number;
1022
+ readonly height: number;
1023
+ readonly layout: Layout;
1024
+ /** Steps simulated so far. */
1025
+ clock: number;
1026
+ /** Messages for the user (slots ran out, a backend failed). */
1027
+ readonly warnings: string[];
1028
+ private memory;
1029
+ private readonly shared;
1030
+ private f32;
1031
+ private i32;
1032
+ private u32;
1033
+ private slotCount;
1034
+ private readonly freeSlots;
1035
+ private readonly active;
1036
+ private parity;
1037
+ private readonly lanes;
1038
+ private tilt;
1039
+ private paper;
1040
+ private paperBytes;
1041
+ private kind;
1042
+ private wasm;
1043
+ private pool;
1044
+ private busyFlag;
1045
+ private destroyed;
1046
+ private support;
1047
+ private readonly prm;
1048
+ /** Resolves when the fastest available kernel is running (it may stay `typescript`). */
1049
+ readonly ready: Promise<WetBackendInfo>;
1050
+ constructor(width: number, height: number, paper: WetPaperInput, options?: WetWorldOptions);
1051
+ private views;
1052
+ private start;
1053
+ /** The kernel in use and why it is not faster. */
1054
+ backend(): WetBackendInfo;
1055
+ /** Whether a batch is running (edits throw until it ends). */
1056
+ get busy(): boolean;
1057
+ destroy(): void;
1058
+ private laneOf;
1059
+ hasLane(id: string): boolean;
1060
+ laneIds(): string[];
1061
+ /** Adds a wet layer (or returns it). Throws when `MAX_WET_LANES` are in use. */
1062
+ ensureLane(id: string, options?: WetLaneOptions): void;
1063
+ /** Drops a wet layer and its wet paint (nothing is baked). */
1064
+ removeLane(id: string): void;
1065
+ getParams(id: string): WetParams;
1066
+ setParams(id: string, params: Partial<WetParams>): WetParams;
1067
+ getTilt(): WetTilt;
1068
+ setTilt(tilt: Partial<WetTilt>): WetTilt;
1069
+ /** Changes the paper: heights of live tiles are refilled, rates repacked. */
1070
+ setPaper(paper: WetPaperInput): void;
1071
+ /** Sets a layer's flow map (`null` removes it). */
1072
+ setFlow(id: string, flow: WetFlowField | null, strength?: number): void;
1073
+ hasFlow(id: string): boolean;
1074
+ /** The pixels under a layer's wet paint. */
1075
+ getBase(id: string): TiledSurface;
1076
+ /** Replaces the pixels under a layer's wet paint. */
1077
+ setBase(id: string, base: TiledSurface): void;
1078
+ private pack;
1079
+ private touchAll;
1080
+ private laneIndexOf;
1081
+ private slotOf;
1082
+ private slotBase;
1083
+ private requireIdle;
1084
+ /** Writes the active list into memory for the kernels. */
1085
+ private syncList;
1086
+ private grow;
1087
+ /** Activates a tile of a lane. Returns false when no slot can be had. */
1088
+ private activate;
1089
+ private free;
1090
+ private tileXY;
1091
+ private tileKeyOf;
1092
+ private fillPaper;
1093
+ private fillFlow;
1094
+ /** Activates every tile of a lane within `STRIP` cells of a document rectangle. */
1095
+ private wake;
1096
+ /** Fills one slot's halo in the current set from its neighbours (TypeScript). */
1097
+ private haloTs;
1098
+ private halo;
1099
+ /** Refills every live slot's halo in the current set (after edits or wake-ups). */
1100
+ private refreshHalos;
1101
+ /** Whether anything is being simulated (in `id`, or any layer). */
1102
+ isActive(id?: string): boolean;
1103
+ /** Steps until the next batch boundary: at most `want`, `MAX_BATCH`, and the next free check. */
1104
+ private batchSize;
1105
+ /** Runs `n` steps on this thread (TypeScript or wasm kernel). */
1106
+ private runHere;
1107
+ /** After a batch: wake neighbours from the flags, free dead tiles on a free step, restamp. */
1108
+ private afterBatch;
1109
+ /**
1110
+ * Steps the simulation `steps` times on this thread (the TypeScript or single-thread wasm
1111
+ * kernel). Throws while worker threads are in use; use `step` there.
1112
+ */
1113
+ stepSync(steps: number): number;
1114
+ /** Steps the simulation `steps` times (in worker threads when there are any). */
1115
+ step(steps: number): Promise<number>;
1116
+ /** Steps until nothing is wet or `maxSteps` have run. Returns the steps run. */
1117
+ stepUntilDry(maxSteps: number): Promise<number>;
1118
+ /** Float index of a cell's plane-0 value in the current set, or −1 (inactive / off the canvas). */
1119
+ private cell;
1120
+ /** Index of the same cell in the single (deposit, height, flow) planes, given `cell`. */
1121
+ private single;
1122
+ /**
1123
+ * Runs `fn` for every cell of a footprint (`cov` over `rect`, document cells) on a lane, waking
1124
+ * the tiles around it first, then refreshes halos. `fn` gets the cell index and its coverage.
1125
+ */
1126
+ private footprint;
1127
+ private markEdited;
1128
+ /** Adds water (depth units) at rest. */
1129
+ private addWaterAt;
1130
+ /**
1131
+ * Lays paint: `water` depth and pigment mass `pigment` (K r, g, b, S) per unit of coverage, or
1132
+ * per pixel from `field` (4 values per pixel of `rect`). Pigment without water lands straight in
1133
+ * the paper (settled).
1134
+ */
1135
+ paint(id: string, rect: RasterRect, cov: ArrayLike<number> | null, water: number, pigment: ArrayLike<number> | null, field?: ArrayLike<number> | null): void;
1136
+ /** Damp paper: fills the paper's water towards its capacity by `amount` (0..1) × coverage, plus a thin film of surface water. */
1137
+ wetPaper(id: string, rect: RasterRect, cov: ArrayLike<number> | null, amount: number): void;
1138
+ /**
1139
+ * Takes water (and suspended pigment, and settled pigment) away: `water`, `suspended`,
1140
+ * `settled` are fractions 0..1 × coverage. A hair dryer takes water only (the pigment stays and
1141
+ * settles); blotting takes all three.
1142
+ */
1143
+ remove(id: string, rect: RasterRect, cov: ArrayLike<number> | null, water: number, suspended: number, settled: number, paperWater?: number): void;
1144
+ /** Pushes the water: adds velocity (`ux`, `uy` cells per step, each at most 0.1) × coverage. */
1145
+ push(id: string, rect: RasterRect, cov: ArrayLike<number> | null, ux: number, uy: number): void;
1146
+ /** Blends wet paint: each wet cell's suspended pigment moves `strength` × coverage towards the footprint's mean. */
1147
+ blend(id: string, rect: RasterRect, cov: ArrayLike<number> | null, strength: number): void;
1148
+ /**
1149
+ * Drags wet paint by (`dx`, `dy`) cells: each footprint cell takes `strength` × coverage of the
1150
+ * water and suspended pigment of the cell it came from (a smudge through wet paint).
1151
+ */
1152
+ drag(id: string, rect: RasterRect, cov: ArrayLike<number> | null, dx: number, dy: number, strength: number): void;
1153
+ /**
1154
+ * Re-wetting: lifts `amount` × coverage of the dried paint in the layer's pixels (`base`) back into
1155
+ * the paper as settled pigment, so water can move it again. Only where there is surface water.
1156
+ */
1157
+ rewet(id: string, rect: RasterRect, cov: ArrayLike<number> | null, amount: number, paper: readonly [number, number, number]): void;
1158
+ /**
1159
+ * Dries wet paint at once (everything settles where it is, the water goes): in `rect`, or the
1160
+ * whole layer. Whole tiles that end up dry are baked into the base and freed. Returns the
1161
+ * document rectangle that changed, or `null`.
1162
+ */
1163
+ dry(id: string, rect?: RasterRect): RasterRect | null;
1164
+ /**
1165
+ * Bakes a slot's pigment into its lane's base (settling suspended pigment too when `all`).
1166
+ * Returns whether any pixel changed.
1167
+ */
1168
+ private bakeKey;
1169
+ /**
1170
+ * Shades one slot over a base tile. `display`: the wet look (suspended + settled, wet paper a
1171
+ * little darker); `bake`: settled pigment only; `bake-all`: suspended and settled (dry now).
1172
+ * Returns `null` when nothing would change the base.
1173
+ */
1174
+ private shadeSlot;
1175
+ /** The layer's pixels with all its wet paint dried where it is (the bake of "dry on save"); changes nothing. */
1176
+ bakedSurface(id: string): TiledSurface;
1177
+ /**
1178
+ * Sums over a footprint of a lane, weighted by coverage: `weight` (coverage), `water` (surface
1179
+ * depth), `wet` (coverage of wet cells), `pigment` (suspended, 4 channels), `settled` (4 channels).
1180
+ */
1181
+ sample(id: string, rect: RasterRect, cov: ArrayLike<number> | null): {
1182
+ weight: number;
1183
+ water: number;
1184
+ wet: number;
1185
+ pigment: number[];
1186
+ settled: number[];
1187
+ };
1188
+ /** Surface water depth at a document cell (0 where nothing is simulated). */
1189
+ waterAt(id: string, x: number, y: number): number;
1190
+ /** Totals for a layer (scans its live tiles). */
1191
+ stats(id: string): WetLaneStats;
1192
+ /** Whether a layer (or any) has surface water anywhere. */
1193
+ isWet(id?: string): boolean;
1194
+ /** Document rectangles of a layer's live tiles. */
1195
+ activeRects(id: string): RasterRect[];
1196
+ /** A number that changes whenever a layer's display may have changed. */
1197
+ stamp(id: string): number;
1198
+ /**
1199
+ * The layer's pixels with its wet paint shaded in: the base with each live tile shaded over it.
1200
+ * At most `maxTiles` stale tiles are reshaded per call (edited tiles first); the rest keep their
1201
+ * last shading until the next call. Returns the surface and the tiles reshaded.
1202
+ */
1203
+ display(id: string, maxTiles?: number): {
1204
+ surface: TiledSurface;
1205
+ changed: RasterRect[];
1206
+ pending: number;
1207
+ };
1208
+ /**
1209
+ * The water as an overlay tile (RGBA, blue, alpha from surface depth and damp paper) for a
1210
+ * document tile, or `null` where nothing is wet.
1211
+ */
1212
+ waterOverlay(id: string, tx: number, ty: number): Uint8ClampedArray | null;
1213
+ /** A copy of everything (for undo): live slots, layers, clock and tilt. */
1214
+ snapshot(): WetSnapshot;
1215
+ /** Puts a snapshot back exactly (the simulation then continues as it would have). */
1216
+ restore(snap: WetSnapshot): void;
1217
+ /** Bytes of wasm memory held. */
1218
+ memoryBytes(): number;
1219
+ /** Live tiles across all layers. */
1220
+ activeTiles(): number;
1221
+ /** Memory for tests and tools: the raw f32 view (read only, please). */
1222
+ get rawFloats(): Float32Array;
1223
+ /** The current set's parity (tests). */
1224
+ get currentParity(): number;
1225
+ /** Float index of a slot's first plane (tests). */
1226
+ slotIndex(id: string, tx: number, ty: number): number;
1227
+ }
1228
+
1229
+ /**
1230
+ * Flow maps: a push on the water at every cell (cells per step², like tilt), from a few generated
1231
+ * patterns. Every pattern is computed with + − × ÷ only, so it is the same in every engine.
1232
+ */
1233
+
1234
+ type WetFlowKind = 'none' | 'linear' | 'swirl' | 'radial' | 'turbulent';
1235
+ declare const WET_FLOW_KINDS: readonly WetFlowKind[];
1236
+ /** A flow map as settings (saved with the document). */
1237
+ interface WetFlowSpec {
1238
+ kind: WetFlowKind;
1239
+ /** 0..1: how hard it pushes (1 is about as strong as a 25° tilt). */
1240
+ strength: number;
1241
+ /** `linear`: direction in degrees clockwise from canvas down. */
1242
+ angle: number;
1243
+ /** `swirl` / `radial`: centre in document pixels (default the canvas centre). */
1244
+ center?: {
1245
+ x: number;
1246
+ y: number;
1247
+ };
1248
+ /** `swirl`: true turns clockwise. */
1249
+ clockwise: boolean;
1250
+ /** `turbulent`: eddy size in pixels (8..1024). */
1251
+ scale: number;
1252
+ seed: number;
1253
+ }
1254
+ declare const DEFAULT_FLOW: Readonly<WetFlowSpec>;
1255
+ /** sin and cos of an angle in radians, by range reduction and Taylor series (deterministic). */
1256
+ declare function dsincos(a: number): [number, number];
1257
+ /** Settings with every field in range. */
1258
+ declare function normalizeFlow(raw?: Partial<WetFlowSpec>, base?: WetFlowSpec): WetFlowSpec;
1259
+ /** The flow field of a spec on a canvas, or `null` for `none` (strength is applied by the world). */
1260
+ declare function flowField(spec: WetFlowSpec, width: number, height: number): WetFlowField | null;
1261
+
1262
+ export { FLAG_RIGHT as $, normalizeWetParams as A, type BrushSettings as B, CoverageMap as C, type Dab as D, wetSupport as E, type BlenderScratch as F, DEFAULT_BLENDER as G, DEFAULT_BRUSH as H, DEFAULT_MIXER as I, DEFAULT_RETOUCH as J, DEFAULT_SMUDGE as K, DEFAULT_WET_PAPER as L, type MixerSettings as M, DRY_EPS as N, DabWalker as O, type PaintTileTarget as P, EMPTY_MIXER_LOAD as Q, type RetouchSettings as R, StrokeCoverage as S, TileMedium as T, EX as U, EY as V, WetWorld as W, type ExchangeRates as X, FLAG_ALIVE as Y, FLAG_BOTTOM as Z, FLAG_LEFT as _, type MixerLoad as a, blendRadius as a$, FLAG_TOP as a0, FLAG_WET as a1, FLAT as a2, FREE_INTERVAL as a3, MAX_BATCH as a4, MAX_TILT_ACCEL as a5, MAX_WET_LANES as a6, MAX_WET_SLOTS as a7, MIXER_DRAIN as a8, MIXER_PICKUP_RATE as a9, type RetouchSample as aA, SET_PLANES as aB, SLOT_BYTES as aC, SLOT_PLANES as aD, SLOT_SIDE as aE, SPOT_HEAL_TYPES as aF, STRIP as aG, type SmudgeDab as aH, SmudgeTip as aI, type SpotHealType as aJ, TONE_RANGES as aK, type TileMediumOptions as aL, TilePixelSource as aM, type ToneRange as aN, U_MAX as aO, W9 as aP, WET_TILE as aQ, type WetFlowField as aR, type WetKernelKind as aS, type WetLaneOptions as aT, type WetLaneStats as aU, type WetPaper as aV, type WetWorkerLayout as aW, WetWorkerPool as aX, WetWorldError as aY, applyRetouchToTile as aZ, applyStrokeToTile as a_, MIXING_MODELS as aa, OPP as ab, PAPER_CAPACITY as ac, PARAM as ad, PARAM_FLOATS as ae, PIGMENT_CHANNELS as af, PLANE as ag, PLANE_BYTES as ah, P_D0 as ai, P_EDGE as aj, P_FX as ak, P_FY as al, P_H as am, P_P0 as an, P_RHO as ao, P_SW as ap, P_UX as aq, P_UY as ar, PaintExchange as as, type PaintMedium as at, type PaintSample as au, type PixelSource as av, RETOUCH_SAMPLES as aw, RegionPixelSource as ax, type RetouchDabEffect as ay, RetouchDabStroke as az, type MixerTarget as b, blenderDab as b0, canShareMemory as b1, cleanMixer as b2, coverageTileCoord as b3, createBlenderScratch as b4, dabCoverage as b5, dabRect as b6, dodgeBurn as b7, dodgeBurnCurve as b8, dsincos as b9, spotHealWindow as bA, tipFalloff as bB, tipReach as bC, tipShape as bD, toneOf as bE, walkDabs as bF, wetSimdSupported as bG, edgeBits as ba, exchangeRates as bb, flowField as bc, healPixels as bd, latticeViscosity as be, loadMixer as bf, loadWetKernel as bg, luma as bh, mixerRates as bi, normalizeBlender as bj, normalizeBrush as bk, normalizeMixer as bl, normalizeRetouch as bm, normalizeSmudge as bn, normalizeTilt as bo, packWetParams as bp, perDabStrength as bq, rasterizeDab as br, readSourceRegion as bs, rgbaViewOfGrey as bt, saturationOf as bu, smoothPoints as bv, smudgeEffect as bw, sponge as bx, spongeEffect as by, spotHealPixels as bz, MixerStroke as c, type RetouchApply as d, type StrokePoint as e, type RetouchPaint as f, type StrokeApply as g, type MixingModel as h, type BlenderSettings as i, type SmudgeSettings as j, type WetTilt as k, type WetParams as l, type WetFlowSpec as m, type RgbTriple as n, type WetWorldOptions as o, type WetBackendInfo as p, type WetSnapshot as q, type WetPaperInput as r, DEFAULT_FLOW as s, DEFAULT_WET_PARAMS as t, MAX_BRUSH_SIZE as u, WET_FLOW_KINDS as v, WET_PARAM_KEYS as w, type WetFlowKind as x, type WetSupport as y, normalizeFlow as z };