From 70dd46f8cec9c9fd085a47b5f9dd13d10853b9f5 Mon Sep 17 00:00:00 2001 From: Elena Torro Date: Tue, 10 Mar 2026 16:08:55 +0100 Subject: [PATCH 1/9] :bug: Fix inner stroke intersection on paths --- .../get-file-inner-stroke-overlap-seam.json | 769 ++++++++++++++++++ .../ui/render-wasm-specs/shapes.spec.js | 28 + ...verlapping-shapes-with-inner-strokes-1.png | Bin 0 -> 50794 bytes render-wasm/src/render/surfaces.rs | 24 +- 4 files changed, 812 insertions(+), 9 deletions(-) create mode 100644 frontend/playwright/data/render-wasm/get-file-inner-stroke-overlap-seam.json create mode 100644 frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/No-white-seam-at-intersections-of-overlapping-shapes-with-inner-strokes-1.png diff --git a/frontend/playwright/data/render-wasm/get-file-inner-stroke-overlap-seam.json b/frontend/playwright/data/render-wasm/get-file-inner-stroke-overlap-seam.json new file mode 100644 index 0000000000..e499f027dc --- /dev/null +++ b/frontend/playwright/data/render-wasm/get-file-inner-stroke-overlap-seam.json @@ -0,0 +1,769 @@ +{ + "~:features": { + "~#set": [ + "fdata/path-data", + "plugins/runtime", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "styles/v2", + "fdata/pointer-map", + "fdata/objects-map", + "render-wasm/v1", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:team-id": "~uaaa00001-0001-0001-8007-000000000003", + "~:permissions": { + "~:type": "~:membership", + "~:is-owner": true, + "~:is-admin": true, + "~:can-edit": true, + "~:can-read": true, + "~:is-logged": true + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "inner-stroke-overlap-seam", + "~:revn": 1, + "~:modified-at": "~m1771855365377", + "~:vern": 0, + "~:id": "~uaaa00001-0001-0001-8007-000000000001", + "~:is-shared": false, + "~:migrations": { + "~#ordered-set": [ + "legacy-2", + "legacy-3", + "legacy-5", + "legacy-6", + "legacy-7", + "legacy-8", + "legacy-9", + "legacy-10", + "legacy-11", + "legacy-12", + "legacy-13", + "legacy-14", + "legacy-16", + "legacy-17", + "legacy-18", + "legacy-19", + "legacy-25", + "legacy-26", + "legacy-27", + "legacy-28", + "legacy-29", + "legacy-31", + "legacy-32", + "legacy-33", + "legacy-34", + "legacy-36", + "legacy-37", + "legacy-38", + "legacy-39", + "legacy-40", + "legacy-41", + "legacy-42", + "legacy-43", + "legacy-44", + "legacy-45", + "legacy-46", + "legacy-47", + "legacy-48", + "legacy-49", + "legacy-50", + "legacy-51", + "legacy-52", + "legacy-53", + "legacy-54", + "legacy-55", + "legacy-56", + "legacy-57", + "legacy-59", + "legacy-62", + "legacy-65", + "legacy-66", + "legacy-67", + "0001-remove-tokens-from-groups", + "0002-normalize-bool-content-v2", + "0002-clean-shape-interactions", + "0003-fix-root-shape", + "0003-convert-path-content-v2", + "0005-deprecate-image-type", + "0006-fix-old-texts-fills", + "0008-fix-library-colors-v4", + "0009-clean-library-colors", + "0009-add-partial-text-touched-flags", + "0010-fix-swap-slots-pointing-non-existent-shapes", + "0011-fix-invalid-text-touched-flags", + "0012-fix-position-data", + "0013-fix-component-path", + "0013-clear-invalid-strokes-and-fills", + "0014-fix-tokens-lib-duplicate-ids", + "0014-clear-components-nil-objects", + "0015-fix-text-attrs-blank-strings", + "0015-clean-shadow-color", + "0016-copy-fills-from-position-data-to-text-node" + ] + }, + "~:version": 67, + "~:project-id": "~uaaa00001-0001-0001-8007-000000000004", + "~:created-at": "~m1771591980210", + "~:backend": "legacy-db", + "~:data": { + "~:pages": [ + "~uaaa00001-0001-0001-8007-000000000002" + ], + "~:pages-index": { + "~uaaa00001-0001-0001-8007-000000000002": { + "~:objects": { + "~u00000000-0000-0000-0000-000000000000": { + "~#shape": { + "~:y": 0, + "~:hide-fill-on-export": false, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "Root Frame", + "~:width": 0.01, + "~:type": "~:frame", + "~:points": [ + {"~#point": {"~:x": 0, "~:y": 0}}, + {"~#point": {"~:x": 0.01, "~:y": 0}}, + {"~#point": {"~:x": 0.01, "~:y": 0.01}}, + {"~#point": {"~:x": 0, "~:y": 0.01}} + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u00000000-0000-0000-0000-000000000000", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 0, + "~:proportion": 1, + "~:r4": 0, + "~:selrect": {"~#rect": {"~:x": 0, "~:y": 0, "~:width": 0.01, "~:height": 0.01, "~:x1": 0, "~:y1": 0, "~:x2": 0.01, "~:y2": 0.01}}, + "~:fills": [{"~:fill-color": "#FFFFFF", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": 0.01, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992e4ab5"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992e4ab5": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg", + "~:width": 86.215, + "~:type": "~:group", + "~:svg-attrs": {"~:width": "86.215", "~:height": "50"}, + "~:points": [ + {"~#point": {"~:x": 1079, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -187}}, + {"~#point": {"~:x": 1079, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992e4ab5", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1079, "~:y": -237, "~:width": 86.215, "~:height": 50, "~:x1": 1079, "~:y1": -237, "~:x2": 1165.215, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": false, + "~:height": 50, + "~:flip-y": false, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992f0a36"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992f0a36": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 86.215, + "~:type": "~:group", + "~:svg-attrs": {}, + "~:points": [ + {"~#point": {"~:x": 1079, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -187}}, + {"~#point": {"~:x": 1079, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992e4ab5", + "~:svg-viewbox": {"~#rect": {"~:x": -0.000034146222333220067, "~:y": -0.000003814697265625, "~:width": 86.21503414622225, "~:height": 50.000003814697266, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1079, "~:y": -237, "~:width": 86.215, "~:height": 50, "~:x1": 1079, "~:y1": -237, "~:x2": 1165.215, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 50, + "~:flip-y": null, + "~:shapes": [ + "~u8f89d4e8-0efd-804d-8007-b146992fbb39", + "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~u8f89d4e8-0efd-804d-8007-b14699303fd3", + "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~u8f89d4e8-0efd-804d-8007-b146993083e1", + "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~u8f89d4e8-0efd-804d-8007-b146993141e4", + "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~u8f89d4e8-0efd-804d-8007-b1469931a9d0", + "~u8f89d4e8-0efd-804d-8007-b1469931a9d1" + ] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fbb39": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAADGGIhEq6p9wxpukESrqn3DcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fbb39", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616885, "~:y": -0.000003814697265625, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 33.484923261616885, "~:y1": -0.000003814697265625, "~:x2": 52.72992048838314, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.729920488383, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#70d19d", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fde2e": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 19.244997226766372, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616814, "~:y": -0.000003814697265625, "~:width": 19.244997226766372, "~:height": 50.000003814697266, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1112.4849232616168, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.244997226766372, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.7299204883832, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 50, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992fde2f"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fde2f": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAADGGIhEq6p9wxpukESrqn3DcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fde2f", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616885, "~:y": -0.000003814697265625, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 33.484923261616885, "~:y1": -0.000003814697265625, "~:x2": 52.72992048838314, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.729920488383, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b14699303fd3": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAABBBpFEthF7w+aGlUSc+ELDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b14699303fd3", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 43.107421875, "~:y1": 19.66923798963697, "~:x2": 86.21487789622228, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#3c49ff", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469930583b": { + "~#shape": { + "~:y": -217.33076201036303, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 43.10745602122233, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1122.107421875, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 30.33076201036303, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993083e0"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993083e0": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAABBBpFEthF7w+aGlUSc+ELDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993083e0", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 43.107421875, "~:y1": 19.66923798963697, "~:x2": 86.21487789622228, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993083e1": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAD6/4JEnPhCw5+Ah0S2EXvDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993083e1", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": -0.00003414622229014341, "~:y": 19.669237989636976, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": -0.00003414622229014341, "~:y1": 19.669237989636976, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#3c49ff", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469930dc39": { + "~#shape": { + "~:y": -217.33076201036303, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 43.10745602122233, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": -0.000034146222333220067, "~:y": 19.66923798963697, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 30.33076201036303, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993110ec"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993110ec": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAD6/4JEnPhCw5+Ah0S2EXvDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993110ec", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~:svg-viewbox": {"~#rect": {"~:x": -0.00003414622229014341, "~:y": 19.669237989636976, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": -0.00003414622229014341, "~:y1": 19.669237989636976, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e4": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAAgmoxEQb6Cw03qk0RQhmXDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e4", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377042, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 43.107421875, "~:y1": 5.330620727377042, "~:x2": 70.9259006903172, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#434cc2", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e5": { + "~#shape": { + "~:y": -231.66937927262296, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 27.81847881531712, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377038, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1122.107421875, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 44.66937927262296, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993141e6"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e6": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAAgmoxEQb6Cw03qk0RQhmXDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e6", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377042, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 43.107421875, "~:y1": 5.330620727377042, "~:x2": 70.9259006903172, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931a9d0": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAACTnIREUIZlw8Dsi0RBvoLDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d0", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 15.28894305968281, "~:y": 5.330620727377026, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 15.28894305968281, "~:y1": 5.330620727377026, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#434cc2", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931a9d1": { + "~#shape": { + "~:y": -231.66937927262296, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 27.81847881531712, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d1", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 15.288943059682879, "~:y": 5.330620727377038, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1094.2889430596829, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 44.66937927262296, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b1469931e08c"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931e08c": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAACTnIREUIZlw8Dsi0RBvoLDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931e08c", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d1", + "~:svg-viewbox": {"~#rect": {"~:x": 15.28894305968281, "~:y": 5.330620727377026, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 15.28894305968281, "~:y1": 5.330620727377026, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:inner", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + } + }, + "~:id": "~uaaa00001-0001-0001-8007-000000000002", + "~:name": "Page 1" + } + }, + "~:id": "~uaaa00001-0001-0001-8007-000000000001", + "~:options": { + "~:components-v2": true, + "~:base-font-size": "16px" + } + } +} diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js index f61afbfda4..742da692b1 100644 --- a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js +++ b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js @@ -457,6 +457,34 @@ test("Check inner stroke artifacts", async ({ }); }); +test("No white seam at intersections of overlapping shapes with inner strokes", async ({ + page, +}) => { + const workspace = new WasmWorkspacePage(page); + await workspace.setupEmptyFile(); + await workspace.mockGetFile("render-wasm/get-file-inner-stroke-overlap-seam.json"); + + await workspace.goToWorkspace({ + id: "aaa00001-0001-0001-8007-000000000001", + pageId: "aaa00001-0001-0001-8007-000000000002", + }); + await workspace.waitForFirstRender(); + + await workspace.viewport.click(); + await page.keyboard.press("ControlOrMeta+A"); + const previousRenderCount = await workspace.getRenderCount(); + await page.keyboard.press("f"); + await workspace.waitForNextRender(previousRenderCount); + + await workspace.hideUI(); + + // Stricter comparison: white seam artifacts are very subtle + await expect(workspace.canvas).toHaveScreenshot({ + maxDiffPixelRatio: 0, + threshold: 0.1, + }); +}); + test("BUG 13551 - Blurs affecting other elements", async ({ page, }) => { diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/No-white-seam-at-intersections-of-overlapping-shapes-with-inner-strokes-1.png b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/No-white-seam-at-intersections-of-overlapping-shapes-with-inner-strokes-1.png new file mode 100644 index 0000000000000000000000000000000000000000..171b678f26040414ef3389fb42a2120ce6dbb5a5 GIT binary patch literal 50794 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 literal 0 HcmV?d00001 diff --git a/render-wasm/src/render/surfaces.rs b/render-wasm/src/render/surfaces.rs index 5bb227ab04..11239c2007 100644 --- a/render-wasm/src/render/surfaces.rs +++ b/render-wasm/src/render/surfaces.rs @@ -427,17 +427,23 @@ impl Surfaces { let mut stroke_paint = paint.clone(); stroke_paint.set_stroke_width(s * 2.0); canvas.draw_path(&path, &stroke_paint); + } else if let Some(eps) = inset.filter(|&e| e > 0.0) { + // Wrap fill + clear in a save_layer so the BlendMode::Clear + // only erases the current shape's fill, not other shapes + // already drawn on this surface (avoids white seams at + // intersections of shapes with inner strokes). + let layer_rec = skia::canvas::SaveLayerRec::default(); + canvas.save_layer(&layer_rec); + canvas.draw_path(&path, paint); + let mut clear_paint = skia::Paint::default(); + clear_paint.set_style(skia::PaintStyle::Stroke); + clear_paint.set_stroke_width(eps * 2.0); + clear_paint.set_blend_mode(skia::BlendMode::Clear); + clear_paint.set_anti_alias(paint.is_anti_alias()); + canvas.draw_path(&path, &clear_paint); + canvas.restore(); } else { canvas.draw_path(&path, paint); - // Inset: avoid seam with inner strokes by clearing a thin border from the fill - if let Some(eps) = inset.filter(|&e| e > 0.0) { - let mut clear_paint = skia::Paint::default(); - clear_paint.set_style(skia::PaintStyle::Stroke); - clear_paint.set_stroke_width(eps * 2.0); - clear_paint.set_blend_mode(skia::BlendMode::Clear); - clear_paint.set_anti_alias(paint.is_anti_alias()); - canvas.draw_path(&path, &clear_paint); - } } } } From e380886f517bbec1d32f4b9d116a5596caaa2c91 Mon Sep 17 00:00:00 2001 From: Aitor Moreno Date: Wed, 4 Mar 2026 13:38:50 +0100 Subject: [PATCH 2/9] :bug: Fix auto-width/fixed-width regression --- .../src/app/main/ui/workspace/shapes/text/v3_editor.cljs | 2 -- render-wasm/src/shapes/text.rs | 6 +++--- render-wasm/src/wasm/text.rs | 1 - 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v3_editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/v3_editor.cljs index 9fd4a23e99..d0cb12caeb 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v3_editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/v3_editor.cljs @@ -334,8 +334,6 @@ :on-cut on-cut :on-focus on-focus :on-blur on-blur - ;; FIXME on-click - ;; :on-click on-click :id "text-editor-wasm-input" :class (dm/str (cur/get-dynamic "text" (:rotation shape)) " " diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index 298b44cc55..8bc6568c74 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -673,7 +673,7 @@ impl TextContent { }); let size = TextContentSize::new_with_normalized_line_height( - width, + width.ceil(), paragraph_height.ceil(), DEFAULT_TEXT_CONTENT_SIZE, normalized_line_height, @@ -708,12 +708,12 @@ impl TextContent { pub fn set_layout_from_result( &mut self, result: TextContentLayoutResult, - default_height: f32, default_width: f32, + default_height: f32, ) { self.layout.set(result.0, result.1); self.size - .copy_finite_size(result.2, default_height, default_width); + .copy_finite_size(result.2, default_width, default_height); } pub fn update_layout(&mut self, selrect: Rect) -> TextContentSize { diff --git a/render-wasm/src/wasm/text.rs b/render-wasm/src/wasm/text.rs index 737925b9b4..c4f6a682d5 100644 --- a/render-wasm/src/wasm/text.rs +++ b/render-wasm/src/wasm/text.rs @@ -308,7 +308,6 @@ pub extern "C" fn set_shape_text_content() -> crate::error::Result<()> { #[no_mangle] pub extern "C" fn set_shape_grow_type(grow_type: u8) { let grow_type = RawGrowType::from(grow_type); - with_current_shape_mut!(state, |shape: &mut Shape| { if let Type::Text(text_content) = &mut shape.shape_type { text_content.set_grow_type(GrowType::from(grow_type)); From 3e60de958237a20a749b21d47bad729c96768359 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 11 Mar 2026 20:16:32 +0100 Subject: [PATCH 3/9] :bug: Backport merge issues fixes from develop. --- frontend/src/app/main/errors.cljs | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 7fcf21d0de..05f63d622e 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -130,12 +130,13 @@ (defmethod ptk/handle-error :wasm-non-blocking [error] (when-let [cause (::instance error)] - (show-not-blocking-error cause))) + (flash :cause cause))) (defmethod ptk/handle-error :wasm-critical [error] (when-let [cause (::instance error)] (ex/print-throwable cause :prefix "WASM critical error")) + (st/emit! (rt/assign-exception error))) (defmethod ptk/handle-error :wasm-exception @@ -356,24 +357,18 @@ (str/starts-with? message "invalid props on component") (str/starts-with? message "Unexpected token ")))) - (handle-uncaught [cause] - (when cause - (set! last-exception cause) - (let [data (ex-data cause) - type (get data :type)] - (if (#{:wasm-critical :wasm-non-blocking :wasm-exception} type) - (on-error cause) - (when-not (is-ignorable-exception? cause) - (ex/print-throwable cause :prefix "Uncaught Exception") - (ts/schedule #(show-not-blocking-error cause))))))) - (on-unhandled-error [event] (.preventDefault ^js event) (when-let [cause (unchecked-get event "error")] (set! last-exception cause) (when-not (is-ignorable-exception? cause) - (ex/print-throwable cause :prefix "Uncaught Exception") - (ts/schedule #(flash :cause cause :type :unhandled))))) + (let [data (ex-data cause) + type (get data :type)] + (if (#{:wasm-critical :wasm-non-blocking :wasm-exception} type) + (on-error cause) + (do + (ex/print-throwable cause :prefix "Uncaught Exception") + (ts/schedule #(flash :cause cause :type :unhandled)))))))) (on-unhandled-rejection [event] (.preventDefault ^js event) From 70ef763bfedb7ba5a56533f0c2015fbe92397f3f Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 10 Mar 2026 13:36:46 +0100 Subject: [PATCH 4/9] :bug: Fix text width not applied on first change for auto-width texts in WASM viewport --- frontend/src/app/main/data/workspace/modifiers.cljs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frontend/src/app/main/data/workspace/modifiers.cljs b/frontend/src/app/main/data/workspace/modifiers.cljs index 950c60baaa..f8be9f857b 100644 --- a/frontend/src/app/main/data/workspace/modifiers.cljs +++ b/frontend/src/app/main/data/workspace/modifiers.cljs @@ -675,6 +675,13 @@ (let [structure-entries (parse-structure-modifiers modif-tree)] (wasm.api/set-structure-modifiers structure-entries)) + ;; Apply property changes (e.g. grow-type) to WASM shapes before + ;; propagating geometry, so propagate_modifiers sees the updated state. + (doseq [[id {:keys [property value]}] (extract-property-changes modif-tree)] + (when (= property :grow-type) + (wasm.api/use-shape id) + (wasm.api/set-shape-grow-type value))) + (let [objects (dsh/lookup-page-objects state) geometry-entries From 0d1b8dc1d6a847bffd7869d94839cd20d9cb20ce Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 12 Mar 2026 08:45:14 +0100 Subject: [PATCH 5/9] :bug: Fix slash problem in embedded editor --- render-wasm/src/shapes/text.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs index 8bc6568c74..a23010585f 100644 --- a/render-wasm/src/shapes/text.rs +++ b/render-wasm/src/shapes/text.rs @@ -1151,7 +1151,7 @@ impl TextSpan { pub fn apply_text_transform(&self) -> String { let browser = crate::with_state!(state, { state.current_browser }); let text = Self::process_ignored_chars(&self.text, browser); - let transformed_text = match self.text_transform { + match self.text_transform { Some(TextTransform::Uppercase) => text.to_uppercase(), Some(TextTransform::Lowercase) => text.to_lowercase(), Some(TextTransform::Capitalize) => text @@ -1166,9 +1166,7 @@ impl TextSpan { .collect::>() .join(" "), None => text, - }; - - transformed_text.replace("/", "/\u{200B}") + } } pub fn scale_content(&mut self, value: f32) { From e72e2bf176b3003493bfff00377184e0442e8a6f Mon Sep 17 00:00:00 2001 From: Elena Torro Date: Tue, 10 Mar 2026 16:51:42 +0100 Subject: [PATCH 6/9] :bug: Fix stroke closing on outer strokes on paths --- .../get-file-outer-stroke-overlap-seam.json | 769 ++++++++++++++++++ .../ui/render-wasm-specs/shapes.spec.js | 28 + ...verlapping-shapes-with-outer-strokes-1.png | Bin 0 -> 50573 bytes render-wasm/src/shapes/paths.rs | 21 +- render-wasm/src/shapes/strokes.rs | 20 +- 5 files changed, 819 insertions(+), 19 deletions(-) create mode 100644 frontend/playwright/data/render-wasm/get-file-outer-stroke-overlap-seam.json create mode 100644 frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Correct-stroke-closing-at-self-intersection-of-overlapping-shapes-with-outer-strokes-1.png diff --git a/frontend/playwright/data/render-wasm/get-file-outer-stroke-overlap-seam.json b/frontend/playwright/data/render-wasm/get-file-outer-stroke-overlap-seam.json new file mode 100644 index 0000000000..2f2904618a --- /dev/null +++ b/frontend/playwright/data/render-wasm/get-file-outer-stroke-overlap-seam.json @@ -0,0 +1,769 @@ +{ + "~:features": { + "~#set": [ + "fdata/path-data", + "plugins/runtime", + "design-tokens/v1", + "variants/v1", + "layout/grid", + "styles/v2", + "fdata/pointer-map", + "fdata/objects-map", + "render-wasm/v1", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:team-id": "~uaaa00001-0001-0001-8007-000000000003", + "~:permissions": { + "~:type": "~:membership", + "~:is-owner": true, + "~:is-admin": true, + "~:can-edit": true, + "~:can-read": true, + "~:is-logged": true + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "outer-stroke-overlap-seam", + "~:revn": 1, + "~:modified-at": "~m1771855365377", + "~:vern": 0, + "~:id": "~uaaa00001-0001-0001-8007-000000000001", + "~:is-shared": false, + "~:migrations": { + "~#ordered-set": [ + "legacy-2", + "legacy-3", + "legacy-5", + "legacy-6", + "legacy-7", + "legacy-8", + "legacy-9", + "legacy-10", + "legacy-11", + "legacy-12", + "legacy-13", + "legacy-14", + "legacy-16", + "legacy-17", + "legacy-18", + "legacy-19", + "legacy-25", + "legacy-26", + "legacy-27", + "legacy-28", + "legacy-29", + "legacy-31", + "legacy-32", + "legacy-33", + "legacy-34", + "legacy-36", + "legacy-37", + "legacy-38", + "legacy-39", + "legacy-40", + "legacy-41", + "legacy-42", + "legacy-43", + "legacy-44", + "legacy-45", + "legacy-46", + "legacy-47", + "legacy-48", + "legacy-49", + "legacy-50", + "legacy-51", + "legacy-52", + "legacy-53", + "legacy-54", + "legacy-55", + "legacy-56", + "legacy-57", + "legacy-59", + "legacy-62", + "legacy-65", + "legacy-66", + "legacy-67", + "0001-remove-tokens-from-groups", + "0002-normalize-bool-content-v2", + "0002-clean-shape-interactions", + "0003-fix-root-shape", + "0003-convert-path-content-v2", + "0005-deprecate-image-type", + "0006-fix-old-texts-fills", + "0008-fix-library-colors-v4", + "0009-clean-library-colors", + "0009-add-partial-text-touched-flags", + "0010-fix-swap-slots-pointing-non-existent-shapes", + "0011-fix-invalid-text-touched-flags", + "0012-fix-position-data", + "0013-fix-component-path", + "0013-clear-invalid-strokes-and-fills", + "0014-fix-tokens-lib-duplicate-ids", + "0014-clear-components-nil-objects", + "0015-fix-text-attrs-blank-strings", + "0015-clean-shadow-color", + "0016-copy-fills-from-position-data-to-text-node" + ] + }, + "~:version": 67, + "~:project-id": "~uaaa00001-0001-0001-8007-000000000004", + "~:created-at": "~m1771591980210", + "~:backend": "legacy-db", + "~:data": { + "~:pages": [ + "~uaaa00001-0001-0001-8007-000000000002" + ], + "~:pages-index": { + "~uaaa00001-0001-0001-8007-000000000002": { + "~:objects": { + "~u00000000-0000-0000-0000-000000000000": { + "~#shape": { + "~:y": 0, + "~:hide-fill-on-export": false, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "Root Frame", + "~:width": 0.01, + "~:type": "~:frame", + "~:points": [ + {"~#point": {"~:x": 0, "~:y": 0}}, + {"~#point": {"~:x": 0.01, "~:y": 0}}, + {"~#point": {"~:x": 0.01, "~:y": 0.01}}, + {"~#point": {"~:x": 0, "~:y": 0.01}} + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u00000000-0000-0000-0000-000000000000", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 0, + "~:proportion": 1, + "~:r4": 0, + "~:selrect": {"~#rect": {"~:x": 0, "~:y": 0, "~:width": 0.01, "~:height": 0.01, "~:x1": 0, "~:y1": 0, "~:x2": 0.01, "~:y2": 0.01}}, + "~:fills": [{"~:fill-color": "#FFFFFF", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": 0.01, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992e4ab5"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992e4ab5": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg", + "~:width": 86.215, + "~:type": "~:group", + "~:svg-attrs": {"~:width": "86.215", "~:height": "50"}, + "~:points": [ + {"~#point": {"~:x": 1079, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -187}}, + {"~#point": {"~:x": 1079, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992e4ab5", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1079, "~:y": -237, "~:width": 86.215, "~:height": 50, "~:x1": 1079, "~:y1": -237, "~:x2": 1165.215, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": false, + "~:height": 50, + "~:flip-y": false, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992f0a36"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992f0a36": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 86.215, + "~:type": "~:group", + "~:svg-attrs": {}, + "~:points": [ + {"~#point": {"~:x": 1079, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -237}}, + {"~#point": {"~:x": 1165.215, "~:y": -187}}, + {"~#point": {"~:x": 1079, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992e4ab5", + "~:svg-viewbox": {"~#rect": {"~:x": -0.000034146222333220067, "~:y": -0.000003814697265625, "~:width": 86.21503414622225, "~:height": 50.000003814697266, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1079, "~:y": -237, "~:width": 86.215, "~:height": 50, "~:x1": 1079, "~:y1": -237, "~:x2": 1165.215, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 50, + "~:flip-y": null, + "~:shapes": [ + "~u8f89d4e8-0efd-804d-8007-b146992fbb39", + "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~u8f89d4e8-0efd-804d-8007-b14699303fd3", + "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~u8f89d4e8-0efd-804d-8007-b146993083e1", + "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~u8f89d4e8-0efd-804d-8007-b146993141e4", + "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~u8f89d4e8-0efd-804d-8007-b1469931a9d0", + "~u8f89d4e8-0efd-804d-8007-b1469931a9d1" + ] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fbb39": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAADGGIhEq6p9wxpukESrqn3DcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fbb39", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616885, "~:y": -0.000003814697265625, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 33.484923261616885, "~:y1": -0.000003814697265625, "~:x2": 52.72992048838314, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.729920488383, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#70d19d", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fde2e": { + "~#shape": { + "~:y": -237, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 19.244997226766372, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616814, "~:y": -0.000003814697265625, "~:width": 19.244997226766372, "~:height": 50.000003814697266, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1112.4849232616168, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.244997226766372, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.7299204883832, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 50, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146992fde2f"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146992fde2f": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAADGGIhEq6p9wxpukESrqn3DcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -237.00000381469727}}, + {"~#point": {"~:x": 1131.7299204883832, "~:y": -187}}, + {"~#point": {"~:x": 1112.4849232616168, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146992fde2f", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992fde2e", + "~:svg-viewbox": {"~#rect": {"~:x": 33.484923261616885, "~:y": -0.000003814697265625, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 33.484923261616885, "~:y1": -0.000003814697265625, "~:x2": 52.72992048838314, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1112.4849232616168, "~:y": -237.00000381469727, "~:width": 19.24499722676625, "~:height": 50.000003814697266, "~:x1": 1112.4849232616168, "~:y1": -237.00000381469727, "~:x2": 1131.729920488383, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b14699303fd3": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAABBBpFEthF7w+aGlUSc+ELDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b14699303fd3", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 43.107421875, "~:y1": 19.66923798963697, "~:x2": 86.21487789622228, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#3c49ff", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469930583b": { + "~#shape": { + "~:y": -217.33076201036303, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 43.10745602122233, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1122.107421875, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 30.33076201036303, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993083e0"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993083e0": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAABBBpFEthF7w+aGlUSc+ELDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1165.2148778962223, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993083e0", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469930583b", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 19.66923798963697, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 43.107421875, "~:y1": 19.66923798963697, "~:x2": 86.21487789622228, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -217.33076201036303, "~:width": 43.107456021222276, "~:height": 30.33076201036303, "~:x1": 1122.107421875, "~:y1": -217.33076201036303, "~:x2": 1165.2148778962223, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993083e1": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAD6/4JEnPhCw5+Ah0S2EXvDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993083e1", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": -0.00003414622229014341, "~:y": 19.669237989636976, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": -0.00003414622229014341, "~:y1": 19.669237989636976, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#3c49ff", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469930dc39": { + "~#shape": { + "~:y": -217.33076201036303, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 43.10745602122233, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": -0.000034146222333220067, "~:y": 19.66923798963697, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1079, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122233, "~:height": 30.33076201036303, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 30.33076201036303, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993110ec"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993110ec": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAD6/4JEnPhCw5+Ah0S2EXvDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -217.33076201036303}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1078.9999658537777, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993110ec", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469930dc39", + "~:svg-viewbox": {"~#rect": {"~:x": -0.00003414622229014341, "~:y": 19.669237989636976, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": -0.00003414622229014341, "~:y1": 19.669237989636976, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1078.9999658537777, "~:y": -217.33076201036303, "~:width": 43.10745602122229, "~:height": 30.330762010363024, "~:x1": 1078.9999658537777, "~:y1": -217.33076201036303, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e4": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAAgmoxEQb6Cw03qk0RQhmXDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e4", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377042, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 43.107421875, "~:y1": 5.330620727377042, "~:x2": 70.9259006903172, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#434cc2", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e5": { + "~#shape": { + "~:y": -231.66937927262296, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 27.81847881531712, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377038, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1122.107421875, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 44.66937927262296, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b146993141e6"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b146993141e6": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAAAgmoxEQb6Cw03qk0RQhmXDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1149.9259006903171, "~:y": -187}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b146993141e6", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146993141e5", + "~:svg-viewbox": {"~#rect": {"~:x": 43.107421875, "~:y": 5.330620727377042, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 43.107421875, "~:y1": 5.330620727377042, "~:x2": 70.9259006903172, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1122.107421875, "~:y": -231.66937927262296, "~:width": 27.818478815317206, "~:height": 44.66937927262296, "~:x1": 1122.107421875, "~:y1": -231.66937927262296, "~:x2": 1149.9259006903171, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931a9d0": { + "~#shape": { + "~:y": null, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAACTnIREUIZlw8Dsi0RBvoLDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:className": "fills"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d0", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 15.28894305968281, "~:y": 5.330620727377026, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 15.28894305968281, "~:y1": 5.330620727377026, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [{"~:fill-color": "#434cc2", "~:fill-opacity": 1}], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931a9d1": { + "~#shape": { + "~:y": -231.66937927262296, + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:name": "svg-g", + "~:width": 27.81847881531712, + "~:type": "~:group", + "~:svg-attrs": {"~:className": "strokes"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d1", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b146992f0a36", + "~:svg-viewbox": {"~#rect": {"~:x": 15.288943059682879, "~:y": 5.330620727377038, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 0, "~:y1": 0, "~:x2": 86.215, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 1094.2889430596829, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.81847881531712, "~:height": 44.66937927262296, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": 44.66937927262296, + "~:flip-y": null, + "~:shapes": ["~u8f89d4e8-0efd-804d-8007-b1469931e08c"] + } + }, + "~u8f89d4e8-0efd-804d-8007-b1469931e08c": { + "~#shape": { + "~:y": null, + "~:stroke-cap-start": "~:round", + "~:transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:rotation": 0, + "~:content": {"~#penpot/path-data": "~bAQAAAAAAAAAAAAAAAAAAAAAAAABwQ4xEAAA7wwMAAACTnIREUIZlw8Dsi0RBvoLDcEOMRAAAO8M="}, + "~:name": "svg-path", + "~:width": null, + "~:type": "~:path", + "~:svg-attrs": {"~:fill": "none", "~:style": {"~:fill": "none"}, "~:strokeLinecap": "round", "~:strokeMiterlimit": "10", "~:className": "stroke-shape"}, + "~:points": [ + {"~#point": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -231.66937927262296}}, + {"~#point": {"~:x": 1122.107421875, "~:y": -187}}, + {"~#point": {"~:x": 1094.2889430596829, "~:y": -187}} + ], + "~:proportion-lock": false, + "~:stroke-cap-end": "~:round", + "~:transform-inverse": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:stroke-linecap": "~:round", + "~:svg-transform": {"~#matrix": {"~:a": 1, "~:b": 0, "~:c": 0, "~:d": 1, "~:e": 0, "~:f": 0}}, + "~:id": "~u8f89d4e8-0efd-804d-8007-b1469931e08c", + "~:parent-id": "~u8f89d4e8-0efd-804d-8007-b1469931a9d1", + "~:svg-viewbox": {"~#rect": {"~:x": 15.28894305968281, "~:y": 5.330620727377026, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 15.28894305968281, "~:y1": 5.330620727377026, "~:x2": 43.107421875, "~:y2": 50}}, + "~:svg-defs": {}, + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [{"~:stroke-alignment": "~:outer", "~:stroke-style": "~:solid", "~:stroke-color": "#000000", "~:stroke-opacity": 1, "~:stroke-width": 1}], + "~:x": null, + "~:proportion": 1, + "~:selrect": {"~#rect": {"~:x": 1094.2889430596829, "~:y": -231.66937927262296, "~:width": 27.818478815317192, "~:height": 44.669379272622976, "~:x1": 1094.2889430596829, "~:y1": -231.66937927262296, "~:x2": 1122.107421875, "~:y2": -187}}, + "~:fills": [], + "~:flip-x": null, + "~:height": null, + "~:flip-y": null + } + } + }, + "~:id": "~uaaa00001-0001-0001-8007-000000000002", + "~:name": "Page 1" + } + }, + "~:id": "~uaaa00001-0001-0001-8007-000000000001", + "~:options": { + "~:components-v2": true, + "~:base-font-size": "16px" + } + } +} diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js index 9d6f38351f..4d0597b9aa 100644 --- a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js +++ b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js @@ -485,6 +485,34 @@ test("No white seam at intersections of overlapping shapes with inner strokes", }); }); +test("Correct stroke closing at self-intersection of overlapping shapes with outer strokes", async ({ + page, +}) => { + const workspace = new WasmWorkspacePage(page); + await workspace.setupEmptyFile(); + await workspace.mockGetFile("render-wasm/get-file-outer-stroke-overlap-seam.json"); + + await workspace.goToWorkspace({ + id: "aaa00001-0001-0001-8007-000000000001", + pageId: "aaa00001-0001-0001-8007-000000000002", + }); + await workspace.waitForFirstRender(); + + await workspace.viewport.click(); + await page.keyboard.press("ControlOrMeta+A"); + const previousRenderCount = await workspace.getRenderCount(); + await page.keyboard.press("f"); + await workspace.waitForNextRender(previousRenderCount); + + await workspace.hideUI(); + + // Stricter comparison: white seam artifacts are very subtle + await expect(workspace.canvas).toHaveScreenshot({ + maxDiffPixelRatio: 0, + threshold: 0.1, + }); +}); + test("BUG 13551 - Blurs affecting other elements", async ({ page, }) => { diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Correct-stroke-closing-at-self-intersection-of-overlapping-shapes-with-outer-strokes-1.png b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Correct-stroke-closing-at-self-intersection-of-overlapping-shapes-with-outer-strokes-1.png new file mode 100644 index 0000000000000000000000000000000000000000..3b041ad6edbe20bdfe1ed33d2ebbfe0977bc0ade GIT binary patch literal 50573 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 Uvr>x|e*NW(1{d;wz5V!q08sl1^8f$< literal 0 HcmV?d00001 diff --git a/render-wasm/src/shapes/paths.rs b/render-wasm/src/shapes/paths.rs index d6d6a8d1ef..8fa81c6b77 100644 --- a/render-wasm/src/shapes/paths.rs +++ b/render-wasm/src/shapes/paths.rs @@ -32,34 +32,25 @@ impl Default for Path { impl Path { pub fn new(segments: Vec) -> Self { let mut pb = skia::PathBuilder::new(); - let mut start = None; + // Don't auto-close the Skia path when start ≈ end. + // SVG treats these as open paths (caps apply at endpoints). + // Auto-closing changes stroke behavior from caps to joins, + // producing artifacts at self-intersection points. + // Only explicit Segment::Close should close the Skia path. for segment in segments.iter() { - let destination = match *segment { + match *segment { Segment::MoveTo(xy) => { - start = Some(xy); pb.move_to(xy); - None } Segment::LineTo(xy) => { pb.line_to(xy); - Some(xy) } Segment::CurveTo((c1, c2, xy)) => { pb.cubic_to(c1, c2, xy); - Some(xy) } Segment::Close => { pb.close(); - None - } - }; - - if let (Some(start), Some(destination)) = (start, destination) { - if math::is_close_to(destination.0, start.0) - && math::is_close_to(destination.1, start.1) - { - pb.close(); } } } diff --git a/render-wasm/src/shapes/strokes.rs b/render-wasm/src/shapes/strokes.rs index 426d5939c3..4ca3b5f906 100644 --- a/render-wasm/src/shapes/strokes.rs +++ b/render-wasm/src/shapes/strokes.rs @@ -213,12 +213,24 @@ impl Stroke { paint.set_anti_alias(antialias); if let Some(svg_attrs) = svg_attrs { - if svg_attrs.stroke_linecap == StrokeLineCap::Round { - paint.set_stroke_cap(skia::paint::Cap::Round); + match svg_attrs.stroke_linecap { + StrokeLineCap::Round => { + paint.set_stroke_cap(skia::paint::Cap::Round); + } + StrokeLineCap::Square => { + paint.set_stroke_cap(skia::paint::Cap::Square); + } + StrokeLineCap::Butt => {} // Skia default } - if svg_attrs.stroke_linejoin == StrokeLineJoin::Round { - paint.set_stroke_join(skia::paint::Join::Round); + match svg_attrs.stroke_linejoin { + StrokeLineJoin::Round => { + paint.set_stroke_join(skia::paint::Join::Round); + } + StrokeLineJoin::Bevel => { + paint.set_stroke_join(skia::paint::Join::Bevel); + } + StrokeLineJoin::Miter => {} // Skia default } } From 6ca8865e5b9ad93e6428f5e9b1c336a393f6cd0a Mon Sep 17 00:00:00 2001 From: Elena Torro Date: Thu, 12 Mar 2026 12:00:03 +0100 Subject: [PATCH 7/9] :bug: Close the subpath when possible --- render-wasm/src/math/bools.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/render-wasm/src/math/bools.rs b/render-wasm/src/math/bools.rs index 67de1e874e..0215e50dca 100644 --- a/render-wasm/src/math/bools.rs +++ b/render-wasm/src/math/bools.rs @@ -365,11 +365,10 @@ fn beziers_to_segments(beziers: &[(BezierSource, Bezier)]) -> Vec { let mut bm = init_bm(beziers); while let Some(bezier) = pop_first(&mut bm) { - result.push(Segment::MoveTo(( - bezier.1.start.x as f32, - bezier.1.start.y as f32, - ))); + let start = (bezier.1.start.x as f32, bezier.1.start.y as f32); + result.push(Segment::MoveTo(start)); push_bezier(&mut result, &bezier.1); + let mut last_end = (bezier.1.end.x as f32, bezier.1.end.y as f32); let mut next_p = BezierStart(bezier.0, bezier.1.end); loop { @@ -377,8 +376,24 @@ fn beziers_to_segments(beziers: &[(BezierSource, Bezier)]) -> Vec { break; }; push_bezier(&mut result, &next.1); + last_end = (next.1.end.x as f32, next.1.end.y as f32); next_p = BezierStart(next.0, next.1.end); } + + // Close the subpath if the last point is close to the start. + if (last_end.0 - start.0).abs() < INTERSECT_THRESHOLD_SAME + && (last_end.1 - start.1).abs() < INTERSECT_THRESHOLD_SAME + { + // Remove the redundant LineTo that goes back to start, if present. + if let Some(Segment::LineTo(p)) = result.last() { + if (p.0 - start.0).abs() < INTERSECT_THRESHOLD_SAME + && (p.1 - start.1).abs() < INTERSECT_THRESHOLD_SAME + { + result.pop(); + } + } + result.push(Segment::Close); + } } result } From 0c778d72784196dfc75395a27e91abc4bdd40946 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 10 Mar 2026 13:58:17 +0100 Subject: [PATCH 8/9] :bug: Consolidate WASM text content update and resize into a single change --- .../src/app/main/data/workspace/shapes.cljs | 6 + .../src/app/main/data/workspace/texts.cljs | 210 ++++++++++++------ .../app/main/data/workspace/wasm_text.cljs | 34 ++- .../ui/workspace/shapes/text/v2_editor.cljs | 3 +- 4 files changed, 166 insertions(+), 87 deletions(-) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index b93258a869..989e85eb38 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -114,6 +114,12 @@ (cts/check-shape shape) (ptk/reify ::add-shape + ptk/UpdateEvent + (update [_ state] + (cond-> state + (and (cfh/text-shape? shape) (nil? (:content shape))) + (update :workspace-new-text-shapes (fnil conj #{}) (:id shape)))) + ptk/WatchEvent (watch [it state _] (let [page-id (:current-page-id state) diff --git a/frontend/src/app/main/data/workspace/texts.cljs b/frontend/src/app/main/data/workspace/texts.cljs index 421b29d4d0..b1903ec5c5 100644 --- a/frontend/src/app/main/data/workspace/texts.cljs +++ b/frontend/src/app/main/data/workspace/texts.cljs @@ -13,6 +13,7 @@ [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cfh] [app.common.geom.point :as gpt] + [app.common.geom.rect :as grc] [app.common.geom.shapes :as gsh] [app.common.math :as mth] [app.common.types.fills :as types.fills] @@ -101,7 +102,9 @@ (update [_ state] (if (some? editor-state) (update state :workspace-editor-state assoc id editor-state) - (update state :workspace-editor-state dissoc id))))) + (-> state + (update :workspace-editor-state dissoc id) + (update :workspace-new-text-shapes disj id)))))) (defn finalize-editor-state [id update-name?] @@ -116,11 +119,12 @@ (ted/get-editor-current-content)) name (gen-name editor-state) - new-shape? (nil? (:content shape))] + new-shape? (contains? (:workspace-new-text-shapes state) id)] (if (ted/content-has-text? content) - (if (features/active-feature? state "render-wasm/v1") - (let [content (d/merge (ted/export-content content) - (dissoc (:content shape) :children))] + (when (features/active-feature? state "render-wasm/v1") + (let [content (d/merge (ted/export-content content) + (dissoc (:content shape) :children)) + new-size (dwwt/get-wasm-text-new-size shape content)] (rx/merge (rx/of (update-editor-state shape nil)) (when (and (not= content (:content shape)) @@ -133,39 +137,38 @@ (-> shape (assoc :content content) (cond-> (and update-name? (some? name)) - (assoc :name name)))) - {:undo-group (when new-shape? id)}) - - (dwm/apply-wasm-modifiers - (dwwt/resize-wasm-text-modifiers shape content) - {:undo-group (when new-shape? id)}))))) - - (let [content (d/merge (ted/export-content content) - (dissoc (:content shape) :children)) - modifiers (get-in state [:workspace-text-modifier id])] - (rx/merge - (rx/of (update-editor-state shape nil)) - (when (and (not= content (:content shape)) - (some? (:current-page-id state)) - (some? shape)) - (rx/of - (dwsh/update-shapes - [id] - (fn [shape] - (let [{:keys [width height position-data]} modifiers] - (-> shape - (assoc :content content) - (cond-> position-data - (assoc :position-data position-data)) - (cond-> (and update-name? (some? name)) - (assoc :name name)) - (cond-> (or (some? width) (some? height)) - (gsh/transform-shape (ctm/change-size shape width height)))))) + (assoc :name name)) + (cond-> (some? new-size) + (gsh/transform-shape + (ctm/change-size shape (:width new-size) (:height new-size)))))) {:undo-group (when new-shape? id)})))))) - (when (some? id) - (rx/of (dws/deselect-shape id) - (dwsh/delete-shapes #{id}))))))))) + (let [content (d/merge (ted/export-content content) + (dissoc (:content shape) :children)) + modifiers (get-in state [:workspace-text-modifier id])] + (rx/merge + (rx/of (update-editor-state shape nil)) + (when (and (not= content (:content shape)) + (some? (:current-page-id state)) + (some? shape)) + (rx/of + (dwsh/update-shapes + [id] + (fn [shape] + (let [{:keys [width height position-data]} modifiers] + (-> shape + (assoc :content content) + (cond-> position-data + (assoc :position-data position-data)) + (cond-> (and update-name? (some? name)) + (assoc :name name)) + (cond-> (or (some? width) (some? height)) + (gsh/transform-shape (ctm/change-size shape width height)))))) + {:undo-group (when new-shape? id)})))))) + + (when (some? id) + (rx/of (dws/deselect-shape id) + (dwsh/delete-shapes #{id})))))))) (defn initialize-editor-state [{:keys [id name content] :as shape} decorator] @@ -178,8 +181,7 @@ editor (cond-> (ted/create-editor-state text-state decorator) (and (nil? content) (some? attrs)) (ted/update-editor-current-block-data attrs))] - (-> state - (assoc-in [:workspace-editor-state id] editor)))) + (assoc-in state [:workspace-editor-state id] editor))) ptk/WatchEvent (watch [_ state stream] @@ -917,6 +919,46 @@ (update [_ state] (update-in state [:workspace-text-modifier shape-id] {:position-data position-data})))) +(defn- add-geometry-undo-to-commit + "Adds geometry undo/redo to a commit so undo restores both content and geometry. + old-geom and final-geom are maps with :selrect :points and optionally :width :height." + [base objects id old-geom final-geom attrs] + (let [objects-with-old (update objects id #(merge % old-geom)) + final-shape-fn (fn [shape] (merge shape final-geom))] + (-> base + (pcb/with-objects objects-with-old) + (pcb/update-shapes [id] final-shape-fn {:attrs attrs}) + (pcb/set-stack-undo? true)))) + +(defn- build-finalize-commit-changes + "Builds the commit changes for text finalization (content + geometry undo). + For auto-width text, include geometry so undo restores e.g. width." + [it state id {:keys [new-shape? content-has-text? content original-content undo-group]}] + (let [page-id (:current-page-id state) + objects (dsh/lookup-page-objects state page-id) + shape* (get objects id) + base (-> (pcb/empty-changes it page-id) + (pcb/set-text-content id content original-content) + (cond-> new-shape? + (-> (pcb/set-undo-group id) + (pcb/set-stack-undo? true))) + (cond-> (and (not new-shape?) (some? undo-group)) + (-> (pcb/set-undo-group undo-group) + (pcb/set-stack-undo? true)))) + final-geom (select-keys shape* [:selrect :points :width :height]) + geom-keys (if new-shape? [:selrect :points] [:selrect :points :width :height]) + old-geom (when (and content-has-text? (not= :fixed (:grow-type shape*))) + (or (get-in state [:workspace-text-session-geom id]) + (let [sr (:selrect shape*) + r (grc/make-rect (or (:x sr) 0) (or (:y sr) 0) 0.01 0.01)] + {:selrect r :points (grc/rect->points r)})))] + (if (some? old-geom) + (add-geometry-undo-to-commit base objects id + (select-keys old-geom geom-keys) + (select-keys final-geom geom-keys) + geom-keys) + base))) + (defn v2-update-text-shape-content [id content & {:keys [update-name? name finalize? save-undo? original-content] :or {update-name? false name nil finalize? false save-undo? true original-content nil}}] @@ -926,64 +968,84 @@ (if (features/active-feature? state "render-wasm/v1") (let [objects (dsh/lookup-page-objects state) shape (get objects id) - new-shape? (nil? (:content shape)) + new-shape? (contains? (:workspace-new-text-shapes state) id) prev-content (:content shape) has-prev-content? (not (nil? (:prev-content shape))) - has-content? (when-not new-shape? - (v2-content-has-text? content)) - did-has-content? (when-not new-shape? - (v2-content-has-text? prev-content))] + ;; For existing shapes, capture geometry at session start once so + ;; finalize can build a single undo entry. Stored in workspace state, + ;; not in the shape, to avoid persisting session-only data. + session-start-geom (or (get-in state [:workspace-text-session-geom id]) + (select-keys shape [:selrect :points :width :height])) + content-has-text? (v2-content-has-text? content) + prev-content-has-text? (v2-content-has-text? prev-content) + new-size (when (and (not= :fixed (:grow-type shape)) + content-has-text?) + (dwwt/get-wasm-text-new-size shape content)) + ;; New shapes: single undo on finalize only (no per-keystroke undo) + effective-save-undo? (if new-shape? finalize? save-undo?) + effective-stack-undo? (and new-shape? finalize?) + finalize-undo-group (when (and finalize? (not new-shape?)) (uuid/next))] (rx/concat (rx/of + ;; Store session-start geometry in workspace state once for existing shapes + (when (and (not new-shape?) + (nil? (get-in state [:workspace-text-session-geom id]))) + (fn [s] (assoc-in s [:workspace-text-session-geom id] session-start-geom))) (dwsh/update-shapes [id] (fn [shape] - (let [new-shape (-> shape - (assoc :content content) - (cond-> (and has-content? - has-prev-content?) - (dissoc :prev-content)) - (cond-> (and did-has-content? - (not has-content?)) - (assoc :prev-content prev-content)) - (cond-> (and update-name? (some? name)) - (assoc :name name)))] - new-shape)) - {:save-undo? save-undo? :undo-group (when new-shape? id)}) + (-> shape + (assoc :content content) + (cond-> (and (not new-shape?) + content-has-text? + has-prev-content?) + (dissoc :prev-content)) + (cond-> (and (not new-shape?) + prev-content-has-text? + (not content-has-text?)) + (assoc :prev-content prev-content)) + (cond-> (and update-name? (some? name)) + (assoc :name name)) + (cond-> (some? new-size) + (gsh/transform-shape + (ctm/change-size shape (:width new-size) (:height new-size)))))) + {:save-undo? effective-save-undo? + :stack-undo? effective-stack-undo? + :undo-group (or finalize-undo-group (when new-shape? id))}) - (when-let [modifiers (dwwt/resize-wasm-text-modifiers shape content)] - (let [options {:undo-group (when new-shape? id)}] - (if (and (not= :fixed (:grow-type shape)) finalize?) - (dwm/apply-wasm-modifiers modifiers options) - (dwm/set-wasm-modifiers modifiers options))))) + ;; When we don't update the shape (no new-size), still update WASM display + (when-not (some? new-size) + (when-let [modifiers (dwwt/resize-wasm-text-modifiers shape content)] + (dwm/set-wasm-modifiers modifiers {:undo-group (when new-shape? id)})))) (when finalize? (rx/concat - (when (and (not has-content?) (some? id)) + (when (and (not content-has-text?) (some? id)) (rx/of (when has-prev-content? (dwsh/update-shapes [id] - (fn [shape] - (let [new-shape (-> shape - (assoc :content (:prev-content shape)))] - new-shape)) + (fn [shape] (assoc shape :content (:prev-content shape))) {:save-undo? false})) (dws/deselect-shape id) (dwsh/delete-shapes #{id}))) (rx/of - ;; This commit is necesary for undo and component propagation - ;; on finalization (dch/commit-changes - (-> (pcb/empty-changes it (:current-page-id state)) - (pcb/set-text-content id content original-content))) - (dwt/finish-transform)))))) + (build-finalize-commit-changes it state id + {:new-shape? new-shape? + :content-has-text? content-has-text? + :content content + :original-content original-content + :undo-group finalize-undo-group})) + (dwt/finish-transform) + (fn [state] + (-> state + (update :workspace-new-text-shapes disj id) + (update :workspace-text-session-geom (fnil dissoc {}) id)))))))) - (let [objects (dsh/lookup-page-objects state) - shape (get objects id) - modifiers (get-in state [:workspace-text-modifier id]) - new-shape? (nil? (:content shape))] + (let [modifiers (get-in state [:workspace-text-modifier id]) + new-shape? (contains? (:workspace-new-text-shapes state) id)] (rx/of (dwsh/update-shapes [id] (fn [shape] diff --git a/frontend/src/app/main/data/workspace/wasm_text.cljs b/frontend/src/app/main/data/workspace/wasm_text.cljs index 594a657105..c43cee567f 100644 --- a/frontend/src/app/main/data/workspace/wasm_text.cljs +++ b/frontend/src/app/main/data/workspace/wasm_text.cljs @@ -22,26 +22,36 @@ [beicon.v2.core :as rx] [potok.v2.core :as ptk])) -(defn resize-wasm-text-modifiers +(defn get-wasm-text-new-size + "Computes the new {width, height} for a text shape from WASM text layout. + For :fixed grow-type, updates WASM content and returns current dimensions (no resize)." ([shape] - (resize-wasm-text-modifiers shape (:content shape))) + (get-wasm-text-new-size shape (:content shape))) - ([{:keys [id points selrect grow-type] :as shape} content] + ([{:keys [id selrect grow-type] :as shape} content] (when id (wasm.api/use-shape id) (wasm.api/set-shape-text-content id content) (wasm.api/set-shape-text-images id content) + (let [dimension (when (not= :fixed grow-type) + (wasm.api/get-text-dimensions))] + {:width (if (#{:fixed :auto-height} grow-type) + (:width selrect) + (:width dimension)) + :height (if (= :fixed grow-type) + (:height selrect) + (:height dimension))})))) - (let [dimension (wasm.api/get-text-dimensions) - width-scale (if (#{:fixed :auto-height} grow-type) - 1.0 - (/ (:width dimension) (:width selrect))) - height-scale (if (= :fixed grow-type) - 1.0 - (/ (:height dimension) (:height selrect))) - resize-v (gpt/point width-scale height-scale) - origin (first points)] +(defn resize-wasm-text-modifiers + ([shape] + (resize-wasm-text-modifiers shape (:content shape))) + ([{:keys [id points selrect] :as shape} content] + (when-let [new-size (get-wasm-text-new-size shape content)] + (let [width-scale (/ (:width new-size) (:width selrect)) + height-scale (/ (:height new-size) (:height selrect)) + resize-v (gpt/point width-scale height-scale) + origin (first points)] {id {:modifiers (ctm/resize-modifiers diff --git a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs index fd33cdcb45..29e6ec6759 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/v2_editor.cljs @@ -118,7 +118,8 @@ :update-name? update-name? :name generated-name :finalize? true - :save-undo? false + ;; Single undo entry for the whole edit + :save-undo? true :original-content original-content)))) (let [container-node (mf/ref-val container-ref)] From 99151fe530c165b22cc0806d96f624567b60fe13 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 12 Mar 2026 17:30:57 +0100 Subject: [PATCH 9/9] :bug: Fix problem with update live sidebar values --- .../src/app/main/ui/workspace/sidebar/options.cljs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options.cljs b/frontend/src/app/main/ui/workspace/sidebar/options.cljs index d5a1f181dd..c7413af9ac 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options.cljs @@ -15,6 +15,7 @@ [app.main.data.helpers :as dsh] [app.main.data.workspace :as udw] [app.main.data.workspace.common :as dwc] + [app.main.features :as features] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.context :as ctx] @@ -39,7 +40,6 @@ [app.main.ui.workspace.sidebar.options.shapes.text :as text] [app.util.i18n :as i18n :refer [tr]] [okulary.core :as l] - [rumext.v2 :as mf])) ;; --- Options @@ -50,10 +50,15 @@ (let [shape-type (dm/get-prop shape :type) shape-id (dm/get-prop shape :id) + wasm-modifiers (mf/deref refs/workspace-wasm-modifiers) modifiers (mf/deref refs/workspace-modifiers) - modifiers (dm/get-in modifiers [shape-id :modifiers]) - shape (gsh/transform-shape shape modifiers) + shape + (if (features/active-feature? @st/state "render-wasm/v1") + (let [wasm-modifiers (into {} wasm-modifiers)] + (gsh/apply-transform shape (get wasm-modifiers shape-id))) + (gsh/transform-shape shape (dm/get-in modifiers [shape-id :modifiers]))) + props (mf/spread-props props {:shape shape :file-id file-id :page-id page-id :libraries libraries})] (case shape-type