Commit Graph
100 Commits
Author SHA1 Message Date
Claude 55a094475d Merge main into fix/dx12-nn-denoise
The only conflict was the 2026-10-19 whats-new entries; both are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K93HTyCiwYvbRGaAkjPvXn
2026-10-21 13:01:31 -07:00
Claude bfe3ab3d58 #2267: the Before label sits below the info overlay too
Review follow-up (CodeRabbit): zoomed in, the badge moves to the canvas'
top-left corner, where the info overlay draws its lines; with the overlay
on, the label was painted under its first line. The badge's top inset
now takes the overlay's extent as well as the filter pill's. The overlay
is split into its lines and an extent helper, laid out with the same
fonts, so the two can't disagree.

Test: zoomed_in_the_before_label_keeps_clear_of_the_info_overlay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-21 19:50:05 +00:00
Claude 1df76a12da Merge upstream main into fix/issue-2267-before-label-in-view
#2274 landed with #2470; What's New keeps both entries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-21 17:25:17 +00:00
Claude 2c085e0ae5 LR-EDIT-DETAIL-DENOISE: check the transposed convolution's stores exactly too
A max-pool, a channel-copy 2x2 transposed convolution (mode 1) and the
channel-copy 1x1 layer give an exact answer, so a store fault in mode 1
can't hide in tolerance (CodeRabbit review of #2380).

On the GTX 1070 this test passes even without mode 1's stepped stores:
FXC merges them the same way, but the driver runs that store right, so
only mode 0 was shown wrong. Mode 1 keeps the stepped stores as a
precaution; the shader comment and docs/gpu-pipeline.md now say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:34:56 -07:00
Claude 75292874a3 LR-EDIT-DETAIL-DENOISE: GPU denoise gives the right result on DX12 with NVIDIA Pascal
On DX12, FXC merged the conv kernel's four output stores (modes 0 and 1)
into one 16-byte store_raw. The DXBC is valid and aligned, but NVIDIA's
driver ran it wrong on a GTX 1070: every second pixel's channels came
out shifted, so AI Denoise on the GPU was silently wrong on Windows.
DXC and Vulkan were right on the same card.

The stores now step by `1 + p.zero` (the always-0 uniform, renamed from
`pad`), which FXC cannot fold, so it keeps them apart. A two-layer
channel-copy network checks the stores exactly; it fails on that card
without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:54:24 -07:00
Claude 1ea75ff9ea #2267: the Before label paints over the window renders, below the filter pill, inside the pane
Review follow-up:
- the badge is painted after the region window renders, which zoomed in
  covered it (the very case the fix is for);
- with a filter active, the pill in the canvas' corner has that corner:
  the badge sits below it, also when the photo's corner is just under it;
- a wide label near the pane's right edge stays 8 points inside it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 18:37:44 +00:00
Claude 3a52cbe464 #2114: the headless test clicks Restore All and the single-place row
The test checked that Restore All was listed but clicked it only when the
machine already had a hidden location, so CI never exercised that path.
It now hides two places and restores them with Restore All, then hides
one and checks the row restores it directly, without a list.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 13:41:05 +00:00
Claude 82a703111e #2267: the Before label stays in view when zoomed in
Zoomed in, the photo's corner is off the canvas, and the "Before" label
(\ key or the Before view) left the screen with it. The label's pill now
sits at the canvas' corner when the photo reaches past it, on whichever
axes it does; at Fit nothing changes. Same rule for the hovered preset's
name. Stacked on #2274 (the dark pill behind the label, same lines).

