Merge branch 'main' into cached-workload

This commit is contained in:
Luc Mcgrady 2025-07-21 01:16:52 +01:00 committed by GitHub
commit 5fab04cd94
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 131 additions and 44 deletions

View file

@ -1 +1 @@
25.08b1 25.07.3rc1

View file

@ -141,7 +141,7 @@ walkdir = "2.5.0"
which = "8.0.0" which = "8.0.0"
widestring = "1.1.0" widestring = "1.1.0"
winapi = { version = "0.3", features = ["wincon", "winreg"] } winapi = { version = "0.3", features = ["wincon", "winreg"] }
windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_Foundation", "Win32_UI_Shell"] } windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_Foundation", "Win32_UI_Shell", "Wdk_System_SystemServices"] }
wiremock = "0.6.3" wiremock = "0.6.3"
xz2 = "0.1.7" xz2 = "0.1.7"
zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] } zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] }

View file

@ -36,7 +36,7 @@ pub fn setup_pyenv(args: PyenvArgs) {
// remove UV_* environment variables to avoid interference // remove UV_* environment variables to avoid interference
for (key, _) in std::env::vars() { for (key, _) in std::env::vars() {
if key.starts_with("UV_") { if key.starts_with("UV_") || key == "VIRTUAL_ENV" {
command.env_remove(key); command.env_remove(key);
} }
} }

@ -1 +1 @@
Subproject commit 3d04bcbf7fefca0007bc9db307409d88210995d8 Subproject commit b90ef6f03c251eb336029ac7c5f551200d41273f

@ -1 +1 @@
Subproject commit c65a9587b1f18931986bdf145872e8e4c44c5c82 Subproject commit 9aa63c335c61b30421d39cf43fd8e3975179059c

View file

@ -7,7 +7,7 @@ dependencies = [
"decorator", "decorator",
"markdown", "markdown",
"orjson", "orjson",
"protobuf>=4.21", "protobuf>=6.0,<8.0",
"requests[socks]", "requests[socks]",
# remove after we update to min python 3.11+ # remove after we update to min python 3.11+
"typing_extensions", "typing_extensions",

View file

@ -70,10 +70,10 @@ def show(mw: aqt.AnkiQt) -> QDialog:
abouttext += f"<p>{lede}" abouttext += f"<p>{lede}"
abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}" abouttext += f"<p>{tr.about_anki_is_licensed_under_the_agpl3()}"
abouttext += f"<p>{tr.about_version(val=version_with_build())}<br>" abouttext += f"<p>{tr.about_version(val=version_with_build())}<br>"
abouttext += ("Python %s Qt %s PyQt %s<br>") % ( abouttext += ("Python %s Qt %s Chromium %s<br>") % (
platform.python_version(), platform.python_version(),
qVersion(), qVersion(),
PYQT_VERSION_STR, (qWebEngineChromiumVersion() or "").split(".")[0],
) )
abouttext += ( abouttext += (
without_unicode_isolation(tr.about_visit_website(val=aqt.appWebsite)) without_unicode_isolation(tr.about_visit_website(val=aqt.appWebsite))
@ -225,6 +225,7 @@ def show(mw: aqt.AnkiQt) -> QDialog:
"Adnane Taghi", "Adnane Taghi",
"Anon_0000", "Anon_0000",
"Bilolbek Normuminov", "Bilolbek Normuminov",
"Sagiv Marzini",
) )
) )

View file

@ -1292,9 +1292,10 @@
<tabstop>daily_backups</tabstop> <tabstop>daily_backups</tabstop>
<tabstop>weekly_backups</tabstop> <tabstop>weekly_backups</tabstop>
<tabstop>monthly_backups</tabstop> <tabstop>monthly_backups</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>syncAnkiHubLogout</tabstop> <tabstop>syncAnkiHubLogout</tabstop>
<tabstop>syncAnkiHubLogin</tabstop> <tabstop>syncAnkiHubLogin</tabstop>
<tabstop>buttonBox</tabstop>
<tabstop>tabWidget</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>

