What's Changed
- Affinity import: bound archive index names and charge failed entry extraction by @dylanmtaylor in #5291
- Native format: document.save can write path coordinates at a fixed precision by @dotCooCoo in #3990
- Drop invalid XML characters from SVG link URLs and aria-labels by @Silvertree2010 in #5279
- Fix #5312: EPS files written by Ghostscript's eps2write open by @JonRC in #5314
- Docs: file-format-parity keeps one .ai editing-data paragraph by @dotCooCoo in #5269
- Type: Tate-chu-yoko offsets in character style definitions stay in range by @dotCooCoo in #5259
- Document Info: Objects counts each object once by @dotCooCoo in #5260
- PDF export: spot inks named All or None print as spot inks by @dotCooCoo in #5250
- Type: an inline graphic takes its character's manual kerning by @dotCooCoo in #5245
- Select: Same › Text Fill & Stroke Color selects type whose fill and stroke both match by @dotCooCoo in #5244
- SVG: an exported ellipse imports as the four-anchor ellipse it was written from by @dotCooCoo in #5243
- i18n(ru): translate the 130 strings the report listed as missing by @rahul05ranjan in #5240
- i18n(sv): translate the 22 strings the report listed as missing by @rahul05ranjan in #5242
- Geometry: a projective map's horizon and invertibility checks do not depend on its scale by @dotCooCoo in #5271
- DXF export: bound curve flattening work and expanded symbol art by @dylanmtaylor in #5289
- Repeat: the instance budget counts opacity-mask art and the nodes each copy holds by @dylanmtaylor in #5290
- Page ranges: overlapping intervals skip indices already picked by @dylanmtaylor in #5292
- Depth limit: merge containers at the cap in one pass over the siblings by @dylanmtaylor in #5294
- Gradients: midpoints and freeform points find their stops by binary search by @dylanmtaylor in #5298
- Brush and symbol libraries: look definitions up by name by @dylanmtaylor in #5300
- Affinity import: count path segments and masks in master page copies; range-check vector masks by @dylanmtaylor in #5302
- Export for Screens: name patterns and taken names take linear work by @dylanmtaylor in #5304
- Affinity import: index the fields of large objects and read four rectangle corners by @dylanmtaylor in #5310
- Global Edit: a Shift-click on a highlighted match leaves it out of the edit by @dotCooCoo in #5237
- Recolor Artwork: the Edit tab shows the colors on a smooth wheel, a segmented wheel or as color bars by @dotCooCoo in #5249
- Symbols: 9-slice guides are shown and dragged on the canvas while editing a symbol by @dotCooCoo in #5280
- Fix Simplified Chinese translation of Luminosity by @cybermaxwel in #5329
- Brushes: leave out an opacity mask whose root symbol draws a brushed stroke by @dylanmtaylor in #5293
- Threaded text: a frame listed twice flows the story once by @dylanmtaylor in #5303
- Place: the place cursor reads its files within the roots it was loaded in by @dylanmtaylor in #5306
- Fix #5316: StandardEncoding and ISOLatin1Encoding are Encoding resources by @JonRC in #5317
- Fix #5318:
knownanswers false for keys no dictionary holds by @JonRC in #5319 - Fix #5321:
currentfilein a file being run is that file by @JonRC in #5323 - Clipboard: leave out the PNG of art too large to scale to 4096 pixels by @dylanmtaylor in #5301
- Flatten Transparency: group overlapping objects without comparing every open pair by @dylanmtaylor in #5307
- Export for Screens: keep PDF passwords out of remembered settings by @dylanmtaylor in #5305
- ICC: refuse a profile whose tag table lists a tag twice by @dylanmtaylor in #5299
- DXF import: budget dash patterns, copied text and names, and block items looked at by @dylanmtaylor in #5288
- Fix #4559: shortcuts can use the ISO key next to left Shift by @dotCooCoo in #5276
- Type: text.setStyle sets the text's stroke as well as its fill by @dotCooCoo in #5257
- Measure: a Shift-drag snaps its end point on its 45° step by @dotCooCoo in #5277
- Canvas: moves after the button-up do not join a stroke by @dotCooCoo in #5268
- Canvas: a dropped press cancels the tool's drag instead of ending it by @dotCooCoo in #5234
- Character Styles: Style Options sets character color and OpenType features by @dotCooCoo in #5255
- Window: Float in Window, Float All in Windows and Cascade float documents by @dotCooCoo in #5278
- Window: drag a document tab out to float it, and a window back to dock it by @dotCooCoo in #5286
- Window: with Open Documents As Tabs cleared, new documents open in windows by @dotCooCoo in #5295
- Window: Tile with one document open leaves the documents under their tabs by @dotCooCoo in #5256
- Preserve SVG styles with encoded attribute selectors by @dotCooCoo in #5325
- Exclude empty runs from matching text selections by @dotCooCoo in #5328
- Update SVG, type, recoloring, and symbol feature records by @dotCooCoo in #5326
- Path type brackets: 8 px reach, hover highlight, and the nearest of a bracket and a port takes the press by @ham9zah in #5332
- Objects on Path: the Space widget spaces the attached objects along the path by @dotCooCoo in #5275
- Type: step font families with the mouse wheel by @dotCooCoo in #5331
- Selection: a click on a large compound path is culled by its control points by @thisisgomaa in #5261
- Render: a compound path's members are assembled once and kept with the node by @thisisgomaa in #5262
- Find Font: Change and Change All add no undo step when no text changes by @dotCooCoo in #5204
- Type: Find Font's Replace With Font From lists the document's, recent or installed fonts by @dotCooCoo in #5217
- Variables: Import Data Sets reads every column as a variable and replaces the data sets by @dotCooCoo in #5151
- Type: the caret, a click and the arrow keys reach the characters inside a ligature by @dotCooCoo in #5225
- .ai import: version 7 pattern definitions come in as pattern swatches by @dotCooCoo in #5189
- .ai import: Effect › Pathfinder on a group opens as a live effect by @dotCooCoo in #5150
- Group flattened multi-line transparent type by line by @Prin-Ing in #5338
- Fix #5342:
eexecskips in the file it is given by @JonRC in #5343 - Fix #5236: Use System Defaults for Edit Original (Preferences › File Handling) by @ruchirguitar in #5327
- Docs: consolidate assessment target metadata by @dotCooCoo in #5352
- Tests: isolate font wheel picking from missing-glyph protection by @dotCooCoo in #5353
- Fix #4924: Text Tweaker ramps or randomises one character attribute letter by letter by @ruchirguitar in #5344
- chore(deps): bump wat from 1.262.0 to 1.263.0 by @dependabot[bot] in #5346
- Paint: use CMYK defaults when creating gradients in CMYK documents by @dotCooCoo in #5354
- Actions: New Action asks for the action's name, set, function key and color by @dotCooCoo in #5270
- Character style evidence links to help without copied instructions by @dotCooCoo in #5358
- Docs: record Find Font replacement sources by @dotCooCoo in #5359
- Transform previews typed values in its effect dialog by @dotCooCoo in #5357
- SVG import preserves selector matches while retaining metadata by @dotCooCoo in #5361
- Type: keep composition spacing along the line when characters rotate by @dotCooCoo in #5370
- Lasso picks gradient mesh points instead of dropping the mesh by @Silvertree2010 in #5371
- Dashes: a pattern whose period overflows to infinity draws solid by @dylanmtaylor in #5373
- Illustrator import: refuse arrays nested past the depth limit by @dylanmtaylor in #5374
- Data Recovery: read only plain files in this account's own areas by @dylanmtaylor in #5375
- Links: the link watch and Link Info read within the asking caller's roots by @dylanmtaylor in #5376
- Placed documents: a refused read shows the preview, not another caller's cached full read by @dylanmtaylor in #5377
- App: open and copied-file paste read only regular files by @dylanmtaylor in #5378
- App: keep preference copies, dialog passwords and migrated folders private by @dylanmtaylor in #5379
- Save: the Templates folder needs write access; portal saves keep the exact file name by @dylanmtaylor in #5380
- Atomic save: a replacement takes no inherited ACL the old file lacked by @dylanmtaylor in #5381
- Recolor: clustering seeds each colour once by @dylanmtaylor in #5382
- Automation roots: refuse network paths outside the roots before resolving them by @dylanmtaylor in #5383
- PDF and print presets: imports number duplicate names in linear time by @dylanmtaylor in #5384
- Gradients drawn pixel by pixel find their stops by binary search (EMF export, Affinity overlays) by @dylanmtaylor in #5385
- Brush and library names number repeats without rescanning by @dylanmtaylor in #5386
- WMF import: a full object table is not rescanned for every creation by @dylanmtaylor in #5387
- Graph designs: Delete Design handles each listed name once by @dylanmtaylor in #5388
- Slices: Create from Guides stops at one past the slice limit by @dylanmtaylor in #5389
- Illustrator import: look swatch names up in a set by @dylanmtaylor in #5390
- Data Recovery: an image entry shared by several keys is written and read once by @dylanmtaylor in #5391
- MCP: busy replies don't repeat a long request id by @dylanmtaylor in #5392
- Geometry: anchor positions and Simplify measure curves through the guarded arc length by @dylanmtaylor in #5393
- Place: a placement read again when it completes stays within the roots it was read in by @dylanmtaylor in #5394
- Brushes: a brush name the library lacks doesn't make art draw a brushed stroke by @dylanmtaylor in #5398
- Threads: a frame left alone by a dropped repeat is flowed again by @dylanmtaylor in #5396
- DXF import: charge every dash copy and symbol name, name the block-work limit by @dylanmtaylor in #5397
- Export for Screens: settings saved without their PDF passwords don't export unprotected by @dylanmtaylor in #5400
- Copy: a PNG too large to make is not offered, and the status bar says why by @dylanmtaylor in #5399
- Fix #5360: Type on a Path Options has a Preview checkbox by @ruchirguitar in #5402
- SVG: CSS class names and imported symbol names take linear work by @dylanmtaylor in #5405
- SVG: the entity expansion cap counts every declaration and refuses names it can't follow by @dylanmtaylor in #5406
- SVG glyphs: keep only typed raster data URLs, and no links by @dylanmtaylor in #5407
- CSS export: line breaks and angle brackets in names can't end a CSS string by @dylanmtaylor in #5408
- PDF: bound marked-content lookup, ASCII85, editing-data hashing, image decodes and ink warnings by @dylanmtaylor in #5410
- Tools: Shape Builder hatch lines are counted; Liquify simplification is linear by @dylanmtaylor in #5411
- Trace: empty and mismatched rasters, and large swatch libraries, take bounded work by @dylanmtaylor in #5412
- Type: a paragraph looks only at its own runs by @dylanmtaylor in #5414
- Render: symbol instances with effects use the symbol budget; CMYK decodes are admitted; checked Targa size by @dylanmtaylor in #5415
- Fonts build: craft-fonts manifest paths stay inside the checkout; licences are published as text by @dylanmtaylor in #5416
- UI: automation can't open the browser or viewer; Preview in Browser stays in its folder; Graph Data is bounded by @dylanmtaylor in #5417
- UI: opening, file picks and the render worker keep the automation roots they started under by @dylanmtaylor in #5418
- Testkit: a reused temp dir must belong to this user by @dylanmtaylor in #5419
- Type: Character menu Kashidas controls selected text by @dotCooCoo in #5404
- Add Enclosing Lasso as an optional tool by @dotCooCoo in #5362
- Type: move right-to-left characters with Touch Type by @dotCooCoo in #5366
- Fix #5369: every way of opening a file focuses its open tab by @ruchirguitar in #5420
- MCP: render_preview and window captures decode the app's PNG under size limits by @dylanmtaylor in #5445
- Render: keep the native thread helper out of Wasm libraries by @dotCooCoo in #5430
- Reject doubly signed OpenType feature tags by @dotCooCoo in #5473
- Clear stale Find Font warning after successful replacement by @dotCooCoo in #5425
- Type: the stop inside an upright ligature on a vertical path follows its drawn cell by @dotCooCoo in #5468
- Resolve GDEF contour-point ligature carets by @dotCooCoo in #5452
- Use original wording for Action Options documentation by @dotCooCoo in #5433
- Docs: replace quoted help-page sentences with plain statements by @dotCooCoo in #5435
- Keep Blend reset after a dropped press by @dotCooCoo in #5434
- Keep dropped placement presses from creating dimensions by @dotCooCoo in #5432
- Measure tool: Shift keeps the end on the pointer's step after the grid rounds it by @dotCooCoo in #5438
- Edit Original: read PhotoCraft's App Paths entry as UTF-16 on Windows by @dotCooCoo in #5440
- Read compound effects when opening effect dialogs by @dotCooCoo in #5428
- Geometry: inverses and conjugates by small affines are no longer refused by @dotCooCoo in #5472
- DXF: paths of lines and circular arcs export as polylines with bulges by @dotCooCoo in #5466
- .ai save: errors and notes name the legacy or non-PDF-compatible .ai by @dotCooCoo in #5471
- Opening an already-open file: close Home, check read roots, wait for dialogs (#5369 follow-ups) by @ruchirguitar in #5437
- Bound work: flattening of huge curves, print layout past the page limit, script-check file names by @dylanmtaylor in #5443
- Path booleans: refuse out-of-range input, guard the contour pass, cuts report refusals (#5465) by @vangel76 in #5474
- Offset Path: skip far segments and stop early in the spurious-contour check (#5455) by @vangel76 in #5460
- Linear-time scans: Add Anchor Points, swatch library adds, export placements, width profiles, symbolism previews by @dylanmtaylor in #5441
- Trace: look up the smoothing weights instead of computing them per pixel (#5454) by @vangel76 in #5458
- Image Trace: noise removal keeps its regions in u32 arrays (#5462) by @vangel76 in #5467
- Image Trace: all_within hashes its grid cells with a small hasher (#5463) by @vangel76 in #5469
- Image Trace: fit the components of a layer in parallel, in chunks (#5464) by @vangel76 in #5470
- Check stroke.set params: a misnamed key is refused (#1442) by @FrancoJacquet in #5453
- About: credits tables fit without side-scrolling and their columns resize by @FredApps in #5449
- Window: New Window opens a second view of the current document by @dotCooCoo in #5461
- Select: the font Same commands take their reference from type that can be selected by @dotCooCoo in #5479
- Contextual Task Bar: type on a path offers Type on a Path Options by @dotCooCoo in #5480
- .ai import: objects that draw differently from the page come in as its art, and the layers stay by @dotCooCoo in #5486
- Add command to begin recording Actions by @dotCooCoo in #5488
- Control server: the junk-closes test leaves no unread input by @bflatastic in #5489
- Fix #2920: an open path in a PDF-compatible .ai opens as drawn by @mockydevs in #4616
- Restore Type editing after a dropped press by @dotCooCoo in #5490
- Toolbars: Manage Toolbars renames, copies and deletes the toolbars made with New Toolbar by @dotCooCoo in #5492
- Preview dimensions on placement press by @dotCooCoo in #5494
- EPS import: bound and charge the filter chain over a pending file by @dylanmtaylor in #5495
- Layers: Layer Options for several rows sends only the settings set in it by @dotCooCoo in #5496
- Fonts: cap the name records and decoded bytes read per name id by @dylanmtaylor in #5497
- 3D effects: every ring pair counts toward the containment budget; no zero-sized inflate cells by @dylanmtaylor in #5413
- .ai save: write editing data with layers, paths, colors and artboards by @dotCooCoo in #4968
- i18n(ka): Georgian for 23 new strings by @devius in #5431
- Docs: reconcile Kashidas and Type options parity by @dotCooCoo in #5436
- Docs: describe help-page behavior in our own words by @dotCooCoo in #5498
- Cap radar graph dimensions, resume slice-name suffix search, weigh plug-in cache keys by @dylanmtaylor in #5499
- Graphs: series marks keep a fill or stroke opacity when the graph is drawn again by @dotCooCoo in #5501
- .ai import: boxes of differing patches on an image-only page use the comparison raster's pixel size by @dotCooCoo in #5503
- .ai import: copies drawn by a layer's or group's look keep their type by @dotCooCoo in #5505
- Fix range text stroke weight defaults and scaling by @dotCooCoo in #5487
- Text Tweaker: refuse ranges that aren't whole bytes, make no step when nothing changes (#4924) by @ruchirguitar in #5509
- Symbols: Break Link keeps the instance's opacity mask by @dotCooCoo in #5506
- Select: the font Same commands take their reference from the type on a selected layer by @dotCooCoo in #5508
- Color controls: preserve working RGB components in numeric edits by @dotCooCoo in #5507
- MCP docs: vertical text uses vert alternates, and duplicate defaults to the current set by @dotCooCoo in #5513
- Actions: New Action leaves its set as the only selected set by @dotCooCoo in #5512
- Select: Same commands take their reference from an object that can be selected by @dotCooCoo in #5510
- Docs: cite where a group's or layer's effect comes from in the .ai look copies entry by @dotCooCoo in #5515
- .ai save: an artboard the document does not have is refused, as an export refuses it by @dotCooCoo in #5517
- Tests: the Color Picker's R, G and B fields show the working RGB values by @dotCooCoo in #5521
- Select: the font Same commands look through a selected group that holds the isolated group by @dotCooCoo in #5522
- Actions: exclude recorded steps from playback by @dotCooCoo in #5422
- Type: typing a list's start in a continued paragraph starts no list by @dotCooCoo in #5523
- Live Paint: preserve face colors at shared curved boundaries by @dotCooCoo in #5524
- Docs: name glows with shadows in the pan raster entry, and mark VectorCraft's own values by @dotCooCoo in #5527
- Add font-aware OpenType stylistic sets menu by @dotCooCoo in #5447
- Docs: Perceptual spot gradients with more than 4,096 curve stops export as images by @dotCooCoo in #5536
- Render: placed-document bitmaps draw undecoded-image marks when the view does by @dotCooCoo in #5535
- .ai import: the layers are compared with every page of a multi-artboard file by @dotCooCoo in #5533
- Layers: Layer Options keeps a Dim Images that was set before Template changes by @dotCooCoo in #5516
- Blends: Convert on a replaced spine changes only its handles by @dotCooCoo in #5538
- Type: Select All in a threaded frame selects the whole story by @dotCooCoo in #5542
- Select: Same Symbol Instance takes its reference from an object that can be selected by @dotCooCoo in #5511
- Expand: selected symbol instances become their art, as Break Link places it by @dotCooCoo in #5543
- Images: a PNG read a row at a time counts all of the reader's buffers by @dotCooCoo in #5556
- Type: list stylistic sets whose lookups come from FeatureVariations by @dotCooCoo in #5551
- .ai import: blends keep their Specified Distance and Smooth Color spacing by @dotCooCoo in #5554
- PDF/.ai import: the file is read and checked once when it opens by @dotCooCoo in #5552
- Control bar: the Global Edit Options dropdown shows while Start Global Edit can run by @dotCooCoo in #5553
- .ai import: brushes come in from the editing data by @dotCooCoo in #5046
- Single instance: the stale-endpoint test connects to no freed port by @bflatastic in #5562
- Fix #5555: Cmd+V pastes once on the web by @byoungyoon in #5561
- .ai import: objects come in bound to their variables by @dotCooCoo in #5481
- i18n: leading and Tracking term checks match whole words in the right label by @dotCooCoo in #5558
- Type: text commands refuse negative or fractional byte offsets by @dotCooCoo in #5537
- Panels: showing a hidden floating group returns its window's panels by @dotCooCoo in #5564
- Render: a long stroke is outlined only near the view after an edit by @dotCooCoo in #5563
- Document Color Mode: convert reusable paints and restore them with Undo by @dotCooCoo in #4517
- Select: the font Same commands skip type on a template sublayer by @dotCooCoo in #5566
- Render: node renders follow the anti-aliasing option by @dotCooCoo in #5567
- Shortcuts: a held Escape that cancels a Tools or ruler move skips the tool by @dotCooCoo in #5568
- .ai import: a brush object without a name counts as a brush left out by @dotCooCoo in #5569
- Object: Unselected Artwork keeps groups that hold a selected layer or a locked guide by @dotCooCoo in #5570
- Direct Selection: a marquee over a long path tests its segments without building a path for each by @dotCooCoo in #5571
- Tests: skip the Arabic Optical kerning test without craft-fonts by @dotCooCoo in #5572
- Canvas: a drag's release reads Backtick as it was at the button-up by @dotCooCoo in #5575
- Type: Done during a Cmd press does not save empty point type by @dotCooCoo in #5576
- Preferences: a Render Threads change before the first UI pass restarts the canvas renderer by @dotCooCoo in #5579
- Type: Kerning menu lists Auto and Optical for mixed kerning modes by @dotCooCoo in #5580
- Global Edit: the options dropdowns close when Global Edit starts by @dotCooCoo in #5583
- Select: describe which object Same Symbol Instance compares with by @dotCooCoo in #5577
- Dialogs: a color with an alpha part is refused instead of losing its alpha by @dotCooCoo in #5574
- Layers: a layer or gap color with an alpha part is refused instead of losing its alpha by @dotCooCoo in #5581
- Validate character style numeric dimensions by @dotCooCoo in #5540
- Navigator: Panel Options sets the view box color and draws dashed lines as solid by @dotCooCoo in #5541
- Character: Kerning reads (10+5)2 as nothing instead of 10+52 by @dotCooCoo in #5585
- Text Tweaker: align byte ranges to character boundaries by @dotCooCoo in #5586
- Keyboard Shortcuts: the backtick key's label ignores the next key's text on the web by @dotCooCoo in #5587
- Appearance: the active row is matched in each selected object on its own by @dotCooCoo in #5591
- Type: the font warning leaves out characters Missing Glyph Protection kept by @dotCooCoo in #5592
- Docs: list PDF spot gradients written as images in process colors by @dotCooCoo in #5593
- Gradient: method help names the PDF Separation and DeviceN shadings by @dotCooCoo in #5596
- Appearance: Add New Fill's params text says it copies the active row's paint by @dotCooCoo in #5589
- Font fields: handle wheel input in floating native windows by @dotCooCoo in #5597
- Native files: documents from before 0.21.0 keep their Twist turning as saved by @dotCooCoo in #5599
- PDF/.ai import: a file whose type all comes from its text document opens without its PDF part by @dotCooCoo in #5598
- Area Type Options: applying to several frames keeps each frame's own options by @mockydevs in #5602
- Fix #3759: vertical alignment buttons for area type in the Properties and Control panels by @mockydevs in #5100
- Commands: a color param with an alpha part is refused instead of losing its alpha by @dotCooCoo in #5603
- Fix #3226: copy and paste ruler guides by @mockydevs in #5085
- Fix #4921: Image Trace > Batch Trace Folder by @mockydevs in #5072
- Actions: Playback Options plays actions accelerated, step by step or with a pause between steps by @dotCooCoo in #5600
- Tests: the Render Threads restart test stays within the preference's range by @dotCooCoo in #5604
- PDF export: freeform gradients without points warn about spot stops by @dotCooCoo in #5605
- Type: Kerning menu checks neither method for a manual value by @dotCooCoo in #5606
- i18n: the package status stays English until the status bar shows it by @dotCooCoo in #5607
- Shortcuts: an Escape that cancels a Tools or ruler move runs no Escape command by @dotCooCoo in #5608
- Shape Builder Tool Options: a highlight color with an alpha part is refused by @dotCooCoo in #5609
- Appearance: Add New Fill and Add New Stroke params text match the code by @dotCooCoo in #5610
- Tabs: setting the stops a paragraph already has records no undo step by @dotCooCoo in #5611
- Fix #5483: a large font library no longer keeps the window from opening by @mockydevs in #5613
- Tests: the opening queue tests wait on the worker's signal instead of the clock by @dotCooCoo in #5615
- Character: Kerning reads (10+5) with a manual value too by @dotCooCoo in #5616
- Accessibility: screen readers can set a dialog slider's number by @dotCooCoo in #5617
- New Document: units belong to the chosen preset, not the whole tab by @FractalEncrypt in #5614
- Tests: the font menu and idle-socket tests don't fail on a busy machine by @bflatastic in #5624
- Gradient: Perceptual spot ink mixes stay continuous from red to blue by @dotCooCoo in #5618
- Type: Touch Type moves an upright character in vertical type down and across its column by @dotCooCoo in #5619
- Type: baseline shift moves an upright glyph across the column in vertical type by @dotCooCoo in #5620
- Gradient: PDF shading notes name linear and radial gradients and DeviceN by @dotCooCoo in #5621
- Fix #5502: Export As PNG exports the active artboard, not always the first by @mockydevs in #5623
- Symbols: the quick box of a 9-slice instance holds art its guides move by @dotCooCoo in #5625
- Symbols: saving leaves out a nested editing layer and keeps layers named in file data by @dotCooCoo in #5626
- i18n: a count in a translated message matches only a number by @dotCooCoo in #5627
- Docs: type-parity lists manual tate-chu-yoko once by @dotCooCoo in #5629
- Type: right-to-left manual kerning keeps whole-point spacing on both sides by @dotCooCoo in #5628
- OpenType: a menu choice at a Type tool caret reaches every character by @dotCooCoo in #5631
- Select: All on Same Layers takes the layers of objects that can be selected by @dotCooCoo in #5634
- Fix #5160: a slow first frame is waited for, not blamed on the graphics adapter by @mockydevs in #5635
- Tests: a file placed while idle renders on the test thread by @dotCooCoo in #5637
- Plug-ins: color parameters, and filters that make guides and lock by @d8abyte-dk in #5630
- .ai save: the editing copy keeps transparency, clipping and opacity masks by @dotCooCoo in #5639
- Glyphs panel: alternates for the current text selection by @dotCooCoo in #5442
- Type: Tate-chu-yoko Settings refuses a value that is not a length by @dotCooCoo in #5640
- Geometry: the nearest point on a long path skips segments whose box is farther than the best found by @dotCooCoo in #5643
- File dialogs: Open and Place list files with capitalized extensions on Linux by @dotCooCoo in #5644
- File formats: Pixar tile pointers into the header or tile table are refused by @dotCooCoo in #5645
- Select by Artboards: select objects overlapping, inside or outside chosen artboards (#5525, #5548, #5549) by @ruchirguitar in #5633
- Docs: the byte-offset rule names only commands that take a range by @dotCooCoo in #5649
- About: let every credits column be dragged and refit changed tables by @FredApps in #5650
- Canvas: Space during a tool's drag keeps the tool's cursor by @sadkotheguest in #5651
- Tests: native menu tests wait for the installed fonts' scan by @dotCooCoo in #5653
- Appearance: Add New Fill and Add New Stroke comment names the paint they take by @dotCooCoo in #5652
- Control bar: the inline X, Y, W and H fields show only when they fit by @dotCooCoo in #5655
- Images: a PNG read a row at a time counts the reader's buffer while it grows by @dotCooCoo in #5656
- Glyphs: the default glyph can be chosen back under a substituting feature by @dotCooCoo in #5657
- Tests: an RGB spot color converts with Document Color Mode and stays spot by @dotCooCoo in #5659
- Select by Artboards dialog: a plain click keeps artboards the search hides by @ruchirguitar in #5662
- i18n(fi): translate the 5 labels Finnish lacks by @Janiz-zzz in #5664
- Plug-ins: compound guides aren't filter inputs; colors follow the working RGB space by @d8abyte-dk in #5665
- About: refit credits tables on what they measure by @FredApps in #5667
- Tabs: setting the stops a paragraph already has ends the typing session by @dotCooCoo in #5668
- Keep drawing cursor during mid-drag Cmd+Space by @dotCooCoo in #5669
- Character: Kerning refuses (1,000) instead of reading it as 1 by @dotCooCoo in #5670
- Package: name every font left out when no dialog is shown by @dotCooCoo in #5671
- Gradient: Perceptual PDF help counts stops as written, CMYK documents included by @dotCooCoo in #5672
- Glyphs: a character with a combining mark reports the glyph it is drawn with by @dotCooCoo in #5674
- Glyphs: overflowing vertical type keeps a chosen default glyph by @dotCooCoo in #5676
- Tooling: reject numeric prerelease leading zeros by @MMexicann in #5678
- Tests: the link-watch and place tests wait for the link scan instead of sleeping by @dotCooCoo in #5679
- Preserve styled text after copying a Type range by @dotCooCoo in #5680
- Pathfinder: holes that touch at a point stay holes of their region by @bflatastic in #5683
- Numeric fields: 1,000% in a size field is refused by @dotCooCoo in #5682
- Preferences: Data Recovery's Folder gets a Choose button by @dotCooCoo in #5681
- Symbols: quick boxes hold art that nested 9-slice guides move by @dotCooCoo in #5685
- Fix #5336: Optical kerning spaces pairs by the font's own stem spacing by @ruchirguitar in #5686
- Render: a long dashed stroke is outlined only near the view after an edit by @dotCooCoo in #5690
- Gradient: Perceptual PDF help says an RGB destination keeps RGB stops in RGB by @dotCooCoo in #5691
- Appearance: edits to the active row reach the matching row in each selected object by @dotCooCoo in #5692
- Glyphs: the Glyphs query reports a consonant's glyph, not its vowel sign's by @dotCooCoo in #5697
- Use destination style for external same-text paste on Windows by @dotCooCoo in #5696
- Transform Each: Relative and Absolute scaling, the scale link, and the documented panel order by @FractalEncrypt in #5695
- Find Font: Replace With Font lists family and style rows by @sadkotheguest in #5677
- Layers: thumbnails of long paths are drawn off the UI thread by @dotCooCoo in #5700
- Glyphs: a consonant's ligature in a cluster with its vowel sign is its glyph by @dotCooCoo in #5701
- Pass the Linux signing key to the release workflow by @dylanmtaylor in #5702
- Fix tinted symbol colors in Expand Appearance by @dotCooCoo in #5703
- Keep symbol colors when expanding a hidden tint by @dotCooCoo in #5704
- Layers: opacity masks and edited objects count toward the thumbnail anchor limit by @dotCooCoo in #5705
- Render: the frame after anchors of a long path move updates only the segments that touch them by @dotCooCoo in #5706
- Glyphs: the Glyphs query reports the glyph of an overflowing character by @dotCooCoo in #5707
- Menus: Delete Empty Artboards and Save Gradient Preset decide their enabled state with less measuring by @dotCooCoo in #5708
- Type: Paste keeps a copy the system clipboard refused by @dotCooCoo in #5709
- Control server: close connections gracefully, so a reply is not lost to a reset by @bflatastic in #5716
- Docs: describe what a Layers row shows while its first thumbnail renders by @dotCooCoo in #5711
- Glyphs: a character's glyph is the first of its glyphs in its cluster by @dotCooCoo in #5712
- Symbols: an instance fill with no opacity keeps the art's swatch links by @dotCooCoo in #5717
- Glyphs: the Glyphs query reports the fallback glyph of an overflowing character by @dotCooCoo in #5718
- Type: a copy elsewhere during a refused write wins the paste by @dotCooCoo in #5719
- SVG export: type with Mojikumi and no Japanese characters is laid out once by @dotCooCoo in #5720
- Glyphs: a fallback face's consonant glyph is reported, not its vowel sign's by @dotCooCoo in #5721
- Type: a refused copy is dropped when a textless clipboard can't track it by @dotCooCoo in #5722
- Tests: the Type › Font menu test waits for the installed fonts' scan (#5647) by @mockydevs in #5723
- PDF import: a DeviceN gradient of a spot ink over process plates keeps the ink and the plates, and PDF export writes it as DeviceN again (#3235) by @mockydevs in #5724
- Isolation mode: a locked or hidden layer keeps the isolated art from clicks and marquees (#5309) by @mockydevs in #5726
- Numeric fields: a decimal comma works in arithmetic next to a number with a point (#5684) by @mockydevs in #5727
- Color Halftone: Max Radius in pixels of the raster effects resolution by @datatimp in #4784
- Effects: Expand Appearance makes each copy of a path's Transform effect an object of its own (#5612) by @mockydevs in #5728
- Layers: heavy type, symbols, meshes and images get their first thumbnail off the UI thread on the desktop by @dotCooCoo in #5730
- Artboards: Shift- and Ctrl/Cmd-click in the Artboards panel select several artboards with any tool, and Fill applies to all of them (#5698) by @mockydevs in #5731
- Render: a moved path reuses its stroke outline by @dotCooCoo in #5732
- Set Corners: round all, odd-numbered or even-numbered anchors (#5546) by @mockydevs in #5733
- fix(ui): avoid duplicate cursor without Wayland theme by @makzumi in #5734
- Control bar and task bar: idle frames borrow the selected object instead of copying it by @dotCooCoo in #5735
- Gradient panel: Delete Stop sits beside the ramp, so a short panel no longer hides it (#5403) by @mockydevs in #5736
- Set Corners: round only the corners in an angle range (#5545) by @mockydevs in #5737
- Fix #5532: Release Type on a Path splits type on a path into point type and its path by @ruchirguitar in #5738
- Preferences: Additional Plug-ins Folder gets Choose…, and OK checks typed folders by @dotCooCoo in #5741
- Render: at very large coordinates an edited path is not taken for a moved one by @dotCooCoo in #5743
- Rasterize: Color Model is a dropdown of the document's model, Grayscale and Bitmap (#5660) by @mockydevs in #5747
- Keep Pencil and Paintbrush Fidelity in screen pixels at any zoom by @Silvertree2010 in #5748
- Document tabs: drag a tab along the strip to reorder the open documents (#5663) by @ruchirguitar in #5749
- Part of #394: each run hyphenates in its own language; Default Language sets new type's by @jo-quast in #2818
- Global Edit: the enabled check decides without normalizing every anchor by @dotCooCoo in #5751
- Contour: live offset tool with a floating bar and its own icon by @K1nsmark in #5694
- MCP: pointer_gesture waits for a key sent before it by @dotCooCoo in #5753
- MCP: remote press_key does not run single-key shortcuts by @dotCooCoo in #5754
- Line a moved selection's edges up with ruler guides by @Silvertree2010 in #5755
- Render: a moved path reuses its gradient stroke slices by @dotCooCoo in #5756
- Compound shapes default by @K1nsmark in #5757
- Layers: the shown document's thumbnails are not held up by another document's queue by @dotCooCoo in #5758
- Fix #5526: select images by link status by @ruchirguitar in #5759
- Render: adding or deleting an anchor of a long path splices the kept path by @dotCooCoo in #5744
- Shape Builder: a merge or erase takes the stretch of every coincident line by @dotCooCoo in #5761
- MCP: pointer_gesture rejects a backquote that is not a boolean by @dotCooCoo in #5762
- SVG export: numbers are written from integers, not through the exact float formatter by @dotCooCoo in #5763
- Tests: the Devanagari fallback-glyph test passes when the fallback face substitutes the vowel sign by @dotCooCoo in #5764
- Type: text cleanup and Convert to Text act on every frame of a selected story by @dotCooCoo in #5766
- MCP: a given-up pointer request no longer holds back later requests by @dotCooCoo in #5768
- .ai save: guides in the editing copy end with the guide operator only by @dotCooCoo in #5770
- .ai save: the editing copy keeps gradients and patterns by @dotCooCoo in #5771
- MCP: pointer_gesture fails when the input sent before it is dropped by @dotCooCoo in #5772
- Document tabs: views stay with their documents when one batch closes and moves documents (#5663) by @ruchirguitar in #5774
- .ai import: object tags open as each object's URL and data by @dotCooCoo in #5775
- .ai/EPS import: type that names no style takes the normal styles by @dotCooCoo in #5777
- #1280: perf --deep measures pointing; PathData::bounds builds no path by @FredApps in #5778
- .ai import: version 7 linked images open as linked images with a placeholder by @dotCooCoo in #5779
- Keep font wheel input with the top native panel layer by @dotCooCoo in #5780
- #1280: PathData::bounds closes a NaN anchor as kurbo does; the perf row names what it times by @FredApps in #5781
- MCP: given-up stale pointer requests do not use up a frame's request limit by @dotCooCoo in #5782
- .ai import: area type with linked areas opens as threaded frames by @dotCooCoo in #5783
- .ai save: the editing copy keeps images and linked files by @dotCooCoo in #5784
- .ai save: new gradient names continue from the last one given by @dotCooCoo in #5786
- Panels: a floating palette keeps out of the way of modal dialogs and menus by @sadkotheguest in #5787
- perf(pathops): optimize Pathfinder Trim, Crop and Merge with batched face classification (#4503) by @el-j in #4511
- Refresh Find Font warnings after document changes by @dotCooCoo in #5773
- .ai import: several clipping paths clip to their intersection by @dotCooCoo in #5789
- .ai import: 1-bit image masks open colorized by their fill color by @dotCooCoo in #5790
- Layers panel: a layer that does not print shows its name italic by @sadkotheguest in #5791
- Export: raster output defaults to the document resolution by @KnottyDyes in #3071
- .ai import: type with the older TS, Te and TM operators opens by @dotCooCoo in #5792
- fix(pathops): bound offset path complexity and handle arrangement failure safely (#4145) by @el-j in #4345
- M2.1: copy and cut direct-selected segments and anchors as independent paths (#2122) by @el-j in #3903
- .ai import: a re-encoded font's own encoding pairs decode its type by @dotCooCoo in #5793
- Keep Group Selection drags on the selected outlined component by @FractalEncrypt in #3272
- Preserve raster coverage of thin curved strokes by @FractalEncrypt in #3273
- Reject malformed Batch Trace Folder options by @dotCooCoo in #5794
- Release Layers thumbnails when a document closes by @dotCooCoo in #5795
- i18n(ka): Georgian for 1 new string by @devius in #5798
- Actions: loading an action set checks its size before reading it by @dotCooCoo in #5799
- .ai import: gradients and patterns are named up to the newline in their names by @dotCooCoo in #5800
- .ai import: legacy type used as a mask clips its clipping group by @dotCooCoo in #5801
- Stop queued Layers thumbnails when both thumbnail panels are hidden by @dotCooCoo in #5802
- Tests: the read_file_head test creates its file exclusively and removes it on failure by @dotCooCoo in #5803
- Disable Object > Path items when no path is selected by @Silvertree2010 in #5805
- Color Effects: Apply Fill to Stroke and Apply Stroke to Fill (#5530) by @Hamza0101 in #5776
- Layers: closing a document drops its running thumbnail job's image by @dotCooCoo in #5806
- Links: a classic Mac OS path is named by its file name by @dotCooCoo in #5807
- .ai import: the file opens on its active artboard by @dotCooCoo in #5808
- Fix thumbnail work for active collapsed flyout tab by @dotCooCoo in #5809
- Preserve queued key order before MCP tool selection by @dotCooCoo in #5810
- .ai import: legacy type keeps its tab stops by @dotCooCoo in #5811
- .ai import: 6D Art Pen brushes open live, and Windows reads pen tilt and rotation (#372) by @Locme in #5815
- Images: a colorized image's missing-link placeholder shows in its own colors by @dotCooCoo in #5817
- Skip unused path bounds during SVG export by @dotCooCoo in #5818
- Clean up temporary files in desktop tests by @dotCooCoo in #5819
- Add-on: 3D Box tool and context-sensitive customizable shape controls by @odysseexp in #5765
- Docs: the .ai editing-data checklist lists how several clipping paths clip by @dotCooCoo in #5821
- Pencil: a new stroke with Keep selected off leaves nothing selected (#5752) by @sadkotheguest in #5822
- Avoid measuring selected art twice for library paint by @dotCooCoo in #5823
- .ai import: version 7 pattern fills in brush art use their operands by @dotCooCoo in #5824
- Skip path rebuild for single-stroke Eyedropper samples by @dotCooCoo in #5825
- Links: Find Linked Files resolves parent folders in a saved path by @dotCooCoo in #5826
- Appearance: Delete Selected Item on an Opacity row sets it back to Default (#5742) by @mockydevs in #5827
- Libraries: spot colours stay spot colours in every document (#5812) by @mockydevs in #5829
- Links: params text and MCP docs say parent folders are resolved by @dotCooCoo in #5830
- .ai import: graphic style libraries open with their styles by @dotCooCoo in #5831
- Selection: a hover checks the bounds memo once, not once per object by @FredApps in #5832
- .ai import: objects other than type keep some Distort & Transform effects live by @dotCooCoo in #5833
- Type: Show Snap to Glyph Options scrolls the Character panel to the options (#5273) by @mockydevs in #5834
- Links: the hashing limit reads 1 GiB in the docs by @dotCooCoo in #5836
- Dialogs: the header that moves a dialog keeps the arrow cursor until dragged (#5246) by @mockydevs in #5837
- .ai import: symbols and their instances open live by @dotCooCoo in #5838
- Shape tools: a shape just drawn shows its bounding box and Live Shape widgets, and its corner and pie widgets drag with the shape tool (#5477) by @mockydevs in #5839
- Effect dialogs: a colour swatch beside a hex colour opens the Color Picker (#5365) by @sadkotheguest in #5843
- Images: a reduced image is shrunk before it is separated into ink planes (#4155) by @simonhull in #5845
- Type: Enter, arrows, Home, End, Tab and the clipboard apply in order with the frame's text by @dotCooCoo in #2636
- Control bar: Paragraph options while type is selected (#5372) by @ZIDAN44 in https://github.com/storytold/vectorcraft/pull/5847
- Canvas: a document's first frame renders on the render worker (#4155) by @simonhull in https://github.com/storytold/vectorcraft/pull/5848
- Tests: the first-frame worker test tolerates another test's placed document by @bflatastic in https://github.com/storytold/vectorcraft/pull/5853
- SVG import: a clipPath's children clip to their union, each under its own clip-rule (#5840) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5849
- Join tool: scrubbing the ends of two crossing paths trims them and joins the paths at the crossing (#5844) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5850
- Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box (#3901) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5851
- SVG import: textLength and lengthAdjust fit text to its length (#5842) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5852
- Blend spine: Shift-click picks several spine points, which drag together (#5285) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5854
- SVG import: clip path on clipPath children clips child silhouettes before union (#5841) by @kk376 in https://github.com/storytold/vectorcraft/pull/5855
- Images: an image zoomed in on has its colours made only for the tiles in view (#4155) by @simonhull in https://github.com/storytold/vectorcraft/pull/5856
- Intertwine: the object brought over leaves no hairline of the one below (#5337) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5857
- Properties: Quick Actions has Repeat Options for a selected repeat (#5181) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5858
- Effects: an image's Inner Glow follows its visible pixels, not its frame (#5308) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5859
- Variables: Load Variable Library keeps a bound text variable the library declares (#4136) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5860
- Tests: two canvas tests render on their own thread by @bflatastic in https://github.com/storytold/vectorcraft/pull/5862
- Scrubby labels: the Control bar's Stroke: and Opacity: links scrub their fields (#4088) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5861
- Tests: the Cmd bounding box test clears its texture delta by @bflatastic in https://github.com/storytold/vectorcraft/pull/5864
- Properties: Edit Artboards shows a Transform section above the artboard options (#5219) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5863
- Reuse text outlines across moves by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5865
- Rebuild fitted text geometry after scaling by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5866
- Reject invalid Slice toggle parameters by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5867
- Reuse selected object locations for large transforms by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5868
- Reject invalid Transparency Grid parameters by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5869
- .ai import: symbol, pattern and brush definitions share the file's blend and envelope limits by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5871
- Reject invalid Guide Lock parameters by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5872
- Speed up hover hits on long plain paths by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5873
- Reject invalid New Art Basic parameters by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5874
- Direct Selection: the cursor reuses the hit result over a path by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5879
- Docs: the .ai notes no longer list guides as a known failure by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5880
- Selection: empty-canvas hover skips distant widgets in large selections by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5881
- i18n: add Hindi interface and message catalog by @ruchirguitar in https://github.com/storytold/vectorcraft/pull/5882
- Tests: a fitted text test changes its fit scale by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5884
- Rendering: open width-profile strokes outline only near the view by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5883
- .ai import: legacy type keeps one copy of tab stops its paragraphs share by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5885
- .ai import: a file whose editing data has no layers also opens on its active artboard by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5886
- Commands: true/false flags reject other values everywhere by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5888
- Docs: .ai symbols are read with the file's layers by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5892
- Text: empty later frames preserve an edited paragraph style by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5893
- fix(eps): bitshift by the most negative integer no longer overflows on negation by @jayzed80 in https://github.com/storytold/vectorcraft/pull/5894
- i18n(sv): translate 1432 new strings, use the agreed terms in 2 by @kler in https://github.com/storytold/vectorcraft/pull/5895
- Automation roots: refuse COM¹ to LPT³ as Windows device names by @adikshan11 in https://github.com/storytold/vectorcraft/pull/5896
- Text: a restyled empty frame keeps its style before an unedited empty frame by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5897
- Layers: F2 renames the selected layer, group or object (#5324) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5828
- Reject invalid Tab Stop string parameters by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5899
- Blend spine: moveAnchor refuses
withalongsidehandle; spine built once per overlay and drag by @mockydevs in https://github.com/storytold/vectorcraft/pull/5904 - .ai import: a pattern or color named as another swatch keeps its swatch by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5903
- SVG import: gradients with color-interpolation="linearRGB" mix their stops in linear light (#5878) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5905
- Legacy .ai export: black-and-white colorized images save as image masks by @dotCooCoo in https://github.com/storytold/vectorcraft/pull/5906
- PDF and .ai export: objects' URLs become clickable links (#5785) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5908
- SVG import: Gaussian blurs keep color-interpolation-filters; Gaussian Blur can blur in linear light (#5877) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5909
- Stroke Weight Up and Down: Cmd/Ctrl+Alt+. and , step the selected strokes' weight (#5797) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5910
- SVG import: filter and mask regions clip what they declare (#5876, #5875) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5913
- Keep the other library when two names share a file name by @adikshan11 in https://github.com/storytold/vectorcraft/pull/5914
- Keep a symbol's options when pasting it into another document by @Silvertree2010 in https://github.com/storytold/vectorcraft/pull/5915
- Drop Shadow and Outer Glow: spinner arrows step Opacity, the offsets, Blur and Darkness (#5367, #5368) by @mockydevs in https://github.com/storytold/vectorcraft/pull/5916
- Copy the shared house rules into AGENTS.md by @FredApps in https://github.com/storytold/vectorcraft/pull/5923
New Contributors
- @JonRC made their first contribution in #5314
- @cybermaxwel made their first contribution in #5329
- @thisisgomaa made their first contribution in #5261
- @FrancoJacquet made their first contribution in #5453
- @byoungyoon made their first contribution in #5561
- @d8abyte-dk made their first contribution in #5630
- @sadkotheguest made their first contribution in #5651
- @makzumi made their first contribution in #5734
- @jo-quast made their first contribution in #2818
- @K1nsmark made their first contribution in #5694
- @Locme made their first contribution in #5815
- @simonhull made their first contribution in #5845
- @ZIDAN44 made their first contribution in https://github.com/storytold/vectorcraft/pull/5847
- @kk376 made their first contribution in https://github.com/storytold/vectorcraft/pull/5855
- @adikshan11 made their first contribution in https://github.com/storytold/vectorcraft/pull/5896
Full Changelog: v0.21.1...v0.22.0