Tests: the pill geometry with the photo inside and past the pane, and a
headless check that at 100 % the registered label rect stays inside the
canvas.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 13:09:20 +00:00
Claude 4b8a5317fc #1508: a refused backup from the menu says why
The menu bar turned a command's error into a toast only for exports, so
File ▸ Back Up Library… did nothing visible when the host refused (changes
still unsaved, or nothing stored in this browser); the refusal reached only
the control channel (found in a real-browser check of PR #1987). Backup and
restore refusals are toasted too. Menu items are registered for automation
as `menuitem:<command id>`, and a headless test clicks File ▸ Back Up
Library… against a refusing host and reads the toast.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 12:39:25 +00:00
Claude e2ea657668 #2114: hidden Local locations come back one at a time
"Show N hidden locations" put every location removed from Local back at
once. With several hidden, the row now lists them (name, path on hover):
each comes back on its own, or all with Restore All. With one hidden, the
row restores it directly, as before. The command side already had
local.restoreHidden {path}; only the panel called it without a path.

The headless test hides a second place, opens the list from the row,
restores one, checks the other stays hidden, then restores the rest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 11:29:48 +00:00
Claude d4627e9c26 #1507: dropping a Session no longer panics on the web
`face_download::Downloads::drop` gave a running download a second to stop,
with `Instant::now()` and `thread::sleep`, which panic on wasm32 ("time not
implemented on this platform"). The web host replaces its Session when the
library can't be opened, so with this branch an unreadable `catalog.log`
killed the page with the generic panic screen instead of showing the
library-problem window (found in a real-browser check of PR #1988). The wait
is skipped on wasm32, where there are no download threads; the cancel flags
are still set. Native test: an idle Downloads drops at once.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 09:01:22 +00:00
Claude 5f17b48c8d #2253: crop.aspect checks orientation before the current/toggle paths
A bad `orientation` was refused only on the refit path: "current" and an
unlocked "toggle" returned before the check, so {"aspect": "current",
"orientation": "bogus"} succeeded silently, and a value that isn't a string
fell back to the default. It is parsed first now, so every path refuses a
wrong word, a number, a boolean or null, and nothing changes (CodeRabbit on
PR #2280).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-19 08:49:40 +00:00
Claude 81f02a6947 #2253: crop ratios keep the orientation asked for
set_aspect always turned the ratio to the image's orientation, so a Custom
ratio taller than wide came out landscape on a landscape photo, and a
ratio picked after X (crop.rotateAspect) turned the crop back. A named
ratio now takes the crop's present orientation (landscape, or portrait
after X; a square crop follows the image), a custom [w, h] is used as
given, and crop.aspect takes orientation: "crop" | "given" to choose.
The window reapplies the remembered ratio to an untouched photo with
orientation "crop", as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-18 22:48:56 +00:00
Claude 55b7b47925 #2242: reverseGeocode maxDistance, and the 15 000-people limit is documented
GeoNames cities15000 holds towns of 15 000 people or more, so a photo in a
smaller town got the nearest larger one in City (Portofino → Rapallo,
5.3 km), another municipality. metadata.reverseGeocode takes maxDistance
(metres): past it, City and Sublocation stay empty, State and Country
still fill, and the reply names the town as nearestCity. Hostile values
are refused. The command help, the Fill Location tooltip and the parity
row say what the list holds. Default unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-18 20:13:25 +00:00
Claude 00f55ef352 #2266: a presets.json that can't be written counts as unsaved
Preset commands change the preset list outside pending_log, and a failed
presets.json write was only logged: unsaved() stayed None, so nothing
warned and the web backup (#1987) would zip a stale presets.json; on
desktop a full disk lost the preset silently. The failure is now kept
(presets_error), counted by unsaved() (plus one change), retried by
persist_if_dirty with the same back-off as failed appends, and cleared
once the write succeeds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-18 19:28:49 +00:00
Claude debfa644ec #1927: a slider drag and unrelated section eyes don't misplace crops
Two more cases from the review of #1990: the end of a slider drag replayed
the crop Constrain Crop had fitted during the drag, so Auto Sync still
copied the active photo's fitted crop to the others; the end of an
interaction now starts again from the original crop when the drag didn't
edit the crop. And any section eye counted as a warp change, so turning
Light off could refit a hand-drawn crop: only the Geometry and Optics
eyes do now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-18 16:48:52 +00:00
Claude 23f00822eb #1927: Auto Sync fits each photo's own crop under Constrain Crop
The crop fit ran before the Auto Sync delta, so a Geometry edit carried
the active photo's fitted crop rect into the delta and onto every other
selected photo, replacing (and could enlarge) their own crops. The delta
is now taken from the edit as asked, and each target fits its own crop.
Review on #1990.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-18 12:37:56 +00:00
Claude 5902a07354 Windows: folder-drop tests name folders as the Folders tree does; offline test waits for its worker
tests_folder_drop built widget ids from OS paths (C:\...), but the Folders
tree names folders with '/' on every platform (libfolder:C:/Users/...), so
8 tests found no row on Windows. tests_offline asserted that the background
probe had run without waiting for the worker thread; it now waits up to 5 s.
Found by running the tests on windows-latest (gap 9). Test-only changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-16 08:25:46 +00:00
Claude 109e4dabd3 Windows: compare exported paths as paths in the same-folder export test
same_folder_as_original_exports_next_to_each_photo compared path strings.
The export joins the subfolder with '/', so on Windows it reports
C:\...\A/Exports/IMG_1.jpg (a valid path) while the test expected
C:\...\A\Exports/IMG_1.jpg. Found by running the tests on windows-latest
(gap 9). Test-only change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-16 07:25:39 +00:00
Claude 54c6c43b07 #1927: Constrain Crop tightens the stored crop
Constrain Crop only applied at render time, and the Crop tool shows the
uncropped view with the stored crop, so in the Crop panel (where the
checkbox is) ticking it or moving a Geometry slider changed nothing.
Session::set_develop now shrinks the stored crop about its centre until it
fits the warped photo when Constrain Crop is turned on, or when an edit
changes the warp (Geometry, Upright, lens corrections, section eyes) while
it is on. A crop edit itself is kept as drawn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-16 00:01:00 +00:00
Claude 37a3ab4177 #1507: web start-up treats only NotFoundError as a missing file
OPFS lookups turned any exception into "absent", and start-up only logged
other read errors, so a library with an unreadable file opened incomplete
and the next save could overwrite the stored copy. Only NotFoundError now
means absent; when a stored library file or the active-library pointer
can't be read, the library isn't opened, nothing is saved and the window
names the file. An unreadable thumbnail index no longer deletes every
stored thumbnail as unindexed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-15 23:08:54 +00:00
Claude abf29ea392 #1508: web backup refuses to start while changes are unsaved
The browser backup copies the stored library files, so while a save to
browser storage is failing it reported success but left out the queued
changes. It now refuses with the number of unsaved changes and why
(Session::unsaved), and is allowed again once they are written.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AbegtYaPuwqZ81pGfELsFK
2026-10-15 21:53:46 +00:00
Claude 6938be39e4 Engine tests: drop the drop() of a closure (clippy drop_non_drop)
Clippy 1.97 rejects `drop(write)` in the same-folder export test: the
closure has no Drop, so its borrow of `written` already ends at its last
use and the call did nothing. Removed, with a note on why the following
read of `written` compiles.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2NDVXA8jQQWeJb4YVTb6b
2026-10-15 19:17:57 +00:00
Claude b5dc500c54 Hasselblad 3FR / FFF: uncompressed RGB embedded previews
These files carry no JPEG: their preview is an uncompressed 8-bit RGB
IFD (1217 x 913 in the H4D-40 FFF, 218 x 218 in the CFV 3FR). The
largest such image is handed on by embedded_preview as a small baseline
TIFF, which lightcraft_codecs::decode reads, so 3FR / FFF show a preview
in the grid and loupe before they are developed. No Orientation tag is
written: the raw file's applies, as for JPEG previews without one. The
FFF's 16-bit copy (with a TransferFunction of unknown meaning) is not
used.

decode_raw_preview applied a container-declared colour space by forcing
the JPEG decoder on any owned preview; it now checks for JPEG bytes, so
a wrapped TIFF (or a JPEG XL preview) goes to its own decoder.

Checked on the CC0 H4D-40 FFF and CFV 3FR through
embedded_preview_srgb: right colours, the 3FR upright through its
Rotate90. Tests cover the wrap, the choice among RGB images, a short
strip and truncated files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2NDVXA8jQQWeJb4YVTb6b
2026-10-15 18:58:05 +00:00
Claude 0f67225e83 Hasselblad FFF: colour matrix from the embedded 3FR header
An FFF (a 3FR converted on the desktop) has no colour matrix of its own:
the camera's stays in the original 3FR header the FFF carries as a
complete TIFF in private IFD0 tag 0xC51B. The new vendor::hasselblad
reader decodes 3FR / FFF through dng::decode_as and, when the file has
no matrix, takes the matrices from that header, so an FFF no longer
develops with the "camera RGB = sRGB" fallback (H4D-40 as-shot white
moves from xy 0.279, 0.356 to 0.325, 0.336).

RGGB checked against the camera preview on the CC0 H4D-40 FFF and CFV
3FR (raw.pixls.us 931 and 709). Synthetic tests cover the embedded
matrix, an own matrix winning, a missing or damaged header, and
truncated files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J2NDVXA8jQQWeJb4YVTb6b
2026-10-15 18:19:15 +00:00
Claude 05352e18dd Merge storytold/lightcraft main into LR-MERGE-HDR (white balance)
Brings in batch 35 / v0.8.0. Code merged cleanly; conflicts only in docs: the LR-MERGE-HDR row keeps main's
lens-correction text plus this branch's white-balance item, and this branch's What's New entry moves to the
2026-10-14 section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-14 16:22:53 +00:00
Claude ac17c580f5 Merge storytold/lightcraft main into LR-MERGE-HDR (frame order, clipped pixels)
Brings in #1423 (HDR merges keep the lens corrections), which landed in batch 35 / v0.8.0. hdr.rs merged cleanly:
the result's lens corrections come from the reference frame after the brightness ordering. Conflicts only in docs:
the LR-MERGE-HDR row keeps main's lens-correction text plus this branch's two items, and this branch's What's New
entry moves to the 2026-10-14 section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-14 16:22:37 +00:00
Claude c472f52c84 Lightroom import: raise catalog/WAL size limit from 1 GiB to 4 GiB
Reserve the exact file size before reading so a large catalog does not
need twice its size in memory while the buffer grows.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013TGi6EFawAr2RPfqXsoCrQ
2026-10-14 14:51:26 +00:00
Claude 3ae306ecb3 LR-IMP-FORMATS: decode EOS R6 Mark II C-RAW with adaptive QP up to 175
EOS R6 Mark II C-RAW QP maps reach 172 and 175; crx.rs accepted 131-168,
so those files opened as their preview ("Canon CRX adaptive QP value 172").
Adaptive QP now goes to 175 (quantization value 51, step 228), the highest
seen in any file; uniform subband values still stop at 44.

Checked black-box against the camera JPEGs on private files: 144 R6 II /
R7 C-RAW files decode to identical hashes where they decoded before, the 3
failing ones now decode (green follows the JPEG at r 0.98), fine detail per
QP shows no jump at 172/175, 100 % crops are clean, and 1,492 files sampled
from a 35,796-file library decode with max QP 175. No third-party decoder
source consulted. Bumps RENDER_CACHE_VERSION to 63; cr3.md and What's New.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSGFEf87ba1zKJZb9uzddK
2026-10-14 08:41:52 +00:00
Claude 951d52788a LR-MERGE-HDR: pixels next to clipped ones don't tint HDR merges
Measured against the darkest frame on real ARW brackets, each frame is linear to 1 % up to the clip far from
clipped pixels, but within 2 px of them the +2 EV frame's green reads 3–5 % low: demosaicing interpolates it from
clipped photosites. That frame carries the most weight (k = 4) and those pixels were unclipped themselves, so they
kept it, and bright windows took a magenta tinge.

A frame's weight now goes by its brightest channel within 1 px (3 × 3; wider margins changed nothing more). On two
real interior brackets (ILCE-7M3, 0 / −2 / +2 EV), bright pixels whose green against red and blue is over 10 % below
the darkest frame's, in camera RGB: dining room 0.32 % → 0.08 %, kitchen 2.86 % → 0.28 %. Rendered at −3 EV with
main's colour tags (#1123), window pixels with G < 0.85·min(R, B) go 50 → 3 and 16 → 10 (the darkest frame alone:
2 and 205); most of the visible magenta those brackets showed before came from the missing colour tags. Test: a
bracket whose +2 EV frame has 5 % less green next to its clipped pixels merges without the deficit (fails before:
−1.96 %).

Docs: docs/merge.md, the LR-MERGE-HDR row, docs/whats-new.md (also for the frame-order fix).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 09:51:11 +00:00
Claude 5cb57ef4ea LR-PROF-CAMERACOLOR: Canon EOS R7 / R6 Mark II calibrate measurements
Held-out and library-wide calibrate runs on real CR3s (calibrate's CR3 /
CR2 input is #1073): profiles change little (R7 2.52 -> 2.57, R6 Mark II
6.12 -> 6.09 mean dE), so none is bundled; notes the CRX adaptive QP
172/175 files that stay preview-only. The catalog test pins that an EOS
R6 Mark II (Exif "Canon EOS R6m2") edits in Kelvin through its measured
matrices and an EOS R7 stays relative.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CzWyUn77ZWLe3q3qMiQbVt
2026-10-13 09:10:47 +00:00
Claude 64f354fca3 LR-MERGE-HDR: merged DNGs declare the white balance their source shows (follow-up to #1123)
#1123 gives HDR and panorama merges of raws without colour matrices the colour they open with, but writes
ColorMatrix1 from the forward matrix, so the as-shot white the DNG declares lands wherever the fitted look and the
generic camera model take it. On real ILCE-7M3 brackets the HDRs opened at As Shot 6113–7307 K / +115 (Duv +0.038)
where the ARWs show 3932–5268 K / +7, and any white-balance edit turned them green (CIEDE2000 11–13 against the ARW
at the same Temp/Tint). The render at As Shot was right (0.4–0.8).

The colour matrices now declare the white balance the source shows, decided by files::WbScaleOf (new dng_white):
the camera's measured matrices when they give the source's scale (lightcraft_raw::spectral; the DNG then reads every
white as the source does), else a matrix under which the as-shot neutral is the white the scale shows (Sony's
presets' reading, 6500 K / 0 on the relative scale, the file's own white otherwise). Forward matrix and neutral are
unchanged, so is the render at As Shot.

Measured on the same brackets with this change on a fork build: As Shot 4813 / 5268 / 3932 K, +8 / +8 / +7 as the
ARWs (declared white Duv +0.003); same Temp/Tint within CIEDE2000 0.8–1.7 of the ARW for most changes, about 5 for
the largest (5268 → 3200 K, 3932 → 6500 K: the ARW adapts its look with Bradford, the DNG rebalances in camera space).

Tests: a merged DNG shows its source's As Shot on all four scales (measured matrices, presets, relative, own); with a
look that tints white the DNG declares the shown white, gives the measured model's multipliers at other whites and
renders at As Shot as the source does. Both fail on main (ILCE-7M3 case: (7342, 115) for (5268, 8)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 06:37:11 +00:00
Claude 146cb7b975 LR-MERGE-HDR: the merge no longer depends on the order the frames come in
The same bracket merged in another order gave a different result: on real ARW brackets, the app's selection
order and the CLI's file order differed on 0.6 % of the pixels (up to 102 levels), while the same order gave
byte-identical files. Alignment seeds were the frames' input positions, and sums, deghost masks and brightness
ties followed them too.

merge_hdr now puts the frames in brightness order first (ties by median, then a content fingerprint, never by
position), runs everything in that order, and returns the per-frame results (EV, alignment, reference index)
in the caller's order. Test: every permutation of a bracket gives the same radiance and deghost overlay bit for
bit, and the same per-frame results (fails before: "the radiance differs").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 05:57:13 +00:00
Claude 8bb084074c Merge storytold/lightcraft main into LR-MERGE-HDR (lens corrections)
Conflicts: crates/engine/src/tests_merge.rs (#1123's test landed where this branch's is; both kept),
docs/parity-checklist.md (the LR-MERGE-HDR row: both notes) and docs/whats-new.md (both entries).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 05:57:08 +00:00
Claude 4c1dfc5b0f LR-MERGE-HDR: keep the reference frame's lens corrections in HDR merges
Merged HDR DNGs lost the camera's embedded lens correction: load_frame strips the lens opcodes from each
source (frames are merged uncorrected) and write_linear_dng wrote no OpcodeList3, so Optics ▸ Enable Lens
Corrections did nothing on the result (Sony ILCE-7M3/7RM4A, Panasonic/Leica, DNGs with their own opcodes).

Each raw frame now keeps the lens corrections it applies (the DNG 1.6 skip rule already applied),
re-expressed for the default crop develop keeps by the new Opcode::cropped: the centre moves into the crop
and coefficients are rescaled for the crop's farthest corner. HdrResult carries the reference frame's and the
DNG writes them as its OpcodeList3. Frames turned before merging (mixed orientations) and panoramas carry none.

Tests: cropped corrections give the crop of the corrected whole (WarpRectilinear, WarpRectilinear2 with and
without reciprocal, FixVignetteRadial); an HDR merge of cropped, corrected brackets, upright and vertical, gives
the same profile correction as its reference photo (fails without the fix). Real brackets not measured yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015gRtdWF1E9358FfzhzYqCS
2026-10-13 01:05:26 +00:00
Claude 5343fd10ff LR-EXP-TYPE: the Export dialog is 615 pt wide with JPEG XL in the format row
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 14:49:19 +00:00
Claude 9e41805a12 M-edit-in: the many-photos test uses distinct files and edits before the second copy
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 14:31:29 +00:00
Claude 3b306259e5 M-edit-in: the copies toast is a format string (move it to the -formats catalogs)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 14:05:56 +00:00
Claude 76a2899383 Merge remote-tracking branch 'origin/main' into claude/integrate-batch-31 2026-10-11 14:04:21 +00:00
Claude ea51574172 Merge batch 30 fixes 2026-10-11 13:37:49 +00:00
Claude f01d3304e2 Batch 30: parity summary refreshed (cargo xtask parity --write)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 13:37:12 +00:00
Claude 45b174a781 Batch 30: one tracker row each for LR-PREF-DISPLAY / -PERFORMANCE / -PEOPLE (a rename-crossing merge doubled them)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 13:34:22 +00:00
Claude 4ebb934c56 Merge PR #677
On merge: the HDR histogram is applied in develop_reporting (#712 split develop), is skipped for
draft renders (a second render per drag tick), and HdrBins::bin clamps a hand-built split so it
can't underflow (test hdr_bins_with_any_split_stay_in_range).
2026-10-11 13:09:34 +00:00
Claude 9cf47c86fe Merge batch 30 fixes 2026-10-11 13:08:50 +00:00
Claude 7fe8f8dbd1 LR-BEHAV-UNDO: each rename-provenance fixture gets its own folder (#874's tests shared one and failed when run in parallel)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 13:08:37 +00:00
Claude 4ff1d9761d Batch 30: a selected slider keeps only its arrow keys, so shortcuts work after a slider click (#884); tests follow the merged dialog and panel state
#884 focuses a develop slider on click so the wheel and arrows adjust it, but a focused widget
owned the whole keyboard, so after touching a slider no shortcut fired (O for the mask overlay,
caught by mask_adjustments_hide_overlay_without_disabling_the_mask). Now a selected slider owns
the arrow keys only. The wheel test opens the Edit panel explicitly (the demo may start on it, and
panel.edit then toggles it shut), and the Export dialog snapshot is 546 px wide since #833's
nine watermark positions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:59:15 +00:00
Claude 9978dc739d Merge PR #643
# Conflicts:
#	crates/engine/src/export.rs
#	crates/engine/src/tests_export.rs
#	crates/mcp/src/headless.rs
#	crates/mcp/src/tools.rs
#	crates/ui-egui/locales/de-formats.json
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es-formats.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr-formats.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja-formats.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br-formats.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru-formats.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk-formats.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans-formats.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant-formats.json
#	crates/ui-egui/locales/zh-hant.json
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-11 12:43:20 +00:00
Claude 0d5f8b1ea4 Merge PR #879
# Conflicts:
#	docs/whats-new.md
2026-10-11 12:42:19 +00:00
Claude 705c59cb42 Docs: PSD export is no longer an open file-write gap (#953); the CLI help lists .psd
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:42:10 +00:00
Claude 6bc25940b8 Merge PR #780 (via claude/integrate-780) 2026-10-11 12:41:50 +00:00
Claude bd3b058a8f M-export: bump RENDER_CACHE_VERSION for the XYB JPEG XL decode fix
PR #780 changes how lossy (XYB) wide-gamut JPEG XL files decode (crates/codecs/src/jxl.rs), so cached renders of those photos are stale.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:41:12 +00:00
Claude f4a205b4ff M-export: pin jixel to =0.3.4
Young crate with a fast release cadence; take updates deliberately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:41:00 +00:00
Claude 255b23816d LR-EXP-PSD: Edit In makes a copy of every selected photo and opens them all (#920)
photo.editExternal takes the selection (or ids, at most 50): each photo gets its own -Edit copy
stacked on its original, the copies are selected and returned in copies (path / id / original
still name the first). Photo ▸ Edit In opens each copy in the editor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:40:58 +00:00
Claude 4a0d04b994 Merge PR #780
JPEG XL export via the pure-Rust jixel crate (robmdunn; fixes #247).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:40:55 +00:00
Claude 4ec3494733 Merge PR #434
On merge: Lightroom's default profiles (Adobe Standard, Adobe Color), named by nearly every sidecar,
give no camera-profile warning; other profiles still do (test default_lightroom_profiles_are_not_reported).
The import help string keeps main's onDeleted wording and gains warnings.
2026-10-11 12:38:16 +00:00
Claude e4a248c91f Merge PR #755
On merge: the quick preview path orients like the whole-file path (preview_orientation with the
raw's header prefix, so a portrait raw whose embedded JPEG carries no orientation is not sideways),
and its doc links point at preview_window.
2026-10-11 12:37:14 +00:00
Claude c54328b2d3 Merge PR #725
On merge: translations overlaid on main's zh-hans.json, so the keys main added since (docking panels and
others) stay.
2026-10-11 12:36:44 +00:00
Claude eae1eb5ba2 Merge PR #822
On merge: translations overlaid on main's ru.json, so the keys main added since (docking panels and
others) stay.
2026-10-11 12:36:44 +00:00
Claude 870eaa74e6 KEY-SLIDER-WHEEL: the wheel-nudge test reads exposure as a number (follow-up to #884)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:34:32 +00:00
Claude fce79feadb LR-IMP-FORMATS: the R5 Mark II QP-map test is a test again (its #[test] was lost merging #915 next to #829)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:33:43 +00:00
Claude 44f86dc855 LRC-LIB-FOLDERS: drop an unused import (#947 follow-up)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:33:07 +00:00
Claude 47b5e0ae1b Batch 30: cargo fmt over the merged PRs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:32:03 +00:00
Claude 8df1ad0392 Merge main (batch 26 landed) 2026-10-11 12:31:18 +00:00
Claude 37b26c56a3 Merge batch 29b (#946, #947, #953, #950)
# Conflicts:
#	Cargo.toml
#	crates/engine/src/rename.rs
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/icons.rs
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/menubar.rs
#	crates/ui-egui/src/menus.rs
#	crates/ui-egui/src/panels/left.rs
#	docs/whats-new.md
2026-10-11 12:08:44 +00:00
Claude d761e1b231 LR-PREF-INTERFACE: sort the test module list after merging #950 (rustfmt)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:07:17 +00:00
Claude 155ad70c6e LR-PREF-INTERFACE: French and Ukrainian appearance strings (modes, themes)
PR #950 gave fr and uk only the three favourites strings; add the thirteen
Appearance Mode / theme strings the other locales got, translated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:06:54 +00:00
Claude 10ebeccdc8 Merge PR #950
# Conflicts:
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/lib.rs
#	crates/ui-egui/src/panels/dialogs.rs
#	crates/ui-egui/src/state.rs
#	docs/parity-checklist.md
2026-10-11 12:06:31 +00:00
Claude 2e5a9f92ca LR-EXP-PSD: settings path fields use TextField; Windows default editor via Explorer; PackBits encoder without indexing
- Settings ▸ General ▸ External Editing: the PhotoCraft location and Other editor
  fields move from egui::TextEdit to TextField (edit menu, Esc restores).
- Edit In with the system default on Windows starts explorer.exe with the file
  as one argument instead of cmd /C start, which read & ^ % | in file names as
  shell syntax.
- psd::packbits walks the row with first()/get()/split_at_checked instead of
  direct indexing and slicing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:05:13 +00:00
Claude acdfa08f00 Merge branch 'claude/fix-922-denoise-toggle'
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:04:31 +00:00
Claude b89fb8bbab Merge branch 'claude/fix-942-cube-import-messages'
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:04:31 +00:00
Claude e6af53d46c LR-EDIT-DETAIL-DENOISE: a remote denoise tile with values that aren't finite fails, and runs on this computer instead (follow-up to #813)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:04:23 +00:00
Claude d1e20f0292 LR-BEHAV-LOCALIZE: the Latin-only test face has a neutral name (follow-up to #750)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:04:23 +00:00
Claude b04c2c831c LR-CLOUD-SMARTPREVIEW: the shard folder name is taken with get(), not a slice (follow-up to #834)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:04:23 +00:00
Claude e1016acc0f Merge PR #953
# Conflicts:
#	crates/codecs/src/lib.rs
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-11 12:03:58 +00:00
Claude 8c4898ec04 Merge PR #645
# Conflicts:
#	crates/engine/src/media.rs
#	crates/pipeline/src/finish.rs
#	crates/pipeline/src/local.rs
2026-10-11 12:03:53 +00:00
Claude 59011d114f Merge PR #617
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:03:31 +00:00
Claude f7ffa1433c Issue #947: compare a cross-volume move's copy in 1 MiB chunks; Move to Folder… uses the shared folder picker
move_across_volumes read both whole files into memory to compare them; it now
compares lengths first, then streams 1 MiB chunks. The grid's Move to Folder…
asks through pick::ask (background dialog where the host has one) like the
other folder pickers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:03:29 +00:00
Claude 33686e6951 Merge PR #734
# Conflicts:
#	ROADMAP.md
#	crates/engine/src/media.rs
#	crates/raw/tests/corpus.rs
#	docs/parity-checklist.md
2026-10-11 12:03:15 +00:00
Claude 45a6a42ebf Merge PR #947
# Conflicts:
#	crates/ui-egui/locales/de-formats.json
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es-formats.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr-formats.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja-formats.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br-formats.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru-formats.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk-formats.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans-formats.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant-formats.json
#	crates/ui-egui/locales/zh-hant.json
2026-10-11 12:02:51 +00:00
Claude a0e422ce4a Merge PR #752
# Conflicts:
#	crates/engine/src/cmd/develop.rs
#	crates/engine/src/files.rs
#	docs/mcp.md
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-11 12:02:46 +00:00
Claude 56a62f6d8b LRC-LIB-CATALOG-SWITCH: a failed library switch keeps the current library open; library names valid on Windows
Check the target (Lightroom catalog, file, unreadable folder, locked by another
program) with Session::check_library before closing the open library, and if
opening still fails, reopen the previous one (both errors reported if that fails
too). New Library names reject Windows-reserved characters and trailing dots.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:02:43 +00:00
Claude 6b22c5ca25 Merge PR #789
# Conflicts:
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/control.rs
#	crates/ui-egui/src/panels/left.rs
#	docs/parity-checklist.md
2026-10-11 12:02:10 +00:00
Claude c53b61732d Merge PR #738
On merge: the XWayland default goes in front of the catch_unwind-wrapped launch (#951), and the
README's Linux section names the LIGHTCRAFT_WAYLAND=1 opt-out.
2026-10-11 12:01:41 +00:00
Claude 76fc27a7bc Merge PR #791
# Conflicts:
#	Cargo.lock
#	apps/lightcraft/src/main.rs
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-11 12:01:19 +00:00
Claude c9d131bfbc Merge PR #946
# Conflicts:
#	crates/engine/src/library.rs
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	crates/ui-egui/src/menus.rs
#	crates/ui-egui/src/panels/settings.rs
#	crates/ui-egui/src/state.rs
#	docs/parity-checklist.md
#	docs/whats-new.md
2026-10-11 12:01:18 +00:00
Claude 8339028a80 Merge PR #794
# Conflicts:
#	crates/engine/src/media.rs
#	crates/pipeline/src/optics.rs
#	docs/parity-checklist.md
2026-10-11 12:00:57 +00:00
Claude 6308ca1088 Merge PR #547
# Conflicts:
#	crates/ui-egui/src/panels/detail.rs
2026-10-11 12:00:46 +00:00
Claude 11f41cbe97 Merge PR #813 2026-10-11 12:00:21 +00:00
Claude 7ff683f037 Merge PR #750 2026-10-11 12:00:20 +00:00
Claude 477c078b35 Merge PR #834 2026-10-11 12:00:20 +00:00
Claude 5ba413baf2 Merge PR #625
# Conflicts:
#	crates/engine/src/media.rs
#	docs/parity-checklist.md
2026-10-11 12:00:20 +00:00
Claude 421000916e Merge PR #667
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:00:19 +00:00
Claude 860b0d69c6 Merge PR #749 2026-10-11 12:00:19 +00:00
Claude 111bb42aa3 Merge PR #825
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:00:17 +00:00
Claude 8380415222 Merge PR #874
# Conflicts:
#	docs/parity-checklist.md
2026-10-11 12:00:17 +00:00
Claude d7f868fc6d LR-EDIT-DETAIL-DENOISE: dismissing the model setup turns AI Denoise back off (#922)
Turning on AI Denoise without a model opens Settings > AI Denoise and
keeps a pending request, so the switch showed checked and Settings
offered "Cancel pending action". Closing the setup with no model
download or installation running now drops that request: the switch
goes back off and nothing claims to be pending. A download started
before closing still turns AI Denoise on when it finishes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:00:15 +00:00
Claude da008ce53c LR-IMP-PROFILES: .cube-only imports report their profiles and failures (#942)
File > Import Profiles & Presets... now builds one toast for both halves
(a second toast replaced the first, so a .cube-only import said "No new
presets"). The preset half is skipped when no preset files were picked,
and profile.import's failures are shown with their reason. profile.import
also reports .cube files and zips it couldn't read instead of dropping
them silently. The command's result carries the profile half under
"profiles".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 12:00:08 +00:00
Claude 5df7f733d3 Batch 29: tracker rows for content-aware Fill (#926), printer ICC soft proofing (#928) and the lensfun-format lens database (#930)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKWB9TCnvzJHV6xMLAj2J4
2026-10-11 11:58:25 +00:00
Claude 7ecb0b0191 Merge PR #915
# Conflicts:
#	crates/engine/src/media.rs
#	crates/raw/src/vendor/crx.rs
#	crates/ui-egui/locales/de.json
#	docs/gaps.md
#	docs/parity-checklist.md
#	docs/raw-parity.md
#	docs/whats-new.md
2026-10-11 11:58:15 +00:00
Claude 17dfa9709e Merge PR #926
# Conflicts:
#	Cargo.lock
#	Cargo.toml
#	crates/ui-egui/locales/de.json
#	crates/ui-egui/locales/es.json
#	crates/ui-egui/locales/fr.json
#	crates/ui-egui/locales/ja.json
#	crates/ui-egui/locales/pt-br.json
#	crates/ui-egui/locales/ru.json
#	crates/ui-egui/locales/uk.json
#	crates/ui-egui/locales/zh-hans.json
#	crates/ui-egui/locales/zh-hant.json
#	xtask/src/layers.rs
2026-10-11 11:57:45 +00:00