Commit Graph

3767 Commits

Author SHA1 Message Date
Brayan Oliveira
00dcfc3e8b feat: lazy-load MathJax on Reviewer (#5171)
## Linked issue (required)

* Closes #5172

## Summary / motivation (required)

Loading MathJax makes the reviewer initialization slower, which is
relevant for people who don't use MathJax and slower devices (such as
phones)

## Steps to reproduce (required, use N/A if not applicable)

N/A

## How to test (required)

1. Opened a deck with a card with no MathJax
2. In developer tools' console,, check whether `MathJax` is not defined
3. Answer some cards until a card with MathJax appears -> Check if it is
correctly loaded

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->

## Before / after behavior (optional)

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-07-24 15:23:45 +08:00
Timothy (Tim) Lee
e8d368ca23 fix: image occlusion masks lost when adding notes (#5155)
## Linked issue (required)

Closes #4754

## Summary / motivation (required)

Image occlusion masks could silently go missing from a note at add time.
Two separate problems caused this, both timing dependent, which is why
the bug was rare and hard to reproduce.

**Problem 1: the editor reset races the add (desktop).** Clicking Add on
an image occlusion note saved the note, queued the actual add, and reset
the mask editor all at once. The reset clears the canvas, and clearing
the canvas writes an empty value into the Occlusions field of the same
note object the add was about to read. Depending on which message
arrived first: the add worked normally (the common case), the note was
added with no masks and no warning, or the add was wrongly rejected with
"no occlusion created" while the masks were plainly visible. Fix: reset
the mask editor only after the add succeeds, matching the ordering the
non-legacy TS editor page already uses. This also means a rejected add
no longer wipes the masks you drew.

**Problem 2: one field's save cancels another's.** All fields committed
through a single shared save timer, and scheduling a save cancelled the
timer's previous pending action. Mask edits commit the Occlusions field
through that timer with a 600 ms debounce, so typing into Header or Back
Extra within 600 ms of the last mask edit threw away the pending
occlusions write. It was never retried, because later saves saw the
store already held the same value and skipped notifying. Every mask
drawn since the last committed write was then missing from the added
note. Fix: give each field its own timer. This also surfaced a second
bug in `ChangeTimer` itself: an action scheduled while
`fireImmediately()` was awaiting a previous action was silently
discarded when that await finished; fixed by taking the action before
running it and letting a concurrent flush wait for the run in flight.

## Steps to reproduce (required, use N/A if not applicable)

Problem 2 (reliably reproducible):
1. Add an Image Occlusion note, draw a mask, wait for it to auto-commit
(~1s).
2. Draw a second mask.
3. Immediately (within ~600 ms) switch to the fields view and type a
character into Header.
4. Wait a second, click Add.
5. Before this fix: the added note is missing the second mask. No
warning is shown.

Problem 1 (event-loop timing dependent, not reliably reproducible by
hand):
1. Add an Image Occlusion note, paste an image, draw one or more masks.
2. Click Add.
3. Before this fix: rarely, the note is added with an empty Occlusions
field and no warning, or Add is rejected with "no occlusion created"
while masks are visible on screen.

## How to test (required)

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

- `ts/tests/e2e/io-mask-save-race.spec.ts` reproduces problem 2 with
real mouse drawing and real keystrokes at the real 600 ms timing. Fails
on current `main` (payload contains 1 cloze instead of 2, consistently
across repeated runs) and passes with this change.
- `ts/lib/editable/change-timer.test.ts` covers the discarded-action
case in `ChangeTimer` and fails without the fix.
- Full Playwright e2e suite (`just test-e2e`) passes repeatedly across
fresh profiles.
- `just fmt`, `just lint`, and the vitest suite are clean.
- Problem 1 has no reliable automated test: the outcome depends on how
the Qt event loop interleaves two webChannel messages and a background
task. I verified the mechanism with a scripted headless Anki that drives
the real `AddCards` flow and delivers the racing write inside the
vulnerable window, and confirmed by inspection that after this change
the empty write can no longer be issued while an add is in flight.

## Before / after behavior (optional)

Before: masks could be silently dropped from a newly added note (problem
2, common), or the note could be added completely empty of masks /
spuriously rejected (problem 1, rare). After: neither race is possible;
a rejected add also no longer clears the masks you've drawn, so you can
fix the note and retry instead of redrawing.

## Risk / compatibility / migration (optional)

Low risk. Both fixes are ordering/scoping changes with no behavior
change outside the affected race windows. No schema, API, or migration
changes.

## UI evidence (required for visual changes; otherwise N/A)

N/A (no visual/UI changes).

## Scope

- [x] This PR is focused on one change (no unrelated edits).

This PR contains two fixes rather than one. I considered splitting them,
but both are root causes of the same reported bug (#4754) discovered
during the same investigation, they are already isolated into two
separate commits for review, and neither is a complete fix for the issue
on its own. Happy to split into two PRs if you'd prefer.

---------

Co-authored-by: llama <gh@siid.sh>
2026-07-21 12:32:50 +08:00
Luc Mcgrady
db98bb675a feat: Experimental options in preferences (#5057)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

<!-- Fixes #123 / Closes #123 / Refs #123 -->

closes #4871

## How to test (required)

Find "Labs" as a new option in the preferences

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->
I've implemented the "Labs" feature in a web-view as I presume we are
moving away from QT and
Currently these options have no function. Before we can add the
functionality we should try and come up with the pattern that we should
use to register new flags.

## UI evidence (required for visual changes; otherwise N/A)

<img width="746" height="736" alt="image"
src="https://github.com/user-attachments/assets/28c4fd28-a593-4599-b43e-c2c23881251e"
/>
<img width="746" height="736" alt="image"
src="https://github.com/user-attachments/assets/c1cd69f9-3d8d-4866-a784-030b4274b4e7"
/>

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-07-13 16:16:42 +03:00
Abdo
9863b2f142 fix: Work around race issue with activeWindow() in request handlers (#5136)
## Linked issue

Reported on
[Discord](https://discord.com/channels/368267295601983490/373169624797282304/1524169568862601287).

## Summary / motivation

We call `QApplication.activeWindow()` in several mediasrv request
handlers to get a parent for Qt dialogs or do asynchronous operations,
but it returns None on some systems, apparently due to race issues.

```
Anki 26.05 (5d51ca02) (ao)
Python 3.13.13 Qt 6.11.0 PyQt 6.11.0
Platform: macOS-26.5.1-arm64-arm-64bit-Mach-O

Traceback (most recent call last):
  File "/Users/criticalay/Documents/GitHub/anki/qt/aqt/taskman.py", line 152, in raise_exception
    raise exception
  File "/Users/criticalay/Documents/GitHub/anki/qt/aqt/taskman.py", line 148, in _on_closures_pending
    closure()
    ~~~~~~~^^
  File "/Users/criticalay/Documents/GitHub/anki/qt/aqt/mediasrv.py", line 808, in <lambda>
    aqt.mw.taskman.run_on_main(lambda: self.callback(self))
                                       ~~~~~~~~~~~~~^^^^^^
  File "/Users/criticalay/Documents/GitHub/anki/qt/aqt/mediasrv.py", line 828, in callback
    assert window is not None
           ^^^^^^^^^^^^^^^^^^
AssertionError

===Add-ons (active)===
(add-on provided name [Add-on folder, installed at, version, is config changed])
AnkiWebView Inspector ['31746032', 2023-06-28T00:56, 'None', '']

===IDs of active AnkiWeb add-ons===
31746032

===Add-ons (inactive)===
(add-on provided name [Add-on folder, installed at, version, is config changed])
```

## Steps to reproduce

I failed to reproduce it so far on macOS/Windows.
2026-07-13 11:30:37 +03:00
Timothy (Tim) Lee
3c9f2f7dff fix: clean up FindDuplicatesDialog's webview on close to prevent theme-change crash (#5143)
## Linked issue (required)
Fixes #5140

## Summary / motivation (required)
`FindDuplicatesDialog` never called `AnkiWebView.cleanup()` on close,
unlike
the other dialogs that embed a webview (`EmptyCardsDialog`,
`CardInfoDialog`,
`NewDeckStats`), which all do. Without it, the webview's
`on_theme_did_change`
stays registered in `gui_hooks.theme_did_change` after Qt destroys the
underlying C++ widget, so a theme change shortly after close crashes
with
`RuntimeError: wrapped C/C++ object of type FindDupesWebView has been
deleted`.

## Steps to reproduce
1. Open Find Duplicates (Notes menu → Find Duplicates).
2. Close the dialog.
3. Trigger a theme change (toggle system light/dark mode).
4. Anki crashes with the RuntimeError above.

## How to test
Reproduced the crash via the steps above. No automated test included -
this
change just applies the same `.cleanup()` call the three sibling dialogs
already make in their `finished`/`reject` handler. `./ninja check`
passes.

### Checklist (minimum)
- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed. (same pattern as
EmptyCardsDialog/CardInfoDialog/NewDeckStats - see above)

## Before / after behavior
Before: closing Find Duplicates then triggering a theme change could
crash
Anki. After: the dialog cleans up its webview like its sibling dialogs,
so
the same theme change no longer touches a deleted object.

## Risk / compatibility / migration
None - additive cleanup call, same pattern already used elsewhere in the
codebase.

## UI evidence
N/A - no visual change.

## Scope
- [x] This PR is focused on one change (no unrelated edits).
2026-07-13 00:11:19 +08:00
Abdo
77d61d7c38 chore: Update Briefcase (#5138)
## Linked issue

Related to fixes submitted upstream in #4765

## Summary / motivation

Bump Briefcase and update the templates for some changes:
- The option to create a Windows desktop shortcut is shown in the page
where the installation path is set instead of its own page.
- The minimum Windows build number is set in pyproject.toml and enforced
both at build time and install time.
- The MSI installer shows required disk space.



## How to test

Run `./tools/ninja installer:package` on Windows and give the installer
a quick test.
2026-07-11 20:56:00 +03:00
Abdo
25e21d6619 fix: Do not modify collection if preferences haven't changed (#5135)
## Linked issue

Fixes #5128

## Summary / motivation

Avoid marking the collection as modified if the preferences screen is
closed without making changes to collection settings.

## Steps to reproduce (before)

1. Open the preferences screen and close it without making changes.
2. Notice _Edit > Undo Preferences_ is active.

## How to test (after)

1. Open the preferences screen and close it without making changes.
2. Notice _Edit > Undo_ is inactive.
2026-07-11 20:55:42 +03:00
Fernando Lins
a8ba664e99 fix(ci): fix flaky e2e editor tests caused by premature webServer readiness (#5116)
## Linked issue (required)

Fixes #5108

## Summary / motivation (required)

`/favicon.ico` responds as soon as mediasrv's HTTP thread starts, before
the profile's collection finishes loading, `setupMediaServer()` runs
synchronously in `AnkiQt.__init__`, while `setupProfile()` is deferred
via a `QTimer`. Playwright's `webServer.url` readiness check polled
`/favicon.ico`, so the first e2e test to run in a given CI run could
race the async profile load and time out waiting for `.note-editor`, an
intermittent false negative, not a real editor bug.

This adds `GET /_anki/readyz`, which only returns 200 once `aqt.mw.col`
is open (503 otherwise — Playwright's webServer keeps polling on
non-2xx/3xx responses), and points `playwright.config.ts`'s
`webServer.url` at it instead of `/favicon.ico`.

## Steps to reproduce (required, use N/A if not applicable)

1. Run `just test-e2e` repeatedly on a loaded machine (or add artificial
delay to profile loading).
2. Occasionally, the first test in `context-switching.spec.ts` times out
at `fixtures.ts:37` (`waitForSelector(".note-editor")`) because
Playwright started the test run before the collection had finished
opening.
3. See CI failure:
https://github.com/ankitects/anki/actions/runs/28748635969/job/85243844164

## How to test (required)

- Ran `just test-e2e` locally and confirmed the suite passes.
- Verified `/_anki/readyz` returns 503 immediately after mediasrv starts
and 200 once the profile/collection finishes loading, by curling it
during `qt/tests/launch_anki_for_e2e.py` startup.
- No new test was added — this is a fix to test *infrastructure* (the
readiness gate), not to editor behavior; existing e2e specs are the
regression coverage.

## Before / after behavior (optional)

Before: e2e run could fail intermittently on the first test with a
`.note-editor` timeout, unrelated to the change under test.
After: `webServer` only accepts traffic once the collection is open, so
no test races the profile-load window.

## Risk / compatibility / migration (optional)

Low risk. `/_anki/readyz` is a new, isolated, read-only route used only
by the e2e harness; no existing behavior changes.
2026-07-07 10:20:43 +03:00
Abdo
643187a050 Shift editor control to TypeScript (#4029)
Closes https://github.com/ankitects/anki/issues/3830

---------

Co-authored-by: Fernando Lins <fernandolins@users.noreply.github.com>
2026-07-03 21:56:43 +03:00
Abdo
f99cfb66cb ci: Increase mpv timeout in test (#5098)
Closes #5097
2026-07-03 14:54:35 +03:00
d
7060797747 fix: follow Anki's language preference in webview and native form controls (#4935)
## Linked issue (required)

Fixes #4823

## Summary / motivation

Webview form controls (e.g. `<input type="date">` picker) were rendered
in the operating system's language instead of the language selected in
Anki's preferences. The webview never receives Anki's chosen language,
so its locale fell back to the system default.

This change calls `QLocale.setDefault` passing Anki's resolved language
in `setupLangAndBackend()` (`qt/aqt/__init__.py`), right after the
language is applied, so locale aware controls follow the user's chosen
language, as suggested in issue body.

`setupLangAndBackend()` runs during Anki startup and is responsible for
setting some language-related Qt state, such as QTranslator, therefore
adding the QLocale default setting there is consistent with the existing
responsibilities of the function.

<img width="2070" height="1574" alt="image"
src="https://github.com/user-attachments/assets/40c4a50d-1d39-48ac-b62b-e5db335e69db"
/>

## Steps to reproduce

1. Set the operating system language to something other than current
Anki lang (my OS is in portuguese)
2. Launch Anki, (e.g. `./run -l en -p teste`, -l is the language
parameter)
3. Open a screen with a web date field (e.g. card type edit screen and
add `<input type="date">`).
4. The picker's date format render in the system language, not in Anki's
language.

## How to test

1. Launch Anki
2. Add > "Cards..." > Add a script like the one bellow to card type
template field
```html
<input type="date">
<pre id="loc"></pre>
<script>
  document.getElementById('loc').textContent =
    "navigator.language = " + navigator.language + "\n" +
    "Intl locale        = " + new Intl.DateTimeFormat().resolvedOptions().locale + "\n" +
    "toLocaleDateString = " + new Date().toLocaleDateString() + "\n" +
    "month name         = " + new Intl.DateTimeFormat(undefined,{month:'long'}).format(new Date());
  </script>
```
3. Check if side preview language matches Anki's language.
 
**You can also check QLocale language in debug console (ctrl+shift+;)**
```py
import platform, anki.lang
from aqt.qt import QLocale, QSysInfo
from anki.utils import version_with_build
print("Anki version  :", version_with_build())
print("OS            :", QSysInfo.prettyProductName(), platform.machine())
print("Anki lang     :", anki.lang.current_lang) 
print("OS language   :", QLocale.system().name())
print("QLocale def   :", QLocale().name()) 
print("QLocale is equal to anki lang?", QLocale().name() == QLocale(anki.lang.current_lang).name())
```

**Debug console script to check if all selectable languages in
pylib/anki/lang.py:22-80 resolve to a valid QLocale**
```py
import anki.lang
from aqt.qt import QLocale
# when the language is not valid, QLocale constructor falls back to QLocale.Language.C https://doc.qt.io/qt-6/qlocale.html
print("fallback=", QLocale("not a valid language").name())
bad = []
for name, code in anki.lang.langs:
    disk = anki.lang.lang_to_disk_lang(code)      
    qt_lang = disk.replace("-", "_")              
    loc = QLocale(qt_lang)
    if loc.language() == QLocale.Language.C:       # fallback
        bad.append((name, code, qt_lang))
    print(f"{code:<8} -> {qt_lang:<7} -> {loc.name():<8} {loc.language().name}")

n = len(anki.lang.langs)
print(f"\ntotal={n}  ok={n - len(bad)}  fell_back_to_C={len(bad)}")
print("FAILURES:", bad if bad else "none — all selectable langs resolve to a valid QLocale")
```
<img width="986" height="667" alt="image"
src="https://github.com/user-attachments/assets/83a3bfee-1024-406e-a395-cdba30c61100"
/>
<img width="726" height="664" alt="image"
src="https://github.com/user-attachments/assets/06ea79fe-a4e6-44e1-96b3-2baff8be1f96"
/>


### Checklist

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior change

This is a trivial change (3 lines) in the Qt layer, and I chose not to
add a test for two reasons:

- Consistency: other Qt layer related stuff in setupLangAndBackend (such
as QTranslator) is not currently tested, and nothing in the existing
suite calls this function directly.
- I could not find a place where a new test would be a natural fit. I
considered adding something to test_i18n.py, but it did not seem aligned
with the other tests

## Before (Anki language: Russian, system language: Brazilian
Portuguese)

<img width="1022" height="408" alt="image"
src="https://github.com/user-attachments/assets/62f0af94-c7aa-461f-9a06-f3e42924d459"
/>

## After (Anki language: Russian, system language: Brazilian Portuguese)

<img width="1027" height="368" alt="image"
src="https://github.com/user-attachments/assets/ac11c152-be16-431e-92f0-c7240a25ddda"
/>

## Risk / compatibility / migration (optional)
Low risk; The fix sets the app-wide default QLocale (via
QLocale.setDefault) once at startup, to the language Anki already
resolves. Language changes already require a restart (there's even a pop
up asking for it), so there is no stale-locale edge.

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-07-02 19:16:07 +03:00
Abdo
35de142312 fix: Skip MpvManager test on Linux (#5094)
Missed a Linux failure in
https://github.com/ankitects/anki/pull/5087#pullrequestreview-4617027286
2026-07-02 15:01:34 +03:00
Fernando Lins
b90c8ab120 test: strengthen audio playback coverage (#5087)
## Linked issue

Refs #5016

## Summary / motivation 

Adds follow-up test coverage for audio playback after #5066.

This strengthens the previous basic sound tests by covering additional
edge cases in `anki.sound` and by adding a real mpv playback smoke test.
The goal is to catch regressions where the mpv binary exists and
responds to `--version`, but fails to actually load/decode/play an audio
file in Anki's automated environment.

Coverage added:

- `SoundOrVideoTag.path()` with filenames containing directory
separators
- `hooks.media_file_filter` application in sound tag path resolution
- case-insensitive audio extension detection
- rejection of filenames without extensions
- `_packagedCmd()` preference for `anki_audio` only on macOS/Windows
- generated WAV playback through mpv in headless mode

## Steps to reproduce

1. Have a broken or incompatible mpv/`anki_audio` binary available.
2. Run the sound-related Python tests.
3. Without a playback smoke test, `mpv --version` may pass even if mpv
cannot load/play an audio file.

## How to test

Run:

```sh
just test-py
```

Both passed locally.

The mpv smoke test generates a minimal WAV file and runs mpv with
headless/null audio-video output, so it validates decoding/playback
without requiring audio hardware.

## Before / after behavior
Before: coverage verified that mpv existed and responded to `--version`,
but did not prove it could play/decode an audio file.

After: tests verify that mpv can load and play a generated WAV file in
an automated headless mode.

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-07-02 14:32:34 +03:00
roostwp07
52f9bfb6f9 test: add basic tests for sound module and mpv binary (closes #5016) (#5066)
Closes #5016

## Summary
- Adds `pylib/tests/test_sound.py` covering `anki/sound.py`:
`SoundOrVideoTag.path()`, `strip_av_refs()`, and `AV_REF_RE` matching
- Adds `qt/tests/test_sound.py` covering `aqt/sound.py`: audio file
extension detection and mpv binary smoke test (skipped on platforms
without a bundled binary)

## How to test
```
just test-py --coverage
```

Feel free to suggest additional tests if this isn't comprehensive
enough.
2026-07-01 13:13:52 -03:00
jcznk
b29d32c86d fix: Additional support for newlines in search (#5045)
## Linked issue (required)

Fixes #5046.

This is an expansion upon this PR:
https://github.com/ankitects/anki/pull/4336 (original issue:
https://github.com/ankitects/anki/issues/4215)

## Summary / motivation (required)

The previous PR only replaced `\n`. This did not work correctly on some
OS/environments (for example, on Windows 11). This PR expands the
replacement behavior to `\r\n` and `\r`.

## Steps to reproduce

On Windows 11:
Add this to an existing card's field: `THIS<BR>IS<BR>AN<BR>EXAMPLE`,
then copy paste the rendered HTML to the browser search bar and press
enter.

Before: no search results.

After: the search should behave as expected.

## How to test (required)

### Checklist (minimum)

- [ ] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [x] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
2026-06-29 15:09:12 +03:00
Niko Savola
36213cb1a9 fix: set minimum height for deck options (#5062)
## Linked issue (required)

Fixes #5061

## Summary / motivation (required)

This PR resolves a sizing issue with the options view on Hyprland and
possibly other Wayland-based tiling window managers.

### Changes:
**Minimum Height Constraint:** Adds `self.setMinimumHeight(500)` to
`DeckOptionsDialog._setup_ui()`. This ensures that even when the webview
is temporarily hidden on load
(`self.web.hide_while_preserving_layout()`), tiling window managers do
not collapse the dialog to an unusable height.

## Steps to reproduce (required, use N/A if not applicable)

See #5061

## How to test (required)

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed. (The existing dialog geometry helpers cover this, and
all Pytest/Aqt checks pass).

### Details

Tested manually on a Linux setup running Hyprland:
1. **Minimum Size:** When opening the deck options, the window respects
the minimum size constraints and opens at a readable size.
<img width="1395" height="1375" alt="image"
src="https://github.com/user-attachments/assets/963e9c46-ef7b-42f1-8b54-3a7f9a1473ce"
/>


## Before / after behavior (optional)

* **Before:** Window opened collapsed into a tiny horizontal box on
tiling compositors under Wayland, and user-resized geometries were lost
on Save/Cancel close events.
  
<img width="1403" height="626" alt="image"
src="https://github.com/user-attachments/assets/5cd02070-4563-4d73-9526-b86c8345649e"
/>

* **After:** Window is reliably opened at least 500px high, and user
size adjustments are correctly saved on all close operations.
<img width="1395" height="1375" alt="image"
src="https://github.com/user-attachments/assets/963e9c46-ef7b-42f1-8b54-3a7f9a1473ce"
/>


## Risk / compatibility / migration (optional)

Low risk. A minimum height of 500px easily fits on all standard modern
screens (including small laptops). The number may also be changed if
this seems too large.

## UI evidence (required for visual changes; otherwise N/A)

See screenshots above

## Scope

- [x] This PR is focused on one change (no unrelated edits).
2026-06-26 16:22:20 +03:00
Abdo
77a523ac27 chore: Disable MSI compression on debug build (#5063)
This disables MSI installer compression in debug mode for faster local
builds.
2026-06-25 21:38:36 +03:00
Luc Mcgrady
3650ad8396 fix: Dont close deck config screen when optimizing all presets (#4981)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

<!-- Fixes #123 / Closes #123 / Refs #123 -->

## Summary / motivation (required)
closes https://github.com/ankitects/anki/issues/4978

<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->

## Steps to reproduce (required, use N/A if not applicable)

<!-- Steps to reproduce: how to trigger the bug in the broken state (the
"before").
 - Mainly for bugfixes;
    - For bugs: numbered steps before the fix. For non-bugs: write N/A.
 - use N/A for features, refactors, docs, chore, etc.
-->

1. press "optimize all presets"
2. the window will save the current settings and cloze after it is done.

## How to test (required)

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->
after pressing optimize all presets, you should be prompted if you want
to save. After confirming you want to save, the window will remain open
when the process completes.

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->

## Before / after behavior (optional)

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

<!-- Screenshot or short video -->

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-06-25 16:42:39 +03:00
Abdo
7188bf3056 fix: Do not block install if registry points to a deleted old elevated install (#5054)
## Linked issue

Closes #5053

## Summary

The MSI installer checks for old elevated installs (pre-2.1.64) via the
Windows registry and asks the user to manually uninstall the old version
(as it requires elevation). There are however cases where the registry
value exists but the path is missing (e.g. if the user manually removes
the Anki folder without running uninstall.exe). This makes it so that
uninstall.exe is confirmed to exist in the folder.

Template change:
8d2756a03a

## How to reproduce (before)

1. Install Anki
[2.1.63](https://github.com/ankitects/anki/releases/tag/2.1.63)
2. Go to the installation folder and delete all files
3. Try to install 26.05 and confirm installation is blocked with the
message: "A previous Anki version needs to be uninstalled first. After
uninstallation completes, please run this installer again."


## How to test (after)

Repeat the same process but with an MSI installer built from this PR and
confirm you're not blocked from installation.
2026-06-23 09:58:01 +03:00
Luc Mcgrady
ff8e4f6e7a fix: move add_dynamic_styling_and_props_then_show to _on_load_finished (#4993)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

<!-- Fixes #123 / Closes #123 / Refs #123 -->
Fixes #4992

## Summary / motivation (required)

<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->
This prevents the webview refreshing from affecting the styling of the
page.

## Steps to reproduce (required, use N/A if not applicable)

<!-- Steps to reproduce: how to trigger the bug in the broken state (the
"before").
 - Mainly for bugfixes;
    - For bugs: numbered steps before the fix. For non-bugs: write N/A.
 - use N/A for features, refactors, docs, chore, etc.
-->

1. Load an anki webview
2. Refresh it (Using the ankiview web inspector addon or otherwise)
3. The body will have none of the classes on it and none of the other
styling will be applied

## How to test (required)

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->
Follow the reproduction steps and the classes should be the same as
before

### Checklist (minimum)

- [X] I ran `./ninja check` or an equivalent relevant check locally.
- [ ] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

<!-- Commands, manual steps, edge cases, and what you observed -->

## Before / after behavior (optional)

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

Before (After a refresh):
<img width="644" height="103" alt="image"
src="https://github.com/user-attachments/assets/888c1794-ed1a-447f-8b14-6cc631a1a1d3"
/>
After (After a refresh):
<img width="644" height="103" alt="image"
src="https://github.com/user-attachments/assets/49a7d6af-0292-4907-8faa-258d94190663"
/>

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

<!-- Screenshot or short video -->

## Scope

- [X] This PR is focused on one change (no unrelated edits).
2026-06-19 17:49:26 +03:00
Abdo
8f39ce82d5 chore: Sync with the 26.05 branch (#5041)
This syncs security fixes and translation/version updates from the 26.05
branch.

Related: #5039

---------

Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com>
Co-authored-by: Damien Elmes <gpg@ankiweb.net>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-19 16:36:51 +03:00
Abdo
3b705a1b9b fix: All-users MSI installation failing to detect existing installation (#5038)
## Linked issue

Closes #5037

## Summary

#4908 introduced a subtle issue for all-users MSI installations: it was
causing the installer to search for existing per-user installations
_only_, regardless of the user's choice. The fix is to set
`Schedule="afterInstallInitialize"` on the `MajorUpgrade` element so
that the search is done after the user's choice is resolved:
https://docs.firegiant.com/wix/schema/wxs/majorupgrade/

See template fix:
e028990d92

## Steps to reproduce (before)

1. Install
[26.05b2](https://github.com/ankitects/anki/releases/tag/26.05b2) and
choose the per-machine option in the Installation Scope page.
2. Install [26.05](https://github.com/ankitects/anki/releases/tag/26.05)
with the same scope.
3. Go to Windows' _Settings > Apps > Installed Apps_ and notice two Anki
entries.

## How to test (after)

Repeat the same process and confirm only one app entry.
2026-06-18 17:33:27 +03:00
Abdo
0d7b3fdd96 feat: Remove the uv launcher and old packaging code (#5019)
## Linked issue

Closes #4556
Closes #4557
Closes #4144
Closes #4151
Closes #4152
Closes #4153
Closes #4229
Closes #4356
Closes #4401
Closes #4403
Closes #4519
Closes #4523
Closes #4390
Closes #4414
Closes #4484



## Summary / motivation

After 4 months of exploring Briefcase for packaging, we're confident it
solves most problems with the uv launcher with less complexity and at a
lower maintenance cost, especially with the parallel work on the release
CI, which we already used to make 5 releases.

This also removes platform-specific packaging/signing code used to
produce macOS dmg files and Windows NSIS installers, which is now
largely handled by Briefcase and the release CI.
The custom install scripts for Linux are mostly preserved under
qt/installer/linux-template and used in the Briefcase build.

## How to test

- [ ] No build problems.
- [ ] The `tools/build-installer` scripts still work.
- [ ] No CI/release workflow issues.
- [ ] No user-visible changes in dev environment and Briefcase build.
2026-06-17 03:02:52 +03:00
Abdo
8ea145eb78 fix: Do not pass "--no-ytdl" to mpv on Intel Mac (#5015)
Fix audio broken on Intel Macs because our new mpv build doesn't
recognize the `--no-ytdl` option.
2026-06-15 21:10:03 +03:00
Abdo
76741b8b89 fix: Bump minimum required macOS version (#5010)
## Linked issue

Closes #5009

## Summary

Bump the minimum macOS version for the Briefcase build to 13.0 as
according to match Qt requirements.
2026-06-15 16:32:19 +03:00
Abdo
80cf76e4f9 fix: Do not block MSI install if registry points to a deleted older installation (#4998)
## Linked issue

Closes #4997

## Summary

The MSI installer checks the Windows registry for older NSIS-based
installations and tries to run their uninstall.exe. If the registry
value is found but the uninstall file is missing for any reason, the
installer used to fail.

See template change:
8c4932ee1b

## Steps to reproduce (before)

1. Install
[25.09](https://github.com/ankitects/anki/releases/tag/25.09).
2. Go to the installation folder and delete uninstall.exe
3. Try to install
[26.05b2](https://github.com/ankitects/anki/releases/tag/26.05b2) - you
should see an error message as reported in the linked report.

## How to test (after)

1. Install 25.09.
2. Go to the installation folder and delete uninstall.exe.
3. Build the installer: `./tools/ninja installer:package`.
4. Run the installer and confirm it succeeds.
2026-06-12 19:43:26 +03:00
Andrew Sanchez
fb0215a2c1 Prototype unified Mintlify docs site (#4882)
## Summary

- add a generated `docs-site/` Mintlify proof of concept for a unified
Anki docs site
- migrate the desktop manual, AnkiMobile docs, FAQs, add-on docs,
translation docs, release notes, legacy docs, and repo-local Sphinx/MyST
developer docs into the POC tree
- add a migration helper that preserves mdBook ordering, handles common
MDX incompatibilities, and regenerates the landing-page-inspired
Mintlify styling
- apply minimal styling based on the current Anki landing page: Anki
logo, Hanken Grotesk, blue primary color, subtle surfaces, and compact
nav treatment

## Validation

- `uv run --with ty ty check tools/mintlify_poc_migrate.py`
- `source ~/.nvm/nvm.sh && nvm use 22.15.0 && mint validate`
- previewed locally with `mint dev --port 3000` and checked the home
page/developer docs in browser

## Notes

This is intentionally a draft POC. It does not remove the existing
Sphinx or mdBook docs flows yet; it demonstrates what bringing the
sources into this repo and building from a single Mintlify root could
look like.

---------

Co-authored-by: Andrew Sanchez <andrewsanchez@users.noreply.github.com>
Co-authored-by: Luc Mcgrady <lucmcgrady@gmail.com>
Co-authored-by: Abdo <abdo@abdnh.net>
2026-06-12 16:27:33 +03:00
Abdo
08a0780417 fix: Preserve .tar.zst suffix of Linux release zip (#4961)
## Linked issue

Closes #4960


## Steps to reproduce (before)

The latest beta zips have only ".zst" as the suffix:
https://github.com/ankitects/anki/releases/tag/26.05b2

## How to test (after)

Check the artifacts of this GHA run and confirm the suffix is preserved:
https://github.com/ankitects/anki/actions/runs/27027272624
2026-06-08 18:09:44 +03:00
Abdo
76c0407ccc fix: Repaint UI after answer reveal (#4970)
## Linked issue

Closes #4969

## Summary

Add a [QWidget.update()](https://doc.qt.io/qt-6/qwidget.html#update)
call for the main webview after the answer is revealed and images are
loaded. This should reduce UI glitches, especially on cards with images.

## How to test

It's hard to test and reproduce this, because its frequency varies
between operating systems and graphics drivers.
I've seen improvements on my collection on Windows with the default
video driver (Direct3D) while doing my daily reviews today with this
change and I'll continue testing over the week.
2026-06-08 17:51:15 +03:00
Abdo
0073124811 chore: Bump anki-audio to 0.2.1 (#4947)
## Linked issue

#4918 #4949

## Summary

Bump anki-audio to 0.2.1 for the macOS hotfix.

## Steps to reproduce (before)

Audio playback/recording on macOS was broken (see issue).

## How to test (after)

Confirm audio is working now.
2026-06-03 19:03:36 +03:00
Abdo
27f8e8c263 fix: custom mpv.rb formula not being used (#4950)
## Linked issue

Closes #4949

## Summary

It turned out that our mpv.rb formula was never used because of the
`bottle do` statement, which was telling brew to use the upstream
version.

## Steps to reproduce (before)

1. Download and extract anki-audio==0.2.1:
https://pypi.org/project/anki-audio/0.2.1/
2. Run `./mpv --version` and confirm you see the error in the linked
issue.

## How to test (after)

1. Extract the signed artifacts built from this PR:
https://github.com/ankitects/anki/actions/runs/26877282940
2. Run `./mpv --version` and confirm no library errors. You might see
Gatekeeper warnings here as the binary is not notarized.
2026-06-03 18:00:56 +03:00
Abdo
398b51b2ed fix: wrong path of mpv libs in anki-audio wheel (#4919)
## Linked issue

Closes #4918 

## Summary

The anki-audio wheel build script was accidentally using `lib` instead
of `libs` for copied mpv libraries.

## Steps to reproduce (before)

Follow reproduction steps in the forum report and confirm you see the
issue.

## How to test (after)


- Build the wheel: `./qt/audio/build.sh`.
- Confirm `qt/audio/anki_audio/libs` is created.
- Extract `out/wheels/anki_audio-0.2.0-*.whl` and confirm it has the
correct structure.
- Run mpv in the extracted wheel: `./mpv` and confirm no library errors.
2026-06-02 12:30:45 +03:00
Abdo
1822a7c76c feat: Bump anki-audio package (#4913)
## Linked issue

Closes #4699

## Summary

This bumps `anki-audio` to the newly published 0.2.0 release.

## How to test

Confirm audio recording & playback is working by using the record button
in the editor.
2026-05-29 22:52:19 +03:00
Abdo
e5ea3fb40a feat: Allow MSI installer downgrades (#4909)
## Linked issue

Closes #4908

## Summary / motivation

Update the Wix template to allow users to install older versions of the
app, overwriting an existing newer version. See changes in the template:
f4b00da7d0

## Steps to reproduce (before)

1. Build the installer (`./tools/ninja installer:package`) with the
current main branch.
2. Install the MSI package at out/installer/dist.
3. Remove the out/installer folder, modify the .version file to decrease
the version (e.g. `25.09.1`) and build the installer again.
4. Try to install the package - you should get an error message.

## How to test (after)

Repeat the same process and confirm you can install the older version
with no errors.
2026-05-28 18:43:37 +03:00
Abdo
5e46fc4494 fix: Validate add-on's zip entries (#4901)
This validates add-on's zip paths to skip things such as UNC paths
2026-05-27 16:30:06 +03:00
Tim Arnold
9c72a8b828 feat: render sync server messages as rich text (#4560)
## Summary
- Pass `type="rich"` to `showText()` when displaying the sync server
message, enabling HTML rendering via `QTextBrowser.setHtml()`
- Plain-text messages continue to render identically — `setHtml()`
handles plain strings the same as `setPlainText()`
- Allows self-hosted sync servers to send formatted post-sync messages
(e.g. styled statistics, notices with links, tables)

## Context

The `/sync/meta` response includes a `msg` field that is displayed to
the user after sync. The display widget is already a `QTextBrowser`
(which supports Qt rich text/HTML), but `showText()` is called with the
default `type="text"`, routing through `setPlainText()`.

The `showText` helper already has full HTML support — it just needs
`type="rich"`:

```python
# qt/aqt/utils.py
text = QTextBrowser()
text.setOpenExternalLinks(True)
if type == "text":
    text.setPlainText(txt)    # current path
else:
    text.setHtml(txt)         # proposed path
```

**Security:** `QTextBrowser` does not execute JavaScript — only static
HTML/CSS. The sync server is explicitly configured and trusted by the
user.
2026-05-26 21:59:23 +03:00
Abdo
6f332d3a6b refactor: import some modules lazily (#4831)
## Linked issue

A slight improvement related to #4314

## Summary

Import some modules like `jsonschema`, `bs4` and `aqt.mediasrv` lazily
to speed up startup a bit.

## Steps to reproduce

Run Anki with `-X importtime` passed to Python:
```diff
diff --git a/run b/run
index 3051345b1..a907b2925 100755
--- a/run
+++ b/run
@@ -17,4 +17,4 @@ export ANKI_API_PORT=${ANKI_API_PORT-40000}
 export ANKI_API_HOST=${ANKI_API_HOST-127.0.0.1}

 ./ninja pylib qt
-${PYENV}/bin/python tools/run.py $*
+${PYENV}/bin/python -X importtime tools/run.py 2> importtime.txt $*
diff --git a/run.bat b/run.bat
index aecbf2491..69a721641 100755
--- a/run.bat
+++ b/run.bat
@@ -12,5 +12,5 @@ set ANKI_API_HOST=127.0.0.1
 @if not defined PYENV set PYENV=out\pyenv

 call tools\ninja pylib qt || exit /b 1
-%PYENV%\Scripts\python tools\run.py %* || exit /b 1
+%PYENV%\Scripts\python -X importtime tools\run.py %* 2> importtime.txt || exit /b 1
 popd
```

Then import `importtime.txt` to
[https://github.com/kmichel/python-importtime-graph](https://github.com/kmichel/python-importtime-graph)
to visualize timings. You should see `jsonschema` and `bs4` are loaded
at startup.

## How to test

Run profiling again and confirm `jsonschema` and `bs4` are not loaded at
startup. `aqt.mediasrv` will still be loaded at startup (because it's
immediately used in the main screen) but at a later stage.

---------

Co-authored-by: user1823 <92206575+user1823@users.noreply.github.com>
2026-05-26 18:51:31 +03:00
Abdo
88ef75f363 fix: Limit taskbar pinning fix to launcher builds (#4849)
This just limits the fix added in
469fd763c7
to the launcher so it has no effect on Briefcase builds. It looks
harmless, but just in case it does cause subtle issues.

---------

Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-05-26 13:22:18 +03:00
Abdo
6d42e37b72 fix: app unresponsive after clicking on Help button in modal dialogs (#4897)
## Linked issue

Closes #4896

## Summary

On macOS, clicking the Help button in error dialogs shown on top of
modal dialogs such as the Filtered deck screen was causing the app to
become unresponsive after the recent Qt upgrade. This was fixed by:

1. Setting a parent widget for `QMessageBox`.
2. Limiting the `.disconnect()` calls to the `clicked` signal.

## Steps to reproduce (before)

I was not able to reproduce the issue in a dev environment. I had to
build and run the Briefcase package. Follow the steps in the
[forums](https://forums.ankiweb.net/t/anki-26-05-beta-1/69707/43?u=abdo)
and confirm you can reproduce the issue.

## How to test (after)

Run the Briefcase package with the changes and follow reproduction steps
and confirm the issue is fixed.
2026-05-26 13:03:02 +03:00
Abdo
e05a7aace7 feat: Install required system dependencies in install.sh (#4895)
## Linked issue

Closes #4834

## Summary

This installs required Linux system dependencies in the install.sh
script for Debian-based distributions.

## Steps to reproduce (before)

No system dependencies are installed automatically. Users have to refer
to the
[manual](https://docs.ankiweb.net/platform/linux/installing.html#requirements)
to find a (partial) list of required packages.

## How to test (after)

Build the installer and run install.sh in any supported distro and
confirm dependencies are installed.
2026-05-26 13:00:37 +03:00
Abdo
a754a9c847 feat: Bundle Fcitx plugin (#4886)
## Linked issue

Closes #4873

## Summary

Build and package the fcitx5-qt6 plugin.

Latest release CI run:
https://github.com/ankitects/anki/actions/runs/26294296416


## How to test

1. Run installer build on Linux: `./ninja installer:build`.
2. Go to the Qt build directory
(`out/installer/build/anki/linux/zip/anki/app_packages/PyQt6/Qt6`) and
confirm you see the following files:
1.
`plugins/platforminputcontexts/libfcitx5platforminputcontextplugin.so`
    2. `plugins/dbusaddons/libFcitx5Qt6DBusAddons.so*`
2026-05-22 22:33:36 +03:00
Fernando Lins
a140d39329 chore(e2e): add Playwright end-to-end test infrastructure (#4864)
## Linked issue

Closes #4863

## Summary / motivation

Adds Playwright as the e2e test framework so contributors can write
browser-based tests against a real headless Anki instance. There was no
automated way to exercise mediasrv pages, SvelteKit routes, or the
`/_anki/` RPC surface from a browser, this PR establishes that harness.

Key pieces:
- `qt/tests/launch_anki_for_e2e.py` — spawns a throwaway Anki instance
(temp `ANKI_BASE`, `QT_QPA_PLATFORM=offscreen`). Pre-seeds `prefs21.db`
so Anki skips the language picker and profile chooser and goes straight
  to serving mediasrv.
- `playwright.config.ts` — points `webServer` at the launcher; polls
  `/favicon.ico` as the readiness probe.
- `ts/tests/e2e/` — `fixtures.ts` base and a sanity spec that verifies
  mediasrv is reachable and a SvelteKit page hydrates.
- `justfile` — `just test-e2e` recipe; Chromium installed to
  `out/playwright-browsers/`.
- CI — e2e step in `check-linux`; failed-run artifacts uploaded for 7
days.
- `docs/e2e-testing.md` — contributor guide covering setup, managed vs
  reuse-server modes, and writing new tests.

## How to test

Build the project once, then run the e2e suite in managed mode (no
separate `./run` needed — the launcher is started automatically):

```shell
just build
just test-e2e
```

## Before / after behavior (optional)
Before: no browser-level test harness existed.
After: `just test-e2e` drives a real headless Anki instance via
Playwright.

## Risk / compatibility / migration
No production code changed. New dev-only files and CI step only.
Chromium is installed to `out/playwright-browsers/` (gitignored) and
does not affect the regular build.

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-05-22 15:59:42 -03:00
Abdo
1394540217 test: Add tests for build_installer.py (#4868)
## Linked issue

Closes #4859

## Summary

Add tests for the build_installer.py script with 100% coverage.

## How to test

Run `just test-py --coverage --html` and browse coverage data.
2026-05-21 07:10:27 +03:00
Abdo
0519275682 fix: border color of browser cells in macOS (#4872)
## Linked issue

Closes #4870

## Summary

This fixes the border color of browser cells in macOS not following
Anki's theme after Qt 6.10+

## Steps to reproduce (before)

1. Set Anki's theme from _Anki (`python` in dev environment) >
Preferences > Theme_ to be the opposite of your system theme.
2. Open the Browse screen and notice the cell borders have the opposite
color of your Anki theme, matching the system theme.

## How to test (after)

Notice cell borders are more subtle now.

### Details

## UI evidence

Before:
<img width="628" height="346" alt="image"
src="https://github.com/user-attachments/assets/3b46c9fe-5eb8-4e03-ac93-5429d1768344"
/>

After:
<img width="628" height="346" alt="image"
src="https://github.com/user-attachments/assets/aeea6867-ebfe-46cc-8b4a-6f7440da16f4"
/>
2026-05-21 07:10:11 +03:00
Abdo
c9cd85dd97 feat: Distribute compiled sources in Briefcase bundle (#4856)
## Linked issue

#4855

## Summary

Compile .pyc files and package them in the Briefcase bundle instead of
the .py sources.

## How to test

You can run this Powershell script to do a basic benchmark of startup
performance on Windows (Requires
[py-spy](https://github.com/benfred/py-spy)):
```powershell
function Remove-Build {
    Remove-Item -LiteralPath "./out/installer" -Force -Recurse
}

function Start-Anki {
    param (
        [Parameter()]
        [string]
        $OutputPath
    )

    Start-Process -FilePath "py-spy" -ArgumentList "record --output $OutputPath -- ./out/installer/build/anki/windows/app/src/Anki.exe --safemode"
    Start-Sleep -Seconds 10
    Stop-Process -Name Anki
}

if ($null -eq (Get-Command "py-spy" -ErrorAction SilentlyContinue)) {
    Write-Error "py-spy not found. See https://github.com/benfred/py-spy"
    Exit 1
}

git checkout main
Remove-Build
./tools/ninja installer:build
Start-Anki -OutputPath "main.svg"

git checkout briefcase-compile-pyc
Remove-Build
./tools/ninja installer:build
Start-Anki -OutputPath "pyc.svg"
```

Output is written to `main.svg` and `pyc.svg`. Here's an example run
(using default 100 sampling rate):
<img width="950" height="559" alt="image"
src="https://github.com/user-attachments/assets/5da6a06a-3393-4f0e-80fe-ced735d50c2c"
/>
<img width="830" height="352" alt="image"
src="https://github.com/user-attachments/assets/ca9e5d8d-c3d4-4a0b-bd86-7aa2d6c5cee2"
/>
2026-05-18 17:47:03 +03:00
Abdo
03b9fc4814 ci: Fix Windows ARM packaging failing (#4857)
Fixes a CI failure introduced in #4822

See failing run:
https://github.com/ankitects/anki/actions/runs/26009152225/job/76447663427
2026-05-18 17:13:56 +03:00
Tim Gatzke
82eeda9d4f fix(export): preserve browser focus after note export (#4845)
## Linked issue (required)

Fixes #4833

## Summary / motivation (required)

Keep the Browser window focused after exporting selected notes.

The export dialog was opened from the Browser, but the background export
progress and completion tooltip were still parented to the main window.
That could leave the main screen focused after the export completed.
This change carries the dialog parent through the export options and
uses it for progress, errors, and the completion tooltip.

## Steps to reproduce (required, use N/A if not applicable)

1. Open the Browser.
2. Right-click a note and choose Notes > Export Notes.
3. Click Export, choose a save location, and save.
4. Observe that the main screen receives focus after export completion.

## How to test (required)

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

- Ran `./ninja check` successfully.
- Tested behavior on macOS, however I currently don't have a Windows or
Linux environment set up to test on right now as I'm on vacation. The
change is limited to dialog parenting, so I expect it to work the same
across platforms. Would appreciate testing on other platforms if
possible.

## Before / after behavior (optional)

Before: exporting selected notes from the Browser could focus the main
window after completion.

After: export progress and completion UI remain parented to the Browser,
so focus is returned to the Browser.

## Risk / compatibility / migration (optional)

Low risk. The change is limited to export UI parenting and falls back to
the main window when no dialog parent is available.

## UI evidence (required for visual changes; otherwise N/A)

N/A

## Scope

- [x] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-05-18 05:30:57 +03:00
chiragjagga
a2262809c4 fix: regex error fix (#4837)
<!--
Title (for the Pull Request title field at the top):
Use a short prefix so the change type is obvious. You do not need to
repeat it in the body below.

Examples:
- fix: — bugfix
- feat: — feature
- refactor: — internal change without user-facing feature
- docs: — documentation only
- chore: — tooling, CI, deps, build housekeeping
- test: — tests only
-->

## Linked issue (required)

Fixes #4835 

## Summary / motivation (required)

<!-- What this PR does and why. For larger changes, add enough context
for reviewers. -->

Fixes the issue #4835 with a minor change in InvalidRegex error.

## Steps to reproduce (required, use N/A if not applicable)

<!-- Steps to reproduce: how to trigger the bug in the broken state (the
"before").
 - Mainly for bugfixes;
    - For bugs: numbered steps before the fix. For non-bugs: write N/A.
 - use N/A for features, refactors, docs, chore, etc.
-->

1. Open the browser and do a find & replace.
2. Put b[ in “Find”.
3. Enable the regex option.
4. Confirm.

## How to test (required)

<!--- How to test: how you verified the change (checks, unit tests,
manual steps, edge cases — the "after" or general validation). --->
Reproduce the fix and verify the regex error is not within the `<pre>`
tag.

### Checklist (minimum)

- [x] I ran `./ninja check` or an equivalent relevant check locally.
- [x] I added or updated tests when the change is non-trivial or
behavior changed.

### Details

Regex error was return with `<pre>` tags which are removed now so that
the text in the error box is displayed correctly.

## Before / after behavior (optional)
<img width="372" height="211" alt="image"
src="https://github.com/user-attachments/assets/91f53745-301b-4679-b1a5-53fafd628de7"
/>

<!-- For bugfixes: behavior before vs after. For other types: N/A or a
short note. -->

## Risk / compatibility / migration (optional)

<!-- Breaking changes, rollout notes, or N/A for small / low-risk PRs
-->

## UI evidence (required for visual changes; otherwise N/A)

<img width="360" height="226" alt="image"
src="https://github.com/user-attachments/assets/3b7b3f23-9f35-423e-9b10-62834e0a0dd6"
/>

<!-- Screenshot or short video -->

## Scope

- [x] This PR is focused on one change (no unrelated edits).

---------

Co-authored-by: Abdo <abdo@abdnh.net>
2026-05-15 16:45:41 +03:00
dependabot[bot]
1f0fc05f93 chore(deps): bump the python-minor-patch group across 1 directory with 16 updates (#4829)
Bumps the python-minor-patch group with 16 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [pre-commit](https://github.com/pre-commit/pre-commit) | `4.5.1` |
`4.6.0` |
| [mypy](https://github.com/python/mypy) | `1.16.1` | `1.17.1` |
| [ruff](https://github.com/astral-sh/ruff) | `0.12.1` | `0.13.3` |
| [wheel](https://github.com/pypa/wheel) | `0.46.3` | `0.47.0` |
| [hatchling](https://github.com/pypa/hatch) | `1.27.0` | `1.29.0` |
| [types-requests](https://github.com/python/typeshed) |
`2.32.4.20250611` | `2.33.0.20260503` |
| [types-markdown](https://github.com/python/typeshed) |
`3.8.0.20250415` | `3.10.2.20260408` |
|
[sphinx-book-theme](https://github.com/executablebooks/sphinx-book-theme)
| `1.1.4` | `1.2.0` |
| [sphinx-autoapi](https://github.com/readthedocs/sphinx-autoapi) |
`3.6.0` | `3.8.0` |
|
[sphinxcontrib-mermaid](https://github.com/mgaitan/sphinxcontrib-mermaid)
| `2.0.1` | `2.0.2` |
| [markdown](https://github.com/Python-Markdown/markdown) | `3.8.2` |
`3.10.2` |
| [orjson](https://github.com/ijl/orjson) | `3.10.18` | `3.11.8` |
| [typing-extensions](https://github.com/python/typing_extensions) |
`4.14.0` | `4.15.0` |
| [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) |
`4.13.4` | `4.14.3` |
| [flask-cors](https://github.com/corydolphin/flask-cors) | `6.0.1` |
`6.0.2` |
| [jsonschema](https://github.com/python-jsonschema/jsonschema) |
`4.24.0` | `4.26.0` |


Updates `pre-commit` from 4.5.1 to 4.6.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pre-commit/pre-commit/releases">pre-commit's
releases</a>.</em></p>
<blockquote>
<h2>pre-commit v4.6.0</h2>
<h3>Features</h3>
<ul>
<li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to
be missing to enable easier usage with <code>git</code> 2.54+ git hooks.
<ul>
<li><a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a>
PR by <a
href="https://github.com/asottile"><code>@​asottile</code></a>.</li>
</ul>
</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is
required.
<ul>
<li><a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a>
PR by <a
href="https://github.com/asottile"><code>@​asottile</code></a>.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md">pre-commit's
changelog</a>.</em></p>
<blockquote>
<h1>4.6.0 - 2026-04-21</h1>
<h3>Features</h3>
<ul>
<li><code>pre-commit hook-impl</code>: allow <code>--hook-dir</code> to
be missing to enable easier
usage with <code>git</code> 2.54+ git hooks.
<ul>
<li><a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a>
PR by <a
href="https://github.com/asottile"><code>@​asottile</code></a>.</li>
</ul>
</li>
</ul>
<h3>Fixes</h3>
<ul>
<li><code>pre-commit hook-impl</code>: <code>--hook-type</code> is
required.
<ul>
<li><a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a>
PR by <a
href="https://github.com/asottile"><code>@​asottile</code></a>.</li>
</ul>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f35134b050"><code>f35134b</code></a>
v4.6.0</li>
<li><a
href="2a51ffcb81"><code>2a51ffc</code></a>
Merge pull request <a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3662">#3662</a>
from pre-commit/hook-impl-optional-hook-dir</li>
<li><a
href="d7dee322ab"><code>d7dee32</code></a>
make --hook-dir optional for hook-impl</li>
<li><a
href="965aeb1c68"><code>965aeb1</code></a>
Merge pull request <a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3661">#3661</a>
from pre-commit/hook-impl-required</li>
<li><a
href="2eacc064aa"><code>2eacc06</code></a>
--hook-type is required for hook-impl</li>
<li><a
href="f5678bf4ac"><code>f5678bf</code></a>
Merge pull request <a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3657">#3657</a>
from pre-commit/pre-commit-ci-update-config</li>
<li><a
href="054cc5bd6b"><code>054cc5b</code></a>
[pre-commit.ci] pre-commit autoupdate</li>
<li><a
href="5c0f3024d2"><code>5c0f302</code></a>
Merge pull request <a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3652">#3652</a>
from pre-commit/pre-commit-ci-update-config</li>
<li><a
href="a5d9114267"><code>a5d9114</code></a>
[pre-commit.ci] pre-commit autoupdate</li>
<li><a
href="129a1f5ca1"><code>129a1f5</code></a>
Merge pull request <a
href="https://redirect.github.com/pre-commit/pre-commit/issues/3641">#3641</a>
from pre-commit/mxr-patch-1</li>
<li>Additional commits viewable in <a
href="https://github.com/pre-commit/pre-commit/compare/v4.5.1...v4.6.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `mypy` from 1.16.1 to 1.17.1
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/python/mypy/blob/master/CHANGELOG.md">mypy's
changelog</a>.</em></p>
<blockquote>
<h3>Mypy 1.17.1</h3>
<ul>
<li>Retain <code>None</code> as constraints bottom if no bottoms were
provided (Stanislav Terliakov, PR <a
href="https://redirect.github.com/python/mypy/pull/19485">19485</a>)</li>
<li>Fix &quot;ignored exception in <code>hasattr</code>&quot; in dmypy
(Stanislav Terliakov, PR <a
href="https://redirect.github.com/python/mypy/pull/19428">19428</a>)</li>
<li>Prevent a crash when InitVar is redefined with a method in a
subclass (Stanislav Terliakov, PR <a
href="https://redirect.github.com/python/mypy/pull/19453">19453</a>)</li>
</ul>
<h3>Mypy 1.17</h3>
<ul>
<li>Optionally check that match is exhaustive (<code>--enable-error-code
exhaustive-match</code>) (Donal Burns, PR <a
href="https://redirect.github.com/python/mypy/pull/19144">19144</a>)</li>
<li>Further improvements to attribute resolution and protocol subtyping
(Ivan Levkivskyi)</li>
<li>Fixes to nondeterministic type checking (Shantanu)</li>
<li>Remove support for targeting Python 3.8 (Marc Mueller)</li>
<li>Initial support for Python 3.14 (Marc Mueller)</li>
<li>Stricter checking of <code>type: ignore</code> comments — must now
specify error code(s)</li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>Additional commits viewable in <a
href="https://github.com/python/mypy/compare/v1.16.1...v1.17.1">compare
view</a></li>
</ul>
</details>
<br />
Updates `ruff` from 0.12.1 to 0.13.3
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/ruff/releases">ruff's
releases</a>.</em></p>
<blockquote>
<h2>0.13.3</h2>
<p>Released on 2025-10-02.</p>
<h3>Preview features</h3>
<ul>
<li>Display diffs for <code>ruff format --check</code> and add support
for different output formats (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20443">#20443</a>)</li>
<li>[<code>pyflakes</code>] Handle some common submodule import
situations for <code>unused-import</code> (<code>F401</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20200">#20200</a>)</li>
<li>[<code>ruff</code>] Do not flag <code>%r</code> +
<code>repr()</code> combinations (<code>RUF065</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20600">#20600</a>)</li>
</ul>
<h3>Bug fixes</h3>
<ul>
<li>[<code>cli</code>] Add conflict between <code>--add-noqa</code> and
<code>--diff</code> options (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20642">#20642</a>)</li>
<li>[<code>pylint</code>] Exempt required imports from
<code>PLR0402</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20381">#20381</a>)</li>
<li>[<code>pylint</code>] Fix missing <code>max-nested-blocks</code> in
settings display (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20574">#20574</a>)</li>
<li>[<code>pyupgrade</code>] Prevent infinite loop with
<code>I002</code> and <code>UP026</code> (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20634">#20634</a>)</li>
</ul>
<h3>Rule changes</h3>
<ul>
<li>[<code>flake8-simplify</code>] Improve help message clarity
(<code>SIM105</code>) (<a
href="https://redirect.github.com/astral-sh/ruff/pull/20548">#20548</a>)</li>
</ul>
<h3>Contributors</h3>
<ul>
<li><a href="https://github.com/TaKO8Ki"><code>@​TaKO8Ki</code></a></li>
<li><a href="https://github.com/ntBre"><code>@​ntBre</code></a></li>
<li><a href="https://github.com/dylwil3"><code>@​dylwil3</code></a></li>
<li><a
href="https://github.com/MichaReiser"><code>@​MichaReiser</code></a></li>
<li><a
href="https://github.com/danparizher"><code>@​danparizher</code></a></li>
</ul>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/ruff/compare/0.12.1...0.13.3">compare
view</a></li>
</ul>
</details>
<br />
Updates `wheel` from 0.46.3 to 0.47.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/wheel/releases">wheel's
releases</a>.</em></p>
<blockquote>
<h2>0.47.0</h2>
<ul>
<li>Added the <code>wheel info</code> subcommand to display metadata
about wheel files without unpacking them (<a
href="https://redirect.github.com/pypa/wheel/issues/639">#639</a>)</li>
<li>Fixed <code>WheelFile</code> raising <code>Missing RECORD
file</code> when the wheel filename contains uppercase characters (e.g.
<code>Django-3.2.5.whl</code>) but the <code>.dist-info</code> directory
inside uses normalized lowercase naming (<a
href="https://redirect.github.com/pypa/wheel/issues/411">#411</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/wheel/blob/main/docs/news.rst">wheel's
changelog</a>.</em></p>
<blockquote>
<h1>Release Notes</h1>
<p><strong>0.47.0 (2026-04-22)</strong></p>
<ul>
<li>Added the <code>wheel info</code> subcommand to display metadata
about wheel files without
unpacking them (<code>[#639](https://github.com/pypa/wheel/issues/639)
&lt;https://github.com/pypa/wheel/issues/639&gt;</code>_)</li>
<li>Fixed <code>WheelFile</code> raising <code>Missing RECORD
file</code> when the wheel filename contains
uppercase characters (e.g. <code>Django-3.2.5.whl</code>) but the
<code>.dist-info</code> directory
inside uses normalized lowercase naming
(<code>[#411](https://github.com/pypa/wheel/issues/411)
&lt;https://github.com/pypa/wheel/issues/411&gt;</code>_)</li>
</ul>
<p><strong>0.46.3 (2026-01-22)</strong></p>
<ul>
<li>Fixed <code>ImportError: cannot import name '_setuptools_logging'
from 'wheel'</code> when
installed alongside an old version of setuptools and running the
<code>bdist_wheel</code>
command (<code>[#676](https://github.com/pypa/wheel/issues/676)
&lt;https://github.com/pypa/wheel/issues/676&gt;</code>_)</li>
</ul>
<p><strong>0.46.2 (2026-01-22)</strong></p>
<ul>
<li>Restored the <code>bdist_wheel</code> command for compatibility with
<code>setuptools</code> older than
v70.1</li>
<li>Importing <code>wheel.bdist_wheel</code> now emits a
<code>FutureWarning</code> instead of a
<code>DeprecationWarning</code></li>
<li>Fixed <code>wheel unpack</code> potentially altering the permissions
of files outside of the
destination tree with maliciously crafted wheels (CVE-2026-24049)</li>
</ul>
<p><strong>0.46.1 (2025-04-08)</strong></p>
<ul>
<li>Temporarily restored the <code>wheel.macosx_libfile</code> module
(<code>[#659](https://github.com/pypa/wheel/issues/659)
&lt;https://github.com/pypa/wheel/issues/659&gt;</code>_)</li>
</ul>
<p><strong>0.46.0 (2025-04-03)</strong></p>
<ul>
<li>Dropped support for Python 3.8</li>
<li>Removed the <code>bdist_wheel</code> setuptools command
implementation and entry point.
The <code>wheel.bdist_wheel</code> module is now just an alias to
<code>setuptools.command.bdist_wheel</code>, emitting a deprecation
warning on import.</li>
<li>Removed vendored <code>packaging</code> in favor of a run-time
dependency on it</li>
<li>Made the <code>wheel.metadata</code> module private (with a
deprecation warning if it's
imported</li>
<li>Made the <code>wheel.cli</code> package private (no deprecation
warning)</li>
<li>Fixed an exception when calling the <code>convert</code> command
with an empty description
field</li>
</ul>
<p><strong>0.45.1 (2024-11-23)</strong></p>
<ul>
<li>Fixed pure Python wheels converted from eggs and wininst files
having the ABI tag in
the file name</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="efd83a750f"><code>efd83a7</code></a>
Created a new release</li>
<li><a
href="bb69216d35"><code>bb69216</code></a>
Reordered the changelog entries</li>
<li><a
href="d5a1763ce9"><code>d5a1763</code></a>
fix(wheelfile): resolve .dist-info path case-insensitively when reading
wheel...</li>
<li><a
href="5718957928"><code>5718957</code></a>
[pre-commit.ci] pre-commit autoupdate (<a
href="https://redirect.github.com/pypa/wheel/issues/685">#685</a>)</li>
<li><a
href="625806845a"><code>6258068</code></a>
chore: log_level is better than log_cli_level (<a
href="https://redirect.github.com/pypa/wheel/issues/684">#684</a>)</li>
<li><a
href="2975debc78"><code>2975deb</code></a>
Require tox &gt;= 4.22</li>
<li><a
href="47674ba770"><code>47674ba</code></a>
chore: add check-sdist to checks (<a
href="https://redirect.github.com/pypa/wheel/issues/681">#681</a>)</li>
<li><a
href="56223f6f8d"><code>56223f6</code></a>
<code>__package__</code> → <code>__spec__.parent</code> (<a
href="https://redirect.github.com/pypa/wheel/issues/679">#679</a>)</li>
<li><a
href="0ce509e02d"><code>0ce509e</code></a>
Added the wheel info subcommand (<a
href="https://redirect.github.com/pypa/wheel/issues/669">#669</a>)</li>
<li><a
href="39039c0f34"><code>39039c0</code></a>
Improved the index page</li>
<li>Additional commits viewable in <a
href="https://github.com/pypa/wheel/compare/0.46.3...0.47.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `hatchling` from 1.27.0 to 1.29.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pypa/hatch/releases">hatchling's
releases</a>.</em></p>
<blockquote>
<h2>Hatchling v1.29.0</h2>
<p><em><strong>Fixed:</strong></em></p>
<ul>
<li>Source Date Epoch no longer fails when set to date before 1980.</li>
</ul>
<h2>Hatchling v1.28.0</h2>
<p><em><strong>Changed:</strong></em></p>
<ul>
<li>Drop support for Python 3.9</li>
</ul>
<p><em><strong>Added:</strong></em></p>
<ul>
<li>Add <code>sbom-files</code> option and <code>sbom_files</code> build
data to the <code>wheel</code> build target for including Software Bill
of Materials files.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="1a74daa6f5"><code>1a74daa</code></a>
Noqa release command to unblock GHA for PRs</li>
<li><a
href="78065f4c54"><code>78065f4</code></a>
For Immutable Releases (<a
href="https://redirect.github.com/pypa/hatch/issues/2188">#2188</a>)</li>
<li><a
href="592c0a9c8c"><code>592c0a9</code></a>
release Hatchling v1.29.0 (<a
href="https://redirect.github.com/pypa/hatch/issues/2186">#2186</a>)</li>
<li><a
href="874059b82d"><code>874059b</code></a>
Prerelease doc updates. (<a
href="https://redirect.github.com/pypa/hatch/issues/2183">#2183</a>)</li>
<li><a
href="0e31bb64ec"><code>0e31bb6</code></a>
Immutable releases ci (<a
href="https://redirect.github.com/pypa/hatch/issues/2182">#2182</a>)</li>
<li><a
href="f400be159b"><code>f400be1</code></a>
Support a SOURCE_DATE_EPOCH prior to 1980 (<a
href="https://redirect.github.com/pypa/hatch/issues/1999">#1999</a>)</li>
<li><a
href="47b55ce0a9"><code>47b55ce</code></a>
Fixing failing tests for changes in Rich markdown rendering (<a
href="https://redirect.github.com/pypa/hatch/issues/2172">#2172</a>)</li>
<li><a
href="cc4acd6686"><code>cc4acd6</code></a>
Add a note guiding users to include SBOM files in the source
distribution (<a
href="https://redirect.github.com/pypa/hatch/issues/2">#2</a>...</li>
<li><a
href="9068758886"><code>9068758</code></a>
Fix <a
href="https://redirect.github.com/pypa/hatch/issues/2164">#2164</a>
keep_env type error for hatch shell (<a
href="https://redirect.github.com/pypa/hatch/issues/2165">#2165</a>)</li>
<li><a
href="bc31cfccc1"><code>bc31cfc</code></a>
Fix warning and tests with packaging 26.0 (<a
href="https://redirect.github.com/pypa/hatch/issues/2159">#2159</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pypa/hatch/compare/hatchling-v1.27.0...hatchling-v1.29.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `types-requests` from 2.32.4.20250611 to 2.33.0.20260503
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/python/typeshed/commits">compare view</a></li>
</ul>
</details>
<br />

Updates `types-markdown` from 3.8.0.20250415 to 3.10.2.20260408
<details>
<summary>Commits</summary>
<ul>
<li>See full diff in <a
href="https://github.com/python/typeshed/commits">compare view</a></li>
</ul>
</details>
<br />

Updates `sphinx-book-theme` from 1.1.4 to 1.2.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/executablebooks/sphinx-book-theme/releases">sphinx-book-theme's
releases</a>.</em></p>
<blockquote>
<h2>v1.2.0 -- 2026-03-09</h2>
<ul>
<li>Jupyterlite button - patched, merged version of <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/issues/655">#655</a>
by <a
href="https://github.com/matthew-brett"><code>@​matthew-brett</code></a>
in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/914">executablebooks/sphinx-book-theme#914</a></li>
<li>[ENH] Show source text on GitLab projects by <a
href="https://github.com/tymcauley"><code>@​tymcauley</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/916">executablebooks/sphinx-book-theme#916</a></li>
<li>Fix typo in docs by <a
href="https://github.com/user27182"><code>@​user27182</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/913">executablebooks/sphinx-book-theme#913</a></li>
<li>prepare for latest pydata and python releases by <a
href="https://github.com/choldgraf"><code>@​choldgraf</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/920">executablebooks/sphinx-book-theme#920</a></li>
<li>Ignore PendingDeprecationWarning about parser_name deprecation with
Docutils 0.22 by <a
href="https://github.com/mitya57"><code>@​mitya57</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/919">executablebooks/sphinx-book-theme#919</a></li>
<li>CI: adding cronjob by <a
href="https://github.com/bsipocz"><code>@​bsipocz</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/926">executablebooks/sphinx-book-theme#926</a></li>
<li>DOC: Fix margin directive documentation by <a
href="https://github.com/melissawm"><code>@​melissawm</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/930">executablebooks/sphinx-book-theme#930</a></li>
<li>MAINT: adding sphinx9 and python3.14 support and bumping minimum
sphinx to 7 and python to 3.11 by <a
href="https://github.com/bsipocz"><code>@​bsipocz</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/927">executablebooks/sphinx-book-theme#927</a></li>
</ul>
<p><strong>Full Changelog</strong>:
<a
href="https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.4...v1.2">https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.4...v1.2</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/executablebooks/sphinx-book-theme/blob/main/CHANGELOG.md">sphinx-book-theme's
changelog</a>.</em></p>
<blockquote>
<h2>v1.2.0 -- 2026-03-09</h2>
<ul>
<li>Jupyterlite button - patched, merged version of <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/issues/655">#655</a>
by <a
href="https://github.com/matthew-brett"><code>@​matthew-brett</code></a>
in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/914">executablebooks/sphinx-book-theme#914</a></li>
<li>[ENH] Show source text on GitLab projects by <a
href="https://github.com/tymcauley"><code>@​tymcauley</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/916">executablebooks/sphinx-book-theme#916</a></li>
<li>Fix typo in docs by <a
href="https://github.com/user27182"><code>@​user27182</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/913">executablebooks/sphinx-book-theme#913</a></li>
<li>prepare for latest pydata and python releases by <a
href="https://github.com/choldgraf"><code>@​choldgraf</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/920">executablebooks/sphinx-book-theme#920</a></li>
<li>Ignore PendingDeprecationWarning about parser_name deprecation with
Docutils 0.22 by <a
href="https://github.com/mitya57"><code>@​mitya57</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/919">executablebooks/sphinx-book-theme#919</a></li>
<li>CI: adding cronjob by <a
href="https://github.com/bsipocz"><code>@​bsipocz</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/926">executablebooks/sphinx-book-theme#926</a></li>
<li>DOC: Fix margin directive documentation by <a
href="https://github.com/melissawm"><code>@​melissawm</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/930">executablebooks/sphinx-book-theme#930</a></li>
<li>MAINT: adding sphinx9 and python3.14 support and bumping minimum
sphinx to 7 and python to 3.11 by <a
href="https://github.com/bsipocz"><code>@​bsipocz</code></a> in <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/927">executablebooks/sphinx-book-theme#927</a></li>
</ul>
<p><strong>Full Changelog</strong>:
<a
href="https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.4...v1.2">https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.4...v1.2</a></p>
<h2>v1.1.2 -- 2024-02-13</h2>
<p>(<a
href="https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.1...3da24da74f6042599fe6c9e2d612f5cbdef42280">full
changelog</a>)</p>
<h3>Enhancements made</h3>
<ul>
<li>ENH: bump version <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/818">#818</a>
(<a href="https://github.com/agoose77"><code>@​agoose77</code></a>)</li>
</ul>
<h3>Bugs fixed</h3>
<ul>
<li>FIX: correct event-handler signature <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/817">#817</a>
(<a href="https://github.com/agoose77"><code>@​agoose77</code></a>)</li>
</ul>
<h3>Contributors to this release</h3>
<p>(<a
href="https://github.com/executablebooks/sphinx-book-theme/graphs/contributors?from=2024-02-13&amp;to=2024-02-13&amp;type=c">GitHub
contributors page for this release</a>)</p>
<p><a
href="https://github.com/search?q=repo%3Aexecutablebooks%2Fsphinx-book-theme+involves%3Aagoose77+updated%3A2024-02-13..2024-02-13&amp;type=Issues"><code>@​agoose77</code></a></p>
<h2>v1.1.1 -- 2024-02-13</h2>
<p>(<a
href="https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.0...9335ab99b0bc77b826cb2c5afcef3432f14e8780">full
changelog</a>)</p>
<h3>Enhancements made</h3>
<ul>
<li>ENH: bump version for 1.1.1 <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/815">#815</a>
(<a href="https://github.com/agoose77"><code>@​agoose77</code></a>)</li>
</ul>
<h3>Bugs fixed</h3>
<ul>
<li>FIX: use <code>config-inited</code> event to register config <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/814">#814</a>
(<a href="https://github.com/agoose77"><code>@​agoose77</code></a>)</li>
</ul>
<h3>Other merged PRs</h3>
<ul>
<li>Build(deps): Bump actions/setup-python from 4 to 5 <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/803">#803</a>
(<a
href="https://github.com/dependabot"><code>@​dependabot</code></a>)</li>
<li>[pre-commit.ci] pre-commit autoupdate <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/pull/801">#801</a>
(<a
href="https://github.com/pre-commit-ci"><code>@​pre-commit-ci</code></a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="30f968ff99"><code>30f968f</code></a>
Release v1.2.0</li>
<li><a
href="b78d24f610"><code>b78d24f</code></a>
Finalizing changelog for v1.2.0</li>
<li><a
href="0415925b13"><code>0415925</code></a>
MAINT: ignore bots in release notes</li>
<li><a
href="5797d88ca3"><code>5797d88</code></a>
Merge pull request <a
href="https://redirect.github.com/executablebooks/sphinx-book-theme/issues/927">#927</a>
from bsipocz/MAINT_sphinx_dev</li>
<li><a
href="f23d0946c7"><code>f23d094</code></a>
CI: Adding workaround for autodoc typehint parsing issue</li>
<li><a
href="8747e975f9"><code>8747e97</code></a>
MAINT: dropping sphinx&lt;7 and python&lt;3.11 support</li>
<li><a
href="ffac4dee87"><code>ffac4de</code></a>
MAINT: using python 3.12 for RTD</li>
<li><a
href="cb587276c9"><code>cb58727</code></a>
MAINT: min pin for ablog due to sphinx9 incompatibility</li>
<li><a
href="8cc45e4ef5"><code>8cc45e4</code></a>
CI: ignore linkchecking URLs where anchors throw 403</li>
<li><a
href="d521920234"><code>d521920</code></a>
MAINT: adding sphinx9 and python 3.14 to testing</li>
<li>Additional commits viewable in <a
href="https://github.com/executablebooks/sphinx-book-theme/compare/v1.1.4...v1.2.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `sphinx-autoapi` from 3.6.0 to 3.8.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/readthedocs/sphinx-autoapi/releases">sphinx-autoapi's
releases</a>.</em></p>
<blockquote>
<h2>v3.8.0</h2>
<h1>Features</h1>
<ul>
<li>Autodoc-style directives can access members excluded by
autoapi_options</li>
</ul>
<h1>Misc</h1>
<ul>
<li><a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/553">#553</a></li>
</ul>
<h2>v3.7.0</h2>
<h1>Features</h1>
<ul>
<li>Added autoapi.import warning for when AutoAPI directives are given
non-existent objects</li>
<li>Adding autoapi_follow_symlinks, which allows api to traverse into
symlinked directories when generating the API documentation.</li>
<li>Drop support for Python 3.9 and officially support Python 3.14</li>
<li>Support rendering PEP-695 type parameters</li>
</ul>
<h1>Bugfixes</h1>
<ul>
<li>Render typing_extensions.TypeAlias like other type aliases (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/520">#520</a>)</li>
<li>Fix PythonFunction.overloads typing when source code overload(s) do
not provide a return type (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/523">#523</a>)</li>
</ul>
<h1>Misc</h1>
<ul>
<li>Fix deprecation warnings raised by astroid and sphinx</li>
<li>Handling case where match returns None to fix mypy unit test.</li>
</ul>
<h2>v3.6.1</h2>
<h1>Bugfixes</h1>
<ul>
<li>Update the supported versions of astroid. Fix the breaking change to
Import and pass in the AstroidManager to the AstroidBuilder (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/536">#536</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/readthedocs/sphinx-autoapi/blob/main/CHANGELOG.rst">sphinx-autoapi's
changelog</a>.</em></p>
<blockquote>
<h2>v3.8.0 (2026-03-07)</h2>
<p>Features
^^^^^^^^</p>
<ul>
<li>Autodoc-style directives can access members excluded by
autoapi_options</li>
</ul>
<p>Misc
^^^^</p>
<ul>
<li><a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/553">#553</a></li>
</ul>
<h2>v3.7.0 (2026-02-10)</h2>
<p>Features
^^^^^^^^</p>
<ul>
<li>Added autoapi.import warning for when AutoAPI directives are given
non-existent objects</li>
<li>Adding <code>autoapi_follow_symlinks</code>, which allows api to
traverse into symlinked directories when generating the API
documentation.</li>
<li>Drop support for Python 3.9 and officially support Python 3.14</li>
<li>Support rendering PEP-695 type parameters</li>
</ul>
<p>Bugfixes
^^^^^^^^</p>
<ul>
<li>Render typing_extensions.TypeAlias like other type aliases (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/520">#520</a>)</li>
<li>Fix <code>PythonFunction.overloads</code> typing when source code
overload(s) do not provide a return type (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/523">#523</a>)</li>
</ul>
<p>Misc
^^^^</p>
<ul>
<li>Fix deprecation warnings raised by astroid and sphinx</li>
<li>Handling case where match returns None to fix mypy unit test.</li>
</ul>
<h2>v3.6.1 (2025-10-06)</h2>
<p>Bugfixes
^^^^^^^^</p>
<ul>
<li>Update the supported versions of astroid.
Fix the breaking change to Import and pass in the AstroidManager to the
AstroidBuilder (<a
href="https://redirect.github.com/readthedocs/sphinx-autoapi/issues/536">#536</a>)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="75cbffdea0"><code>75cbffd</code></a>
Version 3.8.0</li>
<li><a
href="7838cf6937"><code>7838cf6</code></a>
Bump the github-actions group with 2 updates</li>
<li><a
href="f1cdd30233"><code>f1cdd30</code></a>
Attempt to fix macos-latest build</li>
<li><a
href="34bb24ccc9"><code>34bb24c</code></a>
Autodoc-style directives can access members excluded by
autoapi_options</li>
<li><a
href="ccb2e898cb"><code>ccb2e89</code></a>
astroid requirement is consistent across all versions of Python</li>
<li><a
href="0917ed2d4a"><code>0917ed2</code></a>
Version 3.7.0</li>
<li><a
href="394beb4532"><code>394beb4</code></a>
Add warning for missing import</li>
<li><a
href="96cd74d1a0"><code>96cd74d</code></a>
Update changelog</li>
<li><a
href="c248b85d66"><code>c248b85</code></a>
Render typing_extensions.TypeAlias like other type aliases</li>
<li><a
href="a2f49c9689"><code>a2f49c9</code></a>
Fix deprecation warnings raised by astroid and sphinx</li>
<li>Additional commits viewable in <a
href="https://github.com/readthedocs/sphinx-autoapi/compare/v3.6.0...v3.8.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `sphinxcontrib-mermaid` from 2.0.1 to 2.0.2
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/mgaitan/sphinxcontrib-mermaid/blob/master/CHANGELOG.md">sphinxcontrib-mermaid's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<h2>Unreleased</h2>
<ul>
<li>Add <code>mermaid_dark_theme</code> and
<code>mermaid_light_theme</code> config options for configurable theme
switching</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="19be468202"><code>19be468</code></a>
Merge pull request <a
href="https://redirect.github.com/mgaitan/sphinxcontrib-mermaid/issues/240">#240</a>
from timkpaine/tkp/hatch</li>
<li><a
href="e1f9eccc13"><code>e1f9ecc</code></a>
Switch to hatchling</li>
<li><a
href="42aa20a010"><code>42aa20a</code></a>
Merge pull request <a
href="https://redirect.github.com/mgaitan/sphinxcontrib-mermaid/issues/239">#239</a>
from timkpaine/tkp/202</li>
<li><a
href="2db5b555ff"><code>2db5b55</code></a>
bump to 2.0.2</li>
<li><a
href="25c7ef7b8f"><code>25c7ef7</code></a>
Merge pull request <a
href="https://redirect.github.com/mgaitan/sphinxcontrib-mermaid/issues/237">#237</a>
from kartben/local_paths</li>
<li><a
href="e98c6f8b88"><code>e98c6f8</code></a>
increase test coverage for _use_local options</li>
<li><a
href="1422b452a5"><code>1422b45</code></a>
Resolve local Mermaid/ELK/ZenUML/D3 JS paths under html_static_path</li>
<li><a
href="d6d874c4fb"><code>d6d874c</code></a>
Merge pull request <a
href="https://redirect.github.com/mgaitan/sphinxcontrib-mermaid/issues/236">#236</a>
from jensens/configurable-theme</li>
<li><a
href="bce597640b"><code>bce5976</code></a>
Document mermaid_dark_theme and mermaid_light_theme config options</li>
<li><a
href="12bb2ac696"><code>12bb2ac</code></a>
Add mermaid_dark_theme and mermaid_light_theme config options</li>
<li>See full diff in <a
href="https://github.com/mgaitan/sphinxcontrib-mermaid/compare/2.0.1...2.0.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `markdown` from 3.8.2 to 3.10.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/Python-Markdown/markdown/releases">markdown's
releases</a>.</em></p>
<blockquote>
<h2>Release 3.10.2</h2>
<h3>Fixed</h3>
<ul>
<li>Fix a regression related to comment handling (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1590">#1590</a>).</li>
<li>More reliable fix for <code>&lt;/</code> (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1593">#1593</a>).</li>
</ul>
<h2>Release 3.10.1</h2>
<h3>Fixed</h3>
<ul>
<li>Ensure nested elements inside inline comments are properly unescaped
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1571">#1571</a>).</li>
<li>Make the docs build successfully with mkdocstrings-python 2.0 (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1575">#1575</a>).</li>
<li>Fix infinite loop when multiple bogus or unclosed HTML comments
appear in input (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1578">#1578</a>).</li>
<li>Fix another infinite loop when handling bad comments (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1586">#1586</a>).</li>
</ul>
<h2>Release 3.10.0</h2>
<h3>Changed</h3>
<ul>
<li>Officially support Python 3.14 and PyPy 3.11 and drop support for
Python 3.9
and PyPy 3.9.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix an HTML comment parsing case in some Python versions that can
cause an
infinite loop (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1554">#1554</a>).</li>
<li>Revert the default behavior of <code>USE_DEFINITION_ORDER</code> (to
<code>True</code>). The new
behavior introduced in 3.9.0 is experimental and results are
inconsistent.
It should not have been made the default behavior (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1561">#1561</a>).</li>
</ul>
<h2>Release 3.9.0</h2>
<h3>Changed</h3>
<ul>
<li>Footnotes are now ordered by the occurrence of their references in
the
document. A new configuration option for the footnotes extension,
<code>USE_DEFINITION_ORDER</code>, has been added to support restoring
the previous
behavior of ordering footnotes by the occurrence of definitions (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1367">#1367</a>).</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure inline processing iterates through elements in document order
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1546">#1546</a>).</li>
<li>Fix handling of incomplete HTML tags in code spans in Python 3.14
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1547">#1547</a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md">markdown's
changelog</a>.</em></p>
<blockquote>
<h2>[3.10.2] - 2026-02-09</h2>
<h3>Fixed</h3>
<ul>
<li>Fix a regression related to comment handling (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1590">#1590</a>).</li>
<li>More reliable fix for <code>&lt;/</code> (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1593">#1593</a>).</li>
</ul>
<h2>[3.10.1] - 2026-01-21</h2>
<h3>Fixed</h3>
<ul>
<li>Ensure nested elements inside inline comments are properly unescaped
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1571">#1571</a>).</li>
<li>Make the docs build successfully with mkdocstrings-python 2.0 (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1575">#1575</a>).</li>
<li>Fix infinite loop when multiple bogus or unclosed HTML comments
appear in input (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1578">#1578</a>).</li>
<li>Fix another infinite loop when handling bad comments (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1586">#1586</a>).</li>
</ul>
<h2>[3.10.0] - 2025-11-03</h2>
<h3>Changed</h3>
<ul>
<li>Officially support Python 3.14 and PyPy 3.11 and drop support for
Python 3.9
and PyPy 3.9.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix an HTML comment parsing case in some Python versions that can
cause an
infinite loop (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1554">#1554</a>).</li>
<li>Revert the default behavior of <code>USE_DEFINITION_ORDER</code> (to
<code>True</code>). The new
behavior introduced in 3.9.0 is experimental and results are
inconsistent.
It should not have been made the default behavior (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1561">#1561</a>).</li>
</ul>
<h2>[3.9.0] - 2025-09-04</h2>
<h3>Changed</h3>
<ul>
<li>Footnotes are now ordered by the occurrence of their references in
the
document. A new configuration option for the footnotes extension,
<code>USE_DEFINITION_ORDER</code>, has been added to support restoring
the previous
behavior of ordering footnotes by the occurrence of definitions (<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1367">#1367</a>).</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Ensure inline processing iterates through elements in document order
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1546">#1546</a>).</li>
<li>Fix handling of incomplete HTML tags in code spans in Python 3.14
(<a
href="https://redirect.github.com/Python-Markdown/markdown/issues/1547">#1547</a>).</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e7a0efb3a7"><code>e7a0efb</code></a>
Bump version to 3.10.2</li>
<li><a
href="630183336b"><code>6301833</code></a>
Document HTML sanitation policy</li>
<li><a
href="7f29f1a69d"><code>7f29f1a</code></a>
More reliable fix for <code>&lt;/</code></li>
<li><a
href="c4386475a6"><code>c438647</code></a>
Fix regression of special comments</li>
<li><a
href="e5fa5b86e8"><code>e5fa5b8</code></a>
Bump version to 3.10.1</li>
<li><a
href="f9253495f5"><code>f925349</code></a>
More HTML fixes</li>
<li><a
href="9933a0a469"><code>9933a0a</code></a>
Revert &quot;Allow reference links with backticks&quot;</li>
<li><a
href="07dfa4eb43"><code>07dfa4e</code></a>
Allow reference links with backticks</li>
<li><a
href="fb6b27a6ff"><code>fb6b27a</code></a>
Fix infinite loop when text contains multiple unclosed comments</li>
<li><a
href="89112c293f"><code>89112c2</code></a>
Make the docs build successfully with mkdocstrings-python 2.0</li>
<li>Additional commits viewable in <a
href="https://github.com/Python-Markdown/markdown/compare/3.8.2...3.10.2">compare
view</a></li>
</ul>
</details>
<br />

Updates `orjson` from 3.10.18 to 3.11.8
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/ijl/orjson/releases">orjson's
releases</a>.</em></p>
<blockquote>
<h2>3.11.8</h2>
<h3>Changed</h3>
<ul>
<li>Build and compatibility improvements.</li>
</ul>
<h2>3.11.7</h2>
<h3>Changed</h3>
<ul>
<li>Use a faster library to serialize <code>float</code>. Users with
byte-exact regression
tests should note positive exponents are now written using a
<code>+</code>, e.g.,
<code>1.2e+30</code> instead of <code>1.2e30</code>. Both formats are
spec-compliant.</li>
<li>ABI compatibility with CPython 3.15 alpha 5 free-threading.</li>
</ul>
<h2>3.11.6</h2>
<h3>Changed</h3>
<ul>
<li>orjson now includes code licensed under the Mozilla Public License
2.0 (MPL-2.0).</li>
<li>Drop support for Python 3.9.</li>
<li>ABI compatibility with CPython 3.15 alpha 5.</li>
<li>Build now depends on Rust 1.89 or later instead of 1.85.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix sporadic crash serializing deeply nested <code>list</code> of
<code>dict</code>.</li>
</ul>
<h2>3.11.5</h2>
<h3>Changed</h3>
<ul>
<li>Show simple error message instead of traceback when attempting to
build on unsupported Python versions.</li>
</ul>
<h2>3.11.4</h2>
<h3>Changed</h3>
<ul>
<li>ABI compatibility with CPython 3.15 alpha 1.</li>
<li>Publish PyPI wheels for 3.14 and manylinux i686, manylinux arm7,
manylinux ppc64le, manylinux s390x.</li>
<li>Build now requires a C compiler.</li>
</ul>
<h2>3.11.3</h2>
<h3>Fixed</h3>
<ul>
<li>Fix PyPI project metadata when using maturin 1.9.2 or later.</li>
</ul>
<h2>3.11.2</h2>
<h3>Fixed</h3>
<ul>
<li>Fix build using Rust 1.89 on amd64.</li>
</ul>
<h3>Changed</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ijl/orjson/blob/master/CHANGELOG.md">orjson's
changelog</a>.</em></p>
<blockquote>
<h2>3.11.8 - 2026-03-31</h2>
<h3>Changed</h3>
<ul>
<li>Build and compatibility improvements.</li>
</ul>
<h2>3.11.7 - 2026-02-02</h2>
<h3>Changed</h3>
<ul>
<li>Use a faster library to serialize <code>float</code>. Users with
byte-exact regression
tests should note positive exponents are now written using a
<code>+</code>, e.g.,
<code>1.2e+30</code> instead of <code>1.2e30</code>. Both formats are
spec-compliant.</li>
<li>ABI compatibility with CPython 3.15 alpha 5 free-threading.</li>
</ul>
<h2>3.11.6 - 2026-01-29</h2>
<h3>Changed</h3>
<ul>
<li>orjson now includes code licensed under the Mozilla Public License
2.0 (MPL-2.0).</li>
<li>Drop support for Python 3.9.</li>
<li>ABI compatibility with CPython 3.15 alpha 5.</li>
<li>Build now depends on Rust 1.89 or later instead of 1.85.</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fix sporadic crash serializing deeply nested <code>list</code> of
<code>dict</code>.</li>
</ul>
<h2>3.11.5 - 2025-12-06</h2>
<h3>Changed</h3>
<ul>
<li>Show simple error message instead of traceback when attempting to
build on unsupported Python versions.</li>
</ul>
<h2>3.11.4 - 2025-10-24</h2>
<h3>Changed</h3>
<ul>
<li>ABI compatibility with CPython 3.15 alpha 1.</li>
<li>Publish PyPI wheels for 3.14 and manylinux i686, manylinux arm7,
manylinux ppc64le, manylinux s390x.</li>
<li>Build now requires a C compiler.</li>
</ul>
<h2>3.11.3 - 2025-08-26</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5cbb3d0398"><code>5cbb3d0</code></a>
3.11.8</li>
<li><a
href="4195d7f263"><code>4195d7f</code></a>
writer::half</li>
<li><a
href="d00641b694"><code>d00641b</code></a>
writer::uuid</li>
<li><a
href="c84d9b4ba4"><code>c84d9b4</code></a>
build and compatibility misc</li>
<li><a
href="4547234b68"><code>4547234</code></a>
ffi::numpy</li>
<li><a
href="0d4a5ad1f1"><code>0d4a5ad</code></a>
datetime PyRef idiom</li>
<li><a
href="e93a13d372"><code>e93a13d</code></a>
Cross-compile avoids maturin v1.12 build-details.json error</li>
<li><a
href="ec2b066cae"><code>ec2b066</code></a>
3.11.7</li>
<li><a
href="1ca01f78cf"><code>1ca01f7</code></a>
zmij</li>
<li><a
href="1716a226bd"><code>1716a22</code></a>
cargo update</li>
<li>Additional commits viewable in <a
href="https://github.com/ijl/orjson/compare/3.10.18...3.11.8">compare
view</a></li>
</ul>
</details>
<br />

Updates `typing-extensions` from 4.14.0 to 4.15.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/python/typing_extensions/releases">typing-extensions's
releases</a>.</em></p>
<blockquote>
<h2>4.15.0</h2>
<p>No user-facing changes since 4.15.0rc1.</p>
<p>New features since 4.14.1:</p>
<ul>
<li>Add the <code>@typing_extensions.disjoint_base</code> decorator, as
specified
in PEP 800. Patch by Jelle Zijlstra.</li>
<li>Add <code>typing_extensions.type_repr</code>, a backport of
<a
href="https://docs.python.org/3.14/library/annotationlib.html#annotationlib.type_repr"><code>annotationlib.type_repr</code></a>,
introduced in Python 3.14 (CPython PR <a
href="https://redirect.github.com/python/cpython/pull/124551">#124551</a>,
originally by Jelle Zijlstra). Patch by Semyon Moroz.</li>
<li>Fix behavior of type params in
<code>typing_extensions.evaluate_forward_ref</code>. Backport of
CPython PR <a
href="https://redirect.github.com/python/cpython/pull/137227">#137227</a>
by Jelle Zijlstra.</li>
</ul>
<h2>4.15.0rc1</h2>
<ul>
<li>Add the <code>@typing_extensions.disjoint_base</code> decorator, as
specified
in PEP 800. Patch by Jelle Zijlstra.</li>
<li>Add <code>typing_extensions.type_repr</code>, a backport of
<a
href="https://docs.python.org/3.14/library/annotationlib.html#annotationlib.type_repr"><code>annotationlib.type_repr</code></a>,
introduced in Python 3.14 (CPython PR <a
href="https://redirect.github.com/python/cpython/pull/124551">#124551</a>,
originally by Jelle Zijlstra). Patch by Semyon Moroz.</li>
<li>Fix behavior of type params in
<code>typing_extensions.evaluate_forward_ref</code>. Backport of
CPython PR <a
href="https://redirect.github.com/python/cpython/pull/137227">#137227</a>
by Jelle Zijlstra.</li>
</ul>
<h2>4.14.1</h2>
<h1>Release 4.14.1 (July 4, 2025)</h1>
<ul>
<li>Fix usage of <code>typing_extensions.TypedDict</code> nested inside
other types
(e.g., <code>typing.Type[typing_extensions.TypedDict]</code>). This is
not allowed by the
type system but worked on older versions, so we maintain support.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/python/typing_extensions/blob/main/CHANGELOG.md">typing-extensions's
changelog</a>.</em></p>
<blockquote>
<h1>Release 4.15.0 (August 25, 2025)</h1>
<p>No user-facing changes since 4.15.0rc1.</p>
<h1>Release 4.15.0rc1 (August 18, 2025)</h1>
<ul>
<li>Add the <code>@typing_extensions.disjoint_base</code> decorator, as
specified
in PEP 800. Patch by Jelle Zijlstra.</li>
<li>Add <code>typing_extensions.type_repr</code>, a backport of
<a
href="https://docs.python.org/3.14/library/annotationlib.html#annotationlib.type_repr"><code>annotationlib.type_repr</code></a>,
introduced in Python 3.14 (CPython PR <a
href="https://redirect.github.com/python/cpython/pull/124551">#124551</a>,
originally by Jelle Zijlstra). Patch by Semyon Moroz.</li>
<li>Fix behavior of type params in
<code>typing_extensions.evaluate_forward_ref</code>. Backport of
CPython PR <a
href="https://redirect.github.com/python/cpython/pull/137227">#137227</a>
by Jelle Zijlstra.</li>
</ul>
<h1>Release 4.14.1 (July 4, 2025)</h1>
<ul>
<li>Fix usage of <code>typing_extensions.TypedDict</code> nested inside
other types
(e.g., <code>typing.Type[typing_extensions.TypedDict]</code>). This is
not allowed by the
type system but worked on older versions, so we maintain support.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="9d1637e264"><code>9d1637e</code></a>
Prepare release 4.15.0 (<a
href="https://redirect.github.com/python/typing_extensions/issues/658">#658</a>)</li>
<li><a
href="4bd67c5be5"><code>4bd67c5</code></a>
Coverage: exclude some noise (<a
href="https://redirect.github.com/python/typing_extensions/issues/656">#656</a>)</li>
<li><a
href="e589a26da7"><code>e589a26</code></a>
Coverage: add detailed report to job summary (<a
href="https://redirect.github.com/python/typing_extensions/issues/655">#655</a>)</li>
<li><a
href="67d37fed12"><code>67d37fe</code></a>
Coverage: Implement fail_under (<a
href="https://redirect.github.com/python/typing_extensions/issues/654">#654</a>)</li>
<li><a
href="e9ae26f528"><code>e9ae26f</code></a>
Don't delete previous coverage comment (<a
href="https://redirect.github.com/python/typing_extensions/issues/653">#653</a>)</li>
<li><a
href="ac80bb728a"><code>ac80bb7</code></a>
Add Coverage workflow (<a href="https://redirect.gith...

_Description has been truncated_
zsh:1: command not found: dump_zsh_state

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Fernando Lins <1887601+fernandolins@users.noreply.github.com>
2026-05-13 11:53:14 -03:00
Abdo
8ee11614e1 fix: optimize Briefcase bundle size (#4822)
## Linked issue

Closes #4820

## Summary

Optimize size of the Briefcase bundle by removing unused dependency
files:
- Remove large *.debug.pak/*.debug.bin files included in Qt.
- Remove packaging/typing/testing metadata.
- Remove app_packages/bin binaries.
- Remove miscellaneous unused files in PyQt6/pywin32.
- Trim large qtwebengine_locales files by only keeping files for
languages we support.
- Set MSI compression level in the Wix template to "high".

This reduces the size of the Windows MSI by ~30 MB. I was tempted to go
further and prune unused Qt modules since the bulk of the app size comes
from Qt, but that proved to be error-prone: We can't simply remove
modules not imported by Anki as they can be possibly used by add-ons and
other modules might have hidden dependencies on them.

## How to test

Build the installer and confirm installation works.
2026-05-12 22:44:24 +03:00