@pixerate/editor 0.113.0 → 0.114.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/THIRD_PARTY_NOTICES.md +5 -0
- package/dist/animation-editor/index.cjs +60 -54
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +3 -3
- package/dist/animation-editor/index.d.ts +3 -3
- package/dist/animation-editor/index.js +14 -8
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/builtin-CY97ppKM.d.cts +354 -0
- package/dist/builtin-CY97ppKM.d.ts +354 -0
- package/dist/canvas/index.cjs +3 -3
- package/dist/canvas/index.cjs.map +1 -1
- package/dist/canvas/index.js +9 -9
- package/dist/chunk-26PGXHY7.cjs +753 -0
- package/dist/chunk-26PGXHY7.cjs.map +1 -0
- package/dist/chunk-2OJACTPR.cjs +929 -0
- package/dist/chunk-2OJACTPR.cjs.map +1 -0
- package/dist/chunk-3UFGNHSP.js +929 -0
- package/dist/chunk-3UFGNHSP.js.map +1 -0
- package/dist/{chunk-YGIMK4NX.cjs → chunk-5OVJHMZQ.cjs} +757 -825
- package/dist/chunk-5OVJHMZQ.cjs.map +1 -0
- package/dist/chunk-643B2HKC.cjs +534 -0
- package/dist/chunk-643B2HKC.cjs.map +1 -0
- package/dist/chunk-6FCKOS2B.js +534 -0
- package/dist/chunk-6FCKOS2B.js.map +1 -0
- package/dist/chunk-BRLYOPLT.js +2574 -0
- package/dist/chunk-BRLYOPLT.js.map +1 -0
- package/dist/{chunk-LQEEDHOP.js → chunk-C6C5PDKU.js} +759 -761
- package/dist/chunk-C6C5PDKU.js.map +1 -0
- package/dist/{chunk-4KLT7ZYS.cjs → chunk-DFQEX3AM.cjs} +29 -29
- package/dist/{chunk-4KLT7ZYS.cjs.map → chunk-DFQEX3AM.cjs.map} +1 -1
- package/dist/{chunk-CZOXTEMN.js → chunk-EUVSQ25B.js} +336 -404
- package/dist/chunk-EUVSQ25B.js.map +1 -0
- package/dist/chunk-G5NMLUVF.cjs +2574 -0
- package/dist/chunk-G5NMLUVF.cjs.map +1 -0
- package/dist/{chunk-LPYOIVLA.js → chunk-LKCYANMW.js} +3 -3
- package/dist/{chunk-W3GXSUSQ.cjs → chunk-LPLCWZTM.cjs} +5087 -1283
- package/dist/chunk-LPLCWZTM.cjs.map +1 -0
- package/dist/chunk-MMVHBKMM.js +753 -0
- package/dist/chunk-MMVHBKMM.js.map +1 -0
- package/dist/{chunk-POGBUYWE.cjs → chunk-ST7E3NEE.cjs} +857 -859
- package/dist/chunk-ST7E3NEE.cjs.map +1 -0
- package/dist/{chunk-7VOHOPLW.cjs → chunk-TCKIXI46.cjs} +59 -59
- package/dist/{chunk-7VOHOPLW.cjs.map → chunk-TCKIXI46.cjs.map} +1 -1
- package/dist/{chunk-XIOMMGPD.cjs → chunk-TFOPHZ3U.cjs} +1 -1
- package/dist/chunk-TFOPHZ3U.cjs.map +1 -0
- package/dist/{chunk-Z4BC6M74.js → chunk-UBIXVXPR.js} +2 -2
- package/dist/{chunk-BLWCAQCW.js → chunk-VXR7XWMF.js} +4574 -770
- package/dist/chunk-VXR7XWMF.js.map +1 -0
- package/dist/{chunk-HNS7UHCM.js → chunk-XK5LZKBD.js} +1 -1
- package/dist/chunk-XK5LZKBD.js.map +1 -0
- package/dist/cms/index.cjs +146 -0
- package/dist/cms/index.cjs.map +1 -0
- package/dist/cms/index.d.cts +51 -0
- package/dist/cms/index.d.ts +51 -0
- package/dist/cms/index.js +146 -0
- package/dist/cms/index.js.map +1 -0
- package/dist/{export-DIkoK8-r.d.ts → export-_1dUKwpF.d.ts} +217 -191
- package/dist/{export-CEXEzqBf.d.cts → export-b6NjCZ5-.d.cts} +217 -191
- package/dist/image-editor/index.cjs +1779 -1280
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +77 -93
- package/dist/image-editor/index.d.ts +77 -93
- package/dist/image-editor/index.js +740 -241
- package/dist/image-editor/index.js.map +1 -1
- package/dist/opentype-BZEOSOX3.d.ts +188 -0
- package/dist/opentype-Dpe75vL5.d.cts +188 -0
- package/dist/paint/index.cjs +4 -4
- package/dist/paint/index.d.cts +2 -2
- package/dist/paint/index.d.ts +2 -2
- package/dist/paint/index.js +3 -3
- package/dist/paint-editor/index.cjs +146 -145
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +9 -8
- package/dist/paint-editor/index.d.ts +9 -8
- package/dist/paint-editor/index.js +6 -5
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/raster/index.cjs +53 -3
- package/dist/raster/index.cjs.map +1 -1
- package/dist/raster/index.d.cts +62 -91
- package/dist/raster/index.d.ts +62 -91
- package/dist/raster/index.js +59 -9
- package/dist/{render-BEriFuqK.d.cts → render-B1K_OoLy.d.cts} +87 -2
- package/dist/{render-tjzKaik-.d.ts → render-CrmHOgpo.d.ts} +87 -2
- package/dist/{retouch-CEIKR22W.d.cts → retouch-Bxkuc0KH.d.cts} +1 -1
- package/dist/{retouch-BXmeSCaB.d.ts → retouch-Do6tBs2H.d.ts} +1 -1
- package/dist/{surface-C8RRg_Bh.d.cts → surface-Cn30xIV6.d.cts} +6 -1
- package/dist/{surface-C8RRg_Bh.d.ts → surface-Cn30xIV6.d.ts} +6 -1
- package/dist/{svg-D_cfkhlB.d.cts → svg-BnRj0q8i.d.cts} +16 -4
- package/dist/{svg-wIaKLrU0.d.ts → svg-CmmBFfGT.d.ts} +16 -4
- package/dist/{types-DtL_qLFz.d.ts → types-1SUQKDAw.d.ts} +273 -4
- package/dist/{types-DyQq-WPY.d.cts → types-yINF17Ta.d.cts} +273 -4
- package/dist/vector/index.cjs +12170 -7343
- package/dist/vector/index.cjs.map +1 -1
- package/dist/vector/index.d.cts +1579 -16
- package/dist/vector/index.d.ts +1579 -16
- package/dist/vector/index.js +6303 -1476
- package/dist/vector/index.js.map +1 -1
- package/dist/warp-B39VsOtd.d.cts +348 -0
- package/dist/warp-DMN30aY6.d.ts +348 -0
- package/dist/zlib-dxQdgHyN.d.cts +95 -0
- package/dist/zlib-dxQdgHyN.d.ts +95 -0
- package/package.json +6 -1
- package/skills/pixerate-image-editor/SKILL.md +12 -36
- package/skills/pixerate-image-editor/references/color-management.md +37 -0
- package/skills/pixerate-image-editor/references/photoshop-files.md +39 -0
- package/skills/pixerate-vector/SKILL.md +54 -2
- package/dist/chunk-BLWCAQCW.js.map +0 -1
- package/dist/chunk-CZOXTEMN.js.map +0 -1
- package/dist/chunk-HNS7UHCM.js.map +0 -1
- package/dist/chunk-JLYX4V57.cjs +0 -2001
- package/dist/chunk-JLYX4V57.cjs.map +0 -1
- package/dist/chunk-KB2YBCVS.js +0 -2001
- package/dist/chunk-KB2YBCVS.js.map +0 -1
- package/dist/chunk-LQEEDHOP.js.map +0 -1
- package/dist/chunk-POGBUYWE.cjs.map +0 -1
- package/dist/chunk-W3GXSUSQ.cjs.map +0 -1
- package/dist/chunk-XIOMMGPD.cjs.map +0 -1
- package/dist/chunk-YGIMK4NX.cjs.map +0 -1
- package/dist/homography-CZ-tFjay.d.cts +0 -50
- package/dist/homography-Ctfjoc1b.d.ts +0 -50
- package/dist/warp-CWHZzE3x.d.ts +0 -118
- package/dist/warp-D5jz_tN7.d.cts +0 -118
- /package/dist/{chunk-LPYOIVLA.js.map → chunk-LKCYANMW.js.map} +0 -0
- /package/dist/{chunk-Z4BC6M74.js.map → chunk-UBIXVXPR.js.map} +0 -0
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -12,6 +12,7 @@ reproduced at the end of this file. Paths are relative to each source repository
|
|
|
12
12
|
|
|
13
13
|
© 2026 ArtCraft Team and the CadCraft contributors.
|
|
14
14
|
|
|
15
|
+
- `crates/engine/src/snap/tracking.rs` (`polar_angles`, `MAX_ACQUIRED`, `DWELL`, `Tracker::toggle` / `hover` / `paths` / `find`: acquired points sending alignment paths and an endpoint's extension, then a crossing of two paths, a path crossing the drawing, or the nearest path) and its direct distance entry → `vectorPolarAngles`, `vectorTrackingPaths` and tracking in `snapFrom` in `packages/core/src/vector/snap.ts`, and `acquireTrackingPoint`, `placePenPoint` and `addPathByDimensions` in `packages/core/src/vector/controller.ts`; parallel and apparent-intersection tracking are not ported; test cases re-expressed → `packages/core/tests/vector-tracking.test.ts`
|
|
15
16
|
- `crates/engine/src/spatial.rs` (an R-tree over object bounds used by picking, window selection and snaps, built only above 256 objects, reused while the content is the same and rebuilt from unchanged parts after an edit, returning candidates in draw order for the same exact tests a scan runs) → the approach of `VectorRTree`, `vectorSpatialIndex` and `vectorNodesNear` in `packages/core/src/vector/spatial.ts`, used by `hitTestVectorNodes`, marquee selection and snapping to segments; the tree is our own sort-tile-recursive packing (cadcraft uses the `rstar` crate), and unchanged parts are reused by caching each node's bounds by node object; parity tests are our own → `packages/core/tests/vector-spatial.test.ts`
|
|
16
17
|
- `crates/constraints/src/lm.rs` (damped, weighted minimum-norm Gauss–Newton with a numerical Jacobian, `Δx = −W⁻¹Jᵀ(JW⁻¹Jᵀ + μI)⁻¹r`; Gaussian elimination with partial pivoting; Householder QR with column pivoting on row- and column-balanced matrices for rank and null space), `lib.rs` (constraints grouped into connected components, edited geometry weighted to move least, conflicts located by leaving each constraint out, new constraints refused when they do not raise the Jacobian's rank or when a Fix locks parameters already determined), `residual.rs` (the residual forms: point–point, point on line or circle, collinear, parallel, perpendicular, horizontal / vertical, tangent line–circle and circle–circle, symmetric, equal, distance along an axis, angle with its orientation from the starting geometry, radius, diameter), `dof.rs` (remaining degrees of freedom per component, per object by the null space restricted to its parameters, statuses), `auto.rs` (`infer`: coincident points, concentric and tangent circles, horizontal / vertical lines, collinear, connected perpendicular and parallel pairs, equal lengths and radii, in that order) and `expr.rs` (named expressions with `+ - * /`, parentheses and `pi`, evaluated lazily with cycle detection) → `packages/core/src/vector/constraints/lm.ts`, `solve.ts`, `auto.ts` and `expr.ts`; entities and handles became our anchors with stable ids, segments, handles, G1 / G2 joints at anchors and round closed paths, angle-type residuals are scaled to lengths so one tolerance fits all rows, and a solve after every edit weights what changed since the last solve; test cases re-expressed → `packages/core/tests/vector-constraints.test.ts`
|
|
17
18
|
- `crates/geom/src/region.rs` (`enclosing_loop`, `boundary_at_gap` and `build_gap`: curves split at their crossings, gaps between loose ends bridged to the nearest other loose end within reach, a ray from the point meeting edges in order and the face to the left of each traced by always taking the sharpest left turn until a counter-clockwise loop round the point comes back; islands — pieces nested in that face — as holes; `interior_point`) → `PlanarMap.regionAt` and `closeGaps` in `packages/core/src/canvas/pathops/planar.ts` and `fillRegion` in `packages/core/src/vector/controller.ts`; islands are taken per face (the smallest face of another piece around each outer boundary) rather than every group inside the loop, so islands inside islands are not holes; test cases re-expressed → `packages/core/tests/canvas-pathfinder.test.ts`
|
|
@@ -31,6 +32,7 @@ reproduced at the end of this file. Paths are relative to each source repository
|
|
|
31
32
|
|
|
32
33
|
© 2026 ArtCraft Team and the DeckCraft contributors.
|
|
33
34
|
|
|
35
|
+
- `crates/engine/src/connect.rs` (`sites`, `nearest_site`, `reroute` dropping glue to shapes that no longer exist, `set_glue` turning a plain line into a connector) → `packages/core/src/vector/connectors.ts` (`vectorConnectionSites`, `vectorConnectorTargetAt`, `rerouteVectorConnectors`) and `setConnector` in `packages/core/src/vector/controller.ts`; test cases our own → `packages/core/tests/vector-connectors.test.ts`
|
|
34
36
|
- `crates/geom/src/morph.rs` (`contours`: every segment as a cubic, lines with handles at thirds; `align`: contours paired in order, one without a partner meeting a point at the same place relative to the other outline's box (`place`); `turn`: a closed contour restarted at another anchor; `match_pair`: the closed side of a pair turned, open paired with closed) → `subpathToMorphContour`, `turnMorphContour` and `correspondMorphContours` in `packages/core/src/vector/blend.ts`; anchors are inserted by arc length rather than split evenly per curve, and the winding of closed shapes follows their areas (effectcraft) instead of a cost comparison; test cases re-expressed → `packages/core/tests/vector-blend.test.ts`
|
|
35
37
|
- `crates/model/src/anim.rs` (`ANIMATIONS`: PowerPoint's preset IDs per effect class) and `crates/pptx/src/read/timing.rs` (`collect` and `animations`: effects found by their `presetClass`, the target from `p:spTgt`, `nodeType` as on click, with previous or after previous) → `fromPptxAnimation` in `packages/core/src/animation-editor/pptx.ts`; effects map onto the editor's commands, and each click starts a shot
|
|
36
38
|
- `crates/anim/src/morph.rs` (`morph_pairs`: shapes paired in passes, each used once — by name, then by matching content, then by kind — and unpaired shapes faded out) → `matchMotionNodes` and the `match` command in `packages/core/src/animation-editor/match.ts` and `compile.ts`; the passes are name, then id with the groups' own ids taken out, then kind in stacking order, and paired groups pair their own parts
|
|
@@ -74,6 +76,7 @@ reproduced at the end of this file. Paths are relative to each source repository
|
|
|
74
76
|
- `crates/engine/src/snap.rs` (`spacings` / `equal_spacing` / `spacing_guides`: centred between neighbours, repeating the gap of the pair before or after, gap labels; threshold in screen pixels divided by the zoom) → `VectorSnapTargets.snapRect` in `packages/core/src/vector/snap.ts`; its equal-spacing cases re-expressed → `packages/core/tests/vector-snap.test.ts`
|
|
75
77
|
- `crates/layout/src/lib.rs` (`layout_frame`, `distribute`, `main_offsets`, `fit_hug_text`, `enforce_limits`, `item_baseline`, `resize_child`, `grid_place`, `resolve_tracks`, `track_content`, `grid_geometry`, `layout_grid`, `apply_constraints`, `layout_page`, `layout_up`, `coherent_sizing`, `clamp_size`) → `packages/core/src/canvas/autoLayout.ts`
|
|
76
78
|
- `crates/layout/src/{tests.rs,behaviour_tests.rs,nested_tests.rs,content_align_tests.rs}` (test cases re-expressed) → `packages/core/tests/canvas-auto-layout.test.ts`
|
|
79
|
+
- `crates/layout/src/lib.rs` (`apply_constraints`: a child keeps its left / right / both margins, its offset from the centre, or scales with its frame, per axis) → `vectorFrameChildMatrix` in `packages/core/src/vector/frames.ts`, applied when a vector frame is resized (`bakeFrame` in `packages/core/src/vector/geometry.ts`), with text keeping its font size; test cases our own → `packages/core/tests/vector-frames.test.ts`
|
|
77
80
|
- `crates/doc/src/styles.rs` (`Collection`, `Mode`, `Variable`, `VariableValue`, `Variables::resolve`, `default_mode`, `current_mode`, `find_mode`, `scopes_for`, `normalize_scopes`, `in_scope`) → `packages/core/src/tokens/types.ts`, `packages/core/src/tokens/model.ts`
|
|
78
81
|
- `crates/engine/src/cmd/variables.rs` (`alias_target` cycle check, `forget_variables` alias detaching, `remove_mode`, `move_mode`, `rename_collection`, `delete_collection`, `field_scope`) → `packages/core/src/tokens/model.ts`, `packages/core/src/canvas/tokenBindings.ts`
|
|
79
82
|
- `crates/doc/src/lib.rs` (`modes_for`: modes inherited down the tree) → `getEffectiveTokenModes` in `packages/core/src/canvas/tokenBindings.ts`
|
|
@@ -189,6 +192,7 @@ GridCraft. Apache POI is © The Apache Software Foundation, licensed under the A
|
|
|
189
192
|
- `crates/raster/src/lib.rs` (`Surface`: a sparse map of 256 px tiles behind shared pointers with a default pixel, copy-on-write writes that share untouched tiles, uniform tiles stored once, `prune` of tiles equal to the default, `content_bounds`, `translated`, region read / write) → `TiledSurface`, `SurfaceDraft`, `readRegion`, `writeRegion`, `fillRect`, `contentBounds` and `translateSurface` in `packages/core/src/raster/surface.ts`; 8-bit RGBA / 1-byte mask tiles instead of photocraft's pixel formats
|
|
190
193
|
- `crates/paint/src/lib.rs` (`TIP_SHAPE`, `tip_shape`, `soft_exp`, `tip_falloff`, `tip_reach`, `dab_coverage`: Photoshop's measured round tip; `smooth`), `crates/paint/src/dynamics.rs` (`PathWalker`: the first point as a dab, then one every spacing × diameter along the path; `base_diameter` and the Transfer pressure-to-opacity rule) and `crates/paint/src/render.rs` (`rasterize_into` for the round computed tip with a 4 × 4 sub-pixel grid below 3 px; `CoverageMap::accumulate`: flow building up towards each dab's opacity ceiling; `composite`: one composite at the stroke opacity over the pre-stroke pixels, the selection multiplying coverage, the eraser and lock transparency) → `packages/core/src/paint/brush.ts`; only the computed round tip, pressure size and opacity, and simple smoothing are ported (no sampled tips, jitter, texture, dual brush, wet edges or dithering); brush test cases re-expressed → `packages/core/tests/image-layers-paint.test.ts`
|
|
191
194
|
- `crates/paint/src/mixer.rs` (`MixerSettings`, `MixerState`, `PICKUP_RATE`, `apply_mixer_stroke`: per dab, sample the canvas under the footprint by coverage and alpha, move the pickup colour towards it by the pick-up rate × wet, mix the reservoir (weight amount × (1 − mix·wet)) with the pickup (weight mix·wet), deposit at flow × the total weight, drain the reservoir by 8 % × (1 − load) per dab; `load` / `clean`) → `MixerStroke`, `normalizeMixer`, `loadMixer` and `cleanMixer` in `packages/core/src/paint/mixer.ts`; our additions are the pigment mixing model for pickup, paint and deposit, load / clean after each stroke, and tiles in place of photocraft's surfaces (no Sample All Layers or Transfer › Wetness yet); mixer test cases re-expressed → `packages/core/tests/paint-mixer.test.ts`
|
|
195
|
+
- `crates/cms/src` (`math.rs`, `curve.rs`, `clut.rs`, `pipeline.rs`, `profile.rs`, `write.rs`, `transform.rs`, `gamut.rs`, `lut3d.rs`, `builtin.rs`, `synth.rs`: the ICC v2 / v4 reader for matrix/TRC, grey TRC and `mft1` / `mft2` / `mAB ` / `mBA ` profiles, the v4.3 writer, the float stage pipeline with its optimiser, tetrahedral CLUT evaluation, transforms with per-code shaper tables, x^(1/4)-indexed output tables and 33³ / 17⁴ device links, white fixing, absolute-colorimetric media-white scaling, black point compensation after Adobe's published algorithm, soft-proof chains, gamut checks, 3D display tables, the built-in profiles from published primaries and the synthetic coated CMYK model with its Neugebauer printing model, damped least-squares separation with GCR and gamut-boundary compression) → `packages/core/src/cms`; single-threaded, the CMYK profile generated on first use (a 17³ B2A grid and a coarser gamut-boundary sample instead of photocraft's shipped 21³ profile), no `.cube` / LUT files; test cases re-expressed → `packages/core/tests/cms.test.ts`
|
|
192
196
|
- `crates/paint/src/retouch.rs` (the two retouching stroke shapes: accumulate a stroke's coverage and composite paint taken from the pre-stroke state through it, or run dabs in order over a working copy; `Smudge`), `crates/algo/src/retouch.rs` (`tone_curve`, `dodge_burn` with Protect Tones on luma and gamut compression towards luma, `saturation`, `sponge` with vibrance), `crates/algo/src/poisson.rs` (`solve_membrane`: cascadic multigrid with over-relaxed Gauss-Seidel sweeps; `seamless_clone` after Pérez, Gangnet and Blake 2003; `membrane_fill`), `crates/algo/src/inpaint.rs` (`best_offset`: the ring-matched proximity search with a coarse grid and a refinement, a hole summed-area table and a mild distance penalty) and `crates/engine/src/retouch_cmds.rs` (`clone_stamp`, `healing_brush`'s padded coverage and Dirichlet ring, `spot_heal_surface`'s dilated fill domain and heal mask, `tone_stroke`'s tone-once-from-the-original under capped coverage, `per_dab`, the aligned / non-aligned offset) → `packages/core/src/paint/retouch.ts` and `heal.ts`; on 8-bit tiles, translation-only clone sources (no scale, rotation or Clone Source panel), Spot Healing with proximity match or a smooth fill (no content-aware synthesis yet), the Smudge on our `SmudgeTip` and no Blur, Sharpen or History Brush yet; test cases re-expressed → `packages/core/tests/image-retouch.test.ts`
|
|
193
197
|
- `crates/paint/src/procedural.rs` (`smooth`, the tileable `value_noise` on a wrapped lattice, `fbm` doubling the lattice per octave, the `Paper` and `Canvas` pattern styles: fractal noise with per-pixel grain, and an over / under weave of sine threads) and `crates/paint/src/rng.rs` (counter-based randomness: every value a pure hash of seed, index and stream, so a stroke's jitter replays however its points are chunked) → `TileableNoise`, `hash2`, `rand01` in `packages/core/src/paint-editor/noise.ts` and the `cold-pressed` and `canvas` grain patterns in `packages/core/src/paint-editor/paper.ts`; on 32-bit integer hashes instead of SplitMix64, with unequal lattice periods per axis for fibres and streaks; the other paper patterns, the paper library and the grain response of dry media are our own. The paint editor's `PenDabWalker` extends our port of `crates/paint/src/dynamics.rs`'s `PathWalker` (above) with tilt, barrel rotation and velocity
|
|
194
198
|
- `crates/paint/src/symmetry.rs` (`SymmetryMode` vertical / horizontal / dual / diagonal, `PresetSymmetry::directions` with each mode's initial axis and the rotation added, `reflected_passes`: reflection about the centre along each axis plus the point reflection for dual, `segments`: the axes clipped to the document without assuming the centre is inside, and the coordinate limit) → `symmetryAxisAngles`, `symmetryCopies` and `symmetryAxisSegments` in `packages/core/src/paint-editor/guides.ts`, as affine maps of the stroke's points so one stroke paints every copy; our additions are the kaleidoscope (n rotations and the mirrored segments) and perspective guides; symmetry test cases re-expressed → `packages/core/tests/paint-editor-guides.test.ts`
|
|
@@ -271,6 +275,7 @@ GridCraft. Apache POI is © The Apache Software Foundation, licensed under the A
|
|
|
271
275
|
|
|
272
276
|
© 2026 ArtCraft Team and the WordCraft contributors.
|
|
273
277
|
|
|
278
|
+
- `crates/doc/src/connector.rs` (`sites` at the middles of the sides through the shape's turn, `site_point`, `nearest_site`, `connector_segs` straight / elbow / curved, `reroute_group`) → `packages/core/src/vector/connectors.ts`, elbows and curves leaving along the sides' normals with a gap, plus `auto` sides; test cases re-expressed → `packages/core/tests/vector-connectors.test.ts`
|
|
274
279
|
- `crates/engine/src/cmd/mailings.rs` (`parse_csv` delimiter auto-detection and blank-row skipping, `table_from_rows`, `header_split` padding / truncation and record caps, `address_map` field aliases) → `packages/core/src/grammar/data-source.ts`
|
|
275
280
|
- `crates/formats/src/sheet.rs` (`field_names`: blank headers as `Column N`, repeated headers numbered) → `packages/core/src/grammar/data-source.ts`
|
|
276
281
|
- `crates/engine/src/cmd/mailings.rs` (`condition` numeric-or-text comparison with `= <> < > <= >=`, `finish` one copy per record with SKIPIF and a merge cap) → `packages/core/src/grammar/variables.ts`, `packages/core/src/grammar/merge.ts`
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class;
|
|
2
2
|
|
|
3
|
+
var _chunk26PGXHY7cjs = require('../chunk-26PGXHY7.cjs');
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
var _chunkJLYX4V57cjs = require('../chunk-JLYX4V57.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
var _chunkWAJQKWQUcjs = require('../chunk-WAJQKWQU.cjs');
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
|
|
14
|
-
var _chunkWAJQKWQUcjs = require('../chunk-WAJQKWQU.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -30,7 +30,8 @@ var _chunkWAJQKWQUcjs = require('../chunk-WAJQKWQU.cjs');
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
var _chunkLPLCWZTMcjs = require('../chunk-LPLCWZTM.cjs');
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
|
|
@@ -558,7 +559,7 @@ function smoothMotionTimes(points, start, duration, pacing = "even") {
|
|
|
558
559
|
function motionTextLayout(nodes, id) {
|
|
559
560
|
const group = _optionalChain([nodes, 'access', _5 => _5.get, 'call', _6 => _6(id), 'optionalAccess', _7 => _7.node]);
|
|
560
561
|
if (!group || group.type !== "group") return null;
|
|
561
|
-
const letters =
|
|
562
|
+
const letters = _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, group).map((p) => ({ id: p.id, b: _optionalChain([nodes, 'access', _8 => _8.get, 'call', _9 => _9(p.id), 'optionalAccess', _10 => _10.bounds]) })).filter((l) => !!l.b && l.b.width + l.b.height > 0);
|
|
562
563
|
if (!letters.length) return null;
|
|
563
564
|
const lines = [];
|
|
564
565
|
for (const l of [...letters].sort((a, c) => a.b.y + a.b.height / 2 - (c.b.y + c.b.height / 2))) {
|
|
@@ -643,21 +644,21 @@ function indexMotionNodes(nodes) {
|
|
|
643
644
|
const out = /* @__PURE__ */ new Map();
|
|
644
645
|
const walk = (list, parentWorld, ancestors) => {
|
|
645
646
|
for (const node of list) {
|
|
646
|
-
const local =
|
|
647
|
-
const bounds =
|
|
647
|
+
const local = _chunkLPLCWZTMcjs.vectorNodeBounds.call(void 0, node);
|
|
648
|
+
const bounds = _chunkLPLCWZTMcjs.vectorNodeBounds.call(void 0, node, parentWorld);
|
|
648
649
|
const center = local ? { x: local.x + local.width / 2, y: local.y + local.height / 2 } : { x: 0, y: 0 };
|
|
649
650
|
if (!out.has(node.id)) out.set(node.id, { node, ancestors, parentWorld, center, bounds, box: local });
|
|
650
|
-
if (node.type === "group") walk(node.children,
|
|
651
|
+
if (node.type === "group") walk(node.children, _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, node), parentWorld), [...ancestors, node.id]);
|
|
651
652
|
}
|
|
652
653
|
};
|
|
653
|
-
walk(nodes,
|
|
654
|
+
walk(nodes, _chunkLPLCWZTMcjs.IDENTITY_MATRIX, []);
|
|
654
655
|
indexCache.set(nodes, out);
|
|
655
656
|
return out;
|
|
656
657
|
}
|
|
657
658
|
var solid = (paint) => typeof paint === "string" && paint !== "none" ? paint : void 0;
|
|
658
659
|
function firstPaint(node, key) {
|
|
659
660
|
if (node.type === "path") return solid(node[key]);
|
|
660
|
-
for (const p of
|
|
661
|
+
for (const p of _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node)) {
|
|
661
662
|
const s = solid(p[key]);
|
|
662
663
|
if (s) return s;
|
|
663
664
|
}
|
|
@@ -665,7 +666,7 @@ function firstPaint(node, key) {
|
|
|
665
666
|
}
|
|
666
667
|
function strokeReach(node) {
|
|
667
668
|
let reach = 0;
|
|
668
|
-
for (const p of node.type === "path" ? [node] :
|
|
669
|
+
for (const p of node.type === "path" ? [node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node)) {
|
|
669
670
|
if (p.stroke == null || p.stroke === "none") continue;
|
|
670
671
|
const width = _nullishCoalesce(p.strokeWidth, () => ( 1));
|
|
671
672
|
reach = Math.max(reach, p.strokeAlign === "outside" ? width : p.strokeAlign === "inside" ? 0 : width / 2);
|
|
@@ -735,7 +736,7 @@ function motionRestValue(entry, property, artwork) {
|
|
|
735
736
|
case "stroke":
|
|
736
737
|
return _nullishCoalesce((node && firstPaint(node, property)), () => ( "transparent"));
|
|
737
738
|
case "strokeWidth": {
|
|
738
|
-
const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ?
|
|
739
|
+
const path = _optionalChain([node, 'optionalAccess', _13 => _13.type]) === "path" ? node : node ? _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node)[0] : void 0;
|
|
739
740
|
return _nullishCoalesce(_optionalChain([path, 'optionalAccess', _14 => _14.strokeWidth]), () => ( 1));
|
|
740
741
|
}
|
|
741
742
|
case "shape":
|
|
@@ -846,12 +847,12 @@ function resolveMotionCamera(camera, scene) {
|
|
|
846
847
|
const r = camera;
|
|
847
848
|
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
848
849
|
}
|
|
849
|
-
function motionPathLength(node, parentWorld =
|
|
850
|
+
function motionPathLength(node, parentWorld = _chunkLPLCWZTMcjs.IDENTITY_MATRIX) {
|
|
850
851
|
let longest = 0;
|
|
851
|
-
const paths = node.type === "path" ? [node] :
|
|
852
|
+
const paths = node.type === "path" ? [node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node);
|
|
852
853
|
for (const p of paths) {
|
|
853
854
|
try {
|
|
854
|
-
longest = Math.max(longest, _chunkXGD3FSNCcjs.bezierPathLength.call(void 0,
|
|
855
|
+
longest = Math.max(longest, _chunkXGD3FSNCcjs.bezierPathLength.call(void 0, _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, p, parentWorld, { effects: false })));
|
|
855
856
|
} catch (e2) {
|
|
856
857
|
}
|
|
857
858
|
}
|
|
@@ -1104,12 +1105,12 @@ function compileMotionScene(scene) {
|
|
|
1104
1105
|
const order2 = _nullishCoalesce(o.order, () => ( "together"));
|
|
1105
1106
|
const pace = _nullishCoalesce(o.pace, () => ( "time"));
|
|
1106
1107
|
if (order2 === "together" && pace === "time") return null;
|
|
1107
|
-
const paths = entry.node.type === "path" ? [entry.node] :
|
|
1108
|
+
const paths = entry.node.type === "path" ? [entry.node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, entry.node);
|
|
1108
1109
|
let list = paths.map((p) => {
|
|
1109
1110
|
const at = nodes.get(p.id);
|
|
1110
1111
|
let first = { x: 0, y: 0 };
|
|
1111
1112
|
try {
|
|
1112
|
-
const m =
|
|
1113
|
+
const m = _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, p, _nullishCoalesce(_optionalChain([at, 'optionalAccess', _41 => _41.parentWorld]), () => ( _chunkLPLCWZTMcjs.IDENTITY_MATRIX)), { effects: false })[0];
|
|
1113
1114
|
if (m && m.type === "M") first = { x: m.x, y: m.y };
|
|
1114
1115
|
} catch (e3) {
|
|
1115
1116
|
}
|
|
@@ -1221,17 +1222,17 @@ function compileMotionScene(scene) {
|
|
|
1221
1222
|
let dx = _nullishCoalesce(_optionalChain([command3, 'access', _44 => _44.by, 'optionalAccess', _45 => _45.x]), () => ( 0));
|
|
1222
1223
|
let dy = _nullishCoalesce(_optionalChain([command3, 'access', _46 => _46.by, 'optionalAccess', _47 => _47.y]), () => ( 0));
|
|
1223
1224
|
if (command3.to) {
|
|
1224
|
-
const inv =
|
|
1225
|
-
const target =
|
|
1225
|
+
const inv = _chunkLPLCWZTMcjs.invertMatrix.call(void 0, entry.parentWorld);
|
|
1226
|
+
const target = _chunkLPLCWZTMcjs.applyMatrix.call(void 0, inv, command3.to);
|
|
1226
1227
|
dx = target.x - (entry.center.x + num2("x"));
|
|
1227
1228
|
dy = target.y - (entry.center.y + num2("y"));
|
|
1228
1229
|
}
|
|
1229
1230
|
if (_optionalChain([command3, 'access', _48 => _48.via, 'optionalAccess', _49 => _49.length])) {
|
|
1230
|
-
const inv =
|
|
1231
|
+
const inv = _chunkLPLCWZTMcjs.invertMatrix.call(void 0, entry.parentWorld);
|
|
1231
1232
|
const x0 = num2("x");
|
|
1232
1233
|
const y0 = num2("y");
|
|
1233
1234
|
const add = command3.blend === "add";
|
|
1234
|
-
const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) =>
|
|
1235
|
+
const offsets = [{ x: 0, y: 0 }, ...command3.via.map((p) => _chunkLPLCWZTMcjs.applyMatrix.call(void 0, inv, p)).map((p) => ({ x: p.x - entry.center.x - x0, y: p.y - entry.center.y - y0 })), { x: dx, y: dy }];
|
|
1235
1236
|
const times = smoothMotionTimes(offsets, start, end - start, _nullishCoalesce(command3.pacing, () => ( "even")));
|
|
1236
1237
|
for (const axis of ["x", "y"]) {
|
|
1237
1238
|
const base = add ? 0 : axis === "x" ? x0 : y0;
|
|
@@ -1366,6 +1367,7 @@ function fadePaint(paint, alpha) {
|
|
|
1366
1367
|
}
|
|
1367
1368
|
function mapPaths(node, fn) {
|
|
1368
1369
|
if (node.type === "path") return fn(node);
|
|
1370
|
+
if (node.type === "text" || node.type === "instance") return node;
|
|
1369
1371
|
return { ...node, children: node.children.map((c) => mapPaths(c, fn)) };
|
|
1370
1372
|
}
|
|
1371
1373
|
var morphCache = /* @__PURE__ */ new WeakMap();
|
|
@@ -1373,13 +1375,13 @@ function morphBetween(a, b) {
|
|
|
1373
1375
|
let inner = morphCache.get(a);
|
|
1374
1376
|
if (!inner) morphCache.set(a, inner = /* @__PURE__ */ new WeakMap());
|
|
1375
1377
|
let morph = inner.get(b);
|
|
1376
|
-
if (!morph) inner.set(b, morph =
|
|
1378
|
+
if (!morph) inner.set(b, morph = _chunk26PGXHY7cjs.createVectorMorph.call(void 0, a, b, { id: a.id }));
|
|
1377
1379
|
return morph;
|
|
1378
1380
|
}
|
|
1379
1381
|
function shapeIn(entry, shape) {
|
|
1380
1382
|
if (shape === entry) return entry.node;
|
|
1381
|
-
const m =
|
|
1382
|
-
return { ...shape.node, ...
|
|
1383
|
+
const m = _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, shape.node), shape.parentWorld), _chunkLPLCWZTMcjs.invertMatrix.call(void 0, entry.parentWorld));
|
|
1384
|
+
return { ...shape.node, ..._chunkLPLCWZTMcjs.isIdentityMatrix.call(void 0, m) ? { transform: void 0 } : { transform: m } };
|
|
1383
1385
|
}
|
|
1384
1386
|
function shapeAt(entry, timeline, nodes, time) {
|
|
1385
1387
|
const track = timeline.tracks.get(motionTrackKey(entry.node.id, "shape"));
|
|
@@ -1399,7 +1401,7 @@ function shapeAt(entry, timeline, nodes, time) {
|
|
|
1399
1401
|
function motionFollowRoute(entry, path) {
|
|
1400
1402
|
if (!path || path.node.type !== "path") return null;
|
|
1401
1403
|
try {
|
|
1402
|
-
return _chunkXGD3FSNCcjs.transformBezierPath.call(void 0,
|
|
1404
|
+
return _chunkXGD3FSNCcjs.transformBezierPath.call(void 0, _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, path.node, path.parentWorld, { effects: false }), _chunkLPLCWZTMcjs.invertMatrix.call(void 0, entry.parentWorld));
|
|
1403
1405
|
} catch (e4) {
|
|
1404
1406
|
return null;
|
|
1405
1407
|
}
|
|
@@ -1433,9 +1435,9 @@ function motionNodeOffset(entry, timeline, time, nodes = indexMotionNodes([entry
|
|
|
1433
1435
|
const scaleX = read("scaleX", 1);
|
|
1434
1436
|
const scaleY = read("scaleY", 1);
|
|
1435
1437
|
const c = entry.center;
|
|
1436
|
-
let matrix =
|
|
1438
|
+
let matrix = _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.scaleMatrix.call(void 0, scaleX, scaleY, c), _chunkLPLCWZTMcjs.rotateMatrix.call(void 0, rotation, c)), _chunkLPLCWZTMcjs.translateMatrix.call(void 0, dx, dy));
|
|
1437
1439
|
const along = follow ? followAt(entry, timeline, nodes, time) : null;
|
|
1438
|
-
if (along) matrix =
|
|
1440
|
+
if (along) matrix = _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, matrix, _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.translateMatrix.call(void 0, -c.x, -c.y), _chunkLPLCWZTMcjs.rotateMatrix.call(void 0, along.angle)), _chunkLPLCWZTMcjs.translateMatrix.call(void 0, along.x, along.y)));
|
|
1439
1441
|
return { matrix, dx, dy, rotation, scaleX, scaleY, follow: along };
|
|
1440
1442
|
}
|
|
1441
1443
|
function motionNodeClips(id, timeline, time) {
|
|
@@ -1502,7 +1504,7 @@ function motionFrameAt(scene, time, options = {}) {
|
|
|
1502
1504
|
const start = Math.min(1, Math.max(0, typeof drawStart === "number" ? drawStart : 0));
|
|
1503
1505
|
const end = Math.min(1, Math.max(0, typeof drawEnd === "number" ? drawEnd : 1));
|
|
1504
1506
|
if (start > 0 || end < 1) {
|
|
1505
|
-
const trim =
|
|
1507
|
+
const trim = _chunkLPLCWZTMcjs.createVectorEffect.call(void 0, "trim", MOTION_DRAW_EFFECT_ID, { start: tidy(start * 100), end: tidy(end * 100) });
|
|
1506
1508
|
p = { ...p, effects: [trim, ...(_nullishCoalesce(p.effects, () => ( []))).filter((e) => e.id !== MOTION_DRAW_EFFECT_ID)] };
|
|
1507
1509
|
}
|
|
1508
1510
|
}
|
|
@@ -1516,8 +1518,8 @@ function motionFrameAt(scene, time, options = {}) {
|
|
|
1516
1518
|
if (o >= 1) delete out.opacity;
|
|
1517
1519
|
}
|
|
1518
1520
|
const offset = options.offsets === false ? null : motionNodeOffset(entry, timeline, time, nodes);
|
|
1519
|
-
if (offset && !
|
|
1520
|
-
const m =
|
|
1521
|
+
if (offset && !_chunkLPLCWZTMcjs.isIdentityMatrix.call(void 0, offset.matrix)) {
|
|
1522
|
+
const m = _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, out), offset.matrix).map(tidy);
|
|
1521
1523
|
out = { ...out, transform: m };
|
|
1522
1524
|
}
|
|
1523
1525
|
return out;
|
|
@@ -1537,7 +1539,7 @@ function motionFrameToSvg(scene, time, options = {}) {
|
|
|
1537
1539
|
const wrap = { ...options.wrap };
|
|
1538
1540
|
for (const [id, clips] of Object.entries(frame.clips))
|
|
1539
1541
|
wrap[id] = [..._nullishCoalesce(wrap[id], () => ( [])), ...clips.map((clip, i) => ({ clip: { id: `${prefix}reveal-${id}-${i}`, shape: clip.shape, attrs: motionClipAttrs(clip) } }))];
|
|
1540
|
-
return withViewBox(
|
|
1542
|
+
return withViewBox(_chunkLPLCWZTMcjs.vectorDocumentToSvg.call(void 0, frame.document, { ...options, wrap }), frame.camera);
|
|
1541
1543
|
}
|
|
1542
1544
|
function withViewBox(svg, box) {
|
|
1543
1545
|
const f = (n) => String(Math.round(n * 1e3) / 1e3);
|
|
@@ -1720,8 +1722,8 @@ function visibleAt(timeline, id, time, node) {
|
|
|
1720
1722
|
if (Array.isArray(rect) && (rect[2] <= 1e-4 || rect[3] <= 1e-4)) return false;
|
|
1721
1723
|
const circle = clip("clipCircle");
|
|
1722
1724
|
if (Array.isArray(circle) && circle[2] <= 1e-4) return false;
|
|
1723
|
-
const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" :
|
|
1724
|
-
const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" ||
|
|
1725
|
+
const hasFill = node.type === "path" ? !!node.fill && node.fill !== "none" : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node).some((p) => p.fill && p.fill !== "none");
|
|
1726
|
+
const drawn = num2("drawEnd", 1) > 0.01 && (node.type === "path" || _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node).length === 0 || _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node).some((p) => {
|
|
1725
1727
|
const v = trackValue(timeline.tracks.get(motionTrackKey(p.id, "drawEnd")), time);
|
|
1726
1728
|
return typeof v !== "number" || v > 0.01;
|
|
1727
1729
|
}));
|
|
@@ -1807,7 +1809,7 @@ function checkMotionScene(scene) {
|
|
|
1807
1809
|
}
|
|
1808
1810
|
for (const id of targets) {
|
|
1809
1811
|
const node = nodes.get(id).node;
|
|
1810
|
-
const paths = node.type === "path" ? [node] :
|
|
1812
|
+
const paths = node.type === "path" ? [node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node);
|
|
1811
1813
|
if (paths.some((p) => p[key] !== void 0 && p[key] !== null && typeof p[key] !== "string"))
|
|
1812
1814
|
issues.push(_chunkWAJQKWQUcjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient ${key}; it switches to ${color} at the end instead of blending.`, { ...where, ids: [id] }));
|
|
1813
1815
|
}
|
|
@@ -1820,7 +1822,7 @@ function checkMotionScene(scene) {
|
|
|
1820
1822
|
else
|
|
1821
1823
|
for (const id of targets) {
|
|
1822
1824
|
const node = nodes.get(id).node;
|
|
1823
|
-
const paths = node.type === "path" ? [node] :
|
|
1825
|
+
const paths = node.type === "path" ? [node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node);
|
|
1824
1826
|
if (paths.some((p) => typeof p[key] !== "string"))
|
|
1825
1827
|
issues.push(_chunkWAJQKWQUcjs.motionIssue.call(void 0, "paint-not-color", `"${id}" has a gradient or no ${key}, so a colour pulse cannot tint it; give it a solid ${key} or pulse the ${key === "fill" ? "stroke" : "fill"}.`, { ...where, ids: [id] }));
|
|
1826
1828
|
}
|
|
@@ -2404,7 +2406,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2404
2406
|
raw: (t) => transformAt(t, true)
|
|
2405
2407
|
});
|
|
2406
2408
|
}
|
|
2407
|
-
const paths = node.type === "path" ? [node] :
|
|
2409
|
+
const paths = node.type === "path" ? [node] : _chunkLPLCWZTMcjs.collectPathNodes.call(void 0, node);
|
|
2408
2410
|
for (const path of paths) {
|
|
2409
2411
|
if (pathsSeen.has(path.id)) continue;
|
|
2410
2412
|
pathsSeen.add(path.id);
|
|
@@ -2426,7 +2428,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2426
2428
|
if (shapeSegments.length) {
|
|
2427
2429
|
if (node.type !== "path") notes.push(`"${id}" is a group: its morph or effect animation is not exported (Flair tweens one path's "d").`);
|
|
2428
2430
|
else {
|
|
2429
|
-
const inverse =
|
|
2431
|
+
const inverse = _chunkLPLCWZTMcjs.invertMatrix.call(void 0, _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, node));
|
|
2430
2432
|
channels.push({
|
|
2431
2433
|
id,
|
|
2432
2434
|
kind: "attr",
|
|
@@ -2435,9 +2437,9 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2435
2437
|
exact: () => false,
|
|
2436
2438
|
value: (t) => {
|
|
2437
2439
|
const frame = motionFrameAt(scene, t, { draw: false, offsets: false });
|
|
2438
|
-
const now =
|
|
2440
|
+
const now = _chunkLPLCWZTMcjs.expandVectorAppearance.call(void 0, _optionalChain([indexMotionNodes, 'call', _108 => _108(frame.document.nodes), 'access', _109 => _109.get, 'call', _110 => _110(id), 'optionalAccess', _111 => _111.node]));
|
|
2439
2441
|
if (!now || now.type !== "path") return "";
|
|
2440
|
-
const bezier = _chunkXGD3FSNCcjs.transformBezierPath.call(void 0,
|
|
2442
|
+
const bezier = _chunkXGD3FSNCcjs.transformBezierPath.call(void 0, _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, now, _chunkLPLCWZTMcjs.IDENTITY_MATRIX, { effects: false }), inverse);
|
|
2441
2443
|
return _chunkXGD3FSNCcjs.bezierPathToSvg.call(void 0, bezier, { precision: Math.min(precision, 2) });
|
|
2442
2444
|
}
|
|
2443
2445
|
});
|
|
@@ -2544,7 +2546,7 @@ function toFlairSvgMotion(scene, options = {}) {
|
|
|
2544
2546
|
}
|
|
2545
2547
|
if (scene.motionBlur) notes.push("Motion blur is drawn on the stage only; Flair plays the scene sharp.");
|
|
2546
2548
|
if (trigger && (_nullishCoalesce(scene.loop, () => ( "none"))) !== "none") notes.push(`The scene plays on ${trigger}, so its loop does not apply in Flair.`);
|
|
2547
|
-
let svg =
|
|
2549
|
+
let svg = _chunkLPLCWZTMcjs.vectorDocumentToSvg.call(void 0, { ...scene.artwork, nodes: _chunkLPLCWZTMcjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) }, { pretty: false, precision, wrap });
|
|
2548
2550
|
if (routes.length) svg = svg.replace(/^(<svg[^>]*>)/, `$1<defs>${routes.join("")}</defs>`);
|
|
2549
2551
|
let motion = { svg, animate };
|
|
2550
2552
|
if (_optionalChain([scene, 'access', _114 => _114.controls, 'optionalAccess', _115 => _115.length])) {
|
|
@@ -2628,14 +2630,14 @@ function easingOf(ease, fallback) {
|
|
|
2628
2630
|
return fallback;
|
|
2629
2631
|
}
|
|
2630
2632
|
function poseOf(value, entry) {
|
|
2631
|
-
const t =
|
|
2632
|
-
const o =
|
|
2633
|
+
const t = _chunkLPLCWZTMcjs.parseSvgTransform.call(void 0, String(value));
|
|
2634
|
+
const o = _chunkLPLCWZTMcjs.multiplyMatrices.call(void 0, _nullishCoalesce(_chunkLPLCWZTMcjs.invertMatrix.call(void 0, _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, entry.node)), () => ( [1, 0, 0, 1, 0, 0])), t);
|
|
2633
2635
|
const sx = Math.hypot(o[0], o[1]);
|
|
2634
2636
|
if (!(sx > 1e-9)) return null;
|
|
2635
2637
|
const sy = (o[0] * o[3] - o[1] * o[2]) / sx;
|
|
2636
2638
|
if (Math.abs(o[2] + o[1] / sx * sy) > 1e-6 || Math.abs(o[3] - o[0] / sx * sy) > 1e-6) return null;
|
|
2637
2639
|
const c = entry.center;
|
|
2638
|
-
const moved =
|
|
2640
|
+
const moved = _chunkLPLCWZTMcjs.applyMatrix.call(void 0, o, c);
|
|
2639
2641
|
return { dx: moved.x - c.x, dy: moved.y - c.y, rotation: Math.atan2(o[1], o[0]) * 180 / Math.PI, sx, sy };
|
|
2640
2642
|
}
|
|
2641
2643
|
var near = (a, b, eps = 1e-6) => Math.abs(a - b) < eps;
|
|
@@ -2720,7 +2722,7 @@ function fromFlairSvgMotion(input, options = {}) {
|
|
|
2720
2722
|
const notes = [];
|
|
2721
2723
|
if (!input || typeof input.svg !== "string") throw new Error('Give a Flair SvgMotion: { svg: "<svg \u2026>", animate: [ \u2026 ] }.');
|
|
2722
2724
|
const { motion, controls } = resolvePlaceholders(input, notes);
|
|
2723
|
-
const artwork =
|
|
2725
|
+
const artwork = _chunkLPLCWZTMcjs.parseVectorSvg.call(void 0, motion.svg);
|
|
2724
2726
|
const nodes = indexMotionNodes(artwork.nodes);
|
|
2725
2727
|
const byStep = /* @__PURE__ */ new Map();
|
|
2726
2728
|
for (const anim of _nullishCoalesce(motion.animate, () => ( []))) {
|
|
@@ -2967,9 +2969,9 @@ function toLottie(scene, options = {}) {
|
|
|
2967
2969
|
const items = [];
|
|
2968
2970
|
const shapeSegments = [...timeline.tracks.entries()].filter(([k]) => k.startsWith(`${path.id}\0`) && (k.endsWith("\0shape") || k.includes("\0effect:"))).flatMap(([, v]) => v);
|
|
2969
2971
|
const geometryAt = (t) => {
|
|
2970
|
-
if (!shapeSegments.length) return
|
|
2972
|
+
if (!shapeSegments.length) return _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, path);
|
|
2971
2973
|
const now = _optionalChain([indexMotionNodes, 'call', _124 => _124(motionFrameAt(scene, t, { draw: false, offsets: false }).document.nodes), 'access', _125 => _125.get, 'call', _126 => _126(path.id), 'optionalAccess', _127 => _127.node]);
|
|
2972
|
-
return now && now.type === "path" ?
|
|
2974
|
+
return now && now.type === "path" ? _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, _chunkLPLCWZTMcjs.expandVectorAppearances.call(void 0, [now])[0]) : _chunkLPLCWZTMcjs.vectorPathWorldBezier.call(void 0, path);
|
|
2973
2975
|
};
|
|
2974
2976
|
const rest = lottieContours(_chunkXGD3FSNCcjs.toBezierPath.call(void 0, geometryAt(0)), round2);
|
|
2975
2977
|
rest.forEach((contour, n) => {
|
|
@@ -3041,10 +3043,14 @@ function toLottie(scene, options = {}) {
|
|
|
3041
3043
|
let inner;
|
|
3042
3044
|
const innerTr = STATIC_TR();
|
|
3043
3045
|
if (node.type === "path") inner = [...pathShapes(node)];
|
|
3044
|
-
else {
|
|
3046
|
+
else if (node.type === "text" || node.type === "instance") {
|
|
3047
|
+
const drawn = _chunkLPLCWZTMcjs.expandVectorAppearance.call(void 0, node);
|
|
3048
|
+
inner = drawn.type === "path" ? [...pathShapes(drawn)] : drawn.children.filter((c) => c.type === "path").reverse().flatMap((c) => [...pathShapes(c)]);
|
|
3049
|
+
notes.push(`"${node.id}": text is exported as its outlines${_chunkLPLCWZTMcjs.vectorTextHasOutlines.call(void 0, ) ? "" : " (glyph boxes: set an outline text shaper for real glyphs)"}.`);
|
|
3050
|
+
} else {
|
|
3045
3051
|
inner = shown(node.children).reverse().map(nodeGroup);
|
|
3046
|
-
const m =
|
|
3047
|
-
if (m !==
|
|
3052
|
+
const m = _chunkLPLCWZTMcjs.nodeMatrix.call(void 0, node);
|
|
3053
|
+
if (m !== _chunkLPLCWZTMcjs.IDENTITY_MATRIX) {
|
|
3048
3054
|
const parts = staticParts(m);
|
|
3049
3055
|
if (!parts) notes.push(`"${node.id}": its transform skews, which is not exported; it is drawn without the skew.`);
|
|
3050
3056
|
else {
|
|
@@ -3057,7 +3063,7 @@ function toLottie(scene, options = {}) {
|
|
|
3057
3063
|
const body = { ty: "gr", nm: `${node.id} (own)`, it: [...inner, innerTr] };
|
|
3058
3064
|
return { ty: "gr", nm: _nullishCoalesce(node.name, () => ( node.id)), it: [body, poseTransform(entry)] };
|
|
3059
3065
|
};
|
|
3060
|
-
const artwork = { ...scene.artwork, nodes:
|
|
3066
|
+
const artwork = { ...scene.artwork, nodes: _chunkLPLCWZTMcjs.expandVectorAppearances.call(void 0, scene.artwork.nodes) };
|
|
3061
3067
|
const content = shown(artwork.nodes).reverse().map(nodeGroup);
|
|
3062
3068
|
if (artwork.background && rgba(artwork.background))
|
|
3063
3069
|
content.push({ ty: "gr", nm: "Background", it: [{ ty: "rc", nm: "Background", p: { a: 0, k: [artwork.width / 2, artwork.height / 2] }, s: { a: 0, k: [artwork.width, artwork.height] }, r: { a: 0, k: 0 } }, { ty: "fl", c: { a: 0, k: rgba(artwork.background).map(round2) }, o: { a: 0, k: 100 }, r: 1 }, STATIC_TR()] });
|
|
@@ -3156,11 +3162,11 @@ function preset(prst, w, h) {
|
|
|
3156
3162
|
const poly = (pts) => [{ closed: true, anchors: pts.map(([x, y]) => ({ x, y })) }];
|
|
3157
3163
|
switch (prst) {
|
|
3158
3164
|
case "rect":
|
|
3159
|
-
return [
|
|
3165
|
+
return [_chunkLPLCWZTMcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
3160
3166
|
case "roundRect":
|
|
3161
|
-
return [
|
|
3167
|
+
return [_chunkLPLCWZTMcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h }, Math.min(w, h) * 0.16667)];
|
|
3162
3168
|
case "ellipse":
|
|
3163
|
-
return [
|
|
3169
|
+
return [_chunkLPLCWZTMcjs.ellipseSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
3164
3170
|
case "triangle":
|
|
3165
3171
|
return poly([[w / 2, 0], [w, h], [0, h]]);
|
|
3166
3172
|
case "rtTriangle":
|
|
@@ -3268,7 +3274,7 @@ function shapes(ctx, tree, map) {
|
|
|
3268
3274
|
let subpaths = cust ? custom(cust, w, h) : prst ? preset(prst, w, h) : null;
|
|
3269
3275
|
if (!subpaths) {
|
|
3270
3276
|
if (prst) ctx.notes.push(`"${name}" is a ${prst}, drawn as its bounding rectangle.`);
|
|
3271
|
-
subpaths = [
|
|
3277
|
+
subpaths = [_chunkLPLCWZTMcjs.rectSubpath.call(void 0, { x: 0, y: 0, width: w, height: h })];
|
|
3272
3278
|
}
|
|
3273
3279
|
const style = kid(el, "style");
|
|
3274
3280
|
const fill = kid(spPr, "noFill") ? null : _nullishCoalesce(colour(ctx, kid(spPr, "solidFill")), () => ( (el.localName === "cxnSp" ? null : colour(ctx, kid(style, "fillRef")))));
|
|
@@ -4253,7 +4259,7 @@ function createAnimationEditorToolProvider(controller, options = {}) {
|
|
|
4253
4259
|
handler: ({ svg }) => {
|
|
4254
4260
|
let artwork;
|
|
4255
4261
|
try {
|
|
4256
|
-
artwork =
|
|
4262
|
+
artwork = _chunkLPLCWZTMcjs.parseVectorSvg.call(void 0, svg);
|
|
4257
4263
|
} catch (error) {
|
|
4258
4264
|
throw new Error(`The SVG could not be read: ${error.message}. Nothing was changed.`);
|
|
4259
4265
|
}
|