diff --git a/common/src/app/common/types/shape/interactions.cljc b/common/src/app/common/types/shape/interactions.cljc
index 127ebee57f..6b06b68897 100644
--- a/common/src/app/common/types/shape/interactions.cljc
+++ b/common/src/app/common/types/shape/interactions.cljc
@@ -139,8 +139,8 @@
[:map {:title "OpenOverlayInteraction"}
[:action-type [:= :open-overlay]]
[:event-type [::sm/one-of event-types]]
- [:overlay-position ::gpt/point]
- [:overlay-pos-type [::sm/one-of overlay-positioning-types]]
+ [:overlay-position {:optional true} ::gpt/point]
+ [:overlay-pos-type {:optional true} [::sm/one-of overlay-positioning-types]]
[:destination {:optional true} [:maybe ::sm/uuid]]
[:close-click-outside {:optional true} :boolean]
[:background-overlay {:optional true} :boolean]
@@ -151,8 +151,8 @@
[:map {:title "ToggleOverlayInteraction"}
[:action-type [:= :toggle-overlay]]
[:event-type [::sm/one-of event-types]]
- [:overlay-position ::gpt/point]
- [:overlay-pos-type [::sm/one-of overlay-positioning-types]]
+ [:overlay-position {:optional true} ::gpt/point]
+ [:overlay-pos-type {:optional true} [::sm/one-of overlay-positioning-types]]
[:destination {:optional true} [:maybe ::sm/uuid]]
[:close-click-outside {:optional true} :boolean]
[:background-overlay {:optional true} :boolean]
diff --git a/docs/img/styling/background-blur.webp b/docs/img/styling/background-blur.webp
new file mode 100644
index 0000000000..3c7a0859de
Binary files /dev/null and b/docs/img/styling/background-blur.webp differ
diff --git a/docs/package.json b/docs/package.json
index cf16fae313..299d497e48 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -27,16 +27,16 @@
"@11ty/eleventy": "^3.1.6",
"@11ty/eleventy-navigation": "^1.0.5",
"@11ty/eleventy-plugin-rss": "^3.0.0",
- "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0",
+ "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
"@tigersway/eleventy-plugin-ancestry": "^1.0.3",
"@types/markdown-it": "14.1.2",
"elasticlunr": "^0.9.5",
- "eleventy-plugin-metagen": "^1.8.3",
+ "eleventy-plugin-metagen": "^1.8.4",
"eleventy-plugin-nesting-toc": "^1.3.0",
- "eleventy-plugin-youtube-embed": "^1.10.2",
- "luxon": "^3.4.4",
- "markdown-it": "^14.1.0",
- "markdown-it-anchor": "^9.0.1",
+ "eleventy-plugin-youtube-embed": "^1.13.2",
+ "luxon": "^3.7.2",
+ "markdown-it": "^14.2.0",
+ "markdown-it-anchor": "^9.2.0",
"markdown-it-plantuml": "^1.4.1"
},
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b"
diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml
index 2ea471ca0c..d32be57396 100644
--- a/docs/pnpm-lock.yaml
+++ b/docs/pnpm-lock.yaml
@@ -18,7 +18,7 @@ importers:
specifier: ^3.0.0
version: 3.0.0
'@11ty/eleventy-plugin-syntaxhighlight':
- specifier: ^5.0.0
+ specifier: ^5.0.2
version: 5.0.2
'@tigersway/eleventy-plugin-ancestry':
specifier: ^1.0.3
@@ -30,22 +30,22 @@ importers:
specifier: ^0.9.5
version: 0.9.5
eleventy-plugin-metagen:
- specifier: ^1.8.3
+ specifier: ^1.8.4
version: 1.8.4
eleventy-plugin-nesting-toc:
specifier: ^1.3.0
version: 1.3.0
eleventy-plugin-youtube-embed:
- specifier: ^1.10.2
+ specifier: ^1.13.2
version: 1.13.2
luxon:
- specifier: ^3.4.4
+ specifier: ^3.7.2
version: 3.7.2
markdown-it:
- specifier: ^14.1.0
+ specifier: ^14.2.0
version: 14.2.0
markdown-it-anchor:
- specifier: ^9.0.1
+ specifier: ^9.2.0
version: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.2.0)
markdown-it-plantuml:
specifier: ^1.4.1
@@ -436,8 +436,8 @@ packages:
resolution: {integrity: sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==}
engines: {node: '>=6.0'}
- js-yaml@3.14.2:
- resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==}
+ js-yaml@3.15.0:
+ resolution: {integrity: sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==}
hasBin: true
js-yaml@4.2.0:
@@ -692,8 +692,8 @@ packages:
uc.micro@2.1.0:
resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
- undici@7.27.2:
- resolution: {integrity: sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==}
+ undici@7.28.0:
+ resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==}
engines: {node: '>=20.18.1'}
unpipe@1.0.0:
@@ -943,7 +943,7 @@ snapshots:
parse5: 7.3.0
parse5-htmlparser2-tree-adapter: 7.1.0
parse5-parser-stream: 7.1.2
- undici: 7.27.2
+ undici: 7.28.0
whatwg-mimetype: 4.0.0
chokidar@3.6.0:
@@ -1126,7 +1126,7 @@ snapshots:
gray-matter@4.0.3:
dependencies:
- js-yaml: 3.14.2
+ js-yaml: 3.15.0
kind-of: 6.0.3
section-matter: 1.0.0
strip-bom-string: 1.0.0
@@ -1188,7 +1188,7 @@ snapshots:
iso-639-1@3.1.5: {}
- js-yaml@3.14.2:
+ js-yaml@3.15.0:
dependencies:
argparse: 1.0.10
esprima: 4.0.1
@@ -1410,7 +1410,7 @@ snapshots:
uc.micro@2.1.0: {}
- undici@7.27.2: {}
+ undici@7.28.0: {}
unpipe@1.0.0: {}
diff --git a/docs/pnpm-workspace.yaml b/docs/pnpm-workspace.yaml
index e69de29bb2..79b7d49256 100644
--- a/docs/pnpm-workspace.yaml
+++ b/docs/pnpm-workspace.yaml
@@ -0,0 +1,3 @@
+minimumReleaseAgeExclude:
+ - undici@7.28.0
+ - js-yaml@3.15.0
diff --git a/docs/user-guide/design-systems/design-tokens.njk b/docs/user-guide/design-systems/design-tokens.njk
index 390959a2ed..53f58cdb99 100644
--- a/docs/user-guide/design-systems/design-tokens.njk
+++ b/docs/user-guide/design-systems/design-tokens.njk
@@ -31,6 +31,7 @@ desc: Learn how to create, manage and apply Penpot Design Tokens using W3C DTCG
Description: You can also choose to add a description to your token.
Once you have named the token and assigned it a value, click Save to store the token and start referencing it.
+Token value fields suggest existing tokens as you type. Pick a suggestion to insert a reference, or keep typing a custom value.
Referencing tokens into values (aliases)
When assigning a value to a token, you can reference existing tokens - these are called aliases at the DTCG Glossary .
@@ -111,7 +112,7 @@ desc: Learn how to create, manage and apply Penpot Design Tokens using W3C DTCG
This ensures the spacing is at least 8, even if the base token is smaller.
Editing a token
-Tokens can be edited by right-clicking the token and selecting Edit token . This will allow you to change the tokens name, value and description. Once the changes are made, click Save .
+Tokens can be edited by right-clicking the token and selecting Edit token . This will allow you to change the tokens name, value and description. Value fields offer the same token suggestions as when creating a token. Once the changes are made, click Save .
@@ -141,12 +142,15 @@ desc: Learn how to create, manage and apply Penpot Design Tokens using W3C DTCG
Size and position: width, height, x, y
Rotation and border radius
Layout spacing: gaps, paddings, margins, min and max widths and heights
- Typography: letter spacing and line height
+ Typography: letter spacing, line height, and composite typography tokens on text layers
Stroke width
Shadows: x, y, blur, spread
Blur amount
Click the token control on a field to open a list of applicable tokens from your active sets and themes. Select a token to apply it; a token pill shows the bound token. Use the pill menu to detach the token when you need a custom value again.
+On text layers, the Typography section shows a composite typography token row when one is applied. Open the token list from the section header to pick or switch tokens without going to the Tokens panel. Hover a token name to see its resolved values (font family, size, weight, and the rest).
+When you multi-select text layers that share typography tokens, the Typography section shows the applied token. If the selection mixes different tokens, detach them from there or apply a new one to the whole selection.
+Typography options in the dropdown list show resolved values on hover, so you can tell styles apart before applying them.
When a numeric field has a token applied, drag-to-change is disabled for that field. Edit the token or detach it first.
@@ -528,6 +532,7 @@ ExtraBold Italic
Apply a Typography token
A Typography composite token can be applied to a full text layer to set all typography properties at once. This lets you manage complete text styles using a single token instead of combining multiple individual ones.
+Apply it from the Tokens panel, or from the Typography section in the Design sidebar when a text layer is selected.
When applying a Typography composite token to a layer, any previously applied Typography composite token or style will be detached. The same happens in reverse. Only one of them can be active at a time.
Shadow
diff --git a/docs/user-guide/designing/color-stroke.njk b/docs/user-guide/designing/color-stroke.njk
index d6d227fac3..012b45b264 100644
--- a/docs/user-guide/designing/color-stroke.njk
+++ b/docs/user-guide/designing/color-stroke.njk
@@ -57,7 +57,7 @@ desc: Style your designs with Penpot's options! Learn about color fills, gradien
Color type - Solid, gradient, or image.
Sliders - Easily manage settings like brightness, saturation or opacity.
Values - Set precise color values. Available formats depend on the selected color model.
- Libraries - Switch between recent colors and libraries.
+ Libraries - Switch between recent colors and libraries. Color tokens in a library can be shown as a grid or a list. Use the list view when you need to scan names or work with long token lists.
Color palette - A quick launcher of the palette with the selected library.
@@ -116,6 +116,7 @@ desc: Style your designs with Penpot's options! Learn about color fills, gradien
Style - solid, dotted, dashed, mixed
Visibility - show or hide the stroke without removing it
+When the style is set to dashed , two extra fields appear to control the dash and gap length in pixels.
You can add as many strokes as you want to the same layer.
diff --git a/docs/user-guide/designing/layers.njk b/docs/user-guide/designing/layers.njk
index 474432b66c..2c55a7a7ca 100644
--- a/docs/user-guide/designing/layers.njk
+++ b/docs/user-guide/designing/layers.njk
@@ -461,8 +461,18 @@ You can choose to edit individual nodes or create new ones. Press Esc
Blur
-You can set a blur for each and every layer at Penpot.
- Applying a lot and/or big values for blurs can affect Penpot’s performance as it requires a lot from the browser.
+You can add blur effects to layers from the Design sidebar. Penpot supports two types:
+
+ Layer blur blurs the layer content itself.
+ Background blur blurs whatever sits behind the layer. Use it for frosted-glass or depth effects. Background blur requires the WebGL renderer to be enabled.
+
+Background blur is not included in exported files yet (PNG, SVG, PDF, and others). The exporter still uses the legacy SVG renderer, so the effect only shows in the workspace and View mode. Export support is a current priority and will land in an upcoming release.
+
+
+ Background blur affects the layers behind the shape, not the shape itself.
+
+Click + in the Blur section to add an effect. You can apply both types on the same layer. Use the type selector to switch between them, the eye icon to show or hide an effect without removing it, and the value field to set the blur amount.
+Applying many or large blur values can affect Penpot’s performance, as it requires a lot from the browser.
diff --git a/docs/user-guide/prototyping-testing/prototyping.njk b/docs/user-guide/prototyping-testing/prototyping.njk
index 7be44ec22e..5adaba4b39 100644
--- a/docs/user-guide/prototyping-testing/prototyping.njk
+++ b/docs/user-guide/prototyping-testing/prototyping.njk
@@ -42,6 +42,10 @@ desc: This Penpot user guide explains how to prototype interactions, connect boa
10) Flow indicator and launcher
+Interaction settings
+When a layer with interactions is selected, the Prototype sidebar lists every connection attached to it. From there you can change the trigger, action, destination, animation, and other options.
+Destination dropdowns include a search field. Type to filter boards on the current page when your file has many screens.
+
Interaction triggers
diff --git a/frontend/package.json b/frontend/package.json
index 2a47553243..4e0b3f365d 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -64,7 +64,7 @@
"@storybook/addon-vitest": "10.4.6",
"@storybook/react-vite": "10.4.6",
"@tokens-studio/sd-transforms": "2.0.3",
- "@types/node": "^26.0.1",
+ "@types/node": "^26.1.0",
"@vitest/browser": "4.1.9",
"@vitest/browser-playwright": "^4.1.9",
"@vitest/coverage-v8": "4.1.9",
@@ -80,7 +80,7 @@
"getopts": "^2.3.0",
"gettext-parser": "^9.0.2",
"highlight.js": "^11.10.0",
- "js-beautify": "^1.15.4",
+ "js-beautify": "^2.0.3",
"jsdom": "^29.0.2",
"lodash": "^4.18.1",
"lodash.debounce": "^4.0.8",
@@ -95,7 +95,7 @@
"playwright": "1.61.1",
"postcss": "^8.5.16",
"postcss-clean": "^1.2.2",
- "postcss-modules": "^6.0.1",
+ "postcss-modules": "^9.0.0",
"postcss-scss": "^4.0.9",
"prettier": "3.9.4",
"pretty-time": "^1.1.0",
@@ -122,11 +122,11 @@
"tdigest": "^0.1.2",
"tinycolor2": "^1.6.0",
"typescript": "^6.0.2",
- "vite": "^8.1.0",
+ "vite": "^8.1.2",
"vitest": "^4.1.9",
"wait-on": "^9.0.4",
"watcher": "^2.3.1",
- "workerpool": "^10.0.1",
+ "workerpool": "^10.0.3",
"xregexp": "^5.1.2"
}
}
diff --git a/frontend/playwright/data/workspace/get-file-token-tooltip.json b/frontend/playwright/data/workspace/get-file-token-tooltip.json
new file mode 100644
index 0000000000..55a35d9d60
--- /dev/null
+++ b/frontend/playwright/data/workspace/get-file-token-tooltip.json
@@ -0,0 +1,382 @@
+{
+ "~:features": {
+ "~#set": [
+ "design-tokens/v1",
+ "layout/grid",
+ "fdata/pointer-map",
+ "fdata/objects-map",
+ "components/v2",
+ "fdata/shape-data-type"
+ ]
+ },
+ "~: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": "Tooltip check",
+ "~:revn": 36,
+ "~:modified-at": "~m1737542758402",
+ "~:vern": 0,
+ "~:id": "~uc7ce0794-0992-8105-8004-38f280443849",
+ "~:is-shared": false,
+ "~:version": 60,
+ "~:project-id": "~u0df61468-6cbf-8067-8005-6b453ce996d0",
+ "~:created-at": "~m1737536563847",
+ "~:data": {
+ "~:pages": [
+ "~u4530574a-7a0a-807b-8008-0107b2c4628e"
+ ],
+ "~:pages-index": {
+ "~u4530574a-7a0a-807b-8008-0107b2c4628e": {
+ "~:id": "~u4530574a-7a0a-807b-8008-0107b2c4628e",
+ "~:name": "Page 1",
+ "~:objects": {
+ "~#penpot/objects-map/v2": {
+ "~u00000000-0000-0000-0000-000000000000": "[\"~#shape\",[\"^ \",\"~:y\",0,\"~:hide-fill-on-export\",false,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:name\",\"Root Frame\",\"~:width\",0.01,\"~:type\",\"~:frame\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",0.0,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.0]],[\"^:\",[\"^ \",\"~:x\",0.01,\"~:y\",0.01]],[\"^:\",[\"^ \",\"~:x\",0.0,\"~:y\",0.01]]],\"~:r2\",0,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^3\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u4530574a-7a0a-807b-8008-0107b2c4628e\",\"~: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.0,\"~:r4\",0,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",0,\"~:y\",0,\"^6\",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,\"^I\",0.01,\"~:flip-y\",null,\"~:shapes\",[\"~ua7df6ab8-bee5-802f-8008-010d9ff3da26\",\"~uf2256046-b127-808e-8008-411c4cba63d8\",\"~u1de8c150-538b-80b2-8008-40356208fc39\",\"~uf2256046-b127-808e-8008-411c4cba63d9\",\"~u1de8c150-538b-80b2-8008-4036773cc8d0\",\"~u886f2846-a2c5-808d-8008-4115e86119e9\",\"~u1de8c150-538b-80b2-8008-403b5150a59b\",\"~u886f2846-a2c5-808d-8008-4115e86119ea\",\"~u20f9ccb0-68e2-80d9-8008-413fa842a6b5\",\"~u20f9ccb0-68e2-80d9-8008-413fb1f2ef51\"]]]",
+ "~u1de8c150-538b-80b2-8008-403b5150a59b": "[\"~#shape\",[\"^ \",\"~:y\",419,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Deleted token rect\",\"~:width\",162,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",-147,\"~:y\",419]],[\"^<\",[\"^ \",\"~:x\",15,\"~:y\",419]],[\"^<\",[\"^ \",\"~:x\",15,\"~:y\",565]],[\"^<\",[\"^ \",\"~:x\",-147,\"~:y\",565]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:r1\",20,\"~:id\",\"~u1de8c150-538b-80b2-8008-403b5150a59b\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"blue\",\"^A\",\"deleted\",\"^=\",\"deleted\",\"^@\",\"deleted\",\"~:r4\",\"deleted\"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",-147,\"~:proportion\",1,\"^F\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",-147,\"~:y\",419,\"^8\",162,\"~:height\",146,\"~:x1\",-147,\"~:y1\",419,\"~:x2\",15,\"~:y2\",565]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#0a20bf\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^L\",146,\"~:flip-y\",null]]",
+ "~u20f9ccb0-68e2-80d9-8008-413fa842a6b5": "[\"~#shape\",[\"^ \",\"~:y\",369,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle with token\",\"~:width\",274.99999999999994,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",-536,\"~:y\",369]],[\"^<\",[\"^ \",\"~:x\",-261.00000000000006,\"~:y\",369]],[\"^<\",[\"^ \",\"~:x\",-261.00000000000006,\"~:y\",565]],[\"^<\",[\"^ \",\"~:x\",-536,\"~:y\",565]]],\"~:r2\",50,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",50,\"~:r1\",50,\"~:id\",\"~u20f9ccb0-68e2-80d9-8008-413fa842a6b5\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"out-ref\",\"^A\",\"base-50\",\"^=\",\"base-50\",\"^@\",\"base-50\",\"~:r4\",\"base-50\"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",-536,\"~:proportion\",1,\"^F\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",-536,\"~:y\",369,\"^8\",274.99999999999994,\"~:height\",196,\"~:x1\",-536,\"~:y1\",369,\"~:x2\",-261.00000000000006,\"~:y2\",565]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#da1fea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^L\",196,\"~:flip-y\",null]]",
+ "~u1de8c150-538b-80b2-8008-4036773cc8d0": "[\"~#shape\",[\"^ \",\"~:y\",588,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^8\",[[\"^ \",\"^9\",\"1.2\",\"^:\",\"normal\",\"~:text-transform\",\"none\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-alegreya-sans-sc\",\"~:font-size\",\"23\",\"~:font-weight\",\"400\",\"~:text-direction\",\"ltr\",\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-opacity\",1]],\"~:font-family\",\"Alegreya Sans SC\",\"~:text\",\"Text with deleted token\"]],\"^;\",\"none\",\"^<\",\"left\",\"^=\",\"gfont-alegreya-sans-sc\",\"~:key\",\"fu3vh\",\"^>\",\"23\",\"^?\",\"400\",\"^@\",\"ltr\",\"^7\",\"paragraph\",\"^A\",\"regular\",\"^B\",\"none\",\"^C\",\"0\",\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"^G\",\"Alegreya Sans SC\"]]]]],\"~:hide-in-viewer\",false,\"~:name\",\"Text with deleted token\",\"~:width\",198,\"^7\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",-161,\"~:y\",588]],[\"^N\",[\"^ \",\"~:x\",37,\"~:y\",588]],[\"^N\",[\"^ \",\"~:x\",37,\"~:y\",641]],[\"^N\",[\"^ \",\"~:x\",-161,\"~:y\",641]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u1de8c150-538b-80b2-8008-4036773cc8d0\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:typography\",\"deleted-typo\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",613,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"~:y1\",2,\"^L\",176.203125,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",-161,\"~:x1\",0,\"~:y2\",25,\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"~:x2\",176.203125,\"~:direction\",\"ltr\",\"^G\",\"\\\"Alegreya Sans SC\\\"\",\"~:height\",23,\"^H\",\"Text with deleted \"]],[\"^U\",[\"^ \",\"~:y\",640.59375,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"^V\",29.59375,\"^L\",56.9375,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",-161,\"^W\",0,\"^X\",52.59375,\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"^Y\",56.9375,\"^Z\",\"ltr\",\"^G\",\"\\\"Alegreya Sans SC\\\"\",\"^[\",23,\"^H\",\"token\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:x\",-161,\"~:selrect\",[\"^U\",[\"^ \",\"~:x\",-161,\"~:y\",588,\"^L\",198,\"^[\",53,\"^W\",-161,\"^V\",588,\"^Y\",37,\"^X\",641]],\"~:flip-x\",null,\"^[\",53,\"~:flip-y\",null]]",
+ "~u20f9ccb0-68e2-80d9-8008-413fb1f2ef51": "[\"~#shape\",[\"^ \",\"~:y\",609,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^8\",[[\"^ \",\"^9\",\"1.2\",\"^:\",\"normal\",\"~:text-transform\",\"none\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-arizonia\",\"~:font-size\",\"23\",\"~:font-weight\",\"400\",\"~:text-direction\",\"ltr\",\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#da1fea\",\"~:fill-opacity\",1]],\"~:font-family\",\"Arizonia\",\"~:text\",\"Text with token\"]],\"^;\",\"none\",\"^<\",\"left\",\"^=\",\"gfont-arizonia\",\"~:key\",\"fu3vh\",\"^>\",\"23\",\"^?\",\"400\",\"^@\",\"ltr\",\"^7\",\"paragraph\",\"^A\",\"regular\",\"^B\",\"none\",\"^C\",\"0\",\"^D\",[[\"^ \",\"^E\",\"#da1fea\",\"^F\",1]],\"^G\",\"Arizonia\"]]]]],\"~:hide-in-viewer\",false,\"~:name\",\"Text with token\",\"~:width\",198,\"^7\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",-516,\"~:y\",609]],[\"^N\",[\"^ \",\"~:x\",-318,\"~:y\",609]],[\"^N\",[\"^ \",\"~:x\",-318,\"~:y\",662]],[\"^N\",[\"^ \",\"~:x\",-516,\"~:y\",662]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u20f9ccb0-68e2-80d9-8008-413fb1f2ef51\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:typography\",\"out-typo\",\"~:fill\",\"out-ref\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",637,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"~:y1\",-1,\"^L\",117.453125,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",-516,\"~:x1\",0,\"~:y2\",28,\"^D\",[[\"^ \",\"^E\",\"#da1fea\",\"^F\",1]],\"~:x2\",117.453125,\"~:direction\",\"ltr\",\"^G\",\"Arizonia\",\"~:height\",29,\"^H\",\"Text with token\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",-516,\"~:selrect\",[\"^V\",[\"^ \",\"~:x\",-516,\"~:y\",609,\"^L\",198,\"^10\",53,\"^X\",-516,\"^W\",609,\"^Z\",-318,\"^Y\",662]],\"~:flip-x\",null,\"^10\",53,\"~:flip-y\",null]]",
+ "~uf2256046-b127-808e-8008-411c4cba63d8": "[\"~#shape\",[\"^ \",\"~:y\",267,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle with not active reference\",\"~:width\",287,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",390,\"~:y\",267]],[\"^<\",[\"^ \",\"~:x\",677,\"~:y\",267]],[\"^<\",[\"^ \",\"~:x\",677,\"~:y\",579]],[\"^<\",[\"^ \",\"~:x\",390,\"~:y\",579]]],\"~:r2\",50,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u4530574a-7a0a-807b-8008-0107b2c4628e\",\"~:r3\",50,\"~:r1\",50,\"~:id\",\"~uf2256046-b127-808e-8008-411c4cba63d8\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"in-color\",\"^=\",\"in-br\",\"^A\",\"in-br\",\"^B\",\"in-br\",\"~:r4\",\"in-br\"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",390,\"~:proportion\",1,\"^G\",50,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",390,\"~:y\",267,\"^8\",287,\"~:height\",312,\"~:x1\",390,\"~:y1\",267,\"~:x2\",677,\"~:y2\",579]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#da1fea\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^M\",312,\"~:flip-y\",null]]",
+ "~uf2256046-b127-808e-8008-411c4cba63d9": "[\"~#shape\",[\"^ \",\"~:y\",602,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:line-height\",\"1.2\",\"^8\",[[\"^ \",\"^9\",\"1.2\",\"~:text-transform\",\"none\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-arizonia\",\"~:font-size\",\"14\",\"~:font-weight\",\"200\",\"~:text-direction\",\"ltr\",\"~:font-variant-id\",\"regular\",\"~:weight\",\"200\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#da1fea\",\"~:fill-opacity\",1]],\"~:font-family\",\"Arizonia\",\"~:text\",\"Text with not active reference\"]],\"^:\",\"none\",\"^;\",\"left\",\"^<\",\"gfont-arizonia\",\"~:key\",\"d22fo\",\"^=\",\"14\",\"^>\",\"200\",\"^?\",\"ltr\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^A\",\"200\",\"^B\",\"none\",\"^C\",\"0\",\"^D\",[[\"^ \",\"^E\",\"#da1fea\",\"^F\",1]],\"^G\",\"Arizonia\"]]]]],\"~:hide-in-viewer\",false,\"~:name\",\"Text with not active reference\",\"~:width\",139,\"^7\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",479,\"~:y\",602]],[\"^N\",[\"^ \",\"~:x\",618,\"~:y\",602]],[\"^N\",[\"^ \",\"~:x\",618,\"~:y\",630]],[\"^N\",[\"^ \",\"~:x\",479,\"~:y\",630]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~uf2256046-b127-808e-8008-411c4cba63d9\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"in-color\",\"~:typography\",\"in-typo\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",619,\"~:font-style\",\"normal\",\"^:\",\"none\",\"^=\",\"14px\",\"^>\",\"400\",\"~:y1\",-1,\"^L\",97.46875,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",479,\"~:x1\",0,\"~:y2\",17,\"^D\",[[\"^ \",\"^E\",\"#da1fea\",\"^F\",1]],\"~:x2\",97.46875,\"~:direction\",\"ltr\",\"^G\",\"Arizonia\",\"~:height\",18,\"^H\",\"Text with not active \"]],[\"^V\",[\"^ \",\"~:y\",635.796875,\"^W\",\"normal\",\"^:\",\"none\",\"^=\",\"14px\",\"^>\",\"400\",\"^X\",15.796875,\"^L\",42.8125,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",479,\"^Y\",0,\"^Z\",33.796875,\"^D\",[[\"^ \",\"^E\",\"#da1fea\",\"^F\",1]],\"^[\",42.8125,\"^10\",\"ltr\",\"^G\",\"Arizonia\",\"^11\",18,\"^H\",\"reference\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:x\",479,\"~:selrect\",[\"^V\",[\"^ \",\"~:x\",479,\"~:y\",602,\"^L\",139,\"^11\",28,\"^Y\",479,\"^X\",602,\"^[\",618,\"^Z\",630]],\"~:flip-x\",null,\"^11\",28,\"~:flip-y\",null]]",
+ "~u1de8c150-538b-80b2-8008-40356208fc39": "[\"~#shape\",[\"^ \",\"~:y\",609,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:line-height\",\"1.2\",\"^8\",[[\"^ \",\"^9\",\"1.2\",\"~:text-transform\",\"none\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-ar-one-sans\",\"~:font-size\",\"14\",\"~:font-weight\",\"200\",\"~:text-direction\",\"ltr\",\"~:font-variant-id\",\"regular\",\"~:weight\",\"200\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ef0c0c\",\"~:fill-opacity\",1]],\"~:font-family\",\"AR One Sans\",\"~:text\",\"Text with not active token\"]],\"^:\",\"none\",\"^;\",\"left\",\"^<\",\"gfont-ar-one-sans\",\"~:key\",\"d22fo\",\"^=\",\"14\",\"^>\",\"200\",\"^?\",\"ltr\",\"^7\",\"paragraph\",\"^@\",\"regular\",\"^A\",\"200\",\"^B\",\"none\",\"^C\",\"0\",\"^D\",[[\"^ \",\"^E\",\"#ef0c0c\",\"^F\",1]],\"^G\",\"AR One Sans\"]]]]],\"~:hide-in-viewer\",false,\"~:name\",\"Text with not active token\",\"~:width\",139,\"^7\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",812,\"~:y\",609]],[\"^N\",[\"^ \",\"~:x\",951,\"~:y\",609]],[\"^N\",[\"^ \",\"~:x\",951,\"~:y\",637]],[\"^N\",[\"^ \",\"~:x\",812,\"~:y\",637]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u1de8c150-538b-80b2-8008-40356208fc39\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"red\",\"~:typography\",\"typo-2\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",626,\"~:font-style\",\"normal\",\"^:\",\"none\",\"^=\",\"14px\",\"^>\",\"400\",\"~:y1\",-2,\"^L\",134.625,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",812,\"~:x1\",0,\"~:y2\",17,\"^D\",[[\"^ \",\"^E\",\"#ef0c0c\",\"^F\",1]],\"~:x2\",134.625,\"~:direction\",\"ltr\",\"^G\",\"\\\"AR One Sans\\\"\",\"~:height\",19,\"^H\",\"Text with not active \"]],[\"^V\",[\"^ \",\"~:y\",642.796875,\"^W\",\"normal\",\"^:\",\"none\",\"^=\",\"14px\",\"^>\",\"400\",\"^X\",14.796875,\"^L\",37.40625,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",812,\"^Y\",0,\"^Z\",33.796875,\"^D\",[[\"^ \",\"^E\",\"#ef0c0c\",\"^F\",1]],\"^[\",37.40625,\"^10\",\"ltr\",\"^G\",\"\\\"AR One Sans\\\"\",\"^11\",19,\"^H\",\"token\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:x\",812,\"~:selrect\",[\"^V\",[\"^ \",\"~:x\",812,\"~:y\",609,\"^L\",139,\"^11\",28,\"^Y\",812,\"^X\",609,\"^[\",951,\"^Z\",637]],\"~:flip-x\",null,\"^11\",28,\"~:flip-y\",null]]",
+ "~u886f2846-a2c5-808d-8008-4115e86119ea": "[\"~#shape\",[\"^ \",\"~:y\",399,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle with deleted reference\",\"~:width\",162,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",193,\"~:y\",399]],[\"^<\",[\"^ \",\"~:x\",355,\"~:y\",399]],[\"^<\",[\"^ \",\"~:x\",355,\"~:y\",545]],[\"^<\",[\"^ \",\"~:x\",193,\"~:y\",545]]],\"~:r2\",20,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:r3\",20,\"~:r1\",20,\"~:id\",\"~u886f2846-a2c5-808d-8008-4115e86119ea\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"ref-grfeen\",\"^A\",\"ref-1\",\"^=\",\"ref-1\",\"^@\",\"ref-1\",\"~:r4\",\"ref-1\"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",193,\"~:proportion\",1,\"^F\",20,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",193,\"~:y\",399,\"^8\",162,\"~:height\",146,\"~:x1\",193,\"~:y1\",399,\"~:x2\",355,\"~:y2\",545]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#0a20bf\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^L\",146,\"~:flip-y\",null]]",
+ "~u886f2846-a2c5-808d-8008-4115e86119e9": "[\"~#shape\",[\"^ \",\"~:y\",586,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:content\",[\"^ \",\"~:type\",\"root\",\"~:children\",[[\"^ \",\"^7\",\"paragraph-set\",\"^8\",[[\"^ \",\"~:line-height\",\"1.2\",\"~:font-style\",\"normal\",\"^8\",[[\"^ \",\"^9\",\"1.2\",\"^:\",\"normal\",\"~:text-transform\",\"none\",\"~:text-align\",\"left\",\"~:font-id\",\"gfont-adlam-display\",\"~:font-size\",\"23\",\"~:font-weight\",\"400\",\"~:text-direction\",\"ltr\",\"~:font-variant-id\",\"regular\",\"~:text-decoration\",\"none\",\"~:letter-spacing\",\"0\",\"~:fills\",[[\"^ \",\"~:fill-color\",\"#000000\",\"~:fill-opacity\",1]],\"~:font-family\",\"ADLaM Display\",\"~:text\",\"Text with deleted reference\"]],\"^;\",\"none\",\"^<\",\"left\",\"^=\",\"gfont-adlam-display\",\"~:key\",\"fu3vh\",\"^>\",\"23\",\"^?\",\"400\",\"^@\",\"ltr\",\"^7\",\"paragraph\",\"^A\",\"regular\",\"^B\",\"none\",\"^C\",\"0\",\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"^G\",\"ADLaM Display\"]]]]],\"~:hide-in-viewer\",false,\"~:name\",\"Text with deleted reference\",\"~:width\",137,\"^7\",\"^H\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",198,\"~:y\",586]],[\"^N\",[\"^ \",\"~:x\",335,\"~:y\",586]],[\"^N\",[\"^ \",\"~:x\",335,\"~:y\",683]],[\"^N\",[\"^ \",\"~:x\",198,\"~:y\",683]]],\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:id\",\"~u886f2846-a2c5-808d-8008-4115e86119e9\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"ref-grfeen\",\"~:typography\",\"ref-typo\"],\"~:position-data\",[[\"~#rect\",[\"^ \",\"~:y\",614,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"~:y1\",-2,\"^L\",107.921875,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",198,\"~:x1\",0,\"~:y2\",28,\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"~:x2\",107.921875,\"~:direction\",\"ltr\",\"^G\",\"\\\"ADLaM Display\\\"\",\"~:height\",30,\"^H\",\"Text with \"]],[\"^V\",[\"^ \",\"~:y\",641.59375,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"^W\",25.59375,\"^L\",88.890625,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",198,\"^X\",0,\"^Y\",55.59375,\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"^Z\",88.890625,\"^[\",\"ltr\",\"^G\",\"\\\"ADLaM Display\\\"\",\"^10\",30,\"^H\",\"deleted \"]],[\"^V\",[\"^ \",\"~:y\",669.1875,\"^:\",\"normal\",\"^;\",\"none\",\"^>\",\"23px\",\"^?\",\"400\",\"^W\",53.1875,\"^L\",103.46875,\"^B\",\"none\",\"^C\",\"normal\",\"~:x\",198,\"^X\",0,\"^Y\",83.1875,\"^D\",[[\"^ \",\"^E\",\"#000000\",\"^F\",1]],\"^Z\",103.46875,\"^[\",\"ltr\",\"^G\",\"\\\"ADLaM Display\\\"\",\"^10\",30,\"^H\",\"reference\"]]],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:x\",198,\"~:selrect\",[\"^V\",[\"^ \",\"~:x\",198,\"~:y\",586,\"^L\",137,\"^10\",97,\"^X\",198,\"^W\",586,\"^Z\",335,\"^Y\",683]],\"~:flip-x\",null,\"^10\",97,\"~:flip-y\",null]]",
+ "~ua7df6ab8-bee5-802f-8008-010d9ff3da26": "[\"~#shape\",[\"^ \",\"~:y\",274,\"~:transform\",[\"~#matrix\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:rotation\",0,\"~:grow-type\",\"~:fixed\",\"~:hide-in-viewer\",false,\"~:name\",\"Rectangle with not active token\",\"~:width\",287,\"~:type\",\"~:rect\",\"~:points\",[[\"~#point\",[\"^ \",\"~:x\",723,\"~:y\",274]],[\"^<\",[\"^ \",\"~:x\",1010,\"~:y\",274]],[\"^<\",[\"^ \",\"~:x\",1010,\"~:y\",586]],[\"^<\",[\"^ \",\"~:x\",723,\"~:y\",586]]],\"~:r2\",100,\"~:proportion-lock\",false,\"~:transform-inverse\",[\"^2\",[\"^ \",\"~:a\",1.0,\"~:b\",0.0,\"~:c\",0.0,\"~:d\",1.0,\"~:e\",0.0,\"~:f\",0.0]],\"~:page-id\",\"~u4530574a-7a0a-807b-8008-0107b2c4628e\",\"~:r3\",100,\"~:r1\",100,\"~:id\",\"~ua7df6ab8-bee5-802f-8008-010d9ff3da26\",\"~:parent-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:applied-tokens\",[\"^ \",\"~:fill\",\"red\",\"^B\",\"border-radius\",\"^=\",\"border-radius\",\"^A\",\"border-radius\",\"~:r4\",\"border-radius\"],\"~:frame-id\",\"~u00000000-0000-0000-0000-000000000000\",\"~:strokes\",[],\"~:x\",723,\"~:proportion\",1,\"^G\",100,\"~:selrect\",[\"~#rect\",[\"^ \",\"~:x\",723,\"~:y\",274,\"^8\",287,\"~:height\",312,\"~:x1\",723,\"~:y1\",274,\"~:x2\",1010,\"~:y2\",586]],\"~:fills\",[[\"^ \",\"~:fill-color\",\"#ef0c0c\",\"~:fill-opacity\",1]],\"~:flip-x\",null,\"^M\",312,\"~:flip-y\",null]]"
+ }
+ }
+ }
+ },
+ "~:tokens-lib": {
+ "~#penpot/tokens-lib": {
+ "~:sets": {
+ "~#ordered-map": [
+ [
+ "S-Global",
+ {
+ "~#penpot/token-set": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de8c",
+ "~:name": "Global",
+ "~:description": "",
+ "~:modified-at": "~m1782813028640",
+ "~:tokens": {
+ "~#ordered-map": [
+ [
+ "base-50",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de87",
+ "~:name": "base-50",
+ "~:type": "~:border-radius",
+ "~:value": "50",
+ "~:description": "",
+ "~:modified-at": "~m1782742859871"
+ }
+ }
+ ],
+ [
+ "out-ref",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-411bec9b1109",
+ "~:name": "out-ref",
+ "~:type": "~:color",
+ "~:value": "rgb(218, 31, 234)",
+ "~:description": "",
+ "~:modified-at": "~m1782803549804"
+ }
+ }
+ ],
+ [
+ "out-typo",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-411bf90df57e",
+ "~:name": "out-typo",
+ "~:type": "~:typography",
+ "~:value": {
+ "~:font-family": [
+ "Arizonia"
+ ]
+ },
+ "~:description": "",
+ "~:modified-at": "~m1782803562551"
+ }
+ }
+ ]
+ ]
+ }
+ }
+ }
+ ],
+ [
+ "G-Mode",
+ {
+ "~#ordered-map": [
+ [
+ "S-Dark",
+ {
+ "~#penpot/token-set": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de8d",
+ "~:name": "Mode/Dark",
+ "~:description": "",
+ "~:modified-at": "~m1782803647245",
+ "~:tokens": {
+ "~#ordered-map": [
+ [
+ "red",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de88",
+ "~:name": "red",
+ "~:type": "~:color",
+ "~:value": "#ef0c0c",
+ "~:description": "",
+ "~:modified-at": "~m1782742859871"
+ }
+ }
+ ],
+ [
+ "ref-grfeen",
+ {
+ "~#penpot/token": {
+ "~:id": "~u886f2846-a2c5-808d-8008-4115e5fdae2e",
+ "~:name": "ref-grfeen",
+ "~:type": "~:color",
+ "~:value": "{green}",
+ "~:description": "",
+ "~:modified-at": "~m1782801970166"
+ }
+ }
+ ],
+ [
+ "ref-typo",
+ {
+ "~#penpot/token": {
+ "~:id": "~u886f2846-a2c5-808d-8008-41160c4641f4",
+ "~:name": "ref-typo",
+ "~:type": "~:typography",
+ "~:value": "{typo1}",
+ "~:description": "",
+ "~:modified-at": "~m1782802009369"
+ }
+ }
+ ],
+ [
+ "ref-1",
+ {
+ "~#penpot/token": {
+ "~:id": "~u886f2846-a2c5-808d-8008-411628261dc7",
+ "~:name": "ref-1",
+ "~:type": "~:border-radius",
+ "~:value": "{b1}",
+ "~:description": "",
+ "~:modified-at": "~m1782802037912"
+ }
+ }
+ ],
+ [
+ "in-br",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-411c0aced089",
+ "~:name": "in-br",
+ "~:type": "~:border-radius",
+ "~:value": "{base-50}",
+ "~:description": "",
+ "~:modified-at": "~m1782803580731"
+ }
+ }
+ ],
+ [
+ "in-color",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-411c263c999b",
+ "~:name": "in-color",
+ "~:type": "~:color",
+ "~:value": "{out-ref}",
+ "~:description": "",
+ "~:modified-at": "~m1782803608818"
+ }
+ }
+ ],
+ [
+ "in-typo",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-411c472f33d3",
+ "~:name": "in-typo",
+ "~:type": "~:typography",
+ "~:value": "{out-typo}",
+ "~:description": "",
+ "~:modified-at": "~m1782803642556"
+ }
+ }
+ ]
+ ]
+ }
+ }
+ }
+ ],
+ [
+ "S-Light",
+ {
+ "~#penpot/token-set": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de8e",
+ "~:name": "Mode/Light",
+ "~:description": "",
+ "~:modified-at": "~m1782812999332",
+ "~:tokens": {
+ "~#ordered-map": [
+ [
+ "red",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf71719b3-63a1-8157-8008-40346917de89",
+ "~:name": "red",
+ "~:type": "~:color",
+ "~:value": "#ec9090",
+ "~:description": "",
+ "~:modified-at": "~m1782742859871"
+ }
+ }
+ ],
+ [
+ "typo-2",
+ {
+ "~#penpot/token": {
+ "~:id": "~u1de8c150-538b-80b2-8008-40357ed6d13a",
+ "~:name": "typo-2",
+ "~:type": "~:typography",
+ "~:value": {
+ "~:font-family": [
+ "AR One Sans"
+ ],
+ "~:font-weight": "200"
+ },
+ "~:description": "",
+ "~:modified-at": "~m1782812999332"
+ }
+ }
+ ],
+ [
+ "border-radius",
+ {
+ "~#penpot/token": {
+ "~:id": "~uf2256046-b127-808e-8008-4134c130c292",
+ "~:name": "border-radius",
+ "~:type": "~:border-radius",
+ "~:value": "{base-50} * 2",
+ "~:description": "",
+ "~:modified-at": "~m1782810058947"
+ }
+ }
+ ]
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ }
+ ]
+ ]
+ },
+ "~:themes": {
+ "~#ordered-map": [
+ [
+ "",
+ {
+ "~#ordered-map": [
+ [
+ "__PENPOT__HIDDEN__TOKEN__THEME__",
+ {
+ "~#penpot/token-theme": {
+ "~:id": "~u00000000-0000-0000-0000-000000000000",
+ "~:name": "__PENPOT__HIDDEN__TOKEN__THEME__",
+ "~:group": "",
+ "~:description": "",
+ "~:is-source": false,
+ "~:external-id": "",
+ "~:modified-at": "~m1782812922760",
+ "~:sets": {
+ "~#set": [
+ "Global"
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ }
+ ],
+ [
+ "App",
+ {
+ "~#ordered-map": [
+ [
+ "Web",
+ {
+ "~#penpot/token-theme": {
+ "~:id": "~u37900259-7f15-8003-8007-9ee75dd2f2d2",
+ "~:name": "Web",
+ "~:group": "App",
+ "~:description": "",
+ "~:is-source": false,
+ "~:external-id": "37900259-7f15-8003-8007-9ee75dd2f2d2",
+ "~:modified-at": "~m1782810072529",
+ "~:sets": {
+ "~#set": [
+ "Mode/Dark",
+ "Global"
+ ]
+ }
+ }
+ }
+ ],
+ [
+ "Mobile",
+ {
+ "~#penpot/token-theme": {
+ "~:id": "~u37900259-7f15-8003-8007-9ee77eb567bd",
+ "~:name": "Mobile",
+ "~:group": "App",
+ "~:description": "",
+ "~:is-source": false,
+ "~:external-id": "37900259-7f15-8003-8007-9ee77eb567bd",
+ "~:modified-at": "~m1782810072529",
+ "~:sets": {
+ "~#set": [
+ "Mode/Light",
+ "Global"
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ }
+ ]
+ ]
+ },
+ "~:active-themes": {
+ "~#set": [
+ "/__PENPOT__HIDDEN__TOKEN__THEME__"
+ ]
+ }
+ }
+ },
+ "~:id": "~u55608328-aed3-807a-8008-41341f2f7247",
+ "~:options": {
+ "~:components-v2": true,
+ "~:base-font-size": "16px"
+ }
+ }
+}
\ No newline at end of file
diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/BUG-13551---Blurs-affecting-other-elements-1.png b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/BUG-13551---Blurs-affecting-other-elements-1.png
index 770c417a65..f1830e82dd 100644
Binary files a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/BUG-13551---Blurs-affecting-other-elements-1.png and b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/BUG-13551---Blurs-affecting-other-elements-1.png differ
diff --git a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png
index e74e55f39f..88824190be 100644
Binary files a/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png and b/frontend/playwright/ui/render-wasm-specs/shapes.spec.js-snapshots/Check-inner-stroke-artifacts-1.png differ
diff --git a/frontend/playwright/ui/render-wasm-specs/texts.spec.js b/frontend/playwright/ui/render-wasm-specs/texts.spec.js
index 23a4701bbd..b474c7ca05 100644
--- a/frontend/playwright/ui/render-wasm-specs/texts.spec.js
+++ b/frontend/playwright/ui/render-wasm-specs/texts.spec.js
@@ -209,7 +209,10 @@ test("Renders a file with emoji and text decoration", async ({ page }) => {
pageId: "82d128e1-d3b1-80a5-8006-ae60fedcd5e8",
});
await workspace.waitForFirstRenderWithoutUI();
- await expect(workspace.canvas).toHaveScreenshot();
+ await expect(workspace.canvas).toHaveScreenshot({
+ maxDiffPixelRatio: 0,
+ threshold: 0.1,
+ });
});
test("Renders a file with multiple emoji", async ({ page }) => {
diff --git a/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-emoji-and-text-decoration-1.png b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-emoji-and-text-decoration-1.png
index c2ed2f2321..70ba1f8cbf 100644
Binary files a/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-emoji-and-text-decoration-1.png and b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-emoji-and-text-decoration-1.png differ
diff --git a/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-group-with-strokes-and-not-100-opacities-1.png b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-group-with-strokes-and-not-100-opacities-1.png
index 54dca6599c..646da5cdb5 100644
Binary files a/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-group-with-strokes-and-not-100-opacities-1.png and b/frontend/playwright/ui/render-wasm-specs/texts.spec.js-snapshots/Renders-a-file-with-group-with-strokes-and-not-100-opacities-1.png differ
diff --git a/frontend/playwright/ui/specs/text-editor-v2.spec.js b/frontend/playwright/ui/specs/text-editor-v2.spec.js
index 25676c45e1..a58c71dba4 100644
--- a/frontend/playwright/ui/specs/text-editor-v2.spec.js
+++ b/frontend/playwright/ui/specs/text-editor-v2.spec.js
@@ -331,3 +331,33 @@ test("BUG 14098 - Fix text editor having 0 width or height", async ({ page }) =>
const textEditor = workspace.page.locator(`div[class*="viewport"]`).first().getByRole('textbox').first();
await expect(textEditor).toBeVisible();
});
+
+test("Preserves empty fill after editing text without changes", async ({ page }) => {
+ const initialText = "Hello";
+ const workspace = new WasmWorkspacePage(page, {
+ textEditor: true,
+ });
+
+ await workspace.setupEmptyFile();
+ await workspace.mockRPC("update-file?id=*", "text-editor/update-file.json");
+ await workspace.goToWorkspace();
+
+ await workspace.createTextShape(190, 150, 300, 200, initialText);
+ await workspace.textEditor.stopEditing();
+
+ const fillColorButton = workspace.page.getByRole("button", {
+ name: "#000000",
+ });
+ await expect(fillColorButton).toBeVisible();
+ await workspace.page.getByRole("button", { name: "Remove color" }).click();
+ await expect(fillColorButton).toHaveCount(0);
+
+ await workspace.doubleClickLeafLayer(initialText);
+ await workspace.textEditor.waitForEditor();
+ await workspace.moveButton.click();
+ await workspace.clickAt(100, 100);
+
+ await workspace.clickLeafLayer(initialText);
+ await expect(fillColorButton).toHaveCount(0);
+ await expect(workspace.page.getByTestId("add-fill")).toBeVisible();
+});
diff --git a/frontend/playwright/ui/specs/tokens/apply.spec.js b/frontend/playwright/ui/specs/tokens/apply.spec.js
index 1fb605acf2..5b9ae462d0 100644
--- a/frontend/playwright/ui/specs/tokens/apply.spec.js
+++ b/frontend/playwright/ui/specs/tokens/apply.spec.js
@@ -907,7 +907,7 @@ test.describe("Tokens: Detach token", () => {
await expect(page.getByText("Don't remap")).toBeVisible();
await page.getByText("Don't remap").click();
const brokenPill = borderRadiusSection.getByRole("button", {
- name: "is not in any active set",
+ name: "{borderRadius.sm} token does not exist or has been deleted",
});
await expect(brokenPill).toBeVisible();
@@ -1775,3 +1775,375 @@ test("BUG: 14234, Numeric input token filtering must be case sensitive", async (
measuresSection.getByText("dim-up", { exact: true }),
).not.toBeVisible();
});
+
+test("BUG: 10471, Correct tooltip on right sidebar tokens", async ({
+ page,
+}) => {
+ const {
+ workspacePage,
+ tokensSidebar,
+ tokenContextMenuForToken,
+ tokenThemesSetsSidebar,
+ tokenSetGroupItems,
+ } = await setupTokensFileRender(page, {
+ file: "workspace/get-file-token-tooltip.json",
+ });
+
+ await page.getByRole("tab", { name: "Layers" }).click();
+ const borderRadiusSection = page.getByRole("region", {
+ name: "Border radius section",
+ });
+
+ const fillSection = workspacePage.rightSidebar.getByRole("region", {
+ name: "Fill section",
+ });
+
+ const typographySection = workspacePage.rightSidebar.getByRole("region", {
+ name: "Text section",
+ });
+ // ----------------------------------
+ // Select rectangle with active token
+ // ----------------------------------
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Rectangle with token" })
+ .click();
+ await expect(borderRadiusSection).toBeVisible();
+ const brPill = borderRadiusSection.getByRole("button", { name: "base-50" });
+ await expect(brPill).toBeVisible();
+ await brPill.hover();
+ await expect(page.getByRole("tooltip", { name: "base-50" })).toBeVisible();
+ await expect(fillSection).toBeVisible();
+ const fillTokenPill = fillSection.getByLabel("out-ref", {
+ exact: true,
+ });
+ await expect(fillTokenPill).toBeVisible();
+ await fillTokenPill.hover();
+ const colorTokenTooltip = page.getByRole("tooltip", {
+ name: "out-ref",
+ });
+ await expect(colorTokenTooltip).toBeVisible();
+ await expect(colorTokenTooltip).toHaveText(
+ "Name: out-refResolved value: #da1fea",
+ );
+ // ----------------------------------
+ // Select text with active token
+ // ----------------------------------
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Text with token" })
+ .click();
+ await expect(fillSection).toBeVisible();
+ const textFillTokenPill = fillSection.getByLabel("out-ref", {
+ exact: true,
+ });
+ await expect(textFillTokenPill).toBeVisible();
+ await textFillTokenPill.hover();
+ await expect(colorTokenTooltip).toBeVisible();
+ await expect(colorTokenTooltip).toHaveText(
+ "Name: out-refResolved value: #da1fea",
+ );
+ await expect(typographySection).toBeVisible();
+ const typographyTokenPill = typographySection.getByLabel("out-typo", {
+ exact: true,
+ });
+ await expect(typographyTokenPill).toBeVisible();
+ await typographyTokenPill.hover();
+ const typographyTokenTooltip = page.getByRole("tooltip", {
+ name: "out-typo",
+ });
+ await expect(typographyTokenTooltip).toBeVisible();
+ await expect(typographyTokenTooltip).toHaveText(
+ 'Name: out-typoResolved value:- font-family: "Arizonia"',
+ );
+ // -----------------------------------------
+ // Select rectangle layer with deleted token
+ // -----------------------------------------
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Deleted token rect" })
+ .click();
+
+ await expect(borderRadiusSection).toBeVisible();
+ const deletedBrPill = borderRadiusSection.getByRole("button", {
+ name: "{deleted} token does not exist or",
+ });
+ await expect(deletedBrPill).toBeVisible();
+ await deletedBrPill.hover();
+ await expect(
+ page.getByRole("tooltip", { name: "{deleted} token does not exist or" }),
+ ).toBeVisible();
+ await expect(fillSection).toBeVisible();
+ const fillBrokenTokenPill = fillSection.getByLabel("blue", {
+ exact: true,
+ });
+ await expect(fillBrokenTokenPill).toBeVisible();
+ await fillBrokenTokenPill.hover();
+ const fillBrokenTokenTooltip = page.getByRole("tooltip", {
+ name: "blue",
+ });
+ await expect(fillBrokenTokenTooltip).toBeVisible();
+ await expect(fillBrokenTokenTooltip).toHaveText(
+ "{blue} token does not exist or has been deleted.",
+ );
+ // ------------------------------------
+ // Select text layer with deleted token
+ // ------------------------------------
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Text with deleted token" })
+ .click();
+ await expect(typographySection).toBeVisible();
+ const brokenTypographyTokenPill = typographySection.getByLabel(
+ "deleted-typo",
+ { exact: true },
+ );
+ await expect(brokenTypographyTokenPill).toBeVisible();
+ await brokenTypographyTokenPill.hover();
+ const brokenTypographyTokenTooltip = page.getByRole("tooltip", {
+ name: "deleted-typo",
+ });
+ await expect(brokenTypographyTokenTooltip).toBeVisible();
+ await expect(brokenTypographyTokenTooltip).toHaveText(
+ "{deleted-typo} token does not exist or has been deleted.",
+ );
+
+ // ---------------------------------------------------
+ // Select rectangle layer with deleted reference token
+ // ---------------------------------------------------
+ await page.getByRole("tab", { name: "Tokens" }).click();
+ await tokenThemesSetsSidebar.getByRole("button", { name: "Dark" }).click();
+
+ await tokenThemesSetsSidebar
+ .getByRole("button", { name: "Dark" })
+ .getByRole("checkbox")
+ .click();
+ await page.getByRole("tab", { name: "Layers" }).click();
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Rectangle with deleted reference" })
+ .click();
+ await expect(borderRadiusSection).toBeVisible();
+ const deletedReferenceBrPill = borderRadiusSection.getByRole("button", {
+ name: "Reference in {ref-1} is not valid or is not in any active set.",
+ });
+ await expect(deletedReferenceBrPill).toBeVisible();
+ await deletedReferenceBrPill.hover();
+ await expect(
+ page.getByRole("tooltip", {
+ name: "Reference in {ref-1} is not valid or is not in any active set.",
+ }),
+ ).toBeVisible();
+ await expect(fillSection).toBeVisible();
+ const fillDeletedReferenceTokenPill = fillSection.getByLabel("ref-grfeen", {
+ exact: true,
+ });
+ await expect(fillDeletedReferenceTokenPill).toBeVisible();
+ await fillDeletedReferenceTokenPill.hover();
+ const fillDeletedReferenceTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {ref-grfeen} is not valid or is not in any active set.",
+ });
+ await expect(fillDeletedReferenceTokenTooltip).toBeVisible();
+ await expect(fillDeletedReferenceTokenTooltip).toHaveText(
+ "Reference in {ref-grfeen} is not valid or is not in any active set.",
+ );
+
+ // ----------------------------------------------
+ // Select text layer with deleted reference token
+ // ----------------------------------------------
+
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Text with deleted reference" })
+ .click();
+
+ await expect(typographySection).toBeVisible();
+ const deletedRefTypographyTokenPill = typographySection.getByLabel(
+ "ref-typo",
+ { exact: true },
+ );
+ await expect(deletedRefTypographyTokenPill).toBeVisible();
+ await deletedRefTypographyTokenPill.hover();
+ const deletedRefTypographyTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {ref-typo} is not valid or is",
+ });
+ await expect(deletedRefTypographyTokenTooltip).toBeVisible();
+ await expect(deletedRefTypographyTokenTooltip).toHaveText(
+ "Reference in {ref-typo} is not valid or is not in any active set.",
+ );
+ await expect(fillSection).toBeVisible();
+ const fillTextDeletedReferenceTokenPill = fillSection.getByLabel(
+ "ref-grfeen",
+ {
+ exact: true,
+ },
+ );
+ await expect(fillTextDeletedReferenceTokenPill).toBeVisible();
+ await fillTextDeletedReferenceTokenPill.hover();
+ const fillTextDeletedReferenceTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {ref-grfeen} is not valid or is not in any active set.",
+ });
+ await expect(fillTextDeletedReferenceTokenTooltip).toBeVisible();
+ await expect(fillTextDeletedReferenceTokenTooltip).toHaveText(
+ "Reference in {ref-grfeen} is not valid or is not in any active set.",
+ );
+
+ // -----------------------------------------------------------
+ // Select rectangle layer with reference token on inactive set
+ // -----------------------------------------------------------
+ await page.getByRole("tab", { name: "Tokens" }).click();
+ await tokenThemesSetsSidebar.getByRole("button", { name: "Global" }).click();
+
+ await tokenThemesSetsSidebar
+ .getByRole("button", { name: "Global" })
+ .getByRole("checkbox")
+ .click();
+ await page.getByRole("tab", { name: "Layers" }).click();
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Rectangle with not active reference" })
+ .click();
+ await expect(borderRadiusSection).toBeVisible();
+ const nonActiveReferenceBrPill = borderRadiusSection.getByRole("button", {
+ name: "Reference in {in-br} is not valid or is not in any active set.",
+ });
+ await expect(nonActiveReferenceBrPill).toBeVisible();
+ await nonActiveReferenceBrPill.hover();
+ await expect(
+ page.getByRole("tooltip", {
+ name: "Reference in {in-br} is not valid or is not in any active set.",
+ }),
+ ).toBeVisible();
+ await expect(fillSection).toBeVisible();
+ const fillNonActiveReferenceTokenPill = fillSection.getByLabel("in-color", {
+ exact: true,
+ });
+ await expect(fillNonActiveReferenceTokenPill).toBeVisible();
+ await fillNonActiveReferenceTokenPill.hover();
+ const fillNonActiveReferenceTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {in-color} is not valid or is not in any active set.",
+ });
+ await expect(fillNonActiveReferenceTokenTooltip).toBeVisible();
+ await expect(fillNonActiveReferenceTokenTooltip).toHaveText(
+ "Reference in {in-color} is not valid or is not in any active set.",
+ );
+ // ------------------------------------------------------
+ // Select text layer with reference token on inactive set
+ // ------------------------------------------------------
+
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Text with not active reference" })
+ .click();
+
+ await expect(typographySection).toBeVisible();
+ const notActiveRefTypographyTokenPill = typographySection.getByLabel(
+ "in-typo",
+ { exact: true },
+ );
+ await expect(notActiveRefTypographyTokenPill).toBeVisible();
+ await notActiveRefTypographyTokenPill.hover();
+ const notActiveRefTypographyTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {in-typo} is not valid or is",
+ });
+ await expect(notActiveRefTypographyTokenTooltip).toBeVisible();
+ await expect(notActiveRefTypographyTokenTooltip).toHaveText(
+ "Reference in {in-typo} is not valid or is not in any active set.",
+ );
+ await expect(fillSection).toBeVisible();
+ const fillTextNotActiveReferenceTokenPill = fillSection.getByLabel(
+ "in-color",
+ {
+ exact: true,
+ },
+ );
+ await expect(fillTextNotActiveReferenceTokenPill).toBeVisible();
+ await fillTextNotActiveReferenceTokenPill.hover();
+ const fillTextNotActiveReferenceTokenTooltip = page.getByRole("tooltip", {
+ name: "Reference in {in-color} is not valid or is not in any active set.",
+ });
+ await expect(fillTextNotActiveReferenceTokenTooltip).toBeVisible();
+ await expect(fillTextNotActiveReferenceTokenTooltip).toHaveText(
+ "Reference in {in-color} is not valid or is not in any active set.",
+ );
+
+ // -------------------------------------------------
+ // Select rectangle layer with token on inactive set
+ // -------------------------------------------------
+ await page.getByRole("tab", { name: "Tokens" }).click();
+ await tokenThemesSetsSidebar.getByRole("button", { name: "Dark" }).click();
+
+ await tokenThemesSetsSidebar
+ .getByRole("button", { name: "Dark" })
+ .getByRole("checkbox")
+ .click();
+ await page.getByRole("tab", { name: "Layers" }).click();
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Rectangle with not active token" })
+ .click();
+ await expect(borderRadiusSection).toBeVisible();
+ const nonActiveBrPill = borderRadiusSection.getByRole("button", {
+ name: "{border-radius} token is not in any active set",
+ });
+ await expect(nonActiveBrPill).toBeVisible();
+ await nonActiveBrPill.hover();
+ await expect(
+ page.getByRole("tooltip", {
+ name: "{border-radius} token is not in any active set or has an invalid value",
+ }),
+ ).toBeVisible();
+ await expect(fillSection).toBeVisible();
+ const fillNonActiveTokenPill = fillSection.getByLabel("red", {
+ exact: true,
+ });
+ await expect(fillNonActiveTokenPill).toBeVisible();
+ await fillNonActiveTokenPill.hover();
+ const fillNonActiveTokenTooltip = page.getByRole("tooltip", {
+ name: "{red} token is not in any active set or has an invalid value.",
+ });
+ await expect(fillNonActiveTokenTooltip).toBeVisible();
+ await expect(fillNonActiveTokenTooltip).toHaveText(
+ "{red} token is not in any active set or has an invalid value.",
+ );
+
+ // --------------------------------------------
+ // Select text layer with token on inactive set
+ // --------------------------------------------
+
+ await workspacePage.layers
+ .getByTestId("layer-row")
+ .filter({ hasText: "Text with not active token" })
+ .click();
+
+ await expect(typographySection).toBeVisible();
+ const notActiveTypographyTokenPill = typographySection.getByLabel(
+ "typo-2",
+ { exact: true },
+ );
+ await expect(notActiveTypographyTokenPill).toBeVisible();
+ await notActiveTypographyTokenPill.hover();
+ const notActiveTypographyTokenTooltip = page.getByRole("tooltip", {
+ name: "{typo-2} token is not in any active set or has an invalid value.",
+ });
+ await expect(notActiveTypographyTokenTooltip).toBeVisible();
+ await expect(notActiveTypographyTokenTooltip).toHaveText(
+ "{typo-2} token is not in any active set or has an invalid value.",
+ );
+ await expect(fillSection).toBeVisible();
+ const fillTextNotActiveTokenPill = fillSection.getByLabel(
+ "red",
+ {
+ exact: true,
+ },
+ );
+ await expect(fillTextNotActiveTokenPill).toBeVisible();
+ await fillTextNotActiveTokenPill.hover();
+ const fillTextNotActiveTokenTooltip = page.getByRole("tooltip", {
+ name: "{red} token is not in any active set or has an invalid value.",
+ });
+ await expect(fillTextNotActiveTokenTooltip).toBeVisible();
+ await expect(fillTextNotActiveTokenTooltip).toHaveText(
+ "{red} token is not in any active set or has an invalid value.",
+ );
+});
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index edd27334f3..c11f5736a6 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -54,7 +54,7 @@ importers:
version: 1.61.1
'@storybook/addon-docs':
specifier: 10.4.6
- version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@storybook/addon-themes':
specifier: 10.4.6
version: 10.4.6(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
@@ -63,19 +63,19 @@ importers:
version: 10.4.6(@vitest/browser-playwright@4.1.9)(@vitest/browser@4.1.9)(@vitest/runner@4.1.9)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vitest@4.1.9)
'@storybook/react-vite':
specifier: 10.4.6
- version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@tokens-studio/sd-transforms':
specifier: 2.0.3
version: 2.0.3(style-dictionary@5.4.4(tslib@2.8.1))
'@types/node':
- specifier: ^26.0.1
- version: 26.0.1
+ specifier: ^26.1.0
+ version: 26.1.0
'@vitest/browser':
specifier: 4.1.9
- version: 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ version: 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/browser-playwright':
specifier: ^4.1.9
- version: 4.1.9(playwright@1.61.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ version: 4.1.9(playwright@1.61.1)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/coverage-v8':
specifier: 4.1.9
version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9)
@@ -116,8 +116,8 @@ importers:
specifier: ^11.10.0
version: 11.11.1
js-beautify:
- specifier: ^1.15.4
- version: 1.15.4
+ specifier: ^2.0.3
+ version: 2.0.3
jsdom:
specifier: ^29.0.2
version: 29.1.1(canvas@3.2.3)
@@ -161,8 +161,8 @@ importers:
specifier: ^1.2.2
version: 1.2.2
postcss-modules:
- specifier: ^6.0.1
- version: 6.0.1(postcss@8.5.16)
+ specifier: ^9.0.0
+ version: 9.0.0(postcss@8.5.16)
postcss-scss:
specifier: ^4.0.9
version: 4.0.9(postcss@8.5.16)
@@ -242,11 +242,11 @@ importers:
specifier: ^6.0.2
version: 6.0.3
vite:
- specifier: ^8.1.0
- version: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ specifier: ^8.1.2
+ version: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
vitest:
specifier: ^4.1.9
- version: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
wait-on:
specifier: ^9.0.4
version: 9.0.10(supports-color@5.5.0)
@@ -254,8 +254,8 @@ importers:
specifier: ^2.3.1
version: 2.3.1
workerpool:
- specifier: ^10.0.1
- version: 10.0.2
+ specifier: ^10.0.3
+ version: 10.0.3
xregexp:
specifier: ^5.1.2
version: 5.1.2
@@ -307,7 +307,7 @@ importers:
version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)
'@storybook/react-vite':
specifier: 10.4.6
- version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@testing-library/dom':
specifier: 10.4.1
version: 10.4.1
@@ -322,7 +322,7 @@ importers:
version: 19.2.3(@types/react@19.2.17)
'@vitejs/plugin-react':
specifier: ^6.0.3
- version: 6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
babel-plugin-react-compiler:
specifier: ^1.0.0
version: 1.0.0
@@ -346,7 +346,7 @@ importers:
version: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
vite-plugin-dts:
specifier: ^5.0.3
- version: 5.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.0.1))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 5.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.1.0))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
text-editor:
devDependencies:
@@ -354,11 +354,11 @@ importers:
specifier: 1.61.1
version: 1.61.1
'@types/node':
- specifier: ^26.0.1
- version: 26.0.1
+ specifier: ^26.1.0
+ version: 26.1.0
'@vitest/browser':
specifier: ^4.1.9
- version: 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ version: 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/coverage-v8':
specifier: ^4.1.9
version: 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9)
@@ -381,11 +381,11 @@ importers:
specifier: ^3.9.4
version: 3.9.4
vite:
- specifier: ^8.1.1
- version: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ specifier: ^8.1.2
+ version: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
vitest:
specifier: ^4.1.9
- version: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ version: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
packages:
@@ -964,10 +964,6 @@ packages:
resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==}
engines: {node: '>=18.18'}
- '@isaacs/cliui@8.0.2':
- resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
- engines: {node: '>=12'}
-
'@joshwooding/vite-plugin-react-docgen-typescript@0.7.0':
resolution: {integrity: sha512-qvsTEwEFefhdirGOPnu9Wp6ChfIwy2dBCRuETU3uE+4cC+PFoxMSiiEhxk4lOluA34eARHA0OxqsEUYDqRMgeQ==}
peerDependencies:
@@ -1165,8 +1161,8 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
- '@one-ini/wasm@0.1.1':
- resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==}
+ '@one-ini/wasm@0.2.1':
+ resolution: {integrity: sha512-TUqERXGNTifZ9y2g3wPxQrw3HpHv/02DsW3D90T9x0hhonrL1ZqpSmNrU2XkoIq0fP1N6gZfVQzy2Fw1ZvGBNg==}
'@oxc-parser/binding-android-arm-eabi@0.127.0':
resolution: {integrity: sha512-0LC7ye4hvqbIKxAzThzvswgHLFu2AURKzYLeSVvLdu2TBOYWQDmHnTqPLeA597BcUCxiLqLsS4CJ5uoI5WYWCQ==}
@@ -1500,10 +1496,6 @@ packages:
resolution: {gitHosted: true, integrity: sha512-BxcjiWGtCbGBT+dsOnEODk1jASZLNYp27BuGQaJR7fxU4gLws3251r90Sp9seubcpRhGrfRdsA5WU0ExRdPOgg==, tarball: https://codeload.github.com/penpot/ua-parser/tar.gz/90b970f39f2dc08378b975a0f01045b4ec8e89a4}
version: 1.0.0
- '@pkgjs/parseargs@0.11.0':
- resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
- engines: {node: '>=14'}
-
'@playwright/test@1.61.1':
resolution: {integrity: sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==}
engines: {node: '>=18'}
@@ -2078,8 +2070,8 @@ packages:
'@types/mdx@2.0.14':
resolution: {integrity: sha512-T48PeuJtvLosNTPVhfnIp3i/n3a4g4Bad7YCq5k64D4u7NwDrAotikQ+5+sjtUvBmxCMlbo3dVL+C2dP0rWHzg==}
- '@types/node@26.0.1':
- resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==}
+ '@types/node@26.1.0':
+ resolution: {integrity: sha512-O0A1G3xPGy4w7AgQdAQYUlQ+BKk2Oovw8eRpofyp5KdBZULnbe+WqaOVNrm705SHphCiG4XHsACrSmPu1f+Kgw==}
'@types/react-dom@19.2.3':
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
@@ -2194,9 +2186,9 @@ packages:
resolution: {integrity: sha512-RQ4h9F6DOiHxpdocUDrOl6xBM+yOtz+LkUol47AVWcfebGBDpZ7w7Xvz9PS24JgXvLGiXXzSAfdCdVy1tPlaFA==}
engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=18.0.0'}
- abbrev@2.0.0:
- resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ abbrev@5.0.0:
+ resolution: {integrity: sha512-/XrFJgzQQQHpti1raDJC6m4ws6aNktmjBlhk8Fdlk7LwCEuDoieEJJY9OFHjfiFJFFRM2tK+Ky/IsfbbmlMu1w==}
+ engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
accepts@2.0.0:
resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
@@ -2421,9 +2413,6 @@ packages:
brace-expansion@1.1.15:
resolution: {integrity: sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==}
- brace-expansion@2.1.1:
- resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==}
-
brace-expansion@5.0.7:
resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==}
engines: {node: 18 || 20 || >=22}
@@ -2594,10 +2583,6 @@ packages:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
- commander@10.0.1:
- resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
- engines: {node: '>=14'}
-
commander@12.1.0:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
@@ -2912,12 +2897,9 @@ packages:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
- eastasianwidth@0.2.0:
- resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
-
- editorconfig@1.0.4:
- resolution: {integrity: sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==}
- engines: {node: '>=14'}
+ editorconfig@3.0.2:
+ resolution: {integrity: sha512-T0ix8GhtxyKVfUFEcvdNDt3YGqlwkFHbD4/5bgFUDgFmxhI/cSRAeJ87/Sz//Cq8Eam6JX/e23RkoFO71P7aAA==}
+ engines: {node: '>=20'}
hasBin: true
ee-first@1.1.1:
@@ -3250,12 +3232,8 @@ packages:
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
engines: {node: '>= 0.4'}
- foreground-child@3.3.1:
- resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
- engines: {node: '>=14'}
-
- form-data@4.0.5:
- resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
+ form-data@4.0.6:
+ resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==}
engines: {node: '>= 6'}
forwarded@0.2.0:
@@ -3354,11 +3332,6 @@ packages:
peerDependencies:
tslib: '2'
- glob@10.5.0:
- resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
- deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
- hasBin: true
-
glob@13.0.6:
resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
@@ -3736,9 +3709,6 @@ packages:
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
engines: {node: '>= 0.4'}
- jackspeak@3.4.3:
- resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
-
jju@1.4.0:
resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==}
@@ -3746,8 +3716,8 @@ packages:
resolution: {integrity: sha512-2/OKlogiESf2Nh3TFCrRjrr9z1DRHeW0I+KReF67+4J0Ns+8hBtHRmoWAZ2OFU6I5+TWLEe6sVlSdXPjHm5UbQ==}
engines: {node: '>= 20'}
- js-beautify@1.15.4:
- resolution: {integrity: sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==}
+ js-beautify@2.0.3:
+ resolution: {integrity: sha512-cyFbh3tkPhknnTD/0bLf0T0yy2ZIbqL05mttzbt4y1Zfr7NxqXQZ62dkBLKs3oHH/lpjmDRAnciJiSUyOy8XwQ==}
engines: {node: '>=14'}
hasBin: true
@@ -3968,9 +3938,6 @@ packages:
loupe@3.2.1:
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
- lru-cache@10.4.3:
- resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
-
lru-cache@11.5.1:
resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
engines: {node: 20 || >=22}
@@ -4080,10 +4047,6 @@ packages:
minimatch@3.1.5:
resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==}
- minimatch@9.0.9:
- resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
- engines: {node: '>=16 || 14 >=14.17'}
-
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
@@ -4138,8 +4101,8 @@ packages:
nice-try@1.0.5:
resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==}
- node-abi@3.92.0:
- resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==}
+ node-abi@3.93.0:
+ resolution: {integrity: sha512-Cu6yUpX5Iavugm8BeX7c0wgU9CvOqfd1yM6A1d2q2ZMjym7GjpASv2GdRcTq3Fx+Sb5OgBkEEpw4VnAbY6Y5RA==}
engines: {node: '>=10'}
node-addon-api@7.1.1:
@@ -4163,9 +4126,9 @@ packages:
engines: {node: '>=10'}
hasBin: true
- nopt@7.2.1:
- resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
- engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
+ nopt@10.0.1:
+ resolution: {integrity: sha512-df3sBr/6ax9hSGuC3CspvLlbnX8cP5L5nZwXF8cGN8l0zSWR6BvzmQ6jPUKjvo6+/xdpkNvEcucBNUdBeeV13g==}
+ engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0}
hasBin: true
normalize-package-data@2.5.0:
@@ -4320,10 +4283,6 @@ packages:
path-parse@1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- path-scurry@1.11.1:
- resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
- engines: {node: '>=16 || 14 >=14.18'}
-
path-scurry@2.0.2:
resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
engines: {node: 18 || 20 || >=22}
@@ -4430,8 +4389,9 @@ packages:
peerDependencies:
postcss: ^8.5.10
- postcss-modules@6.0.1:
- resolution: {integrity: sha512-zyo2sAkVvuZFFy0gc2+4O+xar5dYlaVy/ebO24KT0ftk/iJevSNyPyQellsBLlnccwh7f6V6Y4GvuKRYToNgpQ==}
+ postcss-modules@9.0.0:
+ resolution: {integrity: sha512-nyZGaOkHFRvXy10ryKSE3yfh1EhwSrEX2mIhwZblTTdHbKOfH5fNhAC6eZmXB2uCy7x6Bb1Zib5KS2Yw6gSzHQ==}
+ engines: {node: '>=20.6'}
peerDependencies:
postcss: ^8.5.10
@@ -5065,10 +5025,6 @@ packages:
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
engines: {node: '>=8'}
- string-width@5.1.2:
- resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
- engines: {node: '>=12'}
-
string-width@7.2.0:
resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
engines: {node: '>=18'}
@@ -5413,8 +5369,8 @@ packages:
undici-types@8.3.0:
resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
- undici@7.25.0:
- resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==}
+ undici@7.28.0:
+ resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==}
engines: {node: '>=20.18.1'}
unicorn-magic@0.4.0:
@@ -5518,51 +5474,8 @@ packages:
vite:
optional: true
- vite@8.1.0:
- resolution: {integrity: sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==}
- engines: {node: ^20.19.0 || >=22.12.0}
- hasBin: true
- peerDependencies:
- '@types/node': ^20.19.0 || >=22.12.0
- '@vitejs/devtools': ^0.3.0
- esbuild: ^0.27.0 || ^0.28.0
- jiti: '>=1.21.0'
- less: ^4.0.0
- sass: ^1.70.0
- sass-embedded: ^1.70.0
- stylus: '>=0.54.8'
- sugarss: ^5.0.0
- terser: ^5.16.0
- tsx: ^4.8.1
- yaml: ^2.8.3
- peerDependenciesMeta:
- '@types/node':
- optional: true
- '@vitejs/devtools':
- optional: true
- esbuild:
- optional: true
- jiti:
- optional: true
- less:
- optional: true
- sass:
- optional: true
- sass-embedded:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- tsx:
- optional: true
- yaml:
- optional: true
-
- vite@8.1.1:
- resolution: {integrity: sha512-X/05/cT+VITy2AeDc1der6smvGWWREtL4hPbPTaVbjSBuuWkmNOjR6HP3NzqcQA2nF6VHGUPaFRJyft/2AE9Kg==}
+ vite@8.1.2:
+ resolution: {integrity: sha512-6YYPbRXTxx6bRXmOn7XdnQAy5DQNHhDgtjhDHI13oe4pY93kkcdGJWxpGwOm++/Wh0QpQhDrpIoVMrmrsI5AGQ==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -5723,17 +5636,13 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
- workerpool@10.0.2:
- resolution: {integrity: sha512-8PCeZlCwu0+8hXruze1ahYNsY+M0LOCmbmySZ9BWWqWIXP9TAXa6FZCxACTDL/0j47pFcC4xW98Gr8nAC5oymg==}
+ workerpool@10.0.3:
+ resolution: {integrity: sha512-6z2Iis68Wqth93/G/wJP9u+R3O+d2XTlgWChGCwuT1qLbBsOYueGRZuJ++v3mtDP5KjYdy+WzvWC+VWETSVXJA==}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
- wrap-ansi@8.1.0:
- resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
- engines: {node: '>=12'}
-
wrap-ansi@9.0.2:
resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==}
engines: {node: '>=18'}
@@ -6394,28 +6303,11 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {}
- '@isaacs/cliui@8.0.2':
- dependencies:
- string-width: 5.1.2
- string-width-cjs: string-width@4.2.3
- strip-ansi: 7.2.0
- strip-ansi-cjs: strip-ansi@6.0.1
- wrap-ansi: 8.1.0
- wrap-ansi-cjs: wrap-ansi@7.0.0
-
- '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
glob: 13.0.6
react-docgen-typescript: 2.4.0(typescript@6.0.3)
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
- optionalDependencies:
- typescript: 6.0.3
-
- '@joshwooding/vite-plugin-react-docgen-typescript@0.7.0(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
- dependencies:
- glob: 13.0.6
- react-docgen-typescript: 2.4.0(typescript@6.0.3)
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
optionalDependencies:
typescript: 6.0.3
@@ -6579,24 +6471,24 @@ snapshots:
'@types/react': 19.2.17
react: 19.2.7
- '@microsoft/api-extractor-model@7.32.2(@types/node@26.0.1)':
+ '@microsoft/api-extractor-model@7.32.2(@types/node@26.1.0)':
dependencies:
'@microsoft/tsdoc': 0.16.0
'@microsoft/tsdoc-config': 0.18.1
- '@rushstack/node-core-library': 5.19.1(@types/node@26.0.1)
+ '@rushstack/node-core-library': 5.19.1(@types/node@26.1.0)
transitivePeerDependencies:
- '@types/node'
optional: true
- '@microsoft/api-extractor@7.56.2(@types/node@26.0.1)':
+ '@microsoft/api-extractor@7.56.2(@types/node@26.1.0)':
dependencies:
- '@microsoft/api-extractor-model': 7.32.2(@types/node@26.0.1)
+ '@microsoft/api-extractor-model': 7.32.2(@types/node@26.1.0)
'@microsoft/tsdoc': 0.16.0
'@microsoft/tsdoc-config': 0.18.1
- '@rushstack/node-core-library': 5.19.1(@types/node@26.0.1)
+ '@rushstack/node-core-library': 5.19.1(@types/node@26.1.0)
'@rushstack/rig-package': 0.6.0
- '@rushstack/terminal': 0.21.0(@types/node@26.0.1)
- '@rushstack/ts-command-line': 5.2.0(@types/node@26.0.1)
+ '@rushstack/terminal': 0.21.0(@types/node@26.1.0)
+ '@rushstack/ts-command-line': 5.2.0(@types/node@26.1.0)
diff: 8.0.4
lodash: 4.18.1
minimatch: 10.2.5
@@ -6652,7 +6544,7 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.20.1
- '@one-ini/wasm@0.1.1': {}
+ '@one-ini/wasm@0.2.1': {}
'@oxc-parser/binding-android-arm-eabi@0.127.0':
optional: true
@@ -6854,9 +6746,6 @@ snapshots:
'@penpot/ua-parser@https://codeload.github.com/penpot/ua-parser/tar.gz/90b970f39f2dc08378b975a0f01045b4ec8e89a4': {}
- '@pkgjs/parseargs@0.11.0':
- optional: true
-
'@playwright/test@1.61.1':
dependencies:
playwright: 1.61.1
@@ -7050,7 +6939,7 @@ snapshots:
'@rtsao/scc@1.1.0': {}
- '@rushstack/node-core-library@5.19.1(@types/node@26.0.1)':
+ '@rushstack/node-core-library@5.19.1(@types/node@26.1.0)':
dependencies:
ajv: 8.20.0
ajv-draft-04: 1.0.0(ajv@8.20.0)
@@ -7061,12 +6950,12 @@ snapshots:
resolve: 1.22.12
semver: 7.5.4
optionalDependencies:
- '@types/node': 26.0.1
+ '@types/node': 26.1.0
optional: true
- '@rushstack/problem-matcher@0.1.1(@types/node@26.0.1)':
+ '@rushstack/problem-matcher@0.1.1(@types/node@26.1.0)':
optionalDependencies:
- '@types/node': 26.0.1
+ '@types/node': 26.1.0
optional: true
'@rushstack/rig-package@0.6.0':
@@ -7075,18 +6964,18 @@ snapshots:
strip-json-comments: 3.1.1
optional: true
- '@rushstack/terminal@0.21.0(@types/node@26.0.1)':
+ '@rushstack/terminal@0.21.0(@types/node@26.1.0)':
dependencies:
- '@rushstack/node-core-library': 5.19.1(@types/node@26.0.1)
- '@rushstack/problem-matcher': 0.1.1(@types/node@26.0.1)
+ '@rushstack/node-core-library': 5.19.1(@types/node@26.1.0)
+ '@rushstack/problem-matcher': 0.1.1(@types/node@26.1.0)
supports-color: 8.1.1
optionalDependencies:
- '@types/node': 26.0.1
+ '@types/node': 26.1.0
optional: true
- '@rushstack/ts-command-line@5.2.0(@types/node@26.0.1)':
+ '@rushstack/ts-command-line@5.2.0(@types/node@26.1.0)':
dependencies:
- '@rushstack/terminal': 0.21.0(@types/node@26.0.1)
+ '@rushstack/terminal': 0.21.0(@types/node@26.1.0)
'@types/argparse': 1.0.38
argparse: 1.0.10
string-argv: 0.3.2
@@ -7103,10 +6992,10 @@ snapshots:
'@standard-schema/spec@1.1.0': {}
- '@storybook/addon-docs@10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@storybook/addon-docs@10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
'@mdx-js/react': 3.1.1(@types/react@19.2.17)(react@19.2.7)
- '@storybook/csf-plugin': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@storybook/csf-plugin': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
'@storybook/react-dom-shim': 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))
react: 19.2.7
@@ -7133,53 +7022,33 @@ snapshots:
'@storybook/icons': 2.0.2(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
optionalDependencies:
- '@vitest/browser': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
- '@vitest/browser-playwright': 4.1.9(playwright@1.61.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ '@vitest/browser': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ '@vitest/browser-playwright': 4.1.9(playwright@1.61.1)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/runner': 4.1.9
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ vitest: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
transitivePeerDependencies:
- react
- react-dom
- '@storybook/builder-vite@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@storybook/builder-vite@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
- '@storybook/csf-plugin': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@storybook/csf-plugin': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
ts-dedent: 2.3.0
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
transitivePeerDependencies:
- esbuild
- rollup
- webpack
- '@storybook/builder-vite@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
- dependencies:
- '@storybook/csf-plugin': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
- ts-dedent: 2.3.0
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
- transitivePeerDependencies:
- - esbuild
- - rollup
- - webpack
-
- '@storybook/csf-plugin@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@storybook/csf-plugin@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
unplugin: 2.3.11
optionalDependencies:
esbuild: 0.28.1
rollup: 4.61.1
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
-
- '@storybook/csf-plugin@10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
- dependencies:
- storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
- unplugin: 2.3.11
- optionalDependencies:
- esbuild: 0.28.1
- rollup: 4.61.1
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
'@storybook/global@5.0.0': {}
@@ -7197,11 +7066,11 @@ snapshots:
'@types/react': 19.2.17
'@types/react-dom': 19.2.3(@types/react@19.2.17)
- '@storybook/react-vite@10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@storybook/react-vite@10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
- '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@rollup/pluginutils': 5.4.0(rollup@4.61.1)
- '@storybook/builder-vite': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@storybook/builder-vite': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@storybook/react': 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)
empathic: 2.0.1
magic-string: 0.30.21
@@ -7211,31 +7080,7 @@ snapshots:
resolve: 1.22.12
storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
tsconfig-paths: 4.2.0
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
- transitivePeerDependencies:
- - '@types/react'
- - '@types/react-dom'
- - esbuild
- - rollup
- - supports-color
- - typescript
- - webpack
-
- '@storybook/react-vite@10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(esbuild@0.28.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
- dependencies:
- '@joshwooding/vite-plugin-react-docgen-typescript': 0.7.0(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- '@rollup/pluginutils': 5.4.0(rollup@4.61.1)
- '@storybook/builder-vite': 10.4.6(esbuild@0.28.1)(rollup@4.61.1)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- '@storybook/react': 10.4.6(@types/react-dom@19.2.3(@types/react@19.2.17))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(storybook@10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(typescript@6.0.3)
- empathic: 2.0.1
- magic-string: 0.30.21
- react: 19.2.7
- react-docgen: 8.0.3
- react-dom: 19.2.7(react@19.2.7)
- resolve: 1.22.12
- storybook: 10.4.6(@testing-library/dom@10.4.1)(@types/react@19.2.17)(prettier@3.9.4)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
- tsconfig-paths: 4.2.0
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
@@ -7371,7 +7216,7 @@ snapshots:
'@types/mdx@2.0.14': {}
- '@types/node@26.0.1':
+ '@types/node@26.1.0':
dependencies:
undici-types: 8.3.0
@@ -7387,67 +7232,36 @@ snapshots:
'@types/triple-beam@1.3.5': {}
- '@vitejs/plugin-react@6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@vitejs/plugin-react@6.0.3(babel-plugin-react-compiler@1.0.0)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
'@rolldown/pluginutils': 1.0.1
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
optionalDependencies:
babel-plugin-react-compiler: 1.0.0
- '@vitest/browser-playwright@4.1.9(playwright@1.61.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
+ '@vitest/browser-playwright@4.1.9(playwright@1.61.1)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
dependencies:
- '@vitest/browser': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
- '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@vitest/browser': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ '@vitest/mocker': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
playwright: 1.61.1
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ vitest: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
transitivePeerDependencies:
- bufferutil
- msw
- utf-8-validate
- vite
- '@vitest/browser-playwright@4.1.9(playwright@1.61.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
- dependencies:
- '@vitest/browser': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
- '@vitest/mocker': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- playwright: 1.61.1
- tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- transitivePeerDependencies:
- - bufferutil
- - msw
- - utf-8-validate
- - vite
- optional: true
-
- '@vitest/browser@4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
+ '@vitest/browser@4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
dependencies:
'@blazediff/core': 1.9.1
- '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@vitest/mocker': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@vitest/utils': 4.1.9
magic-string: 0.30.21
pngjs: 7.0.0
sirv: 3.0.2
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- ws: 8.21.0
- transitivePeerDependencies:
- - bufferutil
- - msw
- - utf-8-validate
- - vite
-
- '@vitest/browser@4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)':
- dependencies:
- '@blazediff/core': 1.9.1
- '@vitest/mocker': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- '@vitest/utils': 4.1.9
- magic-string: 0.30.21
- pngjs: 7.0.0
- sirv: 3.0.2
- tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ vitest: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
ws: 8.21.0
transitivePeerDependencies:
- bufferutil
@@ -7467,9 +7281,9 @@ snapshots:
obug: 2.1.3
std-env: 4.1.0
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ vitest: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
optionalDependencies:
- '@vitest/browser': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ '@vitest/browser': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/expect@3.2.4':
dependencies:
@@ -7488,21 +7302,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.0
- '@vitest/mocker@4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
+ '@vitest/mocker@4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
dependencies:
'@vitest/spy': 4.1.9
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
-
- '@vitest/mocker@4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))':
- dependencies:
- '@vitest/spy': 4.1.9
- estree-walker: 3.0.3
- magic-string: 0.30.21
- optionalDependencies:
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
'@vitest/pretty-format@3.2.4':
dependencies:
@@ -7539,7 +7345,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ vitest: 4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@vitest/utils@3.2.4':
dependencies:
@@ -7571,7 +7377,7 @@ snapshots:
'@zip.js/zip.js@2.8.26(patch_hash=7b556bbd426f152eb086f0126a53900e369a95cf64357c380b7c8d8e940c3d95)': {}
- abbrev@2.0.0: {}
+ abbrev@5.0.0: {}
accepts@2.0.0:
dependencies:
@@ -7783,7 +7589,7 @@ snapshots:
axios@1.16.1(supports-color@5.5.0):
dependencies:
follow-redirects: 1.16.0
- form-data: 4.0.5
+ form-data: 4.0.6
https-proxy-agent: 5.0.1(supports-color@5.5.0)
proxy-from-env: 2.1.0
transitivePeerDependencies:
@@ -7841,10 +7647,6 @@ snapshots:
balanced-match: 1.0.2
concat-map: 0.0.1
- brace-expansion@2.1.1:
- dependencies:
- balanced-match: 1.0.2
-
brace-expansion@5.0.7:
dependencies:
balanced-match: 4.0.4
@@ -8027,8 +7829,6 @@ snapshots:
dependencies:
delayed-stream: 1.0.0
- commander@10.0.1: {}
-
commander@12.1.0: {}
commander@14.0.3: {}
@@ -8333,14 +8133,12 @@ snapshots:
es-errors: 1.3.0
gopd: 1.2.0
- eastasianwidth@0.2.0: {}
-
- editorconfig@1.0.4:
+ editorconfig@3.0.2:
dependencies:
- '@one-ini/wasm': 0.1.1
- commander: 10.0.1
- minimatch: 9.0.9
- semver: 7.8.4
+ '@one-ini/wasm': 0.2.1
+ commander: 14.0.3
+ minimatch: 10.2.5
+ semver: 7.8.5
ee-first@1.1.1: {}
@@ -8830,12 +8628,7 @@ snapshots:
dependencies:
is-callable: 1.2.7
- foreground-child@3.3.1:
- dependencies:
- cross-spawn: 7.0.6
- signal-exit: 4.1.0
-
- form-data@4.0.5:
+ form-data@4.0.6:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
@@ -8936,15 +8729,6 @@ snapshots:
dependencies:
tslib: 2.8.1
- glob@10.5.0:
- dependencies:
- foreground-child: 3.3.1
- jackspeak: 3.4.3
- minimatch: 9.0.9
- minipass: 7.1.3
- package-json-from-dist: 1.0.1
- path-scurry: 1.11.1
-
glob@13.0.6:
dependencies:
minimatch: 10.2.5
@@ -9298,12 +9082,6 @@ snapshots:
has-symbols: 1.1.0
set-function-name: 2.0.2
- jackspeak@3.4.3:
- dependencies:
- '@isaacs/cliui': 8.0.2
- optionalDependencies:
- '@pkgjs/parseargs': 0.11.0
-
jju@1.4.0:
optional: true
@@ -9317,13 +9095,13 @@ snapshots:
'@hapi/topo': 6.0.2
'@standard-schema/spec': 1.1.0
- js-beautify@1.15.4:
+ js-beautify@2.0.3:
dependencies:
config-chain: 1.1.13
- editorconfig: 1.0.4
- glob: 10.5.0
+ editorconfig: 3.0.2
+ glob: 13.0.6
js-cookie: 3.0.8
- nopt: 7.2.1
+ nopt: 10.0.1
js-cookie@3.0.8: {}
@@ -9356,7 +9134,7 @@ snapshots:
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 6.0.1
- undici: 7.25.0
+ undici: 7.28.0
w3c-xmlserializer: 5.0.0
webidl-conversions: 8.0.1
whatwg-mimetype: 5.0.0
@@ -9525,8 +9303,6 @@ snapshots:
loupe@3.2.1: {}
- lru-cache@10.4.3: {}
-
lru-cache@11.5.1: {}
lru-cache@5.1.1:
@@ -9624,10 +9400,6 @@ snapshots:
dependencies:
brace-expansion: 1.1.15
- minimatch@9.0.9:
- dependencies:
- brace-expansion: 2.1.1
-
minimist@1.2.8: {}
minipass@7.1.3: {}
@@ -9663,7 +9435,7 @@ snapshots:
nice-try@1.0.5: {}
- node-abi@3.92.0:
+ node-abi@3.93.0:
dependencies:
semver: 7.8.5
@@ -9690,9 +9462,9 @@ snapshots:
touch: 3.1.1
undefsafe: 2.0.5
- nopt@7.2.1:
+ nopt@10.0.1:
dependencies:
- abbrev: 2.0.0
+ abbrev: 5.0.0
normalize-package-data@2.5.0:
dependencies:
@@ -9905,11 +9677,6 @@ snapshots:
path-parse@1.0.7: {}
- path-scurry@1.11.1:
- dependencies:
- lru-cache: 10.4.3
- minipass: 7.1.3
-
path-scurry@2.0.2:
dependencies:
lru-cache: 11.5.1
@@ -9987,20 +9754,20 @@ snapshots:
dependencies:
icss-utils: 5.1.0(postcss@8.5.16)
postcss: 8.5.16
- postcss-selector-parser: 7.1.1
+ postcss-selector-parser: 7.1.4
postcss-value-parser: 4.2.0
postcss-modules-scope@3.2.1(postcss@8.5.16):
dependencies:
postcss: 8.5.16
- postcss-selector-parser: 7.1.1
+ postcss-selector-parser: 7.1.4
postcss-modules-values@4.0.0(postcss@8.5.16):
dependencies:
icss-utils: 5.1.0(postcss@8.5.16)
postcss: 8.5.16
- postcss-modules@6.0.1(postcss@8.5.16):
+ postcss-modules@9.0.0(postcss@8.5.16):
dependencies:
generic-names: 4.0.0
icss-utils: 5.1.0(postcss@8.5.16)
@@ -10050,7 +9817,7 @@ snapshots:
minimist: 1.2.8
mkdirp-classic: 0.5.3
napi-build-utils: 2.0.0
- node-abi: 3.92.0
+ node-abi: 3.93.0
pump: 3.0.4
rc: 1.2.8
simple-get: 4.0.1
@@ -10718,12 +10485,6 @@ snapshots:
is-fullwidth-code-point: 3.0.0
strip-ansi: 6.0.1
- string-width@5.1.2:
- dependencies:
- eastasianwidth: 0.2.0
- emoji-regex: 9.2.2
- strip-ansi: 7.2.0
-
string-width@7.2.0:
dependencies:
emoji-regex: 10.6.0
@@ -11161,7 +10922,7 @@ snapshots:
undici-types@8.3.0: {}
- undici@7.25.0: {}
+ undici@7.28.0: {}
unicorn-magic@0.4.0: {}
@@ -11170,7 +10931,7 @@ snapshots:
unpipe@1.0.0: {}
- unplugin-dts@1.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.0.1))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
+ unplugin-dts@1.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.1.0))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
dependencies:
'@rollup/pluginutils': 5.4.0(rollup@4.61.1)
'@volar/typescript': 2.4.28
@@ -11182,11 +10943,11 @@ snapshots:
typescript: 6.0.3
unplugin: 2.3.11
optionalDependencies:
- '@microsoft/api-extractor': 7.56.2(@types/node@26.0.1)
+ '@microsoft/api-extractor': 7.56.2(@types/node@26.1.0)
esbuild: 0.28.1
rolldown: 1.1.3
rollup: 4.61.1
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
transitivePeerDependencies:
- supports-color
@@ -11248,13 +11009,13 @@ snapshots:
remove-trailing-separator: 1.1.0
replace-ext: 1.0.1
- vite-plugin-dts@5.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.0.1))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
+ vite-plugin-dts@5.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.1.0))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
dependencies:
- unplugin-dts: 1.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.0.1))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ unplugin-dts: 1.0.3(@microsoft/api-extractor@7.56.2(@types/node@26.1.0))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.61.1)(supports-color@5.5.0)(typescript@6.0.3)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
optionalDependencies:
- '@microsoft/api-extractor': 7.56.2(@types/node@26.0.1)
+ '@microsoft/api-extractor': 7.56.2(@types/node@26.1.0)
rollup: 4.61.1
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
transitivePeerDependencies:
- '@rspack/core'
- '@vue/language-core'
@@ -11264,7 +11025,7 @@ snapshots:
- typescript
- webpack
- vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0):
+ vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
@@ -11272,30 +11033,16 @@ snapshots:
rolldown: 1.1.3
tinyglobby: 0.2.17
optionalDependencies:
- '@types/node': 26.0.1
+ '@types/node': 26.1.0
esbuild: 0.28.1
fsevents: 2.3.3
sass: 1.101.0
sass-embedded: 1.100.0
- vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0):
- dependencies:
- lightningcss: 1.32.0
- picomatch: 4.0.4
- postcss: 8.5.16
- rolldown: 1.1.3
- tinyglobby: 0.2.17
- optionalDependencies:
- '@types/node': 26.0.1
- esbuild: 0.28.1
- fsevents: 2.3.3
- sass: 1.101.0
- sass-embedded: 1.100.0
-
- vitest@4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
+ vitest@4.1.9(@types/node@26.1.0)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
dependencies:
'@vitest/expect': 4.1.9
- '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
+ '@vitest/mocker': 4.1.9(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
'@vitest/pretty-format': 4.1.9
'@vitest/runner': 4.1.9
'@vitest/snapshot': 4.1.9
@@ -11312,42 +11059,11 @@ snapshots:
tinyexec: 1.0.2
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
+ vite: 8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
why-is-node-running: 2.3.0
optionalDependencies:
- '@types/node': 26.0.1
- '@vitest/browser-playwright': 4.1.9(playwright@1.61.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
- '@vitest/coverage-v8': 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9)
- '@vitest/ui': 4.1.9(vitest@4.1.9)
- jsdom: 29.1.1(canvas@3.2.3)
- transitivePeerDependencies:
- - msw
-
- vitest@4.1.9(@types/node@26.0.1)(@vitest/browser-playwright@4.1.9)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(jsdom@29.1.1(canvas@3.2.3))(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)):
- dependencies:
- '@vitest/expect': 4.1.9
- '@vitest/mocker': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))
- '@vitest/pretty-format': 4.1.9
- '@vitest/runner': 4.1.9
- '@vitest/snapshot': 4.1.9
- '@vitest/spy': 4.1.9
- '@vitest/utils': 4.1.9
- es-module-lexer: 2.1.0
- expect-type: 1.3.0
- magic-string: 0.30.21
- obug: 2.1.3
- pathe: 2.0.3
- picomatch: 4.0.4
- std-env: 4.1.0
- tinybench: 2.9.0
- tinyexec: 1.0.2
- tinyglobby: 0.2.17
- tinyrainbow: 3.1.0
- vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0)
- why-is-node-running: 2.3.0
- optionalDependencies:
- '@types/node': 26.0.1
- '@vitest/browser-playwright': 4.1.9(playwright@1.61.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
+ '@types/node': 26.1.0
+ '@vitest/browser-playwright': 4.1.9(playwright@1.61.1)(vite@8.1.2(@types/node@26.1.0)(esbuild@0.28.1)(sass-embedded@1.100.0)(sass@1.101.0))(vitest@4.1.9)
'@vitest/coverage-v8': 4.1.9(@vitest/browser@4.1.9)(vitest@4.1.9)
'@vitest/ui': 4.1.9(vitest@4.1.9)
jsdom: 29.1.1(canvas@3.2.3)
@@ -11474,7 +11190,7 @@ snapshots:
word-wrap@1.2.5: {}
- workerpool@10.0.2: {}
+ workerpool@10.0.3: {}
wrap-ansi@7.0.0:
dependencies:
@@ -11482,12 +11198,6 @@ snapshots:
string-width: 4.2.3
strip-ansi: 6.0.1
- wrap-ansi@8.1.0:
- dependencies:
- ansi-styles: 6.2.3
- string-width: 5.1.2
- strip-ansi: 7.2.0
-
wrap-ansi@9.0.2:
dependencies:
ansi-styles: 6.2.3
diff --git a/frontend/src/app/main/ui/ds/controls/select.cljs b/frontend/src/app/main/ui/ds/controls/select.cljs
index a09fe3f263..337d9f3b51 100644
--- a/frontend/src/app/main/ui/ds/controls/select.cljs
+++ b/frontend/src/app/main/ui/ds/controls/select.cljs
@@ -204,6 +204,10 @@
(mf/with-effect [options]
(mf/set-ref-val! options-ref options))
+ (mf/with-effect [default-selected options]
+ (reset! selected-id*
+ (get-selected-option-id options default-selected)))
+
[:div {:class [wrapper-class (stl/css :select-wrapper)]
:on-click on-click
:ref select-ref
diff --git a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs
index 5be77b6ef9..0b6958069b 100644
--- a/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs
+++ b/frontend/src/app/main/ui/ds/controls/utilities/token_field.cljs
@@ -9,6 +9,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
+ [app.main.refs :as refs]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.foundations.assets.icon :as i]
[app.main.ui.ds.tooltip :refer [tooltip*]]
@@ -43,10 +44,25 @@
token-has-errors]}]
(let [set-active? (some? id)
+ all-tokens-map (mf/deref refs/workspace-all-tokens-map)
+ token-exists? (contains? all-tokens-map label)
+ token-not-active (and token-exists? (not set-active?))
content (cond
- token-has-errors (tr "workspace.tokens.ref-not-valid")
- (not set-active?) (tr "ds.inputs.token-field.no-active-token-option" label)
- :else label)
+ (not token-exists?)
+ (tr "options.deleted-token-with-name" label)
+
+ (and token-exists? (not set-active?))
+ (tr "ds.inputs.token-field.no-active-token-option" label)
+
+ (and token-exists? token-has-errors)
+ (tr "workspace.tokens.ref-not-valid" label)
+
+ :else
+ label)
+
+ broken-state (or (not token-exists?)
+ token-has-errors
+ token-not-active)
default-id (mf/use-id)
id (d/nilv id default-id)
@@ -84,15 +100,13 @@
[:button {:on-click on-click
:ref pill-ref
:class (stl/css-case :pill true
- :no-set-pill (or (not set-active?)
- token-has-errors)
+ :no-set-pill broken-state
:pill-disabled disabled)
:disabled disabled
:aria-labelledby (dm/str id "-pill")
:on-key-down on-token-key-down}
value
- (when (or (not set-active?)
- token-has-errors)
+ (when broken-state
[:div {:class (stl/css :pill-dot)}])]]]
(when-not ^boolean disabled
diff --git a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
index 5a226c5207..0647a74c3c 100644
--- a/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
+++ b/frontend/src/app/main/ui/ds/tooltip/tooltip.scss
@@ -159,6 +159,7 @@ $arrow-side: 12px;
padding: var(--sp-s) var(--sp-m);
grid-area: content;
block-size: fit-content;
+ overflow-wrap: anywhere;
}
.tooltip-trigger {
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss
index f234b4115c..cffa05d73b 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.scss
@@ -193,10 +193,12 @@
.interaction-row-position {
grid-column: 4 / span 5;
display: grid;
- grid-template:
- "topleft top topright" 1fr
- "left center right" 1fr
- "bottomleft bottom bottomright" 1fr / repeat(3, 1fr);
+ grid-template-areas:
+ "topleft top topright"
+ "left center right"
+ "bottomleft bottom bottomright";
+ grid-template-rows: 1fr 1fr 1fr;
+ grid-template-columns: 1fr 1fr 1fr;
inline-size: calc($sz-32 * 3);
block-size: calc($sz-32 * 3);
border-radius: $br-8;
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs
index 645ccb5c8c..9ca3054996 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs
@@ -9,6 +9,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
+ [app.main.refs :as refs]
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
[app.main.ui.ds.controls.shared.token-option :as to]
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
@@ -25,31 +26,46 @@
token (->> (:typography active-tokens)
(d/seek #(= (:name %) token-name)))
- has-errors (some? (:errors token))
display-name (or (:name token) token-name)
resolved-value (:resolved-value token)
- not-active (or (nil? token)
- (empty? (:typography active-tokens)))
on-detach
(mf/use-fn
(mf/deps display-name)
(fn []
(detach-token display-name)))
+ all-tokens-map (mf/deref refs/workspace-all-tokens-map)
+
+ token-exists? (contains? all-tokens-map token-name)
+ has-errors (and token-exists?
+ (some? (:errors token)))
+
+ not-active (and
+ token-exists?
+ (or (nil? token)
+ (empty? (:typography active-tokens))))
+
+ broken-state (or (not token-exists?)
+ has-errors
+ not-active)
tooltip-content (cond
not-active
- (tr "options.deleted-token")
+ (tr "ds.inputs.token-field.no-active-token-option" token-name)
+
+ (not token-exists?)
+ (tr "options.deleted-token-with-name" token-name)
+
has-errors
- (tr "not-active-token.no-name")
+ (tr "workspace.tokens.ref-not-valid" token-name)
+
:else
(mf/html [:> to/resolved-value-tooltip* {:token-name token-name
:resolved-value resolved-value}]))]
[:div {:class (stl/css-case :token-typography-row true
- :token-typography-row-with-errors has-errors
- :token-typography-row-not-active not-active)}
- (when (or has-errors not-active)
+ :token-typography-row-with-errors broken-state)}
+ (when broken-state
[:div {:class (stl/css :error-dot)}])
[:> icon* {:icon-id i/text-typography
:class (stl/css :icon)}]
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.scss b/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.scss
index 5d6ac3d6ac..615e8379c5 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.scss
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.scss
@@ -35,8 +35,7 @@
}
}
-.token-typography-row-with-errors,
-.token-typography-row-not-active {
+.token-typography-row-with-errors {
--token-typography-row-background-color: var(--color-background-primary);
--token-typography-row-foreground-color: var(--color-foreground-secondary);
--token-typography-row-border-color: var(--color-token-border);
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs
index 1dcfa53306..6fd4f3c654 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs
@@ -89,42 +89,72 @@
(let [token-name (or (:name token) applied-token-name)]
(detach-token token-name))))
- has-errors (some? (:errors token))
token-name (:name token)
resolved (:resolved-value token)
- not-active (or (empty? active-tokens)
- (nil? token))
+
+
+ ;; Tooltip content for the swatch and token name, based on the token's state
+ all-tokens-map (mf/deref refs/workspace-all-tokens-map)
+
+ token-exists? (contains? all-tokens-map applied-token-name)
+ has-errors (and token-exists?
+ (some? (:errors token)))
+
+ not-active (and
+ token-exists?
+ (or (empty? active-tokens)
+ (nil? token)))
+
id (dm/str (:id token) "-name")
token-name-ref (mf/use-ref nil)
+
+ broken-state (or (not token-exists?)
+ has-errors
+ not-active)
+
swatch-tooltip-content (cond
not-active
- (tr "options.deleted-token")
+ (tr "ds.inputs.token-field.no-active-token-option" applied-token-name)
+
+ (not token-exists?)
+ (tr "options.deleted-token-with-name" applied-token-name)
+
has-errors
- (tr "not-active-token.no-name")
+ (tr "workspace.tokens.ref-not-valid" applied-token-name)
+
:else
(tr "workspace.tokens.resolved-value" resolved))
+
name-tooltip-content (cond
- not-active
- (tr "options.deleted-token")
has-errors
- (tr "not-active-token.no-name")
+ (tr "workspace.tokens.ref-not-valid" applied-token-name)
+
+ not-active
+ (tr "ds.inputs.token-field.no-active-token-option" applied-token-name)
+
+ (not token-exists?)
+ (tr "options.deleted-token-with-name" applied-token-name)
+
:else
#(mf/html
[:div
[:span (dm/str (tr "workspace.tokens.token-name") ": ")]
- [:span {:class (stl/css :token-name-tooltip)} applied-token-name]]))]
+ [:span {:class (stl/css :token-name-tooltip)} applied-token-name]
+ [:div
+ [:span (tr "inspect.tabs.styles.token-resolved-value")]
+ [:span {:class (stl/css :resolved-value)} (dm/str " " resolved)]]]))]
+
[:div {:class (stl/css :color-info)}
[:div {:class (stl/css-case :token-color-wrapper true
- :token-color-with-errors has-errors
- :token-color-not-active not-active)}
+ :token-color-with-errors broken-state)}
[:div {:class (stl/css :color-bullet-wrapper)}
- (when (or has-errors not-active)
+ (when broken-state
[:div {:class (stl/css :error-dot)}])
[:> swatch* {:background color
:tooltip-content swatch-tooltip-content
:on-click on-swatch-click-token
- :has-errors (or has-errors not-active)
+ :has-errors broken-state
:size "small"}]]
[:> tooltip* {:content name-tooltip-content
:id id
diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
index de2ddd2ed0..9b3005ecea 100644
--- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
+++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/text.cljs
@@ -171,7 +171,7 @@
:cell (ctl/get-cell-by-shape-id (first parents) (first ids))}])
(when is-layout-child?
- [:& layout-item-menu*
+ [:> layout-item-menu*
{:ids ids
:type type
:values layout-item-values
diff --git a/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs b/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs
index 85c5846035..c4f636db79 100644
--- a/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs
+++ b/frontend/src/app/main/ui/workspace/tokens/management/token_pill.cljs
@@ -127,7 +127,7 @@
(cond
;; If there are errors, show the appropriate message
ref-not-in-active-set
- (tr "workspace.tokens.ref-not-valid")
+ (tr "workspace.tokens.ref-not-valid" name)
is-name-collision
(wte/resolve-error-message (first errors))
@@ -290,7 +290,7 @@
:token-pill-disabled disabled?
:token-pill-applied (and can-edit? has-selected? (or half-applied? full-applied?))
:token-pill-invalid (and can-edit? errors?)
- :token-pill-invalid-applied (and full-applied? errors? can-edit?)
+ :token-pill-invalid-applied (and (or half-applied? full-applied?) errors? can-edit?)
:token-pill-viewer is-viewer?
:token-pill-applied-viewer (and is-viewer? has-selected?
(or half-applied? full-applied?))
diff --git a/frontend/src/app/main/ui/workspace/viewport.cljs b/frontend/src/app/main/ui/workspace/viewport.cljs
index ee85719d9b..5941f1301e 100644
--- a/frontend/src/app/main/ui/workspace/viewport.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport.cljs
@@ -507,7 +507,8 @@
(when (and (seq selected-shapes)
(not transform)
(not text-editing?)
- (not edition))
+ (not edition)
+ (not mode-inspect?))
[:> msr/selection-size-badge*
{:selrect (gsh/shapes->rect selected-shapes)
:zoom zoom}])
diff --git a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs
index ba451a7b01..7ae291414d 100644
--- a/frontend/src/app/main/ui/workspace/viewport_wasm.cljs
+++ b/frontend/src/app/main/ui/workspace/viewport_wasm.cljs
@@ -778,6 +778,7 @@
(not transform)
(not text-editing?)
(not edition)
+ (not mode-inspect?)
(not page-transition?))
[:> msr/selection-size-badge*
{:selrect (gsh/shapes->rect selected-shapes)
diff --git a/frontend/src/app/plugins/flex.cljs b/frontend/src/app/plugins/flex.cljs
index 57c7fda4e3..d3067fb7c0 100644
--- a/frontend/src/app/plugins/flex.cljs
+++ b/frontend/src/app/plugins/flex.cljs
@@ -151,7 +151,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :rowGap value)
(not (r/check-permission plugin-id "content:write"))
@@ -169,7 +169,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :columnGap value)
(not (r/check-permission plugin-id "content:write"))
@@ -187,7 +187,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :verticalPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -205,7 +205,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :horizontalPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -223,7 +223,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :topPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -241,7 +241,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :rightPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -259,7 +259,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :bottomPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -277,7 +277,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :leftPadding value)
(not (r/check-permission plugin-id "content:write"))
diff --git a/frontend/src/app/plugins/grid.cljs b/frontend/src/app/plugins/grid.cljs
index 6964a034dd..3ef266c1ad 100644
--- a/frontend/src/app/plugins/grid.cljs
+++ b/frontend/src/app/plugins/grid.cljs
@@ -141,7 +141,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :rowGap value)
(not (r/check-permission plugin-id "content:write"))
@@ -159,7 +159,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :columnGap value)
(not (r/check-permission plugin-id "content:write"))
@@ -177,7 +177,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :verticalPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -195,7 +195,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :horizontalPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -213,7 +213,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :topPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -231,14 +231,14 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :rightPadding value)
(not (r/check-permission plugin-id "content:write"))
- (u/not-valid plugin-id :righPadding "Plugin doesn't have 'content:write' permission")
+ (u/not-valid plugin-id :rightPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
- (u/not-valid plugin-id :righPadding "Cannot modify a page that is not currently active")
+ (u/not-valid plugin-id :rightPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}}))))}
@@ -249,7 +249,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :bottomPadding value)
(not (r/check-permission plugin-id "content:write"))
@@ -267,7 +267,7 @@
:set
(fn [_ value]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :leftPadding value)
(not (r/check-permission plugin-id "content:write"))
diff --git a/frontend/src/app/plugins/parser.cljs b/frontend/src/app/plugins/parser.cljs
index 0c3c2af32a..1b9f844c48 100644
--- a/frontend/src/app/plugins/parser.cljs
+++ b/frontend/src/app/plugins/parser.cljs
@@ -336,7 +336,7 @@
(d/without-nils
{:type (-> (obj/get guide "type") parse-keyword)
:display (obj/get guide "display")
- :params (-> (obj/get guide "params") parse-frame-guide-column-params)})))
+ :params (-> (obj/get guide "params") parse-frame-guide-square-params)})))
(defn parse-frame-guide
[^js guide]
@@ -488,8 +488,8 @@
{:action-type action-type
:destination (-> (obj/get action "destination") (obj/get "$id"))
:relative-to (-> (obj/get action "relativeTo") (obj/get "$id"))
- :overlay-pos-type (-> (obj/get action "position") parse-keyword)
- :overlay-position (-> (obj/get action "manualPositionLocation") parse-point (d/nilv (gpt/point 0 0)))
+ :overlay-pos-type (or (-> (obj/get action "position") parse-keyword) :center)
+ :overlay-position (-> (obj/get action "manualPositionLocation") parse-point)
:close-click-outside (obj/get action "closeWhenClickOutside")
:background-overlay (obj/get action "addBackgroundOverlay")
:animation (-> (obj/get action "animation") parse-animation)}
diff --git a/frontend/src/app/plugins/shape.cljs b/frontend/src/app/plugins/shape.cljs
index cccc32c625..a535cad23b 100644
--- a/frontend/src/app/plugins/shape.cljs
+++ b/frontend/src/app/plugins/shape.cljs
@@ -112,7 +112,7 @@
:set
(fn [_ value]
(cond
- (or (not (number? value)) (not (pos? value)))
+ (or (not (sm/valid-safe-int? value)) (neg? value))
(u/not-valid plugin-id :delay value)
:else
@@ -422,7 +422,7 @@
(fn [self value]
(let [id (obj/get self "$id")]
(cond
- (or (not (sm/valid-safe-int? value)) (< value 0))
+ (or (not (sm/valid-safe-number? value)) (< value 0))
(u/not-valid plugin-id :borderRadius value)
(not (r/check-permission plugin-id "content:write"))
@@ -441,7 +441,7 @@
(fn [self value]
(let [id (obj/get self "$id")]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :borderRadiusTopLeft value)
(not (r/check-permission plugin-id "content:write"))
@@ -460,7 +460,7 @@
(fn [self value]
(let [id (obj/get self "$id")]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :borderRadiusTopRight value)
(not (r/check-permission plugin-id "content:write"))
@@ -479,7 +479,7 @@
(fn [self value]
(let [id (obj/get self "$id")]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :borderRadiusBottomRight value)
(not (r/check-permission plugin-id "content:write"))
@@ -498,7 +498,7 @@
(fn [self value]
(let [id (obj/get self "$id")]
(cond
- (not (sm/valid-safe-int? value))
+ (not (sm/valid-safe-number? value))
(u/not-valid plugin-id :borderRadiusBottomLeft value)
(not (r/check-permission plugin-id "content:write"))
diff --git a/frontend/src/app/plugins/tokens.cljs b/frontend/src/app/plugins/tokens.cljs
index a9c27c9649..e832e7750a 100644
--- a/frontend/src/app/plugins/tokens.cljs
+++ b/frontend/src/app/plugins/tokens.cljs
@@ -453,6 +453,23 @@
(defn token-theme-proxy? [p]
(obj/type-of? p "TokenThemeProxy"))
+(defn- resolve-token-set
+ "Resolves an addSet/removeSet argument to a token set. A proxy is returned
+ as-is; an id is located in the file's token library."
+ [file-id set-arg]
+ (if (token-set-proxy? set-arg)
+ set-arg
+ (u/locate-token-set file-id set-arg)))
+
+(defn- token-set-name
+ "Reads the name from a resolved token set, supporting both proxies (whose
+ getter falls back to the freshly-created name) and located sets."
+ [set]
+ (when (some? set)
+ (if (token-set-proxy? set)
+ (obj/get set "name")
+ (ctob/get-name set))))
+
(defn token-theme-proxy
[plugin-id file-id id]
(obj/reify {:name "TokenThemeProxy"
@@ -535,27 +552,20 @@
:addSet
{:enumerable false
- :schema [:tuple [:fn token-set-proxy?]]
- :fn (fn [token-set]
- ;; Resolve the set name before the theme lookup. The proxy's :name
- ;; getter now falls back to `initial-name` when state hasn't
- ;; propagated, so this is safe even for freshly created sets.
- ;; Guard against nil to prevent `enable-set` from conj'ing nil
- ;; into the theme's :sets — which would send `:sets #{nil}` to the
- ;; backend and crash the workspace.
- (let [set-name (obj/get token-set "name")
+ :schema [:tuple [:or [:fn token-set-proxy?] ::sm/uuid]]
+ :fn (fn [set-arg]
+ (let [set-name (token-set-name (resolve-token-set file-id set-arg))
theme (u/locate-token-theme file-id id)]
- (when (and (some? set-name) (some? theme))
+ (when (and set-name theme)
(st/emit! (dwtl/update-token-theme id (ctob/enable-set theme set-name))))))}
:removeSet
{:enumerable false
- :schema [:tuple [:fn token-set-proxy?]]
- :fn (fn [token-set]
- ;; Same nil guard as addSet — see comment above.
- (let [set-name (obj/get token-set "name")
+ :schema [:tuple [:or [:fn token-set-proxy?] ::sm/uuid]]
+ :fn (fn [set-arg]
+ (let [set-name (token-set-name (resolve-token-set file-id set-arg))
theme (u/locate-token-theme file-id id)]
- (when (and (some? set-name) (some? theme))
+ (when (and set-name theme)
(st/emit! (dwtl/update-token-theme id (ctob/disable-set theme set-name))))))}
:duplicate
diff --git a/frontend/src/app/plugins/utils.cljs b/frontend/src/app/plugins/utils.cljs
index 2e0db5d324..f55d63372e 100644
--- a/frontend/src/app/plugins/utils.cljs
+++ b/frontend/src/app/plugins/utils.cljs
@@ -311,12 +311,16 @@
(defn error-messages
[explain]
- (->> (:errors explain)
- (reduce csm/interpret-schema-problem {})
- (flatten-error-map)
- (map (fn [[field message]]
- (tr "plugins.validation.message" field message)))
- (str/join ". ")))
+ (let [msg (->> (:errors explain)
+ (reduce csm/interpret-schema-problem {})
+ (flatten-error-map)
+ (map (fn [[field message]]
+ (tr "plugins.validation.message" field message)))
+ (str/join ". "))]
+ ;; Return nil (not "") when the explain has no mappable errors, so
+ ;; `handle-error` can fall back to a non-empty message instead of
+ ;; surfacing a bare "Value not valid. Code: :error" (#9692).
+ (when-not (str/blank? msg) msg)))
(defn handle-error
"Function to be used in plugin proxies methods to handle errors and print a readable
@@ -340,8 +344,8 @@
(if explain
(do
(js/console.error (sm/humanize-explain explain))
- (error-messages explain))
- (ex-data cause))]
+ (or (error-messages explain) (pr-str explain)))
+ (or (ex-data cause) (ex-message cause) (str cause)))]
(js/console.log (.-stack cause))
(not-valid plugin-id :error message))))))
diff --git a/frontend/src/app/render_wasm/api.cljs b/frontend/src/app/render_wasm/api.cljs
index 3ddf63d3d9..579eaa0ade 100644
--- a/frontend/src/app/render_wasm/api.cljs
+++ b/frontend/src/app/render_wasm/api.cljs
@@ -1423,18 +1423,20 @@
(set-shape-layout shape)
(set-layout-data shape)
(let [is-text? (= type :text)
- pending_thumbnails (into [] (concat
- (when is-text? (set-shape-text-content id content))
+ text-content-pending (when is-text? (set-shape-text-content id content))
+ pending-thumbnails (into [] (concat
+ text-content-pending
(when is-text? (set-shape-text-images id content true))
(set-shape-fills id fills true)
(set-shape-strokes id strokes true)))
- pending_full (into [] (concat
+ pending-full (into [] (concat
(when is-text? (set-shape-text-images id content false))
(set-shape-fills id fills false)
(set-shape-strokes id strokes false)))]
(perf/end-measure "set-object")
- {:thumbnails pending_thumbnails
- :full pending_full}))))
+ {:thumbnails pending-thumbnails
+ :full pending-full
+ :font-pending-ids (if (some :callback text-content-pending) [id] [])}))))
(defn- update-text-layouts
"Synchronously update text layouts for all shapes and send rect updates
@@ -1442,8 +1444,29 @@
[text-ids]
(run! f/update-text-layout text-ids))
+(defn- force-update-text-layouts
+ "Like update-text-layouts but forces a relayout. Use after pending fonts
+ resolve so layouts (and the extrect/tiles derived from them) use real glyph
+ metrics instead of fallback-font estimates."
+ [text-ids]
+ (run! f/force-update-text-layout text-ids))
+
+(defn- relayout-after-fonts!
+ "Relayout text shapes once their pending fonts have resolved. Shapes in
+ `font-pending-ids` had a font fetched, so they get a forced relayout to pick
+ up the real glyph metrics; the remaining text shapes get a normal layout."
+ [shapes font-pending-ids]
+ (let [force-ids (set font-pending-ids)
+ text-ids (into [] (comp (filter cfh/text-shape?) (map :id)) shapes)
+ forced (filterv force-ids text-ids)
+ rest-ids (filterv (complement force-ids) text-ids)]
+ (when (seq forced)
+ (force-update-text-layouts forced))
+ (when (seq rest-ids)
+ (update-text-layouts rest-ids))))
+
(defn process-pending
- [shapes thumbnails full on-complete]
+ [shapes thumbnails full font-pending-ids on-complete]
(let [pending-thumbnails
(d/index-by :key :callback thumbnails)
@@ -1467,11 +1490,7 @@
(rx/catch #(rx/empty))))
(rx/subs!
(fn [_]
- ;; Fonts are now loaded — recompute text layouts so Skia
- ;; uses the real metrics instead of fallback-font estimates.
- (let [text-ids (into [] (comp (filter cfh/text-shape?) (map :id)) shapes)]
- (when (seq text-ids)
- (update-text-layouts text-ids)))
+ (relayout-after-fonts! shapes font-pending-ids)
(request-render "images-loaded"))
noop-fn
(fn [] (when (fn? on-complete) (on-complete)))))
@@ -1480,8 +1499,8 @@
(defn process-object
[shape]
- (let [{:keys [thumbnails full]} (set-object shape)]
- (process-pending [shape] thumbnails full noop-fn)))
+ (let [{:keys [thumbnails full font-pending-ids]} (set-object shape)]
+ (process-pending [shape] thumbnails full font-pending-ids noop-fn)))
(defn process-objects
"Like process-object but for multiple shapes at once. Accumulates all
@@ -1490,37 +1509,43 @@
just the first shape that triggered the fetch."
[shapes]
(let [total-shapes (count shapes)
- {:keys [thumbnails full]}
- (loop [index 0 thumbnails-acc (transient []) full-acc (transient [])]
+ {:keys [thumbnails full font-pending-ids]}
+ (loop [index 0 thumbnails-acc (transient []) full-acc (transient []) font-acc (transient [])]
(if (< index total-shapes)
(let [shape (nth shapes index)
- {:keys [thumbnails full]} (set-object shape)]
+ {:keys [thumbnails full font-pending-ids]} (set-object shape)]
(recur (inc index)
(reduce conj! thumbnails-acc thumbnails)
- (reduce conj! full-acc full)))
- {:thumbnails (persistent! thumbnails-acc) :full (persistent! full-acc)}))]
- (process-pending shapes thumbnails full noop-fn)))
+ (reduce conj! full-acc full)
+ (reduce conj! font-acc font-pending-ids)))
+ {:thumbnails (persistent! thumbnails-acc)
+ :full (persistent! full-acc)
+ :font-pending-ids (persistent! font-acc)}))]
+ (process-pending shapes thumbnails full font-pending-ids noop-fn)))
(defn- process-shapes-chunk
"Process shapes starting at `start-index` until the time budget is exhausted.
- Returns {:thumbnails [...] :full [...] :next-index n}"
- [shapes start-index thumbnails-acc full-acc]
+ Returns {:thumbnails [...] :full [...] :font-pending-ids [...] :next-index n}"
+ [shapes start-index thumbnails-acc full-acc font-pending-acc]
(let [total (count shapes)
deadline (+ (js/performance.now) CHUNK_TIME_BUDGET_MS)]
(loop [index start-index
t-acc (transient thumbnails-acc)
- f-acc (transient full-acc)]
+ f-acc (transient full-acc)
+ fp-acc (transient font-pending-acc)]
(if (and (< index total)
;; Check performance.now every 8 shapes to reduce overhead
(or (pos? (bit-and (- index start-index) 7))
(<= (js/performance.now) deadline)))
(let [shape (nth shapes index)
- {:keys [thumbnails full]} (set-object shape)]
+ {:keys [thumbnails full font-pending-ids]} (set-object shape)]
(recur (inc index)
(reduce conj! t-acc thumbnails)
- (reduce conj! f-acc full)))
+ (reduce conj! f-acc full)
+ (reduce conj! fp-acc font-pending-ids)))
{:thumbnails (persistent! t-acc)
:full (persistent! f-acc)
+ :font-pending-ids (persistent! fp-acc)
:next-index index}))))
(defn- set-objects-async
@@ -1531,16 +1556,16 @@
(let [total-shapes (count shapes)]
(p/create
(fn [resolve _reject]
- (letfn [(process-next-chunk [index thumbnails-acc full-acc]
+ (letfn [(process-next-chunk [index thumbnails-acc full-acc font-pending-acc]
(if (< index total-shapes)
;; Process one time-budgeted chunk
- (let [{:keys [thumbnails full next-index]}
+ (let [{:keys [thumbnails full font-pending-ids next-index]}
(process-shapes-chunk shapes index
- thumbnails-acc full-acc)]
+ thumbnails-acc full-acc font-pending-acc)]
;; Yield to browser, then continue with next chunk
(-> (yield-to-browser)
(p/then (fn [_]
- (process-next-chunk next-index thumbnails full)))))
+ (process-next-chunk next-index thumbnails full font-pending-ids)))))
;; All chunks done - finalize
(do
(perf/end-measure "set-objects")
@@ -1587,13 +1612,11 @@
(rx/reduce conj [])))
(rx/subs!
(fn [_]
- (let [text-ids (into [] (comp (filter cfh/text-shape?) (map :id)) shapes)]
- (when (seq text-ids)
- (update-text-layouts text-ids)))
+ (relayout-after-fonts! shapes font-pending-acc)
(request-render "images-loaded"))
noop-fn
noop-fn)))))))]
- (process-next-chunk 0 [] []))))))
+ (process-next-chunk 0 [] [] []))))))
;; This is a version of process-pending that doesn't have sideffects
@@ -1646,22 +1669,25 @@
"Synchronously process all shapes (for small shape counts)."
[shapes render-callback on-shapes-ready]
(let [total-shapes (count shapes)
- {:keys [thumbnails full]}
- (loop [index 0 thumbnails-acc (transient []) full-acc (transient [])]
+ {:keys [thumbnails full font-pending-ids]}
+ (loop [index 0 thumbnails-acc (transient []) full-acc (transient []) font-acc (transient [])]
(if (< index total-shapes)
(let [shape (nth shapes index)
- {:keys [thumbnails full]} (set-object shape)]
+ {:keys [thumbnails full font-pending-ids]} (set-object shape)]
(recur (inc index)
(reduce conj! thumbnails-acc thumbnails)
- (reduce conj! full-acc full)))
- {:thumbnails (persistent! thumbnails-acc) :full (persistent! full-acc)}))]
+ (reduce conj! full-acc full)
+ (reduce conj! font-acc font-pending-ids)))
+ {:thumbnails (persistent! thumbnails-acc)
+ :full (persistent! full-acc)
+ :font-pending-ids (persistent! font-acc)}))]
(perf/end-measure "set-objects")
(when on-shapes-ready (on-shapes-ready))
;; Rebuild the tile index so _render knows which shapes
;; map to which tiles after a page switch.
(h/call wasm/internal-module "_set_view_end")
(reset! view-interaction-active? false)
- (process-pending shapes thumbnails full
+ (process-pending shapes thumbnails full font-pending-ids
(fn []
(if render-callback
(render-callback)
diff --git a/frontend/src/app/render_wasm/api/fonts.cljs b/frontend/src/app/render_wasm/api/fonts.cljs
index 676a00cf78..86946db5ba 100644
--- a/frontend/src/app/render_wasm/api/fonts.cljs
+++ b/frontend/src/app/render_wasm/api/fonts.cljs
@@ -119,6 +119,16 @@
(aget shape-id-buffer 2)
(aget shape-id-buffer 3)))))
+(defn force-update-text-layout
+ [id]
+ (when wasm/context-initialized?
+ (let [shape-id-buffer (uuid/get-u32 id)]
+ (h/call wasm/internal-module "_force_update_shape_text_layout_for"
+ (aget shape-id-buffer 0)
+ (aget shape-id-buffer 1)
+ (aget shape-id-buffer 2)
+ (aget shape-id-buffer 3)))))
+
;; IMPORTANT: Only TTF fonts can be stored.
(defn- store-font-buffer
[font-data font-array-buffer emoji? fallback?]
diff --git a/frontend/src/app/render_wasm/shape.cljs b/frontend/src/app/render_wasm/shape.cljs
index feed61d674..403a1314ee 100644
--- a/frontend/src/app/render_wasm/shape.cljs
+++ b/frontend/src/app/render_wasm/shape.cljs
@@ -250,13 +250,15 @@
(api/set-shape-svg-raw-content (api/get-static-markup shape))
(cfh/text-shape? shape)
- (let [pending-thumbnails (into [] (concat (api/set-shape-text-content id v)))
- pending-full (into [] (concat (api/set-shape-text-images id v)))]
+ (let [text-content-pending (api/set-shape-text-content id v)
+ pending-thumbnails (vec text-content-pending)
+ pending-full (vec (api/set-shape-text-images id v))
+ font-pending-ids (when (some :callback text-content-pending) [id])]
;; FIXME: this is a hack to process the pending tasks
;; asynchronously we should probably modify set-wasm-attr!
;; to return a list of callbacks to be executed in a
;; second pass.
- (api/process-pending [shape] pending-thumbnails pending-full api/noop-fn)
+ (api/process-pending [shape] pending-thumbnails pending-full font-pending-ids api/noop-fn)
nil))
:grow-type
diff --git a/frontend/src/app/util/text/content/from_dom.cljs b/frontend/src/app/util/text/content/from_dom.cljs
index 7b56b014c1..19d0293287 100644
--- a/frontend/src/app/util/text/content/from_dom.cljs
+++ b/frontend/src/app/util/text/content/from_dom.cljs
@@ -42,8 +42,7 @@
(let [attrs (or attrs [])
value-empty? (fn [v]
(or (nil? v)
- (and (string? v) (empty? v))
- (and (coll? v) (empty? v))))]
+ (and (string? v) (empty? v))))]
(reduce (fn [acc key]
(let [style (.-style element)
value (if (contains? styles/mapping key)
diff --git a/frontend/stylelint.config.mjs b/frontend/stylelint.config.mjs
index d2a9c37097..903e1abb98 100644
--- a/frontend/stylelint.config.mjs
+++ b/frontend/stylelint.config.mjs
@@ -14,6 +14,12 @@ export default {
"at-rule-no-unknown": null,
"declaration-property-value-no-unknown": null,
"property-no-unknown": [true, { ignoreProperties: ["text-box"] }],
+ "declaration-block-no-redundant-longhand-properties": [
+ true,
+ {
+ ignoreShorthands: ["grid-template"],
+ },
+ ],
"selector-pseudo-class-no-unknown": [
true,
{ ignorePseudoClasses: ["global"] }, // TODO: Avoid global selector usage and remove this exception
diff --git a/frontend/test/frontend_tests/plugins/interactions_test.cljs b/frontend/test/frontend_tests/plugins/interactions_test.cljs
index 0afd39e05c..20c70fffda 100644
--- a/frontend/test/frontend_tests/plugins/interactions_test.cljs
+++ b/frontend/test/frontend_tests/plugins/interactions_test.cljs
@@ -11,7 +11,8 @@
[app.plugins.api :as api]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.state :as ths]
- [frontend-tests.helpers.wasm :as thw]))
+ [frontend-tests.helpers.wasm :as thw]
+ [potok.v2.core :as ptk]))
(defn- flows-of
"The vals of the current page flows from the store."
@@ -80,3 +81,27 @@
(.addInteraction board1 "click" #js {:type "open-url" :url "https://example.com"})
(t/is (empty? (flows-of store context page))
"open-url interactions do not create a flow"))))))
+
+(def ^:private plugin-id "00000000-0000-0000-0000-000000000000")
+
+(defn- throws?
+ [thunk]
+ (try (thunk) false (catch :default _ true)))
+
+(t/deftest interaction-delay-accepts-zero
+ ;; Regression: the InteractionProxy `:delay` setter rejected 0 via
+ ;; `(not (pos? value))`, but the model (`set-delay` -> `check-safe-int`) allows
+ ;; 0 (an immediate after-delay interaction). With `throwValidationErrors`
+ ;; enabled, setting 0 must NOT throw (its validation guard passes), while a
+ ;; negative value must still be rejected.
+ (thw/with-wasm-mocks*
+ (fn []
+ (let [store (ths/setup-store (cthf/sample-file :file1 :page-label :page1))
+ ^js context (api/create-context plugin-id)
+ _ (set! st/state store)
+ ^js board1 (.createBoard context)
+ ^js board2 (.createBoard context)
+ ^js inter (.addInteraction board1 "after-delay" #js {:type "navigate-to" :destination board2} 300)]
+ (ptk/emit! store #(assoc-in % [:plugins :flags plugin-id :throw-validation-errors] true))
+ (t/is (not (throws? #(set! (.-delay inter) 0))) "delay = 0 must be accepted")
+ (t/is (throws? #(set! (.-delay inter) -1)) "negative delay must be rejected")))))
diff --git a/frontend/test/frontend_tests/plugins/page_active_validation_test.cljs b/frontend/test/frontend_tests/plugins/page_active_validation_test.cljs
index 5b36691404..6f3651e81a 100644
--- a/frontend/test/frontend_tests/plugins/page_active_validation_test.cljs
+++ b/frontend/test/frontend_tests/plugins/page_active_validation_test.cljs
@@ -269,3 +269,50 @@
(doseq [[label thunk] (setter-specs m)]
(t/is (not (throws? thunk)) (str label " must be allowed on the active page")))))))
+(t/deftest test-layout-gap-padding-accepts-fractional-values
+ ;; Regression: the flex/grid gap and padding setters validated with
+ ;; `valid-safe-int?`, but the layout model types `:row-gap`/`:column-gap` and
+ ;; `:p1`-`:p4` as `safe-number` (and the sidebar accepts decimals), so a
+ ;; fractional value was wrongly rejected. With `throwValidationErrors` on (set
+ ;; by `setup`) and page2 active, a fractional value must be accepted (no throw).
+ (thw/with-wasm-mocks*
+ (fn []
+ (let [{:keys [store page2-id ^js flex ^js grid]} (setup)]
+ (activate-page! store page2-id)
+ (doseq [[label thunk]
+ [["flex.rowGap" #(set! (.-rowGap flex) 10.5)]
+ ["flex.columnGap" #(set! (.-columnGap flex) 3.25)]
+ ["flex.verticalPadding" #(set! (.-verticalPadding flex) 4.5)]
+ ["flex.horizontalPadding" #(set! (.-horizontalPadding flex) 4.5)]
+ ["flex.topPadding" #(set! (.-topPadding flex) 1.5)]
+ ["flex.rightPadding" #(set! (.-rightPadding flex) 1.5)]
+ ["flex.bottomPadding" #(set! (.-bottomPadding flex) 1.5)]
+ ["flex.leftPadding" #(set! (.-leftPadding flex) 1.5)]
+ ["grid.rowGap" #(set! (.-rowGap grid) 7.5)]
+ ["grid.columnGap" #(set! (.-columnGap grid) 2.25)]
+ ["grid.verticalPadding" #(set! (.-verticalPadding grid) 4.5)]
+ ["grid.horizontalPadding" #(set! (.-horizontalPadding grid) 4.5)]
+ ["grid.topPadding" #(set! (.-topPadding grid) 1.5)]
+ ["grid.rightPadding" #(set! (.-rightPadding grid) 1.5)]
+ ["grid.bottomPadding" #(set! (.-bottomPadding grid) 1.5)]
+ ["grid.leftPadding" #(set! (.-leftPadding grid) 1.5)]]]
+ (t/is (not (throws? thunk)) (str label " must accept a fractional value")))))))
+
+(t/deftest test-border-radius-accepts-fractional-values
+ ;; Regression: the ShapeProxy borderRadius setters validated with
+ ;; `valid-safe-int?`, but the model types `:r1`-`:r4` as `safe-number` (and the
+ ;; radius sidebar input has min 0, not integer-only), so a fractional radius was
+ ;; wrongly rejected. With `throwValidationErrors` on and page2 active, a
+ ;; fractional radius must be accepted (no throw).
+ (thw/with-wasm-mocks*
+ (fn []
+ (let [{:keys [store page2-id ^js rect]} (setup)]
+ (activate-page! store page2-id)
+ (doseq [[label thunk]
+ [["borderRadius" #(set! (.-borderRadius rect) 7.5)]
+ ["borderRadiusTopLeft" #(set! (.-borderRadiusTopLeft rect) 2.5)]
+ ["borderRadiusTopRight" #(set! (.-borderRadiusTopRight rect) 2.5)]
+ ["borderRadiusBottomRight" #(set! (.-borderRadiusBottomRight rect) 2.5)]
+ ["borderRadiusBottomLeft" #(set! (.-borderRadiusBottomLeft rect) 2.5)]]]
+ (t/is (not (throws? thunk)) (str label " must accept a fractional value")))))))
+
diff --git a/frontend/test/frontend_tests/plugins/parser_test.cljs b/frontend/test/frontend_tests/plugins/parser_test.cljs
index 44abb8ebbd..e6f78c185f 100644
--- a/frontend/test/frontend_tests/plugins/parser_test.cljs
+++ b/frontend/test/frontend_tests/plugins/parser_test.cljs
@@ -7,9 +7,31 @@
(ns frontend-tests.plugins.parser-test
(:require
[app.common.geom.point :as gpt]
+ [app.common.schema :as sm]
+ [app.common.types.grid :as ctg]
+ [app.common.types.shape.interactions :as ctsi]
+ [app.common.uuid :as uuid]
[app.plugins.parser :as parser]
[cljs.test :as t :include-macros true]))
+(defn- overlay-action
+ [{:keys [type destination position manual-position-location]}]
+ (let [action (js-obj "type" type
+ "destination" (js-obj "$id" destination))]
+ (when (some? position)
+ (unchecked-set action "position" position))
+ (when (some? manual-position-location)
+ (unchecked-set action "manualPositionLocation" manual-position-location))
+ action))
+
+(defn- parse-overlay-interaction
+ [action]
+ (parser/parse-interaction "click" (overlay-action action) nil))
+
+(defn- valid-interaction?
+ [interaction]
+ (sm/validate ctsi/schema:interaction interaction))
+
(t/deftest test-parse-point-returns-gpt-point-record
;; Regression test for issue #8409.
;;
@@ -32,18 +54,6 @@
(t/is (= 0 (:x result)))
(t/is (= 0 (:y result))))))
-(t/deftest test-parse-overlay-action-defaults-manual-position
- (let [destination #js {"$id" (random-uuid)}
- action (parser/parse-action
- #js {:type "open-overlay"
- :destination destination
- :position "center"})]
- (t/is (= :open-overlay (:action-type action)))
- (t/is (= :center (:overlay-pos-type action)))
- (t/is (gpt/point? (:overlay-position action)))
- (t/is (= 0 (:x (:overlay-position action))))
- (t/is (= 0 (:y (:overlay-position action))))))
-
(t/deftest test-parse-frame-guide-calls-guide-parser
(let [column (parser/parse-frame-guide
#js {:type "column"
@@ -61,3 +71,105 @@
(t/is (= :row (:type row)))
(t/is (= false (:display row)))
(t/is (= :center (get-in row [:params :type])))))
+
+(t/deftest test-parse-frame-guides
+ ;; Regression test for issue #9773.
+ ;;
+ ;; `parse-frame-guide` returned the parser fns for column/row instead of
+ ;; calling them with the guide, and the `board.guides` setter validated
+ ;; against an unregistered `::ctg/grid` reference (now `ctg/schema:grid`).
+ ;; Parsed guides must be plain maps that validate against the same direct
+ ;; schema the setter uses, and clearing (empty input) must validate too.
+ (let [column #js {:type "column" :display true
+ :params #js {:color #js {:color "#DE4762" :opacity 0.2}
+ :type "stretch" :size 12 :gutter 16 :margin 16}}
+ square #js {:type "square" :display true
+ :params #js {:color #js {:color "#DE4762" :opacity 0.2} :size 8}}
+ parsed (parser/parse-frame-guides #js [column square])]
+ (t/is (= :column (-> parsed first :type)))
+ (t/is (= :square (-> parsed second :type)))
+ (t/is (map? (-> parsed first :params)))
+ (t/is (sm/validate [:vector ctg/schema:grid] parsed)))
+
+ (t/testing "clearing guides with an empty vector validates"
+ (t/is (sm/validate [:vector ctg/schema:grid] (parser/parse-frame-guides #js [])))))
+
+(t/deftest test-parse-overlay-action-position-is-optional
+ (t/testing "open-overlay defaults omitted position to center"
+ (let [destination (uuid/next)
+ result (parse-overlay-interaction {:type "open-overlay"
+ :destination destination})]
+ (t/is (= :open-overlay (:action-type result)))
+ (t/is (= :click (:event-type result)))
+ (t/is (= destination (:destination result)))
+ (t/is (= :center (:overlay-pos-type result)))
+ (t/is (not (contains? result :overlay-position)))
+ (t/is (valid-interaction? result))))
+
+ (t/testing "toggle-overlay preserves manualPositionLocation"
+ (let [destination (uuid/next)
+ result (parse-overlay-interaction
+ {:type "toggle-overlay"
+ :destination destination
+ :position "manual"
+ :manual-position-location #js {:x 10 :y 20}})
+ position (:overlay-position result)]
+ (t/is (= :toggle-overlay (:action-type result)))
+ (t/is (= :manual (:overlay-pos-type result)))
+ (t/is (gpt/point? position))
+ (t/is (= 10 (:x position)))
+ (t/is (= 20 (:y position)))
+ (t/is (valid-interaction? result))))
+
+ (t/testing "explicit center position does not require manualPositionLocation"
+ (let [destination (uuid/next)
+ result (parse-overlay-interaction {:type "open-overlay"
+ :destination destination
+ :position "center"})]
+ (t/is (= :center (:overlay-pos-type result)))
+ (t/is (not (contains? result :overlay-position)))
+ (t/is (valid-interaction? result))))
+
+ (t/testing "manual position without manualPositionLocation still parses"
+ (let [destination (uuid/next)
+ result (parse-overlay-interaction {:type "open-overlay"
+ :destination destination
+ :position "manual"})]
+ (t/is (= :manual (:overlay-pos-type result)))
+ (t/is (not (contains? result :overlay-position)))
+ (t/is (valid-interaction? result)))))
+
+(t/deftest test-parse-close-overlay-without-animation-validates
+ (t/testing "close-overlay without animation parses and validates"
+ (let [result (parser/parse-interaction "click" #js {:type "close-overlay"} nil)]
+ (t/is (= {:event-type :click
+ :action-type :close-overlay}
+ result))
+ (t/is (false? (contains? result :animation)))
+ (t/is (true? (sm/validate ctsi/schema:interaction result)))))
+
+ (t/testing "close-overlay preserves destination without animation"
+ (let [destination-id (uuid/next)
+ result (parser/parse-interaction
+ "click"
+ #js {:type "close-overlay"
+ :destination #js {"$id" destination-id}}
+ nil)]
+ (t/is (= destination-id (:destination result)))
+ (t/is (false? (contains? result :animation)))
+ (t/is (true? (sm/validate ctsi/schema:interaction result)))))
+
+ (t/testing "close-overlay preserves an explicit dissolve animation"
+ (let [result (parser/parse-interaction
+ "click"
+ #js {:type "close-overlay"
+ :animation #js {:type "dissolve"
+ :duration 300
+ :easing "linear"}}
+ nil)]
+ (t/is (= {:animation-type :dissolve
+ :duration 300
+ :easing :linear}
+ (:animation result)))
+ (t/is (true? (sm/validate ctsi/schema:interaction result))))))
+
diff --git a/frontend/test/frontend_tests/plugins/tokens_test.cljs b/frontend/test/frontend_tests/plugins/tokens_test.cljs
index f95ba1d811..fe04a6a5e3 100644
--- a/frontend/test/frontend_tests/plugins/tokens_test.cljs
+++ b/frontend/test/frontend_tests/plugins/tokens_test.cljs
@@ -11,6 +11,7 @@
[app.common.test-helpers.ids-map :as cthi]
[app.common.test-helpers.tokens :as ctht]
[app.common.types.tokens-lib :as ctob]
+ [app.common.uuid :as uuid]
[app.main.data.tokenscript :as ts]
[app.main.data.workspace.tokens.library-edit :as dwtl]
[app.main.store :as st]
@@ -338,3 +339,66 @@
result (get-resolved-value token {(:name token) token})]
(t/is (array? result))
(t/is (= ["Inter" "Arial"] (vec result)))))
+
+(t/deftest token-theme-add-set-accepts-token-set-id
+ (let [plugin-id "plugin-id"
+ file-id (uuid/next)
+ theme-id (uuid/next)
+ set-id (uuid/next)
+ token-set (ctob/make-token-set :id set-id :name "Core")
+ theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
+ emitted (atom [])
+ invalid (atom [])]
+ (with-redefs [u/locate-token-set (fn [_ id] (when (= id set-id) token-set))
+ u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
+ u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
+ dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
+ st/emit! (fn ([event] (swap! emitted conj event) nil)
+ ([event & _] (swap! emitted conj event) nil))]
+ (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)]
+ (.addSet theme-proxy (str set-id))
+ (t/is (= #{"Core"} (-> @emitted first :theme :sets)))
+ (t/is (empty? @invalid))))))
+
+(t/deftest token-theme-add-set-accepts-token-set-proxy
+ (let [plugin-id "plugin-id"
+ file-id (uuid/next)
+ theme-id (uuid/next)
+ set-id (uuid/next)
+ token-set (ctob/make-token-set :id set-id :name "Core")
+ theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
+ emitted (atom [])
+ invalid (atom [])]
+ (with-redefs [u/locate-token-set (fn [_ id] (when (= id set-id) token-set))
+ u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
+ u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
+ dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
+ st/emit! (fn ([event] (swap! emitted conj event) nil)
+ ([event & _] (swap! emitted conj event) nil))]
+ (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)
+ set-proxy (ptok/token-set-proxy plugin-id file-id set-id "Core")]
+ (.addSet theme-proxy set-proxy)
+ (t/is (= #{"Core"} (-> @emitted first :theme :sets)))
+ (t/is (empty? @invalid))))))
+
+(t/deftest token-theme-add-set-rejects-invalid-arguments
+ (let [plugin-id "plugin-id"
+ file-id (uuid/next)
+ theme-id (uuid/next)
+ theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
+ emitted (atom [])
+ invalid (atom [])]
+ (with-redefs [u/locate-token-set (constantly nil)
+ u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
+ u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
+ dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
+ st/emit! (fn ([event] (swap! emitted conj event) nil)
+ ([event & _] (swap! emitted conj event) nil))]
+ (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)]
+ ;; Non-id, non-proxy arguments are rejected by the schema coercer.
+ (.addSet theme-proxy 42)
+ (.removeSet theme-proxy nil)
+ (t/is (empty? @emitted))
+ (t/is (= 2 (count @invalid)))
+ (t/is (every? #(= :error (first %)) @invalid))))))
+
diff --git a/frontend/test/frontend_tests/plugins/utils_test.cljs b/frontend/test/frontend_tests/plugins/utils_test.cljs
index 8fbf4e4f40..a2a1e98124 100644
--- a/frontend/test/frontend_tests/plugins/utils_test.cljs
+++ b/frontend/test/frontend_tests/plugins/utils_test.cljs
@@ -54,3 +54,36 @@
;; No validation errors -> no output (callers join with ". " and would
;; otherwise emit an empty string, which is fine).
(t/is (empty? (flatten-error-map {}))))
+
+;; ---------------------------------------------------------------------
+;; Issue #9692 — `handle-error` must surface a useful message instead of a
+;; bare "Value not valid. Code: :error".
+;;
+;; `not-valid` is redefined to capture the rendered message directly, so the
+;; assertions don't depend on `st/state` or the console.
+
+(t/deftest test-handle-error-plain-js-error
+ ;; A plain JS error has no `::sm/explain` and CLJS `ex-data` returns nil, so
+ ;; the handler must fall back to the error's own message rather than nil.
+ (let [captured (atom ::none)]
+ (with-redefs [plugins.utils/not-valid (fn [_plugin-id _code value]
+ (reset! captured value) nil)]
+ ((plugins.utils/handle-error #uuid "00000000-0000-0000-0000-000000000000")
+ (js/Error. "boom: not a function")))
+ (t/is (= "boom: not a function" @captured))))
+
+(t/deftest test-handle-error-empty-explain
+ ;; An explain whose errors don't render any message must not produce an
+ ;; empty string; the handler falls back to the raw explain.
+ (let [captured (atom ::none)
+ cause (ex-info "invalid" {:app.common.schema/explain {:errors [] :value 1}})]
+ (with-redefs [plugins.utils/not-valid (fn [_plugin-id _code value]
+ (reset! captured value) nil)]
+ ((plugins.utils/handle-error #uuid "00000000-0000-0000-0000-000000000000") cause))
+ (t/is (string? @captured))
+ (t/is (not= "" @captured))))
+
+(t/deftest test-error-messages-empty-returns-nil
+ ;; `error-messages` returns nil (not "") on an explain with no mappable
+ ;; errors, so `handle-error` can distinguish "no message" from a real one.
+ (t/is (nil? (plugins.utils/error-messages {:errors []}))))
diff --git a/frontend/test/frontend_tests/render_wasm/process_objects_test.cljs b/frontend/test/frontend_tests/render_wasm/process_objects_test.cljs
index 740029a3ca..c985b336ae 100644
--- a/frontend/test/frontend_tests/render_wasm/process_objects_test.cljs
+++ b/frontend/test/frontend_tests/render_wasm/process_objects_test.cljs
@@ -51,7 +51,7 @@
(let [shapes [(make-shape :text) (make-shape :text) (make-shape :rect)]
visited-ids (atom [])
mock-set (fn [s] (swap! visited-ids conj (:id s)) {:thumbnails [] :full []})
- mock-pend (fn [_sh _t _f _cb] nil)]
+ mock-pend (fn [_sh _t _f _fp _cb] nil)]
(with-mocks* mock-set mock-pend #(wasm.api/process-objects shapes))
@@ -66,7 +66,7 @@
(let [shapes [(make-shape :text) (make-shape :text)]
captured (atom nil)
mock-set (fn [_s] {:thumbnails [] :full []})
- mock-pend (fn [sh t f cb] (reset! captured {:shapes sh :thumbnails t :full f :cb cb}))]
+ mock-pend (fn [sh t f _fp cb] (reset! captured {:shapes sh :thumbnails t :full f :cb cb}))]
(with-mocks* mock-set mock-pend #(wasm.api/process-objects shapes))
@@ -99,7 +99,7 @@
{:thumbnails [] :full []}))
mock-pend
- (fn [sh t f _cb] (reset! captured {:shapes sh :thumbnails t :full f}))]
+ (fn [sh t f _fp _cb] (reset! captured {:shapes sh :thumbnails t :full f}))]
(with-mocks* mock-set mock-pend #(wasm.api/process-objects shapes))
diff --git a/frontend/text-editor/package.json b/frontend/text-editor/package.json
index 8a9bcaa5ea..c315c9e6c6 100644
--- a/frontend/text-editor/package.json
+++ b/frontend/text-editor/package.json
@@ -16,7 +16,7 @@
},
"devDependencies": {
"@playwright/test": "1.61.1",
- "@types/node": "^26.0.1",
+ "@types/node": "^26.1.0",
"@vitest/browser": "^4.1.9",
"@vitest/coverage-v8": "^4.1.9",
"@vitest/ui": "^4.1.9",
@@ -25,7 +25,7 @@
"jsdom": "^29.1.1",
"playwright": "1.61.1",
"prettier": "^3.9.4",
- "vite": "^8.1.1",
+ "vite": "^8.1.2",
"vitest": "^4.1.9"
},
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b"
diff --git a/frontend/translations/ar.po b/frontend/translations/ar.po
index 51bd3a79a7..218976a3f6 100644
--- a/frontend/translations/ar.po
+++ b/frontend/translations/ar.po
@@ -378,9 +378,8 @@ msgstr "صدّر التحديد"
msgid "dashboard.export-standard-multi"
msgstr "تحميل %s ملفات أساسية (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"ملف أو أكثر تريد تصديرهم يستخدمون مكتبات مشتركة. ماذا تريد أن تفعل في "
"أصولهم*؟"
diff --git a/frontend/translations/ca.po b/frontend/translations/ca.po
index 149ca31c3d..fd724a3a67 100644
--- a/frontend/translations/ca.po
+++ b/frontend/translations/ca.po
@@ -367,9 +367,8 @@ msgstr "Selecció d'exportació"
msgid "dashboard.export-standard-multi"
msgstr "Baixa %s fitxers estàndard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Un o més fitxers que voleu exportar utilitzen biblioteques compartides. Què "
"voleu fer amb els seus recursos*?"
diff --git a/frontend/translations/cs.po b/frontend/translations/cs.po
index 86ac2cac0d..78f269bf98 100644
--- a/frontend/translations/cs.po
+++ b/frontend/translations/cs.po
@@ -462,9 +462,8 @@ msgstr "Výběr exportu"
msgid "dashboard.export-standard-multi"
msgstr "Stáhnout %s soubory (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Jeden nebo více souborů, které chcete exportovat, používá sdílené knihovny. "
"Co chcete dělat s jejich položkami*?"
@@ -6309,9 +6308,6 @@ msgstr "Momentálně nemáte žádné motivy."
msgid "workspace.tokens.original-value"
msgstr "Původní hodnota: %s"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Reference není platná nebo není v žádné aktivní sadě"
#: src/app/main/data/workspace/tokens/warnings.cljs:15, src/app/main/data/workspace/tokens/warnings.cljs:19, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:59, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:87, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:105, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:296, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:489, src/app/main/ui/workspace/tokens/management/forms/controls/combobox.cljs:298, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:189, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:324, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:259, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:381, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:505, src/app/main/ui/workspace/tokens/management/token_pill.cljs:123
#, fuzzy
diff --git a/frontend/translations/de.po b/frontend/translations/de.po
index 51f87e31e4..b3b060cf94 100644
--- a/frontend/translations/de.po
+++ b/frontend/translations/de.po
@@ -589,9 +589,8 @@ msgstr "Auswahl exportieren"
msgid "dashboard.export-standard-multi"
msgstr "%s Standarddateien herunterladen (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Eine oder mehrere Dateien, die Sie exportieren möchten, verwenden geteilte "
"Bibliotheken. Was möchten Sie mit den Assets* aus diesen Bibliotheken "
@@ -1295,10 +1294,6 @@ msgstr "Keine Treffer gefunden."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Token-Liste öffnen"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} ist nicht Teil eines aktiven Sets oder ungültig."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Auth-Provider für dieses Profil nicht erlaubt"
@@ -7836,10 +7831,6 @@ msgstr "Innenabstände"
msgid "workspace.tokens.radius"
msgstr "Radius"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referenz ist ungültig oder befindet sich nicht in einem aktiven Set"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Geben Sie einen Typografie-Alias für diesen Token ein"
diff --git a/frontend/translations/en.po b/frontend/translations/en.po
index 0410ccc003..e5ea13f565 100644
--- a/frontend/translations/en.po
+++ b/frontend/translations/en.po
@@ -613,14 +613,7 @@ msgstr "Export selection"
msgid "dashboard.export-standard-multi"
msgstr "Download %s standard files (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
-msgstr ""
-"One or more files that you want to download are using shared libraries. "
-"What do you want to do with their assets*?"
-
-#: src/app/main/ui/dashboard/file_menu.cljs:267
+#: src/app/main/ui/dashboard/file_menu.cljs:266
msgid "dashboard.file-menu.delete-files-permanently-option"
msgid_plural "dashboard.file-menu.delete-files-permanently-option"
msgstr[0] "Delete file"
@@ -1471,7 +1464,7 @@ msgstr "Open token list"
#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} is not in any active set or has an invalid value."
+msgstr "{%s} token is not in any active set or has an invalid value."
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
@@ -2070,9 +2063,10 @@ msgid "feedback.type.issue"
msgstr "Issue"
#: src/app/main/ui/exports/files.cljs:131
-#, fuzzy
msgid "files-download-modal.description-1"
msgstr ""
+"One or more files that you want to download are using shared libraries. "
+"What do you want to do with their assets*?"
#: src/app/main/ui/exports/files.cljs:132
msgid "files-download-modal.description-2"
@@ -4480,10 +4474,6 @@ msgstr "Cancel subscription"
msgid "nitrate.subscription.settings.renew-with-code"
msgstr "Renew with activation code"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr "This token is not in any active set or has an invalid value."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "This page doesn't exist"
@@ -5026,7 +5016,12 @@ msgstr "Penpot"
#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:42, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:101, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:108
msgid "options.deleted-token"
-msgstr "This token does not exists or has been deleted."
+msgstr "This token does not exist or has been deleted."
+
+
+#: src/app/main/ui/ds/controls/utilities/token_field.cljs
+msgid "options.deleted-token-with-name"
+msgstr "{%s} token does not exist or has been deleted."
#: src/app/plugins/utils.cljs:318
msgid "plugins.validation.message"
@@ -9460,7 +9455,7 @@ msgstr "Radius"
#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
msgid "workspace.tokens.ref-not-valid"
-msgstr "Reference is not valid or is not in any active set"
+msgstr "Reference in {%s} is not valid or is not in any active set."
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
diff --git a/frontend/translations/es.po b/frontend/translations/es.po
index a24bd2d177..4f7f44f4fa 100644
--- a/frontend/translations/es.po
+++ b/frontend/translations/es.po
@@ -610,9 +610,8 @@ msgstr "Exportar selección"
msgid "dashboard.export-standard-multi"
msgstr "Descargar %s archivos estándar (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Uno o mas ficheros que quieres descargar usan librerias compartidas. ¿Qué "
"quieres hacer con los recursos*?"
@@ -4348,10 +4347,6 @@ msgstr "Cancelar subscripción"
msgid "nitrate.subscription.settings.renew-with-code"
msgstr "Renovar con código de activación"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr "Este token no está disponible en ningún set o tiene un valor inválido."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "Esta página no existe"
@@ -4897,6 +4892,10 @@ msgstr "Penpot"
msgid "options.deleted-token"
msgstr "Este token no existe o ha sido borrado."
+#: src/app/main/ui/ds/controls/utilities/token_field.cljs
+msgid "options.deleted-token-with-name"
+msgstr "El token {%s} no existe o ha sido borrado."
+
#: src/app/main/ui/auth/recovery.cljs:88
msgid "profile.recovery.go-to-login"
msgstr "Ir al login"
@@ -9165,7 +9164,7 @@ msgstr "Valor original: %s"
#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
msgid "workspace.tokens.ref-not-valid"
-msgstr "La referencia no es válida o no se encuentra en ningún set activo."
+msgstr "La referencia en {%s} no es válida o no se encuentra en ningún set activo."
#: src/app/main/ui/workspace/tokens/style_dictionary.cljs
#, unused
diff --git a/frontend/translations/es_419.po b/frontend/translations/es_419.po
index d9a2ad0ba6..442f318cff 100644
--- a/frontend/translations/es_419.po
+++ b/frontend/translations/es_419.po
@@ -375,9 +375,8 @@ msgstr "Selección de exportación"
msgid "dashboard.export-standard-multi"
msgstr "Descargar %s archivos estándar (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Uno o más archivos que desea exportar utilizan bibliotecas compartidas. "
"¿Qué quiere hacer con sus activos*?"
diff --git a/frontend/translations/eu.po b/frontend/translations/eu.po
index ceb1561952..4b4b47d0fe 100644
--- a/frontend/translations/eu.po
+++ b/frontend/translations/eu.po
@@ -360,9 +360,8 @@ msgstr "Esportatu aukeraketa"
msgid "dashboard.export-standard-multi"
msgstr "Deskargatu %s fitxategi estandar (.svn + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Esportatu nahi duzun fitxategi bat edo gehiagok partekatutako liburutegiak "
"darabiltzate. Zer egin nahi duzu baliabideekin*?"
diff --git a/frontend/translations/fa.po b/frontend/translations/fa.po
index 1968b53513..2ec56c1941 100644
--- a/frontend/translations/fa.po
+++ b/frontend/translations/fa.po
@@ -420,9 +420,8 @@ msgstr "انتخاب اکسپورت"
msgid "dashboard.export-standard-multi"
msgstr "دانلود %s عدد فایل های استاندارد (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"یک یا چند فایلی که میخواهید اکسپورت کنید از کتابخانههای مشترک استفاده "
"میکنند. با داراییهای آنها چه میخواهید بکنید*؟"
diff --git a/frontend/translations/fr.po b/frontend/translations/fr.po
index 45e41e1aee..78b9696558 100644
--- a/frontend/translations/fr.po
+++ b/frontend/translations/fr.po
@@ -588,9 +588,8 @@ msgstr "Exporter la sélection"
msgid "dashboard.export-standard-multi"
msgstr "Télécharger %s fichiers standard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Un ou plusieurs fichiers que vous souhaitez exporter utilisent des "
"bibliothèques partagées. Que voulez-vous faire avec leurs ressources ?"
@@ -1294,10 +1293,6 @@ msgstr "Aucune correspondance."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Ouvrir la liste des tokens"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} n'est pas disponible dans la collection ou le thème actif."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Le fournisseur d'authentification n'est pas autorisé pour ce profil"
@@ -8119,10 +8114,6 @@ msgstr "Marges intérieures"
msgid "workspace.tokens.radius"
msgstr "Rayons"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "La référence n'est pas valide ou n'est pas dans une collection active"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Entrer un alias de typographie pour un token"
diff --git a/frontend/translations/fr_CA.po b/frontend/translations/fr_CA.po
index 165f18fcf8..720ad09a06 100644
--- a/frontend/translations/fr_CA.po
+++ b/frontend/translations/fr_CA.po
@@ -616,9 +616,8 @@ msgstr "Exporter la sélection"
msgid "dashboard.export-standard-multi"
msgstr "Télécharger %s fichiers standard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Un ou plus des fichiers que tu veux télécharger utilisent une bibliothèque "
"partagée. Que veux-tu faire avec ces atouts*?"
@@ -1482,10 +1481,6 @@ msgstr "Aucun résultat trouvé."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Ouvrir la liste de tokens"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} n'est disponible dans aucune collection ou est invalide."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Fournisseur d'authentification non permis pour ce profil utilisateur"
@@ -4510,10 +4505,6 @@ msgstr "Annuler l'abonnement"
msgid "nitrate.subscription.settings.renew-with-code"
msgstr "Renouveler avec code d'activation"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr "Ce token n'est disponible dans aucun ensemble ou a une valeur invalide."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "Cette page n'existe pas"
@@ -9426,10 +9417,6 @@ msgstr "Marges intérieures"
msgid "workspace.tokens.radius"
msgstr "Rayon"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "La référence est invalide ou n'existe dans aucun ensemble actif"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Entrer un alias de token typographique"
diff --git a/frontend/translations/gl.po b/frontend/translations/gl.po
index d5dbed0d30..fcca7a664a 100644
--- a/frontend/translations/gl.po
+++ b/frontend/translations/gl.po
@@ -358,9 +358,8 @@ msgstr "Exportar selección"
msgid "dashboard.export-standard-multi"
msgstr "Descargar %s ficheiros estándar (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Un ou máis ficheiros dos que queres exportar usan bibliotecas compartidas. "
"Que queres facer cos recursos?"
diff --git a/frontend/translations/ha.po b/frontend/translations/ha.po
index 10c5b10399..ca57b49e82 100644
--- a/frontend/translations/ha.po
+++ b/frontend/translations/ha.po
@@ -351,9 +351,8 @@ msgstr "Fitar da zavi"
msgid "dashboard.export-standard-multi"
msgstr "Sauke %s cikakken kundi (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr "za ka iya fitar da kundi daya ko fiye ta hanyar tura taska. \"me \"*?"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:336
diff --git a/frontend/translations/he.po b/frontend/translations/he.po
index 9f91b1f22c..5e84585b67 100644
--- a/frontend/translations/he.po
+++ b/frontend/translations/he.po
@@ -561,9 +561,8 @@ msgstr "ייצוא הבחירה"
msgid "dashboard.export-standard-multi"
msgstr "הורדת %s קבצים תקניים (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"אחד או יותר מהקבצים שברצונך לייצא משתמשים בספריות משותפות. מה לעשות עם "
"המשאבים שלהן*?"
@@ -7994,10 +7993,6 @@ msgstr "ריפודים"
msgid "workspace.tokens.radius"
msgstr "רדיוס"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "ההפניה לא תקפה או שאינה באף סדרה פעילה"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "נא למלא כינוי לטיפוגרפיית אסימון"
diff --git a/frontend/translations/hi.po b/frontend/translations/hi.po
index f69af6749f..29f6f44f30 100644
--- a/frontend/translations/hi.po
+++ b/frontend/translations/hi.po
@@ -558,9 +558,8 @@ msgstr "निर्यात चयन"
msgid "dashboard.export-standard-multi"
msgstr "%s मानक फ़ाइलें डाउनलोड करें (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"एक या एक से अधिक फ़ाइलें जिन्हें आप निर्यात करना चाहते हैं, वे साझा की गई "
"लाइब्रेरीज़ का उपयोग कर रही हैं। आप उनके एसेट्स के साथ क्या करना चाहते हैं?"
@@ -7929,10 +7928,6 @@ msgstr "पैडिंग्स"
msgid "workspace.tokens.radius"
msgstr "त्रिज्या"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "संदर्भ मान्य नहीं है या किसी सक्रिय सेट में नहीं है"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "token टाइपोग्राफी उपनाम दर्ज करें"
diff --git a/frontend/translations/hr.po b/frontend/translations/hr.po
index 398e7df7ba..8b46f9df1b 100644
--- a/frontend/translations/hr.po
+++ b/frontend/translations/hr.po
@@ -461,9 +461,8 @@ msgstr "Izvezi odabir"
msgid "dashboard.export-standard-multi"
msgstr "Preuzmi %s standardne datoteke (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Jedna ili više datoteka koju želiš izvesti koristi zajedničke biblioteke. "
"Što želiš učiniti s njihovim stavkama*?"
@@ -6330,10 +6329,6 @@ msgstr "Trenutno nemate nijednu temu."
msgid "workspace.tokens.original-value"
msgstr "Izvorna vrijednost: %s"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referenca nije važeća ili nije ni u jednom aktivnom skupu"
-
#: src/app/main/data/workspace/tokens/warnings.cljs:15, src/app/main/data/workspace/tokens/warnings.cljs:19, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:59, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:87, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:105, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:296, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:489, src/app/main/ui/workspace/tokens/management/forms/controls/combobox.cljs:298, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:189, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:324, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:259, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:381, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:505, src/app/main/ui/workspace/tokens/management/token_pill.cljs:123
#, fuzzy
msgid "workspace.tokens.resolved-value"
diff --git a/frontend/translations/id.po b/frontend/translations/id.po
index b1696a7ed6..de7f6baf49 100644
--- a/frontend/translations/id.po
+++ b/frontend/translations/id.po
@@ -494,9 +494,8 @@ msgstr "Ekspor pilihan"
msgid "dashboard.export-standard-multi"
msgstr "Unduh %s berkas standar (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Satu atau lebih berkas yang ingin Anda ekspor menggunakan pustaka bersama. "
"Apa yang ingin Anda lakukan dengan asetnya*?"
@@ -6675,10 +6674,6 @@ msgstr "Padding"
msgid "workspace.tokens.radius"
msgstr "Radius"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referensi tidak valid atau tidak dalam set aktif mana pun"
-
#: src/app/main/ui/workspace/tokens/style_dictionary.cljs
#, unused
msgid "workspace.tokens.reference-error"
diff --git a/frontend/translations/it.po b/frontend/translations/it.po
index 2fbab4a7e8..227eb4e24f 100644
--- a/frontend/translations/it.po
+++ b/frontend/translations/it.po
@@ -615,9 +615,8 @@ msgstr "Esporta selezionati"
msgid "dashboard.export-standard-multi"
msgstr "Scarica %s file standard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Uno o più file che desideri scaricare utilizzano librerie condivise. Che "
"cosa desideri fare con le loro risorse*?"
@@ -1485,10 +1484,6 @@ msgstr "Nessuna corrispondenza trovata."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Apri elenco token"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} non è disponibile in nessun set o tema attivo."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Provider di autenticazione non consentito per questo profilo"
@@ -4041,10 +4036,6 @@ msgstr ""
msgid "modals.update-remote-component.message"
msgstr "Aggiorna un componente in una libreria condivisa"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr "Questo token non è presente in alcun set attivo o ha un valore non valido."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "Questa pagina non esiste"
@@ -8543,10 +8534,6 @@ msgstr "Padding"
msgid "workspace.tokens.radius"
msgstr "Raggio"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Il riferimento non è valido o non è presente in nessun set attivo"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Inserisci un alias tipografico del token"
diff --git a/frontend/translations/ko.po b/frontend/translations/ko.po
index 2c2ceb3199..c2af51bf67 100644
--- a/frontend/translations/ko.po
+++ b/frontend/translations/ko.po
@@ -554,10 +554,11 @@ msgstr "선택 영역 내보내기"
msgid "dashboard.export-standard-multi"
msgstr "표준 파일 %s개(.svg + .json) 다운로드"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
-msgstr "다운로드하려는 하나 이상의 파일이 공유 라이브러리를 사용 중입니다. 해당 에셋*을 어떻게 처리하시겠습니까?"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
+msgstr ""
+"다운로드하려는 하나 이상의 파일이 공유 라이브러리를 사용 중입니다. 해당 에셋*"
+"을 어떻게 처리하시겠습니까?"
#: src/app/main/ui/dashboard/file_menu.cljs:267
msgid "dashboard.file-menu.delete-files-permanently-option"
@@ -1225,10 +1226,6 @@ msgstr "일치하는 항목이 없습니다."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "token 목록 열기"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "이 token은 활성 세트에 없거나 유효하지 않은 값을 가지고 있습니다."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "이 프로필에 허용되지 않는 인증 제공자입니다"
@@ -7713,10 +7710,6 @@ msgstr "패딩"
msgid "workspace.tokens.radius"
msgstr "반지름"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "참조가 유효하지 않거나 활성 세트에 없습니다"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "타이포그래피 token 별칭 입력"
diff --git a/frontend/translations/lt.po b/frontend/translations/lt.po
index a04ebba88a..fc5b5c047e 100644
--- a/frontend/translations/lt.po
+++ b/frontend/translations/lt.po
@@ -334,9 +334,8 @@ msgstr "Nėra elementų su eksporto nustatymais."
msgid "dashboard.export-shapes.title"
msgstr "Eksportuoti pažymėtą sritį"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Viename ar keliuose failuose, kuriuos norite eksportuoti, naudojamos "
"bendros bibliotekos. Ką norite daryti su jų komponentais*?"
diff --git a/frontend/translations/lv.po b/frontend/translations/lv.po
index d6079c624b..2e5e4baab6 100644
--- a/frontend/translations/lv.po
+++ b/frontend/translations/lv.po
@@ -507,9 +507,8 @@ msgstr "Izgūt atlasi"
msgid "dashboard.export-standard-multi"
msgstr "Lejupielādēt %s standarta datnes (. svg +. json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Viena vai vairākas lejupielādējamās datnes izmanto koplietojamas "
"bibliotēkas. Ko iesākt ar to līdzekļiem*?"
@@ -7476,10 +7475,6 @@ msgstr "Atbīdes"
msgid "workspace.tokens.radius"
msgstr "Rādiuss"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Atsauce nav derīga vai tā nav nevienā aktīvā kopā"
-
#: src/app/main/ui/workspace/tokens/style_dictionary.cljs
#, unused
msgid "workspace.tokens.reference-error"
diff --git a/frontend/translations/ms.po b/frontend/translations/ms.po
index caae11a549..d15d2f2adc 100644
--- a/frontend/translations/ms.po
+++ b/frontend/translations/ms.po
@@ -357,9 +357,8 @@ msgstr "Eksport Pemilihan"
msgid "dashboard.export-standard-multi"
msgstr "Muat turun %s fail standard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Satu atau lebih fail yang anda ingin eksport menggunakan perpustakaan "
"kongsi. Apa yang anda mahu lakukan dengan aset mereka*?"
diff --git a/frontend/translations/nl.po b/frontend/translations/nl.po
index 24c6f0ffda..087c65a440 100644
--- a/frontend/translations/nl.po
+++ b/frontend/translations/nl.po
@@ -585,9 +585,8 @@ msgstr "Selectie exporteren"
msgid "dashboard.export-standard-multi"
msgstr "%s standaardbestanden downloaden (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Een of meer bestanden die je wilt downloaden maken gebruik van gedeelde "
"bibliotheken. Wat wil je doen met hun assets*?"
@@ -1283,10 +1282,6 @@ msgstr "Geen overeenkomsten gevonden."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Lijst met tokens openen"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} is niet beschikbaar in een actieve verzameling of thema."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Auth-provider is niet toegestaan voor dit profiel"
@@ -8125,10 +8120,6 @@ msgstr "Vulling"
msgid "workspace.tokens.radius"
msgstr "Radius"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referentie is niet geldig of zit niet in een actieve verzameling"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Voer een alias voor tokentypografie in"
diff --git a/frontend/translations/pl.po b/frontend/translations/pl.po
index 21b2e84772..982243749b 100644
--- a/frontend/translations/pl.po
+++ b/frontend/translations/pl.po
@@ -362,9 +362,8 @@ msgstr "Eksportuj wybrane"
msgid "dashboard.export-standard-multi"
msgstr "Pobierz %s plików standardowych (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Co najmniej jeden plik, który chcesz wyeksportować, korzysta z bibliotek "
"udostępnionych. Co chcesz zrobić z ich zasobami*?"
diff --git a/frontend/translations/pt_BR.po b/frontend/translations/pt_BR.po
index 5a179dc418..9563253ed1 100644
--- a/frontend/translations/pt_BR.po
+++ b/frontend/translations/pt_BR.po
@@ -497,9 +497,8 @@ msgstr "Exportar seleção"
msgid "dashboard.export-standard-multi"
msgstr "Baixar %s arquivos padrões (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Um ou mais arquivos que você deseja exportar estão usando bibliotecas "
"compartilhadas. O que você quer fazer com seus recursos*?"
@@ -1108,10 +1107,6 @@ msgstr "Nenhum resultado encontrado."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Abrir lista de tokens"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} não está em nenhum conjunto ativo ou possui um valor inválido."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Provedor de autenticação não permitido para este perfil"
diff --git a/frontend/translations/pt_PT.po b/frontend/translations/pt_PT.po
index 8cb7d2f3c4..0e55c63192 100644
--- a/frontend/translations/pt_PT.po
+++ b/frontend/translations/pt_PT.po
@@ -475,9 +475,8 @@ msgstr "Exportar seleção"
msgid "dashboard.export-standard-multi"
msgstr "Descarregar %s ficheiros standard (svg + json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Um ou mais ficheiros que queres exportar estão a utilizar bibliotecas "
"partilhadas. O que queres fazer com os recursos*?"
diff --git a/frontend/translations/ro.po b/frontend/translations/ro.po
index 9852d7c33e..6c341e704f 100644
--- a/frontend/translations/ro.po
+++ b/frontend/translations/ro.po
@@ -506,9 +506,8 @@ msgstr "Exportă selecția"
msgid "dashboard.export-standard-multi"
msgstr "Descarcă %s fișiere standard (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Unul sau mai multe fișiere pe care dorești să le exporți folosesc "
"biblioteci partajate. Ce vrei să faci cu obiectele lor*?"
@@ -1125,10 +1124,6 @@ msgstr "Nu a fost găsit nimic."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Deschide lista de token-uri"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} nu este în nici un set activ sau are o valoare invalidă."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Furnizor de autentificare neautorizat pentru acest profil"
@@ -7753,10 +7748,6 @@ msgstr "Margini interioare"
msgid "workspace.tokens.radius"
msgstr "Raze"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referința nu este validă sau nu este în nici unul dintre seturile active"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Introdu un alias de token tipografic"
diff --git a/frontend/translations/ru.po b/frontend/translations/ru.po
index d56ab5dd01..a68e44ccb9 100644
--- a/frontend/translations/ru.po
+++ b/frontend/translations/ru.po
@@ -579,9 +579,8 @@ msgstr "Выбор экспорта"
msgid "dashboard.export-standard-multi"
msgstr "Скачать стандартные файлы (.svg + .json) (%s)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Один или несколько файлов на экспорт используют общие библиотеки. Что нужно "
"сделать с их ресурсами*?"
diff --git a/frontend/translations/sr.po b/frontend/translations/sr.po
index cb49261e73..3f6cde261a 100644
--- a/frontend/translations/sr.po
+++ b/frontend/translations/sr.po
@@ -411,9 +411,8 @@ msgstr "Избор извоза"
msgid "dashboard.export-standard-multi"
msgstr "Преузмите &s стандардних датотека (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Једна или више датотека које желите да извезете користе дељене библиотеке. "
"Шта желите да урадите са њиховим средстрвима*?"
diff --git a/frontend/translations/sv.po b/frontend/translations/sv.po
index 07f2a724a1..fe624b7c13 100644
--- a/frontend/translations/sv.po
+++ b/frontend/translations/sv.po
@@ -611,9 +611,8 @@ msgstr "Exportera markerade"
msgid "dashboard.export-standard-multi"
msgstr "Ladda ner %s standardfiler (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"En eller flera filer som du vill exportera använder delade bibliotek. Vad "
"vill du göra med deras tillgångar*?"
@@ -1470,10 +1469,6 @@ msgstr "Inga träffar hittades."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Öppna token-lista"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} är inte i någon aktiv uppsättning eller har ett ogiltigt värde."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Autentiseringsleverantör inte tillåten för denna profil"
@@ -4478,12 +4473,6 @@ msgstr "Avsluta prenumeration"
msgid "nitrate.subscription.settings.renew-with-code"
msgstr "Förnya med aktiveringskod"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr ""
-"Denna token finns inte i någon aktiv uppsättning eller har ett ogiltigt "
-"värde."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "Denna sida existerar inte"
@@ -9373,10 +9362,6 @@ msgstr "Utfyllnader"
msgid "workspace.tokens.radius"
msgstr "Radie"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referensen är inte giltig eller finns inte i någon aktiv uppsättning"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Ange ett alias för token-typografi"
diff --git a/frontend/translations/tr.po b/frontend/translations/tr.po
index 84dfb3ef0c..11d791a4a7 100644
--- a/frontend/translations/tr.po
+++ b/frontend/translations/tr.po
@@ -612,9 +612,8 @@ msgstr "Seçimi dışa aktar"
msgid "dashboard.export-standard-multi"
msgstr "%s standart dosyayı indir (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"İndirmek istediğiniz bir veya daha fazla dosya, paylaşılan kütüphaneleri "
"kullanıyor. Bunların varlıklarıyla ne yapmak istiyorsunuz*?"
@@ -1479,10 +1478,6 @@ msgstr "Eşleşme bulunamadı."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Token listesini aç"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr "{%s} herhangi bir etkin kümede bulunmuyor veya geçersiz bir değere sahip."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Kimlik doğrulama sağlayıcısına bu profil için izin verilmiyor"
@@ -4483,12 +4478,6 @@ msgstr "Aboneliği iptal et"
msgid "nitrate.subscription.settings.renew-with-code"
msgstr "Etkinleştirme koduyla yenile"
-#: src/app/main/ui/workspace/sidebar/options/menus/token_typography_row.cljs:44, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:103, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:110
-msgid "not-active-token.no-name"
-msgstr ""
-"Bu token herhangi bir etkin kümede yer almıyor veya geçersiz bir değere "
-"sahip."
-
#: src/app/main/ui/static.cljs:309
msgid "not-found.desc-message.doesnt-exist"
msgstr "Bu sayfa yok"
@@ -9380,10 +9369,6 @@ msgstr "Dolgular"
msgid "workspace.tokens.radius"
msgstr "Yarıçap"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Referans geçerli değil veya herhangi bir etkin kümede bulunmuyor"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Bir token tipografi takma adı girin"
diff --git a/frontend/translations/ukr_UA.po b/frontend/translations/ukr_UA.po
index 5535913a4a..93b48db66c 100644
--- a/frontend/translations/ukr_UA.po
+++ b/frontend/translations/ukr_UA.po
@@ -583,9 +583,8 @@ msgstr "Вибір експорту"
msgid "dashboard.export-standard-multi"
msgstr "Завантажити %s стандартних файлів (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr ""
"Файли, які Ви хочете експортувати, використовують спільні бібліотеки. Що "
"плануєте зробити з їхніми ресурсами*?"
@@ -1282,12 +1281,6 @@ msgstr "Збігів не виявлено."
msgid "ds.inputs.numeric-input.open-token-list-dropdown"
msgstr "Відкрити список токенів"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:48
-msgid "ds.inputs.token-field.no-active-token-option"
-msgstr ""
-"Цей токен не міститься в жодному з активних наборів або має недійсне "
-"значення."
-
#: src/app/main/data/auth.cljs:346
msgid "errors.auth-provider-not-allowed"
msgstr "Провайдер автентифікації не дозволений для цього профілю"
@@ -8041,10 +8034,6 @@ msgstr "Внутрішні відступи"
msgid "workspace.tokens.radius"
msgstr "Радіус"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "Посилання помилкове або ні на одному із активних наборів"
-
#: src/app/main/ui/workspace/tokens/management/forms/typography.cljs:176
msgid "workspace.tokens.reference-composite"
msgstr "Введіть псевдо токену типографіки"
diff --git a/frontend/translations/zh_CN.po b/frontend/translations/zh_CN.po
index 3f51e0f199..d69e418790 100644
--- a/frontend/translations/zh_CN.po
+++ b/frontend/translations/zh_CN.po
@@ -472,9 +472,8 @@ msgstr "导出已选中"
msgid "dashboard.export-standard-multi"
msgstr "下载 %s 标准文件 (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr "你想导出的一个或多个文件用到了共享库。你想怎么处理它们的素材?"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:336
@@ -7022,10 +7021,6 @@ msgstr "内边距"
msgid "workspace.tokens.radius"
msgstr "圆角半径"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "引用无效或不在任何活动集中"
-
#: src/app/main/ui/workspace/tokens/style_dictionary.cljs
#, unused
msgid "workspace.tokens.reference-error"
diff --git a/frontend/translations/zh_Hant.po b/frontend/translations/zh_Hant.po
index 9738082837..621f8b1398 100644
--- a/frontend/translations/zh_Hant.po
+++ b/frontend/translations/zh_Hant.po
@@ -443,9 +443,8 @@ msgstr "匯出已選取項目"
msgid "dashboard.export-standard-multi"
msgstr "下載%s個標準檔案 (.svg + .json)"
-#: src/app/main/ui/exports/files.cljs:155
-#, unused
-msgid "dashboard.export.explain"
+#: src/app/main/ui/exports/files.cljs:132
+msgid "files-download-modal.description-1"
msgstr "你想匯出的單個或多個檔案中使用了共用資料庫,你想要如何處理它們的素材*?"
#: src/app/main/ui/workspace/sidebar/options/menus/typography.cljs:336
@@ -6149,10 +6148,6 @@ msgstr "現主時您沒有任何主題。"
msgid "workspace.tokens.original-value"
msgstr "原始值:%s"
-#: src/app/main/ui/ds/controls/utilities/token_field.cljs:47, src/app/main/ui/workspace/tokens/management/token_pill.cljs:130
-msgid "workspace.tokens.ref-not-valid"
-msgstr "參照無效或不在任何啟用的集內"
-
#: src/app/main/data/workspace/tokens/warnings.cljs:15, src/app/main/data/workspace/tokens/warnings.cljs:19, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:59, src/app/main/ui/workspace/colorpicker/color_tokens.cljs:87, src/app/main/ui/workspace/sidebar/options/rows/color_row.cljs:105, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:296, src/app/main/ui/workspace/tokens/management/forms/controls/color_input.cljs:489, src/app/main/ui/workspace/tokens/management/forms/controls/combobox.cljs:298, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:189, src/app/main/ui/workspace/tokens/management/forms/controls/fonts_combobox.cljs:324, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:259, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:381, src/app/main/ui/workspace/tokens/management/forms/controls/input.cljs:505, src/app/main/ui/workspace/tokens/management/token_pill.cljs:123
#, fuzzy
msgid "workspace.tokens.resolved-value"
diff --git a/mcp/package.json b/mcp/package.json
index 955340d53f..163d0d649a 100644
--- a/mcp/package.json
+++ b/mcp/package.json
@@ -25,6 +25,6 @@
"packageManager": "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
"devDependencies": {
"concurrently": "^10.0.3",
- "prettier": "^3.9.1"
+ "prettier": "^3.9.4"
}
}
diff --git a/mcp/packages/plugin/package.json b/mcp/packages/plugin/package.json
index c5df6328f0..a14df52313 100644
--- a/mcp/packages/plugin/package.json
+++ b/mcp/packages/plugin/package.json
@@ -18,7 +18,7 @@
"devDependencies": {
"cross-env": "^10.1.0",
"typescript": "^6.0.3",
- "vite": "^8.1.0",
+ "vite": "^8.1.1",
"vite-live-preview": "^0.4.0"
}
}
diff --git a/mcp/packages/server/package.json b/mcp/packages/server/package.json
index 62476f19a9..67f220c0a6 100644
--- a/mcp/packages/server/package.json
+++ b/mcp/packages/server/package.json
@@ -29,14 +29,14 @@
"@modelcontextprotocol/sdk": "^1.29.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.15.1",
- "express": "^5.1.0",
+ "express": "^5.2.1",
"ioredis": "^5.11.1",
"js-yaml": "^5.2.0",
"nrepl-client": "^0.3.0",
"penpot-mcp": "file:..",
"pino": "^10.3.1",
"pino-loki": "^3.0.0",
- "pino-pretty": "^13.1.1",
+ "pino-pretty": "^13.1.3",
"reflect-metadata": "^0.2.2",
"sharp": "^0.35.2",
"ws": "^8.21.0",
@@ -47,11 +47,11 @@
"@types/express": "^5.0.6",
"@types/js-yaml": "^4.0.9",
"@types/node": "^26.0.1",
- "@types/ws": "^8.5.10",
+ "@types/ws": "^8.18.1",
"cross-env": "^10.1.0",
"esbuild": "^0.28.1",
"ts-node": "^10.9.2",
- "tsx": "^4.22.3",
+ "tsx": "^4.22.4",
"typescript": "^6.0.3"
},
"ts-node": {
diff --git a/mcp/pnpm-lock.yaml b/mcp/pnpm-lock.yaml
index 259e153b28..f81ed1183d 100644
--- a/mcp/pnpm-lock.yaml
+++ b/mcp/pnpm-lock.yaml
@@ -12,8 +12,8 @@ importers:
specifier: ^10.0.3
version: 10.0.3
prettier:
- specifier: ^3.9.1
- version: 3.9.1
+ specifier: ^3.9.4
+ version: 3.9.4
packages/common:
devDependencies:
@@ -37,11 +37,11 @@ importers:
specifier: ^6.0.3
version: 6.0.3
vite:
- specifier: ^8.1.0
- version: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)
+ specifier: ^8.1.1
+ version: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)
vite-live-preview:
specifier: ^0.4.0
- version: 0.4.0(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4))
+ version: 0.4.0(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4))
packages/server:
dependencies:
@@ -55,7 +55,7 @@ importers:
specifier: ^0.15.1
version: 0.15.1
express:
- specifier: ^5.1.0
+ specifier: ^5.2.1
version: 5.2.1
ioredis:
specifier: ^5.11.1
@@ -76,7 +76,7 @@ importers:
specifier: ^3.0.0
version: 3.0.0
pino-pretty:
- specifier: ^13.1.1
+ specifier: ^13.1.3
version: 13.1.3
reflect-metadata:
specifier: ^0.2.2
@@ -104,7 +104,7 @@ importers:
specifier: ^26.0.1
version: 26.0.1
'@types/ws':
- specifier: ^8.5.10
+ specifier: ^8.18.1
version: 8.18.1
cross-env:
specifier: ^10.1.0
@@ -116,7 +116,7 @@ importers:
specifier: ^10.9.2
version: 10.9.2(@types/node@26.0.1)(typescript@6.0.3)
tsx:
- specifier: ^4.22.3
+ specifier: ^4.22.4
version: 4.22.4
typescript:
specifier: ^6.0.3
@@ -835,8 +835,8 @@ packages:
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
engines: {node: '>= 0.4'}
- es-object-atoms@1.1.1:
- resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
engines: {node: '>= 0.4'}
esbuild@0.28.1:
@@ -942,8 +942,8 @@ packages:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
- hasown@2.0.2:
- resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
engines: {node: '>= 0.4'}
help-me@5.0.0:
@@ -1144,8 +1144,8 @@ packages:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
- path-to-regexp@8.3.0:
- resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
+ path-to-regexp@8.4.2:
+ resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
penpot-mcp@file:packages:
resolution: {directory: packages, type: directory}
@@ -1184,8 +1184,8 @@ packages:
resolution: {integrity: sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==}
engines: {node: ^10 || ^12 || >=14}
- prettier@3.9.1:
- resolution: {integrity: sha512-ppiDo2CSwexck1eyZUwJHg/N3nf1+6IRCv7W/VJ5vaLnVCmB7+3CdRfMwoCHBBX6xTrREDTksZ4OZl5SSf4zXA==}
+ prettier@3.9.4:
+ resolution: {integrity: sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==}
engines: {node: '>=14'}
hasBin: true
@@ -1202,8 +1202,8 @@ packages:
pump@3.0.4:
resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
- qs@6.14.1:
- resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==}
+ qs@6.15.3:
+ resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==}
engines: {node: '>=0.6'}
quick-format-unescaped@4.0.4:
@@ -1293,8 +1293,8 @@ packages:
resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==}
engines: {node: '>= 0.4'}
- side-channel-list@1.0.0:
- resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
+ side-channel-list@1.0.1:
+ resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
engines: {node: '>= 0.4'}
side-channel-map@1.0.1:
@@ -1305,8 +1305,8 @@ packages:
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
engines: {node: '>= 0.4'}
- side-channel@1.1.0:
- resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
+ side-channel@1.1.1:
+ resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
engines: {node: '>= 0.4'}
sonic-boom@4.2.0:
@@ -1417,8 +1417,8 @@ packages:
peerDependencies:
vite: '>=5.4.0'
- vite@8.1.0:
- resolution: {integrity: sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==}
+ vite@8.1.1:
+ resolution: {integrity: sha512-X/05/cT+VITy2AeDc1der6smvGWWREtL4hPbPTaVbjSBuuWkmNOjR6HP3NzqcQA2nF6VHGUPaFRJyft/2AE9Kg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -1927,7 +1927,7 @@ snapshots:
http-errors: 2.0.1
iconv-lite: 0.7.2
on-finished: 2.4.1
- qs: 6.14.1
+ qs: 6.15.3
raw-body: 3.0.2
type-is: 2.0.1
transitivePeerDependencies:
@@ -2034,7 +2034,7 @@ snapshots:
es-errors@1.3.0: {}
- es-object-atoms@1.1.1:
+ es-object-atoms@1.1.2:
dependencies:
es-errors: 1.3.0
@@ -2108,7 +2108,7 @@ snapshots:
once: 1.4.0
parseurl: 1.3.3
proxy-addr: 2.0.7
- qs: 6.14.1
+ qs: 6.15.3
range-parser: 1.2.1
router: 2.2.0
send: 1.2.1
@@ -2160,24 +2160,24 @@ snapshots:
call-bind-apply-helpers: 1.0.2
es-define-property: 1.0.1
es-errors: 1.3.0
- es-object-atoms: 1.1.1
+ es-object-atoms: 1.1.2
function-bind: 1.1.2
get-proto: 1.0.1
gopd: 1.2.0
has-symbols: 1.1.0
- hasown: 2.0.2
+ hasown: 2.0.4
math-intrinsics: 1.1.0
get-proto@1.0.1:
dependencies:
dunder-proto: 1.0.1
- es-object-atoms: 1.1.1
+ es-object-atoms: 1.1.2
gopd@1.2.0: {}
has-symbols@1.1.0: {}
- hasown@2.0.2:
+ hasown@2.0.4:
dependencies:
function-bind: 1.1.2
@@ -2327,7 +2327,7 @@ snapshots:
path-key@3.1.1: {}
- path-to-regexp@8.3.0: {}
+ path-to-regexp@8.4.2: {}
penpot-mcp@file:packages: {}
@@ -2384,7 +2384,7 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
- prettier@3.9.1: {}
+ prettier@3.9.4: {}
process-warning@5.0.0: {}
@@ -2403,9 +2403,10 @@ snapshots:
end-of-stream: 1.4.5
once: 1.4.0
- qs@6.14.1:
+ qs@6.15.3:
dependencies:
- side-channel: 1.1.0
+ es-define-property: 1.0.1
+ side-channel: 1.1.1
quick-format-unescaped@4.0.4: {}
@@ -2459,7 +2460,7 @@ snapshots:
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
- path-to-regexp: 8.3.0
+ path-to-regexp: 8.4.2
transitivePeerDependencies:
- supports-color
@@ -2542,7 +2543,7 @@ snapshots:
shell-quote@1.8.4: {}
- side-channel-list@1.0.0:
+ side-channel-list@1.0.1:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
@@ -2562,11 +2563,11 @@ snapshots:
object-inspect: 1.13.4
side-channel-map: 1.0.1
- side-channel@1.1.0:
+ side-channel@1.1.1:
dependencies:
es-errors: 1.3.0
object-inspect: 1.13.4
- side-channel-list: 1.0.0
+ side-channel-list: 1.0.1
side-channel-map: 1.0.1
side-channel-weakmap: 1.0.2
@@ -2657,20 +2658,20 @@ snapshots:
vary@1.1.2: {}
- vite-live-preview@0.4.0(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)):
+ vite-live-preview@0.4.0(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)):
dependencies:
'@seahax/deep-copy': 0.1.0
'@seahax/semaphore': 0.5.1
'@types/ws': 8.18.1
escape-goat: 4.0.0
strip-ansi: 7.2.0
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4)
ws: 8.21.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
- vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4):
+ vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(tsx@4.22.4):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
diff --git a/mcp/pnpm-workspace.yaml b/mcp/pnpm-workspace.yaml
index 7872ab47f7..60c228aba4 100644
--- a/mcp/pnpm-workspace.yaml
+++ b/mcp/pnpm-workspace.yaml
@@ -4,6 +4,10 @@ allowBuilds:
linkWorkspacePackages: true
+minimumReleaseAgeExclude:
+ - qs@6.14.2 || 6.15.2
+ - path-to-regexp@8.4.0
+
packages:
- "./packages/common"
- "./packages/server"
diff --git a/plugins/CHANGELOG.md b/plugins/CHANGELOG.md
index c3138b0659..5504c20dac 100644
--- a/plugins/CHANGELOG.md
+++ b/plugins/CHANGELOG.md
@@ -21,6 +21,7 @@
- **plugin-types**: Added `fixedWhenScrolling` property for shapes
- **plugin-runtime:** `addToken` now resolves references against all token sets, allowing references to tokens in inactive sets
- **plugin-types:** `TokenCatalog.addSet` now accepts an optional `active` flag to create an already-active set (sets are inactive by default)
+- **plugin-types:** `TokenTheme.addSet` and `TokenTheme.removeSet` now accept a token set id (`string`) in addition to a `TokenSet`
- **plugin-runtime:** A `fontFamilies` token's `resolvedValue` now returns the documented `string[]` (the resolved family list) instead of leaking the raw tokenscript list symbol
### 🩹 Fixes
diff --git a/plugins/apps/plugin-api-test-suite/package.json b/plugins/apps/plugin-api-test-suite/package.json
index 43bf67412c..305612633c 100644
--- a/plugins/apps/plugin-api-test-suite/package.json
+++ b/plugins/apps/plugin-api-test-suite/package.json
@@ -17,6 +17,6 @@
"test:ci:mocked": "pnpm run build:headless && MOCK_BACKEND=1 tsx ci/run-ci.ts"
},
"devDependencies": {
- "playwright": "^1.61.0"
+ "playwright": "^1.61.1"
}
}
diff --git a/plugins/apps/plugin-api-test-suite/src/tests/comments.test.ts b/plugins/apps/plugin-api-test-suite/src/tests/comments.test.ts
index b6ba1745ad..bc53f49d26 100644
--- a/plugins/apps/plugin-api-test-suite/src/tests/comments.test.ts
+++ b/plugins/apps/plugin-api-test-suite/src/tests/comments.test.ts
@@ -4,9 +4,9 @@ import type { CommentThread, Page } from '@penpot/plugin-types';
import type { TestContext } from '../framework/types';
// Comments.
-// Comment threads are created on the current page. Both thread removal APIs are
-// currently broken (see the dedicated red tests), so cleanup is best-effort to
-// keep the other assertions meaningful.
+// Comment threads are created on the current page. Thread/comment removal is
+// asynchronous (it resolves once the backend delete RPC completes), so callers
+// must await it; cleanup is best-effort and swallows errors.
function page(ctx: TestContext): Page {
const p = ctx.penpot.currentPage;
@@ -124,7 +124,7 @@ describe.skipIfMocked('Comments', () => {
x: 8,
y: 8,
});
- thread.remove();
+ await thread.remove();
const threads = await p.findCommentThreads();
expect(threads.every((t) => t.seqNumber !== thread.seqNumber)).toBe(true);
});
diff --git a/plugins/apps/plugin-api-test-suite/src/tests/interactions.test.ts b/plugins/apps/plugin-api-test-suite/src/tests/interactions.test.ts
index 91f26d3dce..842a395031 100644
--- a/plugins/apps/plugin-api-test-suite/src/tests/interactions.test.ts
+++ b/plugins/apps/plugin-api-test-suite/src/tests/interactions.test.ts
@@ -83,6 +83,21 @@ describe('Interactions', () => {
expect(interaction.action.type).toBe('open-overlay');
});
+ // position is optional; when omitted the overlay defaults to 'center'.
+ test('open-overlay without a position defaults to center', (ctx) => {
+ const overlay = board(ctx);
+ const r = rect(ctx);
+ const interaction = r.addInteraction('click', {
+ type: 'open-overlay',
+ destination: overlay,
+ });
+ expect(interaction.action.type).toBe('open-overlay');
+ if (interaction.action.type === 'open-overlay') {
+ expect(interaction.action.destination.id).toBe(overlay.id);
+ expect(interaction.action.position).toBe('center');
+ }
+ });
+
test('toggle-overlay interaction round-trips', (ctx) => {
const overlay = board(ctx);
const r = rect(ctx);
@@ -116,6 +131,23 @@ describe('Interactions', () => {
}
});
+ // animation is optional on close-overlay; omitting it closes with no transition.
+ test('close-overlay without an animation round-trips', (ctx) => {
+ const overlay = board(ctx);
+ const r = rect(ctx);
+ const interaction = r.addInteraction('click', {
+ type: 'close-overlay',
+ destination: overlay,
+ });
+ expect(interaction.action.type).toBe('close-overlay');
+ if (interaction.action.type === 'close-overlay') {
+ expect(
+ interaction.action.destination && interaction.action.destination.id,
+ ).toBe(overlay.id);
+ expect(interaction.action.animation).toBeUndefined();
+ }
+ });
+
test('previous-screen interaction round-trips', (ctx) => {
const r = rect(ctx);
const interaction = r.addInteraction('click', { type: 'previous-screen' });
@@ -134,6 +166,19 @@ describe('Interactions', () => {
expect(interaction.delay).toBeCloseTo(1000, 0);
});
+ // A zero delay is a valid value (fires immediately), not an error.
+ test('after-delay accepts a zero delay', (ctx) => {
+ const dest = board(ctx);
+ const r = rect(ctx);
+ const interaction = r.addInteraction(
+ 'after-delay',
+ { type: 'navigate-to', destination: dest },
+ 0,
+ );
+ expect(interaction.trigger).toBe('after-delay');
+ expect(interaction.delay).toBeCloseTo(0, 0);
+ });
+
test('mouse-leave trigger is recorded', (ctx) => {
// click / mouse-enter / after-delay are covered above; mouse-leave is the
// remaining trigger.
@@ -167,6 +212,20 @@ describe('Interactions', () => {
expect(interaction.action.type).toBe('previous-screen');
});
+ // The delay setter accepts zero (fires immediately) as a valid value.
+ test('delay setter accepts a zero value', (ctx) => {
+ const dest = board(ctx);
+ const r = rect(ctx);
+ const interaction = r.addInteraction(
+ 'after-delay',
+ { type: 'navigate-to', destination: dest },
+ 1000,
+ );
+
+ interaction.delay = 0;
+ expect(interaction.delay).toBeCloseTo(0, 0);
+ });
+
describe('Animations', () => {
test('dissolve animation round-trips', (ctx) => {
const dest = board(ctx);
diff --git a/plugins/apps/plugin-api-test-suite/src/tests/layout.test.ts b/plugins/apps/plugin-api-test-suite/src/tests/layout.test.ts
index f4f8aacc6e..21471365bc 100644
--- a/plugins/apps/plugin-api-test-suite/src/tests/layout.test.ts
+++ b/plugins/apps/plugin-api-test-suite/src/tests/layout.test.ts
@@ -65,6 +65,23 @@ describe('Layout', () => {
expect(flex.leftPadding).toBeCloseTo(4, 0);
});
+ // Gap and padding setters accept fractional numbers, not just integers.
+ test('gaps and padding accept fractional values', (ctx) => {
+ const flex = board(ctx).addFlexLayout();
+ flex.rowGap = 5.5;
+ flex.columnGap = 10.25;
+ flex.topPadding = 1.5;
+ flex.rightPadding = 2.25;
+ flex.bottomPadding = 3.75;
+ flex.leftPadding = 4.5;
+ expect(flex.rowGap).toBeCloseTo(5.5, 2);
+ expect(flex.columnGap).toBeCloseTo(10.25, 2);
+ expect(flex.topPadding).toBeCloseTo(1.5, 2);
+ expect(flex.rightPadding).toBeCloseTo(2.25, 2);
+ expect(flex.bottomPadding).toBeCloseTo(3.75, 2);
+ expect(flex.leftPadding).toBeCloseTo(4.5, 2);
+ });
+
test('sizing round-trips', (ctx) => {
const flex = board(ctx).addFlexLayout();
flex.horizontalSizing = 'fix';
@@ -176,6 +193,23 @@ describe('Layout', () => {
expect(grid.columnGap).toBeCloseTo(9, 0);
});
+ // Gap and padding setters accept fractional numbers, not just integers.
+ test('gaps and padding accept fractional values', (ctx) => {
+ const grid = board(ctx).addGridLayout();
+ grid.rowGap = 7.5;
+ grid.columnGap = 9.25;
+ grid.topPadding = 1.5;
+ grid.rightPadding = 2.75;
+ grid.bottomPadding = 3.25;
+ grid.leftPadding = 4.5;
+ expect(grid.rowGap).toBeCloseTo(7.5, 2);
+ expect(grid.columnGap).toBeCloseTo(9.25, 2);
+ expect(grid.topPadding).toBeCloseTo(1.5, 2);
+ expect(grid.rightPadding).toBeCloseTo(2.75, 2);
+ expect(grid.bottomPadding).toBeCloseTo(3.25, 2);
+ expect(grid.leftPadding).toBeCloseTo(4.5, 2);
+ });
+
// Index boundaries — invalid indices must be rejected.
test('addRowAtIndex with a negative index throws', (ctx) => {
const grid = board(ctx).addGridLayout();
diff --git a/plugins/apps/plugin-api-test-suite/src/tests/shapes-geometry.test.ts b/plugins/apps/plugin-api-test-suite/src/tests/shapes-geometry.test.ts
index 2402f29035..dfeae815f6 100644
--- a/plugins/apps/plugin-api-test-suite/src/tests/shapes-geometry.test.ts
+++ b/plugins/apps/plugin-api-test-suite/src/tests/shapes-geometry.test.ts
@@ -237,6 +237,21 @@ describe('Shapes', () => {
expect(r.borderRadiusBottomRight).toBeCloseTo(3, 0);
expect(r.borderRadiusBottomLeft).toBeCloseTo(4, 0);
});
+
+ // Border radius setters accept fractional numbers, not just integers.
+ test('border radius accepts fractional values', (ctx) => {
+ const r = rect(ctx);
+ r.borderRadius = 4.5;
+ expect(r.borderRadius).toBeCloseTo(4.5, 2);
+ r.borderRadiusTopLeft = 1.25;
+ r.borderRadiusTopRight = 2.5;
+ r.borderRadiusBottomRight = 3.75;
+ r.borderRadiusBottomLeft = 0.5;
+ expect(r.borderRadiusTopLeft).toBeCloseTo(1.25, 2);
+ expect(r.borderRadiusTopRight).toBeCloseTo(2.5, 2);
+ expect(r.borderRadiusBottomRight).toBeCloseTo(3.75, 2);
+ expect(r.borderRadiusBottomLeft).toBeCloseTo(0.5, 2);
+ });
});
describe('Ordering', () => {
diff --git a/plugins/apps/plugin-api-test-suite/src/tests/tokens.test.ts b/plugins/apps/plugin-api-test-suite/src/tests/tokens.test.ts
index 1bfc15003e..8bd2e0f790 100644
--- a/plugins/apps/plugin-api-test-suite/src/tests/tokens.test.ts
+++ b/plugins/apps/plugin-api-test-suite/src/tests/tokens.test.ts
@@ -148,6 +148,19 @@ describe('Tokens', () => {
theme.removeSet(set);
});
+ // addSet/removeSet also accept a token set id (string), not just a TokenSet.
+ test('addSet and removeSet accept a set id', async (ctx) => {
+ const cat = catalog(ctx);
+ const theme = cat.addTheme({ group: '', name: unique('theme') });
+ const set = cat.addSet({ name: unique('set'), active: false });
+ theme.addSet(set.id);
+ await sleep(300);
+ expect(theme.activeSets.length).toBeGreaterThan(0);
+ theme.removeSet(set.id);
+ await sleep(300);
+ expect(theme.activeSets.length).toBe(0);
+ });
+
test('duplicate and remove a theme', (ctx) => {
const theme = catalog(ctx).addTheme({ group: '', name: unique('theme') });
const dup = theme.duplicate();
diff --git a/plugins/libs/plugin-types/index.d.ts b/plugins/libs/plugin-types/index.d.ts
index 2548a05ebb..b95e78c9c3 100644
--- a/plugins/libs/plugin-types/index.d.ts
+++ b/plugins/libs/plugin-types/index.d.ts
@@ -485,9 +485,9 @@ export interface CloseOverlay {
readonly destination?: Board;
/**
- * Animation displayed with this interaction.
+ * Animation displayed with this interaction. Omit it to close with no transition.
*/
- readonly animation: Animation;
+ readonly animation?: Animation;
}
/**
@@ -5291,13 +5291,17 @@ export interface TokenTheme {
/**
* Adds a set to the list of the theme.
+ *
+ * @param tokenSet a `TokenSet` or the id of a token set.
*/
- addSet(tokenSet: TokenSet): void;
+ addSet(tokenSet: TokenSet | string): void;
/**
* Removes a set from the list of the theme.
+ *
+ * @param tokenSet a `TokenSet` or the id of a token set.
*/
- removeSet(tokenSet: TokenSet): void;
+ removeSet(tokenSet: TokenSet | string): void;
/**
* Adds to the catalog a new TokenTheme equal to this one but with a new id.
diff --git a/plugins/libs/plugins-runtime/package.json b/plugins/libs/plugins-runtime/package.json
index 6ee2d85eb5..cac1e949d5 100644
--- a/plugins/libs/plugins-runtime/package.json
+++ b/plugins/libs/plugins-runtime/package.json
@@ -2,9 +2,9 @@
"name": "@penpot/plugins-runtime",
"version": "1.4.2",
"dependencies": {
- "@penpot/plugin-types": "^1.4.2",
+ "@penpot/plugin-types": "workspace:^",
"ses": "^2.1.0",
- "zod": "^3.22.4"
+ "zod": "^3.25.76"
},
"module": "./dist/index.js",
"typings": "./dist/index.d.ts",
diff --git a/plugins/package.json b/plugins/package.json
index e7e5f374a3..bfb9f1fcdc 100644
--- a/plugins/package.json
+++ b/plugins/package.json
@@ -45,9 +45,9 @@
"@types/feather-icons": "^4.29.4",
"@types/node": "26.0.1",
"@types/yargs": "^17.0.35",
- "@typescript-eslint/eslint-plugin": "8.62.0",
- "@typescript-eslint/parser": "8.62.0",
- "@typescript-eslint/utils": "^8.62.0",
+ "@typescript-eslint/eslint-plugin": "8.62.1",
+ "@typescript-eslint/parser": "8.62.1",
+ "@typescript-eslint/utils": "^8.62.1",
"@vitest/coverage-v8": "4.1.9",
"@vitest/ui": "4.1.9",
"concurrently": "^10.0.3",
@@ -60,18 +60,18 @@
"eslint-plugin-react": "7.37.5",
"eslint-plugin-react-hooks": "7.1.1",
"eslint-plugin-unused-imports": "^4.4.1",
- "fs-extra": "^11.3.5",
+ "fs-extra": "^11.3.6",
"globals": "^17.7.0",
"happy-dom": "^20.10.6",
"jiti": "2.7.0",
"jsdom": "~29.1.1",
"jsonc-eslint-parser": "^3.1.0",
- "prettier": "^3.9.1",
+ "prettier": "^3.9.4",
"tsx": "^4.22.4",
"typedoc": "^0.28.19",
"typescript": "6.0.3",
- "typescript-eslint": "^8.62.0",
- "vite": "8.1.0",
+ "typescript-eslint": "^8.62.1",
+ "vite": "8.1.1",
"vite-plugin-checker": "^0.14.4",
"vite-plugin-dts": "5.0.3",
"vite-plugin-static-copy": "^4.1.1",
diff --git a/plugins/pnpm-lock.yaml b/plugins/pnpm-lock.yaml
index dca9ff9d0a..96379796c5 100644
--- a/plugins/pnpm-lock.yaml
+++ b/plugins/pnpm-lock.yaml
@@ -4,6 +4,14 @@ settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
+overrides:
+ '@babel/core@<=7.29.0': ^7.29.1
+ ajv@>=7.0.0-alpha.0 <8.18.0: ^8.18.0
+ lodash@<=4.17.23: ^4.17.24
+ lodash@>=4.0.0 <=4.17.23: ^4.17.24
+ minimatch@>=10.0.0 <10.2.1: ^10.2.1
+ minimatch@>=10.0.0 <10.2.3: ^10.2.3
+
importers:
.:
@@ -59,10 +67,10 @@ importers:
version: 22.0.4(chokidar@5.0.0)
'@angular-eslint/eslint-plugin':
specifier: 22.0.0
- version: 22.0.0(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ version: 22.0.0(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
'@angular-eslint/eslint-plugin-template':
specifier: 22.0.0
- version: 22.0.0(@angular-eslint/template-parser@22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(@typescript-eslint/types@8.62.0)(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ version: 22.0.0(@angular-eslint/template-parser@22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(@typescript-eslint/types@8.62.1)(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
'@angular-eslint/template-parser':
specifier: 22.0.0
version: 22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
@@ -94,14 +102,14 @@ importers:
specifier: ^17.0.35
version: 17.0.35
'@typescript-eslint/eslint-plugin':
- specifier: 8.62.0
- version: 8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ specifier: 8.62.1
+ version: 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
'@typescript-eslint/parser':
- specifier: 8.62.0
- version: 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ specifier: 8.62.1
+ version: 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
'@typescript-eslint/utils':
- specifier: ^8.62.0
- version: 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ specifier: ^8.62.1
+ version: 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
'@vitest/coverage-v8':
specifier: 4.1.9
version: 4.1.9(vitest@4.1.9)
@@ -125,7 +133,7 @@ importers:
version: 10.1.8(eslint@10.6.0(jiti@2.7.0))
eslint-plugin-import:
specifier: 2.32.0
- version: 2.32.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))
+ version: 2.32.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))
eslint-plugin-jsx-a11y:
specifier: 6.10.2
version: 6.10.2(eslint@10.6.0(jiti@2.7.0))
@@ -137,10 +145,10 @@ importers:
version: 7.1.1(eslint@10.6.0(jiti@2.7.0))
eslint-plugin-unused-imports:
specifier: ^4.4.1
- version: 4.4.1(@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))
+ version: 4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))
fs-extra:
- specifier: ^11.3.5
- version: 11.3.5
+ specifier: ^11.3.6
+ version: 11.3.6
globals:
specifier: ^17.7.0
version: 17.7.0
@@ -157,8 +165,8 @@ importers:
specifier: ^3.1.0
version: 3.1.0
prettier:
- specifier: ^3.9.1
- version: 3.9.1
+ specifier: ^3.9.4
+ version: 3.9.4
tsx:
specifier: ^4.22.4
version: 4.22.4
@@ -169,23 +177,23 @@ importers:
specifier: 6.0.3
version: 6.0.3
typescript-eslint:
- specifier: ^8.62.0
- version: 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ specifier: ^8.62.1
+ version: 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
vite:
- specifier: 8.1.0
- version: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ specifier: 8.1.1
+ version: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
vite-plugin-checker:
specifier: ^0.14.4
- version: 0.14.4(eslint@10.6.0(jiti@2.7.0))(optionator@0.9.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ version: 0.14.4(eslint@10.6.0(jiti@2.7.0))(optionator@0.9.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
vite-plugin-dts:
specifier: 5.0.3
- version: 5.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16))
+ version: 5.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16))
vite-plugin-static-copy:
specifier: ^4.1.1
- version: 4.1.1(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ version: 4.1.1(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
vitest:
specifier: 4.1.9
- version: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ version: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
yargs:
specifier: ^18.0.0
version: 18.0.0
@@ -207,7 +215,7 @@ importers:
apps/plugin-api-test-suite:
devDependencies:
playwright:
- specifier: ^1.61.0
+ specifier: ^1.61.1
version: 1.61.1
apps/poc-state-plugin: {}
@@ -223,13 +231,13 @@ importers:
libs/plugins-runtime:
dependencies:
'@penpot/plugin-types':
- specifier: ^1.4.2
+ specifier: workspace:^
version: link:../plugin-types
ses:
specifier: ^2.1.0
version: 2.1.0
zod:
- specifier: ^3.22.4
+ specifier: ^3.25.76
version: 3.25.76
libs/plugins-styles: {}
@@ -498,10 +506,6 @@ packages:
resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==}
engines: {node: '>=6.9.0'}
- '@babel/core@7.29.0':
- resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==}
- engines: {node: '>=6.9.0'}
-
'@babel/core@7.29.7':
resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==}
engines: {node: '>=6.9.0'}
@@ -530,7 +534,7 @@ packages:
resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==}
engines: {node: '>=6.9.0'}
peerDependencies:
- '@babel/core': ^7.0.0
+ '@babel/core': ^7.29.1
'@babel/helper-split-export-declaration@7.24.7':
resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==}
@@ -634,8 +638,8 @@ packages:
'@endo/immutable-arraybuffer@1.1.2':
resolution: {integrity: sha512-u+NaYB2aqEugQ3u7w3c5QNkPogf8q/xGgsPaqdY6pUiGWtYiTiFspKFcha6+oeZhWXWQ23rf0KrUq0kfuzqYyQ==}
- '@esbuild/aix-ppc64@0.27.7':
- resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ '@esbuild/aix-ppc64@0.27.2':
+ resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
@@ -646,8 +650,8 @@ packages:
cpu: [ppc64]
os: [aix]
- '@esbuild/android-arm64@0.27.7':
- resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ '@esbuild/android-arm64@0.27.2':
+ resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
@@ -658,8 +662,8 @@ packages:
cpu: [arm64]
os: [android]
- '@esbuild/android-arm@0.27.7':
- resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ '@esbuild/android-arm@0.27.2':
+ resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
@@ -670,8 +674,8 @@ packages:
cpu: [arm]
os: [android]
- '@esbuild/android-x64@0.27.7':
- resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ '@esbuild/android-x64@0.27.2':
+ resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
@@ -682,8 +686,8 @@ packages:
cpu: [x64]
os: [android]
- '@esbuild/darwin-arm64@0.27.7':
- resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ '@esbuild/darwin-arm64@0.27.2':
+ resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
@@ -694,8 +698,8 @@ packages:
cpu: [arm64]
os: [darwin]
- '@esbuild/darwin-x64@0.27.7':
- resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ '@esbuild/darwin-x64@0.27.2':
+ resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
@@ -706,8 +710,8 @@ packages:
cpu: [x64]
os: [darwin]
- '@esbuild/freebsd-arm64@0.27.7':
- resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ '@esbuild/freebsd-arm64@0.27.2':
+ resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
@@ -718,8 +722,8 @@ packages:
cpu: [arm64]
os: [freebsd]
- '@esbuild/freebsd-x64@0.27.7':
- resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ '@esbuild/freebsd-x64@0.27.2':
+ resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
@@ -730,8 +734,8 @@ packages:
cpu: [x64]
os: [freebsd]
- '@esbuild/linux-arm64@0.27.7':
- resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ '@esbuild/linux-arm64@0.27.2':
+ resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
@@ -742,8 +746,8 @@ packages:
cpu: [arm64]
os: [linux]
- '@esbuild/linux-arm@0.27.7':
- resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ '@esbuild/linux-arm@0.27.2':
+ resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
@@ -754,8 +758,8 @@ packages:
cpu: [arm]
os: [linux]
- '@esbuild/linux-ia32@0.27.7':
- resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ '@esbuild/linux-ia32@0.27.2':
+ resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
@@ -766,8 +770,8 @@ packages:
cpu: [ia32]
os: [linux]
- '@esbuild/linux-loong64@0.27.7':
- resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ '@esbuild/linux-loong64@0.27.2':
+ resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
@@ -778,8 +782,8 @@ packages:
cpu: [loong64]
os: [linux]
- '@esbuild/linux-mips64el@0.27.7':
- resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ '@esbuild/linux-mips64el@0.27.2':
+ resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
@@ -790,8 +794,8 @@ packages:
cpu: [mips64el]
os: [linux]
- '@esbuild/linux-ppc64@0.27.7':
- resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ '@esbuild/linux-ppc64@0.27.2':
+ resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
@@ -802,8 +806,8 @@ packages:
cpu: [ppc64]
os: [linux]
- '@esbuild/linux-riscv64@0.27.7':
- resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ '@esbuild/linux-riscv64@0.27.2':
+ resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
@@ -814,8 +818,8 @@ packages:
cpu: [riscv64]
os: [linux]
- '@esbuild/linux-s390x@0.27.7':
- resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ '@esbuild/linux-s390x@0.27.2':
+ resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
@@ -826,8 +830,8 @@ packages:
cpu: [s390x]
os: [linux]
- '@esbuild/linux-x64@0.27.7':
- resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ '@esbuild/linux-x64@0.27.2':
+ resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
@@ -838,8 +842,8 @@ packages:
cpu: [x64]
os: [linux]
- '@esbuild/netbsd-arm64@0.27.7':
- resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ '@esbuild/netbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
@@ -850,8 +854,8 @@ packages:
cpu: [arm64]
os: [netbsd]
- '@esbuild/netbsd-x64@0.27.7':
- resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ '@esbuild/netbsd-x64@0.27.2':
+ resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
@@ -862,8 +866,8 @@ packages:
cpu: [x64]
os: [netbsd]
- '@esbuild/openbsd-arm64@0.27.7':
- resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ '@esbuild/openbsd-arm64@0.27.2':
+ resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
@@ -874,8 +878,8 @@ packages:
cpu: [arm64]
os: [openbsd]
- '@esbuild/openbsd-x64@0.27.7':
- resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ '@esbuild/openbsd-x64@0.27.2':
+ resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
@@ -886,8 +890,8 @@ packages:
cpu: [x64]
os: [openbsd]
- '@esbuild/openharmony-arm64@0.27.7':
- resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ '@esbuild/openharmony-arm64@0.27.2':
+ resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
@@ -898,8 +902,8 @@ packages:
cpu: [arm64]
os: [openharmony]
- '@esbuild/sunos-x64@0.27.7':
- resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ '@esbuild/sunos-x64@0.27.2':
+ resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
@@ -910,8 +914,8 @@ packages:
cpu: [x64]
os: [sunos]
- '@esbuild/win32-arm64@0.27.7':
- resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ '@esbuild/win32-arm64@0.27.2':
+ resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
@@ -922,8 +926,8 @@ packages:
cpu: [arm64]
os: [win32]
- '@esbuild/win32-ia32@0.27.7':
- resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ '@esbuild/win32-ia32@0.27.2':
+ resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
@@ -934,8 +938,8 @@ packages:
cpu: [ia32]
os: [win32]
- '@esbuild/win32-x64@0.27.7':
- resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ '@esbuild/win32-x64@0.27.2':
+ resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
@@ -1173,14 +1177,6 @@ packages:
'@types/node':
optional: true
- '@isaacs/balanced-match@4.0.1':
- resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==}
- engines: {node: 20 || >=22}
-
- '@isaacs/brace-expansion@5.0.1':
- resolution: {integrity: sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ==}
- engines: {node: 20 || >=22}
-
'@isaacs/fs-minipass@4.0.1':
resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==}
engines: {node: '>=18.0.0'}
@@ -2182,63 +2178,63 @@ packages:
'@types/yargs@17.0.35':
resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==}
- '@typescript-eslint/eslint-plugin@8.62.0':
- resolution: {integrity: sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==}
+ '@typescript-eslint/eslint-plugin@8.62.1':
+ resolution: {integrity: sha512-4EQM77WgVNxj7OkL/5b/D/xZsw00G577+UriYTC7JF5opcF3T2AuoeY7ueLaZgSVjSgCS6yOAJB5bRGLPSJUzA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
- '@typescript-eslint/parser': ^8.62.0
+ '@typescript-eslint/parser': ^8.62.1
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/parser@8.62.0':
- resolution: {integrity: sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==}
+ '@typescript-eslint/parser@8.62.1':
+ resolution: {integrity: sha512-sPhE4iHuJDSvoAiec+Ro8JyXw8f0ql13HFR82P99nCm9GwTEKG0KYLvDe6REk8BCXuit6vJAv/Yxg5ABaNS2rA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/project-service@8.62.0':
- resolution: {integrity: sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==}
+ '@typescript-eslint/project-service@8.62.1':
+ resolution: {integrity: sha512-yQ3RgY5RkSBpsNS1Bx/JQEcA24FOSdfGktoyprAr5u18390UQdtVcfnEv4nIrIshNnavlVyZBKxQwT1fIAE6cg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/scope-manager@8.62.0':
- resolution: {integrity: sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==}
+ '@typescript-eslint/scope-manager@8.62.1':
+ resolution: {integrity: sha512-r4d249KbQ1SFdpeStvob8Ih6aPPIzfqllPVOtvhve6ZcpuVcYo5/7zUWckKpHE7StASX4kTKZTLf0WQm/wPkcg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/tsconfig-utils@8.62.0':
- resolution: {integrity: sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==}
+ '@typescript-eslint/tsconfig-utils@8.62.1':
+ resolution: {integrity: sha512-xadytJqX9vJVQ2fdQjkcIVigwaOJNWkpjdLt6cEQ+xPnrI1fkp+/jZE/I97k9KUjqtpd25i0HeyZf3T6dutv2g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/type-utils@8.62.0':
- resolution: {integrity: sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==}
+ '@typescript-eslint/type-utils@8.62.1':
+ resolution: {integrity: sha512-aXM5xlqXiTxPibXB93cLAURfT3rlizf7uMXISCXy66Isr/9hISJx3yDsKl0L7lKa51b8JpFuNKby0/O0pEm9jg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/types@8.62.0':
- resolution: {integrity: sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==}
+ '@typescript-eslint/types@8.62.1':
+ resolution: {integrity: sha512-ooCzJFaf+Hg+uG6fA3NRFGuFjlfNlDhBthbv4ZPU/0elCAFUfnyXUvf/WOpHz/jYwSmvU2GkR2LtyUfy1AxZ1Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@typescript-eslint/typescript-estree@8.62.0':
- resolution: {integrity: sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==}
+ '@typescript-eslint/typescript-estree@8.62.1':
+ resolution: {integrity: sha512-xMcW9oP9u7fAMXYs9A65CVmtLQe2r//oXINHfi8HV+oiqhih17sbLdhXr4540YWlgpDKQdY854OL5ZrdCiQsAA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/utils@8.62.0':
- resolution: {integrity: sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==}
+ '@typescript-eslint/utils@8.62.1':
+ resolution: {integrity: sha512-sHtbPfuKNZCG+ih8SyjjucqRntSVmp8XgL5u6o9mAhiSn8ds5o/M/XdM0abweme2Tln3szOstOrZ9OXitvPh0g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
typescript: '>=4.8.4 <6.1.0'
- '@typescript-eslint/visitor-keys@8.62.0':
- resolution: {integrity: sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==}
+ '@typescript-eslint/visitor-keys@8.62.1':
+ resolution: {integrity: sha512-4g3BLxfdTMy8iZG0MaBkadnlRrCJ74cQiFbyEVMrkwIoqdyaXXQM22cotDvrl4x28wgIZ9rEJRoM+mmhSJpJ1g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@vitejs/plugin-basic-ssl@2.3.0':
@@ -2397,7 +2393,7 @@ packages:
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
peerDependencies:
- ajv: ^8.5.0
+ ajv: ^8.18.0
peerDependenciesMeta:
ajv:
optional: true
@@ -2405,7 +2401,7 @@ packages:
ajv-formats@2.1.1:
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependencies:
- ajv: ^8.0.0
+ ajv: ^8.18.0
peerDependenciesMeta:
ajv:
optional: true
@@ -2413,7 +2409,7 @@ packages:
ajv-formats@3.0.1:
resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
peerDependencies:
- ajv: ^8.0.0
+ ajv: ^8.18.0
peerDependenciesMeta:
ajv:
optional: true
@@ -2421,14 +2417,11 @@ packages:
ajv-keywords@5.1.0:
resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==}
peerDependencies:
- ajv: ^8.8.2
+ ajv: ^8.18.0
ajv@6.15.0:
resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==}
- ajv@8.13.0:
- resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
-
ajv@8.18.0:
resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==}
@@ -2921,8 +2914,8 @@ packages:
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
engines: {node: '>= 0.4'}
- esbuild@0.27.7:
- resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ esbuild@0.27.2:
+ resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
engines: {node: '>=18'}
hasBin: true
@@ -3122,6 +3115,9 @@ packages:
fast-uri@3.1.2:
resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==}
+ fast-uri@3.1.3:
+ resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==}
+
fast-wrap-ansi@0.2.2:
resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
@@ -3188,8 +3184,8 @@ packages:
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
engines: {node: '>= 0.8'}
- fs-extra@11.3.5:
- resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==}
+ fs-extra@11.3.6:
+ resolution: {integrity: sha512-w8ZNZr2mKIc7qeNaQ9AVPT1+iFaI+Avd4xudVOvdDJ8VytREi1Ft5Ih7hd9jjehod8vAM5GMsfQ/TpPf4EyoEA==}
engines: {node: '>=14.14'}
fs-minipass@3.0.3:
@@ -3381,8 +3377,8 @@ packages:
engines: {node: '>=0.10.0'}
hasBin: true
- immutable@5.1.8:
- resolution: {integrity: sha512-TM5YqrGeTsVIPPpILzeqZ8D2Zc2TvNgSDi88zPF2a4cyqQdWV/wVWBDRDbNzzrLeRWScrFcOX9lW2iX6GOtUDw==}
+ immutable@5.1.9:
+ resolution: {integrity: sha512-m8nVez3rwrgmWxtLMt1ZYXB2Lv7OKYn/disyxAlSDYAlKSlFoPPfIAmAM/M5xqL4m4C/wAPw7S2/CNaUii1Hxg==}
import-lazy@4.0.0:
resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==}
@@ -3770,8 +3766,8 @@ packages:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
- lodash@4.17.23:
- resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
+ lodash@4.18.1:
+ resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
log-symbols@7.0.1:
resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==}
@@ -3867,10 +3863,6 @@ packages:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
- minimatch@10.0.3:
- resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==}
- engines: {node: 20 || >=22}
-
minimatch@10.2.5:
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: 18 || 20 || >=22}
@@ -4212,8 +4204,8 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
- prettier@3.9.1:
- resolution: {integrity: sha512-ppiDo2CSwexck1eyZUwJHg/N3nf1+6IRCv7W/VJ5vaLnVCmB7+3CdRfMwoCHBBX6xTrREDTksZ4OZl5SSf4zXA==}
+ prettier@3.9.4:
+ resolution: {integrity: sha512-yWG/o/4oJfo036EKAfK6ACAoDOfHeRHx4tuxkfBZiauURiaSmYwlpOr5LQqKtIkRD2z1PLteme2WoxEnj4tHTg==}
engines: {node: '>=14'}
hasBin: true
@@ -4911,8 +4903,8 @@ packages:
peerDependencies:
typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x
- typescript-eslint@8.62.0:
- resolution: {integrity: sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==}
+ typescript-eslint@8.62.1:
+ resolution: {integrity: sha512-vymnnM5g0AKQDSAyfP12nMIBvgwgA42syg74kkuZ4x1VuTzwQKwc5h9rGxeShCjny5o+zWAb6OEoz7XLgrIkIw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies:
eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
@@ -4945,8 +4937,8 @@ packages:
resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==}
engines: {node: '>=18.17'}
- undici@7.26.0:
- resolution: {integrity: sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==}
+ undici@7.28.0:
+ resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==}
engines: {node: '>=20.18.1'}
unicorn-magic@0.3.0:
@@ -5106,8 +5098,8 @@ packages:
yaml:
optional: true
- vite@8.1.0:
- resolution: {integrity: sha512-BuJcQK/56NQTWDGn4ABea3q4SSBdNPWwNZKTkkUpcMPnLoquSYH8llRtSUIgoL1KSCpHt5eghLShn50mH36y7Q==}
+ vite@8.1.1:
+ resolution: {integrity: sha512-X/05/cT+VITy2AeDc1der6smvGWWREtL4hPbPTaVbjSBuuWkmNOjR6HP3NzqcQA2nF6VHGUPaFRJyft/2AE9Kg==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
peerDependencies:
@@ -5488,23 +5480,23 @@ snapshots:
'@angular-eslint/bundled-angular-compiler@22.0.0': {}
- '@angular-eslint/eslint-plugin-template@22.0.0(@angular-eslint/template-parser@22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(@typescript-eslint/types@8.62.0)(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@angular-eslint/eslint-plugin-template@22.0.0(@angular-eslint/template-parser@22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(@typescript-eslint/types@8.62.1)(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@angular-eslint/bundled-angular-compiler': 22.0.0
'@angular-eslint/template-parser': 22.0.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@angular-eslint/utils': 22.0.0(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@angular-eslint/utils': 22.0.0(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
aria-query: 5.3.2
axobject-query: 4.1.0
eslint: 10.6.0(jiti@2.7.0)
typescript: 6.0.3
- '@angular-eslint/eslint-plugin@22.0.0(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@angular-eslint/eslint-plugin@22.0.0(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@angular-eslint/bundled-angular-compiler': 22.0.0
- '@angular-eslint/utils': 22.0.0(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@angular-eslint/utils': 22.0.0(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
eslint: 10.6.0(jiti@2.7.0)
ts-api-utils: 2.5.0(typescript@6.0.3)
typescript: 6.0.3
@@ -5516,10 +5508,10 @@ snapshots:
eslint-scope: 9.1.2
typescript: 6.0.3
- '@angular-eslint/utils@22.0.0(@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@angular-eslint/utils@22.0.0(@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@angular-eslint/bundled-angular-compiler': 22.0.0
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
eslint: 10.6.0(jiti@2.7.0)
typescript: 6.0.3
@@ -5535,7 +5527,7 @@ snapshots:
'@angular-devkit/architect': 0.2200.4(chokidar@5.0.0)
'@angular/compiler': 22.0.4
'@angular/compiler-cli': 22.0.4(@angular/compiler@22.0.4)(typescript@6.0.3)
- '@babel/core': 7.29.0
+ '@babel/core': 7.29.7
'@babel/helper-annotate-as-pure': 7.27.3
'@babel/helper-split-export-declaration': 7.24.7
'@inquirer/confirm': 6.0.12(@types/node@26.0.1)
@@ -5567,7 +5559,7 @@ snapshots:
less: 4.6.4
lmdb: 3.5.4
postcss: 8.5.16
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
transitivePeerDependencies:
- '@types/node'
- chokidar
@@ -5697,26 +5689,6 @@ snapshots:
'@babel/compat-data@7.29.7': {}
- '@babel/core@7.29.0':
- dependencies:
- '@babel/code-frame': 7.29.7
- '@babel/generator': 7.29.7
- '@babel/helper-compilation-targets': 7.29.7
- '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0)
- '@babel/helpers': 7.29.7
- '@babel/parser': 7.29.7
- '@babel/template': 7.29.7
- '@babel/traverse': 7.29.7
- '@babel/types': 7.29.7
- '@jridgewell/remapping': 2.3.5
- convert-source-map: 2.0.0
- debug: 4.4.3
- gensync: 1.0.0-beta.2
- json5: 2.2.3
- semver: 6.3.1
- transitivePeerDependencies:
- - supports-color
-
'@babel/core@7.29.7':
dependencies:
'@babel/code-frame': 7.29.7
@@ -5766,15 +5738,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-module-imports': 7.29.7
- '@babel/helper-validator-identifier': 7.29.7
- '@babel/traverse': 7.29.7
- transitivePeerDependencies:
- - supports-color
-
'@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)':
dependencies:
'@babel/core': 7.29.7
@@ -5881,157 +5844,157 @@ snapshots:
'@endo/immutable-arraybuffer@1.1.2': {}
- '@esbuild/aix-ppc64@0.27.7':
+ '@esbuild/aix-ppc64@0.27.2':
optional: true
'@esbuild/aix-ppc64@0.28.1':
optional: true
- '@esbuild/android-arm64@0.27.7':
+ '@esbuild/android-arm64@0.27.2':
optional: true
'@esbuild/android-arm64@0.28.1':
optional: true
- '@esbuild/android-arm@0.27.7':
+ '@esbuild/android-arm@0.27.2':
optional: true
'@esbuild/android-arm@0.28.1':
optional: true
- '@esbuild/android-x64@0.27.7':
+ '@esbuild/android-x64@0.27.2':
optional: true
'@esbuild/android-x64@0.28.1':
optional: true
- '@esbuild/darwin-arm64@0.27.7':
+ '@esbuild/darwin-arm64@0.27.2':
optional: true
'@esbuild/darwin-arm64@0.28.1':
optional: true
- '@esbuild/darwin-x64@0.27.7':
+ '@esbuild/darwin-x64@0.27.2':
optional: true
'@esbuild/darwin-x64@0.28.1':
optional: true
- '@esbuild/freebsd-arm64@0.27.7':
+ '@esbuild/freebsd-arm64@0.27.2':
optional: true
'@esbuild/freebsd-arm64@0.28.1':
optional: true
- '@esbuild/freebsd-x64@0.27.7':
+ '@esbuild/freebsd-x64@0.27.2':
optional: true
'@esbuild/freebsd-x64@0.28.1':
optional: true
- '@esbuild/linux-arm64@0.27.7':
+ '@esbuild/linux-arm64@0.27.2':
optional: true
'@esbuild/linux-arm64@0.28.1':
optional: true
- '@esbuild/linux-arm@0.27.7':
+ '@esbuild/linux-arm@0.27.2':
optional: true
'@esbuild/linux-arm@0.28.1':
optional: true
- '@esbuild/linux-ia32@0.27.7':
+ '@esbuild/linux-ia32@0.27.2':
optional: true
'@esbuild/linux-ia32@0.28.1':
optional: true
- '@esbuild/linux-loong64@0.27.7':
+ '@esbuild/linux-loong64@0.27.2':
optional: true
'@esbuild/linux-loong64@0.28.1':
optional: true
- '@esbuild/linux-mips64el@0.27.7':
+ '@esbuild/linux-mips64el@0.27.2':
optional: true
'@esbuild/linux-mips64el@0.28.1':
optional: true
- '@esbuild/linux-ppc64@0.27.7':
+ '@esbuild/linux-ppc64@0.27.2':
optional: true
'@esbuild/linux-ppc64@0.28.1':
optional: true
- '@esbuild/linux-riscv64@0.27.7':
+ '@esbuild/linux-riscv64@0.27.2':
optional: true
'@esbuild/linux-riscv64@0.28.1':
optional: true
- '@esbuild/linux-s390x@0.27.7':
+ '@esbuild/linux-s390x@0.27.2':
optional: true
'@esbuild/linux-s390x@0.28.1':
optional: true
- '@esbuild/linux-x64@0.27.7':
+ '@esbuild/linux-x64@0.27.2':
optional: true
'@esbuild/linux-x64@0.28.1':
optional: true
- '@esbuild/netbsd-arm64@0.27.7':
+ '@esbuild/netbsd-arm64@0.27.2':
optional: true
'@esbuild/netbsd-arm64@0.28.1':
optional: true
- '@esbuild/netbsd-x64@0.27.7':
+ '@esbuild/netbsd-x64@0.27.2':
optional: true
'@esbuild/netbsd-x64@0.28.1':
optional: true
- '@esbuild/openbsd-arm64@0.27.7':
+ '@esbuild/openbsd-arm64@0.27.2':
optional: true
'@esbuild/openbsd-arm64@0.28.1':
optional: true
- '@esbuild/openbsd-x64@0.27.7':
+ '@esbuild/openbsd-x64@0.27.2':
optional: true
'@esbuild/openbsd-x64@0.28.1':
optional: true
- '@esbuild/openharmony-arm64@0.27.7':
+ '@esbuild/openharmony-arm64@0.27.2':
optional: true
'@esbuild/openharmony-arm64@0.28.1':
optional: true
- '@esbuild/sunos-x64@0.27.7':
+ '@esbuild/sunos-x64@0.27.2':
optional: true
'@esbuild/sunos-x64@0.28.1':
optional: true
- '@esbuild/win32-arm64@0.27.7':
+ '@esbuild/win32-arm64@0.27.2':
optional: true
'@esbuild/win32-arm64@0.28.1':
optional: true
- '@esbuild/win32-ia32@0.27.7':
+ '@esbuild/win32-ia32@0.27.2':
optional: true
'@esbuild/win32-ia32@0.28.1':
optional: true
- '@esbuild/win32-x64@0.27.7':
+ '@esbuild/win32-x64@0.27.2':
optional: true
'@esbuild/win32-x64@0.28.1':
@@ -6232,14 +6195,6 @@ snapshots:
optionalDependencies:
'@types/node': 26.0.1
- '@isaacs/balanced-match@4.0.1':
- optional: true
-
- '@isaacs/brace-expansion@5.0.1':
- dependencies:
- '@isaacs/balanced-match': 4.0.1
- optional: true
-
'@isaacs/fs-minipass@4.0.1':
dependencies:
minipass: 7.1.3
@@ -6320,8 +6275,8 @@ snapshots:
'@rushstack/terminal': 0.21.0(@types/node@26.0.1)
'@rushstack/ts-command-line': 5.1.7(@types/node@26.0.1)
diff: 8.0.4
- lodash: 4.17.23
- minimatch: 10.0.3
+ lodash: 4.18.1
+ minimatch: 10.2.5
resolve: 1.22.12
semver: 7.5.4
source-map: 0.6.1
@@ -6510,7 +6465,7 @@ snapshots:
'@npmcli/fs@5.0.0':
dependencies:
- semver: 7.8.5
+ semver: 7.7.4
'@npmcli/git@7.0.2':
dependencies:
@@ -6520,7 +6475,7 @@ snapshots:
lru-cache: 11.5.1
npm-pick-manifest: 11.0.3
proc-log: 6.1.0
- semver: 7.8.5
+ semver: 7.7.4
which: 6.0.1
'@npmcli/installed-package-contents@4.0.0':
@@ -6537,7 +6492,7 @@ snapshots:
hosted-git-info: 9.0.3
json-parse-even-better-errors: 5.0.0
proc-log: 6.1.0
- semver: 7.8.5
+ semver: 7.7.4
spdx-expression-parse: 4.0.0
'@npmcli/promise-spawn@9.0.1':
@@ -6895,10 +6850,10 @@ snapshots:
'@rushstack/node-core-library@5.19.1(@types/node@26.0.1)':
dependencies:
- ajv: 8.13.0
- ajv-draft-04: 1.0.0(ajv@8.13.0)
- ajv-formats: 3.0.1(ajv@8.13.0)
- fs-extra: 11.3.5
+ ajv: 8.20.0
+ ajv-draft-04: 1.0.0(ajv@8.20.0)
+ ajv-formats: 3.0.1(ajv@8.20.0)
+ fs-extra: 11.3.6
import-lazy: 4.0.0
jju: 1.4.0
resolve: 1.22.12
@@ -7073,14 +7028,14 @@ snapshots:
dependencies:
'@types/yargs-parser': 21.0.3
- '@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@eslint-community/regexpp': 4.12.2
- '@typescript-eslint/parser': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/scope-manager': 8.62.0
- '@typescript-eslint/type-utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/visitor-keys': 8.62.0
+ '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/scope-manager': 8.62.1
+ '@typescript-eslint/type-utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/visitor-keys': 8.62.1
eslint: 10.6.0(jiti@2.7.0)
ignore: 7.0.5
natural-compare: 1.4.0
@@ -7089,41 +7044,41 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/scope-manager': 8.62.0
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/visitor-keys': 8.62.0
+ '@typescript-eslint/scope-manager': 8.62.1
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/visitor-keys': 8.62.1
debug: 4.4.3
eslint: 10.6.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/project-service@8.62.0(typescript@6.0.3)':
+ '@typescript-eslint/project-service@8.62.1(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/types': 8.62.0
+ '@typescript-eslint/tsconfig-utils': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/types': 8.62.1
debug: 4.4.3
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/scope-manager@8.62.0':
+ '@typescript-eslint/scope-manager@8.62.1':
dependencies:
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/visitor-keys': 8.62.0
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/visitor-keys': 8.62.1
- '@typescript-eslint/tsconfig-utils@8.62.0(typescript@6.0.3)':
+ '@typescript-eslint/tsconfig-utils@8.62.1(typescript@6.0.3)':
dependencies:
typescript: 6.0.3
- '@typescript-eslint/type-utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/type-utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
debug: 4.4.3
eslint: 10.6.0(jiti@2.7.0)
ts-api-utils: 2.5.0(typescript@6.0.3)
@@ -7131,14 +7086,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/types@8.62.0': {}
+ '@typescript-eslint/types@8.62.1': {}
- '@typescript-eslint/typescript-estree@8.62.0(typescript@6.0.3)':
+ '@typescript-eslint/typescript-estree@8.62.1(typescript@6.0.3)':
dependencies:
- '@typescript-eslint/project-service': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/tsconfig-utils': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/visitor-keys': 8.62.0
+ '@typescript-eslint/project-service': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/tsconfig-utils': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/visitor-keys': 8.62.1
debug: 4.4.3
minimatch: 10.2.5
semver: 7.8.5
@@ -7148,20 +7103,20 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/utils@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
+ '@typescript-eslint/utils@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)':
dependencies:
'@eslint-community/eslint-utils': 4.9.1(eslint@10.6.0(jiti@2.7.0))
- '@typescript-eslint/scope-manager': 8.62.0
- '@typescript-eslint/types': 8.62.0
- '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3)
+ '@typescript-eslint/scope-manager': 8.62.1
+ '@typescript-eslint/types': 8.62.1
+ '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3)
eslint: 10.6.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
- supports-color
- '@typescript-eslint/visitor-keys@8.62.0':
+ '@typescript-eslint/visitor-keys@8.62.1':
dependencies:
- '@typescript-eslint/types': 8.62.0
+ '@typescript-eslint/types': 8.62.1
eslint-visitor-keys: 5.0.1
'@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(less@4.6.4)(lightningcss@1.32.0)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))':
@@ -7180,7 +7135,7 @@ snapshots:
obug: 2.1.3
std-env: 4.1.0
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/expect@4.1.9':
dependencies:
@@ -7191,13 +7146,13 @@ snapshots:
chai: 6.2.2
tinyrainbow: 3.1.0
- '@vitest/mocker@4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))':
+ '@vitest/mocker@4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))':
dependencies:
'@vitest/spy': 4.1.9
estree-walker: 3.0.3
magic-string: 0.30.21
optionalDependencies:
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
'@vitest/pretty-format@4.1.9':
dependencies:
@@ -7226,7 +7181,7 @@ snapshots:
sirv: 3.0.2
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
- vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ vitest: 4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/utils@4.1.9':
dependencies:
@@ -7375,9 +7330,9 @@ snapshots:
agent-base@9.0.0: {}
- ajv-draft-04@1.0.0(ajv@8.13.0):
+ ajv-draft-04@1.0.0(ajv@8.20.0):
optionalDependencies:
- ajv: 8.13.0
+ ajv: 8.20.0
optional: true
ajv-formats@2.1.1(ajv@8.20.0):
@@ -7385,11 +7340,6 @@ snapshots:
ajv: 8.20.0
optional: true
- ajv-formats@3.0.1(ajv@8.13.0):
- optionalDependencies:
- ajv: 8.13.0
- optional: true
-
ajv-formats@3.0.1(ajv@8.20.0):
optionalDependencies:
ajv: 8.20.0
@@ -7407,18 +7357,10 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
- ajv@8.13.0:
- dependencies:
- fast-deep-equal: 3.1.3
- json-schema-traverse: 1.0.0
- require-from-string: 2.0.2
- uri-js: 4.4.1
- optional: true
-
ajv@8.18.0:
dependencies:
fast-deep-equal: 3.1.3
- fast-uri: 3.1.2
+ fast-uri: 3.1.3
json-schema-traverse: 1.0.0
require-from-string: 2.0.2
optional: true
@@ -8031,34 +7973,34 @@ snapshots:
is-date-object: 1.1.0
is-symbol: 1.1.1
- esbuild@0.27.7:
+ esbuild@0.27.2:
optionalDependencies:
- '@esbuild/aix-ppc64': 0.27.7
- '@esbuild/android-arm': 0.27.7
- '@esbuild/android-arm64': 0.27.7
- '@esbuild/android-x64': 0.27.7
- '@esbuild/darwin-arm64': 0.27.7
- '@esbuild/darwin-x64': 0.27.7
- '@esbuild/freebsd-arm64': 0.27.7
- '@esbuild/freebsd-x64': 0.27.7
- '@esbuild/linux-arm': 0.27.7
- '@esbuild/linux-arm64': 0.27.7
- '@esbuild/linux-ia32': 0.27.7
- '@esbuild/linux-loong64': 0.27.7
- '@esbuild/linux-mips64el': 0.27.7
- '@esbuild/linux-ppc64': 0.27.7
- '@esbuild/linux-riscv64': 0.27.7
- '@esbuild/linux-s390x': 0.27.7
- '@esbuild/linux-x64': 0.27.7
- '@esbuild/netbsd-arm64': 0.27.7
- '@esbuild/netbsd-x64': 0.27.7
- '@esbuild/openbsd-arm64': 0.27.7
- '@esbuild/openbsd-x64': 0.27.7
- '@esbuild/openharmony-arm64': 0.27.7
- '@esbuild/sunos-x64': 0.27.7
- '@esbuild/win32-arm64': 0.27.7
- '@esbuild/win32-ia32': 0.27.7
- '@esbuild/win32-x64': 0.27.7
+ '@esbuild/aix-ppc64': 0.27.2
+ '@esbuild/android-arm': 0.27.2
+ '@esbuild/android-arm64': 0.27.2
+ '@esbuild/android-x64': 0.27.2
+ '@esbuild/darwin-arm64': 0.27.2
+ '@esbuild/darwin-x64': 0.27.2
+ '@esbuild/freebsd-arm64': 0.27.2
+ '@esbuild/freebsd-x64': 0.27.2
+ '@esbuild/linux-arm': 0.27.2
+ '@esbuild/linux-arm64': 0.27.2
+ '@esbuild/linux-ia32': 0.27.2
+ '@esbuild/linux-loong64': 0.27.2
+ '@esbuild/linux-mips64el': 0.27.2
+ '@esbuild/linux-ppc64': 0.27.2
+ '@esbuild/linux-riscv64': 0.27.2
+ '@esbuild/linux-s390x': 0.27.2
+ '@esbuild/linux-x64': 0.27.2
+ '@esbuild/netbsd-arm64': 0.27.2
+ '@esbuild/netbsd-x64': 0.27.2
+ '@esbuild/openbsd-arm64': 0.27.2
+ '@esbuild/openbsd-x64': 0.27.2
+ '@esbuild/openharmony-arm64': 0.27.2
+ '@esbuild/sunos-x64': 0.27.2
+ '@esbuild/win32-arm64': 0.27.2
+ '@esbuild/win32-ia32': 0.27.2
+ '@esbuild/win32-x64': 0.27.2
esbuild@0.28.1:
optionalDependencies:
@@ -8107,17 +8049,17 @@ snapshots:
transitivePeerDependencies:
- supports-color
- eslint-module-utils@2.13.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0(jiti@2.7.0)):
+ eslint-module-utils@2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0(jiti@2.7.0)):
dependencies:
debug: 3.2.7
optionalDependencies:
- '@typescript-eslint/parser': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
eslint: 10.6.0(jiti@2.7.0)
eslint-import-resolver-node: 0.3.10
transitivePeerDependencies:
- supports-color
- eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0)):
+ eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.9
@@ -8128,7 +8070,7 @@ snapshots:
doctrine: 2.1.0
eslint: 10.6.0(jiti@2.7.0)
eslint-import-resolver-node: 0.3.10
- eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0(jiti@2.7.0))
+ eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.6.0(jiti@2.7.0))
hasown: 2.0.4
is-core-module: 2.16.2
is-glob: 4.0.3
@@ -8140,7 +8082,7 @@ snapshots:
string.prototype.trimend: 1.0.9
tsconfig-paths: 3.15.0
optionalDependencies:
- '@typescript-eslint/parser': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
transitivePeerDependencies:
- eslint-import-resolver-typescript
- eslint-import-resolver-webpack
@@ -8198,11 +8140,11 @@ snapshots:
string.prototype.matchall: 4.0.12
string.prototype.repeat: 1.0.0
- eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0)):
+ eslint-plugin-unused-imports@4.4.1(@typescript-eslint/eslint-plugin@8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0)):
dependencies:
eslint: 10.6.0(jiti@2.7.0)
optionalDependencies:
- '@typescript-eslint/eslint-plugin': 8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
eslint-scope@5.1.1:
dependencies:
@@ -8356,6 +8298,9 @@ snapshots:
fast-uri@3.1.2: {}
+ fast-uri@3.1.3:
+ optional: true
+
fast-wrap-ansi@0.2.2:
dependencies:
fast-string-width: 3.0.2
@@ -8420,7 +8365,7 @@ snapshots:
fresh@2.0.0: {}
- fs-extra@11.3.5:
+ fs-extra@11.3.6:
dependencies:
graceful-fs: 4.2.11
jsonfile: 6.2.1
@@ -8632,7 +8577,7 @@ snapshots:
image-size@0.5.5:
optional: true
- immutable@5.1.8: {}
+ immutable@5.1.9: {}
import-lazy@4.0.0:
optional: true
@@ -8854,7 +8799,7 @@ snapshots:
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 6.0.1
- undici: 7.26.0
+ undici: 7.28.0
w3c-xmlserializer: 5.0.0
webidl-conversions: 8.0.1
whatwg-mimetype: 5.0.0
@@ -9031,7 +8976,7 @@ snapshots:
dependencies:
p-locate: 5.0.0
- lodash@4.17.23:
+ lodash@4.18.1:
optional: true
log-symbols@7.0.1:
@@ -9140,11 +9085,6 @@ snapshots:
mimic-function@5.0.1: {}
- minimatch@10.0.3:
- dependencies:
- '@isaacs/brace-expansion': 5.0.1
- optional: true
-
minimatch@10.2.5:
dependencies:
brace-expansion: 5.0.7
@@ -9263,7 +9203,7 @@ snapshots:
graceful-fs: 4.2.11
nopt: 9.0.0
proc-log: 6.1.0
- semver: 7.8.5
+ semver: 7.7.4
tar: 7.5.19
tinyglobby: 0.2.17
undici: 6.27.0
@@ -9283,7 +9223,7 @@ snapshots:
npm-install-checks@8.0.0:
dependencies:
- semver: 7.8.5
+ semver: 7.7.4
npm-normalize-package-bin@5.0.0: {}
@@ -9304,7 +9244,7 @@ snapshots:
npm-install-checks: 8.0.0
npm-normalize-package-bin: 5.0.0
npm-package-arg: 13.0.2
- semver: 7.8.5
+ semver: 7.7.4
npm-registry-fetch@19.1.1:
dependencies:
@@ -9534,7 +9474,7 @@ snapshots:
prelude-ls@1.2.1: {}
- prettier@3.9.1: {}
+ prettier@3.9.4: {}
proc-log@6.1.0: {}
@@ -9846,7 +9786,7 @@ snapshots:
dependencies:
'@bufbuild/protobuf': 2.12.1
colorjs.io: 0.5.2
- immutable: 5.1.8
+ immutable: 5.1.9
rxjs: 7.8.2
supports-color: 8.1.1
sync-child-process: 1.0.2
@@ -9875,7 +9815,7 @@ snapshots:
sass@1.97.3:
dependencies:
chokidar: 4.0.3
- immutable: 5.1.8
+ immutable: 5.1.9
source-map-js: 1.2.1
optionalDependencies:
'@parcel/watcher': 2.5.6
@@ -9884,7 +9824,7 @@ snapshots:
sass@1.99.0:
dependencies:
chokidar: 4.0.3
- immutable: 5.1.8
+ immutable: 5.1.9
source-map-js: 1.2.1
optionalDependencies:
'@parcel/watcher': 2.5.6
@@ -10364,12 +10304,12 @@ snapshots:
typescript: 6.0.3
yaml: 2.9.0
- typescript-eslint@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3):
+ typescript-eslint@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3):
dependencies:
- '@typescript-eslint/eslint-plugin': 8.62.0(@typescript-eslint/parser@8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/parser': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
- '@typescript-eslint/typescript-estree': 8.62.0(typescript@6.0.3)
- '@typescript-eslint/utils': 8.62.0(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/eslint-plugin': 8.62.1(@typescript-eslint/parser@8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/parser': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
+ '@typescript-eslint/typescript-estree': 8.62.1(typescript@6.0.3)
+ '@typescript-eslint/utils': 8.62.1(eslint@10.6.0(jiti@2.7.0))(typescript@6.0.3)
eslint: 10.6.0(jiti@2.7.0)
typescript: 6.0.3
transitivePeerDependencies:
@@ -10395,7 +10335,7 @@ snapshots:
undici@6.27.0: {}
- undici@7.26.0: {}
+ undici@7.28.0: {}
unicorn-magic@0.3.0: {}
@@ -10403,7 +10343,7 @@ snapshots:
unpipe@1.0.0: {}
- unplugin-dts@1.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16)):
+ unplugin-dts@1.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16)):
dependencies:
'@rollup/pluginutils': 5.4.0(rollup@4.60.4)
'@volar/typescript': 2.4.28
@@ -10420,7 +10360,7 @@ snapshots:
esbuild: 0.28.1
rolldown: 1.1.3
rollup: 4.60.4
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
webpack: 5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16)
transitivePeerDependencies:
- supports-color
@@ -10449,7 +10389,7 @@ snapshots:
vary@1.1.2: {}
- vite-plugin-checker@0.14.4(eslint@10.6.0(jiti@2.7.0))(optionator@0.9.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
+ vite-plugin-checker@0.14.4(eslint@10.6.0(jiti@2.7.0))(optionator@0.9.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@babel/code-frame': 7.29.7
chokidar: 5.0.0
@@ -10458,19 +10398,19 @@ snapshots:
picomatch: 4.0.4
proper-lockfile: 4.1.2
tiny-invariant: 1.3.3
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
optionalDependencies:
eslint: 10.6.0(jiti@2.7.0)
optionator: 0.9.4
typescript: 6.0.3
- vite-plugin-dts@5.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16)):
+ vite-plugin-dts@5.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16)):
dependencies:
- unplugin-dts: 1.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16))
+ unplugin-dts: 1.0.3(@microsoft/api-extractor@7.56.0(@types/node@26.0.1))(@rspack/core@1.6.8(@swc/helpers@0.5.18))(esbuild@0.28.1)(rolldown@1.1.3)(rollup@4.60.4)(typescript@6.0.3)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))(webpack@5.106.2(esbuild@0.28.1)(lightningcss@1.32.0)(postcss@8.5.16))
optionalDependencies:
'@microsoft/api-extractor': 7.56.0(@types/node@26.0.1)
rollup: 4.60.4
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
transitivePeerDependencies:
- '@rspack/core'
- '@vue/language-core'
@@ -10480,17 +10420,17 @@ snapshots:
- typescript
- webpack
- vite-plugin-static-copy@4.1.1(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
+ vite-plugin-static-copy@4.1.1(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
chokidar: 3.6.0
p-map: 7.0.4
picocolors: 1.1.1
tinyglobby: 0.2.17
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(less@4.6.4)(lightningcss@1.32.0)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
- esbuild: 0.27.7
+ esbuild: 0.27.2
fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4
postcss: 8.5.16
@@ -10508,7 +10448,7 @@ snapshots:
tsx: 4.22.4
yaml: 2.9.0
- vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0):
+ vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0):
dependencies:
lightningcss: 1.32.0
picomatch: 4.0.4
@@ -10527,10 +10467,10 @@ snapshots:
tsx: 4.22.4
yaml: 2.9.0
- vitest@4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
+ vitest@4.1.9(@types/node@26.0.1)(@vitest/coverage-v8@4.1.9)(@vitest/ui@4.1.9)(happy-dom@20.10.6)(jsdom@29.1.1)(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)):
dependencies:
'@vitest/expect': 4.1.9
- '@vitest/mocker': 4.1.9(vite@8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
+ '@vitest/mocker': 4.1.9(vite@8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0))
'@vitest/pretty-format': 4.1.9
'@vitest/runner': 4.1.9
'@vitest/snapshot': 4.1.9
@@ -10547,7 +10487,7 @@ snapshots:
tinyexec: 1.2.4
tinyglobby: 0.2.17
tinyrainbow: 3.1.0
- vite: 8.1.0(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
+ vite: 8.1.1(@types/node@26.0.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.6.4)(sass-embedded@1.97.3)(sass@1.99.0)(terser@5.46.2)(tsx@4.22.4)(yaml@2.9.0)
why-is-node-running: 2.3.0
optionalDependencies:
'@types/node': 26.0.1
diff --git a/plugins/pnpm-workspace.yaml b/plugins/pnpm-workspace.yaml
index cb6f1a1554..ce14894b25 100644
--- a/plugins/pnpm-workspace.yaml
+++ b/plugins/pnpm-workspace.yaml
@@ -13,6 +13,22 @@ allowBuilds:
linkWorkspacePackages: true
+minimumReleaseAgeExclude:
+ - minimatch@10.2.1 || 10.2.3
+ - ajv@8.18.0
+ - lodash@4.17.24
+ - esbuild@0.28.1
+ - '@babel/core@7.29.1'
+ - undici@7.28.0
+
+overrides:
+ '@babel/core@<=7.29.0': ^7.29.1
+ ajv@>=7.0.0-alpha.0 <8.18.0: ^8.18.0
+ lodash@<=4.17.23: ^4.17.24
+ lodash@>=4.0.0 <=4.17.23: ^4.17.24
+ minimatch@>=10.0.0 <10.2.1: ^10.2.1
+ minimatch@>=10.0.0 <10.2.3: ^10.2.3
+
peerDependencyRules:
allowedVersions:
"eslint-plugin-import>eslint": "10.6.0"
diff --git a/render-wasm/src/main.rs b/render-wasm/src/main.rs
index 0aa3fae930..ffa8d34ca3 100644
--- a/render-wasm/src/main.rs
+++ b/render-wasm/src/main.rs
@@ -733,7 +733,11 @@ pub extern "C" fn set_shape_svg_raw_content() -> Result<()> {
.map_err(|e| Error::RecoverableError(e.to_string()))?
.trim_end_matches('\0')
.to_string();
+
+ let render_state = get_render_state();
+ let font_manager = skia::FontMgr::from(render_state.fonts().font_provider().clone());
shape.set_svg_raw_content(svg_raw_content);
+ shape.update_svg_raw_content(font_manager);
});
Ok(())
diff --git a/render-wasm/src/render.rs b/render-wasm/src/render.rs
index ee4ebe3bd0..a75d2fcb8e 100644
--- a/render-wasm/src/render.rs
+++ b/render-wasm/src/render.rs
@@ -410,6 +410,11 @@ pub(crate) struct RenderState {
/// GPU crops from `Backbuffer` or tile atlas keyed by shape id. Filled on full-frame completion; during
/// drag, entries for the moved top-level selection are ensured here
pub backbuffer_crop_cache: HashMap,
+ /// Whether we've already forced a GPU flush+submit before a tile-atlas
+ /// snapshot this render. The first snapshot of a pass can otherwise capture
+ /// a tile before its text glyph uploads complete (blank first/center tile).
+ /// One explicit flush warms the submit path for the rest of the pass.
+ pub tile_atlas_flushed: bool,
}
pub struct InteractiveDragCrop {
@@ -592,6 +597,7 @@ impl RenderState {
interactive_target_seeded: false,
preserve_target_during_render: false,
backbuffer_crop_cache: HashMap::default(),
+ tile_atlas_flushed: false,
})
}
@@ -1020,6 +1026,10 @@ impl RenderState {
.as_ref()
.ok_or(Error::CriticalError("Current tile not found".to_string()))?;
+ if self.tile_atlas_flushed {
+ crate::get_gpu_state().context.flush_and_submit();
+ }
+
self.surfaces.draw_current_tile_into_tile_atlas(
&self.tile_viewbox,
¤t_tile,
@@ -1386,7 +1396,7 @@ impl RenderState {
}
match &shape.shape_type {
- Type::SVGRaw(sr) => {
+ Type::SVGRaw(_) => {
if let Some(svg_transform) = shape.svg_transform() {
matrix.pre_concat(&svg_transform);
}
@@ -1398,21 +1408,13 @@ impl RenderState {
if let Some(svg) = shape.svg.as_ref() {
svg.render(self.surfaces.canvas_and_mark_dirty(fills_surface_id));
} else {
- let font_manager = skia::FontMgr::from(self.fonts().font_provider().clone());
- let dom_result = skia::svg::Dom::from_str(&sr.content, font_manager);
- match dom_result {
- Ok(dom) => {
- dom.render(self.surfaces.canvas_and_mark_dirty(fills_surface_id));
- shape.to_mut().set_svg(dom);
- }
- Err(e) => {
- eprintln!("Error parsing SVG. Error: {}", e);
- }
- }
+ panic!("SVG should be available");
}
}
Type::Text(stored_text_content) => {
+ self.tile_atlas_flushed = true;
+
self.surfaces.apply_mut(surface_ids, |s| {
s.canvas().concat(&matrix);
});
@@ -1469,14 +1471,12 @@ impl RenderState {
.enumerate()
{
if stroke_kinds[i] == StrokeKind::Inner {
- let mut mask_builders = text_content.paragraph_builder_group_opaque();
let mut fill_builders =
text_content.paragraph_builder_group_from_text(None);
text::render_inner_stroke(
Some(self),
None,
&shape,
- &mut mask_builders,
stroke_paragraphs,
&mut fill_builders,
Some(strokes_surface_id),
@@ -1484,6 +1484,17 @@ impl RenderState {
text_stroke_blur_outset,
*layer_opacity,
)?;
+ } else if stroke_kinds[i] == StrokeKind::Outer {
+ text::render_outer_stroke(
+ Some(self),
+ None,
+ &shape,
+ stroke_paragraphs,
+ Some(strokes_surface_id),
+ None,
+ text_stroke_blur_outset,
+ *layer_opacity,
+ )?;
} else {
text::render_with_bounds_outset(
Some(self),
@@ -1499,6 +1510,20 @@ impl RenderState {
)?;
}
}
+
+ if shape.has_visible_strokes() && text_content.has_non_ascii() {
+ let mut emoji_builders = text_content.paragraph_builder_group_opaque();
+ let mut deco_builders =
+ text_content.paragraph_builder_group_from_text(None);
+ text::render_emoji_overlay(
+ self,
+ &shape,
+ &mut emoji_builders,
+ &mut deco_builders,
+ strokes_surface_id,
+ None,
+ );
+ }
} else {
let mut drop_shadows = shape.drop_shadow_paints();
@@ -1605,15 +1630,12 @@ impl RenderState {
.enumerate()
{
if stroke_kinds[i] == StrokeKind::Inner {
- let mut mask_builders =
- text_content.paragraph_builder_group_opaque();
let mut fill_builders =
text_content.paragraph_builder_group_from_text(None);
text::render_inner_stroke(
Some(self),
None,
&shape,
- &mut mask_builders,
stroke_paragraphs,
&mut fill_builders,
Some(strokes_surface_id),
@@ -1621,6 +1643,17 @@ impl RenderState {
text_stroke_blur_outset,
*layer_opacity,
)?;
+ } else if stroke_kinds[i] == StrokeKind::Outer {
+ text::render_outer_stroke(
+ Some(self),
+ None,
+ &shape,
+ stroke_paragraphs,
+ Some(strokes_surface_id),
+ blur_filter.as_ref(),
+ text_stroke_blur_outset,
+ *layer_opacity,
+ )?;
} else {
text::render_with_bounds_outset(
Some(self),
@@ -1637,6 +1670,20 @@ impl RenderState {
}
}
+ if shape.has_visible_strokes() && text_content.has_non_ascii() {
+ let mut emoji_builders = text_content.paragraph_builder_group_opaque();
+ let mut deco_builders =
+ text_content.paragraph_builder_group_from_text(None);
+ text::render_emoji_overlay(
+ self,
+ &shape,
+ &mut emoji_builders,
+ &mut deco_builders,
+ strokes_surface_id,
+ blur_filter.as_ref(),
+ );
+ }
+
// 5. Stroke inner shadows
shadows::render_text_shadows(
self,
@@ -3572,6 +3619,7 @@ impl RenderState {
// a resumed-from-yield case rather than a genuinely
// empty tile.
self.current_tile_had_shapes = false;
+ self.tile_atlas_flushed = false;
let viewer_masked_pass = self.viewer_masked_pass();
diff --git a/render-wasm/src/render/shadows.rs b/render-wasm/src/render/shadows.rs
index 6965f16ed0..c3de172ad8 100644
--- a/render-wasm/src/render/shadows.rs
+++ b/render-wasm/src/render/shadows.rs
@@ -165,13 +165,11 @@ pub fn render_text_shadows(
for (i, stroke_paragraphs) in stroke_paragraphs_group.iter_mut().enumerate() {
if i < stroke_kinds.len() && stroke_kinds[i] == StrokeKind::Inner {
- let mut mask_builders = text_content.paragraph_builder_group_opaque();
let mut fill_builders = text_content.paragraph_builder_group_from_text(Some(true));
text::render_inner_stroke(
None,
Some(canvas),
shape,
- &mut mask_builders,
stroke_paragraphs,
&mut fill_builders,
surface_id,
@@ -179,6 +177,17 @@ pub fn render_text_shadows(
0.0,
None,
)?;
+ } else if i < stroke_kinds.len() && stroke_kinds[i] == StrokeKind::Outer {
+ text::render_outer_stroke(
+ None,
+ Some(canvas),
+ shape,
+ stroke_paragraphs,
+ surface_id,
+ blur_filter.as_ref(),
+ 0.0,
+ None,
+ )?;
} else {
text::render(
None,
diff --git a/render-wasm/src/render/text.rs b/render-wasm/src/render/text.rs
index 4f2d521179..d972e69813 100644
--- a/render-wasm/src/render/text.rs
+++ b/render-wasm/src/render/text.rs
@@ -95,8 +95,6 @@ fn get_text_stroke_paints(
match stroke.kind {
StrokeKind::Inner => {
- // Just the stroke paint — mask+SrcIn+DstOver layering is handled
- // by render_inner_stroke_on_canvas.
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
paint.set_anti_alias(true);
@@ -120,17 +118,14 @@ fn get_text_stroke_paints(
StrokeKind::Outer => {
let mut paint = skia::Paint::default();
paint.set_style(skia::PaintStyle::Stroke);
- paint.set_blend_mode(skia::BlendMode::DstOver);
paint.set_anti_alias(true);
paint.set_stroke_width(stroke.width * 2.0);
- fill_for_paint(&mut paint);
- paints.push(paint);
-
- let mut paint = skia::Paint::default();
- paint.set_style(skia::PaintStyle::Fill);
- paint.set_blend_mode(skia::BlendMode::Clear);
- paint.set_color(skia::Color::TRANSPARENT);
- paint.set_anti_alias(true);
+ if remove_stroke_alpha {
+ paint.set_color(skia::Color::BLACK);
+ paint.set_alpha(255);
+ } else {
+ fill_for_paint(&mut paint);
+ }
paints.push(paint);
}
}
@@ -408,10 +403,10 @@ fn paint_text_with_emoji_overlay(
overlay_emoji: bool,
) {
let text_content = shape.get_text_content();
- let layout_info =
+ let mut layout_info =
calculate_text_layout_data(shape, text_content, paragraph_builder_groups, true);
- for para in &layout_info.paragraphs {
+ for para in &mut layout_info.paragraphs {
para.paragraph.paint(canvas, (para.x, para.y));
if overlay_emoji {
@@ -431,11 +426,48 @@ fn paint_text_with_emoji_overlay(
}
}
+fn paragraph_has_emoji(paragraph: &mut skia::textlayout::Paragraph) -> bool {
+ let line_bounds: Vec<(usize, usize)> = paragraph
+ .get_line_metrics()
+ .iter()
+ .map(|l| (l.start_index, l.end_index))
+ .collect();
+ line_bounds
+ .into_iter()
+ .any(|(start, end)| !line_emoji_ranges(paragraph, start, end).is_empty())
+}
+
+fn line_emoji_ranges(
+ paragraph: &mut skia::textlayout::Paragraph,
+ line_start: usize,
+ line_end: usize,
+) -> Vec<(usize, usize)> {
+ let mut merged: Vec<(usize, usize)> = Vec::new();
+ for idx in line_start..line_end {
+ let font = paragraph.get_font_at_utf16_offset(idx);
+ let normalized = font
+ .typeface()
+ .family_name()
+ .to_lowercase()
+ .replace(' ', "-");
+ if !normalized.contains(DEFAULT_EMOJI_FONT) {
+ continue;
+ }
+
+ match merged.last_mut() {
+ Some(last) if last.1 == idx => last.1 = idx + 1,
+ _ => merged.push((idx, idx + 1)),
+ }
+ }
+
+ merged
+}
+
/// Rasterizes color emoji runs as bitmap overlays. Skia's PDF backend can't
/// embed COLR/CBDT color glyphs, so each emoji is drawn to a raster surface and
/// blitted; `paragraph.paint()` already wrote placeholder glyphs (keeps text
/// selectable).
-fn paint_emoji_overlay(canvas: &Canvas, para: &ParagraphLayout) {
+fn paint_emoji_overlay(canvas: &Canvas, para: &mut ParagraphLayout) {
let line_metrics = para.paragraph.get_line_metrics();
// Rasterize at TARGET_DPI relative to the emoji's on-page size (72 user
@@ -450,45 +482,18 @@ fn paint_emoji_overlay(canvas: &Canvas, para: &ParagraphLayout) {
let sy = (ctm.skew_x().powi(2) + ctm.scale_y().powi(2)).sqrt();
let output_scale = sx.max(sy).max(1.0);
- for line in &line_metrics {
- let style_runs = line.get_style_metrics(line.start_index..line.end_index);
+ let line_bounds: Vec<(usize, usize)> = line_metrics
+ .iter()
+ .map(|l| (l.start_index, l.end_index))
+ .collect();
+ drop(line_metrics);
- // Build a list of (start, end, is_emoji) for each style run.
- let mut run_info: Vec<(usize, usize, bool)> = Vec::new();
- for (i, (start_idx, _style_metric)) in style_runs.iter().enumerate() {
- let end_idx = style_runs.get(i + 1).map_or(line.end_index, |next| next.0);
- if *start_idx >= end_idx {
- continue;
- }
-
- let font = para.paragraph.get_font_at(*start_idx);
- let family_name = font.typeface().family_name();
-
- let normalized = family_name.to_lowercase().replace(' ', "-");
- let is_emoji = normalized.contains(DEFAULT_EMOJI_FONT);
- run_info.push((*start_idx, end_idx, is_emoji));
- }
-
- // Merge consecutive emoji runs: Skia splits ZWJ sequences (e.g. 👩🏿🚀)
- // per codepoint, but `get_rects_for_range` needs the full cluster range.
- let mut merged_emoji_ranges: Vec<(usize, usize)> = Vec::new();
- for &(start, end, is_emoji) in &run_info {
- if is_emoji {
- if let Some(last) = merged_emoji_ranges.last_mut() {
- if last.1 == start {
- // Extend the previous range
- last.1 = end;
- continue;
- }
- }
- merged_emoji_ranges.push((start, end));
- }
- }
-
- for (range_start, range_end) in &merged_emoji_ranges {
+ for (line_start, line_end) in line_bounds {
+ for (range_start, range_end) in line_emoji_ranges(&mut para.paragraph, line_start, line_end)
+ {
// Get the bounding rects for this (possibly merged) emoji run
let rects = para.paragraph.get_rects_for_range(
- *range_start..*range_end,
+ range_start..range_end,
skia::textlayout::RectHeightStyle::Tight,
skia::textlayout::RectWidthStyle::Tight,
);
@@ -542,6 +547,162 @@ fn paint_emoji_overlay(canvas: &Canvas, para: &ParagraphLayout) {
}
}
+fn draw_decoration_stroke(
+ canvas: &Canvas,
+ kind: StrokeKind,
+ stroke_paint: &Paint,
+ bar: skia::Rect,
+) {
+ if kind == StrokeKind::Center {
+ canvas.draw_rect(bar, stroke_paint);
+ return;
+ }
+
+ let blend = if kind == StrokeKind::Inner {
+ skia::BlendMode::SrcIn
+ } else {
+ skia::BlendMode::SrcOut
+ };
+
+ canvas.save_layer(&SaveLayerRec::default());
+ let mut mask_paint = Paint::default();
+ mask_paint.set_color(skia::Color::BLACK);
+ mask_paint.set_anti_alias(true);
+ canvas.draw_rect(bar, &mask_paint);
+
+ let mut blend_paint = Paint::default();
+ blend_paint.set_blend_mode(blend);
+ canvas.save_layer(&SaveLayerRec::default().paint(&blend_paint));
+ canvas.draw_rect(bar, stroke_paint);
+ canvas.restore();
+ canvas.restore();
+}
+
+fn paint_emoji_opaque(
+ canvas: &Canvas,
+ emoji_para: &mut ParagraphLayout,
+ deco_para: &ParagraphLayout,
+ stroke_decos: &[(StrokeKind, Paint)],
+) {
+ let line_bounds: Vec<(usize, usize)> = emoji_para
+ .paragraph
+ .get_line_metrics()
+ .iter()
+ .map(|l| (l.start_index, l.end_index))
+ .collect();
+
+ let mut clip = skia::PathBuilder::new();
+ let mut has_emoji = false;
+ for (line_start, line_end) in line_bounds {
+ for (range_start, range_end) in
+ line_emoji_ranges(&mut emoji_para.paragraph, line_start, line_end)
+ {
+ let rects = emoji_para.paragraph.get_rects_for_range(
+ range_start..range_end,
+ skia::textlayout::RectHeightStyle::Tight,
+ skia::textlayout::RectWidthStyle::Tight,
+ );
+
+ for text_box in &rects {
+ let r = &text_box.rect;
+ if r.width() <= 0.0 || r.height() <= 0.0 {
+ continue;
+ }
+ clip.add_rect(
+ skia::Rect::from_xywh(
+ emoji_para.x + r.left,
+ emoji_para.y + r.top,
+ r.width(),
+ r.height(),
+ ),
+ None,
+ None,
+ );
+ has_emoji = true;
+ }
+ }
+ }
+
+ if !has_emoji {
+ return;
+ }
+
+ canvas.save();
+ canvas.clip_path(&clip.detach(), skia::ClipOp::Intersect, true);
+ emoji_para
+ .paragraph
+ .paint(canvas, (emoji_para.x, emoji_para.y));
+
+ for deco in &deco_para.decorations {
+ draw_text_decorations(
+ canvas,
+ &deco.text_style,
+ Some(deco.y),
+ deco.thickness,
+ deco.left,
+ deco.width,
+ );
+ let r = decoration_rect(deco.y, deco.thickness, deco.left, deco.width);
+ for (kind, paint) in stroke_decos {
+ draw_decoration_stroke(canvas, *kind, paint, r);
+ }
+ }
+ canvas.restore();
+}
+
+pub fn render_emoji_overlay(
+ render_state: &mut RenderState,
+ shape: &Shape,
+ emoji_builders: &mut [Vec],
+ deco_builders: &mut [Vec],
+ surface_id: SurfaceId,
+ blur: Option<&ImageFilter>,
+) {
+ let text_content = shape.get_text_content();
+ let mut emoji_layout = calculate_text_layout_data(shape, text_content, emoji_builders, true);
+
+ if !emoji_layout
+ .paragraphs
+ .iter_mut()
+ .any(|para| paragraph_has_emoji(&mut para.paragraph))
+ {
+ return;
+ }
+
+ let selrect = shape.selrect();
+ let mut stroke_decos: Vec<(StrokeKind, Paint)> = Vec::new();
+ for stroke in shape.visible_strokes().rev() {
+ let (paints, opacity) = get_text_stroke_paints(stroke, &selrect, false);
+ for mut paint in paints {
+ if let Some(opacity) = opacity {
+ paint.set_alpha_f(opacity);
+ }
+ stroke_decos.push((stroke.kind, paint));
+ }
+ }
+
+ let deco_layout = calculate_text_layout_data(shape, text_content, deco_builders, true);
+ let canvas = render_state.surfaces.canvas_and_mark_dirty(surface_id);
+
+ if let Some(blur_filter) = blur {
+ let mut blur_paint = Paint::default();
+ blur_paint.set_image_filter(blur_filter.clone());
+ canvas.save_layer(&SaveLayerRec::default().paint(&blur_paint));
+ }
+
+ for (emoji_para, deco_para) in emoji_layout
+ .paragraphs
+ .iter_mut()
+ .zip(deco_layout.paragraphs.iter())
+ {
+ paint_emoji_opaque(canvas, emoji_para, deco_para, &stroke_decos);
+ }
+
+ if blur.is_some() {
+ canvas.restore();
+ }
+}
+
fn draw_text(
canvas: &Canvas,
shape: &Shape,
@@ -561,27 +722,22 @@ fn draw_text(
paint_text_with_emoji_overlay(canvas, shape, paragraph_builder_groups, overlay_emoji);
}
-/// Renders an inner stroke using mask + SrcIn + DstOver layer structure.
+/// Renders a text stroke masked to the glyph shape.
///
-/// Layer structure:
-/// saveLayer() — outer layer
-/// saveLayer() — mask group (isolation)
-/// paint mask — opaque fill as clip mask
-/// saveLayer(SrcIn) — clips stroke to mask shape
-/// paint stroke
-/// restore
-/// restore
-/// saveLayer(DstOver) — fill behind the stroke
-/// paint fill
-/// restore
-/// restore
+/// `stroke_mask_blend` selects which side of the glyph the stroke keeps:
+/// `SrcIn` for inner strokes (stroke clipped to the glyph), `SrcOut` for outer
+/// strokes (stroke kept outside the glyph). When `fill_builders` is provided
+/// (inner strokes) the fill is composited with `DstOver` *inside* the masked
+/// layer so its anti-aliased edge aligns with the stroke — no seam at the glyph
+/// boundary. Outer strokes pass `None` (fill is drawn separately).
#[allow(clippy::too_many_arguments)]
-fn render_inner_stroke_on_canvas(
+fn render_masked_stroke_on_canvas(
canvas: &Canvas,
shape: &Shape,
mask_builders: &mut [Vec],
stroke_builders: &mut [Vec],
- fill_builders: &mut [Vec],
+ fill_builders: Option<&mut [Vec]>,
+ stroke_mask_blend: skia::BlendMode,
blur: Option<&ImageFilter>,
layer_opacity: Option,
) {
@@ -591,61 +747,59 @@ fn render_inner_stroke_on_canvas(
canvas.save_layer(&SaveLayerRec::default().paint(&blur_paint));
}
- // Opacity layer wraps the entire composition
if let Some(opacity) = layer_opacity {
let mut opacity_paint = Paint::default();
opacity_paint.set_alpha_f(opacity);
canvas.save_layer(&SaveLayerRec::default().paint(&opacity_paint));
}
- // Outer layer
canvas.save_layer(&SaveLayerRec::default());
- // Mask group layer (isolates mask from parent surface content)
canvas.save_layer(&SaveLayerRec::default());
- // Draw opaque mask (full alpha text shape)
paint_text(canvas, shape, mask_builders);
- // SrcIn layer — only keeps stroke pixels where mask has alpha
- let mut src_in_paint = Paint::default();
- src_in_paint.set_blend_mode(skia::BlendMode::SrcIn);
- canvas.save_layer(&SaveLayerRec::default().paint(&src_in_paint));
+ let mut stroke_paint = Paint::default();
+ stroke_paint.set_blend_mode(stroke_mask_blend);
+ canvas.save_layer(&SaveLayerRec::default().paint(&stroke_paint));
- // Draw stroke
paint_text(canvas, shape, stroke_builders);
- canvas.restore(); // SrcIn layer
+ // Fill with DstOver behind the stroke, inside the masked layer so the fill's
+ // anti-aliased edge aligns with the stroke (no seam at the glyph edge).
+ // Outer strokes have no fill here (`None`).
+ if let Some(fill_builders) = fill_builders {
+ let mut dst_over_paint = Paint::default();
+ dst_over_paint.set_blend_mode(skia::BlendMode::DstOver);
+ canvas.save_layer(&SaveLayerRec::default().paint(&dst_over_paint));
+
+ paint_text(canvas, shape, fill_builders);
+
+ canvas.restore(); // DstOver layer
+ }
+
+ canvas.restore(); // SrcIn / SrcOut layer
canvas.restore(); // mask group layer
-
- // Fill with DstOver (behind the stroke result)
- let mut dst_over_paint = Paint::default();
- dst_over_paint.set_blend_mode(skia::BlendMode::DstOver);
- canvas.save_layer(&SaveLayerRec::default().paint(&dst_over_paint));
-
- paint_text(canvas, shape, fill_builders);
-
- canvas.restore(); // DstOver layer
canvas.restore(); // outer layer
if layer_opacity.is_some() {
- canvas.restore(); // opacity layer
+ canvas.restore();
}
if blur.is_some() {
- canvas.restore(); // blur layer
+ canvas.restore();
}
}
-/// Public API for rendering inner strokes with mask+SrcIn+DstOver approach.
#[allow(clippy::too_many_arguments)]
-pub fn render_inner_stroke(
+fn render_masked_stroke(
render_state: Option<&mut RenderState>,
canvas: Option<&Canvas>,
shape: &Shape,
mask_builders: &mut [Vec],
stroke_builders: &mut [Vec],
- fill_builders: &mut [Vec],
+ mut fill_builders: Option<&mut [Vec]>,
+ stroke_mask_blend: skia::BlendMode,
surface_id: Option,
blur: Option<&ImageFilter>,
stroke_bounds_outset: f32,
@@ -665,18 +819,20 @@ pub fn render_inner_stroke(
let bounds = blur_filter.compute_fast_bounds(text_bounds);
if bounds.is_finite() && bounds.width() > 0.0 && bounds.height() > 0.0 {
let blur_filter_clone = blur_filter.clone();
+ let fill_builders = &mut fill_builders;
if filters::render_with_filter_surface(
render_state,
bounds,
target_surface,
|state, temp_surface| {
let temp_canvas = state.surfaces.canvas(temp_surface);
- render_inner_stroke_on_canvas(
+ render_masked_stroke_on_canvas(
temp_canvas,
shape,
mask_builders,
stroke_builders,
- fill_builders,
+ fill_builders.as_deref_mut(),
+ stroke_mask_blend,
Some(&blur_filter_clone),
layer_opacity,
);
@@ -689,12 +845,13 @@ pub fn render_inner_stroke(
}
let canvas = render_state.surfaces.canvas_and_mark_dirty(target_surface);
- render_inner_stroke_on_canvas(
+ render_masked_stroke_on_canvas(
canvas,
shape,
mask_builders,
stroke_builders,
- fill_builders,
+ fill_builders.as_deref_mut(),
+ stroke_mask_blend,
blur,
layer_opacity,
);
@@ -702,12 +859,13 @@ pub fn render_inner_stroke(
}
if let Some(canvas) = canvas {
- render_inner_stroke_on_canvas(
+ render_masked_stroke_on_canvas(
canvas,
shape,
mask_builders,
stroke_builders,
fill_builders,
+ stroke_mask_blend,
blur,
layer_opacity,
);
@@ -715,6 +873,70 @@ pub fn render_inner_stroke(
Ok(())
}
+#[allow(clippy::too_many_arguments)]
+pub fn render_inner_stroke(
+ render_state: Option<&mut RenderState>,
+ canvas: Option<&Canvas>,
+ shape: &Shape,
+ stroke_builders: &mut [Vec],
+ fill_builders: &mut [Vec],
+ surface_id: Option,
+ blur: Option<&ImageFilter>,
+ stroke_bounds_outset: f32,
+ layer_opacity: Option,
+) -> Result<()> {
+ let mut mask_builders = shape.get_text_content().paragraph_builder_group_opaque();
+ render_masked_stroke(
+ render_state,
+ canvas,
+ shape,
+ &mut mask_builders,
+ stroke_builders,
+ Some(fill_builders),
+ skia::BlendMode::SrcIn,
+ surface_id,
+ blur,
+ stroke_bounds_outset,
+ layer_opacity,
+ )
+}
+
+#[allow(clippy::too_many_arguments)]
+pub fn render_outer_stroke(
+ render_state: Option<&mut RenderState>,
+ canvas: Option<&Canvas>,
+ shape: &Shape,
+ stroke_builders: &mut [Vec],
+ surface_id: Option,
+ blur: Option<&ImageFilter>,
+ stroke_bounds_outset: f32,
+ layer_opacity: Option,
+) -> Result<()> {
+ let mut mask_builders = shape.get_text_content().paragraph_builder_group_opaque();
+ render_masked_stroke(
+ render_state,
+ canvas,
+ shape,
+ &mut mask_builders,
+ stroke_builders,
+ None,
+ skia::BlendMode::SrcOut,
+ surface_id,
+ blur,
+ stroke_bounds_outset,
+ layer_opacity,
+ )
+}
+
+fn decoration_rect(y: f32, thickness: f32, text_left: f32, text_width: f32) -> skia_safe::Rect {
+ skia_safe::Rect::new(
+ text_left,
+ y - thickness / 2.0,
+ text_left + text_width,
+ y + thickness / 2.0,
+ )
+}
+
fn draw_text_decorations(
canvas: &Canvas,
text_style: &TextStyle,
@@ -724,12 +946,7 @@ fn draw_text_decorations(
text_width: f32,
) {
if let Some(y) = y {
- let r = skia_safe::Rect::new(
- text_left,
- y - thickness / 2.0,
- text_left + text_width,
- y + thickness / 2.0,
- );
+ let r = decoration_rect(y, thickness, text_left, text_width);
let mut decoration_paint = text_style.foreground();
decoration_paint.set_anti_alias(true);
canvas.draw_rect(r, &decoration_paint);
diff --git a/render-wasm/src/render/vector.rs b/render-wasm/src/render/vector.rs
index 721a02fbc5..04d91552d9 100644
--- a/render-wasm/src/render/vector.rs
+++ b/render-wasm/src/render/vector.rs
@@ -194,14 +194,12 @@ impl ShapeRenderer for VectorRenderer<'_> {
for (kind, stroke_paragraphs) in &mut stroke_shadow_groups {
if *kind == StrokeKind::Inner {
// Inner stroke masked by the glyph fill (outset 0 here).
- let mut mask_builders = text_content.paragraph_builder_group_opaque();
let mut fill_builders =
text_content.paragraph_builder_group_from_text(Some(true));
text::render_inner_stroke(
None,
Some(self.canvas),
shape,
- &mut mask_builders,
stroke_paragraphs,
&mut fill_builders,
None,
@@ -209,6 +207,17 @@ impl ShapeRenderer for VectorRenderer<'_> {
0.0,
None,
)?;
+ } else if *kind == StrokeKind::Outer {
+ text::render_outer_stroke(
+ None,
+ Some(self.canvas),
+ shape,
+ stroke_paragraphs,
+ None,
+ blur_filter.as_ref(),
+ 0.0,
+ None,
+ )?;
} else {
text::render_with_bounds_outset_overlay_emoji(
self.canvas,
@@ -250,13 +259,11 @@ impl ShapeRenderer for VectorRenderer<'_> {
);
if stroke.render_kind(false) == StrokeKind::Inner {
// Inner text stroke: clip to the glyph fill, else it bleeds out.
- let mut mask_builders = text_content.paragraph_builder_group_opaque();
let mut fill_builders = text_content.paragraph_builder_group_from_text(None);
text::render_inner_stroke(
None,
Some(self.canvas),
shape,
- &mut mask_builders,
&mut stroke_paragraphs,
&mut fill_builders,
None,
@@ -264,6 +271,17 @@ impl ShapeRenderer for VectorRenderer<'_> {
stroke_blur_outset,
layer_opacity,
)?;
+ } else if stroke.render_kind(false) == StrokeKind::Outer {
+ text::render_outer_stroke(
+ None,
+ Some(self.canvas),
+ shape,
+ &mut stroke_paragraphs,
+ None,
+ blur_filter.as_ref(),
+ stroke_blur_outset,
+ layer_opacity,
+ )?;
} else {
text::render_with_bounds_outset_overlay_emoji(
self.canvas,
diff --git a/render-wasm/src/shapes.rs b/render-wasm/src/shapes.rs
index 95c704ceff..92d49c7c30 100644
--- a/render-wasm/src/shapes.rs
+++ b/render-wasm/src/shapes.rs
@@ -722,6 +722,23 @@ impl Shape {
self.invalidate_extrect();
}
+ pub fn update_svg_raw_content(&mut self, font_manager: skia::FontMgr) {
+ match &self.shape_type {
+ Type::SVGRaw(sr) => {
+ let dom_result = skia::svg::Dom::from_str(&sr.content, font_manager);
+ match dom_result {
+ Ok(dom) => {
+ self.set_svg(dom);
+ }
+ Err(e) => {
+ eprintln!("Error parsing SVG. Error: {}", e);
+ }
+ }
+ }
+ _ => panic!("Updating SVG raw content on non SVG Raw shape"),
+ }
+ }
+
pub fn set_svg_raw_content(&mut self, content: String) {
self.shape_type = Type::SVGRaw(SVGRaw::from_content(content));
}
diff --git a/render-wasm/src/shapes/text.rs b/render-wasm/src/shapes/text.rs
index 86159ac3df..1ba1381172 100644
--- a/render-wasm/src/shapes/text.rs
+++ b/render-wasm/src/shapes/text.rs
@@ -400,6 +400,13 @@ impl TextContent {
&self.paragraphs
}
+ pub fn has_non_ascii(&self) -> bool {
+ self.paragraphs
+ .iter()
+ .flat_map(|p| p.children())
+ .any(|span| !span.text.is_ascii())
+ }
+
pub fn paragraphs_mut(&mut self) -> &mut Vec {
self.content_version = self.content_version.wrapping_add(1);
&mut self.paragraphs
@@ -888,6 +895,11 @@ impl TextContent {
.copy_finite_size(result.2, default_width, default_height);
}
+ pub fn force_next_layout_update(&mut self) {
+ self.layout_width = None;
+ self.layout.cached_extrect.set(None);
+ }
+
pub fn update_layout(&mut self, selrect: Rect) -> TextContentSize {
if !self.layout.needs_update()
&& self.layout_version == self.content_version
diff --git a/render-wasm/src/wasm/text.rs b/render-wasm/src/wasm/text.rs
index c97ec81276..6e2575741f 100644
--- a/render-wasm/src/wasm/text.rs
+++ b/render-wasm/src/wasm/text.rs
@@ -370,8 +370,11 @@ pub extern "C" fn intersect_position_in_shape(
false
}
-fn update_text_layout(shape: &mut Shape) {
+fn update_text_layout(shape: &mut Shape, force: bool) {
if let Type::Text(text_content) = &mut shape.shape_type {
+ if force {
+ text_content.force_next_layout_update();
+ }
text_content.update_layout(shape.selrect);
shape.invalidate_extrect();
}
@@ -380,7 +383,7 @@ fn update_text_layout(shape: &mut Shape) {
#[no_mangle]
pub extern "C" fn update_shape_text_layout() {
with_current_shape_mut!(state, |shape: &mut Shape| {
- update_text_layout(shape);
+ update_text_layout(shape, false);
});
}
@@ -389,7 +392,18 @@ pub extern "C" fn update_shape_text_layout_for(a: u32, b: u32, c: u32, d: u32) {
with_state!(state, {
let shape_id = uuid_from_u32_quartet(a, b, c, d);
if let Some(shape) = state.shapes.get_mut(&shape_id) {
- update_text_layout(shape);
+ update_text_layout(shape, false);
+ }
+ state.touch_shape(shape_id);
+ });
+}
+
+#[no_mangle]
+pub extern "C" fn force_update_shape_text_layout_for(a: u32, b: u32, c: u32, d: u32) {
+ with_state!(state, {
+ let shape_id = uuid_from_u32_quartet(a, b, c, d);
+ if let Some(shape) = state.shapes.get_mut(&shape_id) {
+ update_text_layout(shape, true);
}
state.touch_shape(shape_id);
});