mirror of
https://github.com/csd4ni3l/fractal-viewer.git
synced 2026-01-01 12:13:43 +01:00
Compare commits
6 Commits
9424bf589a
...
50d1281678
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50d1281678 | ||
|
|
3efb998add | ||
|
|
b6d1b64106 | ||
|
|
73cf6ced71 | ||
|
|
5b2222baaa | ||
|
|
5ef274f60d |
94
.github/workflows/main.yml
vendored
94
.github/workflows/main.yml
vendored
@@ -8,7 +8,13 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
include:
|
||||||
|
- os: ubuntu-22.04
|
||||||
|
platform: linux
|
||||||
|
python-version: "3.11"
|
||||||
|
- os: windows-latest
|
||||||
|
platform: windows
|
||||||
|
python-version: "3.11"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check-out repository
|
- name: Check-out repository
|
||||||
@@ -35,58 +41,78 @@ jobs:
|
|||||||
disable-plugins: tk-inter,dill-compat,eventlet,gevent,pyqt5,pyqt6,pyside2,pyside6,delvewheel,pywebview,matplotlib,spacy,enum-compat,pbr-compat,gevent,pmw-freezer,transformers,upx,kivy,options-nanny,multiprocessing,gi
|
disable-plugins: tk-inter,dill-compat,eventlet,gevent,pyqt5,pyqt6,pyside2,pyside6,delvewheel,pywebview,matplotlib,spacy,enum-compat,pbr-compat,gevent,pmw-freezer,transformers,upx,kivy,options-nanny,multiprocessing,gi
|
||||||
include-data-dir: assets=assets
|
include-data-dir: assets=assets
|
||||||
include-data-files: CREDITS=CREDITS
|
include-data-files: CREDITS=CREDITS
|
||||||
mode: standalone
|
mode: onefile
|
||||||
output-file: FractalViewer
|
output-file: FractalViewer
|
||||||
|
|
||||||
- name: Zip Build Output
|
- name: Locate and rename executable (Linux)
|
||||||
shell: bash
|
if: matrix.os == 'ubuntu-22.04'
|
||||||
run: |
|
run: |
|
||||||
mkdir -p zip_output
|
set -euo pipefail
|
||||||
if [ "${{ runner.os }}" = "Windows" ]; then
|
echo "Searching for built Linux binary..."
|
||||||
powershell.exe -Command "Compress-Archive -Path 'build/run.dist/*' -DestinationPath 'zip_output/FractalViewer-${{ runner.os }}.zip'"
|
# List to help debugging when paths change
|
||||||
else
|
ls -laR . | head -n 500 || true
|
||||||
cd build/run.dist
|
BIN=$(find . -maxdepth 4 -type f -name 'FractalViewer*' -perm -u+x | head -n1 || true)
|
||||||
zip -r "../../zip_output/FractalViewer-${{ runner.os }}.zip" .
|
if [ -z "${BIN}" ]; then
|
||||||
|
echo "ERROR: No Linux binary found after build"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
echo "Found: ${BIN}"
|
||||||
|
mkdir -p build_output
|
||||||
|
cp "${BIN}" build_output/FractalViewer.bin
|
||||||
|
chmod +x build_output/FractalViewer.bin
|
||||||
|
echo "Executable ready: build_output/FractalViewer.bin"
|
||||||
|
shell: bash
|
||||||
|
|
||||||
- name: Upload Zipped Build Artifact
|
- name: Locate and rename executable (Windows)
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: |
|
||||||
|
Write-Host "Searching for built Windows binary..."
|
||||||
|
Get-ChildItem -Recurse -File -Filter 'FractalViewer*.exe' | Select-Object -First 1 | ForEach-Object {
|
||||||
|
Write-Host ("Found: " + $_.FullName)
|
||||||
|
New-Item -ItemType Directory -Force -Path build_output | Out-Null
|
||||||
|
Copy-Item $_.FullName "build_output\FractalViewer.exe"
|
||||||
|
Write-Host "Executable ready: build_output\FractalViewer.exe"
|
||||||
|
}
|
||||||
|
if (!(Test-Path build_output\FractalViewer.exe)) {
|
||||||
|
Write-Error "ERROR: No Windows binary found after build"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
- name: Upload build artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: FractalViewer-${{ runner.os }}.zip
|
name: ${{ matrix.platform }}
|
||||||
path: zip_output/FractalViewer-${{ runner.os }}.zip
|
path: build_output/FractalViewer.*
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Create GitHub Release
|
|
||||||
needs: build
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: build
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Download All Zipped Builds
|
- name: Download All Build Artifacts
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: downloads
|
path: downloads
|
||||||
|
|
||||||
- name: Delete Old Release (if exists)
|
- name: Create release (if missing) and upload artifacts to tag
|
||||||
continue-on-error: true
|
|
||||||
run: gh release delete latest -y
|
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Delete Git tag (if exists)
|
|
||||||
continue-on-error: true
|
|
||||||
run: |
|
run: |
|
||||||
git push origin :refs/tags/latest
|
set -euo pipefail
|
||||||
git tag -d latest
|
TAG="latest"
|
||||||
|
echo "Target release tag: $TAG"
|
||||||
- name: Recreate Git tag at HEAD
|
if gh release view "$TAG" >/dev/null 2>&1; then
|
||||||
run: |
|
echo "Release $TAG already exists; will upload assets with --clobber"
|
||||||
git tag latest
|
else
|
||||||
git push origin latest
|
gh release create "$TAG" \
|
||||||
|
--title "$TAG" \
|
||||||
- name: Create the new release
|
--notes "Automated build for $TAG"
|
||||||
run: gh release create latest downloads/**/FractalViewer-*.zip --title "Latest Build" --notes "Most recent multi-platform builds of FractalViewer"
|
fi
|
||||||
env:
|
# Upload the executables directly (no zip files)
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
gh release upload "$TAG" downloads/linux/FractalViewer.bin --clobber
|
||||||
|
gh release upload "$TAG" downloads/windows/FractalViewer.exe --clobber
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import arcade, arcade.gui, pyglet, json
|
import arcade, arcade.gui, pyglet, json
|
||||||
|
|
||||||
|
from mpmath import mpc
|
||||||
|
|
||||||
from game.shader import create_iter_calc_shader
|
from game.shader import create_iter_calc_shader
|
||||||
from utils.constants import button_style, initial_real_imag
|
from utils.constants import button_style, initial_real_imag
|
||||||
from utils.preload import button_texture, button_hovered_texture, cursor_texture
|
from utils.preload import button_texture, button_hovered_texture, cursor_texture
|
||||||
@@ -14,14 +16,27 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
with open("settings.json", "r") as file:
|
with open("settings.json", "r") as file:
|
||||||
self.settings_dict = json.load(file)
|
self.settings_dict = json.load(file)
|
||||||
|
|
||||||
self.escape_radius = int(self.settings_dict.get(f"{self.fractal_name}_escape_radius", 2))
|
self.escape_radius = int(
|
||||||
self.real_min, self.real_max, self.imag_min, self.imag_max = initial_real_imag[fractal_name] if fractal_name != "julia" else (-self.escape_radius, self.escape_radius, -self.escape_radius, self.escape_radius)
|
self.settings_dict.get(f"{self.fractal_name}_escape_radius", 2)
|
||||||
|
)
|
||||||
|
self.real_min, self.real_max, self.imag_min, self.imag_max = (
|
||||||
|
initial_real_imag[fractal_name]
|
||||||
|
if fractal_name != "julia"
|
||||||
|
else (
|
||||||
|
-self.escape_radius,
|
||||||
|
self.escape_radius,
|
||||||
|
-self.escape_radius,
|
||||||
|
self.escape_radius,
|
||||||
|
)
|
||||||
|
)
|
||||||
self.max_iter = self.settings_dict.get(f"{self.fractal_name}_max_iter", 200)
|
self.max_iter = self.settings_dict.get(f"{self.fractal_name}_max_iter", 200)
|
||||||
self.zoom = 1.0
|
self.zoom = 1.0
|
||||||
self.zoom_start_position = ()
|
self.zoom_start_position = ()
|
||||||
self.zoom_rect = None
|
self.zoom_rect = None
|
||||||
self.has_controller = False
|
self.has_controller = False
|
||||||
self.dragging_with_controller = False
|
self.dragging_with_controller = False
|
||||||
|
self.center_real = self.real_min + 0.5 * (self.real_max - self.real_min)
|
||||||
|
self.center_imag = self.imag_min + 0.5 * (self.imag_max - self.imag_min)
|
||||||
|
|
||||||
def on_show_view(self):
|
def on_show_view(self):
|
||||||
super().on_show_view()
|
super().on_show_view()
|
||||||
@@ -31,33 +46,66 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
self.window.width,
|
self.window.width,
|
||||||
self.window.height,
|
self.window.height,
|
||||||
self.settings_dict.get(f"{self.fractal_name}_precision", "Single").lower(),
|
self.settings_dict.get(f"{self.fractal_name}_precision", "Single").lower(),
|
||||||
int(self.settings_dict.get(f"{self.fractal_name}_n", 2)), # This will work for non-exponentiable fractals as well because they dont have an _n property
|
int(
|
||||||
|
self.settings_dict.get(f"{self.fractal_name}_n", 2)
|
||||||
|
), # This will work for non-exponentiable fractals as well because they dont have an _n property
|
||||||
int(self.settings_dict.get(f"{self.fractal_name}_escape_radius", 2)),
|
int(self.settings_dict.get(f"{self.fractal_name}_escape_radius", 2)),
|
||||||
self.settings_dict.get("julia_type", "Classic swirling")
|
self.settings_dict.get("julia_type", "Classic swirling"),
|
||||||
|
False,
|
||||||
|
mpc(self.real_min, self.imag_min),
|
||||||
|
int(self.max_iter),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.fractal_sprite = pyglet.sprite.Sprite(img=self.fractal_image)
|
self.fractal_sprite = pyglet.sprite.Sprite(img=self.fractal_image)
|
||||||
|
|
||||||
self.create_image()
|
self.create_image()
|
||||||
|
|
||||||
self.pypresence_client.update(state=f'Viewing {self.fractal_name.replace("_", " ").capitalize()}', details=f'Zoom: {self.zoom}\nMax Iterations: {self.max_iter}', start=self.pypresence_client.start_time)
|
self.pypresence_client.update(
|
||||||
|
state=f"Viewing {self.fractal_name.replace('_', ' ').capitalize()}",
|
||||||
|
details=f"Zoom: {self.zoom}\nMax Iterations: {self.max_iter}",
|
||||||
|
start=self.pypresence_client.start_time,
|
||||||
|
)
|
||||||
|
|
||||||
self.setup_ui()
|
self.setup_ui()
|
||||||
|
|
||||||
def main_exit(self):
|
def main_exit(self):
|
||||||
from menus.main import Main
|
from menus.main import Main
|
||||||
|
|
||||||
self.window.show_view(Main(self.pypresence_client))
|
self.window.show_view(Main(self.pypresence_client))
|
||||||
|
|
||||||
def setup_ui(self):
|
def setup_ui(self):
|
||||||
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
|
self.anchor = self.add_widget(arcade.gui.UIAnchorLayout(size_hint=(1, 1)))
|
||||||
|
|
||||||
self.info_box = self.anchor.add(arcade.gui.UIBoxLayout(space_between=10, vertical=False), anchor_x="center", anchor_y="top")
|
self.info_box = self.anchor.add(
|
||||||
self.zoom_label = self.info_box.add(arcade.gui.UILabel(text=f"Zoom: {self.zoom}", font_name="Roboto", font_size=16))
|
arcade.gui.UIBoxLayout(space_between=10, vertical=False),
|
||||||
self.max_iter_label = self.info_box.add(arcade.gui.UILabel(text=f"Max Iterations: {self.max_iter}", font_name="Roboto", font_size=16))
|
anchor_x="center",
|
||||||
|
anchor_y="top",
|
||||||
|
)
|
||||||
|
self.zoom_label = self.info_box.add(
|
||||||
|
arcade.gui.UILabel(
|
||||||
|
text=f"Zoom: {self.zoom}", font_name="Roboto", font_size=16
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.max_iter_label = self.info_box.add(
|
||||||
|
arcade.gui.UILabel(
|
||||||
|
text=f"Max Iterations: {self.max_iter}",
|
||||||
|
font_name="Roboto",
|
||||||
|
font_size=16,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.back_button = arcade.gui.UITextureButton(texture=button_texture, texture_hovered=button_hovered_texture, text='<--', style=button_style, width=100, height=50)
|
self.back_button = arcade.gui.UITextureButton(
|
||||||
|
texture=button_texture,
|
||||||
|
texture_hovered=button_hovered_texture,
|
||||||
|
text="<--",
|
||||||
|
style=button_style,
|
||||||
|
width=100,
|
||||||
|
height=50,
|
||||||
|
)
|
||||||
self.back_button.on_click = lambda event: self.main_exit()
|
self.back_button.on_click = lambda event: self.main_exit()
|
||||||
self.anchor.add(self.back_button, anchor_x="left", anchor_y="top", align_x=5, align_y=-5)
|
self.anchor.add(
|
||||||
|
self.back_button, anchor_x="left", anchor_y="top", align_x=5, align_y=-5
|
||||||
|
)
|
||||||
|
|
||||||
if self.window.get_controllers():
|
if self.window.get_controllers():
|
||||||
self.sprite_list = arcade.SpriteList()
|
self.sprite_list = arcade.SpriteList()
|
||||||
@@ -67,7 +115,10 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
|
|
||||||
def on_button_press(self, controller, button_name):
|
def on_button_press(self, controller, button_name):
|
||||||
if button_name == "a":
|
if button_name == "a":
|
||||||
self.zoom_start_position = self.cursor_sprite.center_x, self.cursor_sprite.center_y
|
self.zoom_start_position = (
|
||||||
|
self.cursor_sprite.center_x,
|
||||||
|
self.cursor_sprite.center_y,
|
||||||
|
)
|
||||||
self.dragging_with_controller = True
|
self.dragging_with_controller = True
|
||||||
elif button_name == "start":
|
elif button_name == "start":
|
||||||
self.main_exit()
|
self.main_exit()
|
||||||
@@ -75,26 +126,55 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
def on_button_release(self, controller, button_name):
|
def on_button_release(self, controller, button_name):
|
||||||
if button_name == "a" and self.dragging_with_controller:
|
if button_name == "a" and self.dragging_with_controller:
|
||||||
self.dragging_with_controller = False
|
self.dragging_with_controller = False
|
||||||
self.on_mouse_release(self.cursor_sprite.center_x, self.cursor_sprite.center_y, None, None)
|
self.on_mouse_release(
|
||||||
|
self.cursor_sprite.center_x, self.cursor_sprite.center_y, None, None
|
||||||
|
)
|
||||||
|
|
||||||
def on_stick_motion(self, controller, name, vector):
|
def on_stick_motion(self, controller, name, vector):
|
||||||
if name == "leftstick":
|
if name == "leftstick":
|
||||||
self.cursor_sprite.center_x += vector.x * 5
|
self.cursor_sprite.center_x += vector.x * 5
|
||||||
self.cursor_sprite.center_y += vector.y * 5
|
self.cursor_sprite.center_y += vector.y * 5
|
||||||
if self.dragging_with_controller:
|
if self.dragging_with_controller:
|
||||||
self.on_mouse_drag(self.cursor_sprite.center_x, self.cursor_sprite.center_y, 0, 0, None, None)
|
self.on_mouse_drag(
|
||||||
|
self.cursor_sprite.center_x,
|
||||||
|
self.cursor_sprite.center_y,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
def create_image(self):
|
def create_image(self):
|
||||||
with self.shader_program:
|
with self.shader_program:
|
||||||
self.shader_program['u_maxIter'] = int(self.max_iter)
|
self.shader_program["u_maxIter"] = int(self.max_iter)
|
||||||
self.shader_program['u_resolution'] = (self.window.width, self.window.height)
|
self.shader_program["u_resolution"] = (
|
||||||
self.shader_program['u_real_range'] = (self.real_min, self.real_max)
|
self.window.width,
|
||||||
self.shader_program['u_imag_range'] = (self.imag_min, self.imag_max)
|
self.window.height,
|
||||||
self.shader_program.dispatch(self.fractal_image.width, self.fractal_image.height, 1, barrier=pyglet.gl.GL_ALL_BARRIER_BITS)
|
)
|
||||||
|
self.shader_program["u_real_range"] = (self.real_min, self.real_max)
|
||||||
|
self.shader_program["u_imag_range"] = (self.imag_min, self.imag_max)
|
||||||
|
# TODO: fix preturbation
|
||||||
|
# self.shader_program["u_center"] = (self.center_real, self.center_imag)
|
||||||
|
# self.shader_program["usepreturbation"] = False
|
||||||
|
self.shader_program.dispatch(
|
||||||
|
self.fractal_image.width,
|
||||||
|
self.fractal_image.height,
|
||||||
|
1,
|
||||||
|
barrier=pyglet.gl.GL_ALL_BARRIER_BITS,
|
||||||
|
)
|
||||||
|
|
||||||
def on_key_press(self, symbol, modifiers):
|
def on_key_press(self, symbol, modifiers):
|
||||||
if symbol == arcade.key.ESCAPE:
|
if symbol == arcade.key.ESCAPE:
|
||||||
self.real_min, self.real_max, self.imag_min, self.imag_max = initial_real_imag[self.fractal_name] if self.fractal_name != "julia" else (-self.escape_radius, self.escape_radius, -self.escape_radius, self.escape_radius)
|
self.real_min, self.real_max, self.imag_min, self.imag_max = (
|
||||||
|
initial_real_imag[self.fractal_name]
|
||||||
|
if self.fractal_name != "julia"
|
||||||
|
else (
|
||||||
|
-self.escape_radius,
|
||||||
|
self.escape_radius,
|
||||||
|
-self.escape_radius,
|
||||||
|
self.escape_radius,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
self.zoom = 1
|
self.zoom = 1
|
||||||
|
|
||||||
@@ -106,9 +186,9 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
self.create_image()
|
self.create_image()
|
||||||
|
|
||||||
self.pypresence_client.update(
|
self.pypresence_client.update(
|
||||||
state=f'Viewing {self.fractal_name.replace("_", " ").capitalize()}',
|
state=f"Viewing {self.fractal_name.replace('_', ' ').capitalize()}",
|
||||||
details=f'Zoom: {self.zoom:.2f}\nMax Iterations: {self.max_iter}',
|
details=f"Zoom: {self.zoom:.2f}\nMax Iterations: {self.max_iter}",
|
||||||
start=self.pypresence_client.start_time
|
start=self.pypresence_client.start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_mouse_drag(self, x, y, dx, dy, _buttons, _modifiers):
|
def on_mouse_drag(self, x, y, dx, dy, _buttons, _modifiers):
|
||||||
@@ -137,7 +217,9 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
bottom = min(y0, y1)
|
bottom = min(y0, y1)
|
||||||
top = max(y0, y1)
|
top = max(y0, y1)
|
||||||
|
|
||||||
self.zoom_rect = arcade.rect.LRBT(left=left, right=right, top=top, bottom=bottom)
|
self.zoom_rect = arcade.rect.LRBT(
|
||||||
|
left=left, right=right, top=top, bottom=bottom
|
||||||
|
)
|
||||||
|
|
||||||
def on_mouse_release(self, x, y, button, modifiers):
|
def on_mouse_release(self, x, y, button, modifiers):
|
||||||
if self.zoom_start_position and self.zoom_rect:
|
if self.zoom_start_position and self.zoom_rect:
|
||||||
@@ -146,18 +228,29 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
center_x = (rect.left + rect.right) / 2
|
center_x = (rect.left + rect.right) / 2
|
||||||
center_y = (rect.bottom + rect.top) / 2
|
center_y = (rect.bottom + rect.top) / 2
|
||||||
|
|
||||||
center_real = self.real_min + (center_x / self.width) * (self.real_max - self.real_min)
|
self.center_real = self.real_min + (center_x / self.width) * (
|
||||||
center_imag = self.imag_min + (center_y / self.height) * (self.imag_max - self.imag_min)
|
self.real_max - self.real_min
|
||||||
|
)
|
||||||
|
self.center_imag = self.imag_min + (center_y / self.height) * (
|
||||||
|
self.imag_max - self.imag_min
|
||||||
|
)
|
||||||
|
|
||||||
real_span = (rect.right - rect.left) / self.width * (self.real_max - self.real_min)
|
real_span = (
|
||||||
imag_span = (rect.top - rect.bottom) / self.height * (self.imag_max - self.imag_min)
|
(rect.right - rect.left) / self.width * (self.real_max - self.real_min)
|
||||||
|
)
|
||||||
|
imag_span = (
|
||||||
|
(rect.top - rect.bottom) / self.height * (self.imag_max - self.imag_min)
|
||||||
|
)
|
||||||
|
|
||||||
self.real_min = center_real - real_span / 2
|
self.real_min = self.center_real - real_span / 2
|
||||||
self.real_max = center_real + real_span / 2
|
self.real_max = self.center_real + real_span / 2
|
||||||
self.imag_min = center_imag - imag_span / 2
|
self.imag_min = self.center_imag - imag_span / 2
|
||||||
self.imag_max = center_imag + imag_span / 2
|
self.imag_max = self.center_imag + imag_span / 2
|
||||||
|
|
||||||
initial_real_range = initial_real_imag[self.fractal_name][1] - initial_real_imag[self.fractal_name][0]
|
initial_real_range = (
|
||||||
|
initial_real_imag[self.fractal_name][1]
|
||||||
|
- initial_real_imag[self.fractal_name][0]
|
||||||
|
)
|
||||||
new_real_range = self.real_max - self.real_min
|
new_real_range = self.real_max - self.real_min
|
||||||
self.zoom = initial_real_range / new_real_range
|
self.zoom = initial_real_range / new_real_range
|
||||||
|
|
||||||
@@ -169,9 +262,9 @@ class IterFractalViewer(arcade.gui.UIView):
|
|||||||
self.create_image()
|
self.create_image()
|
||||||
|
|
||||||
self.pypresence_client.update(
|
self.pypresence_client.update(
|
||||||
state=f'Viewing {self.fractal_name.replace("_", " ").capitalize()}',
|
state=f"Viewing {self.fractal_name.replace('_', ' ').capitalize()}",
|
||||||
details=f'Zoom: {self.zoom:.4f}\nMax Iterations: {self.max_iter}',
|
details=f"Zoom: {self.zoom:.4f}\nMax Iterations: {self.max_iter}",
|
||||||
start=self.pypresence_client.start_time
|
start=self.pypresence_client.start_time,
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_draw(self):
|
def on_draw(self):
|
||||||
|
|||||||
208
game/preturbation.py
Normal file
208
game/preturbation.py
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
|
||||||
|
from mpmath import mp, mpc
|
||||||
|
from utils.constants import c_for_julia_type
|
||||||
|
import array, pyglet
|
||||||
|
from pyglet.gl import GL_TEXTURE_1D, GL_RG32F, GL_NEAREST
|
||||||
|
|
||||||
|
def calculate_julia_orbit(z_start, c_constant, max_iterations):
|
||||||
|
z = z_start # position
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
z = z*z + c_constant
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_multi_julia_orbit(z_start, c_constant, max_iterations, multi_n):
|
||||||
|
z = z_start # position
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
r = abs(z)
|
||||||
|
theta = mp.atan2(z.imag, z.real)
|
||||||
|
r_pow = r**multi_n
|
||||||
|
|
||||||
|
z = mpc(r_pow * mp.cos(multi_n * theta), r_pow * mp.sin(multi_n * theta)) + c_constant
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_mandelbrot_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
z = z*z + c_val
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_multibrot_orbit(c_val, max_iterations, multi_n):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
r = abs(z)
|
||||||
|
theta = mp.atan2(z.imag, z.real)
|
||||||
|
r_n = r ** multi_n
|
||||||
|
theta_n = multi_n * theta
|
||||||
|
|
||||||
|
z = mpc(r_n * mp.cos(theta_n), r_n * mp.sin(theta_n)) + c_val
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_mandelbar_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
z = z.conjugate() ** 2 + c_val
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_multi_mandelbar_orbit(c_val, max_iterations, multi_n):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
r = abs(z)
|
||||||
|
theta = mp.atan2(-z.imag, z.real)
|
||||||
|
r_n = r ** multi_n
|
||||||
|
theta_n = multi_n * theta
|
||||||
|
|
||||||
|
z = mpc(r_n * mp.cos(theta_n), r_n * mp.sin(theta_n)) + c_val
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_buffalo_fractal_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
z_squared = z * z
|
||||||
|
z_abs = mpc(abs(z_squared.real), abs(z_squared.imag))
|
||||||
|
z = z_abs + c_val
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_multi_buffalo_fractal_orbit(c_val, max_iterations, multi_n):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
r = abs(z)
|
||||||
|
theta = mp.atan2(z.imag, z.real)
|
||||||
|
r_n = r ** multi_n
|
||||||
|
theta_n = multi_n * theta
|
||||||
|
zn_real = r_n * mp.cos(theta_n)
|
||||||
|
zn_imag = r_n * mp.sin(theta_n)
|
||||||
|
|
||||||
|
z = mpc(abs(zn_real), abs(zn_imag)) + c_val
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_burning_ship_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
x = z.real
|
||||||
|
y = z.imag
|
||||||
|
|
||||||
|
xtemp = x*x - y*y + c_val.real
|
||||||
|
ytemp = abs(2 * x * y) + c_val.imag
|
||||||
|
|
||||||
|
z = mpc(xtemp, ytemp)
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_phoenix_fractal_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0, 0)
|
||||||
|
z_prev = mpc(0, 0)
|
||||||
|
p = 0.56667
|
||||||
|
orbit = [z]
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
z_new = z.conjugate() ** 2 + c_val - p * z_prev
|
||||||
|
|
||||||
|
z_prev = z
|
||||||
|
|
||||||
|
z = z_new
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_lambda_fractal_orbit(c_val, max_iterations):
|
||||||
|
z = mpc(0.5, 0)
|
||||||
|
orbit = [z]
|
||||||
|
number_reverse_complex = mpc(1, 1)
|
||||||
|
|
||||||
|
for _ in range(max_iterations):
|
||||||
|
one_minus_z = number_reverse_complex - z
|
||||||
|
|
||||||
|
temp = z * one_minus_z
|
||||||
|
|
||||||
|
z = c_val * temp
|
||||||
|
|
||||||
|
orbit.append(z)
|
||||||
|
|
||||||
|
return orbit
|
||||||
|
|
||||||
|
def calculate_orbit(fractal_type, position, max_iterations, multi_n=2, julia_type="Classic swirling"):
|
||||||
|
if fractal_type == "mandelbrot":
|
||||||
|
if int(multi_n) == 2:
|
||||||
|
orbit = calculate_mandelbrot_orbit(position, max_iterations)
|
||||||
|
else:
|
||||||
|
orbit = calculate_multibrot_orbit(position, max_iterations, multi_n)
|
||||||
|
|
||||||
|
elif fractal_type == "mandelbar":
|
||||||
|
if int(multi_n) == 2:
|
||||||
|
orbit = calculate_mandelbar_orbit(position, max_iterations)
|
||||||
|
else:
|
||||||
|
orbit = calculate_multi_mandelbar_orbit(position, max_iterations)
|
||||||
|
|
||||||
|
elif fractal_type == "phoenix_fractal":
|
||||||
|
orbit = calculate_phoenix_fractal_orbit(position, max_iterations)
|
||||||
|
|
||||||
|
elif fractal_type == "lambda_fractal":
|
||||||
|
orbit = calculate_lambda_fractal_orbit(position, max_iterations)
|
||||||
|
|
||||||
|
elif fractal_type == "julia":
|
||||||
|
if int(multi_n) == 2:
|
||||||
|
orbit = calculate_julia_orbit(position, c_for_julia_type[julia_type], max_iterations)
|
||||||
|
else:
|
||||||
|
orbit = calculate_multi_julia_orbit(position, c_for_julia_type[julia_type], max_iterations, multi_n)
|
||||||
|
|
||||||
|
elif fractal_type == "buffalo_fractal":
|
||||||
|
if int(multi_n) == 2:
|
||||||
|
orbit = calculate_buffalo_fractal_orbit(position, max_iterations)
|
||||||
|
else:
|
||||||
|
orbit = calculate_multi_buffalo_fractal_orbit(position, max_iterations)
|
||||||
|
|
||||||
|
elif fractal_type == "burning_ship":
|
||||||
|
orbit = calculate_burning_ship_orbit(position, max_iterations)
|
||||||
|
|
||||||
|
float_array = array.array('f')
|
||||||
|
|
||||||
|
for c_val in orbit:
|
||||||
|
float_array.append(float(c_val.real))
|
||||||
|
float_array.append(float(c_val.imag))
|
||||||
|
|
||||||
|
orbit_texture = pyglet.image.Texture.create(max_iterations, 1, internalformat=GL_RG32F, target=GL_TEXTURE_1D, min_filter=GL_NEAREST, mag_filter=GL_NEAREST)
|
||||||
|
orbit_image_data = pyglet.image.ImageData(max_iterations, 1, "RG", float_array.tobytes())
|
||||||
|
orbit_image_data.blit_to_texture(orbit_texture.target, orbit_texture.level, orbit_texture.anchor_x, orbit_texture.anchor_y, 0, None)
|
||||||
|
|
||||||
|
return orbit_texture
|
||||||
295
game/shader.py
295
game/shader.py
@@ -1,5 +1,8 @@
|
|||||||
import pyglet
|
import pyglet
|
||||||
|
|
||||||
from utils.constants import c_for_julia_type
|
from utils.constants import c_for_julia_type
|
||||||
|
from game.preturbation import calculate_orbit
|
||||||
|
from mpmath import mpc
|
||||||
|
|
||||||
newton_coloring = """vec4 getColor(int color_number) {{
|
newton_coloring = """vec4 getColor(int color_number) {{
|
||||||
vec4 value = vec4(0.0, 0.0, 0.0, 1.0);
|
vec4 value = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
@@ -46,12 +49,55 @@ uniform int u_maxIter;
|
|||||||
uniform vec2 u_resolution;
|
uniform vec2 u_resolution;
|
||||||
uniform vec2 u_real_range;
|
uniform vec2 u_real_range;
|
||||||
uniform vec2 u_imag_range;
|
uniform vec2 u_imag_range;
|
||||||
|
|
||||||
|
uniform vec2 u_center;
|
||||||
|
uniform sampler2D orbit;
|
||||||
|
uniform bool usepreturbation;
|
||||||
|
|
||||||
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
|
||||||
layout(location = 0, rgba32f) uniform image2D img_output;
|
layout(location = 0, rgba32f) uniform image2D img_output;
|
||||||
|
|
||||||
{coloring_func}
|
{coloring_func}
|
||||||
{iter_calc_func}
|
{iter_calc_func}
|
||||||
|
|
||||||
|
int calculate_iters({vec2type} pos) {{
|
||||||
|
int fractal_type = {fractal_type};
|
||||||
|
{vec2type} z = {initial_z};
|
||||||
|
{vec2type} c = {initial_c};
|
||||||
|
|
||||||
|
if (fractal_type != 0) {{
|
||||||
|
return int(fractal_iteration(z, c).x);
|
||||||
|
}}
|
||||||
|
|
||||||
|
int iters = 0;
|
||||||
|
float R = {escape_radius};
|
||||||
|
|
||||||
|
if (!usepreturbation) {{
|
||||||
|
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
||||||
|
z = fractal_iteration(z, c);
|
||||||
|
iters++;
|
||||||
|
}}
|
||||||
|
|
||||||
|
return iters;
|
||||||
|
}}
|
||||||
|
|
||||||
|
{vec2type} delta = c - u_center;
|
||||||
|
{vec2type} eps = {vec2type}(0.0);
|
||||||
|
{vec2type} zn = {vec2type}(0, 0);
|
||||||
|
|
||||||
|
while (dot(zn, zn) < R * R && iters < u_maxIter) {{
|
||||||
|
vec2 Z = texelFetch(orbit, ivec2(iters, 0), 0).xy;
|
||||||
|
{vec2type} eps_sq = {vec2type}(eps.x * eps.x - eps.y * eps.y, 2.0 * eps.x * eps.y);
|
||||||
|
{vec2type} term1 = {vec2type}(2.0 * Z.x * eps.x - 2.0 * Z.y * eps.y, 2.0 * Z.x * eps.y + 2.0 * Z.y * eps.x);
|
||||||
|
eps = term1 + eps_sq + delta;
|
||||||
|
zn = Z + eps;
|
||||||
|
|
||||||
|
iters++;
|
||||||
|
}}
|
||||||
|
|
||||||
|
return iters;
|
||||||
|
}}
|
||||||
|
|
||||||
{vec2type} map_pixel({floattype} x, {floattype} y, {vec2type} resolution, {vec2type} real_range, {vec2type} imag_range) {{
|
{vec2type} map_pixel({floattype} x, {floattype} y, {vec2type} resolution, {vec2type} real_range, {vec2type} imag_range) {{
|
||||||
{floattype} real = real_range.x + (x / resolution.x) * (real_range.y - real_range.x);
|
{floattype} real = real_range.x + (x / resolution.x) * (real_range.y - real_range.x);
|
||||||
{floattype} imag = imag_range.x + (y / resolution.y) * (imag_range.y - imag_range.x);
|
{floattype} imag = imag_range.x + (y / resolution.y) * (imag_range.y - imag_range.x);
|
||||||
@@ -91,172 +137,98 @@ void main() {{
|
|||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
normal_julia_calc = """int calculate_iters({vec2type} z) {{
|
normal_julia_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
float R = {escape_radius};
|
|
||||||
int n = {multi_n};
|
int n = {multi_n};
|
||||||
{vec2type} c = {vec2type}{julia_c};
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter){{
|
|
||||||
{floattype} xtemp = z.x * z.x - z.y * z.y;
|
{floattype} xtemp = z.x * z.x - z.y * z.y;
|
||||||
z.y = 2 * z.x * z.y + c.y;
|
return {vec2type}(xtemp + c.x, 2 * z.x * z.y + c.y);
|
||||||
z.x = xtemp + c.x;
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multi_julia_calc = """int calculate_iters(float z) {{
|
multi_julia_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
float R = {escape_radius};
|
{floattype} n = {floattype}({multi_n});
|
||||||
float n = float({multi_n});
|
{floattype} r = length(z);
|
||||||
float c = float({julia_c});
|
{floattype} theta = atan(z.y, z.x);
|
||||||
|
{floattype} r_pow = pow(r, n);
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
return {vec2type}(r_pow * cos(n * theta), r_pow * sin(n * theta)) + c;
|
||||||
float r = length(z);
|
|
||||||
float theta = atan(z.y, z.x);
|
|
||||||
float r_pow = pow(r, n);
|
|
||||||
|
|
||||||
z = vec2(r_pow * cos(n * theta), r_pow * sin(n * theta)) + c;
|
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mandelbrot_calc = """int calculate_iters({vec2type} c) {{
|
mandelbrot_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
{vec2type} z = {vec2type}(0.0, 0.0);
|
return {vec2type}(
|
||||||
float R = {escape_radius};
|
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
|
||||||
z = {vec2type}(
|
|
||||||
z.x * z.x - z.y * z.y + c.x,
|
z.x * z.x - z.y * z.y + c.x,
|
||||||
2.0 * z.x * z.y + c.y
|
2.0 * z.x * z.y + c.y
|
||||||
);
|
);
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multibrot_calc = """int calculate_iters(vec2 c) {{
|
multibrot_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
vec2 z = vec2(0.0);
|
{floattype} n = {multi_n};
|
||||||
float n = {multi_n};
|
{floattype} r = length(z);
|
||||||
float R = {escape_radius};
|
{floattype} theta = atan(z.y, z.x);
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
{floattype} r_n = pow(r, n);
|
||||||
float r = length(z);
|
{floattype} theta_n = n * theta;
|
||||||
float theta = atan(z.y, z.x);
|
|
||||||
|
|
||||||
float r_n = pow(r, n);
|
return r_n * {vec2type}(cos(theta_n), sin(theta_n)) + c;
|
||||||
float theta_n = n * theta;
|
|
||||||
|
|
||||||
z = r_n * vec2(cos(theta_n), sin(theta_n)) + c;
|
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
mandelbar_calc = """int calculate_iters({vec2type} c) {{
|
mandelbar_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
{vec2type} z = {vec2type}(0.0, 0.0);
|
return {vec2type}(
|
||||||
float R = {escape_radius};
|
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
|
||||||
z = {vec2type}(
|
|
||||||
z.x * z.x - z.y * z.y + c.x,
|
z.x * z.x - z.y * z.y + c.x,
|
||||||
-2.0 * z.x * z.y + c.y
|
-2.0 * z.x * z.y + c.y
|
||||||
);
|
);
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multi_mandelbar_calc = """int calculate_iters(vec2 c) {{
|
multi_mandelbar_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
vec2 z = vec2(0.0);
|
{floattype} n = {multi_n};
|
||||||
float n = {multi_n};
|
{floattype} r = length(z);
|
||||||
float R = {escape_radius};
|
{floattype} theta = atan(-z.y, z.x);
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
{floattype} r_n = pow(r, n);
|
||||||
float r = length(z);
|
{floattype} theta_n = n * theta;
|
||||||
float theta = atan(-z.y, z.x);
|
|
||||||
|
|
||||||
float r_n = pow(r, n);
|
return r_n * {vec2type}(cos(theta_n), sin(theta_n)) + c;
|
||||||
float theta_n = n * theta;
|
|
||||||
|
|
||||||
z = r_n * vec2(cos(theta_n), sin(theta_n)) + c;
|
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
buffalo_fractal_calc = """int calculate_iters({vec2type} c) {{
|
buffalo_fractal_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
{vec2type} z = {vec2type}(0.0, 0.0);
|
|
||||||
{floattype} R = {escape_radius};
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
|
||||||
{floattype} z_squared_real = z.x * z.x - z.y * z.y;
|
{floattype} z_squared_real = z.x * z.x - z.y * z.y;
|
||||||
{floattype} z_squared_imag = 2.0 * z.x * z.y;
|
{floattype} z_squared_imag = 2.0 * z.x * z.y;
|
||||||
z = {vec2type}(abs(z_squared_real) + c.x, abs(z_squared_imag) + c.y);
|
return {vec2type}(abs(z_squared_real) + c.x, abs(z_squared_imag) + c.y);
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
multi_buffalo_fractal_calc = """int calculate_iters(vec2 c) {{
|
multi_buffalo_fractal_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
vec2 z = vec2(0.0);
|
{floattype} n = {floattype}({multi_n});
|
||||||
float n = {multi_n};
|
{floattype} r = length(z);
|
||||||
float R = {escape_radius};
|
{floattype} theta = atan(z.y, z.x);
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
{floattype} r_n = pow(r, n);
|
||||||
float r = length(z);
|
{floattype} theta_n = n * theta;
|
||||||
float theta = atan(z.y, z.x);
|
{floattype} zn_real = r_n * cos(theta_n);
|
||||||
float r_n = pow(r, n);
|
{floattype} zn_imag = r_n * sin(theta_n);
|
||||||
float theta_n = n * theta;
|
return {vec2type}(abs(zn_real) + c.x, abs(zn_imag) + c.y);
|
||||||
float zn_real = r_n * cos(theta_n);
|
|
||||||
float zn_imag = r_n * sin(theta_n);
|
|
||||||
z = vec2(abs(zn_real) + c.x, abs(zn_imag) + c.y);
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
burning_ship_calc = """int calculate_iters({vec2type} c) {{
|
burning_ship_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
{vec2type} z = {vec2type}(0.0, 0.0);
|
|
||||||
float R = {escape_radius};
|
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
|
||||||
{floattype} xtemp = z.x * z.x - z.y * z.y + c.x;
|
{floattype} xtemp = z.x * z.x - z.y * z.y + c.x;
|
||||||
z.y = abs(2.0 * z.x * z.y) + c.y;
|
return {vec2type}(xtemp, abs(2.0 * z.x * z.y) + c.y);
|
||||||
z.x = xtemp;
|
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
phoenix_fractal_calc = """int calculate_iters({vec2type} c) {{
|
phoenix_fractal_calc = """{vec2type} fractal_iteration({vec2type} unused, {vec2type} c) {{
|
||||||
int iters = 0;
|
int iters = 0;
|
||||||
{vec2type} z = {vec2type}(0.0, 0.0);
|
{vec2type} z = {vec2type}(0.0, 0.0);
|
||||||
{vec2type} z_prev = {vec2type}(0.0, 0.0);
|
{vec2type} z_prev = {vec2type}(0.0, 0.0);
|
||||||
@@ -274,16 +246,16 @@ phoenix_fractal_calc = """int calculate_iters({vec2type} c) {{
|
|||||||
iters++;
|
iters++;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
return iters;
|
return {vec2type}(iters, 0);
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
lambda_fractal_calc = """int calculate_iters({vec2type} c) {{
|
lambda_fractal_calc = """
|
||||||
int iters = 0;
|
{vec2type} fractal_iteration ({vec2type} z, {vec2type} c) {{
|
||||||
{vec2type} z = {vec2type}(0.5, 0.0); // Try nonzero start
|
if (z.x == 0) {{
|
||||||
float R = {escape_radius}; // Try R = 2.0 if needed
|
z.x = 0.5;
|
||||||
|
}}
|
||||||
|
|
||||||
while (dot(z, z) < R * R && iters < u_maxIter) {{
|
|
||||||
{vec2type} one_minus_z = {vec2type}(1.0, 1.0) - z;
|
{vec2type} one_minus_z = {vec2type}(1.0, 1.0) - z;
|
||||||
|
|
||||||
{vec2type} temp = {vec2type}(
|
{vec2type} temp = {vec2type}(
|
||||||
@@ -291,64 +263,59 @@ lambda_fractal_calc = """int calculate_iters({vec2type} c) {{
|
|||||||
z.x * one_minus_z.y + z.y * one_minus_z.x
|
z.x * one_minus_z.y + z.y * one_minus_z.x
|
||||||
);
|
);
|
||||||
|
|
||||||
z = {vec2type}(
|
return {vec2type}(
|
||||||
c.x * temp.x - c.y * temp.y,
|
c.x * temp.x - c.y * temp.y,
|
||||||
c.x * temp.y + c.y * temp.x
|
c.x * temp.y + c.y * temp.x
|
||||||
);
|
);
|
||||||
|
|
||||||
iters++;
|
|
||||||
}}
|
|
||||||
|
|
||||||
return iters;
|
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
newton_fractal_calc = """vec2 cmul(vec2 a, vec2 b) {{
|
newton_fractal_calc = """{vec2type} cmul({vec2type} a, {vec2type} b) {{
|
||||||
return vec2(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
|
return {vec2type}(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
vec2 cdiv(vec2 a, vec2 b) {{
|
{vec2type} cdiv({vec2type} a, {vec2type} b) {{
|
||||||
float denom = b.x * b.x + b.y * b.y;
|
float denom = b.x * b.x + b.y * b.y;
|
||||||
return vec2((a.x * b.x + a.y * b.y) / denom, (a.y * b.x - a.x * b.y) / denom);
|
return {vec2type}((a.x * b.x + a.y * b.y) / denom, (a.y * b.x - a.x * b.y) / denom);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
vec2 cpow(vec2 z, int power) {{
|
{vec2type} cpow({vec2type} z, int power) {{
|
||||||
vec2 result = vec2(1.0, 0.0);
|
{vec2type} result = {vec2type}(1.0, 0.0);
|
||||||
for (int i = 0; i < power; ++i) {{
|
for (int i = 0; i < power; ++i) {{
|
||||||
result = cmul(result, z);
|
result = cmul(result, z);
|
||||||
}}
|
}}
|
||||||
return result;
|
return result;
|
||||||
}}
|
}}
|
||||||
|
|
||||||
vec2 func(vec2 z) {{
|
{vec2type} func({vec2type} z) {{
|
||||||
return cpow(z, 3) - vec2(1.0, 0.0);
|
return cpow(z, 3) - {vec2type}(1.0, 0.0);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
vec2 derivative(vec2 z) {{
|
{vec2type} derivative({vec2type} z) {{
|
||||||
return 3.0 * cmul(z, z);
|
return 3.0 * cmul(z, z);
|
||||||
}}
|
}}
|
||||||
|
|
||||||
int calculate_iters(vec2 z) {{
|
{vec2type} fractal_iteration({vec2type} c, {vec2type} z) {{
|
||||||
float tolerance = 0.000001;
|
float tolerance = 0.000001;
|
||||||
vec2 roots[3] = vec2[](
|
{vec2type} roots[3] = {vec2type}[](
|
||||||
vec2(1, 0),
|
{vec2type}(1, 0),
|
||||||
vec2(-0.5, 0.866025404),
|
{vec2type}(-0.5, 0.866025404),
|
||||||
vec2(-0.5, -0.866025404)
|
{vec2type}(-0.5, -0.866025404)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (int iters = 0; iters < u_maxIter; iters++) {{
|
for (int iters = 0; iters < u_maxIter; iters++) {{
|
||||||
z -= cdiv(func(z), derivative(z));
|
z -= cdiv(func(z), derivative(z));
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {{
|
for (int i = 0; i < 3; i++) {{
|
||||||
vec2 difference = z - roots[i];
|
{vec2type} difference = z - roots[i];
|
||||||
if (abs(difference.x) < tolerance && abs(difference.y) < tolerance) {{
|
if (abs(difference.x) < tolerance && abs(difference.y) < tolerance) {{
|
||||||
return i;
|
return {vec2type}(i, 0);
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
}}
|
}}
|
||||||
|
|
||||||
return -1;
|
return {vec2type}(-1, 0);
|
||||||
}}
|
}}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -371,18 +338,25 @@ def create_sierpinsky_carpet_shader(width, height, precision="single"):
|
|||||||
|
|
||||||
return shader_program, sierpinsky_carpet_image
|
return shader_program, sierpinsky_carpet_image
|
||||||
|
|
||||||
def create_iter_calc_shader(fractal_type, width, height, precision="single", multi_n=2, escape_radius=2, julia_type="Classic swirling"):
|
def create_iter_calc_shader(fractal_type, width, height, precision="single", multi_n=2, escape_radius=2, julia_type="Classic swirling", use_preturbation=False, preturbation_center=mpc(0, 0), max_iters=0):
|
||||||
shader_source = iter_fractal_template
|
shader_source = iter_fractal_template
|
||||||
|
|
||||||
replacements = {
|
replacements = {
|
||||||
"multi_n": str(multi_n),
|
"multi_n": str(multi_n),
|
||||||
"julia_c": str(c_for_julia_type[julia_type]),
|
|
||||||
"escape_radius": str(escape_radius),
|
"escape_radius": str(escape_radius),
|
||||||
"vec2type": "dvec2" if int(multi_n) == 2 and precision == "double" else "vec2",
|
"vec2type": "dvec2" if int(multi_n) == 2 and precision == "double" else "vec2",
|
||||||
"floattype": "double" if int(multi_n) == 2 and precision == "double" else "float"
|
"floattype": "double" if int(multi_n) == 2 and precision == "double" else "float"
|
||||||
}
|
}
|
||||||
|
|
||||||
replacements["coloring_func"] = polynomial_coloring.format_map(replacements)
|
replacements["coloring_func"] = polynomial_coloring.format_map(replacements)
|
||||||
|
replacements["fractal_type"] = 0
|
||||||
|
|
||||||
|
if fractal_type == "julia":
|
||||||
|
replacements["initial_z"] = "pos"
|
||||||
|
replacements["initial_c"] = f"{replacements['vec2type']}{c_for_julia_type[julia_type]}" # this works because if its vec2, it would be vec2(..., ...) for example.
|
||||||
|
else:
|
||||||
|
replacements["initial_z"] = "vec2(0.0)"
|
||||||
|
replacements["initial_c"] = "pos"
|
||||||
|
|
||||||
if fractal_type == "mandelbrot":
|
if fractal_type == "mandelbrot":
|
||||||
if int(multi_n) == 2:
|
if int(multi_n) == 2:
|
||||||
@@ -398,6 +372,7 @@ def create_iter_calc_shader(fractal_type, width, height, precision="single", mul
|
|||||||
|
|
||||||
elif fractal_type == "phoenix_fractal":
|
elif fractal_type == "phoenix_fractal":
|
||||||
replacements["iter_calc_func"] = phoenix_fractal_calc.format_map(replacements)
|
replacements["iter_calc_func"] = phoenix_fractal_calc.format_map(replacements)
|
||||||
|
replacements["fractal_type"] = 1
|
||||||
|
|
||||||
elif fractal_type == "lambda_fractal":
|
elif fractal_type == "lambda_fractal":
|
||||||
replacements["iter_calc_func"] = lambda_fractal_calc.format_map(replacements)
|
replacements["iter_calc_func"] = lambda_fractal_calc.format_map(replacements)
|
||||||
@@ -422,14 +397,18 @@ def create_iter_calc_shader(fractal_type, width, height, precision="single", mul
|
|||||||
elif fractal_type == "newton_fractal":
|
elif fractal_type == "newton_fractal":
|
||||||
replacements["coloring_func"] = newton_coloring.format_map(replacements)
|
replacements["coloring_func"] = newton_coloring.format_map(replacements)
|
||||||
replacements["iter_calc_func"] = newton_fractal_calc.format_map(replacements)
|
replacements["iter_calc_func"] = newton_fractal_calc.format_map(replacements)
|
||||||
|
replacements["fractal_type"] = 2
|
||||||
|
|
||||||
shader_source = shader_source.format_map(replacements)
|
shader_source = shader_source.format_map(replacements)
|
||||||
|
|
||||||
shader_program = pyglet.graphics.shader.ComputeShaderProgram(shader_source)
|
shader_program = pyglet.graphics.shader.ComputeShaderProgram(shader_source)
|
||||||
|
|
||||||
iter_calc_image = pyglet.image.Texture.create(width, height, internalformat=pyglet.gl.GL_RGBA32F)
|
fractal_image = pyglet.image.Texture.create(width, height, internalformat=pyglet.gl.GL_RGBA32F)
|
||||||
|
|
||||||
uniform_location = shader_program['img_output']
|
fractal_image.bind_image_texture(unit=shader_program['img_output'])
|
||||||
iter_calc_image.bind_image_texture(unit=uniform_location)
|
|
||||||
|
|
||||||
return shader_program, iter_calc_image
|
if use_preturbation:
|
||||||
|
orbit_image = calculate_orbit(fractal_type, preturbation_center, max_iters, multi_n, julia_type)
|
||||||
|
orbit_image.bind_image_texture(unit=shader_program['orbit'])
|
||||||
|
|
||||||
|
return shader_program, fractal_image
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ description = "Fractal viewer in Python using compute shaders and the Arcade and
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arcade==3.2.0",
|
"arcade>=3.3.3",
|
||||||
|
"mpmath>=1.3.0",
|
||||||
"pypresence>=4.3.0",
|
"pypresence>=4.3.0",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,3 +1,24 @@
|
|||||||
Pillow
|
# This file was autogenerated by uv via the following command:
|
||||||
arcade==3.2.0
|
# uv pip compile pyproject.toml -o requirements.txt
|
||||||
pypresence
|
arcade==3.3.3
|
||||||
|
# via fractalviewer (pyproject.toml)
|
||||||
|
attrs==25.4.0
|
||||||
|
# via pytiled-parser
|
||||||
|
cffi==2.0.0
|
||||||
|
# via pymunk
|
||||||
|
mpmath==1.3.0
|
||||||
|
# via fractalviewer (pyproject.toml)
|
||||||
|
pillow==11.3.0
|
||||||
|
# via arcade
|
||||||
|
pycparser==2.23
|
||||||
|
# via cffi
|
||||||
|
pyglet==2.1.11
|
||||||
|
# via arcade
|
||||||
|
pymunk==6.9.0
|
||||||
|
# via arcade
|
||||||
|
pypresence==4.6.1
|
||||||
|
# via fractalviewer (pyproject.toml)
|
||||||
|
pytiled-parser==2.2.9
|
||||||
|
# via arcade
|
||||||
|
typing-extensions==4.15.0
|
||||||
|
# via pytiled-parser
|
||||||
|
|||||||
40
run.py
40
run.py
@@ -1,8 +1,17 @@
|
|||||||
import pyglet
|
import pyglet
|
||||||
|
|
||||||
|
pyglet.options['shadow_window'] = False # Fix double window issue on Wayland
|
||||||
pyglet.options.debug_gl = False
|
pyglet.options.debug_gl = False
|
||||||
|
|
||||||
import logging, datetime, os, json, sys, arcade
|
import logging, datetime, os, json, sys, arcade, platform
|
||||||
|
|
||||||
|
# Set up paths BEFORE importing modules that load assets
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
pyglet.resource.path.append(script_dir)
|
||||||
|
pyglet.font.add_directory(os.path.join(script_dir, 'assets', 'fonts'))
|
||||||
|
|
||||||
|
import mpmath
|
||||||
|
mpmath.dps = 1000
|
||||||
|
|
||||||
from utils.utils import get_closest_resolution, print_debug_info, on_exception
|
from utils.utils import get_closest_resolution, print_debug_info, on_exception
|
||||||
from utils.constants import log_dir, menu_background_color
|
from utils.constants import log_dir, menu_background_color
|
||||||
@@ -11,9 +20,6 @@ from arcade.experimental.controller_window import ControllerWindow
|
|||||||
|
|
||||||
sys.excepthook = on_exception
|
sys.excepthook = on_exception
|
||||||
|
|
||||||
pyglet.resource.path.append(os.getcwd())
|
|
||||||
pyglet.font.add_directory('./assets/fonts')
|
|
||||||
|
|
||||||
__builtins__.print = lambda *args, **kwargs: logging.debug(" ".join(map(str, args)))
|
__builtins__.print = lambda *args, **kwargs: logging.debug(" ".join(map(str, args)))
|
||||||
|
|
||||||
if not log_dir in os.listdir():
|
if not log_dir in os.listdir():
|
||||||
@@ -28,7 +34,7 @@ timestamp = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
|||||||
log_filename = f"debug_{timestamp}.log"
|
log_filename = f"debug_{timestamp}.log"
|
||||||
logging.basicConfig(filename=f'{os.path.join(log_dir, log_filename)}', format='%(asctime)s %(name)s %(levelname)s: %(message)s', level=logging.DEBUG)
|
logging.basicConfig(filename=f'{os.path.join(log_dir, log_filename)}', format='%(asctime)s %(name)s %(levelname)s: %(message)s', level=logging.DEBUG)
|
||||||
|
|
||||||
for logger_name_to_disable in ['arcade', "numba"]:
|
for logger_name_to_disable in ['arcade']:
|
||||||
logging.getLogger(logger_name_to_disable).propagate = False
|
logging.getLogger(logger_name_to_disable).propagate = False
|
||||||
logging.getLogger(logger_name_to_disable).disabled = True
|
logging.getLogger(logger_name_to_disable).disabled = True
|
||||||
|
|
||||||
@@ -43,6 +49,13 @@ if os.path.exists('settings.json'):
|
|||||||
else:
|
else:
|
||||||
antialiasing = 0
|
antialiasing = 0
|
||||||
|
|
||||||
|
# Wayland workaround (can be overridden with environment variable)
|
||||||
|
if (platform.system() == "Linux" and
|
||||||
|
os.environ.get("WAYLAND_DISPLAY") and
|
||||||
|
not os.environ.get("ARCADE_FORCE_MSAA")):
|
||||||
|
logging.info("Wayland detected - disabling MSAA (set ARCADE_FORCE_MSAA=1 to override)")
|
||||||
|
antialiasing = 0
|
||||||
|
|
||||||
fullscreen = settings['window_mode'] == 'Fullscreen'
|
fullscreen = settings['window_mode'] == 'Fullscreen'
|
||||||
style = arcade.Window.WINDOW_STYLE_BORDERLESS if settings['window_mode'] == 'borderless' else arcade.Window.WINDOW_STYLE_DEFAULT
|
style = arcade.Window.WINDOW_STYLE_BORDERLESS if settings['window_mode'] == 'borderless' else arcade.Window.WINDOW_STYLE_DEFAULT
|
||||||
vsync = settings['vsync']
|
vsync = settings['vsync']
|
||||||
@@ -50,6 +63,14 @@ if os.path.exists('settings.json'):
|
|||||||
else:
|
else:
|
||||||
resolution = get_closest_resolution()
|
resolution = get_closest_resolution()
|
||||||
antialiasing = 4
|
antialiasing = 4
|
||||||
|
|
||||||
|
# Wayland workaround (can be overridden with environment variable)
|
||||||
|
if (platform.system() == "Linux" and
|
||||||
|
os.environ.get("WAYLAND_DISPLAY") and
|
||||||
|
not os.environ.get("ARCADE_FORCE_MSAA")):
|
||||||
|
logging.info("Wayland detected - disabling MSAA (set ARCADE_FORCE_MSAA=1 to override)")
|
||||||
|
antialiasing = 0
|
||||||
|
|
||||||
fullscreen = False
|
fullscreen = False
|
||||||
style = arcade.Window.WINDOW_STYLE_DEFAULT
|
style = arcade.Window.WINDOW_STYLE_DEFAULT
|
||||||
vsync = True
|
vsync = True
|
||||||
@@ -67,7 +88,11 @@ else:
|
|||||||
with open("settings.json", "w") as file:
|
with open("settings.json", "w") as file:
|
||||||
file.write(json.dumps(settings))
|
file.write(json.dumps(settings))
|
||||||
|
|
||||||
window = ControllerWindow(width=resolution[0], height=resolution[1], title='Fractal Viewer', samples=antialiasing, antialiasing=antialiasing > 0, fullscreen=fullscreen, vsync=vsync, resizable=False, style=style)
|
try:
|
||||||
|
window = ControllerWindow(width=resolution[0], height=resolution[1], title='FractalViewer', samples=antialiasing, antialiasing=antialiasing > 0, fullscreen=fullscreen, vsync=vsync, resizable=False, style=style, visible=False)
|
||||||
|
except (FileNotFoundError, PermissionError) as e:
|
||||||
|
logging.warning(f"Controller support unavailable: {e}. Falling back to regular window.")
|
||||||
|
window = arcade.Window(width=resolution[0], height=resolution[1], title='FractalViewer', samples=antialiasing, antialiasing=antialiasing > 0, fullscreen=fullscreen, vsync=vsync, resizable=False, style=style, visible=False)
|
||||||
|
|
||||||
if vsync:
|
if vsync:
|
||||||
window.set_vsync(True)
|
window.set_vsync(True)
|
||||||
@@ -92,6 +117,9 @@ main = Main()
|
|||||||
|
|
||||||
window.show_view(main)
|
window.show_view(main)
|
||||||
|
|
||||||
|
# Make window visible after all setup is complete (helps prevent double window on Wayland)
|
||||||
|
window.set_visible(True)
|
||||||
|
|
||||||
logging.debug('Game started.')
|
logging.debug('Game started.')
|
||||||
|
|
||||||
arcade.run()
|
arcade.run()
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import arcade.gui, arcade
|
import arcade.gui, arcade, os
|
||||||
|
|
||||||
button_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button.png"))
|
# Get the directory where this module is located
|
||||||
button_hovered_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture("assets/graphics/button_hovered.png"))
|
_module_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
cursor_texture = arcade.load_texture("assets/graphics/cursor.png")
|
_assets_dir = os.path.join(os.path.dirname(_module_dir), 'assets')
|
||||||
|
|
||||||
|
button_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'button.png')))
|
||||||
|
button_hovered_texture = arcade.gui.NinePatchTexture(64 // 4, 64 // 4, 64 // 4, 64 // 4, arcade.load_texture(os.path.join(_assets_dir, 'graphics', 'button_hovered.png')))
|
||||||
|
cursor_texture = arcade.load_texture(os.path.join(_assets_dir, "graphics", "cursor.png"))
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
import logging, arcade, arcade.gui, sys, traceback
|
import logging, arcade, traceback, pyglet.display
|
||||||
|
|
||||||
from utils.constants import menu_background_color
|
|
||||||
|
|
||||||
import pyglet.info, pyglet.event
|
|
||||||
|
|
||||||
def dump_platform():
|
def dump_platform():
|
||||||
import platform
|
import platform
|
||||||
@@ -38,29 +34,6 @@ def print_debug_info():
|
|||||||
logging.debug('########################## DEBUG INFO ##########################')
|
logging.debug('########################## DEBUG INFO ##########################')
|
||||||
logging.debug('')
|
logging.debug('')
|
||||||
|
|
||||||
class ErrorView(arcade.gui.UIView):
|
|
||||||
def __init__(self, message, title):
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.message = message
|
|
||||||
self.title = title
|
|
||||||
|
|
||||||
def exit(self):
|
|
||||||
logging.fatal('Exited with error code 1.')
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def on_show_view(self):
|
|
||||||
super().on_show_view()
|
|
||||||
|
|
||||||
self.window.set_caption('Fractal Viewer - Error')
|
|
||||||
self.window.set_mouse_visible(True)
|
|
||||||
self.window.set_exclusive_mouse(False)
|
|
||||||
arcade.set_background_color(menu_background_color)
|
|
||||||
|
|
||||||
msgbox = arcade.gui.UIMessageBox(width=self.window.width / 2, height=self.window.height / 2, message_text=self.message, title=self.title)
|
|
||||||
msgbox.on_action = lambda _: self.exit()
|
|
||||||
self.add_widget(msgbox)
|
|
||||||
|
|
||||||
def on_exception(*exc_info):
|
def on_exception(*exc_info):
|
||||||
logging.error(f"Unhandled exception:\n{''.join(traceback.format_exception(exc_info[1], limit=None))}")
|
logging.error(f"Unhandled exception:\n{''.join(traceback.format_exception(exc_info[1], limit=None))}")
|
||||||
|
|
||||||
|
|||||||
265
uv.lock
generated
265
uv.lock
generated
@@ -4,7 +4,7 @@ requires-python = ">=3.11"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arcade"
|
name = "arcade"
|
||||||
version = "3.2.0"
|
version = "3.3.3"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "pillow" },
|
{ name = "pillow" },
|
||||||
@@ -12,63 +12,88 @@ dependencies = [
|
|||||||
{ name = "pymunk" },
|
{ name = "pymunk" },
|
||||||
{ name = "pytiled-parser" },
|
{ name = "pytiled-parser" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/e5/39/87eaffdfc50ec9d4b4573652ef8b80cca0592e5ccafb5fc5bc8612b1445d/arcade-3.2.0.tar.gz", hash = "sha256:1c2c56181560665f6542157b9ab316b9551274a9ee8468bae017ed5b8fee18fd", size = 41941030, upload_time = "2025-05-09T20:16:20.112Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/5b/8f/7e2d6433bfbaf6c501d51614155a1b8e617805edab6c95b74182c7f2c68b/arcade-3.3.3.tar.gz", hash = "sha256:86a73dfafa0ce4fd4fb9551f850cc332b392e22e88142ff17914ea3fef59540b", size = 41952289, upload_time = "2025-10-09T15:46:14.947Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/40/9a/ac86f5cbccfe5455a28308fcf2d7179af8d9c3087ad4eb45706c2a7b089b/arcade-3.2.0-py3-none-any.whl", hash = "sha256:7bb47cf643b43272e4300d8a5ca5f1b1e9e131b0f3f1d3fad013cb29528d3062", size = 42635264, upload_time = "2025-05-09T20:16:15.98Z" },
|
{ url = "https://files.pythonhosted.org/packages/a9/c9/5888ddef3668caee10b6111dfb98a96addacef40b9b098213497a8ed614e/arcade-3.3.3-py3-none-any.whl", hash = "sha256:25f4e0e5b8bcbe7a7d087c0a23b19e9f423b0c70ec00945c8712c9a3e541ebd2", size = 42669158, upload_time = "2025-10-09T15:46:11.382Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "25.3.0"
|
version = "25.4.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload_time = "2025-03-13T11:10:22.779Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload_time = "2025-10-06T13:54:44.725Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload_time = "2025-03-13T11:10:21.14Z" },
|
{ url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload_time = "2025-10-06T13:54:43.17Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cffi"
|
name = "cffi"
|
||||||
version = "1.17.1"
|
version = "2.0.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "pycparser" },
|
{ name = "pycparser", marker = "implementation_name != 'PyPy'" },
|
||||||
]
|
]
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload_time = "2024-09-04T20:45:21.852Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/eb/56/b1ba7935a17738ae8453301356628e8147c79dbb825bcbc73dc7401f9846/cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529", size = 523588, upload_time = "2025-09-08T23:24:04.541Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload_time = "2024-09-04T20:43:51.124Z" },
|
{ url = "https://files.pythonhosted.org/packages/12/4a/3dfd5f7850cbf0d06dc84ba9aa00db766b52ca38d8b86e3a38314d52498c/cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe", size = 184344, upload_time = "2025-09-08T23:22:26.456Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload_time = "2024-09-04T20:43:52.872Z" },
|
{ url = "https://files.pythonhosted.org/packages/4f/8b/f0e4c441227ba756aafbe78f117485b25bb26b1c059d01f137fa6d14896b/cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c", size = 180560, upload_time = "2025-09-08T23:22:28.197Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload_time = "2024-09-04T20:43:56.123Z" },
|
{ url = "https://files.pythonhosted.org/packages/b1/b7/1200d354378ef52ec227395d95c2576330fd22a869f7a70e88e1447eb234/cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92", size = 209613, upload_time = "2025-09-08T23:22:29.475Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload_time = "2024-09-04T20:43:57.891Z" },
|
{ url = "https://files.pythonhosted.org/packages/b8/56/6033f5e86e8cc9bb629f0077ba71679508bdf54a9a5e112a3c0b91870332/cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93", size = 216476, upload_time = "2025-09-08T23:22:31.063Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload_time = "2024-09-04T20:44:00.18Z" },
|
{ url = "https://files.pythonhosted.org/packages/dc/7f/55fecd70f7ece178db2f26128ec41430d8720f2d12ca97bf8f0a628207d5/cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5", size = 203374, upload_time = "2025-09-08T23:22:32.507Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload_time = "2024-09-04T20:44:01.585Z" },
|
{ url = "https://files.pythonhosted.org/packages/84/ef/a7b77c8bdc0f77adc3b46888f1ad54be8f3b7821697a7b89126e829e676a/cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664", size = 202597, upload_time = "2025-09-08T23:22:34.132Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload_time = "2024-09-04T20:44:03.467Z" },
|
{ url = "https://files.pythonhosted.org/packages/d7/91/500d892b2bf36529a75b77958edfcd5ad8e2ce4064ce2ecfeab2125d72d1/cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26", size = 215574, upload_time = "2025-09-08T23:22:35.443Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload_time = "2024-09-04T20:44:05.023Z" },
|
{ url = "https://files.pythonhosted.org/packages/44/64/58f6255b62b101093d5df22dcb752596066c7e89dd725e0afaed242a61be/cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9", size = 218971, upload_time = "2025-09-08T23:22:36.805Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload_time = "2024-09-04T20:44:06.444Z" },
|
{ url = "https://files.pythonhosted.org/packages/ab/49/fa72cebe2fd8a55fbe14956f9970fe8eb1ac59e5df042f603ef7c8ba0adc/cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414", size = 211972, upload_time = "2025-09-08T23:22:38.436Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload_time = "2024-09-04T20:44:08.206Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/28/dd0967a76aab36731b6ebfe64dec4e981aff7e0608f60c2d46b46982607d/cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743", size = 217078, upload_time = "2025-09-08T23:22:39.776Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload_time = "2024-09-04T20:44:09.481Z" },
|
{ url = "https://files.pythonhosted.org/packages/2b/c0/015b25184413d7ab0a410775fdb4a50fca20f5589b5dab1dbbfa3baad8ce/cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5", size = 172076, upload_time = "2025-09-08T23:22:40.95Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload_time = "2024-09-04T20:44:10.873Z" },
|
{ url = "https://files.pythonhosted.org/packages/ae/8f/dc5531155e7070361eb1b7e4c1a9d896d0cb21c49f807a6c03fd63fc877e/cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5", size = 182820, upload_time = "2025-09-08T23:22:42.463Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload_time = "2024-09-04T20:44:12.232Z" },
|
{ url = "https://files.pythonhosted.org/packages/95/5c/1b493356429f9aecfd56bc171285a4c4ac8697f76e9bbbbb105e537853a1/cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d", size = 177635, upload_time = "2025-09-08T23:22:43.623Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload_time = "2024-09-04T20:44:13.739Z" },
|
{ url = "https://files.pythonhosted.org/packages/ea/47/4f61023ea636104d4f16ab488e268b93008c3d0bb76893b1b31db1f96802/cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d", size = 185271, upload_time = "2025-09-08T23:22:44.795Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload_time = "2024-09-04T20:44:15.231Z" },
|
{ url = "https://files.pythonhosted.org/packages/df/a2/781b623f57358e360d62cdd7a8c681f074a71d445418a776eef0aadb4ab4/cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c", size = 181048, upload_time = "2025-09-08T23:22:45.938Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload_time = "2024-09-04T20:44:17.188Z" },
|
{ url = "https://files.pythonhosted.org/packages/ff/df/a4f0fbd47331ceeba3d37c2e51e9dfc9722498becbeec2bd8bc856c9538a/cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe", size = 212529, upload_time = "2025-09-08T23:22:47.349Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload_time = "2024-09-04T20:44:18.688Z" },
|
{ url = "https://files.pythonhosted.org/packages/d5/72/12b5f8d3865bf0f87cf1404d8c374e7487dcf097a1c91c436e72e6badd83/cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062", size = 220097, upload_time = "2025-09-08T23:22:48.677Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload_time = "2024-09-04T20:44:20.248Z" },
|
{ url = "https://files.pythonhosted.org/packages/c2/95/7a135d52a50dfa7c882ab0ac17e8dc11cec9d55d2c18dda414c051c5e69e/cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e", size = 207983, upload_time = "2025-09-08T23:22:50.06Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload_time = "2024-09-04T20:44:21.673Z" },
|
{ url = "https://files.pythonhosted.org/packages/3a/c8/15cb9ada8895957ea171c62dc78ff3e99159ee7adb13c0123c001a2546c1/cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037", size = 206519, upload_time = "2025-09-08T23:22:51.364Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload_time = "2024-09-04T20:44:23.245Z" },
|
{ url = "https://files.pythonhosted.org/packages/78/2d/7fa73dfa841b5ac06c7b8855cfc18622132e365f5b81d02230333ff26e9e/cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba", size = 219572, upload_time = "2025-09-08T23:22:52.902Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload_time = "2024-09-04T20:44:24.757Z" },
|
{ url = "https://files.pythonhosted.org/packages/07/e0/267e57e387b4ca276b90f0434ff88b2c2241ad72b16d31836adddfd6031b/cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94", size = 222963, upload_time = "2025-09-08T23:22:54.518Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload_time = "2024-09-04T20:44:26.208Z" },
|
{ url = "https://files.pythonhosted.org/packages/b6/75/1f2747525e06f53efbd878f4d03bac5b859cbc11c633d0fb81432d98a795/cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187", size = 221361, upload_time = "2025-09-08T23:22:55.867Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload_time = "2024-09-04T20:44:27.578Z" },
|
{ url = "https://files.pythonhosted.org/packages/7b/2b/2b6435f76bfeb6bbf055596976da087377ede68df465419d192acf00c437/cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18", size = 172932, upload_time = "2025-09-08T23:22:57.188Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload_time = "2024-09-04T20:44:28.956Z" },
|
{ url = "https://files.pythonhosted.org/packages/f8/ed/13bd4418627013bec4ed6e54283b1959cf6db888048c7cf4b4c3b5b36002/cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5", size = 183557, upload_time = "2025-09-08T23:22:58.351Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload_time = "2024-09-04T20:44:30.289Z" },
|
{ url = "https://files.pythonhosted.org/packages/95/31/9f7f93ad2f8eff1dbc1c3656d7ca5bfd8fb52c9d786b4dcf19b2d02217fa/cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6", size = 177762, upload_time = "2025-09-08T23:22:59.668Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload_time = "2024-09-04T20:44:32.01Z" },
|
{ url = "https://files.pythonhosted.org/packages/4b/8d/a0a47a0c9e413a658623d014e91e74a50cdd2c423f7ccfd44086ef767f90/cffi-2.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:00bdf7acc5f795150faa6957054fbbca2439db2f775ce831222b66f192f03beb", size = 185230, upload_time = "2025-09-08T23:23:00.879Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload_time = "2024-09-04T20:44:33.606Z" },
|
{ url = "https://files.pythonhosted.org/packages/4a/d2/a6c0296814556c68ee32009d9c2ad4f85f2707cdecfd7727951ec228005d/cffi-2.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:45d5e886156860dc35862657e1494b9bae8dfa63bf56796f2fb56e1679fc0bca", size = 181043, upload_time = "2025-09-08T23:23:02.231Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload_time = "2024-09-04T20:44:35.191Z" },
|
{ url = "https://files.pythonhosted.org/packages/b0/1e/d22cc63332bd59b06481ceaac49d6c507598642e2230f201649058a7e704/cffi-2.0.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:07b271772c100085dd28b74fa0cd81c8fb1a3ba18b21e03d7c27f3436a10606b", size = 212446, upload_time = "2025-09-08T23:23:03.472Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload_time = "2024-09-04T20:44:36.743Z" },
|
{ url = "https://files.pythonhosted.org/packages/a9/f5/a2c23eb03b61a0b8747f211eb716446c826ad66818ddc7810cc2cc19b3f2/cffi-2.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d48a880098c96020b02d5a1f7d9251308510ce8858940e6fa99ece33f610838b", size = 220101, upload_time = "2025-09-08T23:23:04.792Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload_time = "2024-09-04T20:44:38.492Z" },
|
{ url = "https://files.pythonhosted.org/packages/f2/7f/e6647792fc5850d634695bc0e6ab4111ae88e89981d35ac269956605feba/cffi-2.0.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f93fd8e5c8c0a4aa1f424d6173f14a892044054871c771f8566e4008eaa359d2", size = 207948, upload_time = "2025-09-08T23:23:06.127Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload_time = "2024-09-04T20:44:40.046Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/1e/a5a1bd6f1fb30f22573f76533de12a00bf274abcdc55c8edab639078abb6/cffi-2.0.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:dd4f05f54a52fb558f1ba9f528228066954fee3ebe629fc1660d874d040ae5a3", size = 206422, upload_time = "2025-09-08T23:23:07.753Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload_time = "2024-09-04T20:44:41.616Z" },
|
{ url = "https://files.pythonhosted.org/packages/98/df/0a1755e750013a2081e863e7cd37e0cdd02664372c754e5560099eb7aa44/cffi-2.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c8d3b5532fc71b7a77c09192b4a5a200ea992702734a2e9279a37f2478236f26", size = 219499, upload_time = "2025-09-08T23:23:09.648Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload_time = "2024-09-04T20:44:43.733Z" },
|
{ url = "https://files.pythonhosted.org/packages/50/e1/a969e687fcf9ea58e6e2a928ad5e2dd88cc12f6f0ab477e9971f2309b57c/cffi-2.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d9b29c1f0ae438d5ee9acb31cadee00a58c46cc9c0b2f9038c6b0b3470877a8c", size = 222928, upload_time = "2025-09-08T23:23:10.928Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload_time = "2024-09-04T20:44:45.309Z" },
|
{ url = "https://files.pythonhosted.org/packages/36/54/0362578dd2c9e557a28ac77698ed67323ed5b9775ca9d3fe73fe191bb5d8/cffi-2.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d50360be4546678fc1b79ffe7a66265e28667840010348dd69a314145807a1b", size = 221302, upload_time = "2025-09-08T23:23:12.42Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/eb/6d/bf9bda840d5f1dfdbf0feca87fbdb64a918a69bca42cfa0ba7b137c48cb8/cffi-2.0.0-cp313-cp313-win32.whl", hash = "sha256:74a03b9698e198d47562765773b4a8309919089150a0bb17d829ad7b44b60d27", size = 172909, upload_time = "2025-09-08T23:23:14.32Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/37/18/6519e1ee6f5a1e579e04b9ddb6f1676c17368a7aba48299c3759bbc3c8b3/cffi-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:19f705ada2530c1167abacb171925dd886168931e0a7b78f5bffcae5c6b5be75", size = 183402, upload_time = "2025-09-08T23:23:15.535Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cb/0e/02ceeec9a7d6ee63bb596121c2c8e9b3a9e150936f4fbef6ca1943e6137c/cffi-2.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:256f80b80ca3853f90c21b23ee78cd008713787b1b1e93eae9f3d6a7134abd91", size = 177780, upload_time = "2025-09-08T23:23:16.761Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/92/c4/3ce07396253a83250ee98564f8d7e9789fab8e58858f35d07a9a2c78de9f/cffi-2.0.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fc33c5141b55ed366cfaad382df24fe7dcbc686de5be719b207bb248e3053dc5", size = 185320, upload_time = "2025-09-08T23:23:18.087Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/59/dd/27e9fa567a23931c838c6b02d0764611c62290062a6d4e8ff7863daf9730/cffi-2.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c654de545946e0db659b3400168c9ad31b5d29593291482c43e3564effbcee13", size = 181487, upload_time = "2025-09-08T23:23:19.622Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/43/0e822876f87ea8a4ef95442c3d766a06a51fc5298823f884ef87aaad168c/cffi-2.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:24b6f81f1983e6df8db3adc38562c83f7d4a0c36162885ec7f7b77c7dcbec97b", size = 220049, upload_time = "2025-09-08T23:23:20.853Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b4/89/76799151d9c2d2d1ead63c2429da9ea9d7aac304603de0c6e8764e6e8e70/cffi-2.0.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:12873ca6cb9b0f0d3a0da705d6086fe911591737a59f28b7936bdfed27c0d47c", size = 207793, upload_time = "2025-09-08T23:23:22.08Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/dd/3465b14bb9e24ee24cb88c9e3730f6de63111fffe513492bf8c808a3547e/cffi-2.0.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9b97165e8aed9272a6bb17c01e3cc5871a594a446ebedc996e2397a1c1ea8ef", size = 206300, upload_time = "2025-09-08T23:23:23.314Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/47/d9/d83e293854571c877a92da46fdec39158f8d7e68da75bf73581225d28e90/cffi-2.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:afb8db5439b81cf9c9d0c80404b60c3cc9c3add93e114dcae767f1477cb53775", size = 219244, upload_time = "2025-09-08T23:23:24.541Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2b/0f/1f177e3683aead2bb00f7679a16451d302c436b5cbf2505f0ea8146ef59e/cffi-2.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:737fe7d37e1a1bffe70bd5754ea763a62a066dc5913ca57e957824b72a85e205", size = 222828, upload_time = "2025-09-08T23:23:26.143Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/c6/0f/cafacebd4b040e3119dcb32fed8bdef8dfe94da653155f9d0b9dc660166e/cffi-2.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:38100abb9d1b1435bc4cc340bb4489635dc2f0da7456590877030c9b3d40b0c1", size = 220926, upload_time = "2025-09-08T23:23:27.873Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/aa/df335faa45b395396fcbc03de2dfcab242cd61a9900e914fe682a59170b1/cffi-2.0.0-cp314-cp314-win32.whl", hash = "sha256:087067fa8953339c723661eda6b54bc98c5625757ea62e95eb4898ad5e776e9f", size = 175328, upload_time = "2025-09-08T23:23:44.61Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bb/92/882c2d30831744296ce713f0feb4c1cd30f346ef747b530b5318715cc367/cffi-2.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:203a48d1fb583fc7d78a4c6655692963b860a417c0528492a6bc21f1aaefab25", size = 185650, upload_time = "2025-09-08T23:23:45.848Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9f/2c/98ece204b9d35a7366b5b2c6539c350313ca13932143e79dc133ba757104/cffi-2.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:dbd5c7a25a7cb98f5ca55d258b103a2054f859a46ae11aaf23134f9cc0d356ad", size = 180687, upload_time = "2025-09-08T23:23:47.105Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/3e/61/c768e4d548bfa607abcda77423448df8c471f25dbe64fb2ef6d555eae006/cffi-2.0.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9a67fc9e8eb39039280526379fb3a70023d77caec1852002b4da7e8b270c4dd9", size = 188773, upload_time = "2025-09-08T23:23:29.347Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2c/ea/5f76bce7cf6fcd0ab1a1058b5af899bfbef198bea4d5686da88471ea0336/cffi-2.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7a66c7204d8869299919db4d5069a82f1561581af12b11b3c9f48c584eb8743d", size = 185013, upload_time = "2025-09-08T23:23:30.63Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/be/b4/c56878d0d1755cf9caa54ba71e5d049479c52f9e4afc230f06822162ab2f/cffi-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cc09976e8b56f8cebd752f7113ad07752461f48a58cbba644139015ac24954c", size = 221593, upload_time = "2025-09-08T23:23:31.91Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e0/0d/eb704606dfe8033e7128df5e90fee946bbcb64a04fcdaa97321309004000/cffi-2.0.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:92b68146a71df78564e4ef48af17551a5ddd142e5190cdf2c5624d0c3ff5b2e8", size = 209354, upload_time = "2025-09-08T23:23:33.214Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d8/19/3c435d727b368ca475fb8742ab97c9cb13a0de600ce86f62eab7fa3eea60/cffi-2.0.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:b1e74d11748e7e98e2f426ab176d4ed720a64412b6a15054378afdb71e0f37dc", size = 208480, upload_time = "2025-09-08T23:23:34.495Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d0/44/681604464ed9541673e486521497406fadcc15b5217c3e326b061696899a/cffi-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:28a3a209b96630bca57cce802da70c266eb08c6e97e5afd61a75611ee6c64592", size = 221584, upload_time = "2025-09-08T23:23:36.096Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/25/8e/342a504ff018a2825d395d44d63a767dd8ebc927ebda557fecdaca3ac33a/cffi-2.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7553fb2090d71822f02c629afe6042c299edf91ba1bf94951165613553984512", size = 224443, upload_time = "2025-09-08T23:23:37.328Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e1/5e/b666bacbbc60fbf415ba9988324a132c9a7a0448a9a8f125074671c0f2c3/cffi-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c6c373cfc5c83a975506110d17457138c8c63016b563cc9ed6e056a82f13ce4", size = 223437, upload_time = "2025-09-08T23:23:38.945Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a0/1d/ec1a60bd1a10daa292d3cd6bb0b359a81607154fb8165f3ec95fe003b85c/cffi-2.0.0-cp314-cp314t-win32.whl", hash = "sha256:1fc9ea04857caf665289b7a75923f2c6ed559b8298a1b8c49e59f7dd95c8481e", size = 180487, upload_time = "2025-09-08T23:23:40.423Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bf/41/4c1168c74fac325c0c8156f04b6749c8b6a8f405bbf91413ba088359f60d/cffi-2.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d68b6cef7827e8641e8ef16f4494edda8b36104d79773a334beaa1e3521430f6", size = 191726, upload_time = "2025-09-08T23:23:41.742Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload_time = "2025-09-08T23:23:43.004Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -77,80 +102,126 @@ version = "0.1.0"
|
|||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "arcade" },
|
{ name = "arcade" },
|
||||||
|
{ name = "mpmath" },
|
||||||
{ name = "pypresence" },
|
{ name = "pypresence" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.metadata]
|
[package.metadata]
|
||||||
requires-dist = [
|
requires-dist = [
|
||||||
{ name = "arcade", specifier = "==3.2.0" },
|
{ name = "arcade", specifier = ">=3.3.3" },
|
||||||
|
{ name = "mpmath", specifier = ">=1.3.0" },
|
||||||
{ name = "pypresence", specifier = ">=4.3.0" },
|
{ name = "pypresence", specifier = ">=4.3.0" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pillow"
|
name = "mpmath"
|
||||||
version = "11.0.0"
|
version = "1.3.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780, upload_time = "2024-10-15T14:24:29.672Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload_time = "2023-03-07T16:47:11.061Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/f0/eb/f7e21b113dd48a9c97d364e0915b3988c6a0b6207652f5a92372871b7aa4/pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", size = 3154705, upload_time = "2024-10-15T14:22:15.419Z" },
|
{ url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload_time = "2023-03-07T16:47:09.197Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/25/b3/2b54a1d541accebe6bd8b1358b34ceb2c509f51cb7dcda8687362490da5b/pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", size = 2979222, upload_time = "2024-10-15T14:22:17.681Z" },
|
]
|
||||||
{ url = "https://files.pythonhosted.org/packages/20/12/1a41eddad8265c5c19dda8fb6c269ce15ee25e0b9f8f26286e6202df6693/pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", size = 4190220, upload_time = "2024-10-15T14:22:19.826Z" },
|
|
||||||
{ url = "https://files.pythonhosted.org/packages/a9/9b/8a8c4d07d77447b7457164b861d18f5a31ae6418ef5c07f6f878fa09039a/pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", size = 4291399, upload_time = "2024-10-15T14:22:22.129Z" },
|
[[package]]
|
||||||
{ url = "https://files.pythonhosted.org/packages/fc/e4/130c5fab4a54d3991129800dd2801feeb4b118d7630148cd67f0e6269d4c/pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", size = 4202709, upload_time = "2024-10-15T14:22:23.953Z" },
|
name = "pillow"
|
||||||
{ url = "https://files.pythonhosted.org/packages/39/63/b3fc299528d7df1f678b0666002b37affe6b8751225c3d9c12cf530e73ed/pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", size = 4372556, upload_time = "2024-10-15T14:22:25.706Z" },
|
version = "11.3.0"
|
||||||
{ url = "https://files.pythonhosted.org/packages/c6/a6/694122c55b855b586c26c694937d36bb8d3b09c735ff41b2f315c6e66a10/pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", size = 4287187, upload_time = "2024-10-15T14:22:27.362Z" },
|
source = { registry = "https://pypi.org/simple" }
|
||||||
{ url = "https://files.pythonhosted.org/packages/ba/a9/f9d763e2671a8acd53d29b1e284ca298bc10a595527f6be30233cdb9659d/pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", size = 4418468, upload_time = "2024-10-15T14:22:29.093Z" },
|
sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload_time = "2025-07-01T09:16:30.666Z" }
|
||||||
{ url = "https://files.pythonhosted.org/packages/6e/0e/b5cbad2621377f11313a94aeb44ca55a9639adabcaaa073597a1925f8c26/pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", size = 2249249, upload_time = "2024-10-15T14:22:31.268Z" },
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/dc/83/1470c220a4ff06cd75fc609068f6605e567ea51df70557555c2ab6516b2c/pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", size = 2566769, upload_time = "2024-10-15T14:22:32.974Z" },
|
{ url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload_time = "2025-07-01T09:13:59.203Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/52/98/def78c3a23acee2bcdb2e52005fb2810ed54305602ec1bfcfab2bda6f49f/pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", size = 2254611, upload_time = "2024-10-15T14:22:35.496Z" },
|
{ url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload_time = "2025-07-01T09:14:01.101Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642, upload_time = "2024-10-15T14:22:37.736Z" },
|
{ url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload_time = "2025-07-03T13:09:55.638Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999, upload_time = "2024-10-15T14:22:39.654Z" },
|
{ url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload_time = "2025-07-03T13:10:00.37Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794, upload_time = "2024-10-15T14:22:41.598Z" },
|
{ url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload_time = "2025-07-01T09:14:04.491Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762, upload_time = "2024-10-15T14:22:45.952Z" },
|
{ url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload_time = "2025-07-01T09:14:06.235Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468, upload_time = "2024-10-15T14:22:47.789Z" },
|
{ url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload_time = "2025-07-01T09:14:07.978Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824, upload_time = "2024-10-15T14:22:49.668Z" },
|
{ url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload_time = "2025-07-01T09:14:10.233Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436, upload_time = "2024-10-15T14:22:51.911Z" },
|
{ url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload_time = "2025-07-01T09:14:11.921Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714, upload_time = "2024-10-15T14:22:53.967Z" },
|
{ url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload_time = "2025-07-01T09:14:13.623Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631, upload_time = "2024-10-15T14:22:56.404Z" },
|
{ url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload_time = "2025-07-01T09:14:15.268Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533, upload_time = "2024-10-15T14:22:58.087Z" },
|
{ url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload_time = "2025-07-01T09:14:17.648Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890, upload_time = "2024-10-15T14:22:59.918Z" },
|
{ url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload_time = "2025-07-01T09:14:19.828Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/63/24/e2e15e392d00fcf4215907465d8ec2a2f23bcec1481a8ebe4ae760459995/pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", size = 3147300, upload_time = "2024-10-15T14:23:01.855Z" },
|
{ url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload_time = "2025-07-03T13:10:04.448Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/43/72/92ad4afaa2afc233dc44184adff289c2e77e8cd916b3ddb72ac69495bda3/pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", size = 2978742, upload_time = "2024-10-15T14:23:03.749Z" },
|
{ url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload_time = "2025-07-03T13:10:10.391Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/9e/da/c8d69c5bc85d72a8523fe862f05ababdc52c0a755cfe3d362656bb86552b/pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", size = 4194349, upload_time = "2024-10-15T14:23:06.055Z" },
|
{ url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload_time = "2025-07-01T09:14:21.63Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/cd/e8/686d0caeed6b998351d57796496a70185376ed9c8ec7d99e1d19ad591fc6/pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", size = 4298714, upload_time = "2024-10-15T14:23:07.919Z" },
|
{ url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload_time = "2025-07-01T09:14:23.321Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ec/da/430015cec620d622f06854be67fd2f6721f52fc17fca8ac34b32e2d60739/pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", size = 4208514, upload_time = "2024-10-15T14:23:10.19Z" },
|
{ url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload_time = "2025-07-01T09:14:25.237Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/44/ae/7e4f6662a9b1cb5f92b9cc9cab8321c381ffbee309210940e57432a4063a/pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", size = 4380055, upload_time = "2024-10-15T14:23:12.08Z" },
|
{ url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload_time = "2025-07-01T09:14:27.053Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/74/d5/1a807779ac8a0eeed57f2b92a3c32ea1b696e6140c15bd42eaf908a261cd/pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", size = 4296751, upload_time = "2024-10-15T14:23:13.836Z" },
|
{ url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload_time = "2025-07-01T09:14:30.104Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/38/8c/5fa3385163ee7080bc13026d59656267daaaaf3c728c233d530e2c2757c8/pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", size = 4430378, upload_time = "2024-10-15T14:23:15.735Z" },
|
{ url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload_time = "2025-07-01T09:14:31.899Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/ca/1d/ad9c14811133977ff87035bf426875b93097fb50af747793f013979facdb/pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", size = 2249588, upload_time = "2024-10-15T14:23:17.905Z" },
|
{ url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload_time = "2025-07-01T09:14:33.709Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/fb/01/3755ba287dac715e6afdb333cb1f6d69740a7475220b4637b5ce3d78cec2/pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", size = 2567509, upload_time = "2024-10-15T14:23:19.643Z" },
|
{ url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload_time = "2025-07-01T09:14:35.276Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/c0/98/2c7d727079b6be1aba82d195767d35fcc2d32204c7a5820f822df5330152/pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", size = 2254791, upload_time = "2024-10-15T14:23:21.601Z" },
|
{ url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload_time = "2025-07-01T09:14:37.203Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/eb/38/998b04cc6f474e78b563716b20eecf42a2fa16a84589d23c8898e64b0ffd/pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", size = 3150854, upload_time = "2024-10-15T14:23:23.91Z" },
|
{ url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload_time = "2025-07-01T09:14:39.344Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/13/8e/be23a96292113c6cb26b2aa3c8b3681ec62b44ed5c2bd0b258bd59503d3c/pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", size = 2982369, upload_time = "2024-10-15T14:23:27.184Z" },
|
{ url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload_time = "2025-07-01T09:14:41.843Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/97/8a/3db4eaabb7a2ae8203cd3a332a005e4aba00067fc514aaaf3e9721be31f1/pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", size = 4333703, upload_time = "2024-10-15T14:23:28.979Z" },
|
{ url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload_time = "2025-07-01T09:14:44.008Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/28/ac/629ffc84ff67b9228fe87a97272ab125bbd4dc462745f35f192d37b822f1/pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", size = 4412550, upload_time = "2024-10-15T14:23:30.846Z" },
|
{ url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload_time = "2025-07-03T13:10:15.628Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/07/a505921d36bb2df6868806eaf56ef58699c16c388e378b0dcdb6e5b2fb36/pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", size = 4461038, upload_time = "2024-10-15T14:23:32.687Z" },
|
{ url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload_time = "2025-07-03T13:10:21.857Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/d6/b9/fb620dd47fc7cc9678af8f8bd8c772034ca4977237049287e99dda360b66/pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", size = 2253197, upload_time = "2024-10-15T14:23:35.309Z" },
|
{ url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload_time = "2025-07-01T09:14:45.698Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/df/86/25dde85c06c89d7fc5db17940f07aae0a56ac69aa9ccb5eb0f09798862a8/pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", size = 2572169, upload_time = "2024-10-15T14:23:37.33Z" },
|
{ url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload_time = "2025-07-01T09:14:47.415Z" },
|
||||||
{ url = "https://files.pythonhosted.org/packages/51/85/9c33f2517add612e17f3381aee7c4072779130c634921a756c97bc29fb49/pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", size = 2256828, upload_time = "2024-10-15T14:23:39.826Z" },
|
{ url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload_time = "2025-07-01T09:14:49.636Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload_time = "2025-07-01T09:14:51.962Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload_time = "2025-07-01T09:14:54.142Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload_time = "2025-07-01T09:14:56.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload_time = "2025-07-01T09:14:58.072Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload_time = "2025-07-01T09:14:59.79Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload_time = "2025-07-01T09:15:01.648Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload_time = "2025-07-03T13:10:27.018Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload_time = "2025-07-03T13:10:33.01Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload_time = "2025-07-01T09:15:03.365Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload_time = "2025-07-01T09:15:05.655Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload_time = "2025-07-01T09:15:07.358Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload_time = "2025-07-01T09:15:09.317Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload_time = "2025-07-01T09:15:11.311Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload_time = "2025-07-01T09:15:13.164Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload_time = "2025-07-01T09:15:15.695Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload_time = "2025-07-01T09:15:17.429Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload_time = "2025-07-01T09:15:19.423Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload_time = "2025-07-03T13:10:38.404Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload_time = "2025-07-03T13:10:44.987Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload_time = "2025-07-01T09:15:21.237Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload_time = "2025-07-01T09:15:23.186Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload_time = "2025-07-01T09:15:25.1Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload_time = "2025-07-01T09:15:27.378Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload_time = "2025-07-01T09:15:29.294Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload_time = "2025-07-01T09:15:31.128Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload_time = "2025-07-01T09:15:33.328Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload_time = "2025-07-01T09:15:35.194Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload_time = "2025-07-01T09:15:37.114Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload_time = "2025-07-03T13:10:50.248Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload_time = "2025-07-03T13:10:56.432Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload_time = "2025-07-01T09:15:39.436Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload_time = "2025-07-01T09:15:41.269Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload_time = "2025-07-01T09:15:43.13Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload_time = "2025-07-01T09:15:44.937Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload_time = "2025-07-01T09:15:46.673Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload_time = "2025-07-01T09:15:48.512Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload_time = "2025-07-01T09:15:50.399Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload_time = "2025-07-01T09:16:19.801Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload_time = "2025-07-01T09:16:21.818Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload_time = "2025-07-03T13:11:20.738Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload_time = "2025-07-03T13:11:26.283Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload_time = "2025-07-01T09:16:23.762Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload_time = "2025-07-01T09:16:25.593Z" },
|
||||||
|
{ url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload_time = "2025-07-01T09:16:27.732Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pycparser"
|
name = "pycparser"
|
||||||
version = "2.22"
|
version = "2.23"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload_time = "2024-03-30T13:22:22.564Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload_time = "2025-09-09T13:23:47.91Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload_time = "2024-03-30T13:22:20.476Z" },
|
{ url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload_time = "2025-09-09T13:23:46.651Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyglet"
|
name = "pyglet"
|
||||||
version = "2.1.6"
|
version = "2.1.11"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/f7/bc/0533ccb30566ee59b540d700dbbf916dafa89132a4d582d0fd1fe158243d/pyglet-2.1.6.tar.gz", hash = "sha256:18483880b1411b39692eaf7756819285797b1aaf9ef63d40eb9f9b5d01c63416", size = 6546705, upload_time = "2025-04-27T01:12:30.995Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/e3/6b/84c397a74cd33eb377168c682e9e3d6b90c1c10c661e11ea5b397ac8497c/pyglet-2.1.11.tar.gz", hash = "sha256:8285d0af7d0ab443232a81df4d941e0d5c48c18a23ec770b3e5c59a222f5d56e", size = 6594448, upload_time = "2025-11-07T04:29:52.092Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/a3/ad/e16f9b56c4a935934341e385753d0d0a2a83b7d320e52906b44f32698feb/pyglet-2.1.6-py3-none-any.whl", hash = "sha256:52ef9e75f3969b6a28bfa5c223e50ff03a05c2baa67bfe00d2a9eec4e831a7c5", size = 983998, upload_time = "2025-04-27T01:12:26.307Z" },
|
{ url = "https://files.pythonhosted.org/packages/77/a2/2b09fbff0eedbe44fbf164b321439a38f7c5568d8b754aa197ee45886431/pyglet-2.1.11-py3-none-any.whl", hash = "sha256:fa0f4fdf366cfc5040aeb462416910b0db2fa374b7d620b7a432178ca3fa8af1", size = 1032213, upload_time = "2025-11-07T04:29:46.06Z" },
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -212,9 +283,9 @@ wheels = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "4.13.2"
|
version = "4.15.0"
|
||||||
source = { registry = "https://pypi.org/simple" }
|
source = { registry = "https://pypi.org/simple" }
|
||||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload_time = "2025-04-10T14:19:05.416Z" }
|
sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload_time = "2025-08-25T13:49:26.313Z" }
|
||||||
wheels = [
|
wheels = [
|
||||||
{ url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload_time = "2025-04-10T14:19:03.967Z" },
|
{ url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload_time = "2025-08-25T13:49:24.86Z" },
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user