diff --git a/client/next.config.mjs b/client/next.config.mjs
index 950b3e64..abff464b 100644
--- a/client/next.config.mjs
+++ b/client/next.config.mjs
@@ -1,12 +1,6 @@
-// import os from "node:os";
-// import isInsideContainer from "is-inside-container";
-
-// const isWindowsDevContainer = () =>
-// os.release().toLowerCase().includes("microsoft") && isInsideContainer();
-
/** @type {import('next').NextConfig} */
-const config = {
+const nextConfig = {
reactStrictMode: true,
turbopack: {
root: import.meta.dirname,
@@ -27,4 +21,4 @@ const config = {
// : undefined,
};
-export default config;
+export default nextConfig;
diff --git a/client/public/go-back-icon.svg b/client/public/go-back-icon.svg
new file mode 100644
index 00000000..e920f5a5
--- /dev/null
+++ b/client/public/go-back-icon.svg
@@ -0,0 +1,10 @@
+
diff --git a/client/public/placeholder-icon.svg b/client/public/placeholder-icon.svg
new file mode 100644
index 00000000..6879e787
--- /dev/null
+++ b/client/public/placeholder-icon.svg
@@ -0,0 +1,6 @@
+
diff --git a/client/public/placeholder1293x405.svg b/client/public/placeholder1293x405.svg
new file mode 100644
index 00000000..34f928c8
--- /dev/null
+++ b/client/public/placeholder1293x405.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/client/src/components/ui/go-back-button.tsx b/client/src/components/ui/go-back-button.tsx
new file mode 100644
index 00000000..53ca3501
--- /dev/null
+++ b/client/src/components/ui/go-back-button.tsx
@@ -0,0 +1,30 @@
+import Image from "next/image";
+import Link from "next/link";
+
+interface GoBackButtonProps {
+ url: string;
+ label: string;
+}
+const GoBackButton = ({ url, label }: GoBackButtonProps) => {
+ return (
+
+
+
+ );
+};
+
+export default GoBackButton;
diff --git a/client/src/components/ui/image-card.tsx b/client/src/components/ui/image-card.tsx
new file mode 100644
index 00000000..32fba7e0
--- /dev/null
+++ b/client/src/components/ui/image-card.tsx
@@ -0,0 +1,99 @@
+import Image from "next/image";
+import { useRouter } from "next/router";
+import React from "react";
+
+interface ImageCardProps {
+ imageSrc?: string;
+ imageAlt?: string;
+ /** Optional content rendered on the front (over the image or placeholder). */
+ children?: React.ReactNode;
+ /** Optional content rendered on the back when hovering/focused. */
+ backContent?: React.ReactNode;
+ /** Optional href for navigation when clicking the front face */
+ href?: string;
+}
+
+const ImageCard = ({
+ imageSrc,
+ imageAlt = "Image",
+ children,
+ backContent,
+ href,
+}: ImageCardProps) => {
+ const router = useRouter();
+ const [isFlipped, setIsFlipped] = React.useState(false);
+ const [isMobile, setIsMobile] = React.useState(false);
+
+ React.useEffect(() => {
+ const checkMobile = () => {
+ setIsMobile(window.innerWidth < 768);
+ };
+
+ checkMobile();
+ window.addEventListener("resize", checkMobile);
+ return () => window.removeEventListener("resize", checkMobile);
+ }, []);
+
+ const handleClick = () => {
+ // On mobile, navigate directly if href is provided
+ if (isMobile && href) {
+ router.push(href);
+ } else if (backContent) {
+ // On desktop, toggle flip state
+ setIsFlipped(!isFlipped);
+ }
+ };
+
+ return (
+
+
+
+ {imageSrc ? (
+ <>
+
+ {children && (
+
+ {children}
+
+ )}
+ >
+ ) : (
+
+ {children || No Image}
+
+ )}
+
+
+ {backContent && (
+
+ {backContent}
+
+ )}
+
+
+ );
+};
+
+export default ImageCard;
diff --git a/client/src/components/ui/image-placeholder.tsx b/client/src/components/ui/image-placeholder.tsx
new file mode 100644
index 00000000..c694f378
--- /dev/null
+++ b/client/src/components/ui/image-placeholder.tsx
@@ -0,0 +1,21 @@
+import Image from "next/image";
+import React from "react";
+
+const ImagePlaceholder = () => {
+ return (
+
+ );
+};
+export default ImagePlaceholder;
diff --git a/client/src/components/ui/modal/error-modal.tsx b/client/src/components/ui/modal/error-modal.tsx
new file mode 100644
index 00000000..ba1c2404
--- /dev/null
+++ b/client/src/components/ui/modal/error-modal.tsx
@@ -0,0 +1,45 @@
+import React, { useState } from "react";
+
+interface ErrorModalProps {
+ message: string | null;
+ onClose: () => void;
+}
+
+const ErrorModal = ({ message, onClose = () => {} }: ErrorModalProps) => {
+ const [isVisible, setIsVisible] = useState(true);
+ if (!isVisible || !message) {
+ return null;
+ }
+
+ function onModalClose() {
+ setIsVisible(false);
+ onClose();
+ }
+
+ return (
+ // Backdrop overlay
+
+ {/* Modal content container */}
+
e.stopPropagation()} // Prevent closing when clicking inside the modal
+ >
+
Error
+
{message}
+
+
+
+
+
+ );
+};
+
+export default ErrorModal;
diff --git a/client/src/hooks/use-artwork-data.ts b/client/src/hooks/use-artwork-data.ts
new file mode 100644
index 00000000..60a65adf
--- /dev/null
+++ b/client/src/hooks/use-artwork-data.ts
@@ -0,0 +1,58 @@
+import { Art } from "@/types/art";
+
+export const generateMockArtworks = (count: number): Art[] => {
+ const artworks: Art[] = [];
+ for (let i = 1; i <= count; i++) {
+ artworks.push({
+ id: i,
+ name: `Artwork ${i}`,
+ description: "Mock artwork description",
+ //source_game: "Mock Game",
+ media: "",
+ active: true,
+ contributors: [
+ {
+ id: i * 10 + 1,
+ art_id: i,
+ member_name: "Contributor 1",
+ role: "artist",
+ },
+ {
+ id: i * 10 + 2,
+ art_id: i,
+ member_name: "Contributor 2",
+ role: "designer",
+ },
+ ],
+ //created_at: new Date().toISOString(),
+ });
+ }
+ return artworks;
+};
+
+export const generateMockArtwork = (id: string): Art => {
+ return {
+ id: Number(id),
+ name: "Mock Artwork Title",
+ description:
+ "Lorem ipsum dolor sit amet. Non numquam dicta nam autem dicta 33 error molestias et repellat consequatur eum iste expedita est dolorem libero et quas provident!",
+ //source_game: "Mock Game",
+ media: "",
+ active: true,
+ //created_at: new Date().toISOString(),
+ contributors: [
+ {
+ id: 1,
+ art_id: Number(id),
+ member_name: "Contributor 1",
+ role: "user1",
+ },
+ {
+ id: 2,
+ art_id: Number(id),
+ member_name: "Contributor 2",
+ role: "user2",
+ },
+ ],
+ };
+};
diff --git a/client/src/pages/artwork/[id].tsx b/client/src/pages/artwork/[id].tsx
new file mode 100644
index 00000000..064e8e18
--- /dev/null
+++ b/client/src/pages/artwork/[id].tsx
@@ -0,0 +1,178 @@
+import { GetServerSideProps } from "next";
+import Image from "next/image";
+import { useRouter } from "next/navigation";
+
+import GoBackButton from "@/components/ui/go-back-button";
+import ImagePlaceholder from "@/components/ui/image-placeholder";
+import ErrorModal from "@/components/ui/modal/error-modal";
+import api from "@/lib/api";
+import { Art } from "@/types/art";
+
+interface ArtworkPageProps {
+ artwork?: Art;
+ error?: string;
+}
+
+function displayContributors(artwork: Art) {
+ return (
+
+
+
+
+ {artwork.contributors?.map((contributor) => (
+
+
+ {contributor.member_name}
+
+
+ ))}
+
+
+
+ );
+}
+
+export default function ArtworkPage({ artwork, error }: ArtworkPageProps) {
+ const router = useRouter();
+ if (error) {
+ return router.back()} />;
+ }
+ return (
+
+
+
+
+ {artwork!.media ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ {artwork!.name}
+
+
+
+
+ {artwork!.description}
+
+
+
+ {displayContributors(artwork!)}
+
+
+
+
+
+ {artwork!.name}
+
+
+
+
+ {artwork!.description}
+
+
+
+ {displayContributors(artwork!)}
+
+
+
+
+ TODO add footer
+
+
+ );
+}
+
+export const getServerSideProps: GetServerSideProps = async (
+ context,
+) => {
+ const { id } = context.params as { id: string };
+ try {
+ const artResponse = await api.get(`arts/${id}`);
+ const artwork = artResponse.data;
+ return { props: { artwork } };
+ } catch (err: unknown) {
+ return {
+ props: { error: (err as Error).message || "Failed to load artwork." },
+ };
+ }
+};
diff --git a/client/src/pages/artwork/index.tsx b/client/src/pages/artwork/index.tsx
new file mode 100644
index 00000000..3cb76285
--- /dev/null
+++ b/client/src/pages/artwork/index.tsx
@@ -0,0 +1,138 @@
+import { GetServerSideProps } from "next";
+import Image from "next/image";
+import Link from "next/link";
+import { useRouter } from "next/navigation";
+
+import ImageCard from "@/components/ui/image-card";
+import ErrorModal from "@/components/ui/modal/error-modal";
+import { generateMockArtworks } from "@/hooks/use-artwork-data";
+import api from "@/lib/api";
+import { Art } from "@/types/art";
+
+export interface PageResult {
+ count: number;
+ next: string;
+ previous: string;
+ results: T[];
+}
+
+interface ArtworksPageProps {
+ artworks?: PageResult;
+ error?: string;
+}
+
+const PLACEHOLDER_ICON = (
+
+
+
+);
+
+function renderArtworkCard(artwork: Art) {
+ return (
+
+
+
+ {artwork.name}
+
+
+ from GAME NAME
+
+
+ {artwork.description || "No description available."}
+
+
+
+ {artwork.contributors.length > 0 && (
+
+
+ Contributors
+
+
+ {artwork.contributors.map((contributor) => (
+
+ {contributor.member_name}
+
+ ))}
+
+
+ )}
+
+ e.stopPropagation()}
+ >
+ VIEW FULL DETAILS
+
+
+ }
+ >
+ {!artwork.media && PLACEHOLDER_ICON}
+
+ );
+}
+
+export default function ArtworksPage({ artworks, error }: ArtworksPageProps) {
+ const router = useRouter();
+ if (error) {
+ return router.back()} />;
+ }
+
+ return (
+
+
+
+ FEATURED
+
+
+
+ {artworks?.results.slice(0, 3).map(renderArtworkCard)}
+
+
+
+ );
+}
+
+export const getServerSideProps: GetServerSideProps<
+ ArtworksPageProps
+> = async () => {
+ try {
+ const res = await api.get>("arts");
+ return { props: { artworks: res.data } };
+ //} catch (err: unknown) {
+ } catch {
+ // return {
+ // props: { error: (err as Error).message || "Failed to load artworks." },
+ // };
+
+ // Fallback to mock data on error
+ const mockArtworks = generateMockArtworks(3);
+ return {
+ props: {
+ artworks: {
+ results: mockArtworks,
+ count: mockArtworks.length,
+ next: "",
+ previous: "",
+ },
+ },
+ };
+ }
+};
diff --git a/client/src/types/art-contributor.ts b/client/src/types/art-contributor.ts
new file mode 100644
index 00000000..8afd03b5
--- /dev/null
+++ b/client/src/types/art-contributor.ts
@@ -0,0 +1,6 @@
+export interface ArtContributor {
+ id: number;
+ art_id: number;
+ member_name: string;
+ role: string;
+}
diff --git a/client/src/types/art.ts b/client/src/types/art.ts
new file mode 100644
index 00000000..ebb22e13
--- /dev/null
+++ b/client/src/types/art.ts
@@ -0,0 +1,10 @@
+import { ArtContributor } from "./art-contributor";
+
+export interface Art {
+ id: number;
+ name: string;
+ description: string;
+ media: string;
+ active: boolean;
+ contributors: ArtContributor[];
+}
diff --git a/client/tailwind.config.ts b/client/tailwind.config.ts
index 52306b8e..156c4005 100644
--- a/client/tailwind.config.ts
+++ b/client/tailwind.config.ts
@@ -70,6 +70,12 @@ const config = {
neutral_4: "var(--neutral-4)",
light_1: "var(--light-1)",
light_2: "var(--light-2)",
+ light_3: "var(--light-3)",
+ light_alt: "var(--light-alt)",
+ light_alt_2: "var(--light-alt-2)",
+ logo_blue_2: "var(--logo-blue-2)",
+ logo_blue_1: "var(--logo-blue-1)",
+ error: "var(--error)",
},
borderRadius: {
lg: "var(--radius)",
diff --git a/server/game_dev/admin.py b/server/game_dev/admin.py
index d07b4da7..3b95f3a6 100644
--- a/server/game_dev/admin.py
+++ b/server/game_dev/admin.py
@@ -1,5 +1,5 @@
from django.contrib import admin
-from .models import Member, Game, Event, GameContributor, GameShowcase, Committee
+from .models import Art, ArtContributor, Member, Game, Event, GameContributor, GameShowcase, Committee
class MemberAdmin(admin.ModelAdmin):
@@ -34,4 +34,6 @@ class CommitteeAdmin(admin.ModelAdmin):
admin.site.register(Game, GamesAdmin)
admin.site.register(GameContributor, GameContributorAdmin)
admin.site.register(GameShowcase, GameShowcaseAdmin)
+admin.site.register(Art)
+admin.site.register(ArtContributor)
admin.site.register(Committee, CommitteeAdmin)
diff --git a/server/game_dev/migrations/0005_art_artcontributor.py b/server/game_dev/migrations/0005_art_artcontributor.py
new file mode 100644
index 00000000..f3d0c905
--- /dev/null
+++ b/server/game_dev/migrations/0005_art_artcontributor.py
@@ -0,0 +1,68 @@
+# Generated by Django 5.1.14 on 2025-11-28 17:32
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0004_alter_event_date"),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name="Art",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("name", models.CharField(max_length=200)),
+ ("description", models.CharField(max_length=200)),
+ ("path_to_media", models.CharField(max_length=500)),
+ ("active", models.BooleanField()),
+ ],
+ ),
+ migrations.CreateModel(
+ name="ArtContributor",
+ fields=[
+ (
+ "id",
+ models.BigAutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name="ID",
+ ),
+ ),
+ ("role", models.CharField(max_length=100)),
+ (
+ "art",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="contributors",
+ to="game_dev.art",
+ ),
+ ),
+ (
+ "member",
+ models.ForeignKey(
+ on_delete=django.db.models.deletion.CASCADE,
+ related_name="art_contributions",
+ to="game_dev.member",
+ ),
+ ),
+ ],
+ options={
+ "verbose_name": "Art Contributor",
+ "verbose_name_plural": "Art Contributors",
+ "unique_together": {("art", "member")},
+ },
+ ),
+ ]
diff --git a/server/game_dev/migrations/0006_rename_path_to_media_to_media.py b/server/game_dev/migrations/0006_rename_path_to_media_to_media.py
new file mode 100644
index 00000000..95713557
--- /dev/null
+++ b/server/game_dev/migrations/0006_rename_path_to_media_to_media.py
@@ -0,0 +1,23 @@
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0005_art_artcontributor"),
+ ]
+
+ operations = [
+ # First, rename the field
+ migrations.RenameField(
+ model_name="art",
+ old_name="path_to_media",
+ new_name="media",
+ ),
+ # Then, alter the field to ImageField
+ migrations.AlterField(
+ model_name="art",
+ name="media",
+ field=models.ImageField(upload_to='art_images/'),
+ ),
+ ]
diff --git a/server/game_dev/migrations/0007_alter_artcontributor_unique_together_and_more.py b/server/game_dev/migrations/0007_alter_artcontributor_unique_together_and_more.py
new file mode 100644
index 00000000..3c917f6b
--- /dev/null
+++ b/server/game_dev/migrations/0007_alter_artcontributor_unique_together_and_more.py
@@ -0,0 +1,33 @@
+# Generated by Django 5.1.15 on 2026-01-16 15:09
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0006_rename_path_to_media_to_media"),
+ ]
+
+ operations = [
+ migrations.AlterUniqueTogether(
+ name="artcontributor",
+ unique_together=set(),
+ ),
+ migrations.AlterField(
+ model_name="art",
+ name="active",
+ field=models.BooleanField(default=True),
+ ),
+ migrations.AlterField(
+ model_name="art",
+ name="media",
+ field=models.ImageField(upload_to="art/"),
+ ),
+ migrations.AddConstraint(
+ model_name="artcontributor",
+ constraint=models.UniqueConstraint(
+ fields=("art", "member"), name="unique_art_member"
+ ),
+ ),
+ ]
diff --git a/server/game_dev/migrations/0008_merge_20260130_2216.py b/server/game_dev/migrations/0008_merge_20260130_2216.py
new file mode 100644
index 00000000..fda3f25b
--- /dev/null
+++ b/server/game_dev/migrations/0008_merge_20260130_2216.py
@@ -0,0 +1,13 @@
+# Generated by Django 6.0 on 2026-01-30 14:16
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0005_alter_member_profile_picture"),
+ ("game_dev", "0007_alter_artcontributor_unique_together_and_more"),
+ ]
+
+ operations = []
diff --git a/server/game_dev/migrations/0010_merge_20260131_1145.py b/server/game_dev/migrations/0010_merge_20260131_1145.py
new file mode 100644
index 00000000..b998ef79
--- /dev/null
+++ b/server/game_dev/migrations/0010_merge_20260131_1145.py
@@ -0,0 +1,13 @@
+# Generated by Django 5.1.15 on 2026-01-31 03:45
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0008_merge_20260130_2216"),
+ ("game_dev", "0009_merge_20260131_1044"),
+ ]
+
+ operations = []
diff --git a/server/game_dev/migrations/0011_merge_20260214_1212.py b/server/game_dev/migrations/0011_merge_20260214_1212.py
new file mode 100644
index 00000000..8568c504
--- /dev/null
+++ b/server/game_dev/migrations/0011_merge_20260214_1212.py
@@ -0,0 +1,13 @@
+# Generated by Django 6.0 on 2026-02-14 04:12
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("game_dev", "0010_merge_20260131_1118"),
+ ("game_dev", "0010_merge_20260131_1145"),
+ ]
+
+ operations = []
diff --git a/server/game_dev/models.py b/server/game_dev/models.py
index 3c39a421..a730ae3d 100644
--- a/server/game_dev/models.py
+++ b/server/game_dev/models.py
@@ -95,3 +95,30 @@ def get_member(self):
def __str__(self):
return self.id.name
+
+
+class Art(models.Model):
+ name = models.CharField(null=False, max_length=200)
+ description = models.CharField(max_length=200,)
+ source_game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name='art_pieces')
+ media = models.ImageField(upload_to='art/', null=False)
+ active = models.BooleanField(default=True)
+
+ def __str__(self):
+ return str(self.name)
+
+
+class ArtContributor(models.Model):
+ art = models.ForeignKey('Art', on_delete=models.CASCADE, related_name='contributors')
+ member = models.ForeignKey('Member', on_delete=models.CASCADE, related_name='art_contributions')
+ role = models.CharField(max_length=100)
+
+ class Meta:
+ constraints = [
+ models.UniqueConstraint(fields=['art', 'member'], name='unique_art_member')
+ ]
+ verbose_name = 'Art Contributor'
+ verbose_name_plural = 'Art Contributors'
+
+ def __str__(self):
+ return f"{self.member.name} - {self.art.name} ({self.role})"
diff --git a/server/game_dev/serializers.py b/server/game_dev/serializers.py
index a9e5c811..6c0ff7a2 100644
--- a/server/game_dev/serializers.py
+++ b/server/game_dev/serializers.py
@@ -1,5 +1,5 @@
from rest_framework import serializers
-from .models import Event, Game, Member, GameShowcase, GameContributor
+from .models import Event, Game, Art, ArtContributor, Member, GameShowcase, GameContributor
class EventSerializer(serializers.ModelSerializer):
@@ -68,6 +68,23 @@ def get_contributors(self, obj):
return ShowcaseContributorSerializer(contributors, many=True).data
+class ArtContributorSerializer(serializers.ModelSerializer):
+ member_name = serializers.CharField(source='member.name', read_only=True)
+ art_id = serializers.IntegerField(source='art.id', read_only=True)
+
+ class Meta:
+ model = ArtContributor
+ fields = ['id', 'art_id', 'member', 'member_name', 'role']
+
+
+class ArtSerializer(serializers.ModelSerializer):
+ contributors = ArtContributorSerializer(many=True, read_only=True)
+
+ class Meta:
+ model = Art
+ fields = ['id', 'name', 'description', 'media', 'active', 'contributors']
+
+
class MemberSerializer(serializers.ModelSerializer):
class Meta:
model = Member
diff --git a/server/game_dev/views.py b/server/game_dev/views.py
index 40ea5457..8f2af698 100644
--- a/server/game_dev/views.py
+++ b/server/game_dev/views.py
@@ -1,6 +1,6 @@
from rest_framework import generics
-from .serializers import GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer
-from .models import Game, GameShowcase, Event, Member, Committee
+from .serializers import GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer, ArtSerializer
+from .models import Game, GameShowcase, Event, Member, Committee, Art
from django.utils import timezone
from rest_framework.views import APIView
from rest_framework.response import Response
@@ -96,3 +96,14 @@ def get_queryset(self):
except Committee.DoesNotExist:
outputList.append(placeholderMember)
return outputList
+
+
+class ArtDetailAPIView(generics.RetrieveAPIView):
+ """
+ GET /api/artworks//
+ """
+ serializer_class = ArtSerializer
+ lookup_field = "id"
+
+ def get_queryset(self):
+ return Art.objects.all()
diff --git a/server/poetry.lock b/server/poetry.lock
index 9e7859f1..34f6c925 100644
--- a/server/poetry.lock
+++ b/server/poetry.lock
@@ -265,127 +265,111 @@ files = [
[[package]]
name = "pillow"
-version = "11.3.0"
-description = "Python Imaging Library (Fork)"
+version = "12.1.1"
+description = "Python Imaging Library (fork)"
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["main"]
files = [
- {file = "pillow-11.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1b9c17fd4ace828b3003dfd1e30bff24863e0eb59b535e8f80194d9cc7ecf860"},
- {file = "pillow-11.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:65dc69160114cdd0ca0f35cb434633c75e8e7fad4cf855177a05bf38678f73ad"},
- {file = "pillow-11.3.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7107195ddc914f656c7fc8e4a5e1c25f32e9236ea3ea860f257b0436011fddd0"},
- {file = "pillow-11.3.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:cc3e831b563b3114baac7ec2ee86819eb03caa1a2cef0b481a5675b59c4fe23b"},
- {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f1f182ebd2303acf8c380a54f615ec883322593320a9b00438eb842c1f37ae50"},
- {file = "pillow-11.3.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4445fa62e15936a028672fd48c4c11a66d641d2c05726c7ec1f8ba6a572036ae"},
- {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:71f511f6b3b91dd543282477be45a033e4845a40278fa8dcdbfdb07109bf18f9"},
- {file = "pillow-11.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:040a5b691b0713e1f6cbe222e0f4f74cd233421e105850ae3b3c0ceda520f42e"},
- {file = "pillow-11.3.0-cp310-cp310-win32.whl", hash = "sha256:89bd777bc6624fe4115e9fac3352c79ed60f3bb18651420635f26e643e3dd1f6"},
- {file = "pillow-11.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:19d2ff547c75b8e3ff46f4d9ef969a06c30ab2d4263a9e287733aa8b2429ce8f"},
- {file = "pillow-11.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:819931d25e57b513242859ce1876c58c59dc31587847bf74cfe06b2e0cb22d2f"},
- {file = "pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722"},
- {file = "pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288"},
- {file = "pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d"},
- {file = "pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494"},
- {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58"},
- {file = "pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f"},
- {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e"},
- {file = "pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94"},
- {file = "pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0"},
- {file = "pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac"},
- {file = "pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd"},
- {file = "pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4"},
- {file = "pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69"},
- {file = "pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d"},
- {file = "pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6"},
- {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7"},
- {file = "pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024"},
- {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809"},
- {file = "pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d"},
- {file = "pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149"},
- {file = "pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d"},
- {file = "pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542"},
- {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd"},
- {file = "pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8"},
- {file = "pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f"},
- {file = "pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c"},
- {file = "pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd"},
- {file = "pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e"},
- {file = "pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1"},
- {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805"},
- {file = "pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8"},
- {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2"},
- {file = "pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b"},
- {file = "pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3"},
- {file = "pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51"},
- {file = "pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580"},
- {file = "pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e"},
- {file = "pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d"},
- {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced"},
- {file = "pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c"},
- {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8"},
- {file = "pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59"},
- {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe"},
- {file = "pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c"},
- {file = "pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788"},
- {file = "pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31"},
- {file = "pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e"},
- {file = "pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12"},
- {file = "pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a"},
- {file = "pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632"},
- {file = "pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673"},
- {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027"},
- {file = "pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77"},
- {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874"},
- {file = "pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a"},
- {file = "pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214"},
- {file = "pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635"},
- {file = "pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6"},
- {file = "pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae"},
- {file = "pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653"},
- {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6"},
- {file = "pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36"},
- {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b"},
- {file = "pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477"},
- {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50"},
- {file = "pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b"},
- {file = "pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12"},
- {file = "pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db"},
- {file = "pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa"},
- {file = "pillow-11.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:48d254f8a4c776de343051023eb61ffe818299eeac478da55227d96e241de53f"},
- {file = "pillow-11.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7aee118e30a4cf54fdd873bd3a29de51e29105ab11f9aad8c32123f58c8f8081"},
- {file = "pillow-11.3.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:23cff760a9049c502721bdb743a7cb3e03365fafcdfc2ef9784610714166e5a4"},
- {file = "pillow-11.3.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6359a3bc43f57d5b375d1ad54a0074318a0844d11b76abccf478c37c986d3cfc"},
- {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:092c80c76635f5ecb10f3f83d76716165c96f5229addbd1ec2bdbbda7d496e06"},
- {file = "pillow-11.3.0-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadc9e0ea0a2431124cde7e1697106471fc4c1da01530e679b2391c37d3fbb3a"},
- {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6a418691000f2a418c9135a7cf0d797c1bb7d9a485e61fe8e7722845b95ef978"},
- {file = "pillow-11.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:97afb3a00b65cc0804d1c7abddbf090a81eaac02768af58cbdcaaa0a931e0b6d"},
- {file = "pillow-11.3.0-cp39-cp39-win32.whl", hash = "sha256:ea944117a7974ae78059fcc1800e5d3295172bb97035c0c1d9345fca1419da71"},
- {file = "pillow-11.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:e5c5858ad8ec655450a7c7df532e9842cf8df7cc349df7225c60d5d348c8aada"},
- {file = "pillow-11.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:6abdbfd3aea42be05702a8dd98832329c167ee84400a1d1f61ab11437f1717eb"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3cee80663f29e3843b68199b9d6f4f54bd1d4a6b59bdd91bceefc51238bcb967"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b5f56c3f344f2ccaf0dd875d3e180f631dc60a51b314295a3e681fe8cf851fbe"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e67d793d180c9df62f1f40aee3accca4829d3794c95098887edc18af4b8b780c"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d000f46e2917c705e9fb93a3606ee4a819d1e3aa7a9b442f6444f07e77cf5e25"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:527b37216b6ac3a12d7838dc3bd75208ec57c1c6d11ef01902266a5a0c14fc27"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be5463ac478b623b9dd3937afd7fb7ab3d79dd290a28e2b6df292dc75063eb8a"},
- {file = "pillow-11.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8dc70ca24c110503e16918a658b869019126ecfe03109b754c402daff12b3d9f"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7"},
- {file = "pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8"},
- {file = "pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523"},
+ {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"},
+ {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"},
+ {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"},
+ {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"},
+ {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"},
+ {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"},
+ {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"},
+ {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"},
+ {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"},
+ {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"},
+ {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"},
+ {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"},
+ {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"},
+ {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"},
+ {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"},
+ {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"},
+ {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"},
+ {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"},
+ {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"},
+ {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"},
+ {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"},
+ {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"},
+ {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"},
+ {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"},
+ {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"},
+ {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"},
+ {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"},
+ {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"},
+ {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"},
+ {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"},
+ {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"},
+ {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"},
+ {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"},
+ {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"},
+ {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"},
+ {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"},
+ {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"},
+ {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"},
+ {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"},
+ {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"},
+ {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"},
+ {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"},
+ {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"},
+ {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"},
+ {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"},
+ {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"},
+ {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"},
+ {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"},
+ {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"},
+ {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"},
]
[package.extras]
docs = ["furo", "olefile", "sphinx (>=8.2)", "sphinx-autobuild", "sphinx-copybutton", "sphinx-inline-tabs", "sphinxext-opengraph"]
fpx = ["olefile"]
mic = ["olefile"]
-test-arrow = ["pyarrow"]
-tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
-typing = ["typing-extensions ; python_version < \"3.10\""]
+test-arrow = ["arro3-compute", "arro3-core", "nanoarrow", "pyarrow"]
+tests = ["check-manifest", "coverage (>=7.4.2)", "defusedxml", "markdown2", "olefile", "packaging", "pyroma (>=5)", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "trove-classifiers (>=2024.10.12)"]
xmp = ["defusedxml"]
[[package]]
@@ -493,18 +477,18 @@ files = [
[[package]]
name = "sqlparse"
-version = "0.5.1"
+version = "0.5.4"
description = "A non-validating SQL parser."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
- {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"},
- {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"},
+ {file = "sqlparse-0.5.4-py3-none-any.whl", hash = "sha256:99a9f0314977b76d776a0fcb8554de91b9bb8a18560631d6bc48721d07023dcb"},
+ {file = "sqlparse-0.5.4.tar.gz", hash = "sha256:4396a7d3cf1cd679c1be976cf3dc6e0a51d0111e87787e7a8d780e7d5a998f9e"},
]
[package.extras]
-dev = ["build", "hatch"]
+dev = ["build"]
doc = ["sphinx"]
[[package]]
@@ -603,4 +587,4 @@ files = [
[metadata]
lock-version = "2.1"
python-versions = "^3.12"
-content-hash = "f804c2f3998772b91e34ad214e5fcafe900bec97675f73046d3bcc79aba0f7db"
+content-hash = "9576347c536499de99b323235e5722ecff72a250598b689f042441da6d57411c"