View file

@ -82,11 +82,14 @@ class Preferences(QDialog):
) )
group = self.form.preferences_answer_keys group = self.form.preferences_answer_keys
group.setLayout(layout := QFormLayout()) group.setLayout(layout := QFormLayout())
tab_widget: QWidget = self.form.url_schemes
for ease, label in ease_labels: for ease, label in ease_labels:
layout.addRow( layout.addRow(
label, label,
line_edit := QLineEdit(self.mw.pm.get_answer_key(ease) or ""), line_edit := QLineEdit(self.mw.pm.get_answer_key(ease) or ""),
) )
QWidget.setTabOrder(tab_widget, line_edit)
tab_widget = line_edit
qconnect( qconnect(
line_edit.textChanged, line_edit.textChanged,
functools.partial(self.mw.pm.set_answer_key, ease), functools.partial(self.mw.pm.set_answer_key, ease),

View file

@ -13,7 +13,8 @@ HOST_ARCH=$(uname -m)
# Define output paths # Define output paths
OUTPUT_DIR="../../../out/launcher" OUTPUT_DIR="../../../out/launcher"
LAUNCHER_DIR="$OUTPUT_DIR/anki-linux" ANKI_VERSION=$(cat ../../../.version | tr -d '\n')
LAUNCHER_DIR="$OUTPUT_DIR/anki-launcher-$ANKI_VERSION-linux"
# Clean existing output directory # Clean existing output directory
rm -rf "$LAUNCHER_DIR" rm -rf "$LAUNCHER_DIR"
@ -77,8 +78,8 @@ chmod +x \
chmod -R a+r "$LAUNCHER_DIR" chmod -R a+r "$LAUNCHER_DIR"
ZSTD="zstd -c --long -T0 -18" ZSTD="zstd -c --long -T0 -18"
TRANSFORM="s%^.%anki-linux%S" TRANSFORM="s%^.%anki-launcher-$ANKI_VERSION-linux%S"
TARBALL="$OUTPUT_DIR/anki-linux.tar.zst" TARBALL="$OUTPUT_DIR/anki-launcher-$ANKI_VERSION-linux.tar.zst"
tar -I "$ZSTD" --transform "$TRANSFORM" -cf "$TARBALL" -C "$LAUNCHER_DIR" . tar -I "$ZSTD" --transform "$TRANSFORM" -cf "$TARBALL" -C "$LAUNCHER_DIR" .

View file

@ -5,7 +5,7 @@
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Anki</string> <string>Anki</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0</string> <string>ANKI_VERSION</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>12</string> <string>12</string>
<key>LSApplicationCategoryType</key> <key>LSApplicationCategoryType</key>

View file

@ -31,7 +31,8 @@ lipo -create \
cp "$OUTPUT_DIR/uv" "$APP_LAUNCHER/Contents/MacOS/" cp "$OUTPUT_DIR/uv" "$APP_LAUNCHER/Contents/MacOS/"
# Copy support files # Copy support files
cp Info.plist "$APP_LAUNCHER/Contents/" ANKI_VERSION=$(cat ../../../.version | tr -d '\n')
sed "s/ANKI_VERSION/$ANKI_VERSION/g" Info.plist > "$APP_LAUNCHER/Contents/Info.plist"
cp icon/Assets.car "$APP_LAUNCHER/Contents/Resources/" cp icon/Assets.car "$APP_LAUNCHER/Contents/Resources/"
cp ../pyproject.toml "$APP_LAUNCHER/Contents/Resources/" cp ../pyproject.toml "$APP_LAUNCHER/Contents/Resources/"
cp ../../../.python-version "$APP_LAUNCHER/Contents/Resources/" cp ../../../.python-version "$APP_LAUNCHER/Contents/Resources/"

View file

@ -6,7 +6,8 @@ set -e
# base folder with Anki.app in it # base folder with Anki.app in it
output="$1" output="$1"
dist="$1/tmp" dist="$1/tmp"
dmg_path="$output/Anki.dmg" ANKI_VERSION=$(cat ../../../.version | tr -d '\n')
dmg_path="$output/anki-launcher-$ANKI_VERSION-mac.dmg"
if [ -d "/Volumes/Anki" ] if [ -d "/Volumes/Anki" ]
then then

View file

@ -22,6 +22,11 @@ const NSIS_PATH: &str = "C:\\Program Files (x86)\\NSIS\\makensis.exe";
fn main() -> Result<()> { fn main() -> Result<()> {
println!("Building Windows launcher..."); println!("Building Windows launcher...");
// Read version early so it can be used throughout the build process
let version = std::fs::read_to_string("../../../.version")?
.trim()
.to_string();
let output_dir = PathBuf::from(OUTPUT_DIR); let output_dir = PathBuf::from(OUTPUT_DIR);
let launcher_exe_dir = PathBuf::from(LAUNCHER_EXE_DIR); let launcher_exe_dir = PathBuf::from(LAUNCHER_EXE_DIR);
let nsis_dir = PathBuf::from(NSIS_DIR); let nsis_dir = PathBuf::from(NSIS_DIR);
@ -31,16 +36,20 @@ fn main() -> Result<()> {
extract_nsis_plugins()?; extract_nsis_plugins()?;
copy_files(&output_dir)?; copy_files(&output_dir)?;
sign_binaries(&output_dir)?; sign_binaries(&output_dir)?;
copy_nsis_files(&nsis_dir)?; copy_nsis_files(&nsis_dir, &version)?;
build_uninstaller(&output_dir, &nsis_dir)?; build_uninstaller(&output_dir, &nsis_dir)?;
sign_file(&output_dir.join("uninstall.exe"))?; sign_file(&output_dir.join("uninstall.exe"))?;
generate_install_manifest(&output_dir)?; generate_install_manifest(&output_dir)?;
build_installer(&output_dir, &nsis_dir)?; build_installer(&output_dir, &nsis_dir)?;
sign_file(&PathBuf::from("../../../out/launcher_exe/anki-install.exe"))?;
let installer_filename = format!("anki-launcher-{version}-windows.exe");
let installer_path = PathBuf::from("../../../out/launcher_exe").join(&installer_filename);
sign_file(&installer_path)?;
println!("Build completed successfully!"); println!("Build completed successfully!");
println!("Output directory: {}", output_dir.display()); println!("Output directory: {}", output_dir.display());
println!("Installer: ../../../out/launcher_exe/anki-install.exe"); println!("Installer: ../../../out/launcher_exe/{installer_filename}");
Ok(()) Ok(())
} }
@ -235,11 +244,13 @@ fn generate_install_manifest(output_dir: &Path) -> Result<()> {
Ok(()) Ok(())
} }
fn copy_nsis_files(nsis_dir: &Path) -> Result<()> { fn copy_nsis_files(nsis_dir: &Path, version: &str) -> Result<()> {
println!("Copying NSIS support files..."); println!("Copying NSIS support files...");
// Copy anki.template.nsi as anki.nsi // Copy anki.template.nsi as anki.nsi and substitute version placeholders
copy_file("anki.template.nsi", nsis_dir.join("anki.nsi"))?; let template_content = std::fs::read_to_string("anki.template.nsi")?;
let substituted_content = template_content.replace("ANKI_VERSION", version);
write_file(nsis_dir.join("anki.nsi"), substituted_content)?;
// Copy fileassoc.nsh // Copy fileassoc.nsh
copy_file("fileassoc.nsh", nsis_dir.join("fileassoc.nsh"))?; copy_file("fileassoc.nsh", nsis_dir.join("fileassoc.nsh"))?;

View file

@ -198,6 +198,7 @@ fn extract_aqt_version(
) -> Option<String> { ) -> Option<String> {
let output = Command::new(uv_path) let output = Command::new(uv_path)
.current_dir(uv_install_root) .current_dir(uv_install_root)
.env("VIRTUAL_ENV", uv_install_root.join(".venv"))
.args(["pip", "show", "aqt"]) .args(["pip", "show", "aqt"])
.output() .output()
.ok()?; .ok()?;
@ -269,7 +270,7 @@ fn handle_version_install_or_update(state: &State, choice: MainMenuChoice) -> Re
// remove UV_* environment variables to avoid interference // remove UV_* environment variables to avoid interference
for (key, _) in std::env::vars() { for (key, _) in std::env::vars() {
if key.starts_with("UV_") { if key.starts_with("UV_") || key == "VIRTUAL_ENV" {
command.env_remove(key); command.env_remove(key);
} }
} }

View file

@ -8,6 +8,7 @@ use anyhow::Context;
use anyhow::Result; use anyhow::Result;
use widestring::u16cstr; use widestring::u16cstr;
use windows::core::PCWSTR; use windows::core::PCWSTR;
use windows::Wdk::System::SystemServices::RtlGetVersion;
use windows::Win32::System::Console::AttachConsole; use windows::Win32::System::Console::AttachConsole;
use windows::Win32::System::Console::GetConsoleWindow; use windows::Win32::System::Console::GetConsoleWindow;
use windows::Win32::System::Console::ATTACH_PARENT_PROCESS; use windows::Win32::System::Console::ATTACH_PARENT_PROCESS;
@ -18,8 +19,25 @@ use windows::Win32::System::Registry::HKEY;
use windows::Win32::System::Registry::HKEY_CURRENT_USER; use windows::Win32::System::Registry::HKEY_CURRENT_USER;
use windows::Win32::System::Registry::KEY_READ; use windows::Win32::System::Registry::KEY_READ;
use windows::Win32::System::Registry::REG_SZ; use windows::Win32::System::Registry::REG_SZ;
use windows::Win32::System::SystemInformation::OSVERSIONINFOW;
use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID; use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID;
/// Returns true if running on Windows 10 (not Windows 11)
fn is_windows_10() -> bool {
unsafe {
let mut info = OSVERSIONINFOW {
dwOSVersionInfoSize: std::mem::size_of::<OSVERSIONINFOW>() as u32,
..Default::default()
};
if RtlGetVersion(&mut info).is_ok() {
// Windows 10 has build numbers < 22000, Windows 11 >= 22000
info.dwBuildNumber < 22000 && info.dwMajorVersion == 10
} else {
false
}
}
}
pub fn ensure_terminal_shown() -> Result<()> { pub fn ensure_terminal_shown() -> Result<()> {
unsafe { unsafe {
if !GetConsoleWindow().is_invalid() { if !GetConsoleWindow().is_invalid() {
@ -29,6 +47,14 @@ pub fn ensure_terminal_shown() -> Result<()> {
} }
if std::env::var("ANKI_IMPLICIT_CONSOLE").is_ok() && attach_to_parent_console() { if std::env::var("ANKI_IMPLICIT_CONSOLE").is_ok() && attach_to_parent_console() {
// This black magic triggers Windows to switch to the new
// ANSI-supporting console host, which is usually only available
// when the app is built with the console subsystem.
// Only needed on Windows 10, not Windows 11.
if is_windows_10() {
let _ = Command::new("cmd").args(["/C", ""]).status();
}
// Successfully attached to parent console // Successfully attached to parent console
reconnect_stdio_to_console(); reconnect_stdio_to_console();
return Ok(()); return Ok(());

View file

@ -24,7 +24,7 @@ Name "Anki"
Unicode true Unicode true
; The file to write (relative to nsis directory) ; The file to write (relative to nsis directory)
OutFile "..\launcher_exe\anki-install.exe" OutFile "..\launcher_exe\anki-launcher-ANKI_VERSION-windows.exe"
; Non elevated ; Non elevated
RequestExecutionLevel user RequestExecutionLevel user
@ -214,7 +214,7 @@ Section ""
; Write the uninstall keys for Windows ; Write the uninstall keys for Windows
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "DisplayName" "Anki Launcher" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "DisplayName" "Anki Launcher"
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "DisplayVersion" "1.0.0" WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "DisplayVersion" "ANKI_VERSION"
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "UninstallString" '"$INSTDIR\uninstall.exe"'
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S' WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S'
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "NoModify" 1 WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Anki" "NoModify" 1

View file

@ -40,8 +40,8 @@ qt67 = [
qt = [ qt = [
"pyqt6==6.9.1", "pyqt6==6.9.1",
"pyqt6-qt6==6.9.1", "pyqt6-qt6==6.9.1",
"pyqt6-webengine==6.9.0", "pyqt6-webengine==6.8.0",
"pyqt6-webengine-qt6==6.9.1", "pyqt6-webengine-qt6==6.8.2",
"pyqt6_sip==13.10.2", "pyqt6_sip==13.10.2",
] ]
qt68 = [ qt68 = [

View file

@ -4,7 +4,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="ts"> <script lang="ts">
import * as tr from "@generated/ftl"; import * as tr from "@generated/ftl";
import { isApplePlatform } from "@tslib/platform"; import { chromiumVersion, isApplePlatform } from "@tslib/platform";
import { getPlatformString } from "@tslib/shortcuts"; import { getPlatformString } from "@tslib/shortcuts";
import { createEventDispatcher } from "svelte"; import { createEventDispatcher } from "svelte";
import { get } from "svelte/store"; import { get } from "svelte/store";
@ -22,9 +22,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const { focusedInput, fields } = noteEditorContext.get(); const { focusedInput, fields } = noteEditorContext.get();
// Workaround for Cmd+Option+Shift+C not working on macOS. The keyup approach works // Workaround for Cmd+Option+Shift+C not working on macOS on older Chromium
// on Linux as well, but fails on Windows. // versions.
const event = isApplePlatform() ? "keyup" : "keydown"; const chromiumVer = chromiumVersion();
const event =
isApplePlatform() && chromiumVer != null && chromiumVer <= 112
? "keyup"
: "keydown";
const clozePattern = /\{\{c(\d+)::/gu; const clozePattern = /\{\{c(\d+)::/gu;
function getCurrentHighestCloze(increment: boolean): number { function getCurrentHighestCloze(increment: boolean): number {

View file

@ -13,3 +13,20 @@ export function isApplePlatform(): boolean {
export function isDesktop(): boolean { export function isDesktop(): boolean {
return !(/iphone|ipad|ipod|android/i.test(window.navigator.userAgent)); return !(/iphone|ipad|ipod|android/i.test(window.navigator.userAgent));
} }
export function chromiumVersion(): number | null {
const userAgent = window.navigator.userAgent;
// Check if it's a Chromium-based browser (Chrome, Edge, Opera, etc.)
// but exclude Safari which also contains "Chrome" in its user agent
if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) {
return null; // Safari
}
const chromeMatch = userAgent.match(/Chrome\/(\d+)/);
if (chromeMatch) {
return parseInt(chromeMatch[1], 10);
}
return null; // Not a Chromium-based browser
}

48
uv.lock
View file

@ -66,7 +66,7 @@ requires-dist = [
{ name = "distro", marker = "sys_platform != 'darwin' and sys_platform != 'win32'" }, { name = "distro", marker = "sys_platform != 'darwin' and sys_platform != 'win32'" },
{ name = "markdown" }, { name = "markdown" },
{ name = "orjson" }, { name = "orjson" },
{ name = "protobuf", specifier = ">=4.21" }, { name = "protobuf", specifier = ">=6.0,<8.0" },
{ name = "requests", extras = ["socks"] }, { name = "requests", extras = ["socks"] },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
@ -170,8 +170,8 @@ dependencies = [
{ name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" }, { name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
{ name = "pyqt6-webengine", version = "6.6.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt66' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6-webengine", version = "6.6.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt66' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
{ name = "pyqt6-webengine", version = "6.7.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt67' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6-webengine", version = "6.7.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt67' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
{ name = "pyqt6-webengine", version = "6.8.0", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6-webengine", version = "6.8.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or extra == 'extra-3-aqt-qt68' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67')" },
{ name = "pyqt6-webengine", version = "6.9.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" }, { name = "pyqt6-webengine", version = "6.9.0", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
{ name = "pywin32", marker = "sys_platform == 'win32' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" }, { name = "pywin32", marker = "sys_platform == 'win32' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
{ name = "requests" }, { name = "requests" },
{ name = "send2trash" }, { name = "send2trash" },
@ -186,8 +186,8 @@ qt = [
{ name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } },
{ name = "pyqt6-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } },
{ name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" } },
{ name = "pyqt6-webengine", version = "6.9.0", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-webengine", version = "6.8.0", source = { registry = "https://pypi.org/simple" } },
{ name = "pyqt6-webengine-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-webengine-qt6", version = "6.8.2", source = { registry = "https://pypi.org/simple" } },
] ]
qt66 = [ qt66 = [
{ name = "pyqt6", version = "6.6.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6", version = "6.6.1", source = { registry = "https://pypi.org/simple" } },
@ -234,11 +234,11 @@ requires-dist = [
{ name = "pyqt6-sip", marker = "extra == 'qt67'", specifier = "==13.10.2" }, { name = "pyqt6-sip", marker = "extra == 'qt67'", specifier = "==13.10.2" },
{ name = "pyqt6-sip", marker = "extra == 'qt68'", specifier = "==13.10.2" }, { name = "pyqt6-sip", marker = "extra == 'qt68'", specifier = "==13.10.2" },
{ name = "pyqt6-webengine", specifier = ">=6.2" }, { name = "pyqt6-webengine", specifier = ">=6.2" },
{ name = "pyqt6-webengine", marker = "extra == 'qt'", specifier = "==6.9.0" }, { name = "pyqt6-webengine", marker = "extra == 'qt'", specifier = "==6.8.0" },
{ name = "pyqt6-webengine", marker = "extra == 'qt66'", specifier = "==6.6.0" }, { name = "pyqt6-webengine", marker = "extra == 'qt66'", specifier = "==6.6.0" },
{ name = "pyqt6-webengine", marker = "extra == 'qt67'", specifier = "==6.7.0" }, { name = "pyqt6-webengine", marker = "extra == 'qt67'", specifier = "==6.7.0" },
{ name = "pyqt6-webengine", marker = "extra == 'qt68'", specifier = "==6.8.0" }, { name = "pyqt6-webengine", marker = "extra == 'qt68'", specifier = "==6.8.0" },
{ name = "pyqt6-webengine-qt6", marker = "extra == 'qt'", specifier = "==6.9.1" }, { name = "pyqt6-webengine-qt6", marker = "extra == 'qt'", specifier = "==6.8.2" },
{ name = "pyqt6-webengine-qt6", marker = "extra == 'qt66'", specifier = "==6.6.2" }, { name = "pyqt6-webengine-qt6", marker = "extra == 'qt66'", specifier = "==6.6.2" },
{ name = "pyqt6-webengine-qt6", marker = "extra == 'qt67'", specifier = "==6.7.3" }, { name = "pyqt6-webengine-qt6", marker = "extra == 'qt67'", specifier = "==6.7.3" },
{ name = "pyqt6-webengine-qt6", marker = "extra == 'qt68'", specifier = "==6.8.1" }, { name = "pyqt6-webengine-qt6", marker = "extra == 'qt68'", specifier = "==6.8.1" },
@ -535,7 +535,7 @@ name = "importlib-metadata"
version = "8.7.0" version = "8.7.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "zipp" }, { name = "zipp", marker = "python_full_version < '3.10' or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" }
wheels = [ wheels = [
@ -1017,8 +1017,8 @@ resolution-markers = [
"python_full_version < '3.10'", "python_full_version < '3.10'",
] ]
dependencies = [ dependencies = [
{ name = "pyqt6-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
{ name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/32/1b/567f46eb43ca961efd38d7a0b73efb70d7342854f075fd919179fdb2a571/pyqt6-6.9.1.tar.gz", hash = "sha256:50642be03fb40f1c2111a09a1f5a0f79813e039c15e78267e6faaf8a96c1c3a6", size = 1067230, upload-time = "2025-06-06T08:49:30.307Z" } sdist = { url = "https://files.pythonhosted.org/packages/32/1b/567f46eb43ca961efd38d7a0b73efb70d7342854f075fd919179fdb2a571/pyqt6-6.9.1.tar.gz", hash = "sha256:50642be03fb40f1c2111a09a1f5a0f79813e039c15e78267e6faaf8a96c1c3a6", size = 1067230, upload-time = "2025-06-06T08:49:30.307Z" }
wheels = [ wheels = [
@ -1229,8 +1229,10 @@ resolution-markers = [
] ]
dependencies = [ dependencies = [
{ name = "pyqt6", version = "6.8.0", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6", version = "6.8.0", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" },
{ name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
{ name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or extra == 'extra-3-aqt-qt68' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67')" },
{ name = "pyqt6-webengine-qt6", version = "6.8.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" }, { name = "pyqt6-webengine-qt6", version = "6.8.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra != 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68')" },
{ name = "pyqt6-webengine-qt6", version = "6.8.2", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-3-aqt-qt' or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68')" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/cd/c8/cadaa950eaf97f29e48c435e274ea5a81c051e745a3e2f5d9d994b7a6cda/PyQt6_WebEngine-6.8.0.tar.gz", hash = "sha256:64045ea622b6a41882c2b18f55ae9714b8660acff06a54e910eb72822c2f3ff2", size = 34203, upload-time = "2024-12-12T15:34:35.573Z" } sdist = { url = "https://files.pythonhosted.org/packages/cd/c8/cadaa950eaf97f29e48c435e274ea5a81c051e745a3e2f5d9d994b7a6cda/PyQt6_WebEngine-6.8.0.tar.gz", hash = "sha256:64045ea622b6a41882c2b18f55ae9714b8660acff06a54e910eb72822c2f3ff2", size = 34203, upload-time = "2024-12-12T15:34:35.573Z" }
wheels = [ wheels = [
@ -1252,9 +1254,9 @@ resolution-markers = [
"python_full_version < '3.10'", "python_full_version < '3.10'",
] ]
dependencies = [ dependencies = [
{ name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
{ name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-sip", version = "13.10.2", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
{ name = "pyqt6-webengine-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" } }, { name = "pyqt6-webengine-qt6", version = "6.9.1", source = { registry = "https://pypi.org/simple" }, marker = "(extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt66') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt67') or (extra == 'extra-3-aqt-qt66' and extra == 'extra-3-aqt-qt68') or (extra == 'extra-3-aqt-qt67' and extra == 'extra-3-aqt-qt68') or (extra != 'extra-3-aqt-qt' and extra != 'extra-3-aqt-qt66' and extra != 'extra-3-aqt-qt67' and extra != 'extra-3-aqt-qt68')" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/8f/1a/9971af004a7e859347702f816fb71ecd67c3e32b2f0ae8daf1c1ded99f62/pyqt6_webengine-6.9.0.tar.gz", hash = "sha256:6ae537e3bbda06b8e06535e4852297e0bc3b00543c47929541fcc9b11981aa25", size = 34616, upload-time = "2025-04-08T08:57:35.402Z" } sdist = { url = "https://files.pythonhosted.org/packages/8f/1a/9971af004a7e859347702f816fb71ecd67c3e32b2f0ae8daf1c1ded99f62/pyqt6_webengine-6.9.0.tar.gz", hash = "sha256:6ae537e3bbda06b8e06535e4852297e0bc3b00543c47929541fcc9b11981aa25", size = 34616, upload-time = "2025-04-08T08:57:35.402Z" }
wheels = [ wheels = [
@ -1321,6 +1323,24 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b0/b5/a641ebe3e5113bee23d911c58fdd2e65061a6e3786a26b068468b988e5d2/PyQt6_WebEngine_Qt6-6.8.1-py3-none-win_amd64.whl", hash = "sha256:0ced2a10433da2571cfa29ed882698e0e164184d54068d17ba73799c45af5f0f", size = 95657750, upload-time = "2024-12-06T13:47:43.048Z" }, { url = "https://files.pythonhosted.org/packages/b0/b5/a641ebe3e5113bee23d911c58fdd2e65061a6e3786a26b068468b988e5d2/PyQt6_WebEngine_Qt6-6.8.1-py3-none-win_amd64.whl", hash = "sha256:0ced2a10433da2571cfa29ed882698e0e164184d54068d17ba73799c45af5f0f", size = 95657750, upload-time = "2024-12-06T13:47:43.048Z" },
] ]
[[package]]
name = "pyqt6-webengine-qt6"
version = "6.8.2"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"python_full_version >= '3.12'",
"python_full_version == '3.11.*'",
"python_full_version == '3.10.*'",
"python_full_version < '3.10'",
]
wheels = [
{ url = "https://files.pythonhosted.org/packages/5a/da/639523b821d68a253f7fb2a8a4f2b277f5a03e9adba5a9cfcc2aa1aa9ed1/PyQt6_WebEngine_Qt6-6.8.2-py3-none-macosx_10_14_x86_64.whl", hash = "sha256:84312705615b5fccedb386531bbd505eb110469444d778f09acd6a214836789e", size = 113127300, upload-time = "2025-02-06T12:05:55.965Z" },
{ url = "https://files.pythonhosted.org/packages/df/bd/33b89cc7cdf54d172be3f98746273b4b6fba73b4802a2e5a6fa757951b47/PyQt6_WebEngine_Qt6-6.8.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:672363b3809973bbe3408048fc49e98f5c54db8629e855d813fd531e05929007", size = 101984083, upload-time = "2025-02-06T12:06:09.736Z" },
{ url = "https://files.pythonhosted.org/packages/91/90/2693e9de1f064ac7cc10ba25548bbab6ce45a163eef07a22db3ff5ce8b81/PyQt6_WebEngine_Qt6-6.8.2-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:c3be75ef7563b965306de53cae0b357438672d3bf7d9b39edacc307fbeb9965e", size = 105210886, upload-time = "2025-02-06T12:06:23.944Z" },
{ url = "https://files.pythonhosted.org/packages/42/8a/f30075726c8ac391b6fbbc7ab043795ec79f56e452e9d835b883576738b2/PyQt6_WebEngine_Qt6-6.8.2-py3-none-manylinux_2_39_aarch64.whl", hash = "sha256:72c1b4c45a3226f32f6c821ee474c4418727913536a62506d9787e24a46d6f27", size = 101194628, upload-time = "2025-02-06T12:06:37.196Z" },
{ url = "https://files.pythonhosted.org/packages/f3/2a/4fe2bfd3a1ed0e27d1b8f32a5259ebe966432365391c9a541f290f5438de/PyQt6_WebEngine_Qt6-6.8.2-py3-none-win_amd64.whl", hash = "sha256:4421159f3ac4a796499b7f73e98028797a4ae636b04f920b8165308ca0b8c629", size = 95573175, upload-time = "2025-02-06T12:06:49.642Z" },
]
[[package]] [[package]]
name = "pyqt6-webengine-qt6" name = "pyqt6-webengine-qt6"
version = "6.9.1" version = "6.9.1"