chore: sync upstream (58 Commits) #24

Merged
alf merged 58 commits from chore/sync-upstream-20261111 into main 2026-11-11 21:48:13 +00:00
Owner

Upstream-Sync von upstream/main (58 Commits). Fast-Forward.

  • d6a09639 Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237)
  • dc9eea26 Small bounds: outline simplification, table row insertion, note ids, xtask stats (#2232)
  • eba00a0d Opening documents: index lookups in Document::check and the format-1 style upgrade (#2218)
  • 15bea9fa Tagged Text, RTF, EPUB classes and PDF layers: lookups by set or map instead of list searches (#2212)
  • 5a350751 File reads: refuse devices and pipes, cap whole-file reads (#2227)
  • 8d595904 Package: copy each font as it was loaded, check read roots, number duplicate names in one pass (#2208)
  • cfd99ba9 Automation roots: compare paths exactly; recovery reads only regular entry files (#2205)
  • 34f24a4d Gradients: expand midpoint stops in linear time (#2214)
  • eba5b9f8 datamerge: all further pages in one insertion, page lookups by start index (#2279)
  • c684db54 Tools: selection bounds in one walk, bounded smart spacing and parent snapping (#2260)
  • 79d7a912 Strokes: cap the points a wavy or hashed stroke places along a path (#2188)
  • 589f5ff8 Engine: Erase and Smooth search each distinct drag sample once (#2272)
  • bcbc3ed4 Story: appending text no longer scans every run and the whole prefix (#2245)
  • ed3f45a5 render: cap the blend-area growth rounds, one name per optional-content layer (#2257)
  • 94c67985 swatches panel: group membership and row lookups by name map (#2262)
Upstream-Sync von `upstream/main` (58 Commits). Fast-Forward. - d6a09639 Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) - dc9eea26 Small bounds: outline simplification, table row insertion, note ids, xtask stats (#2232) - eba00a0d Opening documents: index lookups in Document::check and the format-1 style upgrade (#2218) - 15bea9fa Tagged Text, RTF, EPUB classes and PDF layers: lookups by set or map instead of list searches (#2212) - 5a350751 File reads: refuse devices and pipes, cap whole-file reads (#2227) - 8d595904 Package: copy each font as it was loaded, check read roots, number duplicate names in one pass (#2208) - cfd99ba9 Automation roots: compare paths exactly; recovery reads only regular entry files (#2205) - 34f24a4d Gradients: expand midpoint stops in linear time (#2214) - eba5b9f8 datamerge: all further pages in one insertion, page lookups by start index (#2279) - c684db54 Tools: selection bounds in one walk, bounded smart spacing and parent snapping (#2260) - 79d7a912 Strokes: cap the points a wavy or hashed stroke places along a path (#2188) - 589f5ff8 Engine: Erase and Smooth search each distinct drag sample once (#2272) - bcbc3ed4 Story: appending text no longer scans every run and the whole prefix (#2245) - ed3f45a5 render: cap the blend-area growth rounds, one name per optional-content layer (#2257) - 94c67985 swatches panel: group membership and row lookups by name map (#2262)
alf added 58 commits 2026-11-11 21:48:12 +00:00
The EPSF binary header is 22 bytes (magic, psStart, psLength, tiffStart,
tiffLength, checksum), so the TIFF section is at 12/16 — not at 20/24,
which is the checksum plus the first two bytes of the PostScript section
and always lands past the end of a real file. A legacy DOS EPS therefore
never showed its preview: it fell back to drawn rectangles or the grey
placeholder. The old fixture encoded the same wrong layout, so it could
not catch it.

Read tiffStart/tiffLength at 12/16, document the header, and rebuild the
fixture on the real layout. Regression: the fixture test fails on main
(pixel_size 201x101 — the stand-in) and passes with the fix (10x5 — the
preview).
The DOS EPS header is 30 bytes: WMF offsets at 12/16, TIFF at 20/24,
checksum at 28-29 (EPSF 3.0, section 5.2). Reading the TIFF preview from
the WMF slot stopped standard previews from loading; the offsets and the
fixture are back where the spec puts them, and a WMF-only file now has a
regression test.
In a spread with two or more pages the paper is one rectangle and
nothing marked where the pages meet. Draw a hairline at each shared
page edge, the full height of the taller page, in the guides pass: it
shows on screen only, hides with the other guides and in the preview
modes, and exports never see it since the render crate draws no chrome.

Tests: a three-page facing document gets one spine between pages 2 and
3 and none at outer edges; the line goes with guides off, in Preview
and in Presentation.
Review follow-up: bound right to left, a spread lists its right page
first, so averaging the first page's right edge with the second page's
left edge put the line halfway between the outer edges when the pages
differ in width. Order the two pages by position and use the edges that
meet. Test: a right-to-left spread whose right page is narrower.
Review follow-up: the spine runs the height of the taller page. Make the
narrower right page shorter too, so a line that stopped at the page
listed first would fail the test.
The spine used the UI theme's dim text colour, which follows the app
theme while the paper follows the document, so on white paper it was
barely visible (about 1.25:1). The spine is the inner edge of the
spread, so it now uses the same dark grey hairline as the spread's
outline, through one shared PAGE_EDGE constant for both; it reads on
white paper and doesn't change with the theme. Not the smart-guide
green, which marks snapping and would make the spine look like one.
# Conflicts:
#	ROADMAP.md
The canvas worked out page boundaries itself, pairing pages in list
order and drawing a line between each pair. Pages that don't touch (an
imported spread can keep gaps between them) got a false spine in the
gap, and list order isn't position order for every spread.

Spread::page_seams, next to spine_x, now gives the edges where two of a
spread's pages meet: pages in position order, facing edges that touch,
each seam spanning both pages' heights. The canvas draws exactly those.

Test: page_seams for a facing pair in either list order, three pages
(two seams), a single page (none), a gap (none) and pages of different
heights.
# Conflicts:
#	ROADMAP.md
A GREP style's subroutine calls ((?1), (?R), \g<name>) are inlined by the regex compiler, so a short pattern whose groups call each other twice compiles exponentially. The dialect has no subroutines; they are now refused before compiling.

find_nonempty skipped empty matches without counting them, so a pattern that only matches empty ran one search per character. Each search now counts: the scan stops after limit x SEARCHES_PER_MATCH searches.
- crates/compose/src/grep.rs
Copying, pasting, deleting or releasing an anchored text frame left a
document that Document::check rejects, so once saved it could not be
opened again.

- Copy and paste: copied text takes the stories of its anchored text
  frames along. Pasting text (also into another document) gives the
  anchored copies fresh ids and stories of their own
  (Document::adopt_anchored), and the text clipboard keeps a copy of the
  source document holding only those stories and the graphics the text
  and they place, which come along under the destination's asset ids
  (Document::adopt_anchored_from). A story shown by frames in several
  copied stories is copied once per paste and threads all their copies, as
  the original does, so shared stories don't multiply. Copied frames
  (clip_doc) keep the stories of their anchored frames too.
- Document::fix_anchored_text_frames, run after edits and for new
  documents: copies with taken ids get fresh ones and stories of their own,
  deleted anchored frames leave their threads and their stories go with
  them, and a frame whose story is missing gets an empty one.
- Release threads the released frame, under its new id, to its story.
- The generated endnote story is set before the repair, and again when the
  repair changed anything: text with an anchored frame pasted into it is
  replaced, and the repair copies and removes stories with their endnotes.

Duplicating and pasting frames already give anchored items fresh ids and
story copies on main (#1522); this covers text copied with them, deletion
and release.
fix_anchored_text_frames walks every story, and ran after every edit in a
document with anchored items. It now runs only when the edit could have
left something to repair (Document::anchored_items_changed_since): a story
added with anchored items, a story removed, or a story whose anchored items
(their ids and the stories they show) or thread changed. Typing,
formatting and moving frames compare the stories that changed and skip it.
The endnote story is still set before the repair and again after it.
Fixes #2514.

- crates/doc/src/arrow.rs
- crates/doc/tests/autocraft_regression_2514.rs

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
* Place: a graphic dropped on a line gets its own frame and leaves the line alone (#2290)

drop_frame took any unlocked item under the pointer whose content takes a
graphic, so a file dropped on a line's stroke turned the line into a
zero-height image frame. It now also requires the item's path to enclose
an area, as the place cursor's click already does.

* Place: the next file of a drop doesn't replace a graphic that got its own frame (#2290)

A graphic dropped on a line, or on the page, gets a frame of its own at
the pointer but left frame_free set, so the next file of the same drop
found that new frame under the pointer and replaced the first graphic.
Any graphic placed by the drop now clears the flag.
GREP: refuse subroutine calls and bound the empty-match scan
* pt-BR: translate the 634 interface strings added since the catalog was completed

Covers the strings the catalog lacked after #495: tool names, menu
paths (Edit > Menus), Japanese typesetting dialogs (ruby, kinsoku,
mojikumi, warichu, kenten), special characters, Load Styles, Text
Frame auto-size, Data Merge, preflight, font replacement and About.
Tools are "Ferramenta X", parent pages "página principal", stories
"artigo"; menu paths reuse the existing menu names. IT, VA and Y:
stay as they are, as in every other language.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pt-BR: one term per feature, the unit names, a catalog test and the docs

Review fixes for the new rows: Gradient Feather, stroke styles and type
on a path use the catalog's existing terms; warichu's Line Spacing no
longer reads as Leading; em/en dash, hair space, nonbreaking space and
hyphen and paragraph return take their Brazilian typographic names; the
file and word counts read correctly for one. File > New's unit names,
which reach tr at run time, are translated too.

The new test checks every pt-BR row's placeholders, padding and
ellipsis, and that each menu path is made of the menu names.

Docs: pt-BR re-measured at 2,416 of 2,419 strings (61% before) in
localization-parity.md, gaps.md (gap 21), target-app-parity.md and the
ROADMAP languages table and progress log. Readiness is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: trace each localization count to its commit; list Russian

The 1,724 baseline was counted at a127c6d5 (#355); recounting that
commit by the same rule gives 1,723, with pt-BR at the same 1,057. The
2,419 strings are main at 438d7b6d. The 2,021 figure is gone: it was
the same rule at the last commit of 2026-10-10, not another scale.

Russian (ru, 1,705 of 2,419) joins the other shipped languages, which
makes six beyond the twelve; ROADMAP's two "Also shipped" lines become
one that includes it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pt-BR: the 12 strings main added since; docs re-measured at 2e36dcf9

Merging main brought window and guide commands, the InDesign shortcut-set
import and the credits' PRs column, which pt-BR didn't translate yet. Its
button label and result message reach tr as literals no other catalog
has, so they join the shared test's list of UI strings.

Re-measured at main 2e36dcf9: pt-BR translates 2,431 of 2,434 strings
(the Control panel's IT, VA and Y: stay English) and the unit names;
Russian 1,709 of 2,434. The PR adds 645 strings and 7 unit names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: pt-BR at 2,574 of 2,941 strings by i18n-report; Russian listed

Re-measured on main f3bcc886 with `cargo xtask i18n-report`: pt-BR
translates 2,574 of 2,941 interface strings (1,933 before); the 367 it
lacks are mostly strings main added since 2026-10-23. pt-BR to full is
4-6 h. localization-parity.md, gaps.md (gap 21), target-app-parity.md
and the ROADMAP languages table and progress log say so, each with its
revision row; the ROADMAP entry is dated today, as the review asked.

Russian (1,855 of 2,941) joins the other shipped languages, eight beyond
the twelve, and ROADMAP's two "Also shipped" lines become one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pt-BR: drop two rows main removed; the test lists eight live labels

`cargo xtask i18n-report` flagged ten pt-BR rows whose keys its
interface list lacks. "/1000 em" and "Import InDesign Set…" are gone
from the code, so their rows go. The other eight still reach tr
(Auto-Sizing, Color Theme, Minimum Height/Width, No Line Breaks,
Reference Point, the shortcut-import result and the unavailable-fonts
message) and join the test's list of UI strings.

The report now counts 2,939 strings; pt-BR translates 2,572 of them
(88%), Russian 1,853. The docs say so; the PR adds 632 strings and the
7 unit names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pt-BR: the 364 strings main added since 2026-10-23

Keyboard Shortcuts sets (craft-keymap's dialog, import messages and
counts), panel docking, OpenType features, page presets, the Package
summary and the command dialog's parameter names. "Atalho", "conjunto"
and "escopo" for shortcut, set and scope; tab groups stay "grupo de
guias" and inks "de escala"/"especial", as in the catalog. Key names
stay as printed on keyboards.

`cargo xtask i18n-report` now lists only the Control panel's IT, VA and
Y: for pt-BR: 2,936 of 2,939 strings. The docs say so; pt-BR to full is
1-2 h (an in-app check and the older parent-page and story terms).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pt-BR review fixes: Affix in, Dir, End, Pathfinder and three clashes; doc scales

- "Affix in" (where footnote prefix and suffix appear) is "Afixos em".
- "Dir" is a folder in file.save, recovery save and links.copyTo and a
  direction in text.move: "Pasta/direção".
- The End key is "Fim", as Home is "Início".
- Pathfinder keeps its name ("Objeto/Pathfinder"), as "Pathfinder:"
  already did, instead of "Localizador de caminhos" beside "demarcador".
- Pattern (stroke dashes) is "Padrão de traço", apart from Default
  ("Padrão"); Skipped is "Pulados", apart from "ignoradas"; Heading is
  "Intertítulo", apart from Title and Section headings.

ROADMAP's "Also shipped" line now uses one scale (today's i18n-report of
2,939 strings); the pt-BR note names main ef6c3686, and Russian reads
1,855 of 2,939.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
* Fix Links panel stalls on network paths

* Fix Links review findings

* Fix Links worker gating and wasm build

A link check blocked on another document's unreachable share no longer
holds back the document now shown: after 200 ms a fresh worker takes
over (at most four alive at once) and the stale result is dropped.

relinked_asset used the native-only fingerprint_from, breaking the
wasm build; it now uses fingerprint_of. The EPS relink and IDML link
reach tests build Windows paths correctly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Fix Links worker repaint and graphic read retry

Switching documents before the 200 ms takeover now schedules a repaint
for it: a blocked worker never asks for one, so without other input the
panel kept waiting. A failed graphic read is no longer cached as
missing, so the next check reads again. The legacy EPS fixture clears
its source fingerprint, as documents from before fingerprints have
none, so the test no longer depends on running within two seconds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Keep touched links OK and poll Links within seconds

Only a new size now marks a graphic Modified from its fingerprint. A
file with the same size but a new time (saved again, copied, restored
or checked out) is compared byte for byte, once per new time, and stays
OK when unchanged.

External changes are polled every two seconds instead of every five
minutes. The next check waits at least as long as the last one took
(up to five minutes), so a slow share stays idle half the time.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Wake Links when a worker slot frees; translate check strings

A worker thread asks for a repaint when it ends, so a document waiting
at the four-worker limit gets a worker as soon as a superseded one
returns from its blocked call, without other input.

Rows from a check keep a weak reference to their document. The key
names it by address, which a later document can't reuse while the
allocation is kept.

The Links panel's new strings ("Checking", "Checking links…", "Link
status is unavailable.") use the UI's ellipsis and are translated in
every interface language. The comments on Session::text_link_checks and
on the byte comparison in links::status describe what they do now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Links: rows from the document, statuses from a check that can stop

The panel lists links from the document on the UI thread (no file is
looked at) and fills in the statuses a worker check last found, kept
per document. An edit shows at once, and a check of an earlier edit
still supplies statuses instead of being discarded.

- A check of another document is told to stop and ends before its next
  file; only one blocked in a file system call is replaced, so blocked
  workers no longer hold their slots for a whole document.
- Checks are timed on the worker, and what they remember passes to the
  worker that replaces them.
- A fingerprint is kept only for a file whose time was settled when it
  was read, as for linked text. A file found unchanged by its bytes
  gets its current size and time stored with the document
  (remember_link_files), without marking a saved document as changed.
- Asset::set_link keeps link and fingerprint together; copies made by
  Package and Copy Links To carry none.
- The Session holds one LinkListChecks. Update Link lists files only
  when a linked story was edited in the layout.
- The unused "Checking links..." caption is removed.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: FredApps <153173854+FredApps@users.noreply.github.com>
Anchored text frames: own stories and ids through copy, paste, duplicate, release and delete
images: test WMF-only DOS EPS preview handling
- crates/engine/src/cmd/variables.rs
- crates/engine/src/cmd/variables/tests.rs
- crates/engine/src/script.rs
- crates/engine/src/cmd/variables.rs
- crates/engine/src/script.rs
Engine: variable deletion and merge-marker scans that end, a depth and step budget for nested scripts
Canvas: a spine line where the pages of a spread meet (#1838)
Adds step-security/harden-runner (audit, pinned to v2.22.4 like
craft-common-actions) as the first step of each job that did not have it,
so every workflow in the org's public repos reports its egress to
StepSecurity. Audit, not block: block-mode allow lists come from each
job's observed traffic.
Updates: take craft-update from craft-libs main at 6e03f65bf
* fix(flatpak): allow release checks and self-update helpers

* test: keep Flatpak permission parsing within strict Clippy rules
* Tables: commands given a table id run with nothing in a table selected

Table commands whose params list `story?` and `table?` (table.insertRow,
table.deleteColumn, table.options, the Convert Rows commands and the
others) were refused with "place the insertion point in a table" when the
call named the table but the selection was not in one. A call that passes
`table` now acts on that table whatever is selected. A table that is not
in the document, or not in the given `story`, is refused, and a `story`
that is not a non-negative integer is an error.

The menus are unchanged: with nothing in a table selected, the table
items stay disabled, and calls that name no table are still refused.

* Tables: a bad story is refused whether or not a table is selected

A call that names a table with a story that is not a non-negative integer (a string, a negative number, a fraction or null) was refused only when nothing in a table was selected. With a table selected, the command ignored the story and acted on the named table. Both paths now read story with one helper and refuse it the same way.

* Tables: an edit to a named table keeps a caret in footnote text

With the caret in footnote text, a table command that names a table
runs, and the edit cleared the caret's footnote address, so the next
typing went into the story. clamp_selection now leaves footnote
addresses alone, as in_cell does.
* doc: appending to a story extends the last run, no scans

* Apply review fixes

- crates/doc/src/story.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* engine: Erase/Smooth look at each distinct drag sample once, thinned past 4096

* Apply review fixes

- crates/engine/src/cmd/anchors.rs

* address review: decide whether a drag touched the path on every distinct sample, then thin

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
* Strokes: cap the points a wavy or hashed stroke places along a path

* address review: zero-length quadratic contributes no length in stroke samples

* Fix failing CI check

- crates/geom/src/stroke_style.rs

* Fix failing CI check

- crates/geom/src/stroke_style.rs

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
* tools: selection bounds in one walk, caps on smart-spacing boxes and parent occurrences

* Apply review fixes

- crates/tools/src/lib.rs

* address review: iterative selection walk; stop collecting spacing boxes at the cap

---------

Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
* fix(color): sample gradients by binary search when expanding midpoints

* Apply review fixes

- crates/color/src/gradient.rs

* Apply review fixes

- crates/color/src/gradient.rs

* Fix failing CI check

- crates/color/src/gradient.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* fix(engine): exact root containment and regular-file recovery entries

* Apply review fixes

- crates/engine/src/recovery.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* fix(engine): package fonts from their loaded bytes under the read roots

* address review: a font's own file is neither overwritten nor packaged when it changed since loading

* Apply review fixes

- crates/engine/src/cmd/package.rs

* address review: compare packaged font file in fixed-size chunks

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* fix(engine): whole-file reads take regular files only, up to the format limit

* Apply review fixes

- crates/engine/src/io.rs

* Apply review fixes

- crates/engine/src/io.rs

* Fix failing CI check

- crates/engine/src/io.rs

* address review: refuse to save an encoded document longer than the open limit

* address review: open files for reading without blocking (FIFOs, stream-backed pseudo-files)

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* fix: index style, font, class and layer name lookups in exporters and importers

* Apply review fixes

- crates/epub/src/css.rs

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
* fix(doc): index items, threads and styles when opening a document

* Apply review fixes

- crates/doc/src/tests.rs

* address review: borrow style names in pin_para_default

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Co-authored-by: autocraft-bot[bot] <354215646+autocraft-bot[bot]@users.noreply.github.com>
* fix: iterative outline simplification, bulk row insertion, linear note ids, no symlink walking in xtask stats

* Apply review fixes

- crates/doc/src/tests.rs
- crates/geom/src/trace.rs

* Apply review fixes

- crates/geom/src/trace.rs

* address review: cover a maximal note id in tests, format trace test

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237)
Some checks failed
ci.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (pull_request) Failing after 0s
nix.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (pull_request) Failing after 0s
packaging-lint.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (pull_request) Failing after 0s
sonarcloud.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (pull_request) Failing after 0s
ci.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (push) Failing after 0s
nix.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (push) Failing after 0s
packaging-lint.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (push) Failing after 0s
sonarcloud.yml / Repagination, IDML swatch import and style folders: linear work, bounded depth (#2237) (push) Failing after 0s
d6a09639bf
* Repagination, swatch import and style folders: linear page numbers, resumed duplicate suffixes, bounded folder depth

* fix Section initializer after merging main

---------

Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
alf merged commit d6a09639bf into main 2026-11-11 21:48:13 +00:00
alf deleted branch chore/sync-upstream-20261111 2026-11-11 21:48:13 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
iris/designcraft!24
No description provided.