diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..dfedc172f --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +frontend/ @bates64 diff --git a/.github/ISSUE_TEMPLATE/create-or-update-a-compiler-preset.md b/.github/ISSUE_TEMPLATE/create-or-update-a-compiler-preset.md index 92e9d9fe3..107dfc996 100644 --- a/.github/ISSUE_TEMPLATE/create-or-update-a-compiler-preset.md +++ b/.github/ISSUE_TEMPLATE/create-or-update-a-compiler-preset.md @@ -7,7 +7,7 @@ assignees: '' --- -I would like to create/update (delete as applicable) a compiler preset on decomp.me. +I would like to create/update a compiler preset on decomp.me. - **Preset Name:** e.g. `Superfrog 64` - **Preset ID (when updating):** e.g. `13` (see [Compiler Presets API](https://decomp.me/api/preset)) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ffc8d59ab..7acb29259 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -169,6 +169,7 @@ jobs: --build-arg ENABLE_GC_WII_SUPPORT=YES \ --build-arg ENABLE_PS2_SUPPORT=YES \ --build-arg ENABLE_SATURN_SUPPORT=YES \ + --build-arg ENABLE_DREAMCAST_SUPPORT=YES \ --build-arg ENABLE_WIN32_SUPPORT=YES - name: Run tests run: |- @@ -181,7 +182,6 @@ jobs: -v $(pwd)/local_files:/local_files \ -v $(pwd)/compilers:/compilers \ -v $(pwd)/libraries:/libraries \ - --tmpfs /dev/shm:exec,uid=1000,gid=1000,size=64M,mode=0700 \ --security-opt apparmor=unconfined \ --security-opt seccomp=unconfined \ --entrypoint /bin/bash \ @@ -197,6 +197,7 @@ jobs: poetry install --no-root && \ poetry run compilers/download.py --compilers-dir ${COMPILER_BASE_PATH} && \ poetry run libraries/download.py --libraries-dir ${LIBRARY_BASE_PATH} && \ + for r in wine/*.reg; do regedit $r; done && \ poetry run python manage.py test' frontend_lint: diff --git a/backend/Dockerfile b/backend/Dockerfile index 46f1646b7..ac52edda4 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -61,7 +61,7 @@ RUN apt-get -y update && apt-get install -y \ && rm -rf /var/lib/apt/lists/* RUN curl -sSL https://install.python-poetry.org/ | \ - POETRY_VERSION=1.6.1 POETRY_HOME=/etc/poetry python3.10 - + POETRY_VERSION=1.8.3 POETRY_HOME=/etc/poetry python3.10 - COPY --from=nsjail /nsjail/nsjail /bin/nsjail @@ -77,16 +77,20 @@ RUN add-apt-repository -y ppa:dosemu2/ppa && \ ARG ENABLE_MSDOS_SUPPORT ARG ENABLE_PS2_SUPPORT ARG ENABLE_WIN32_SUPPORT +ARG ENABLE_DREAMCAST_SUPPORT RUN if [ "${ENABLE_MSDOS_SUPPORT}" = "YES" ] || \ [ "${ENABLE_PS2_SUPPORT}" = "YES" ] || \ + [ "${ENABLE_DREAMCAST_SUPPORT}" = "YES" ] || \ [ "${ENABLE_WIN32_SUPPORT}" = "YES" ]; then \ dpkg --add-architecture i386 && apt-get update && \ apt-get install -y -o APT::Immediate-Configure=false \ wine; \ fi +ARG ENABLE_PSP_SUPPORT + # Patched mips binutils -RUN if [ "${ENABLE_PS2_SUPPORT}" = "YES" ]; then \ +RUN if [ "${ENABLE_PS2_SUPPORT}" = "YES" ] || [ "${ENABLE_PSP_SUPPORT}" = "YES" ]; then \ wget "https://github.com/decompals/binutils-mips-ps2-decompals/releases/download/v0.4/binutils-mips-ps2-decompals-linux-x86-64.tar.gz" && \ tar xvzf binutils-mips-ps2-decompals-linux-x86-64.tar.gz -C /usr/bin mips-ps2-decompals-as mips-ps2-decompals-nm mips-ps2-decompals-objdump && \ rm binutils-mips-ps2-decompals-linux-x86-64.tar.gz && \ @@ -128,6 +132,7 @@ USER user RUN if [ "${ENABLE_MSDOS_SUPPORT}" = "YES" ] || \ [ "${ENABLE_NDS_ARM9_SUPPORT}" = "YES" ] || \ [ "${ENABLE_PS2_SUPPORT}" = "YES" ] || \ + [ "${ENABLE_DREAMCAST_SUPPORT}" = "YES" ] || \ [ "${ENABLE_WIN32_SUPPORT}" = "YES" ]; then \ wineboot --init; \ fi @@ -141,7 +146,6 @@ ARG ENABLE_N3DS_SUPPORT ARG ENABLE_N64_SUPPORT ARG ENABLE_NDS_ARM9_SUPPORT ARG ENABLE_PS1_SUPPORT -ARG ENABLE_PSP_SUPPORT ARG ENABLE_SATURN_SUPPORT ARG ENABLE_SWITCH_SUPPORT @@ -150,6 +154,7 @@ ENV ENABLE_GC_WII_SUPPORT=${ENABLE_GC_WII_SUPPORT} ENV ENABLE_MACOSX_SUPPORT=${ENABLE_MACOSX_SUPPORT} ENV ENABLE_MSDOS_SUPPORT=${ENABLE_MSDOS_SUPPORT} ENV ENABLE_N3DS_SUPPORT=${ENABLE_N3DS_SUPPORT} +ENV ENABLE_DREAMCAST_SUPPORT=${ENABLE_DREAMCAST_SUPPORT} ENV ENABLE_N64_SUPPORT=${ENABLE_N64_SUPPORT} ENV ENABLE_NDS_ARM9_SUPPORT=${ENABLE_NDS_ARM9_SUPPORT} ENV ENABLE_PS1_SUPPORT=${ENABLE_PS1_SUPPORT} diff --git a/backend/compilers/compilers.linux.yaml b/backend/compilers/compilers.linux.yaml index e0f15df69..6ebf64aef 100644 --- a/backend/compilers/compilers.linux.yaml +++ b/backend/compilers/compilers.linux.yaml @@ -8,9 +8,11 @@ gc_wii: - mwcc_233_163 - mwcc_233_163e - mwcc_233_163n + - mwcc_242_53 - mwcc_242_81 - mwcc_242_81r - mwcc_247_92 + - mwcc_247_92p1 - mwcc_247_105 - mwcc_247_107 - mwcc_247_108 @@ -24,9 +26,10 @@ gc_wii: - mwcc_42_140 - mwcc_42_142 - mwcc_43_145 - - mwcc_43_188 - mwcc_43_151 - mwcc_43_172 + - mwcc_43_188 + - mwcc_43_202 - mwcc_43_213 - prodg_35 - prodg_37 @@ -99,6 +102,7 @@ ps1: - psyq4.4 - psyq4.5 - psyq4.6 + - psyq_263_221 - gcc2.5.7-psx - gcc2.6.3-psx - gcc2.6.0-mipsel @@ -111,6 +115,7 @@ ps1: - gcc2.7.2.3-mipsel - gcc2.8.0-mipsel - gcc2.8.1-mipsel + - gcc2.8.1-psx - gcc2.91.66-mipsel - gcc2.95.2-mipsel @@ -168,6 +173,9 @@ psp: saturn: - cygnus-2.7-96Q3 +dreamcast: + - shc-v5.1r11 + macosx: - gcc-5026 - gcc-5363 @@ -191,3 +199,4 @@ win32: - msvc6.6 - msvc7.0 - msvc7.1 + - msvc8.0 diff --git a/backend/coreapp/admin.py b/backend/coreapp/admin.py index b076f08fe..561beb212 100644 --- a/backend/coreapp/admin.py +++ b/backend/coreapp/admin.py @@ -2,14 +2,13 @@ from .models.course import Course, CourseChapter, CourseScenario from .models.github import GitHubUser -from .models.preset import Preset +from .models.preset import Preset, PresetAdmin from .models.profile import Profile from .models.project import Project, ProjectMember from .models.scratch import ( Asm, Assembly, AssemblyAdmin, - CompilerConfig, Scratch, ScratchAdmin, ) @@ -19,8 +18,7 @@ admin.site.register(Asm) admin.site.register(Assembly, AssemblyAdmin) admin.site.register(Scratch, ScratchAdmin) -admin.site.register(CompilerConfig) -admin.site.register(Preset) +admin.site.register(Preset, PresetAdmin) admin.site.register(Project) admin.site.register(ProjectMember) admin.site.register(Course) diff --git a/backend/coreapp/asm_preludes/ps2.s b/backend/coreapp/asm_preludes/ps2.s index a6bb54fde..1b60ed9a3 100644 --- a/backend/coreapp/asm_preludes/ps2.s +++ b/backend/coreapp/asm_preludes/ps2.s @@ -1,21 +1,67 @@ -.macro glabel label - .global \label - .type \label, @function - \label: +.macro glabel name, visibility=global +.\visibility "\name" +.type "\name", @function +"\name": .endm -.macro dlabel label - .global \label - \label: +.macro dlabel name, visibility=global +.\visibility "\name" +.type "\name", @object +"\name": .endm -.macro jlabel label - \label: +.macro jlabel name, visibility=local +.\visibility "\name" +"\name": .endm .macro .late_rodata .section .rodata .endm +# Defines a sized symbol with function type. +# Usage: +# .fn my_function, local +# /* asm here */ +# .endfn my_function +.macro .fn name, visibility=global +.\visibility "\name" +.type "\name", @function +"\name": +.endm + +.macro .endfn name +.size "\name", . - "\name" +.endm + +# Defines a sized symbol with object type. +# Usage: +# .obj my_object, local +# /* data here */ +# .endobj my_object +.macro .obj name, visibility=global +.\visibility "\name" +.type "\name", @object +"\name": +.endm + +.macro .endobj name +.size "\name", . - "\name" +.endm + +# Defines a sized symbol without a type. +# Usage: +# .sym my_sym, local +# /* anything here */ +# .endsym my_sym +.macro .sym name, visibility=global +.\visibility "\name" +"\name": +.endm + +.macro .endsym name +.size "\name", . - "\name" +.endm + .set noat .set noreorder diff --git a/backend/coreapp/compiler_wrapper.py b/backend/coreapp/compiler_wrapper.py index 2da2dbf9f..2e0155a30 100644 --- a/backend/coreapp/compiler_wrapper.py +++ b/backend/coreapp/compiler_wrapper.py @@ -53,8 +53,8 @@ def lru_cache(maxsize: int = 128, typed: bool = False) -> Callable[[F], F]: @dataclass class DiffResult: - result: Dict[str, Any] - errors: str + result: Optional[Dict[str, Any]] = None + errors: Optional[str] = None @dataclass @@ -255,7 +255,6 @@ def assemble_asm(platform: Platform, asm: Asm) -> Assembly: hash=hash, arch=platform.arch, source_asm=asm, - elf_object=f"assembled({asm.data})".encode("UTF-8"), ) assembly.save() return assembly diff --git a/backend/coreapp/compilers.py b/backend/coreapp/compilers.py index c50389357..8e2ff3cf5 100644 --- a/backend/coreapp/compilers.py +++ b/backend/coreapp/compilers.py @@ -9,6 +9,7 @@ from coreapp.flags import ( COMMON_ARMCC_FLAGS, COMMON_CLANG_FLAGS, + COMMON_SHC_FLAGS, COMMON_GCC_FLAGS, COMMON_GCC_PS1_FLAGS, COMMON_GCC_PS2_FLAGS, @@ -36,6 +37,7 @@ PS2, PSP, SATURN, + DREAMCAST, SWITCH, WIN32, Platform, @@ -107,6 +109,12 @@ class ArmccCompiler(Compiler): library_include_flag: str = "-J" +@dataclass(frozen=True) +class SHCCompiler(Compiler): + flags: ClassVar[Flags] = COMMON_SHC_FLAGS + library_include_flag: str = "" + + @dataclass(frozen=True) class GCCCompiler(Compiler): is_gcc: ClassVar[bool] = True @@ -317,11 +325,18 @@ def available_platforms() -> List[Platform]: '(HOME="." /usr/bin/dosemu -quiet -dumb -f ${COMPILER_DIR}/dosemurc -K . -E "ASPSX.EXE -quiet object.os -o object.oo") && ' '${COMPILER_DIR}/psyq-obj-parser object.oo -o "$OUTPUT"' ) + PSYQ_CC = ( - 'cpp -P "$INPUT" | unix2dos | ' - '${WIBO} ${COMPILER_DIR}/CC1PSX.EXE -quiet ${COMPILER_FLAGS} -o "$OUTPUT".s && ' - '${WIBO} ${COMPILER_DIR}/ASPSX.EXE -quiet "$OUTPUT".s -o "$OUTPUT".obj && ' - '${COMPILER_DIR}/psyq-obj-parser "$OUTPUT".obj -o "$OUTPUT"' + 'cpp -P "${INPUT}" | unix2dos | ' + '${WIBO} ${COMPILER_DIR}/CC1PSX.EXE -quiet ${COMPILER_FLAGS} -o "${OUTPUT}".s && ' + '${WIBO} ${COMPILER_DIR}/ASPSX.EXE -quiet "${OUTPUT}".s -o "${OUTPUT}"bj && ' + '${COMPILER_DIR}/psyq-obj-parser "${OUTPUT}"bj -o "${OUTPUT}"' +) + +PSYQ_263_221 = GCCPS1Compiler( + id="psyq_263_221", + platform=PS1, + cc=PSYQ_MSDOS_CC, ) PSYQ33 = GCCPS1Compiler( @@ -348,51 +363,42 @@ def available_platforms() -> List[Platform]: cc=PSYQ_CC, ) -PSYQ41 = GCCPS1Compiler( - id="psyq4.1", +PSYQ43 = GCCPS1Compiler( + id="psyq4.3", platform=PS1, cc=PSYQ_CC, ) -PSYQ43 = GCCPS1Compiler( - id="psyq4.3", +PSYQ_CCPSX = ( + 'echo "[ccpsx]" >> SN.INI && ' + 'echo "compiler_path=${COMPILER_DIR//\\//\\\\}" >> SN.INI && ' + 'echo "assembler_path=${COMPILER_DIR//\\//\\\\}" >> SN.INI && ' + 'echo "tmpdir=/tmp" >> SN.INI && ' + 'SN_PATH=. ${WINE} ${COMPILER_DIR}/CCPSX.EXE -v -c ${COMPILER_FLAGS} "${INPUT}" -o "${OUTPUT}bj" && ' + '${COMPILER_DIR}/psyq-obj-parser "${OUTPUT}"bj -o "${OUTPUT}"' +) + +PSYQ41 = GCCPS1Compiler( + id="psyq4.1", platform=PS1, - cc=PSYQ_CC, + cc=PSYQ_CCPSX, ) PSYQ44 = GCCPS1Compiler( id="psyq4.4", platform=PS1, - cc=PSYQ_CC, + cc=PSYQ_CCPSX, ) PSYQ45 = GCCPS1Compiler( id="psyq4.5", platform=PS1, - cc=PSYQ_CC, + cc=PSYQ_CCPSX, ) PSYQ46 = GCCPS1Compiler( id="psyq4.6", platform=PS1, - cc=PSYQ_CC, -) - -PSYQ_CCPSX = ( - "echo ${OUTPUT} && " - "echo pwd is $(pwd) && " - 'echo "[ccpsx]" >> SN.INI && ' - 'echo "compiler_path=${COMPILER_DIR//\\//\\\\}" >> SN.INI && ' - 'echo "assembler_path=${COMPILER_DIR//\\//\\\\}" >> SN.INI && ' - 'echo "tmpdir=/tmp" >> SN.INI && ' - 'SN_PATH=. ${WIBO} ${COMPILER_DIR}/CCPSX.EXE -v -c ${COMPILER_FLAGS} "${INPUT}" -o "${OUTPUT}bj" && ' - '${COMPILER_DIR}/psyq-obj-parser "${OUTPUT}"bj -o "${OUTPUT}"' -) - -PSYQ44_CCPSX = GCCPS1Compiler( - id="psyq4.4-ccpsx", - base_compiler=PSYQ44, - platform=PS1, cc=PSYQ_CCPSX, ) @@ -473,6 +479,12 @@ def available_platforms() -> List[Platform]: cc=PS1_GCC, ) +GCC281_PSX = GCCPS1Compiler( + id="gcc2.8.1-psx", + platform=PS1, + cc=PS1_GCC, +) + GCC29166_MIPSEL = GCCPS1Compiler( id="gcc2.91.66-mipsel", platform=PS1, @@ -502,6 +514,15 @@ def available_platforms() -> List[Platform]: cc=SATURN_CC, ) +DREAMCAST_CC = ( + 'cat "$INPUT" | unix2dos > dos_src.c && ' + "cp -r ${COMPILER_DIR}/bin/* . && " + "(SHC_LIB=. SHC_TMP=. ${WINE} ${COMPILER_DIR}/bin/shc.exe dos_src.c ${COMPILER_FLAGS} -comment=nonest -cpu=sh4 -division=cpu -fpu=single -endian=little -extra=a=1800 -pic=0 -macsave=0 -sjis -string=const -aggressive=2 -object=dos_src.obj) && " + "${WIBO} ${COMPILER_DIR}/bin/elfcnv.exe dos_src.obj ${OUTPUT}" +) + +SHC_V51R11 = SHCCompiler(id="shc-v5.1r11", platform=DREAMCAST, cc=DREAMCAST_CC) + # PS2 EE_GCC29_990721 = GCCPS2Compiler( id="ee-gcc2.9-990721", @@ -1015,6 +1036,12 @@ def available_platforms() -> List[Platform]: cc=MWCCEPPC_CC, ) +MWCC_242_53 = MWCCWiiGCCompiler( + id="mwcc_242_53", + platform=GC_WII, + cc=MWCCEPPC_CC, +) + MWCC_242_81 = MWCCWiiGCCompiler( id="mwcc_242_81", platform=GC_WII, @@ -1033,6 +1060,12 @@ def available_platforms() -> List[Platform]: cc=MWCCEPPC_CC, ) +MWCC_247_92P1 = MWCCWiiGCCompiler( + id="mwcc_247_92p1", + platform=GC_WII, + cc=MWCCEPPC_CC, +) + MWCC_247_105 = MWCCWiiGCCompiler( id="mwcc_247_105", platform=GC_WII, @@ -1129,6 +1162,12 @@ def available_platforms() -> List[Platform]: cc=MWCCEPPC_CC, ) +MWCC_43_202 = MWCCWiiGCCompiler( + id="mwcc_43_202", + platform=GC_WII, + cc=MWCCEPPC_CC, +) + MWCC_43_213 = MWCCWiiGCCompiler( id="mwcc_43_213", platform=GC_WII, @@ -1300,7 +1339,7 @@ def available_platforms() -> List[Platform]: cc=MWCCARM_CC, ) -CL_WIN = '${WIBO} "${COMPILER_DIR}"/Bin/CL.EXE /c /nologo /IZ:"${COMPILER_DIR}"/Include/ ${COMPILER_FLAGS} /Fd"Z:/tmp/" /Bk"Z:/tmp/" /Fo"Z:${OUTPUT}" "Z:${INPUT}"' +CL_WIN = '${WIBO} "${COMPILER_DIR}/Bin/CL.EXE" /c /nologo /I"Z:${COMPILER_DIR}/Include/" ${COMPILER_FLAGS} /Fd"Z:/tmp/" /Bk"Z:/tmp/" /Fo"Z:${OUTPUT}" "Z:${INPUT}"' MSVC40 = MSVCCompiler( id="msvc4.0", @@ -1361,6 +1400,12 @@ def available_platforms() -> List[Platform]: platform=WIN32, cc=CL_WIN, ) + +MSVC80 = MSVCCompiler( + id="msvc8.0", + platform=WIN32, + cc=CL_WIN, +) # Watcom doesn't like '/' in paths passed to it so we need to replace them. WATCOM_ARGS = ' -zq -i="Z:${COMPILER_DIR}/h" -i="Z:${COMPILER_DIR}/h/nt" ${COMPILER_FLAGS} -fo"Z:${OUTPUT}" "Z:${INPUT}"' WATCOM_CC = ( @@ -1450,6 +1495,7 @@ def available_platforms() -> List[Platform]: CLANG_401, CLANG_800, # PS1 + PSYQ_263_221, PSYQ33, PSYQ35, PSYQ36, @@ -1459,7 +1505,6 @@ def available_platforms() -> List[Platform]: PSYQ44, PSYQ45, PSYQ46, - PSYQ44_CCPSX, GCC257_PSX, GCC263_PSX, GCC260_MIPSEL, @@ -1472,6 +1517,7 @@ def available_platforms() -> List[Platform]: GCC2723_MIPSEL, GCC280_MIPSEL, GCC281_MIPSEL, + GCC281_PSX, GCC29166_MIPSEL, GCC2952_MIPSEL, # PSP @@ -1490,6 +1536,8 @@ def available_platforms() -> List[Platform]: MWCCPSP_3_0_1_219, # Saturn CYGNUS_2_7_96Q3, + # Dreamcast + SHC_V51R11, # PS2 EE_GCC29_990721, EE_GCC29_991111, @@ -1554,9 +1602,11 @@ def available_platforms() -> List[Platform]: MWCC_233_163, MWCC_233_163E, MWCC_233_163N, + MWCC_242_53, MWCC_242_81, MWCC_242_81R, MWCC_247_92, + MWCC_247_92P1, MWCC_247_105, MWCC_247_107, MWCC_247_108, @@ -1573,6 +1623,7 @@ def available_platforms() -> List[Platform]: MWCC_43_151, MWCC_43_172, MWCC_43_188, + MWCC_43_202, MWCC_43_213, PRODG_35, PRODG_37, @@ -1620,6 +1671,7 @@ def available_platforms() -> List[Platform]: MSVC66, MSVC70, MSVC71, + MSVC80, # Watcom, DOS and Win32 WATCOM_105_C, WATCOM_105_CPP, diff --git a/backend/coreapp/diff_wrapper.py b/backend/coreapp/diff_wrapper.py index 626244565..086d74d4f 100644 --- a/backend/coreapp/diff_wrapper.py +++ b/backend/coreapp/diff_wrapper.py @@ -261,7 +261,7 @@ def diff( ) -> DiffResult: if platform == DUMMY: # Todo produce diff for dummy - return DiffResult({"rows": ["a", "b"]}, "") + return DiffResult({"rows": ["a", "b"]}) try: arch = asm_differ.get_arch(platform.arch or "") @@ -294,4 +294,4 @@ def diff( except Exception as e: raise DiffError(f"Error running asm-differ: {e}") - return DiffResult(result, "") + return DiffResult(result) diff --git a/backend/coreapp/flags.py b/backend/coreapp/flags.py index 9c31b5b92..478ed94c0 100644 --- a/backend/coreapp/flags.py +++ b/backend/coreapp/flags.py @@ -109,6 +109,15 @@ def to_json(self) -> Dict[str, Union[str, List[str]]]: Checkbox(id="clang_no_exceptions", flag="-fno-exceptions"), ] +COMMON_SHC_FLAGS: Flags = [ + FlagSet(id="shc_opt_level", flags=["-optimize=0", "-optimize=1"]), + FlagSet(id="shc_opt_type", flags=["-speed", "-size"]), + FlagSet(id="shc_round", flags=["-round=zero", "-round=nearest"]), + Checkbox(id="shc_debug", flag="-debug"), + Checkbox(id="shc_loop", flag="-loop"), + Checkbox(id="shc_inline", flag="-inline"), +] + COMMON_GCC_FLAGS: Flags = [ FlagSet(id="gcc_opt_level", flags=["-O0", "-O1", "-O2", "-O3"]), FlagSet( @@ -269,10 +278,12 @@ def to_json(self) -> Dict[str, Union[str, List[str]]]: id="msvc_opt_level", flags=["/Od", "/O1", "/O2", "/Os", "/Ot", "/Og", "/Ox"] ), FlagSet(id="msvc_codegen", flags=["/GB", "/G3", "/G4", "/G5", "/G6"]), + FlagSet(id="msvc_fp", flags=["/fp:precise", "/fp:strict", "/fp:fast"]), Checkbox("msvc_compile_cpp", "/TP"), Checkbox("msvc_use_rtti", "/GR"), Checkbox("msvc_use_ehsc", "/GX"), Checkbox("msvc_disable_stack_checking", "/Gs"), + Checkbox("msvc_disable_buffer_security_checks", "/GS-"), Checkbox("msvc_runtime_debug_checks", "/GZ"), Checkbox("msvc_cdecl", "/Gd"), Checkbox("msvc_fastcall", "/Gr"), diff --git a/backend/coreapp/migrations/0055_alter_preset_owner.py b/backend/coreapp/migrations/0055_alter_preset_owner.py new file mode 100644 index 000000000..fec26bf60 --- /dev/null +++ b/backend/coreapp/migrations/0055_alter_preset_owner.py @@ -0,0 +1,24 @@ +# Generated by Django 5.0.3 on 2024-05-23 06:50 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("coreapp", "0054_presets_owner"), + ] + + operations = [ + migrations.AlterField( + model_name="preset", + name="owner", + field=models.ForeignKey( + blank=True, + default=None, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="coreapp.profile", + ), + ), + ] diff --git a/backend/coreapp/migrations/0056_delete_compilerconfig.py b/backend/coreapp/migrations/0056_delete_compilerconfig.py new file mode 100644 index 000000000..a9d15bff4 --- /dev/null +++ b/backend/coreapp/migrations/0056_delete_compilerconfig.py @@ -0,0 +1,15 @@ +# Generated by Django 5.0.6 on 2024-05-26 15:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("coreapp", "0055_alter_preset_owner"), + ] + + operations = [ + migrations.DeleteModel( + name="CompilerConfig", + ), + ] diff --git a/backend/coreapp/models/preset.py b/backend/coreapp/models/preset.py index df5661331..b5f5f82da 100644 --- a/backend/coreapp/models/preset.py +++ b/backend/coreapp/models/preset.py @@ -1,6 +1,7 @@ from datetime import datetime from coreapp.models.scratch import LibrariesField +from django.contrib import admin from django.db import models from django.utils.timezone import now from rest_framework.request import Request @@ -38,3 +39,7 @@ def most_recent_updated(request: Request) -> datetime: if not Preset.objects.count() else Preset.objects.latest("last_updated").last_updated ) + + +class PresetAdmin(admin.ModelAdmin[Preset]): + raw_id_fields = ["owner"] diff --git a/backend/coreapp/models/scratch.py b/backend/coreapp/models/scratch.py index 4428850a7..d104a1205 100644 --- a/backend/coreapp/models/scratch.py +++ b/backend/coreapp/models/scratch.py @@ -45,14 +45,6 @@ class AssemblyAdmin(admin.ModelAdmin[Assembly]): raw_id_fields = ["source_asm"] -class CompilerConfig(models.Model): - # TODO: validate compiler and platform - compiler = models.CharField(max_length=100) - platform = models.CharField(max_length=100) - compiler_flags = models.TextField(max_length=1000, default="", blank=True) - diff_flags = models.JSONField(default=list, blank=True, null=True) - - class LibrariesField(models.JSONField): def __init__(self, **kwargs: Any): class MyEncoder(json.JSONEncoder): @@ -90,16 +82,10 @@ class Scratch(models.Model): description = models.TextField(max_length=5000, default="", blank=True) creation_time = models.DateTimeField(auto_now_add=True) last_updated = models.DateTimeField(auto_now=True) - compiler = models.CharField(max_length=100) # TODO: reference a CompilerConfig - platform = models.CharField( - max_length=100, blank=True - ) # TODO: reference a CompilerConfig - compiler_flags = models.TextField( - max_length=1000, default="", blank=True - ) # TODO: reference a CompilerConfig - diff_flags = models.JSONField( - default=list, blank=True - ) # TODO: reference a CompilerConfig + compiler = models.CharField(max_length=100) + platform = models.CharField(max_length=100, blank=True) + compiler_flags = models.TextField(max_length=1000, default="", blank=True) + diff_flags = models.JSONField(default=list, blank=True) preset = models.ForeignKey( "Preset", null=True, blank=True, on_delete=models.SET_NULL ) diff --git a/backend/coreapp/platforms.py b/backend/coreapp/platforms.py index d93e5db65..2df98526c 100644 --- a/backend/coreapp/platforms.py +++ b/backend/coreapp/platforms.py @@ -79,7 +79,7 @@ def from_id(platform_id: str) -> Platform: name="Microsoft DOS", description="x86", arch="i686", - assemble_cmd='jwasm -c -Fo"$OUTPUT" "$PRELUDE" "$INPUT"', + assemble_cmd='jwasm -c -Fo"$OUTPUT" -Fi"$PRELUDE" "$INPUT"', objdump_cmd="omf-objdump", nm_cmd="omf-nm", ) @@ -146,9 +146,9 @@ def from_id(platform_id: str) -> Platform: name="PlayStation Portable", description="MIPS (little-endian)", arch="mipsel:4000", - assemble_cmd='mips-linux-gnu-as -EL -march=gs464 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"', - objdump_cmd="mips-linux-gnu-objdump", - nm_cmd="mips-linux-gnu-nm", + assemble_cmd='mips-ps2-decompals-as -EL -march=gs464 -mabi=32 -o "$OUTPUT" "$PRELUDE" "$INPUT"', + objdump_cmd="mips-ps2-decompals-objdump", + nm_cmd="mips-ps2-decompals-nm", diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS, has_decompiler=True, ) @@ -164,12 +164,24 @@ def from_id(platform_id: str) -> Platform: diff_flags=COMMON_DIFF_FLAGS, ) +DREAMCAST = Platform( + id="dreamcast", + name="Dreamcast", + description="SH4 (little-endian)", + arch="sh4", + assemble_cmd='sh-elf-as --isa=sh4 --little --relax -o "$OUTPUT" "$PRELUDE" "$INPUT"', + objdump_cmd="sh-elf-objdump", + nm_cmd="sh-elf-nm", + diff_flags=COMMON_DIFF_FLAGS, + has_decompiler=False, +) + PS2 = Platform( id="ps2", name="PlayStation 2", description="MIPS (little-endian)", arch="mipsee", - assemble_cmd='mips-ps2-decompals-as -EL -march=r5900 -mabi=eabi -o "$OUTPUT" "$PRELUDE" "$INPUT"', + assemble_cmd='mips-ps2-decompals-as -EL -march=r5900 -o "$OUTPUT" "$PRELUDE" "$INPUT"', objdump_cmd="mips-ps2-decompals-objdump", nm_cmd="mips-ps2-decompals-nm", diff_flags=COMMON_DIFF_FLAGS + COMMON_MIPS_DIFF_FLAGS, @@ -241,6 +253,7 @@ def from_id(platform_id: str) -> Platform: "ps2": PS2, "psp": PSP, "saturn": SATURN, + "dreamcast": DREAMCAST, "macosx": MACOSX, "msdos": MSDOS, "win32": WIN32, diff --git a/backend/coreapp/sandbox.py b/backend/coreapp/sandbox.py index 13b61ce17..442a8e2a5 100644 --- a/backend/coreapp/sandbox.py +++ b/backend/coreapp/sandbox.py @@ -1,4 +1,5 @@ import contextlib +import getpass import logging import os import shlex @@ -50,6 +51,11 @@ def sandbox_command(self, mounts: List[Path], env: Dict[str, str]) -> List[str]: assert ":" not in str(self.path) assert ":" not in str(settings.WINEPREFIX) + + # wine-specific hacks + user = getpass.getuser() + (self.path / "Temp").mkdir(parents=True, exist_ok=True) + # fmt: off wrapper = [ str(settings.SANDBOX_NSJAIL_BIN_PATH), @@ -75,6 +81,7 @@ def sandbox_command(self, mounts: List[Path], env: Dict[str, str]) -> List[str]: "--rlimit_nofile", "soft", # the following are settings that can be removed once we are done with wine "--bindmount_ro", f"{settings.WINEPREFIX}:/wine", + "--bindmount", f"{self.path}/Temp:/wine/drive_c/users/{user}/Temp", "--env", "WINEDEBUG=-all", "--env", "WINEPREFIX=/wine", ] diff --git a/backend/coreapp/serializers.py b/backend/coreapp/serializers.py index c8ff10175..360df46fe 100644 --- a/backend/coreapp/serializers.py +++ b/backend/coreapp/serializers.py @@ -22,7 +22,7 @@ from .models.scratch import Scratch -def serialize_profile(request: Request, profile: Profile) -> Dict[str, Any]: +def serialize_profile(profile: Profile) -> Dict[str, Any]: if profile.user is None: return { "is_anonymous": True, @@ -55,7 +55,7 @@ def serialize_profile(request: Request, profile: Profile) -> Dict[str, Any]: class ProfileField(ProfileFieldBaseClass): def to_representation(self, profile: Profile) -> Dict[str, Any]: - return serialize_profile(self.context["request"], profile) + return serialize_profile(profile) class LibrarySerializer(serializers.Serializer[Library]): diff --git a/backend/coreapp/tests/test_compilation.py b/backend/coreapp/tests/test_compilation.py index 8ee41c6a5..867694e4f 100644 --- a/backend/coreapp/tests/test_compilation.py +++ b/backend/coreapp/tests/test_compilation.py @@ -260,6 +260,7 @@ def test_all_compilers(self, compiler: Compiler) -> None: diff_flags=[], ) - self.assertTrue("rows" in diff.result) - self.assertGreater(len(diff.result["rows"]), 0) - self.assertEqual("", diff.errors) + diff_result: dict[str, Any] = diff.result # type: ignore + self.assertTrue(diff_result is not None and "rows" in diff_result) + self.assertGreater(len(diff_result["rows"]), 0) + self.assertEqual(None, diff.errors) diff --git a/backend/coreapp/tests/test_preset.py b/backend/coreapp/tests/test_preset.py index 55990e200..3acd668aa 100644 --- a/backend/coreapp/tests/test_preset.py +++ b/backend/coreapp/tests/test_preset.py @@ -78,6 +78,22 @@ def test_user_create_preset(self) -> None: assert preset.owner is not None assert preset.owner.pk == self.user.pk + def test_list_compiler_with_custom_presets(self) -> None: + user = self.create_user() + self.create_preset(DUMMY_PRESET_DICT) + response = self.client.get(reverse("compiler")) + body = response.json() + + assert "platforms" in body + assert "dummy" in body["platforms"] + assert "presets" in body["platforms"]["dummy"] + assert len(body["platforms"]["dummy"]["presets"]) == 1 + assert ( + body["platforms"]["dummy"]["presets"][0]["name"] + == DUMMY_PRESET_DICT["name"] + ) + assert body["platforms"]["dummy"]["presets"][0]["owner"]["id"] == user.pk + def test_owner_can_delete_preset(self) -> None: self.create_user() preset = self.create_preset(DUMMY_PRESET_DICT) diff --git a/backend/coreapp/tests/test_scratch.py b/backend/coreapp/tests/test_scratch.py index 35d9db27e..4d4fbb486 100644 --- a/backend/coreapp/tests/test_scratch.py +++ b/backend/coreapp/tests/test_scratch.py @@ -3,7 +3,7 @@ from coreapp import compilers, platforms from coreapp.compilers import GCC281PM, IDO53, IDO71, MWCC_242_81, EE_GCC29_991111 -from coreapp.models.scratch import Assembly, CompilerConfig, Scratch +from coreapp.models.scratch import Assembly, Scratch from coreapp.platforms import GC_WII, N64 from coreapp.tests.common import BaseTestCase, requiresCompiler from coreapp.views.scratch import compile_scratch_update_score @@ -270,10 +270,6 @@ def test_fork_scratch(self) -> None: "name": "cat scratch", "libraries": [{"name": "directx", "version": "8.0"}], } - - compiler_config = CompilerConfig() - compiler_config.save() - scratch = self.create_scratch(scratch_dict) slug = scratch.slug @@ -326,7 +322,7 @@ def test_last_modified(self) -> None: response = self.client.head(reverse("scratch-detail", args=[scratch.slug])) self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assert_(response.headers.get("Last-Modified") is not None) + self.assertTrue(response.headers.get("Last-Modified") is not None) def test_if_modified_since(self) -> None: """ diff --git a/backend/coreapp/views/preset.py b/backend/coreapp/views/preset.py index 6e955fe72..e6cff0b08 100644 --- a/backend/coreapp/views/preset.py +++ b/backend/coreapp/views/preset.py @@ -2,6 +2,7 @@ from typing import Any import django_filters +from django import forms from rest_framework.exceptions import APIException from rest_framework.serializers import BaseSerializer @@ -37,16 +38,26 @@ def has_object_permission(self, request: Any, view: Any, obj: Any) -> bool: return False +class PresetFilterSet(django_filters.FilterSet): + owner = django_filters.CharFilter(widget=forms.HiddenInput()) + + class Meta: + model = Preset + fields = ["platform", "compiler", "owner"] + + class PresetViewSet(ModelViewSet): # type: ignore permission_classes = [IsAdminUser | IsOwnerOrReadOnly] queryset = Preset.objects.all() pagination_class = PresetPagination - filterset_fields = ["platform", "compiler", "owner"] + filterset_class = PresetFilterSet filter_backends = [ django_filters.rest_framework.DjangoFilterBackend, filters.SearchFilter, + filters.OrderingFilter, ] search_fields = ["id", "name", "platform", "compiler", "owner"] + ordering_fields = ["creation_time", "id", "name", "compiler"] def get_serializer_class(self) -> type[serializers.ModelSerializer[Preset]]: return PresetSerializer diff --git a/backend/coreapp/views/scratch.py b/backend/coreapp/views/scratch.py index 7a3bd5cd3..25588f700 100644 --- a/backend/coreapp/views/scratch.py +++ b/backend/coreapp/views/scratch.py @@ -1,3 +1,4 @@ +import base64 import hashlib import io import json @@ -56,8 +57,8 @@ def get_db_asm(request_asm: str) -> Asm: return asm -# 500 KB -MAX_FILE_SIZE = 500 * 1024 +# 1 MB +MAX_FILE_SIZE = 1000 * 1024 def cache_object(platform: Platform, file: File[Any]) -> Assembly: @@ -106,7 +107,7 @@ def diff_compilation(scratch: Scratch, compilation: CompilationResult) -> DiffRe diff_flags=scratch.diff_flags, ) except DiffError as e: - return DiffResult({}, str(e)) + return DiffResult(None, str(e)) def update_scratch_score(scratch: Scratch, diff: DiffResult) -> None: @@ -114,6 +115,8 @@ def update_scratch_score(scratch: Scratch, diff: DiffResult) -> None: Given a scratch and a diff, update the scratch's score """ + if diff.result is None: + return score = diff.result.get("current_score", scratch.score) max_score = diff.result.get("max_score", scratch.max_score) if score != scratch.score or max_score != scratch.max_score: @@ -169,23 +172,36 @@ def scratch_etag(request: Request, pk: Optional[str] = None) -> Optional[str]: ) -def is_asm_empty(asm: str) -> bool: - asm = asm.strip() +def is_contentful_asm(asm: Optional[Asm]) -> bool: + if asm is None: + return False - return asm == "" or asm == "nop" + asm_text = asm.data.strip() + + if asm_text == "" or asm_text == "nop": + return False + + return True def family_etag(request: Request, pk: Optional[str] = None) -> Optional[str]: scratch: Optional[Scratch] = Scratch.objects.filter(slug=pk).first() if scratch: - if scratch.target_assembly.source_asm is None or is_asm_empty( - scratch.target_assembly.source_asm.data - ): - family = Scratch.objects.filter(slug=scratch.slug) - else: + if is_contentful_asm(scratch.target_assembly.source_asm): + assert scratch.target_assembly.source_asm is not None + family = Scratch.objects.filter( target_assembly__source_asm__hash=scratch.target_assembly.source_asm.hash, ) + elif ( + scratch.target_assembly.elf_object is not None + and len(scratch.target_assembly.elf_object) > 0 + ): + family = Scratch.objects.filter( + target_assembly__hash=scratch.target_assembly.hash, + ) + else: + family = Scratch.objects.filter(slug=scratch.slug) return str(hash((family, request.headers.get("Accept")))) else: @@ -303,7 +319,7 @@ class ScratchViewSet( filters.OrderingFilter, ] search_fields = ["name", "diff_label"] - ordering_fields = ["score", "creation_time", "last_updated"] + ordering_fields = ["creation_time", "last_updated", "score"] def get_serializer_class(self) -> type[serializers.ModelSerializer[Scratch]]: if self.action == "list": @@ -361,6 +377,7 @@ def compile(self, request: Request, pk: str) -> Response: scratch: Scratch = self.get_object() # Apply partial + omit_diff = False if request.method == "POST": # TODO: use a serializer w/ validation if "compiler" in request.data: @@ -378,11 +395,16 @@ def compile(self, request: Request, pk: str) -> Response: if "libraries" in request.data: libs = [Library(**lib) for lib in request.data["libraries"]] scratch.libraries = libs + if "omit_diff" in request.data: + omit_diff = request.data["omit_diff"] compilation = compile_scratch(scratch) - diff = diff_compilation(scratch, compilation) + if omit_diff: + diff = DiffResult() + else: + diff = diff_compilation(scratch, compilation) - if request.method == "GET": + if not omit_diff and request.method == "GET": update_scratch_score(scratch, diff) compiler_output = "" @@ -391,14 +413,21 @@ def compile(self, request: Request, pk: str) -> Response: if diff.errors: compiler_output += diff.errors + "\n" - return Response( - { - "diff_output": diff.result, - "compiler_output": compiler_output, - "success": compilation.elf_object is not None - and len(compilation.elf_object) > 0, - } - ) + response = { + "diff_output": diff.result, + "compiler_output": compiler_output, + "success": compilation.elf_object is not None + and len(compilation.elf_object) > 0, + } + if omit_diff: + + def to_base64(obj: bytes) -> str: + return base64.b64encode(obj).decode("utf-8") + + response["left_object"] = to_base64(scratch.target_assembly.elf_object) + response["right_object"] = to_base64(compilation.elf_object) + + return Response(response) @action(detail=True, methods=["POST"]) def decompile(self, request: Request, pk: str) -> Response: @@ -517,14 +546,21 @@ def export(self, request: Request, pk: str) -> HttpResponse: def family(self, request: Request, pk: str) -> Response: scratch: Scratch = self.get_object() - if scratch.target_assembly.source_asm is None or is_asm_empty( - scratch.target_assembly.source_asm.data - ): - family = Scratch.objects.filter(slug=scratch.slug) - else: + if is_contentful_asm(scratch.target_assembly.source_asm): + assert scratch.target_assembly.source_asm is not None + family = Scratch.objects.filter( target_assembly__source_asm__hash=scratch.target_assembly.source_asm.hash, ).order_by("creation_time") + elif ( + scratch.target_assembly.elf_object is not None + and len(scratch.target_assembly.elf_object) > 0 + ): + family = Scratch.objects.filter( + target_assembly__hash=scratch.target_assembly.hash, + ).order_by("creation_time") + else: + family = Scratch.objects.filter(slug=scratch.slug) return Response( TerseScratchSerializer(family, many=True, context={"request": request}).data diff --git a/backend/coreapp/views/user.py b/backend/coreapp/views/user.py index 5934c9858..34d2e2c90 100644 --- a/backend/coreapp/views/user.py +++ b/backend/coreapp/views/user.py @@ -1,3 +1,4 @@ +import django_filters from django.contrib.auth import logout from django.db.models.query import QuerySet from django.shortcuts import get_object_or_404 @@ -20,7 +21,7 @@ class CurrentUser(APIView): """ def get(self, request: Request) -> Response: - user = serialize_profile(request, request.profile) + user = serialize_profile(request.profile) return Response(user) def post(self, request: Request) -> Response: @@ -51,7 +52,7 @@ class CurrentUserScratchList(generics.ListAPIView): # type: ignore pagination_class = ScratchPagination serializer_class = TerseScratchSerializer filter_backends = [filters.OrderingFilter] - ordering_fields = ["score", "creation_time", "last_updated"] + ordering_fields = ["creation_time", "last_updated", "score"] def get_queryset(self) -> QuerySet[Scratch]: return Scratch.objects.filter(owner=self.request.profile) @@ -64,8 +65,12 @@ class UserScratchList(generics.ListAPIView): # type: ignore pagination_class = ScratchPagination serializer_class = TerseScratchSerializer - filter_backends = [filters.OrderingFilter] - ordering_fields = ["score", "creation_time", "last_updated"] + filterset_fields = ["preset"] + filter_backends = [ + django_filters.rest_framework.DjangoFilterBackend, + filters.OrderingFilter, + ] + ordering_fields = ["creation_time", "last_updated", "score"] def get_queryset(self) -> QuerySet[Scratch]: return Scratch.objects.filter(owner__user__username=self.kwargs["username"]) @@ -78,5 +83,5 @@ def user(request: Request, username: str) -> Response: """ return Response( - serialize_profile(request, get_object_or_404(Profile, user__username=username)) + serialize_profile(get_object_or_404(Profile, user__username=username)) ) diff --git a/backend/docker_entrypoint.sh b/backend/docker_entrypoint.sh index 497eb5abe..0e9092ea4 100755 --- a/backend/docker_entrypoint.sh +++ b/backend/docker_entrypoint.sh @@ -13,6 +13,11 @@ poetry install poetry run /backend/compilers/download.py poetry run /backend/libraries/download.py +for reg in /backend/wine/*.reg; do + echo "Importing registry file $reg..." + regedit $reg +done + until nc -z ${DB_HOST} ${DB_PORT} > /dev/null; do echo "Waiting for database to become available on ${DB_HOST}:${DB_PORT}..." sleep 1 diff --git a/backend/poetry.lock b/backend/poetry.lock index e9d1f01d6..cee5bc231 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "ansiwrap" @@ -16,13 +16,13 @@ textwrap3 = ">=0.9.2" [[package]] name = "asgiref" -version = "3.7.2" +version = "3.8.1" description = "ASGI specs, helper code, and adapters" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"}, - {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"}, + {file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"}, + {file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"}, ] [package.dependencies] @@ -36,7 +36,7 @@ name = "asm-differ" version = "0.1.0" description = "" optional = false -python-versions = "^3.7" +python-versions = "^3.8" files = [] develop = false @@ -44,14 +44,14 @@ develop = false ansiwrap = "^0.8.4" colorama = "^0.4.6" cxxfilt = "^0.3.0" -levenshtein = "^0.20.9" -watchdog = "^2.2.0" +levenshtein = "^0.25.0" +watchdog = "^4.0.1" [package.source] type = "git" url = "https://github.com/simonlindholm/asm-differ.git" reference = "HEAD" -resolved_reference = "ac7fa0db3638c003da0946f9ef15b34e9f49ab8e" +resolved_reference = "eeb204df66c83797985fb0bfad3a6335e4ad2e17" [[package]] name = "attrs" @@ -319,43 +319,43 @@ files = [ [[package]] name = "cryptography" -version = "42.0.5" +version = "42.0.7" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16"}, - {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec"}, - {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb"}, - {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4"}, - {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278"}, - {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"}, - {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee"}, - {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1"}, - {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d"}, - {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da"}, - {file = "cryptography-42.0.5-cp37-abi3-win32.whl", hash = "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74"}, - {file = "cryptography-42.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940"}, - {file = "cryptography-42.0.5-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8"}, - {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1"}, - {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e"}, - {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc"}, - {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a"}, - {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7"}, - {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922"}, - {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc"}, - {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30"}, - {file = "cryptography-42.0.5-cp39-abi3-win32.whl", hash = "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413"}, - {file = "cryptography-42.0.5-cp39-abi3-win_amd64.whl", hash = "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400"}, - {file = "cryptography-42.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8"}, - {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2"}, - {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c"}, - {file = "cryptography-42.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576"}, - {file = "cryptography-42.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6"}, - {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e"}, - {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac"}, - {file = "cryptography-42.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd"}, - {file = "cryptography-42.0.5.tar.gz", hash = "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1"}, + {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a987f840718078212fdf4504d0fd4c6effe34a7e4740378e59d47696e8dfb477"}, + {file = "cryptography-42.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bd13b5e9b543532453de08bcdc3cc7cebec6f9883e886fd20a92f26940fd3e7a"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a79165431551042cc9d1d90e6145d5d0d3ab0f2d66326c201d9b0e7f5bf43604"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a47787a5e3649008a1102d3df55424e86606c9bae6fb77ac59afe06d234605f8"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:02c0eee2d7133bdbbc5e24441258d5d2244beb31da5ed19fbb80315f4bbbff55"}, + {file = "cryptography-42.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:5e44507bf8d14b36b8389b226665d597bc0f18ea035d75b4e53c7b1ea84583cc"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7f8b25fa616d8b846aef64b15c606bb0828dbc35faf90566eb139aa9cff67af2"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:93a3209f6bb2b33e725ed08ee0991b92976dfdcf4e8b38646540674fc7508e13"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e6b8f1881dac458c34778d0a424ae5769de30544fc678eac51c1c8bb2183e9da"}, + {file = "cryptography-42.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3de9a45d3b2b7d8088c3fbf1ed4395dfeff79d07842217b38df14ef09ce1d8d7"}, + {file = "cryptography-42.0.7-cp37-abi3-win32.whl", hash = "sha256:789caea816c6704f63f6241a519bfa347f72fbd67ba28d04636b7c6b7da94b0b"}, + {file = "cryptography-42.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:8cb8ce7c3347fcf9446f201dc30e2d5a3c898d009126010cbd1f443f28b52678"}, + {file = "cryptography-42.0.7-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:a3a5ac8b56fe37f3125e5b72b61dcde43283e5370827f5233893d461b7360cd4"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:779245e13b9a6638df14641d029add5dc17edbef6ec915688f3acb9e720a5858"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d563795db98b4cd57742a78a288cdbdc9daedac29f2239793071fe114f13785"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:31adb7d06fe4383226c3e963471f6837742889b3c4caa55aac20ad951bc8ffda"}, + {file = "cryptography-42.0.7-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:efd0bf5205240182e0f13bcaea41be4fdf5c22c5129fc7ced4a0282ac86998c9"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a9bc127cdc4ecf87a5ea22a2556cab6c7eda2923f84e4f3cc588e8470ce4e42e"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3577d029bc3f4827dd5bf8bf7710cac13527b470bbf1820a3f394adb38ed7d5f"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2e47577f9b18723fa294b0ea9a17d5e53a227867a0a4904a1a076d1646d45ca1"}, + {file = "cryptography-42.0.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1a58839984d9cb34c855197043eaae2c187d930ca6d644612843b4fe8513c886"}, + {file = "cryptography-42.0.7-cp39-abi3-win32.whl", hash = "sha256:e6b79d0adb01aae87e8a44c2b64bc3f3fe59515280e00fb6d57a7267a2583cda"}, + {file = "cryptography-42.0.7-cp39-abi3-win_amd64.whl", hash = "sha256:16268d46086bb8ad5bf0a2b5544d8a9ed87a0e33f5e77dd3c3301e63d941a83b"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2954fccea107026512b15afb4aa664a5640cd0af630e2ee3962f2602693f0c82"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:362e7197754c231797ec45ee081f3088a27a47c6c01eff2ac83f60f85a50fe60"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f698edacf9c9e0371112792558d2f705b5645076cc0aaae02f816a0171770fd"}, + {file = "cryptography-42.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5482e789294854c28237bba77c4c83be698be740e31a3ae5e879ee5444166582"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e9b2a6309f14c0497f348d08a065d52f3020656f675819fc405fb63bbcd26562"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d8e3098721b84392ee45af2dd554c947c32cc52f862b6a3ae982dbb90f577f14"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c65f96dad14f8528a447414125e1fc8feb2ad5a272b8f68477abbcc1ea7d94b9"}, + {file = "cryptography-42.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:36017400817987670037fbb0324d71489b6ead6231c9604f8fc1f7d008087c68"}, + {file = "cryptography-42.0.7.tar.gz", hash = "sha256:ecbfbc00bf55888edda9868a4cf927205de8499e7fabe6c050322298382953f2"}, ] [package.dependencies] @@ -404,13 +404,13 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "django" -version = "5.0.3" +version = "5.0.6" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false python-versions = ">=3.10" files = [ - {file = "Django-5.0.3-py3-none-any.whl", hash = "sha256:5c7d748ad113a81b2d44750ccc41edc14e933f56581683db548c9257e078cc83"}, - {file = "Django-5.0.3.tar.gz", hash = "sha256:5fb37580dcf4a262f9258c1f4373819aacca906431f505e4688e37f3a99195df"}, + {file = "Django-5.0.6-py3-none-any.whl", hash = "sha256:8363ac062bb4ef7c3f12d078f6fa5d154031d129a15170a1066412af49d30905"}, + {file = "Django-5.0.6.tar.gz", hash = "sha256:ff1b61005004e476e0aeea47c7f79b85864c70124030e95146315396f1e7951f"}, ] [package.dependencies] @@ -547,13 +547,13 @@ typing-extensions = "*" [[package]] name = "djangorestframework" -version = "3.15.0" +version = "3.15.1" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.6" files = [ - {file = "djangorestframework-3.15.0-py3-none-any.whl", hash = "sha256:5fa616048a7ec287fdaab3148aa5151efb73f7f8be1e23a9d18484e61e672695"}, - {file = "djangorestframework-3.15.0.tar.gz", hash = "sha256:3f4a263012e1b263bf49a4907eb4cfe14de840a09b1ba64596d01a9c54835919"}, + {file = "djangorestframework-3.15.1-py3-none-any.whl", hash = "sha256:3ccc0475bce968608cf30d07fb17d8e52d1d7fc8bfe779c905463200750cbca6"}, + {file = "djangorestframework-3.15.1.tar.gz", hash = "sha256:f88fad74183dfc7144b2756d0d2ac716ea5b4c7c9840995ac3bfd8ec034333c1"}, ] [package.dependencies] @@ -598,13 +598,13 @@ djangorestframework = ">=3.9.3" [[package]] name = "graphviz" -version = "0.20.2" +version = "0.20.3" description = "Simple Python interface for Graphviz" optional = false python-versions = ">=3.8" files = [ - {file = "graphviz-0.20.2-py3-none-any.whl", hash = "sha256:63d1ae75f1ca60f980e1cd3a61a678eef8de645ef8427736b2bb9bdd035ca44b"}, - {file = "graphviz-0.20.2.zip", hash = "sha256:d29ca3aadbe5d6e6c584045b7ec4fc1c15af2448dc1c0211b5e94344833243da"}, + {file = "graphviz-0.20.3-py3-none-any.whl", hash = "sha256:81f848f2904515d8cd359cc611faba817598d2feaac4027b266aa3eda7b3dde5"}, + {file = "graphviz-0.20.3.zip", hash = "sha256:09d6bc81e6a9fa392e7ba52135a9d49f1ed62526f96499325930e87ca1b5925d"}, ] [package.extras] @@ -625,13 +625,13 @@ files = [ [[package]] name = "idna" -version = "3.6" +version = "3.7" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, - {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, + {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, + {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, ] [[package]] @@ -649,159 +649,145 @@ cryptography = ">=3.1,<3.4.0 || >3.4.0" [[package]] name = "levenshtein" -version = "0.20.9" +version = "0.25.1" description = "Python extension for computing string edit distances and similarities." optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "Levenshtein-0.20.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:105c239ec786750cd5136991c58196b440cc39b6acf3ec8227f6562c9a94e4b9"}, - {file = "Levenshtein-0.20.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f7728bea7fe6dc55ceecde0dcda4287e74fe3b6733ad42530f46aaa8d2f81d0"}, - {file = "Levenshtein-0.20.9-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc7eca755c13c92814c8cce8175524cf764ce38f39228b602f59eac58cfdc51a"}, - {file = "Levenshtein-0.20.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8a552e79d053dc1324fb90d342447fd4e15736f4cbc5363b6fbd5577f53dce9"}, - {file = "Levenshtein-0.20.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5474b2681ee0b7944fb1e7fe281cd44e2dfe75b03ba4558dca49c96fa0861b62"}, - {file = "Levenshtein-0.20.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:56e132c203b0dd8fc72a33e791c39ad0d5a25bcf24b130a1e202abbf489a3e75"}, - {file = "Levenshtein-0.20.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3badc94708ac05b405e795fde58a53272b90a9ee6099ecd54a345658b7b812e1"}, - {file = "Levenshtein-0.20.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48b9b3ae095b14dad7bc4bd219c7cd9113a7aa123a033337c85b00fe2ed565d3"}, - {file = "Levenshtein-0.20.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0d3a1f7328c91caeb1f857ddd2787e3f19d60cc2c688339d249ca8841da61454"}, - {file = "Levenshtein-0.20.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ef67c50428c99caf67d31bd209da21d9378da5f0cc3ad4f7bafb6caa78aee6f2"}, - {file = "Levenshtein-0.20.9-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:47f6d1592c0891f7355e38a302becd233336ca2f55f9a8be3a8635f946a6784f"}, - {file = "Levenshtein-0.20.9-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2891019740e874f05e0349e9f27b6af8ad837b1612f42e9c90c296d54d1404fd"}, - {file = "Levenshtein-0.20.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c554704eec4f4ba742febdcc79a85491f8f9a1d493cb103bb2af18536d6cf122"}, - {file = "Levenshtein-0.20.9-cp310-cp310-win32.whl", hash = "sha256:7628e356b3f9c78ad7272c3b9137f0641a1368849e749ff6f2c8fe372795806b"}, - {file = "Levenshtein-0.20.9-cp310-cp310-win_amd64.whl", hash = "sha256:ba2bafe3511194a37044cae4e7d328cca70657933052691c37eba2ca428a379d"}, - {file = "Levenshtein-0.20.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7605a94145198d19fdaaa7e29c0f8a56ad719b12386f3ae8cd8ed4cb9fa6c2e4"}, - {file = "Levenshtein-0.20.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:29db4dabfad2ddf33c7986eb6fd525c7587cca4c4d9e187365cff0a5281f5a35"}, - {file = "Levenshtein-0.20.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:965336c1772a4fc5fb2686a2a0bfaf3455dced96f19f50f278da8bc139076d31"}, - {file = "Levenshtein-0.20.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67235753035ac898d6475c0b29540521018db2e0027a3c1deb9aa0af0a84fd74"}, - {file = "Levenshtein-0.20.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:120dca58136aee3d8c7b190e30db7b6a6eb9579ea5712df84ad076a389801743"}, - {file = "Levenshtein-0.20.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6496ea66a6f755e48c0d82f1eee396d16edcd5592d4b3677d26fa789a636a728"}, - {file = "Levenshtein-0.20.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0af20327acc2c904d11611cb3a0d8d17f80c279a12e0b84189eafc35297186d"}, - {file = "Levenshtein-0.20.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d2f891ef53afbab6cf2eeb92ff13151884d17dc80a2d6d3c7ae74d7738b772"}, - {file = "Levenshtein-0.20.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2ab9c72380582bf4745d1c5b055b1df0c85f7a980a04bd7603a855dd91478c0f"}, - {file = "Levenshtein-0.20.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6de13be3eb5ac48053fb1635a7b4daa936b9114ad4b264942e9eb709fcaa41dd"}, - {file = "Levenshtein-0.20.9-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a9fc296860588251d8d72b4f4637cca4eef7351e042a7a23d44e6385aef1e160"}, - {file = "Levenshtein-0.20.9-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:35777b20fe35858248c22da37984469e6dd1278f55d17c53378312853d5d683d"}, - {file = "Levenshtein-0.20.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6b9e0642ddb4c431f77c38cec9edbd0317e26c3f37d072ccf281ab58926dce69"}, - {file = "Levenshtein-0.20.9-cp311-cp311-win32.whl", hash = "sha256:f88ec322d86d3cc9d3936dbf6b421ad813950c2658599d48ac4ede59f2a6047e"}, - {file = "Levenshtein-0.20.9-cp311-cp311-win_amd64.whl", hash = "sha256:2907a6888455f9915d5b656f5d058f63eaf6063b2c7f0f1ff6bc05706ae5bc39"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6bcebc79760be08488cb921732af34ade6abc7476a94866881c68b45ec4b6c82"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47d8d4f3825d1d8f3b19382537a8536e689cf57aaa224d2cb4f44cf844811885"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d40e18a5817ee7f0675401613a26c492fd4ea68d2103c1480fb5a6ab1b8763d"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d258f3d44f6bac17f33002fea34570049507d3476c3716b5267170c666b20b4"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c621e0c389546147ed43c33ca4168de0f91c920508ab8a94a400835fa084f486"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57a31527dc7994353091626e62b7d82d53290cb00df48d3e5d29cb291fb4c03c"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:129c8f192e656b7c2c543bf0d704d677720771b8bc2f30c50db02fbc2001bac2"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5a01fca58255be6bf724a40af2575d7cf644c099c28a00d1f5f6a81675e60e7d"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:4c13749ea39a228f05d5bd9d473e76f726fc2dcd493cafc322f740921a6eeffb"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:69daa0f8eefa5b947255a81346741ed86fe7030e0909741dbd978e38b30da3fd"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fcc78a73ed423bbb09ac902dd2e1ff1094d159d1c6766e5e52da5f376a4cba18"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-win32.whl", hash = "sha256:d82ae57982a9f33c55778f1f0f63d5e51e291aee236abed3b90497578b944202"}, - {file = "Levenshtein-0.20.9-cp36-cp36m-win_amd64.whl", hash = "sha256:4082379b406752fc1173ed1f8c3a122c5d5491e10e564ed721602e4e049e3d4c"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cb499783b7126e6fc45c39ab34c8114148425c5d975b1ce35e6c47c0eda58a94"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ce747b296aad3bd8a563cccf2119cf37bf72f668076bfdad6ec55f0a0596dd9"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1347c3ebbe8f42f7a487e8d23a95bde6529379b4939ad51d32246d001565c499"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2f1c1e8360603a6da29416da61d1907a27656843e269413091c8c3a3e6286e"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73c1caaedbee3617fd29139aac8dab7743776b59c3c1fed2790308ecb43c7b25"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1f24133df69f8b618fc508d6023695130ad3c3c8968ef43aaeca21835eb337a"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cf7260722f8170c09af5cfa714bb45626a4dfc85d71d1c1c9c52c2a6901cc501"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:01668178fd9244df290db0340293982fe7641162a12a35ad9ffb3fe145ce6377"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1e46f9d3483dc4991ac60ff3711b0d40f93e352cc8edc16b68df57ccc472bd6c"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:680cd250dc1875eb80cf2a0cca742bd13f6f9ab11c48317244fcc483eba1dd67"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2346e2f7dfbbc2936bd81e19f7734984e72486ffc086760c897b39b9f674b2fa"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-win32.whl", hash = "sha256:7f31bcf257fec9719d0d97185c419d315f6f20a194f0b442919e352d19418b2e"}, - {file = "Levenshtein-0.20.9-cp37-cp37m-win_amd64.whl", hash = "sha256:48262bc9830ad60de96411fcb2e96a522c7206e7069169e04d89dd79364a7722"}, - {file = "Levenshtein-0.20.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:eba5696e1f8e8da225498fd1d743886d639400cafd0e5be3c553978cbb54c345"}, - {file = "Levenshtein-0.20.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:679333188f9791c85109d2981e97e8721a99b2b975b5c52d16aca50ac9c70757"}, - {file = "Levenshtein-0.20.9-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:06c9cfc61cf66833692d1ed258ec5a0871221b0779f1281c32a10348c492e2c5"}, - {file = "Levenshtein-0.20.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5d80d949168df406f2ac9ade1a5d0419cef0a8df611c8c2efe88f0248c9d0c0"}, - {file = "Levenshtein-0.20.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9275c6e601ff7f659116e2235e8585950c9c39d72504006077be85bf27950b35"}, - {file = "Levenshtein-0.20.9-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6414eea342d9632045e12b66bef043dbc6557189a283dc4dcc5966f63fa48998"}, - {file = "Levenshtein-0.20.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56571c58700600a382ecdf3f9efcb132ed16a0476cbb4e23a9478ab0ae788fd9"}, - {file = "Levenshtein-0.20.9-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7ccb76ffd9b851384f9cf1595b90b17cae46f0ab895e234de11ea48f9d9f73a"}, - {file = "Levenshtein-0.20.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109172943cff7fb10f28a9eb819eb3eaf9c88fe38661fb1d0f230a8ae68a615c"}, - {file = "Levenshtein-0.20.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:534c8bbdfd033fa20575d57332d9ac0447b5afbeca7db975ba169762ece2051f"}, - {file = "Levenshtein-0.20.9-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:381a725963c392585135654caa3c7fc32cb1755ed977fb9db72e8838fee261be"}, - {file = "Levenshtein-0.20.9-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7e4a44b1223980a9880e6f2bbf19121a125928580df9e4e81207199190343e11"}, - {file = "Levenshtein-0.20.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fc0ced58ee6d07351cde140a7ec88e5f2ceb053c805af1f90514d21914d21cad"}, - {file = "Levenshtein-0.20.9-cp38-cp38-win32.whl", hash = "sha256:5eec0868ffcd825564dd5e3399305eaa159220554d1aedbff13af0de1fe01f6c"}, - {file = "Levenshtein-0.20.9-cp38-cp38-win_amd64.whl", hash = "sha256:e9db476e40a3aa184631d102b716a019f70837eb0fcdd5b5d1504f099f91359c"}, - {file = "Levenshtein-0.20.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d5a20ecc20a09a32c72128c43d7df23877a2469b3c17780ae83f9a9d55873c08"}, - {file = "Levenshtein-0.20.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8b7b772f2f62a19a15ccb1b09c6c7754ca7430bb7e19d4ca4ff232958786873b"}, - {file = "Levenshtein-0.20.9-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af92326b90ea6fe4521cf6a5dfe450e21150393c573ef3ad9ee446f1009fbfbd"}, - {file = "Levenshtein-0.20.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b48554dad328e198a636f937e2f4c057aac8e4bfcb8467b10e0f5daa94307b17"}, - {file = "Levenshtein-0.20.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:82304821e128d5453d1755d1c2f3d9cdf75e9def3517cf913b09df174e20283b"}, - {file = "Levenshtein-0.20.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2052357c5da195ede7dbc81a4e3408ebd6374a1ff1b86a0a9d8b8ce9562b32c3"}, - {file = "Levenshtein-0.20.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44d60c6b47ccd6841c990418f7f4f58c28f7da9b07b81eaafc99b836cf351df1"}, - {file = "Levenshtein-0.20.9-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dc2194c917e4466cb604580b16e42286f04e3fe0424489459e68f0834f5c527"}, - {file = "Levenshtein-0.20.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb1e20965d759d89318cac7ff7eb045eb1fafcb5c3fa3047a23f6ae20c810ad7"}, - {file = "Levenshtein-0.20.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:74e959035da10a54e7a2eee28408eff672297ce96cdadd6f4a2f269a06e395c4"}, - {file = "Levenshtein-0.20.9-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4a441b23d9704f57eb34af6a300ae5c335b9e77e6a065ada36ca69d6fc582af9"}, - {file = "Levenshtein-0.20.9-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f59470c49114a5da064712a427317f2b1fa5bb89aa2dfd0e300f8289e26aec28"}, - {file = "Levenshtein-0.20.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:06191f5d0527e3224107aea260b5cffc8a78722e0efb4e793f0e45c449b813a2"}, - {file = "Levenshtein-0.20.9-cp39-cp39-win32.whl", hash = "sha256:3235c461904fe94b4f62fee78a1658c1316344411c81b02400c27d692a893f8f"}, - {file = "Levenshtein-0.20.9-cp39-cp39-win_amd64.whl", hash = "sha256:8b852def43d165c2f2b468239d66b847d9e6f52a775fc657773ced04d26062bd"}, - {file = "Levenshtein-0.20.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f674cc75f127692525563155e500a3fa16aaf24dafd33a9bcda46e2979f793a1"}, - {file = "Levenshtein-0.20.9-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a34e3fd21acb31fcd29a0c8353dca74dfbb59957210a6f142505907a9dff3d59"}, - {file = "Levenshtein-0.20.9-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0ddddf2beafd1a2e17a87f80be562a7f7478e6098ccfc15de4c879972dfa2f9"}, - {file = "Levenshtein-0.20.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9649af1a896a4a7fc7f6f1fd093e8a92f463297f56c7bd0f8d7d16dfabeb236d"}, - {file = "Levenshtein-0.20.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d7bd7f25336849027fbe5ed32b6ffd404436727d78a014e348dcd17347c73fd8"}, - {file = "Levenshtein-0.20.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0371d996ae81089296f42b6e886c7bf138d1cb0f002b0c724a9e5d689b29b5a0"}, - {file = "Levenshtein-0.20.9-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7e00e2fda9f225b5f4537647f6195cf220d468532739d3390eaf082b1d76c87"}, - {file = "Levenshtein-0.20.9-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1600f5ebe2f2aebf13e88cf488ec2e5ce25f7a42b5846335018693baf4ea63bd"}, - {file = "Levenshtein-0.20.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bcd59fcf06aaedda98da185ec289dc2c2c9922ce789f6a9c101709d4a22cac9"}, - {file = "Levenshtein-0.20.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:1549e307028fa5c3a8cf28ae8bcb1f6072df2abf7f36b9d7adf7fd60690fe372"}, - {file = "Levenshtein-0.20.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:795f2e95d09a33c66c73cd49be3ee632fb4b8c41be72c0cb8df29a329ce7d111"}, - {file = "Levenshtein-0.20.9-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:726bfb361d3b6786bea31392752f0ffcca568db7dc3f1e274f1b529489b8ad05"}, - {file = "Levenshtein-0.20.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e0fd315132786375de532355fa06b2f11c4b4af5784b7e064dc54b6ee0c3281"}, - {file = "Levenshtein-0.20.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0674bc0549d5ea9edb934b3b03a160a116cc410feb5739a51f9c4f618ee674e3"}, - {file = "Levenshtein-0.20.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1ef8f3ecdfca5d6f0538226338d58617270439a1cc9b6cacb30a388984bb1608"}, - {file = "Levenshtein-0.20.9.tar.gz", hash = "sha256:70a8ad5e28bb76d87da1eb3f31de940836596547d6d01317c2289f5b7cd0b0ea"}, + {file = "Levenshtein-0.25.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb4d1ec9f2dcbde1757c4b7fb65b8682bc2de45b9552e201988f287548b7abdf"}, + {file = "Levenshtein-0.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b4d9fa3affef48a7e727cdbd0d9502cd060da86f34d8b3627edd769d347570e2"}, + {file = "Levenshtein-0.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1b6cd186e58196ff8b402565317e9346b408d0c04fa0ed12ce4868c0fcb6d03"}, + {file = "Levenshtein-0.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82637ef5428384dd1812849dd7328992819bf0c4a20bff0a3b3ee806821af7ed"}, + {file = "Levenshtein-0.25.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e73656da6cc3e32a6e4bcd48562fcb64599ef124997f2c91f5320d7f1532c069"}, + {file = "Levenshtein-0.25.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5abff796f92cdfba69b9cbf6527afae918d0e95cbfac000bd84017f74e0bd427"}, + {file = "Levenshtein-0.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38827d82f2ca9cb755da6f03e686866f2f411280db005f4304272378412b4cba"}, + {file = "Levenshtein-0.25.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b989df1e3231261a87d68dfa001a2070771e178b09650f9cf99a20e3d3abc28"}, + {file = "Levenshtein-0.25.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2011d3b3897d438a2f88ef7aed7747f28739cae8538ec7c18c33dd989930c7a0"}, + {file = "Levenshtein-0.25.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6c375b33ec7acc1c6855e8ee8c7c8ac6262576ffed484ff5c556695527f49686"}, + {file = "Levenshtein-0.25.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ce0cb9dd012ef1bf4d5b9d40603e7709b6581aec5acd32fcea9b371b294ca7aa"}, + {file = "Levenshtein-0.25.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:9da9ecb81bae67d784defed7274f894011259b038ec31f2339c4958157970115"}, + {file = "Levenshtein-0.25.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3bd7be5dbe5f4a1b691f381e39512927b39d1e195bd0ad61f9bf217a25bf36c9"}, + {file = "Levenshtein-0.25.1-cp310-cp310-win32.whl", hash = "sha256:f6abb9ced98261de67eb495b95e1d2325fa42b0344ed5763f7c0f36ee2e2bdba"}, + {file = "Levenshtein-0.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:97581af3e0a6d359af85c6cf06e51f77f4d635f7109ff7f8ed7fd634d8d8c923"}, + {file = "Levenshtein-0.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:9ba008f490788c6d8d5a10735fcf83559965be97e4ef0812db388a84b1cc736a"}, + {file = "Levenshtein-0.25.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f57d9cf06dac55c2d2f01f0d06e32acc074ab9a902921dc8fddccfb385053ad5"}, + {file = "Levenshtein-0.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:22b60c6d791f4ca67a3686b557ddb2a48de203dae5214f220f9dddaab17f44bb"}, + {file = "Levenshtein-0.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d0444ee62eccf1e6cedc7c5bc01a9face6ff70cc8afa3f3ca9340e4e16f601a4"}, + {file = "Levenshtein-0.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e8758be8221a274c83924bae8dd8f42041792565a3c3bdd3c10e3f9b4a5f94e"}, + {file = "Levenshtein-0.25.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:147221cfb1d03ed81d22fdd2a4c7fc2112062941b689e027a30d2b75bbced4a3"}, + {file = "Levenshtein-0.25.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a454d5bc4f4a289f5471418788517cc122fcc00d5a8aba78c54d7984840655a2"}, + {file = "Levenshtein-0.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c25f3778bbac78286bef2df0ca80f50517b42b951af0a5ddaec514412f79fac"}, + {file = "Levenshtein-0.25.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:181486cf465aff934694cc9a19f3898a1d28025a9a5f80fc1608217e7cd1c799"}, + {file = "Levenshtein-0.25.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8db9f672a5d150706648b37b044dba61f36ab7216c6a121cebbb2899d7dfaa3"}, + {file = "Levenshtein-0.25.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f2a69fe5ddea586d439f9a50d0c51952982f6c0db0e3573b167aa17e6d1dfc48"}, + {file = "Levenshtein-0.25.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:3b684675a3bd35efa6997856e73f36c8a41ef62519e0267dcbeefd15e26cae71"}, + {file = "Levenshtein-0.25.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:cc707ef7edb71f6bf8339198b929ead87c022c78040e41668a4db68360129cef"}, + {file = "Levenshtein-0.25.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:41512c436b8c691326e2d07786d906cba0e92b5e3f455bf338befb302a0ca76d"}, + {file = "Levenshtein-0.25.1-cp311-cp311-win32.whl", hash = "sha256:2a3830175c01ade832ba0736091283f14a6506a06ffe8c846f66d9fbca91562f"}, + {file = "Levenshtein-0.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:9e0af4e6e023e0c8f79af1d1ca5f289094eb91201f08ad90f426d71e4ae84052"}, + {file = "Levenshtein-0.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:38e5d9a1d737d7b49fa17d6a4c03a0359288154bf46dc93b29403a9dd0cd1a7d"}, + {file = "Levenshtein-0.25.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:4a40fa16ecd0bf9e557db67131aabeea957f82fe3e8df342aa413994c710c34e"}, + {file = "Levenshtein-0.25.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4f7d2045d5927cffa65a0ac671c263edbfb17d880fdce2d358cd0bda9bcf2b6d"}, + {file = "Levenshtein-0.25.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f96590539f9815be70e330b4d2efcce0219db31db5a22fffe99565192f5662"}, + {file = "Levenshtein-0.25.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d78512dd25b572046ff86d8903bec283c373063349f8243430866b6a9946425"}, + {file = "Levenshtein-0.25.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c161f24a1b216e8555c874c7dd70c1a0d98f783f252a16c9face920a8b8a6f3e"}, + {file = "Levenshtein-0.25.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:06ebbfd010a00490795f478d18d7fa2ffc79c9c03fc03b678081f31764d16bab"}, + {file = "Levenshtein-0.25.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa9ec0a4489ebfb25a9ec2cba064ed68d0d2485b8bc8b7203f84a7874755e0f"}, + {file = "Levenshtein-0.25.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26408938a6db7b252824a701545d50dc9cdd7a3e4c7ee70834cca17953b76ad8"}, + {file = "Levenshtein-0.25.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:330ec2faff957281f4e6a1a8c88286d1453e1d73ee273ea0f937e0c9281c2156"}, + {file = "Levenshtein-0.25.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9115d1b08626dfdea6f3955cb49ba5a578f7223205f80ead0038d6fc0442ce13"}, + {file = "Levenshtein-0.25.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:bbd602edab758e93a5c67bf0d8322f374a47765f1cdb6babaf593a64dc9633ad"}, + {file = "Levenshtein-0.25.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b930b4df32cd3aabbed0e9f0c4fdd1ea4090a5c022ba9f1ae4ab70ccf1cf897a"}, + {file = "Levenshtein-0.25.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:dd66fb51f88a3f73a802e1ff19a14978ddc9fbcb7ce3a667ca34f95ef54e0e44"}, + {file = "Levenshtein-0.25.1-cp312-cp312-win32.whl", hash = "sha256:386de94bd1937a16ae3c8f8b7dd2eff1b733994ecf56ce4d05dfdd0e776d0261"}, + {file = "Levenshtein-0.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:9ee1902153d47886c9787598a4a5c324ce7fde44d44daa34fcf3652ac0de21bc"}, + {file = "Levenshtein-0.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:b56a7e7676093c3aee50402226f4079b15bd21b5b8f1820f9d6d63fe99dc4927"}, + {file = "Levenshtein-0.25.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6b5dfdf6a0e2f35fd155d4c26b03398499c24aba7bc5db40245789c46ad35c04"}, + {file = "Levenshtein-0.25.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:355ff797f704459ddd8b95354d699d0d0642348636c92d5e67b49be4b0e6112b"}, + {file = "Levenshtein-0.25.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:933b827a3b721210fff522f3dca9572f9f374a0e88fa3a6c7ee3164406ae7794"}, + {file = "Levenshtein-0.25.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be1da669a240f272d904ab452ad0a1603452e190f4e03e886e6b3a9904152b89"}, + {file = "Levenshtein-0.25.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:265cbd78962503a26f2bea096258a3b70b279bb1a74a525c671d3ee43a190f9c"}, + {file = "Levenshtein-0.25.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63cc4d53a35e673b12b721a58b197b4a65734688fb72aa1987ce63ed612dca96"}, + {file = "Levenshtein-0.25.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75fee0c471b8799c70dad9d0d5b70f1f820249257f9617601c71b6c1b37bee92"}, + {file = "Levenshtein-0.25.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:045d6b0db124fbd37379b2b91f6d0786c2d9220e7a848e2dd31b99509a321240"}, + {file = "Levenshtein-0.25.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:db7a2e9c51ac9cc2fd5679484f1eac6e0ab2085cb181240445f7fbf10df73230"}, + {file = "Levenshtein-0.25.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c379c588aa0d93d4607db7eb225fd683263d49669b1bbe49e28c978aa6a4305d"}, + {file = "Levenshtein-0.25.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:966dd00424df7f69b78da02a29b530fbb6c1728e9002a2925ed7edf26b231924"}, + {file = "Levenshtein-0.25.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:09daa6b068709cc1e68b670a706d928ed8f0b179a26161dd04b3911d9f757525"}, + {file = "Levenshtein-0.25.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d6bed0792635081accf70a7e11cfece986f744fddf46ce26808cd8bfc067e430"}, + {file = "Levenshtein-0.25.1-cp38-cp38-win32.whl", hash = "sha256:28e7b7faf5a745a690d1b1706ab82a76bbe9fa6b729d826f0cfdd24fd7c19740"}, + {file = "Levenshtein-0.25.1-cp38-cp38-win_amd64.whl", hash = "sha256:8ca0cc9b9e07316b5904f158d5cfa340d55b4a3566ac98eaac9f087c6efb9a1a"}, + {file = "Levenshtein-0.25.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:45682cdb3ac4a5465c01b2dce483bdaa1d5dcd1a1359fab37d26165b027d3de2"}, + {file = "Levenshtein-0.25.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f8dc3e63c4cd746ec162a4cd744c6dde857e84aaf8c397daa46359c3d54e6219"}, + {file = "Levenshtein-0.25.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:01ad1eb09933a499a49923e74e05b1428ca4ef37fed32965fef23f1334a11563"}, + {file = "Levenshtein-0.25.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbb4e8c4b8b7bbe0e1aa64710b806b6c3f31d93cb14969ae2c0eff0f3a592db8"}, + {file = "Levenshtein-0.25.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b48d1fe224b365975002e3e2ea947cbb91d2936a16297859b71c4abe8a39932c"}, + {file = "Levenshtein-0.25.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a164df16d876aab0a400f72aeac870ea97947ea44777c89330e9a16c7dc5cc0e"}, + {file = "Levenshtein-0.25.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:995d3bcedcf64be6ceca423f6cfe29184a36d7c4cbac199fdc9a0a5ec7196cf5"}, + {file = "Levenshtein-0.25.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdaf62d637bef6711d6f3457e2684faab53b2db2ed53c05bc0dc856464c74742"}, + {file = "Levenshtein-0.25.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:af9de3b5f8f5f3530cfd97daab9ab480d1b121ef34d8c0aa5bab0c645eae219e"}, + {file = "Levenshtein-0.25.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:78fba73c352383b356a30c4674e39f086ffef7122fa625e7550b98be2392d387"}, + {file = "Levenshtein-0.25.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:9e0df0dcea3943321398f72e330c089b5d5447318310db6f17f5421642f3ade6"}, + {file = "Levenshtein-0.25.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:387f768bb201b9bc45f0f49557e2fb9a3774d9d087457bab972162dcd4fd352b"}, + {file = "Levenshtein-0.25.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5dcf931b64311039b43495715e9b795fbd97ab44ba3dd6bf24360b15e4e87649"}, + {file = "Levenshtein-0.25.1-cp39-cp39-win32.whl", hash = "sha256:2449f8668c0bd62a2b305a5e797348984c06ac20903b38b3bab74e55671ddd51"}, + {file = "Levenshtein-0.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:28803fd6ec7b58065621f5ec0d24e44e2a7dc4842b64dcab690cb0a7ea545210"}, + {file = "Levenshtein-0.25.1-cp39-cp39-win_arm64.whl", hash = "sha256:0b074d452dff8ee86b5bdb6031aa32bb2ed3c8469a56718af5e010b9bb5124dc"}, + {file = "Levenshtein-0.25.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e9e060ef3925a68aeb12276f0e524fb1264592803d562ec0306c7c3f5c68eae0"}, + {file = "Levenshtein-0.25.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f84b84049318d44722db307c448f9dcb8d27c73525a378e901189a94889ba61"}, + {file = "Levenshtein-0.25.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e23fdf330cb185a0c7913ca5bd73a189dfd1742eae3a82e31ed8688b191800"}, + {file = "Levenshtein-0.25.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06958e4a81ea0f0b2b7768a2ad05bcd50a9ad04c4d521dd37d5730ff12decdc"}, + {file = "Levenshtein-0.25.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2ea7c34ec22b2fce21299b0caa6dde6bdebafcc2970e265853c9cfea8d1186da"}, + {file = "Levenshtein-0.25.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fddc0ccbdd94f57aa32e2eb3ac8310d08df2e175943dc20b3e1fc7a115850af4"}, + {file = "Levenshtein-0.25.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d52249cb3448bfe661d3d7db3a6673e835c7f37b30b0aeac499a1601bae873d"}, + {file = "Levenshtein-0.25.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8dd4c201b15f8c1e612f9074335392c8208ac147acbce09aff04e3974bf9b16"}, + {file = "Levenshtein-0.25.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:23a4d95ce9d44161c7aa87ab76ad6056bc1093c461c60c097054a46dc957991f"}, + {file = "Levenshtein-0.25.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:65eea8a9c33037b23069dca4b3bc310e3c28ca53f60ec0c958d15c0952ba39fa"}, + {file = "Levenshtein-0.25.1.tar.gz", hash = "sha256:2df14471c778c75ffbd59cb64bbecfd4b0ef320ef9f80e4804764be7d5678980"}, ] [package.dependencies] -rapidfuzz = ">=2.3.0,<3.0.0" +rapidfuzz = ">=3.8.0,<4.0.0" [[package]] name = "libcst" -version = "1.2.0" +version = "1.4.0" description = "A concrete syntax tree with AST-like properties for Python 3.0 through 3.12 programs." optional = false python-versions = ">=3.9" files = [ - {file = "libcst-1.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0149d24a455536ff2e41b3a48b16d3ebb245e28035013c91bd868def16592a0"}, - {file = "libcst-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ba24b8cf789db6b87c6e23a6c6365f5f73cb7306d929397581d5680149e9990c"}, - {file = "libcst-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bbb4e442224da46b59a248d7d632ed335eae023a921dea1f5c72d2a059f6be9"}, - {file = "libcst-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4919978c2b395079b64d8a654357854767adbabab13998b39c1f0bc67da8a7"}, - {file = "libcst-1.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e54389abdea995b39ee96ad736ed1b0b8402ed30a7956b7a279c10baf0c0294"}, - {file = "libcst-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d45718f7e7a1405a16fd8e7fc75c365120001b6928bfa3c4112f7e533990b9a"}, - {file = "libcst-1.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f080e9af843ff609f8f35fc7275c8bf08b02c31115e7cd5b77ca3b6a56c75096"}, - {file = "libcst-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3c7c0edfe3b878d64877671261c7b3ffe9d23181774bfad5d8fcbdbbbde9f064"}, - {file = "libcst-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b5fecb2b26fa3c1efe6e05ef1420522bd31bb4dae239e4c41fdf3ddbd853aeb"}, - {file = "libcst-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:968b93400e66e6711a29793291365e312d206dbafd3fc80219cfa717f0f01ad5"}, - {file = "libcst-1.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e01879aa8cd478bb8b1e4285cfd0607e64047116f7ab52bc2a787cde584cd686"}, - {file = "libcst-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:b4066dcadf92b183706f81ae0b4342e7624fc1d9c5ca2bf2b44066cb74bf863f"}, - {file = "libcst-1.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5c0d548d92c6704bb07ce35d78c0e054cdff365def0645c1b57c856c8e112bb4"}, - {file = "libcst-1.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82373a35711a8bb2a664dba2b7aeb20bbcce92a4db40af964e9cb2b976f989e7"}, - {file = "libcst-1.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb92398236566f0b73a0c73f8a41a9c4906c793e8f7c2745f30e3fb141a34b5"}, - {file = "libcst-1.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13ca9fe82326d82feb2c7b0f5a320ce7ed0d707c32919dd36e1f40792459bf6f"}, - {file = "libcst-1.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dded0e4f2e18150c4b07fedd7ef84a9abc7f9bd2d47cc1c485248ee1ec58e5cc"}, - {file = "libcst-1.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:dece0362540abfc39cd2cf5c98cde238b35fd74a1b0167e2563e4b8bb5f47489"}, - {file = "libcst-1.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c80f36f4a02d530e28eac7073aabdea7c6795fc820773a02224021d79d164e8b"}, - {file = "libcst-1.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b56130f18aca9a98b3bcaf5962b2b26c2dcdd6d5132decf3f0b0b635f4403ba"}, - {file = "libcst-1.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4973a9d509cf1a59e07fac55a98f70bc4fd35e09781dffb3ec93ee32fc0de7af"}, - {file = "libcst-1.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dd388c74c04434b41e3b25fc4a0fafa3e6abf91f97181df55e8f8327fd903cc"}, - {file = "libcst-1.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38fbd56f885e1f77383a6d1d798a917ffbc6d28dc6b1271eddbf8511c194213e"}, - {file = "libcst-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:f2342634f6c61fc9076dc0baf21e9cf5ef0195a06e1e95c0c9dc583ba3a30d00"}, - {file = "libcst-1.2.0.tar.gz", hash = "sha256:71dd69fff76e7edaf8fae0f63ffcdbf5016e8cd83165b1d0688d6856aa48186a"}, + {file = "libcst-1.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:279b54568ea1f25add50ea4ba3d76d4f5835500c82f24d54daae4c5095b986aa"}, + {file = "libcst-1.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3401dae41fe24565387a65baee3887e31a44e3e58066b0250bc3f3ccf85b1b5a"}, + {file = "libcst-1.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1989fa12d3cd79118ebd29ebe2a6976d23d509b1a4226bc3d66fcb7cb50bd5d"}, + {file = "libcst-1.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:addc6d585141a7677591868886f6bda0577529401a59d210aa8112114340e129"}, + {file = "libcst-1.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17d71001cb25e94cfe8c3d997095741a8c4aa7a6d234c0f972bc42818c88dfaf"}, + {file = "libcst-1.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:2d47de16d105e7dd5f4e01a428d9f4dc1e71efd74f79766daf54528ce37f23c3"}, + {file = "libcst-1.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e6227562fc5c9c1efd15dfe90b0971ae254461b8b6b23c1b617139b6003de1c1"}, + {file = "libcst-1.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3399e6c95df89921511b44d8c5bf6a75bcbc2d51f1f6429763609ba005c10f6b"}, + {file = "libcst-1.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48601e3e590e2d6a7ab8c019cf3937c70511a78d778ab3333764531253acdb33"}, + {file = "libcst-1.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f42797309bb725f0f000510d5463175ccd7155395f09b5e7723971b0007a976d"}, + {file = "libcst-1.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb4e42ea107a37bff7f9fdbee9532d39f9ea77b89caa5c5112b37057b12e0838"}, + {file = "libcst-1.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:9d0cc3c5a2a51fa7e1d579a828c0a2e46b2170024fd8b1a0691c8a52f3abb2d9"}, + {file = "libcst-1.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:7ece51d935bc9bf60b528473d2e5cc67cbb88e2f8146297e40ee2c7d80be6f13"}, + {file = "libcst-1.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:81653dea1cdfa4c6520a7c5ffb95fa4d220cbd242e446c7a06d42d8636bfcbba"}, + {file = "libcst-1.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6abce0e66bba2babfadc20530fd3688f672d565674336595b4623cd800b91ef"}, + {file = "libcst-1.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5da9d7dc83801aba3b8d911f82dc1a375db0d508318bad79d9fb245374afe068"}, + {file = "libcst-1.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c54aa66c86d8ece9c93156a2cf5ca512b0dce40142fe9e072c86af2bf892411"}, + {file = "libcst-1.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:62e2682ee1567b6a89c91853865372bf34f178bfd237853d84df2b87b446e654"}, + {file = "libcst-1.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b8ecdba8934632b4dadacb666cd3816627a6ead831b806336972ccc4ba7ca0e9"}, + {file = "libcst-1.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8e54c777b8d27339b70f304d16fc8bc8674ef1bd34ed05ea874bf4921eb5a313"}, + {file = "libcst-1.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:061d6855ef30efe38b8a292b7e5d57c8e820e71fc9ec9846678b60a934b53bbb"}, + {file = "libcst-1.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb0abf627ee14903d05d0ad9b2c6865f1b21eb4081e2c7bea1033f85db2b8bae"}, + {file = "libcst-1.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d024f44059a853b4b852cfc04fec33e346659d851371e46fc8e7c19de24d3da9"}, + {file = "libcst-1.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:3c6a8faab9da48c5b371557d0999b4ca51f4f2cbd37ee8c2c4df0ac01c781465"}, + {file = "libcst-1.4.0.tar.gz", hash = "sha256:449e0b16604f054fa7f27c3ffe86ea7ef6c409836fe68fe4e752a1894175db00"}, ] [package.dependencies] pyyaml = ">=5.2" -typing-extensions = ">=3.7.4.2" -typing-inspect = ">=0.4.0" [package.extras] -dev = ["Sphinx (>=5.1.1)", "black (==23.12.1)", "build (>=0.10.0)", "coverage (>=4.5.4)", "fixit (==2.1.0)", "flake8 (==7.0.0)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.3)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<1.5)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.18)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.3.0)", "usort (==1.0.7)"] +dev = ["Sphinx (>=5.1.1)", "black (==23.12.1)", "build (>=0.10.0)", "coverage (>=4.5.4)", "fixit (==2.1.0)", "flake8 (==7.0.0)", "hypothesis (>=4.36.0)", "hypothesmith (>=0.0.4)", "jinja2 (==3.1.4)", "jupyter (>=1.0.0)", "maturin (>=0.8.3,<1.6)", "nbsphinx (>=0.4.2)", "prompt-toolkit (>=2.0.9)", "pyre-check (==0.9.18)", "setuptools-rust (>=1.5.2)", "setuptools-scm (>=6.0.1)", "slotscheck (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "ufmt (==2.6.0)", "usort (==1.0.8.post1)"] [[package]] name = "m2c" @@ -820,7 +806,7 @@ pycparser = "^2.21" type = "git" url = "https://github.com/matt-kempster/m2c.git" reference = "HEAD" -resolved_reference = "4ee07ea6b0286ed265e06bdbf09550d3b97fe4f0" +resolved_reference = "76808d564c79b9859798430644847e4baa71ae96" [[package]] name = "moreorless" @@ -838,38 +824,38 @@ click = "*" [[package]] name = "mypy" -version = "1.9.0" +version = "1.10.0" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f"}, - {file = "mypy-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed"}, - {file = "mypy-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150"}, - {file = "mypy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374"}, - {file = "mypy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3"}, - {file = "mypy-1.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc"}, - {file = "mypy-1.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129"}, - {file = "mypy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612"}, - {file = "mypy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd"}, - {file = "mypy-1.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6"}, - {file = "mypy-1.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185"}, - {file = "mypy-1.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913"}, - {file = "mypy-1.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b"}, - {file = "mypy-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2"}, - {file = "mypy-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e"}, - {file = "mypy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04"}, - {file = "mypy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02"}, - {file = "mypy-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4"}, - {file = "mypy-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d"}, - {file = "mypy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf"}, - {file = "mypy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9"}, - {file = "mypy-1.9.0-py3-none-any.whl", hash = "sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e"}, - {file = "mypy-1.9.0.tar.gz", hash = "sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2"}, + {file = "mypy-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99"}, + {file = "mypy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2"}, + {file = "mypy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9"}, + {file = "mypy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1"}, + {file = "mypy-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee"}, + {file = "mypy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de"}, + {file = "mypy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7"}, + {file = "mypy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b"}, + {file = "mypy-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30"}, + {file = "mypy-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e"}, + {file = "mypy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5"}, + {file = "mypy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0"}, + {file = "mypy-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727"}, + {file = "mypy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4"}, + {file = "mypy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061"}, + {file = "mypy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976"}, + {file = "mypy-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec"}, + {file = "mypy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821"}, + {file = "mypy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746"}, + {file = "mypy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a"}, + {file = "mypy-1.10.0-py3-none-any.whl", hash = "sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee"}, + {file = "mypy-1.10.0.tar.gz", hash = "sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131"}, ] [package.dependencies] @@ -932,79 +918,80 @@ files = [ [[package]] name = "pillow" -version = "10.2.0" +version = "10.3.0" description = "Python Imaging Library (Fork)" optional = false python-versions = ">=3.8" files = [ - {file = "pillow-10.2.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:7823bdd049099efa16e4246bdf15e5a13dbb18a51b68fa06d6c1d4d8b99a796e"}, - {file = "pillow-10.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:83b2021f2ade7d1ed556bc50a399127d7fb245e725aa0113ebd05cfe88aaf588"}, - {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fad5ff2f13d69b7e74ce5b4ecd12cc0ec530fcee76356cac6742785ff71c452"}, - {file = "pillow-10.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da2b52b37dad6d9ec64e653637a096905b258d2fc2b984c41ae7d08b938a67e4"}, - {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:47c0995fc4e7f79b5cfcab1fc437ff2890b770440f7696a3ba065ee0fd496563"}, - {file = "pillow-10.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:322bdf3c9b556e9ffb18f93462e5f749d3444ce081290352c6070d014c93feb2"}, - {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:51f1a1bffc50e2e9492e87d8e09a17c5eea8409cda8d3f277eb6edc82813c17c"}, - {file = "pillow-10.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:69ffdd6120a4737710a9eee73e1d2e37db89b620f702754b8f6e62594471dee0"}, - {file = "pillow-10.2.0-cp310-cp310-win32.whl", hash = "sha256:c6dafac9e0f2b3c78df97e79af707cdc5ef8e88208d686a4847bab8266870023"}, - {file = "pillow-10.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:aebb6044806f2e16ecc07b2a2637ee1ef67a11840a66752751714a0d924adf72"}, - {file = "pillow-10.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:7049e301399273a0136ff39b84c3678e314f2158f50f517bc50285fb5ec847ad"}, - {file = "pillow-10.2.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:35bb52c37f256f662abdfa49d2dfa6ce5d93281d323a9af377a120e89a9eafb5"}, - {file = "pillow-10.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c23f307202661071d94b5e384e1e1dc7dfb972a28a2310e4ee16103e66ddb67"}, - {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773efe0603db30c281521a7c0214cad7836c03b8ccff897beae9b47c0b657d61"}, - {file = "pillow-10.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11fa2e5984b949b0dd6d7a94d967743d87c577ff0b83392f17cb3990d0d2fd6e"}, - {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:716d30ed977be8b37d3ef185fecb9e5a1d62d110dfbdcd1e2a122ab46fddb03f"}, - {file = "pillow-10.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a086c2af425c5f62a65e12fbf385f7c9fcb8f107d0849dba5839461a129cf311"}, - {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c8de2789052ed501dd829e9cae8d3dcce7acb4777ea4a479c14521c942d395b1"}, - {file = "pillow-10.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:609448742444d9290fd687940ac0b57fb35e6fd92bdb65386e08e99af60bf757"}, - {file = "pillow-10.2.0-cp311-cp311-win32.whl", hash = "sha256:823ef7a27cf86df6597fa0671066c1b596f69eba53efa3d1e1cb8b30f3533068"}, - {file = "pillow-10.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:1da3b2703afd040cf65ec97efea81cfba59cdbed9c11d8efc5ab09df9509fc56"}, - {file = "pillow-10.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:edca80cbfb2b68d7b56930b84a0e45ae1694aeba0541f798e908a49d66b837f1"}, - {file = "pillow-10.2.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:1b5e1b74d1bd1b78bc3477528919414874748dd363e6272efd5abf7654e68bef"}, - {file = "pillow-10.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0eae2073305f451d8ecacb5474997c08569fb4eb4ac231ffa4ad7d342fdc25ac"}, - {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7c2286c23cd350b80d2fc9d424fc797575fb16f854b831d16fd47ceec078f2c"}, - {file = "pillow-10.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e23412b5c41e58cec602f1135c57dfcf15482013ce6e5f093a86db69646a5aa"}, - {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:52a50aa3fb3acb9cf7213573ef55d31d6eca37f5709c69e6858fe3bc04a5c2a2"}, - {file = "pillow-10.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:127cee571038f252a552760076407f9cff79761c3d436a12af6000cd182a9d04"}, - {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:8d12251f02d69d8310b046e82572ed486685c38f02176bd08baf216746eb947f"}, - {file = "pillow-10.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54f1852cd531aa981bc0965b7d609f5f6cc8ce8c41b1139f6ed6b3c54ab82bfb"}, - {file = "pillow-10.2.0-cp312-cp312-win32.whl", hash = "sha256:257d8788df5ca62c980314053197f4d46eefedf4e6175bc9412f14412ec4ea2f"}, - {file = "pillow-10.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:154e939c5f0053a383de4fd3d3da48d9427a7e985f58af8e94d0b3c9fcfcf4f9"}, - {file = "pillow-10.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:f379abd2f1e3dddb2b61bc67977a6b5a0a3f7485538bcc6f39ec76163891ee48"}, - {file = "pillow-10.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:8373c6c251f7ef8bda6675dd6d2b3a0fcc31edf1201266b5cf608b62a37407f9"}, - {file = "pillow-10.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:870ea1ada0899fd0b79643990809323b389d4d1d46c192f97342eeb6ee0b8483"}, - {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4b6b1e20608493548b1f32bce8cca185bf0480983890403d3b8753e44077129"}, - {file = "pillow-10.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3031709084b6e7852d00479fd1d310b07d0ba82765f973b543c8af5061cf990e"}, - {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:3ff074fc97dd4e80543a3e91f69d58889baf2002b6be64347ea8cf5533188213"}, - {file = "pillow-10.2.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:cb4c38abeef13c61d6916f264d4845fab99d7b711be96c326b84df9e3e0ff62d"}, - {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b1b3020d90c2d8e1dae29cf3ce54f8094f7938460fb5ce8bc5c01450b01fbaf6"}, - {file = "pillow-10.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:170aeb00224ab3dc54230c797f8404507240dd868cf52066f66a41b33169bdbe"}, - {file = "pillow-10.2.0-cp38-cp38-win32.whl", hash = "sha256:c4225f5220f46b2fde568c74fca27ae9771536c2e29d7c04f4fb62c83275ac4e"}, - {file = "pillow-10.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:0689b5a8c5288bc0504d9fcee48f61a6a586b9b98514d7d29b840143d6734f39"}, - {file = "pillow-10.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b792a349405fbc0163190fde0dc7b3fef3c9268292586cf5645598b48e63dc67"}, - {file = "pillow-10.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c570f24be1e468e3f0ce7ef56a89a60f0e05b30a3669a459e419c6eac2c35364"}, - {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8ecd059fdaf60c1963c58ceb8997b32e9dc1b911f5da5307aab614f1ce5c2fb"}, - {file = "pillow-10.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c365fd1703040de1ec284b176d6af5abe21b427cb3a5ff68e0759e1e313a5e7e"}, - {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:70c61d4c475835a19b3a5aa42492409878bbca7438554a1f89d20d58a7c75c01"}, - {file = "pillow-10.2.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:b6f491cdf80ae540738859d9766783e3b3c8e5bd37f5dfa0b76abdecc5081f13"}, - {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d189550615b4948f45252d7f005e53c2040cea1af5b60d6f79491a6e147eef7"}, - {file = "pillow-10.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:49d9ba1ed0ef3e061088cd1e7538a0759aab559e2e0a80a36f9fd9d8c0c21591"}, - {file = "pillow-10.2.0-cp39-cp39-win32.whl", hash = "sha256:babf5acfede515f176833ed6028754cbcd0d206f7f614ea3447d67c33be12516"}, - {file = "pillow-10.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:0304004f8067386b477d20a518b50f3fa658a28d44e4116970abfcd94fac34a8"}, - {file = "pillow-10.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:0fb3e7fc88a14eacd303e90481ad983fd5b69c761e9e6ef94c983f91025da869"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:322209c642aabdd6207517e9739c704dc9f9db943015535783239022002f054a"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3eedd52442c0a5ff4f887fab0c1c0bb164d8635b32c894bc1faf4c618dd89df2"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb28c753fd5eb3dd859b4ee95de66cc62af91bcff5db5f2571d32a520baf1f04"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:33870dc4653c5017bf4c8873e5488d8f8d5f8935e2f1fb9a2208c47cdd66efd2"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3c31822339516fb3c82d03f30e22b1d038da87ef27b6a78c9549888f8ceda39a"}, - {file = "pillow-10.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a2b56ba36e05f973d450582fb015594aaa78834fefe8dfb8fcd79b93e64ba4c6"}, - {file = "pillow-10.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d8e6aeb9201e655354b3ad049cb77d19813ad4ece0df1249d3c793de3774f8c7"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:2247178effb34a77c11c0e8ac355c7a741ceca0a732b27bf11e747bbc950722f"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15587643b9e5eb26c48e49a7b33659790d28f190fc514a322d55da2fb5c2950e"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753cd8f2086b2b80180d9b3010dd4ed147efc167c90d3bf593fe2af21265e5a5"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:7c8f97e8e7a9009bcacbe3766a36175056c12f9a44e6e6f2d5caad06dcfbf03b"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d1b35bcd6c5543b9cb547dee3150c93008f8dd0f1fef78fc0cd2b141c5baf58a"}, - {file = "pillow-10.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe4c15f6c9285dc54ce6553a3ce908ed37c8f3825b5a51a15c91442bb955b868"}, - {file = "pillow-10.2.0.tar.gz", hash = "sha256:e87f0b2c78157e12d7686b27d63c070fd65d994e8ddae6f328e0dcf4a0cd007e"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, + {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, + {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, + {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, + {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, + {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, + {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, + {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, + {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, + {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, + {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, + {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, + {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, + {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, + {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, + {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, + {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, + {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, + {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, + {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, + {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, + {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, + {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, + {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, + {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, + {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, + {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, + {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, + {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, + {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, + {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, + {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, + {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, ] [package.extras] @@ -1017,18 +1004,19 @@ xmp = ["defusedxml"] [[package]] name = "platformdirs" -version = "4.2.0" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +version = "4.2.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, - {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] +type = ["mypy (>=1.8)"] [[package]] name = "psycopg2-binary" @@ -1113,24 +1101,24 @@ files = [ [[package]] name = "pycparser" -version = "2.21" +version = "2.22" description = "C parser in Python" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.8" files = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, ] [[package]] name = "pygithub" -version = "2.2.0" +version = "2.3.0" description = "Use the full Github API v3" optional = false python-versions = ">=3.7" files = [ - {file = "PyGithub-2.2.0-py3-none-any.whl", hash = "sha256:41042ea53e4c372219db708c38d2ca1fd4fadab75475bac27d89d339596cfad1"}, - {file = "PyGithub-2.2.0.tar.gz", hash = "sha256:e39be7c4dc39418bdd6e3ecab5931c636170b8b21b4d26f9ecf7e6102a3b51c3"}, + {file = "PyGithub-2.3.0-py3-none-any.whl", hash = "sha256:65b499728be3ce7b0cd2cd760da3b32f0f4d7bc55e5e0677617f90f6564e793e"}, + {file = "PyGithub-2.3.0.tar.gz", hash = "sha256:0148d7347a1cdeed99af905077010aef81a4dad988b0ba51d4108bf66b443f7e"}, ] [package.dependencies] @@ -1212,6 +1200,7 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -1248,119 +1237,104 @@ files = [ [[package]] name = "rapidfuzz" -version = "2.15.2" +version = "3.9.3" description = "rapid fuzzy string matching" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "rapidfuzz-2.15.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b2e64e08588965b2490ee6b581d3901dd207ec3f6919b1c8da495183acfde953"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0af367ecb515ae695d7da21b0bd05784f388621e9d6a2e21dc96e6ba5d18d95f"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:892d0d75f0b820d949b0bf9502f746cfcbaab98d8a47653fa8369607fde250f1"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcf1d564ec948a4bf0750252579871be1790de66200f4cf8d624446017d74ee9"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab2f86733fe34cd825b6cbc688d41b7eb19ae0ce1ea7dc57eac13862d4b9ecb5"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8bdc497a8930428fa35158c58a744ddaa930621b80adfb61884456d8f184288a"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97f6c4948ca07ad1a30e70da56ec672422ef6bf18d10b6a881e7a64ba73a126d"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f3e2cc54edffd62ae38a03802b79c0f0cec6c2f89819607350fb5c4c00442d7"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0a252ccb39d628d0f68bab80ba18a02e0d1853a0ec71991e665a6bf81a28c79a"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ff82edd7ff9796e2ca349aa583fcb6b9ae96db0b6c5a76dcf0c1f67b1cb86964"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:0860877f455833e5ed7113e859a9b2bf9670b22fdc7a48b81384a04c4a8e8a48"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:1a78c75ad082fdd58fdcf04551b7737c96aa9e870f1b008b881fc179e7dc6208"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a9df54f67a22a2447b8b6648880de9ede5e2a2e568644e1de770df9bef5c2fb4"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-win32.whl", hash = "sha256:055e85bb1237142da4ed024f9986c3720d484036f8dd550b090582f288b71bb9"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-win_amd64.whl", hash = "sha256:8f220df380c127ef8a9129d8878dabf99ed0f543597cf81dfdd30eca03843666"}, - {file = "rapidfuzz-2.15.2-cp310-cp310-win_arm64.whl", hash = "sha256:49972e202251ba60de41a7add8e86a055478020eabf3339300f46a8fdc35d048"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:29352510bcc2b7c3c7f3c1ab6f4c2115dc640cd79a9dc8e01adbae19fb96d359"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1ae3f741b9b3e95908158e6e56a5f11c1abc51754801dccd495e5cba734c541e"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a716bbded611cc82f7b27dcd7335b7bae49706c97a8738283464ff1536e7407"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ff36fb50f02259402d7cbdc96f75671b2cb14550db5ad6534a09a7f4940d796"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d60a2368e2564155d7209143a6b1dafa1eb457f31cf44698f917cba608d2341f"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c02fd6d75de19633f622daf6584cb6ed3148eac3a2b6b08fd3539c166de2921f"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a5c875da0e0c9709dbdc6e33a7f061192e98943817e6d0e1f5d1d8b07050e349"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb74dcfadf0c5f520074455fe51fa0f62876e5473f5f60521d153afef888ef70"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b31f65137e8e45c4fb2dda394bb31598cff8290fb0ce5e66c8cf47d1bc554cb"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:689008633f88cf8802dbd281ac745775aeeee67525d532fcbabda0c8bc5b2e32"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:02fd52352346c965fdc9de9d26f55d61941cc27c876a589eeb3f4efdb7dffdb1"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:454ab8b5c8fc526243133dab013f0a3355efcc1200829cfba7ef56280c7763fc"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fd40f263d1ad1cdd4b657e867654674315eea9abf3fce64269610b7bc81265ee"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-win32.whl", hash = "sha256:66db4817c54a6ca91234959c4f6d0cb1fd943ddfb379ee7f9e6dce99b522554e"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:3f8eaf74105ffea1d15198b109ff0ca7b6dccafc61e05fa5f98a53d925707c57"}, - {file = "rapidfuzz-2.15.2-cp311-cp311-win_arm64.whl", hash = "sha256:ed0ec102b5e405d7562e4df05729a89467ae5c8a364c52fcf8c129398e82e6c5"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c0c8475f029a50bf65571b59d332fccd3eb33c5e49283868490a973e9ca7c33c"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ee9ee24eb431d5f73d0b255dc8e66272967a58cd6670cca984a81bbfc7dde904"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a1ecd818c108cefea2c02a9a716e223f811e612a050c8625555336b65d1cabef"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3eda119ebcf501dc35054abd9a187b5249b3d93b3965485371efb48e735b72c"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7ba83d0846991f67c2ec12ff8530b5e0f929e32a57352080b5f95aade0a62e"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c279864902a9538b17547e0d9399f05f36ebb9f3356bc5bc4cec2ba137fa5a17"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c94e247011fa7eea14d210123ebda2ecdf98ccc114254353edb4501ee8a19d7"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675c9052b3a04a4b33c92f0b8952ef2439163853422cc583286351ee82fc4d26"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c2d64820ae7a795082208a2d762c6a291aca116b86e35c2831e468ae3d4bb5cd"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:c0f12cc4a8216edfaa0511aae34d8b2f824a05cfe5a26a08de9cf180ae584e88"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e27da009ef39dc64297bcdf09c8d4c79ac90d0015fcf0a01af2a802cd7e1803"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:ea541d56fbb7de717a013790c2bce655252da220f23db0c6ce24f628cbe228e6"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9f52338e4e69aff4260c84275c7a704d198315b9b84303e67e584971409347d0"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-win32.whl", hash = "sha256:d5550e0078b2618c4ea7ea761053337eb7c5f5cc515f4941d8108ce9b0c7ee8c"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:19f72cfe2553c83c5e383851aba2891dafbb6446b6ae1ec0637333558ddd564e"}, - {file = "rapidfuzz-2.15.2-cp312-cp312-win_arm64.whl", hash = "sha256:423ef2ca785da77cd081d5bbc57035dc9b91500008a1b8e8e811a0ba3871a5ee"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0a02f1b08879a74aa7b4e562823f67a2e913fe3bd18c5346d9270d16fc588500"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a100ca26804b9ac2b2c0f70c632102bc0005d2cafe6d748f5d01dbe569c378bf"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e9fb88659cff92eba1b441efe426a4c349372137ee713b3a3933cc6ead73234"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:58073d3ebed8c0f51e163654dcb5e34f1e8b67f7b23361441861c6021243184b"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4f55ad06ff79c2ffa3d1f5b38ce8f3082fa4db57c04be7de85243bd0625ca4ef"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ceecb57ec9e5c0d5bd9bd2881731c59cdc9a2c51711fd0b29b5bf14bdcab465f"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6c32c855e16ef3890037569f6f1299857172c674cd8946244e5fb7d5cacb771a"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:e46f82fda6f969da8be5a8f33a057b2a9c6e7b80ab8679344a72e6fb708a48fc"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:6edc9b138797c60c1276171d8c97f53b17e304ade37c022ff97b1e995f79ba79"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:b32e4fd756a32f92b6f8b707a682ab4054b90c835021c01d81baba22f6277172"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5fb89d3a8d389eca258aba913adc81a8b8231b48896abbcb2f05768455584c4e"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-win32.whl", hash = "sha256:03ceea6cc9e4442379aa8581fbe61bad6e12d7938b16fbdc8442c8d915ad1154"}, - {file = "rapidfuzz-2.15.2-cp37-cp37m-win_amd64.whl", hash = "sha256:cb9f24fafb5ed77fc2ce23b1d8351efcfdb4c05b5f3b96bf004e89344a3d30ed"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:aab133bea22acbd3fa3740989a2f21d0e275efede2bf406a25a84392086c32f9"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4e110224e0de4fe4876224104a79550d18df15459fe94adf24b4b644e31d69cc"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:780b006bd007e4a071a9c022733f56b0df1f8c269bb7e9dbe079a79e8d9d3b8d"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:898bee3fd785ee695d4cb0d3c689407809cafca472851904aa78143ca6634903"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34623f51ed5dcbb2ddb97b2fefda34e7b53a047c71aac5ec6b72e42d5263f8b2"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02b3612c9318006290e6e6d82f1f98b83aa4cf062075c5ea03fac71ba4d31499"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dd0aab9ffab0010ae28b60f64c98c09c93086b3dc0cb3da863e53a3ca14a2bd"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e772677a84a166531f975301cb91db234a56eb5b6785e79ff5cb335251580efc"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1b7a670aed23d9a8d27a0031fa059e8f50f3f7287bd5a075a448251029794de9"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:830f799e5ec534633dee3b26c6d5398461dd3ced22118ab590f7fd0f91263058"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:e427a9c9c1a8adac7b0293ddfe8f5885edf4f425cfd8a3b7ceae20434ec0663c"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3a3df80a264a999a120e637f98a1460d4f2c815323dd605e2022eef97db55448"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:1496540d2ce8b1b9f340e652b9306674fa657d8d3a0b9629421cf31ace219092"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-win32.whl", hash = "sha256:aabd9da406fec009c08d2cd1bfa444ee568edf8e7c9a9d5e609885fc81c243a3"}, - {file = "rapidfuzz-2.15.2-cp38-cp38-win_amd64.whl", hash = "sha256:d21c66b15fbe253d48399a9d9db361ab2b3462a59b78c9279d9d7d347f5ded91"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ef4dea11b87234e8b08ee47df9d869ae071bdacb5e55df82673ab9fa622f1e0"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ee3d9bc953f232bffcbd973137505f6cf5be5ed9c2cdc5e4a5db4be33bf5a734"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:efb94f6adbbbdacac9f687eb151ae9220ee9f141bb259fe07e82a2087114c17e"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9c3e07d13661871aebc325b9b3acbd42355a1df1e21ad0435fc81980fd20607"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01bae563a010900abba857e485c3747a78d61c88431cc3d9bea894c7c3e521f"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a09187df670e344468597b2c6f5ddc7651be75c4b594baa62c9261a144e5c058"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fcbfe5497c93a1b8717ea38b41b47f7e9d155fbc36a6bbfa84b8c901875465af"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f997a93b85c5798fe139a46c68c85de06ff75b4fd52d52463e46573bff39774"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:199676b8a19746017a0fbad0eb11380cbda4f635b6d2ee477544743b7f99d947"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:499a170088049258d5118bff8cf88f88ef6054544edbea0f2920eba8669e5eb9"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:a69ebe7b493557c425ca1d64bf0b5599f0405772b5179070adc2f62f7867836f"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:00bd97cd31aad049400b70e0872b54457c4769b296176d5b064f6a5d6391909f"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cadabe1287314bc5053f57c6043df04e33cf5fba33514ca0f4c7b0b8476063a0"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-win32.whl", hash = "sha256:301709491a7960473c34501602cd85a7653df7e0d4189c0ded1e0fd86a83b6ca"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-win_amd64.whl", hash = "sha256:9c968a2330b6f2de93e6d54ef7ebd5e5724ee730cd6f225e977cebc7af1df366"}, - {file = "rapidfuzz-2.15.2-cp39-cp39-win_arm64.whl", hash = "sha256:c6776c27385f3fe5810f3c389f01957d5fa6c3c7f7a76fd9815f2933674f787f"}, - {file = "rapidfuzz-2.15.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0b4c632b684478fd8780970685a0c575a5bee65692727ff9898acf75d61cb3ff"}, - {file = "rapidfuzz-2.15.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b1cfca399461e1f534fbeb3c87f39f2c37ed71f8d1dfb02b78a5b3f81bf0ef"}, - {file = "rapidfuzz-2.15.2-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba35ec7256a86270a5e2d193ff0089cf84787a1aa94a48f5f6105f86feb8ca38"}, - {file = "rapidfuzz-2.15.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdfc137bbe2e942321f725004395444d2594077932ad55f927d6b6e884c09142"}, - {file = "rapidfuzz-2.15.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:153366a00ea22e79f051298fb9606bf9472bca5ce1b82319070fcbea2f7b97d7"}, - {file = "rapidfuzz-2.15.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6bf1c60432755ed8ab5870a932b7c9382435a240d727d3b5e68f9ff9f83a3556"}, - {file = "rapidfuzz-2.15.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a358eb275eadad0ac44f0fdb2255d6b373908c742f94e06b2190dbfaaaaa49b8"}, - {file = "rapidfuzz-2.15.2-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34136ab5bbd1b9643f9072102a88471995100b5d734cfaa946d3b63e332e653"}, - {file = "rapidfuzz-2.15.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:796e53c5f78c159aff8e5003bca41bfe007c6a63ee7e7a289765a7db30429197"}, - {file = "rapidfuzz-2.15.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2ce4a91be05c28b57d5019b09cf0970305760623e34da95f2cddd9067e7fe91d"}, - {file = "rapidfuzz-2.15.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:237d5b4cbfacdef0a84f2ead0b4819c586bb74d05f4a380bd2f8489464b7b7fa"}, - {file = "rapidfuzz-2.15.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:773dff970af0474d7d551a953a0075840ced30315d4885e038a289857ed33365"}, - {file = "rapidfuzz-2.15.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c536fbbebb496a76cac3a45f139bf023807b1fb6e2262e77f875fc9b6802ec4e"}, - {file = "rapidfuzz-2.15.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e85579a698c9436c2dac1583d4b07cca635faeb9a7adeab03d42938ec0fe9f58"}, - {file = "rapidfuzz-2.15.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:77c540546c0ea7cb229cd9823f9cd174c93988657727880bfdd6db7f353f93d6"}, - {file = "rapidfuzz-2.15.2.tar.gz", hash = "sha256:bfc1d38a7adcbe8912f980a5f46f27a801dd8655582ff0d4a2c0431c02b7ce33"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdb8c5b8e29238ec80727c2ba3b301efd45aa30c6a7001123a6647b8e6f77ea4"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3bd0d9632088c63a241f217742b1cf86e2e8ae573e01354775bd5016d12138c"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:153f23c03d4917f6a1fc2fb56d279cc6537d1929237ff08ee7429d0e40464a18"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96c5225e840f1587f1bac8fa6f67562b38e095341576e82b728a82021f26d62"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b777cd910ceecd738adc58593d6ed42e73f60ad04ecdb4a841ae410b51c92e0e"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53e06e4b81f552da04940aa41fc556ba39dee5513d1861144300c36c33265b76"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c7ca5b6050f18fdcacdada2dc5fb7619ff998cd9aba82aed2414eee74ebe6cd"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:87bb8d84cb41446a808c4b5f746e29d8a53499381ed72f6c4e456fe0f81c80a8"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:959a15186d18425d19811bea86a8ffbe19fd48644004d29008e636631420a9b7"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a24603dd05fb4e3c09d636b881ce347e5f55f925a6b1b4115527308a323b9f8e"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0d055da0e801c71dd74ba81d72d41b2fa32afa182b9fea6b4b199d2ce937450d"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:875b581afb29a7213cf9d98cb0f98df862f1020bce9d9b2e6199b60e78a41d14"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-win32.whl", hash = "sha256:6073a46f61479a89802e3f04655267caa6c14eb8ac9d81a635a13805f735ebc1"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:119c010e20e561249b99ca2627f769fdc8305b07193f63dbc07bca0a6c27e892"}, + {file = "rapidfuzz-3.9.3-cp310-cp310-win_arm64.whl", hash = "sha256:790b0b244f3213581d42baa2fed8875f9ee2b2f9b91f94f100ec80d15b140ba9"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f57e8305c281e8c8bc720515540e0580355100c0a7a541105c6cafc5de71daae"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4fc7b784cf987dbddc300cef70e09a92ed1bce136f7bb723ea79d7e297fe76d"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b422c0a6fe139d5447a0766268e68e6a2a8c2611519f894b1f31f0a392b9167"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f50fed4a9b0c9825ff37cf0bccafd51ff5792090618f7846a7650f21f85579c9"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b80eb7cbe62348c61d3e67e17057cddfd6defab168863028146e07d5a8b24a89"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f45be77ec82da32ce5709a362e236ccf801615cc7163b136d1778cf9e31b14"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd84b7f652a5610733400307dc732f57c4a907080bef9520412e6d9b55bc9adc"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e6d27dad8c990218b8cd4a5c99cbc8834f82bb46ab965a7265d5aa69fc7ced7"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:05ee0696ebf0dfe8f7c17f364d70617616afc7dafe366532730ca34056065b8a"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2bc8391749e5022cd9e514ede5316f86e332ffd3cfceeabdc0b17b7e45198a8c"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93981895602cf5944d89d317ae3b1b4cc684d175a8ae2a80ce5b65615e72ddd0"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:754b719a4990735f66653c9e9261dcf52fd4d925597e43d6b9069afcae700d21"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-win32.whl", hash = "sha256:14c9f268ade4c88cf77ab007ad0fdf63699af071ee69378de89fff7aa3cae134"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc1991b4cde6c9d3c0bbcb83d5581dc7621bec8c666c095c65b4277233265a82"}, + {file = "rapidfuzz-3.9.3-cp311-cp311-win_arm64.whl", hash = "sha256:0c34139df09a61b1b557ab65782ada971b4a3bce7081d1b2bee45b0a52231adb"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d6a210347d6e71234af5c76d55eeb0348b026c9bb98fe7c1cca89bac50fb734"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b300708c917ce52f6075bdc6e05b07c51a085733650f14b732c087dc26e0aaad"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83ea7ca577d76778250421de61fb55a719e45b841deb769351fc2b1740763050"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8319838fb5b7b5f088d12187d91d152b9386ce3979ed7660daa0ed1bff953791"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:505d99131afd21529293a9a7b91dfc661b7e889680b95534756134dc1cc2cd86"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c52970f7784518d7c82b07a62a26e345d2de8c2bd8ed4774e13342e4b3ff4200"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:143caf7247449055ecc3c1e874b69e42f403dfc049fc2f3d5f70e1daf21c1318"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b8ab0fa653d9225195a8ff924f992f4249c1e6fa0aea563f685e71b81b9fcccf"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57e7c5bf7b61c7320cfa5dde1e60e678d954ede9bb7da8e763959b2138391401"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51fa1ba84653ab480a2e2044e2277bd7f0123d6693051729755addc0d015c44f"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:17ff7f7eecdb169f9236e3b872c96dbbaf116f7787f4d490abd34b0116e3e9c8"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:afe7c72d3f917b066257f7ff48562e5d462d865a25fbcabf40fca303a9fa8d35"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-win32.whl", hash = "sha256:e53ed2e9b32674ce96eed80b3b572db9fd87aae6742941fb8e4705e541d861ce"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:35b7286f177e4d8ba1e48b03612f928a3c4bdac78e5651379cec59f95d8651e6"}, + {file = "rapidfuzz-3.9.3-cp312-cp312-win_arm64.whl", hash = "sha256:e6e4b9380ed4758d0cb578b0d1970c3f32dd9e87119378729a5340cb3169f879"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a39890013f6d5b056cc4bfdedc093e322462ece1027a57ef0c636537bdde7531"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b5bc0fdbf419493163c5c9cb147c5fbe95b8e25844a74a8807dcb1a125e630cf"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe6e200a75a792d37b960457904c4fce7c928a96ae9e5d21d2bd382fe39066e"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de077c468c225d4c18f7188c47d955a16d65f21aab121cbdd98e3e2011002c37"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f917eaadf5388466a95f6a236f678a1588d231e52eda85374077101842e794e"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:858ba57c05afd720db8088a8707079e8d024afe4644001fe0dbd26ef7ca74a65"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d36447d21b05f90282a6f98c5a33771805f9222e5d0441d03eb8824e33e5bbb4"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:acbe4b6f1ccd5b90c29d428e849aa4242e51bb6cab0448d5f3c022eb9a25f7b1"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:53c7f27cdf899e94712972237bda48cfd427646aa6f5d939bf45d084780e4c16"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6175682a829c6dea4d35ed707f1dadc16513270ef64436568d03b81ccb6bdb74"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5276df395bd8497397197fca2b5c85f052d2e6a66ffc3eb0544dd9664d661f95"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:77b5c4f3e72924d7845f0e189c304270066d0f49635cf8a3938e122c437e58de"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-win32.whl", hash = "sha256:8add34061e5cd561c72ed4febb5c15969e7b25bda2bb5102d02afc3abc1f52d0"}, + {file = "rapidfuzz-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:604e0502a39cf8e67fa9ad239394dddad4cdef6d7008fdb037553817d420e108"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21047f55d674614eb4b0ab34e35c3dc66f36403b9fbfae645199c4a19d4ed447"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a56da3aff97cb56fe85d9ca957d1f55dbac7c27da927a86a2a86d8a7e17f80aa"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:964c08481aec2fe574f0062e342924db2c6b321391aeb73d68853ed42420fd6d"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e2b827258beefbe5d3f958243caa5a44cf46187eff0c20e0b2ab62d1550327a"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6e65a301fcd19fbfbee3a514cc0014ff3f3b254b9fd65886e8a9d6957fb7bca"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe93ba1725a8d47d2b9dca6c1f435174859427fbc054d83de52aea5adc65729"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca21c0a34adee582775da997a600283e012a608a107398d80a42f9a57ad323d"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:256e07d3465173b2a91c35715a2277b1ee3ae0b9bbab4e519df6af78570741d0"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:802ca2cc8aa6b8b34c6fdafb9e32540c1ba05fca7ad60b3bbd7ec89ed1797a87"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:dd789100fc852cffac1449f82af0da139d36d84fd9faa4f79fc4140a88778343"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:5d0abbacdb06e27ff803d7ae0bd0624020096802758068ebdcab9bd49cf53115"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:378d1744828e27490a823fc6fe6ebfb98c15228d54826bf4e49e4b76eb5f5579"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-win32.whl", hash = "sha256:5d0cb272d43e6d3c0dedefdcd9d00007471f77b52d2787a4695e9dd319bb39d2"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:15e4158ac4b3fb58108072ec35b8a69165f651ba1c8f43559a36d518dbf9fb3f"}, + {file = "rapidfuzz-3.9.3-cp39-cp39-win_arm64.whl", hash = "sha256:58c6a4936190c558d5626b79fc9e16497e5df7098589a7e80d8bff68148ff096"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5410dc848c947a603792f4f51b904a3331cf1dc60621586bfbe7a6de72da1091"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:282d55700a1a3d3a7980746eb2fcd48c9bbc1572ebe0840d0340d548a54d01fe"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc1037507810833646481f5729901a154523f98cbebb1157ba3a821012e16402"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e33f779391caedcba2ba3089fb6e8e557feab540e9149a5c3f7fea7a3a7df37"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41a81a9f311dc83d22661f9b1a1de983b201322df0c4554042ffffd0f2040c37"}, + {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a93250bd8fae996350c251e1752f2c03335bb8a0a5b0c7e910a593849121a435"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3617d1aa7716c57d120b6adc8f7c989f2d65bc2b0cbd5f9288f1fc7bf469da11"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad04a3f5384b82933213bba2459f6424decc2823df40098920856bdee5fd6e88"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8709918da8a88ad73c9d4dd0ecf24179a4f0ceba0bee21efc6ea21a8b5290349"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b770f85eab24034e6ef7df04b2bfd9a45048e24f8a808e903441aa5abde8ecdd"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930b4e6fdb4d914390141a2b99a6f77a52beacf1d06aa4e170cba3a98e24c1bc"}, + {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c8444e921bfc3757c475c4f4d7416a7aa69b2d992d5114fe55af21411187ab0d"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c1d3ef3878f871abe6826e386c3d61b5292ef5f7946fe646f4206b85836b5da"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d861bf326ee7dabc35c532a40384541578cd1ec1e1b7db9f9ecbba56eb76ca22"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cde6b9d9ba5007077ee321ec722fa714ebc0cbd9a32ccf0f4dd3cc3f20952d71"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb6546e7b6bed1aefbe24f68a5fb9b891cc5aef61bca6c1a7b1054b7f0359bb"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d8a57261ef7996d5ced7c8cba9189ada3fbeffd1815f70f635e4558d93766cb"}, + {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:67201c02efc596923ad950519e0b75ceb78d524177ea557134d6567b9ac2c283"}, + {file = "rapidfuzz-3.9.3.tar.gz", hash = "sha256:b398ea66e8ed50451bce5997c430197d5e4b06ac4aa74602717f792d8d8d06e2"}, ] [package.extras] @@ -1368,13 +1342,13 @@ full = ["numpy"] [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -1407,13 +1381,13 @@ tests = ["coverage (>=6.0.0)", "flake8", "mypy", "pytest (>=4.6)", "pytest-cov", [[package]] name = "sentry-sdk" -version = "1.42.0" +version = "1.45.0" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.42.0.tar.gz", hash = "sha256:4a8364b8f7edbf47f95f7163e48334c96100d9c098f0ae6606e2e18183c223e6"}, - {file = "sentry_sdk-1.42.0-py2.py3-none-any.whl", hash = "sha256:a654ee7e497a3f5f6368b36d4f04baeab1fe92b3105f7f6965d6ef0de35a9ba4"}, + {file = "sentry-sdk-1.45.0.tar.gz", hash = "sha256:509aa9678c0512344ca886281766c2e538682f8acfa50fd8d405f8c417ad0625"}, + {file = "sentry_sdk-1.45.0-py2.py3-none-any.whl", hash = "sha256:1ce29e30240cc289a027011103a8c83885b15ef2f316a60bcc7c5300afa144f1"}, ] [package.dependencies] @@ -1427,6 +1401,7 @@ asyncpg = ["asyncpg (>=0.23)"] beam = ["apache-beam (>=2.12)"] bottle = ["bottle (>=0.12.13)"] celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] chalice = ["chalice (>=1.16.0)"] clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] django = ["django (>=1.8)"] @@ -1451,6 +1426,21 @@ starlette = ["starlette (>=0.19.1)"] starlite = ["starlite (>=1.48)"] tornado = ["tornado (>=5)"] +[[package]] +name = "setuptools" +version = "70.0.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "setuptools-70.0.0-py3-none-any.whl", hash = "sha256:54faa7f2e8d2d11bcd2c07bed282eef1046b5c080d1c32add737d7b5817b1ad4"}, + {file = "setuptools-70.0.0.tar.gz", hash = "sha256:f211a66637b8fa059bb28183da127d4e86396c991a942b028c6650d4319c3fd0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "six" version = "1.16.0" @@ -1464,34 +1454,33 @@ files = [ [[package]] name = "sqlparse" -version = "0.4.4" +version = "0.5.0" description = "A non-validating SQL parser." optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" files = [ - {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"}, - {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"}, + {file = "sqlparse-0.5.0-py3-none-any.whl", hash = "sha256:c204494cd97479d0e39f28c93d46c0b2d5959c7b9ab904762ea6c7af211c8663"}, + {file = "sqlparse-0.5.0.tar.gz", hash = "sha256:714d0a4932c059d16189f58ef5411ec2287a4360f17cdd0edd2d09d4c5087c93"}, ] [package.extras] -dev = ["build", "flake8"] +dev = ["build", "hatch"] doc = ["sphinx"] -test = ["pytest", "pytest-cov"] [[package]] name = "stdlibs" -version = "2024.1.28" +version = "2024.5.15" description = "List of packages in the stdlib" optional = false python-versions = ">=3.8" files = [ - {file = "stdlibs-2024.1.28-py3-none-any.whl", hash = "sha256:a4e8e72485d589cfdbf2c75736e3c58058af9d699b008be7fb1507a9efb7dab7"}, - {file = "stdlibs-2024.1.28.tar.gz", hash = "sha256:ea158ac5b23c1a304153678908044d89a94c6354fa724f4452d754f9d6c16941"}, + {file = "stdlibs-2024.5.15-py3-none-any.whl", hash = "sha256:f775fae037583193c4bb808bf3d01d416b9e93c25736d40d04caef17c3a5490f"}, + {file = "stdlibs-2024.5.15.tar.gz", hash = "sha256:42e0e49747dfd7af21db459bf83e15dd13e49332304667edabf88b94231e9b59"}, ] [package.extras] -dev = ["attribution (==1.6.2)", "black (==24.1.1)", "coverage (==7.4.1)", "flake8 (==7.0.0)", "flit (==3.9.0)", "mypy (==1.8.0)", "packaging (==23.2)", "ufmt (==2.3.0)", "usort (==1.0.7)"] -docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] +dev = ["attribution (==1.7.1)", "black (==24.4.2)", "coverage (==7.5.1)", "flake8 (==7.0.0)", "flit (==3.9.0)", "mypy (==1.10.0)", "packaging (==24.0)", "ufmt (==2.6.0)", "usort (==1.0.8.post1)"] +docs = ["sphinx (==7.3.7)", "sphinx-mdinclude (==0.6.0)"] [[package]] name = "textwrap3" @@ -1526,26 +1515,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "tqdm" -version = "4.66.2" -description = "Fast, Extensible Progress Meter" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, - {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] -notebook = ["ipywidgets (>=6)"] -slack = ["slack-sdk"] -telegram = ["requests"] - [[package]] name = "trailrunner" version = "1.4.0" @@ -1566,13 +1535,13 @@ docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"] [[package]] name = "types-pytz" -version = "2024.1.0.20240203" +version = "2024.1.0.20240417" description = "Typing stubs for pytz" optional = false python-versions = ">=3.8" files = [ - {file = "types-pytz-2024.1.0.20240203.tar.gz", hash = "sha256:c93751ee20dfc6e054a0148f8f5227b9a00b79c90a4d3c9f464711a73179c89e"}, - {file = "types_pytz-2024.1.0.20240203-py3-none-any.whl", hash = "sha256:9679eef0365db3af91ef7722c199dbb75ee5c1b67e3c4dd7bfbeb1b8a71c21a3"}, + {file = "types-pytz-2024.1.0.20240417.tar.gz", hash = "sha256:6810c8a1f68f21fdf0f4f374a432487c77645a0ac0b31de4bf4690cf21ad3981"}, + {file = "types_pytz-2024.1.0.20240417-py3-none-any.whl", hash = "sha256:8335d443310e2db7b74e007414e74c4f53b67452c0cb0d228ca359ccfba59659"}, ] [[package]] @@ -1588,13 +1557,13 @@ files = [ [[package]] name = "types-requests" -version = "2.31.0.20240311" +version = "2.32.0.20240523" description = "Typing stubs for requests" optional = false python-versions = ">=3.8" files = [ - {file = "types-requests-2.31.0.20240311.tar.gz", hash = "sha256:b1c1b66abfb7fa79aae09097a811c4aa97130eb8831c60e47aee4ca344731ca5"}, - {file = "types_requests-2.31.0.20240311-py3-none-any.whl", hash = "sha256:47872893d65a38e282ee9f277a4ee50d1b28bd592040df7d1fdaffdf3779937d"}, + {file = "types-requests-2.32.0.20240523.tar.gz", hash = "sha256:26b8a6de32d9f561192b9942b41c0ab2d8010df5677ca8aa146289d11d505f57"}, + {file = "types_requests-2.32.0.20240523-py3-none-any.whl", hash = "sha256:f19ed0e2daa74302069bbbbf9e82902854ffa780bc790742a810a9aaa52f65ec"}, ] [package.dependencies] @@ -1602,30 +1571,15 @@ urllib3 = ">=2" [[package]] name = "typing-extensions" -version = "4.10.0" +version = "4.12.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, - {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, + {file = "typing_extensions-4.12.0-py3-none-any.whl", hash = "sha256:b349c66bea9016ac22978d800cfff206d5f9816951f12a7d0ec5578b0a819594"}, + {file = "typing_extensions-4.12.0.tar.gz", hash = "sha256:8cbcdc8606ebcb0d95453ad7dc5065e6237b6aa230a31e81d0f440c30fed5fd8"}, ] -[[package]] -name = "typing-inspect" -version = "0.9.0" -description = "Runtime inspection utilities for typing module." -optional = false -python-versions = "*" -files = [ - {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, - {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, -] - -[package.dependencies] -mypy-extensions = ">=0.3.0" -typing-extensions = ">=3.7.4" - [[package]] name = "tzdata" version = "2023.4" @@ -1676,39 +1630,43 @@ trailrunner = ">=1.0" [[package]] name = "watchdog" -version = "2.3.1" +version = "4.0.1" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "watchdog-2.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1f1200d4ec53b88bf04ab636f9133cb703eb19768a39351cee649de21a33697"}, - {file = "watchdog-2.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:564e7739abd4bd348aeafbf71cc006b6c0ccda3160c7053c4a53b67d14091d42"}, - {file = "watchdog-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:95ad708a9454050a46f741ba5e2f3468655ea22da1114e4c40b8cbdaca572565"}, - {file = "watchdog-2.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a073c91a6ef0dda488087669586768195c3080c66866144880f03445ca23ef16"}, - {file = "watchdog-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa8b028750b43e80eea9946d01925168eeadb488dfdef1d82be4b1e28067f375"}, - {file = "watchdog-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:964fd236cd443933268ae49b59706569c8b741073dbfd7ca705492bae9d39aab"}, - {file = "watchdog-2.3.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:91fd146d723392b3e6eb1ac21f122fcce149a194a2ba0a82c5e4d0ee29cd954c"}, - {file = "watchdog-2.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efe3252137392a471a2174d721e1037a0e6a5da7beb72a021e662b7000a9903f"}, - {file = "watchdog-2.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:85bf2263290591b7c5fa01140601b64c831be88084de41efbcba6ea289874f44"}, - {file = "watchdog-2.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f2df370cd8e4e18499dd0bfdef476431bcc396108b97195d9448d90924e3131"}, - {file = "watchdog-2.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ea5d86d1bcf4a9d24610aa2f6f25492f441960cf04aed2bd9a97db439b643a7b"}, - {file = "watchdog-2.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:6f5d0f7eac86807275eba40b577c671b306f6f335ba63a5c5a348da151aba0fc"}, - {file = "watchdog-2.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b848c71ef2b15d0ef02f69da8cc120d335cec0ed82a3fa7779e27a5a8527225"}, - {file = "watchdog-2.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0d9878be36d2b9271e3abaa6f4f051b363ff54dbbe7e7df1af3c920e4311ee43"}, - {file = "watchdog-2.3.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cd61f98cb37143206818cb1786d2438626aa78d682a8f2ecee239055a9771d5"}, - {file = "watchdog-2.3.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3d2dbcf1acd96e7a9c9aefed201c47c8e311075105d94ce5e899f118155709fd"}, - {file = "watchdog-2.3.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:03f342a9432fe08107defbe8e405a2cb922c5d00c4c6c168c68b633c64ce6190"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7a596f9415a378d0339681efc08d2249e48975daae391d58f2e22a3673b977cf"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:0e1dd6d449267cc7d6935d7fe27ee0426af6ee16578eed93bacb1be9ff824d2d"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_i686.whl", hash = "sha256:7a1876f660e32027a1a46f8a0fa5747ad4fcf86cb451860eae61a26e102c8c79"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:2caf77ae137935c1466f8cefd4a3aec7017b6969f425d086e6a528241cba7256"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:53f3e95081280898d9e4fc51c5c69017715929e4eea1ab45801d5e903dd518ad"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:9da7acb9af7e4a272089bd2af0171d23e0d6271385c51d4d9bde91fe918c53ed"}, - {file = "watchdog-2.3.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:8a4d484e846dcd75e96b96d80d80445302621be40e293bfdf34a631cab3b33dc"}, - {file = "watchdog-2.3.1-py3-none-win32.whl", hash = "sha256:a74155398434937ac2780fd257c045954de5b11b5c52fc844e2199ce3eecf4cf"}, - {file = "watchdog-2.3.1-py3-none-win_amd64.whl", hash = "sha256:5defe4f0918a2a1a4afbe4dbb967f743ac3a93d546ea4674567806375b024adb"}, - {file = "watchdog-2.3.1-py3-none-win_ia64.whl", hash = "sha256:4109cccf214b7e3462e8403ab1e5b17b302ecce6c103eb2fc3afa534a7f27b96"}, - {file = "watchdog-2.3.1.tar.gz", hash = "sha256:d9f9ed26ed22a9d331820a8432c3680707ea8b54121ddcc9dc7d9f2ceeb36906"}, + {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:da2dfdaa8006eb6a71051795856bedd97e5b03e57da96f98e375682c48850645"}, + {file = "watchdog-4.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e93f451f2dfa433d97765ca2634628b789b49ba8b504fdde5837cdcf25fdb53b"}, + {file = "watchdog-4.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ef0107bbb6a55f5be727cfc2ef945d5676b97bffb8425650dadbb184be9f9a2b"}, + {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:17e32f147d8bf9657e0922c0940bcde863b894cd871dbb694beb6704cfbd2fb5"}, + {file = "watchdog-4.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:03e70d2df2258fb6cb0e95bbdbe06c16e608af94a3ffbd2b90c3f1e83eb10767"}, + {file = "watchdog-4.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:123587af84260c991dc5f62a6e7ef3d1c57dfddc99faacee508c71d287248459"}, + {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:093b23e6906a8b97051191a4a0c73a77ecc958121d42346274c6af6520dec175"}, + {file = "watchdog-4.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:611be3904f9843f0529c35a3ff3fd617449463cb4b73b1633950b3d97fa4bfb7"}, + {file = "watchdog-4.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:62c613ad689ddcb11707f030e722fa929f322ef7e4f18f5335d2b73c61a85c28"}, + {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d4925e4bf7b9bddd1c3de13c9b8a2cdb89a468f640e66fbfabaf735bd85b3e35"}, + {file = "watchdog-4.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cad0bbd66cd59fc474b4a4376bc5ac3fc698723510cbb64091c2a793b18654db"}, + {file = "watchdog-4.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a3c2c317a8fb53e5b3d25790553796105501a235343f5d2bf23bb8649c2c8709"}, + {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c9904904b6564d4ee8a1ed820db76185a3c96e05560c776c79a6ce5ab71888ba"}, + {file = "watchdog-4.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:667f3c579e813fcbad1b784db7a1aaa96524bed53437e119f6a2f5de4db04235"}, + {file = "watchdog-4.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d10a681c9a1d5a77e75c48a3b8e1a9f2ae2928eda463e8d33660437705659682"}, + {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0144c0ea9997b92615af1d94afc0c217e07ce2c14912c7b1a5731776329fcfc7"}, + {file = "watchdog-4.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:998d2be6976a0ee3a81fb8e2777900c28641fb5bfbd0c84717d89bca0addcdc5"}, + {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e7921319fe4430b11278d924ef66d4daa469fafb1da679a2e48c935fa27af193"}, + {file = "watchdog-4.0.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:f0de0f284248ab40188f23380b03b59126d1479cd59940f2a34f8852db710625"}, + {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bca36be5707e81b9e6ce3208d92d95540d4ca244c006b61511753583c81c70dd"}, + {file = "watchdog-4.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ab998f567ebdf6b1da7dc1e5accfaa7c6992244629c0fdaef062f43249bd8dee"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:dddba7ca1c807045323b6af4ff80f5ddc4d654c8bce8317dde1bd96b128ed253"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_armv7l.whl", hash = "sha256:4513ec234c68b14d4161440e07f995f231be21a09329051e67a2118a7a612d2d"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_i686.whl", hash = "sha256:4107ac5ab936a63952dea2a46a734a23230aa2f6f9db1291bf171dac3ebd53c6"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64.whl", hash = "sha256:6e8c70d2cd745daec2a08734d9f63092b793ad97612470a0ee4cbb8f5f705c57"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f27279d060e2ab24c0aa98363ff906d2386aa6c4dc2f1a374655d4e02a6c5e5e"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_s390x.whl", hash = "sha256:f8affdf3c0f0466e69f5b3917cdd042f89c8c63aebdb9f7c078996f607cdb0f5"}, + {file = "watchdog-4.0.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:ac7041b385f04c047fcc2951dc001671dee1b7e0615cde772e84b01fbf68ee84"}, + {file = "watchdog-4.0.1-py3-none-win32.whl", hash = "sha256:206afc3d964f9a233e6ad34618ec60b9837d0582b500b63687e34011e15bb429"}, + {file = "watchdog-4.0.1-py3-none-win_amd64.whl", hash = "sha256:7577b3c43e5909623149f76b099ac49a1a01ca4e167d1785c76eb52fa585745a"}, + {file = "watchdog-4.0.1-py3-none-win_ia64.whl", hash = "sha256:d7b9f5f3299e8dd230880b6c55504a1f69cf1e4316275d1b215ebdd8187ec88d"}, + {file = "watchdog-4.0.1.tar.gz", hash = "sha256:eebaacf674fa25511e8867028d281e602ee6500045b57f43b08778082f7f8b44"}, ] [package.extras] @@ -1796,4 +1754,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "14cf2fb96d95ff8d9c11940aa4eb4c1c534b9a4d132ab283075bbab353ab72c4" +content-hash = "de0e3cd393bf792ca174f74d0ae989b49a720d7dd65f87af1b271c9f5c08c70b" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index e665d00af..81e07dfaa 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "" authors = ["Decomp.me team"] license = "MIT" +package-mode = false [tool.poetry.dependencies] python = "^3.10" @@ -16,7 +17,6 @@ responses = "0.18.0" jwt = "^1.3.1" PyGithub = "^2.1.1" drf-extensions = "^0.7.1" -tqdm = "^4.66.1" tzdata = "^2023.3" Pillow = "^10.1.0" html-json-forms = "^1.1.1" @@ -28,6 +28,7 @@ sentry-sdk = "^1.39.1" django-session-timeout = "^0.1.0" django = "^5.0" requests = "^2.31.0" +setuptools = "^70.0.0" [tool.poetry.group.dev.dependencies] black = "^23.12.0" diff --git a/backend/wine/README.md b/backend/wine/README.md new file mode 100644 index 000000000..66bb5d4ba --- /dev/null +++ b/backend/wine/README.md @@ -0,0 +1 @@ +This directory contains registry hacks required to get compilers to behave under Wine. diff --git a/backend/wine/msvc80.reg b/backend/wine/msvc80.reg new file mode 100644 index 000000000..fdde5786c --- /dev/null +++ b/backend/wine/msvc80.reg @@ -0,0 +1,11 @@ +Windows Registry Editor Version 5.00 + + +[HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Defaults\Provider Types\Type 001] +"Name"="Microsoft Strong Cryptographic Provider" +"TypeName"="RSA Full (Signature and Key Exchange)" + +[HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\Defaults\Provider\Microsoft Strong Cryptographic Provider] +"Image Path"="rsaenh.dll" +"SigInFile"=dword:0 +"Type"=dword:1 diff --git a/docker-compose.yaml b/docker-compose.yaml index 06447dfd5..d72ff0fd4 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -23,6 +23,7 @@ services: ENABLE_MSDOS_SUPPORT: "NO" ENABLE_PS2_SUPPORT: "NO" ENABLE_WIN32_SUPPORT: "NO" + ENABLE_DREAMCAST_SUPPORT: "NO" # dont install clang by default ENABLE_SWITCH_SUPPORT: "NO" # dont install dosemu by default @@ -45,8 +46,6 @@ services: volumes: - ./backend:/backend tmpfs: - # explicitly mount /dev/shm with exec as dosemu2 requires exec privilege - - /dev/shm:exec,uid=1000,gid=1000,size=64M,mode=0700 # Use a separate tmpfs to prevent a rogue jailed process # from filling /tmp on the parent container - /sandbox/tmp:exec,uid=1000,gid=1000,size=64M,mode=0700 diff --git a/frontend/next.config.js b/frontend/next.config.js index 6560d4822..91bb70887 100644 --- a/frontend/next.config.js +++ b/frontend/next.config.js @@ -1,12 +1,12 @@ +const { Compilation } = require("webpack") const { execSync } = require("child_process") - const { config } = require("dotenv") for (const envFile of [".env.local", ".env"]) { config({ path: `../${envFile}` }) } -const getEnvBool = (key, fallback=false) => { +const getEnvBool = (key, fallback = false) => { const value = process.env[key] if (value === "false" || value === "0" || value === "off") { return false @@ -74,7 +74,7 @@ let app = withPlausibleProxy({ }, { key: "Cross-Origin-Opener-Policy", - value:"same-origin", + value: "same-origin", }, { key: "Cross-Origin-Embedder-Policy", @@ -111,6 +111,31 @@ let app = withPlausibleProxy({ }, }) + // XXX: Terser/SWC currently breaks while minifying objdiff's ESM worker in the static directory because + // it uses `import.meta.url`. next.js provides no way to control this behavior, of course, so we'll + // hook into the optimization stage and mark assets in `static/media/` as already minified. + // https://github.com/vercel/next.js/issues/33914 + // https://github.com/vercel/next.js/discussions/61549 + config.optimization.minimizer.unshift({ + apply(compiler) { + const pluginName = "SkipWorkerMinify" + compiler.hooks.thisCompilation.tap(pluginName, compilation=>{ + compilation.hooks.processAssets.tap({ + name: pluginName, + stage: Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_SIZE, + }, assets=>{ + for (const assetName in assets) { + if (/^static\/media\//.test(assetName)) { + compilation.updateAsset(assetName, assets[assetName], { + minimized: true, + }) + } + } + }) + }) + }, + }) + return config }, images: { diff --git a/frontend/package.json b/frontend/package.json index e5717afeb..1bb2c371f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -38,9 +38,11 @@ "fast-myers-diff": "^3.2.0", "framer-motion": "^11.0.18", "is-dark-color": "^1.2.0", + "memoize-one": "^5.2.1", "next": "^14.1.4", "next-plausible": "^3.12.0", "next-pwa": "^5.6.0", + "objdiff-wasm": "2.0.0-beta.9", "react": "^18.2.0", "react-colorful": "^5.6.1", "react-contenteditable": "^3.3.7", diff --git a/frontend/src/app/(navfooter)/credits/page.tsx b/frontend/src/app/(navfooter)/credits/page.tsx index 21a14039f..15f230927 100644 --- a/frontend/src/app/(navfooter)/credits/page.tsx +++ b/frontend/src/app/(navfooter)/credits/page.tsx @@ -26,6 +26,7 @@ const ICON_SOURCES = { "Happy Mac by NiloGlock": "https://commons.wikimedia.org/wiki/File:Happy_Mac.svg", "Tiger-like-x by Althepal": "https://commons.wikimedia.org/wiki/File:Tiger-like-x.svg", "Saturn by JustDanPatrick": "https://upload.wikimedia.org/wikipedia/commons/archive/7/78/20220518145749%21Sega_Saturn_Black_Logo.svg", + "Dreamcast by Sega": "https://en.wikipedia.org/wiki/File:Dreamcast_logo.svg", "MS-DOS by Microsoft": "https://commons.wikimedia.org/wiki/File:Msdos-icon.svg", "Windows 9x by Microsoft": "https://commons.wikimedia.org/wiki/File:Windows_Logo_(1992-2001).svg", "PerSPire Font by Sean Liew": "https://www.fontspace.com/sean-liew", diff --git a/frontend/src/app/(navfooter)/preset/page.tsx b/frontend/src/app/(navfooter)/preset/page.tsx new file mode 100644 index 000000000..f6dab82e7 --- /dev/null +++ b/frontend/src/app/(navfooter)/preset/page.tsx @@ -0,0 +1,12 @@ +import { Presets } from "@/app/(navfooter)/preset/presets" +import { get } from "@/lib/api/request" + +export default async function Page() { + const compilers = await get("/compiler") + + return ( +
+ +
+ ) +} diff --git a/frontend/src/app/(navfooter)/preset/presets.tsx b/frontend/src/app/(navfooter)/preset/presets.tsx new file mode 100644 index 000000000..53bb7dec3 --- /dev/null +++ b/frontend/src/app/(navfooter)/preset/presets.tsx @@ -0,0 +1,36 @@ +"use client" + +import { useState } from "react" + +import PlatformSelect from "@/components/PlatformSelect" +import { PresetList } from "@/components/PresetList" +import * as api from "@/lib/api" + +export function Presets({ serverCompilers }: { + serverCompilers: { + platforms: { + [id: string]: api.Platform + } + compilers: { + [id: string]: api.Compiler + } + } +}) { + + const platforms = Object.keys(serverCompilers.platforms) + + const [platform, setPlatform] = useState(platforms.length > 0 ? platforms[0] : "") + + return ( +
+

Platforms

+ +

Presets

+ +
+ ) +} diff --git a/frontend/src/app/(navfooter)/settings/editor/EditorSettings.tsx b/frontend/src/app/(navfooter)/settings/editor/EditorSettings.tsx index 676c989bd..4148b167b 100644 --- a/frontend/src/app/(navfooter)/settings/editor/EditorSettings.tsx +++ b/frontend/src/app/(navfooter)/settings/editor/EditorSettings.tsx @@ -2,8 +2,10 @@ import { useEffect, useRef, useState } from "react" import LoadingSpinner from "@/components/loading.svg" -import { ThreeWayDiffBase, useAutoRecompileSetting, useAutoRecompileDelaySetting, useMatchProgressBarEnabled, - useLanguageServerEnabled, useVimModeEnabled, useThreeWayDiffBase } from "@/lib/settings" +import { + ThreeWayDiffBase, useAutoRecompileSetting, useAutoRecompileDelaySetting, useMatchProgressBarEnabled, + useLanguageServerEnabled, useVimModeEnabled, useThreeWayDiffBase, useObjdiffClientEnabled, +} from "@/lib/settings" import Checkbox from "../Checkbox" import RadioList from "../RadioList" @@ -17,6 +19,7 @@ export default function EditorSettings() { const [languageServerEnabled, setLanguageServerEnabled] = useLanguageServerEnabled() const [vimModeEnabled, setVimModeEnabled] = useVimModeEnabled() const [threeWayDiffBase, setThreeWayDiffBase] = useThreeWayDiffBase() + const [objdiffClientEnabled, setObjdiffClientEnabled] = useObjdiffClientEnabled() const [downloadingLanguageServer, setDownloadingLanguageServer] = useState(false) @@ -107,5 +110,13 @@ export default function EditorSettings() { description="Enable vim bindings in the scratch editor"> +
+ + +
} diff --git a/frontend/src/app/(navfooter)/u/[username]/page.tsx b/frontend/src/app/(navfooter)/u/[username]/page.tsx index 8b3e8c132..70f51d8b4 100644 --- a/frontend/src/app/(navfooter)/u/[username]/page.tsx +++ b/frontend/src/app/(navfooter)/u/[username]/page.tsx @@ -2,16 +2,11 @@ import { Metadata } from "next" import { notFound } from "next/navigation" -import { MarkGithubIcon } from "@primer/octicons-react" - -import GhostButton from "@/components/GhostButton" -import ScratchList, { ScratchItemNoOwner } from "@/components/ScratchList" -import UserAvatar from "@/components/user/UserAvatar" +import Profile from "@/components/user/Profile" import { get } from "@/lib/api/request" import { User } from "@/lib/api/types" -import { userGithubHtmlUrl, userUrl } from "@/lib/api/urls" -export async function generateMetadata({ params }: { params: { username: string } }):Promise { +export async function generateMetadata({ params }: { params: { username: string } }): Promise { let user: User try { @@ -44,32 +39,5 @@ export default async function Page({ params }: { params: { username: string } }) return notFound() } - return
-
- -
-

- {user.username} -

- -
- -
- {userGithubHtmlUrl(user) && } - {user.username} -
-
-
-
-
- -
- -
-
+ return } diff --git a/frontend/src/app/robots.txt b/frontend/src/app/robots.txt new file mode 100644 index 000000000..333e7eb6a --- /dev/null +++ b/frontend/src/app/robots.txt @@ -0,0 +1,2 @@ +User-agent: Bytespider +Disallow: / diff --git a/frontend/src/components/Diff/CompilationPanel.tsx b/frontend/src/components/Diff/CompilationPanel.tsx index 72419a817..96d142bad 100644 --- a/frontend/src/components/Diff/CompilationPanel.tsx +++ b/frontend/src/components/Diff/CompilationPanel.tsx @@ -33,6 +33,7 @@ export type PerSaveObj = { } export type Props = { + scratch: api.Scratch compilation: api.Compilation isCompiling?: boolean isCompilationOld?: boolean @@ -40,7 +41,7 @@ export type Props = { perSaveObj: PerSaveObj } -export default function CompilationPanel({ compilation, isCompiling, isCompilationOld, selectedSourceLine, perSaveObj }: Props) { +export default function CompilationPanel({ scratch, compilation, isCompiling, isCompilationOld, selectedSourceLine, perSaveObj }: Props) { const usedCompilationRef = useRef(null) const problemState = getProblemState(compilation) const [threeWayDiffBase] = useThreeWayDiffBase() @@ -53,6 +54,7 @@ export default function CompilationPanel({ compilation, isCompiling, isCompilati } const usedDiff = usedCompilationRef.current?.diff_output ?? null + const objdiffResult = usedCompilationRef.current?.objdiff_output ?? null // If this is the first time we re-render after a save, store the diff // as a possible three-way diff base. @@ -103,7 +105,8 @@ export default function CompilationPanel({ compilation, isCompiling, isCompilati > .cell { overflow: hidden; - color: var(--g1600); - padding: 0 1em; cursor: default; @@ -131,12 +131,14 @@ .immediate { color: #6d6dff; } .stack { color: #abc501; } .register { color: #aa8b00; } +.symbol { color: #fff; } .delay_slot { font-weight: bold; color: #969896; } +.diff_any { background-color: rgba(255, 255, 255, 0.02); } .diff_change { color: #6d6dff; } .diff_add { color: #45bd00; } .diff_remove { color: #c82829; } diff --git a/frontend/src/components/Diff/Diff.tsx b/frontend/src/components/Diff/Diff.tsx index 9d2c6fb71..b21084022 100644 --- a/frontend/src/components/Diff/Diff.tsx +++ b/frontend/src/components/Diff/Diff.tsx @@ -1,9 +1,9 @@ /* eslint css-modules/no-unused-class: off */ -import { createContext, CSSProperties, forwardRef, HTMLAttributes, Fragment, useContext, useRef, useState } from "react" +import { createContext, CSSProperties, forwardRef, HTMLAttributes, useRef, useState } from "react" import { VersionsIcon } from "@primer/octicons-react" -import classNames from "classnames" +import { DiffResult } from "objdiff-wasm" import AutoSizer from "react-virtualized-auto-sizer" import { FixedSizeList } from "react-window" @@ -14,120 +14,10 @@ import { ThreeWayDiffBase, useCodeFontSize } from "@/lib/settings" import Loading from "../loading.svg" import styles from "./Diff.module.scss" +import * as AsmDiffer from "./DiffRowAsmDiffer" +import * as Objdiff from "./DiffRowObjdiff" import DragBar from "./DragBar" - -const PADDING_TOP = 8 -const PADDING_BOTTOM = 8 - -// Regex for tokenizing lines for click-to-highlight purposes. -// Strings matched by the first regex group (spaces, punctuation) -// are treated as non-highlightable. -const RE_TOKEN = /([ \t,()[\]:]+|~>)|%(?:lo|hi)\([^)]+\)|[^ \t,()[\]:]+/g - -const SelectedSourceLineContext = createContext(null) - -type Highlighter = { - value: string | null - setValue: (value: string | null) => void - select: (value: string) => void -} - -function useHighlighter(setAll: Highlighter["setValue"]): Highlighter { - const [value, setValue] = useState(null) - return { - value, - setValue, - select: newValue => { - // When selecting the same value twice (double-clicking), select it - // in all diff columns - if (value === newValue) { - setAll(newValue) - } else { - setValue(newValue) - } - }, - } -} - -function FormatDiffText({ texts, highlighter }: { - texts: api.DiffText[] - highlighter: Highlighter -}) { - return <> { - texts.map((t, index1) => - Array.from(t.text.matchAll(RE_TOKEN)).map((match, index2) => { - const text = match[0] - const isToken = !match[1] - const key = index1 + "," + index2 - - let className: string - if (t.format == "rotation") { - className = styles[`rotation${t.index % 9}`] - } else if (t.format) { - className = styles[t.format] - } - - return { - if (isToken) { - highlighter.select(text) - e.stopPropagation() - } - }} - > - {text} - - }) - ) - } -} - -function DiffCell({ cell, className, highlighter }: { - cell: api.DiffCell | undefined - className?: string - highlighter: Highlighter -}) { - const selectedSourceLine = useContext(SelectedSourceLineContext) - const hasLineNo = typeof cell?.src_line != "undefined" - - if (!cell) - return
- - return
- {hasLineNo && {cell.src_line}} - -
-} - -function DiffRow({ row, style, highlighter1, highlighter2, highlighter3 }: { - row: api.DiffRow - style: CSSProperties - highlighter1: Highlighter - highlighter2: Highlighter - highlighter3: Highlighter -}) { - return
  • - - - -
  • -} +import { useHighlighers } from "./Highlighter" // https://github.com/bvaughn/react-window#can-i-add-padding-to-the-top-and-bottom-of-a-list const innerElementType = forwardRef>(({ style, ...rest }, ref) => { @@ -142,15 +32,26 @@ const innerElementType = forwardRef { - highlighter1.setValue(value) - highlighter2.setValue(value) - highlighter3.setValue(value) +const isAsmDifferOutput = (diff: api.DiffOutput | DiffResult): diff is api.DiffOutput => { + return Object.prototype.hasOwnProperty.call(diff, "arch_str") +} + +function DiffBody({ diff, diffLabel, fontSize }: { diff: api.DiffOutput | DiffResult | null, diffLabel: string | null, fontSize: number | undefined }) { + const { highlighters, setHighlightAll } = useHighlighers(3) + + if (!diff) { + return
    + } + + let itemData: AsmDiffer.DiffListData | Objdiff.DiffListData + let DiffRow: typeof AsmDiffer.DiffRow | typeof Objdiff.DiffRow + if (isAsmDifferOutput(diff)) { + itemData = AsmDiffer.createDiffListData(diff, diffLabel, highlighters) + DiffRow = AsmDiffer.DiffRow + } else { + itemData = Objdiff.createDiffListData(diff, diffLabel, highlighters) + DiffRow = Objdiff.DiffRow } - const highlighter1 = useHighlighter(setHighlightAll) - const highlighter2 = useHighlighter(setHighlightAll) - const highlighter3 = useHighlighter(setHighlightAll) return
    - {diff?.rows && + {({ height, width }: {height: number|undefined, width:number|undefined}) => ( - {({ data, index, style }) => - - } + {DiffRow as any} )} - } +
    } @@ -201,8 +94,14 @@ function ThreeWayToggleButton({ enabled, setEnabled }: { enabled: boolean, setEn } +export const PADDING_TOP = 8 +export const PADDING_BOTTOM = 8 + +export const SelectedSourceLineContext = createContext(null) + export type Props = { - diff: api.DiffOutput | null + diff: api.DiffOutput | DiffResult | null + diffLabel: string | null isCompiling: boolean isCurrentOutdated: boolean threeWayDiffEnabled: boolean @@ -211,7 +110,7 @@ export type Props = { selectedSourceLine: number | null } -export default function Diff({ diff, isCompiling, isCurrentOutdated, threeWayDiffEnabled, setThreeWayDiffEnabled, threeWayDiffBase, selectedSourceLine }: Props) { +export default function Diff({ diff, diffLabel, isCompiling, isCurrentOutdated, threeWayDiffEnabled, setThreeWayDiffEnabled, threeWayDiffBase, selectedSourceLine }: Props) { const [fontSize] = useCodeFontSize() const container = useSize() @@ -273,7 +172,7 @@ export default function Diff({ diff, isCompiling, isCurrentOutdated, threeWayDif
    }
    - + } diff --git a/frontend/src/components/Diff/DiffRowAsmDiffer.tsx b/frontend/src/components/Diff/DiffRowAsmDiffer.tsx new file mode 100644 index 000000000..cc2d281dc --- /dev/null +++ b/frontend/src/components/Diff/DiffRowAsmDiffer.tsx @@ -0,0 +1,107 @@ +/* eslint css-modules/no-unused-class: off */ + +import { CSSProperties, memo, useContext } from "react" + +import classNames from "classnames" +import memoize from "memoize-one" +import { areEqual } from "react-window" + +import * as api from "@/lib/api" + +import { PADDING_TOP, SelectedSourceLineContext } from "./Diff" +import styles from "./Diff.module.scss" +import { Highlighter } from "./Highlighter" + +// Regex for tokenizing lines for click-to-highlight purposes. +// Strings matched by the first regex group (spaces, punctuation) +// are treated as non-highlightable. +const RE_TOKEN = /([ \t,()[\]:]+|~>)|%(?:lo|hi)\([^)]+\)|[^ \t,()[\]:]+/g + +function FormatDiffText({ texts, highlighter }: { + texts: api.DiffText[] + highlighter: Highlighter +}) { + return <> { + texts.map((t, index1) => + Array.from(t.text.matchAll(RE_TOKEN)).map((match, index2) => { + const text = match[0] + const isToken = !match[1] + const key = index1 + "," + index2 + + let className: string + if (t.format == "rotation") { + className = styles[`rotation${t.index % 9}`] + } else if (t.format) { + className = styles[t.format] + } + + return { + if (isToken) { + highlighter.select(text) + e.stopPropagation() + } + }} + > + {text} + + }) + ) + } +} + +function DiffCell({ cell, className, highlighter }: { + cell: api.DiffCell | undefined + className?: string + highlighter: Highlighter +}) { + const selectedSourceLine = useContext(SelectedSourceLineContext) + const hasLineNo = typeof cell?.src_line != "undefined" + + if (!cell) + return
    + + return
    + {hasLineNo && {cell.src_line}} + +
    +} + +export type DiffListData = { + diff: api.DiffOutput | null + itemCount: number + highlighters: Highlighter[] +} + +export const createDiffListData = memoize(( + diff: api.DiffOutput | null, + _diffLabel: string, + highlighters: Highlighter[] +): DiffListData => { + return { diff, highlighters, itemCount: diff?.rows?.length ?? 0 } +}) + +export const DiffRow = memo(function DiffRow({ data, index, style }: { data: DiffListData, index: number, style: CSSProperties }) { + const row = data.diff?.rows?.[index] + return
  • + + + +
  • +}, areEqual) diff --git a/frontend/src/components/Diff/DiffRowObjdiff.tsx b/frontend/src/components/Diff/DiffRowObjdiff.tsx new file mode 100644 index 000000000..567ae3729 --- /dev/null +++ b/frontend/src/components/Diff/DiffRowObjdiff.tsx @@ -0,0 +1,205 @@ +/* eslint css-modules/no-unused-class: off */ + +import { CSSProperties, memo, useContext } from "react" + +import classNames from "classnames" +import memoize from "memoize-one" +import { DiffKind, DiffResult, FunctionDiff, InstructionDiff, ObjectDiff, displayDiff, oneof } from "objdiff-wasm" +import { areEqual } from "react-window" + +import { PADDING_TOP, SelectedSourceLineContext } from "./Diff" +import styles from "./Diff.module.scss" +import { Highlighter } from "./Highlighter" + +function FormatDiffText({ insDiff, baseAddress, highlighter }: { + insDiff: InstructionDiff + baseAddress?: bigint + highlighter?: Highlighter +}) { + const out: JSX.Element[] = [] + let index = 0 + displayDiff(insDiff, baseAddress || BigInt(0), t => { + let className: string | null = null + if (t.diff_index != null) { + className = styles[`rotation${t.diff_index % 9}`] + } + let text = "" + let postText = "" // unhighlightable text after the token + let padTo = 0 + let isToken = false + switch (t.type) { + case "basic": + text = t.text + break + case "basic_color": + text = t.text + className = styles[`rotation${t.index % 9}`] + break + case "line": + text = (t.line_number || 0).toString(16) + padTo = 5 + break + case "address": + text = (t.address || 0).toString(16) + postText = ":" + padTo = 5 + isToken = true + break + case "opcode": + text = t.mnemonic + padTo = 8 + isToken = true + if (insDiff.diff_kind == DiffKind.DIFF_OP_MISMATCH) { + className = styles.diff_change + } + break + case "argument": { + const value = oneof(t.value.value) + switch (value.oneofKind) { + case "signed": + if (value.signed < 0) { + text = `-0x${(-value.signed).toString(16)}` + } else { + text = `0x${value.signed.toString(16)}` + } + break + case "unsigned": + text = `0x${value.unsigned.toString(16)}` + break + case "opaque": + text = value.opaque + break + } + isToken = true + break + } + case "branch_dest": + text = (t.address || 0).toString(16) + isToken = true + break + case "symbol": + text = t.target.symbol.demangled_name || t.target.symbol.name + className = styles.symbol + isToken = true + break + case "spacing": + text = " ".repeat(t.count) + break + default: + console.warn("Unknown text type", t) + return null + } + out.push( { + if (isToken) { + highlighter?.select(text) + e.stopPropagation() + } + }} + >{text}) + index++ + if (postText) { + out.push({postText}) + index++ + } + if (padTo > text.length + postText.length) { + const spacing = " ".repeat(padTo - text.length - postText.length) + out.push({spacing}) + index++ + } + }) + return out +} + +function DiffCell({ cell, baseAddress, className, highlighter }: { + cell: InstructionDiff | undefined + baseAddress: bigint | undefined + className?: string + highlighter?: Highlighter +}) { + const selectedSourceLine = useContext(SelectedSourceLineContext) + const hasLineNo = typeof cell?.instruction?.line_number != "undefined" + + if (!cell) + return
    + + const classes = [] + if (cell?.diff_kind) { + classes.push(styles.diff_any) + } + switch (cell?.diff_kind) { + case DiffKind.DIFF_DELETE: + classes.push(styles.diff_remove) + break + case DiffKind.DIFF_INSERT: + classes.push(styles.diff_add) + break + case DiffKind.DIFF_REPLACE: + classes.push(styles.diff_change) + break + } + + return
    + {hasLineNo && {cell.instruction.line_number}} + +
    +} + +function findSymbol(object: ObjectDiff | null, symbol_name: string): FunctionDiff | null { + if (!object) { + return null + } + for (const section of object.sections) { + for (const symbol_diff of section.functions) { + if (symbol_diff.symbol.name === symbol_name) { + return symbol_diff + } + } + } + return null +} + +export const DiffRow = memo(function DiffRow({ data, index, style }: { data: DiffListData, index: number, style: CSSProperties }) { + const leftIns = data.left?.instructions?.[index] + const leftSymbol = data.left?.symbol + const rightIns = data.right?.instructions?.[index] + const rightSymbol = data.right?.symbol + return
  • + + +
  • +}, areEqual) + +export type DiffListData = { + left: FunctionDiff | undefined + right: FunctionDiff | undefined + itemCount: number + highlighters: Highlighter[] +} + +export const createDiffListData = memoize(( + diff: DiffResult | null, + diffLabel: string, + highlighters: Highlighter[] +): DiffListData => { + const left = findSymbol(diff?.left, diffLabel) + const right = findSymbol(diff?.right, diffLabel) + const itemCount = Math.min(left?.instructions.length ?? 0, right?.instructions.length ?? 0) + return { left, right, itemCount, highlighters } +}) diff --git a/frontend/src/components/Diff/DragBar.module.scss b/frontend/src/components/Diff/DragBar.module.scss index e871e1b41..7bb98b97d 100644 --- a/frontend/src/components/Diff/DragBar.module.scss +++ b/frontend/src/components/Diff/DragBar.module.scss @@ -1,5 +1,5 @@ .vertical { - width: 4px; + width: 8px; height: 100%; position: absolute; diff --git a/frontend/src/components/Diff/Highlighter.tsx b/frontend/src/components/Diff/Highlighter.tsx new file mode 100644 index 000000000..47ae5c14e --- /dev/null +++ b/frontend/src/components/Diff/Highlighter.tsx @@ -0,0 +1,48 @@ +import { useState, useMemo } from "react" + +export type Highlighter = { + value: string | null + setValue: (value: string | null) => void + select: (value: string) => void +} + +export type HighlighterContextData = { + highlighters: Highlighter[] + setHighlightAll: Highlighter["setValue"] +} + +export function useHighlighers(count: number): HighlighterContextData { + const [values, setValues] = useState(Array(count).fill(null)) + if (values.length !== count) { + throw new Error("Count changed") + } + return useMemo(() => { + const highlighters: Highlighter[] = [] + const setHighlightAll = (value: string | null) => { + setValues(Array(count).fill(value)) + } + for (let i = 0; i < count; i++) { + const setValue = (newValue: string | null) => { + setValues(values => { + const newValues = [...values] + newValues[i] = newValue + return newValues + }) + } + highlighters.push({ + value: values[i], + setValue: setValue, + select: (newValue: string) => { + // When selecting the same value twice (double-clicking), select it + // in all diff columns + if (values[i] === newValue) { + setHighlightAll(newValue) + } else { + setValue(newValue) + } + }, + }) + } + return { highlighters, setHighlightAll } + }, [count, values]) +} diff --git a/frontend/src/components/PlatformSelect/PlatformIcon.tsx b/frontend/src/components/PlatformSelect/PlatformIcon.tsx index c93cdf0ae..b25f18f1c 100644 --- a/frontend/src/components/PlatformSelect/PlatformIcon.tsx +++ b/frontend/src/components/PlatformSelect/PlatformIcon.tsx @@ -1,3 +1,8 @@ +import Link from "next/link" + +import { platformUrl } from "@/lib/api/urls" + +import LogoDreamcast from "./dreamcast.svg" import LogoGBA from "./gba.svg" import LogoGCWii from "./gc_wii.svg" import LogoIRIX from "./irix.svg" @@ -30,6 +35,7 @@ const ICONS = { "n3ds": LogoN3DS, "switch": LogoSwitch, "saturn": LogoSaturn, + "dreamcast": LogoDreamcast, } export const PLATFORMS = Object.keys(ICONS) @@ -37,6 +43,7 @@ export const PLATFORMS = Object.keys(ICONS) export type Props = { platform: string className?: string + clickable?: boolean size?: string | number } @@ -44,8 +51,19 @@ export function platformIcon(platform: string) { return ICONS[platform as keyof typeof ICONS] || UnknownIcon } -export function PlatformIcon({ platform, className, size }: Props) { +export function PlatformIcon({ platform, className, clickable, size }: Props) { const Icon = platformIcon(platform) + const url = platformUrl(platform) - return + if (clickable) { + return ( + + + + ) + } else { + return ( + + ) + } } diff --git a/frontend/src/components/PlatformSelect/PlatformSelect.tsx b/frontend/src/components/PlatformSelect/PlatformSelect.tsx index 85be5f391..1babdf177 100644 --- a/frontend/src/components/PlatformSelect/PlatformSelect.tsx +++ b/frontend/src/components/PlatformSelect/PlatformSelect.tsx @@ -25,7 +25,7 @@ export default function PlatformSelect({ platforms, value, onChange, className } className={classNames(styles.platform, { [styles.selected]: value === key })} onClick={() => onChange(key)} > - +
    {platform.name}
    {platform.description}
    diff --git a/frontend/src/components/PlatformSelect/dreamcast.svg b/frontend/src/components/PlatformSelect/dreamcast.svg new file mode 100644 index 000000000..362945ced --- /dev/null +++ b/frontend/src/components/PlatformSelect/dreamcast.svg @@ -0,0 +1,9 @@ + + + image/svg+xml + + + Layer 1 + + + \ No newline at end of file diff --git a/frontend/src/components/PresetList.tsx b/frontend/src/components/PresetList.tsx new file mode 100644 index 000000000..656c4f632 --- /dev/null +++ b/frontend/src/components/PresetList.tsx @@ -0,0 +1,73 @@ +"use client" + +import type { ReactNode, JSX } from "react" + +import Link from "next/link" + +import classNames from "classnames" + +import AsyncButton from "@/components/AsyncButton" +import Button from "@/components/Button" +import LoadingSpinner from "@/components/loading.svg" +import { PlatformIcon } from "@/components/PlatformSelect/PlatformIcon" +import { type Preset, usePaginated } from "@/lib/api" +import { presetUrl } from "@/lib/api/urls" +import useTranslation from "@/lib/i18n/translate" + +export interface Props { + url?: string + className?: string + item?: ({ preset }: { preset: Preset }) => JSX.Element + emptyButtonLabel?: ReactNode +} + +export function PresetList({ url, className, item, emptyButtonLabel }: Props): JSX.Element { + const { results, isLoading, hasNext, loadNext } = usePaginated(url || "/preset") + if (results.length === 0 && isLoading) { + return
    + + Just a moment... +
    + } + + const Item = item ?? PresetItem + + return ( +
      + {results.map(preset => ( + + ))} + {results.length === 0 && emptyButtonLabel &&
    • + + + + + +
    • } + {hasNext &&
    • + + Show more + +
    • } +
    + ) +} + +export function PresetItem({ preset, hideIcon }: { preset: Preset, hideIcon?: boolean }): JSX.Element { + const compilersTranslation = useTranslation("compilers") + const compilerName = compilersTranslation.t(preset.compiler) + + return ( +
    +
    + {hideIcon && } + + {preset.name} + +
    +

    {compilerName}

    +
    + ) +} diff --git a/frontend/src/components/Scratch/Scratch.tsx b/frontend/src/components/Scratch/Scratch.tsx index 2d09c9de5..b2c2c8e22 100644 --- a/frontend/src/components/Scratch/Scratch.tsx +++ b/frontend/src/components/Scratch/Scratch.tsx @@ -18,10 +18,10 @@ import ErrorBoundary from "../ErrorBoundary" import ScoreBadge, { calculateScorePercent } from "../ScoreBadge" import { Tab, TabCloseButton } from "../Tabs" -import AboutScratch from "./AboutScratch" -import DecompilationPanel from "./DecompilePanel" -import FamilyPanel from "./FamilyPanel" import useLanguageServer from "./hooks/useLanguageServer" +import AboutPanel from "./panels/AboutPanel" +import DecompilationPanel from "./panels/DecompilePanel" +import FamilyPanel from "./panels/FamilyPanel" import styles from "./Scratch.module.scss" import ScratchMatchBanner from "./ScratchMatchBanner" import ScratchProgressBar from "./ScratchProgressBar" @@ -194,7 +194,7 @@ export default function Scratch({ switch (id as TabId) { case TabId.ABOUT: return - @@ -274,6 +274,7 @@ export default function Scratch({ className={styles.diffTab} > {compilation && - {matchProgressBarEnabledSetting &&
    } + {matchProgressBarEnabledSetting &&
    } {layout && (url, get) @@ -47,7 +46,7 @@ export type Props = { setScratch?: (scratch: Partial) => void } -export default function AboutScratch({ scratch, setScratch }: Props) { +export default function AboutPanel({ scratch, setScratch }: Props) { const preset: Preset = usePreset(scratch.preset) return ( diff --git a/frontend/src/components/Scratch/DecompilePanel.module.scss b/frontend/src/components/Scratch/panels/DecompilePanel.module.scss similarity index 100% rename from frontend/src/components/Scratch/DecompilePanel.module.scss rename to frontend/src/components/Scratch/panels/DecompilePanel.module.scss diff --git a/frontend/src/components/Scratch/DecompilePanel.tsx b/frontend/src/components/Scratch/panels/DecompilePanel.tsx similarity index 95% rename from frontend/src/components/Scratch/DecompilePanel.tsx rename to frontend/src/components/Scratch/panels/DecompilePanel.tsx index a10e2efa3..592f4b00c 100644 --- a/frontend/src/components/Scratch/DecompilePanel.tsx +++ b/frontend/src/components/Scratch/panels/DecompilePanel.tsx @@ -3,15 +3,14 @@ import { useEffect, useRef, useState } from "react" import { EditorView } from "@codemirror/view" import { useDebounce } from "use-debounce" +import CodeMirror from "@/components/Editor/CodeMirror" +import Loading from "@/components/loading.svg" import * as api from "@/lib/api" import { scratchUrl } from "@/lib/api/urls" import { decompileSetup } from "@/lib/codemirror/basic-setup" import { cpp } from "@/lib/codemirror/cpp" import useCompareExtension from "@/lib/codemirror/useCompareExtension" -import CodeMirror from "../Editor/CodeMirror" -import Loading from "../loading.svg" - import styles from "./DecompilePanel.module.scss" export type Props = { diff --git a/frontend/src/components/Scratch/FamilyPanel.tsx b/frontend/src/components/Scratch/panels/FamilyPanel.tsx similarity index 75% rename from frontend/src/components/Scratch/FamilyPanel.tsx rename to frontend/src/components/Scratch/panels/FamilyPanel.tsx index 3686d6a34..bf6a95d9c 100644 --- a/frontend/src/components/Scratch/FamilyPanel.tsx +++ b/frontend/src/components/Scratch/panels/FamilyPanel.tsx @@ -3,7 +3,7 @@ import dynamic from "next/dynamic" import Loading from "@/components/loading.svg" import { TerseScratch } from "@/lib/api/types" -const SortableFamilyList = dynamic(() => import("./SortableFamilyList"), { +const SortableFamilyList = dynamic(() => import("@/components/Scratch/SortableFamilyList"), { loading: () =>
    , @@ -14,7 +14,7 @@ type Props = { } export default function FamilyPanel({ scratch }: Props) { - return
    + return
    } diff --git a/frontend/src/components/Sort.tsx b/frontend/src/components/Sort.tsx index 593f647a2..27a4d9b20 100644 --- a/frontend/src/components/Sort.tsx +++ b/frontend/src/components/Sort.tsx @@ -18,9 +18,9 @@ export function produceSortFunction(sortMode: SortMode): (a: TerseScratch, b: Te case SortMode.LAST_UPDATED: // most recent first return (a, b) => new Date(b.last_updated).getTime() - new Date(a.last_updated).getTime() case SortMode.LEAST_MATCHED: - return compareScratchScores - case SortMode.MOST_MATCHED: return (a, b) => compareScratchScores(b, a) + case SortMode.MOST_MATCHED: + return compareScratchScores } } diff --git a/frontend/src/components/compiler/PresetSelect.tsx b/frontend/src/components/compiler/PresetSelect.tsx index b0572f6ae..44c1d2f0f 100644 --- a/frontend/src/components/compiler/PresetSelect.tsx +++ b/frontend/src/components/compiler/PresetSelect.tsx @@ -24,9 +24,7 @@ export default function PresetSelect({ className, platform, presetId, setPreset, if (typeof serverPresets === "undefined") serverPresets = api.usePresets(platform) - const sortedPresets = typeof serverPresets === "undefined" ? null : serverPresets.slice().sort((a, b) => a.name.localeCompare(b.name)) - - if (sortedPresets === null) { + if (typeof serverPresets === "undefined") { return { - setPreset(name === "Custom" ? null : sortedPresets.find((p: api.Preset) => p.name === name)) + setPreset(name === "Custom" ? null : serverPresets.find((p: api.Preset) => p.name === name)) }} /> } diff --git a/frontend/src/components/user/Profile.tsx b/frontend/src/components/user/Profile.tsx new file mode 100644 index 000000000..972ec1a43 --- /dev/null +++ b/frontend/src/components/user/Profile.tsx @@ -0,0 +1,93 @@ +"use client" + +import { useState, ReactElement } from "react" + +import { MarkGithubIcon } from "@primer/octicons-react" + +import GhostButton from "@/components/GhostButton" +import Tabs, { Tab } from "@/components/Tabs" +import { User } from "@/lib/api/types" +import { userGithubHtmlUrl } from "@/lib/api/urls" + +import ScratchesTab from "./tabs/ScratchesTab" +import UserAvatar from "./UserAvatar" + +enum TabId { + SCRATCHES = "user_scratches", +} + +interface TabLayout { + activeTab: string + tabs: string[] +} + +const tabLayout: TabLayout = { + activeTab: TabId.SCRATCHES, + tabs: [ + TabId.SCRATCHES, + ], +} + +interface Props { + layout: TabLayout + renderTab: (id: string) => ReactElement + onChange: (layout: TabLayout) => void +} + +function CustomLayout({ renderTab, layout, onChange }: Props) { + const els = [] + + for (const id of layout.tabs) { + els.push(renderTab(id)) + } + + return onChange({ ...layout, activeTab })} + > + {els} + +} + +export default function Profile({ user }: { user: User }) { + const [layout, setLayout] = useState(tabLayout) + + const renderTab = (id: string) => { + switch (id as TabId) { + case TabId.SCRATCHES: + return + {() => } + + default: + return + } + } + + return ( +
    +
    + +
    +

    + {user.username} +

    + +
    + +
    + {userGithubHtmlUrl(user) && } + {user.username} +
    +
    +
    +
    +
    + + {layout && } +
    + ) +} diff --git a/frontend/src/components/user/tabs/ScratchesTab.tsx b/frontend/src/components/user/tabs/ScratchesTab.tsx new file mode 100644 index 000000000..22ec1ca25 --- /dev/null +++ b/frontend/src/components/user/tabs/ScratchesTab.tsx @@ -0,0 +1,15 @@ +import ScratchList, { ScratchItemNoOwner } from "@/components/ScratchList" +import { User } from "@/lib/api" +import { userUrl } from "@/lib/api/urls" + +export default function ScratchesTab({ user }: { user: User }) { + return ( +
    + +
    + ) +} diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index ebc5e6a3b..accf71b3d 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -9,6 +9,8 @@ import { ResponseError, get, post, patch } from "./api/request" import { AnonymousUser, User, Scratch, TerseScratch, Compilation, Page, Compiler, LibraryVersions, Platform, Preset, ClaimableScratch } from "./api/types" import { scratchUrl } from "./api/urls" import { ignoreNextWarnBeforeUnload } from "./hooks" +import { runObjdiff } from "./objdiff" +import { useObjdiffClientEnabled } from "./settings" function onErrorRetry(error: ResponseError, key: string, config: C, revalidate: Revalidator, { retryCount }: RevalidatorOptions) { if (error.status === 404) return @@ -150,7 +152,7 @@ export function useIsScratchSaved(scratch: Scratch): boolean { ) } -export function useCompilation(scratch: Scratch | null, autoRecompile = true, autoRecompileDelay: number, initial: Compilation|null = null): { +export function useCompilation(scratch: Scratch | null, autoRecompile = true, autoRecompileDelay: number, initial: Compilation | null = null): { compilation: Readonly | null compile: () => Promise // no debounce debouncedCompile: () => Promise // with debounce @@ -161,6 +163,7 @@ export function useCompilation(scratch: Scratch | null, autoRecompile = true, au const [compileRequestPromise, setCompileRequestPromise] = useState>(null) const [compilation, setCompilation] = useState(initial) const [isCompilationOld, setIsCompilationOld] = useState(false) + const [objdiffClientEnabled] = useObjdiffClientEnabled() const sUrl = scratchUrl(scratch) const compile = useCallback(() => { @@ -182,6 +185,12 @@ export function useCompilation(scratch: Scratch | null, autoRecompile = true, au libraries: scratch.libraries, source_code: scratch.source_code, context: savedScratch ? undefinedIfUnchanged(savedScratch, scratch, "context") : scratch.context, + omit_diff: objdiffClientEnabled, + }).then((compilation: Compilation) => { + if (objdiffClientEnabled && compilation.success) { + return runObjdiff(compilation) + } + return compilation }).then((compilation: Compilation) => { setCompilation(compilation) }).finally(() => { @@ -189,7 +198,14 @@ export function useCompilation(scratch: Scratch | null, autoRecompile = true, au setIsCompilationOld(false) }).catch(error => { if (error instanceof ResponseError) { - setCompilation({ "compiler_output": error.json?.detail, "diff_output": null, "success": false }) + setCompilation({ + "compiler_output": error.json?.detail, + "diff_output": null, + "objdiff_output": null, + "success": false, + "left_object": null, + "right_object": null, + }) } else { return Promise.reject(error) } @@ -198,7 +214,7 @@ export function useCompilation(scratch: Scratch | null, autoRecompile = true, au setCompileRequestPromise(promise) return promise - }, [compileRequestPromise, savedScratch, scratch]) + }, [compileRequestPromise, savedScratch, scratch, objdiffClientEnabled]) // If the scratch we're looking at changes, we need to recompile const [url, setUrl] = useState(sUrl) @@ -280,7 +296,7 @@ export function useLibraries(platform: string): LibraryVersions[] { export function usePresets(platform: string): Preset[] { const getByPlatform = ([url, platform]: [string | null, string]) => { - return get(url && platform && `${url}?platform=${platform}&page_size=100`) + return get(url && platform && `${url}?platform=${platform}&ordering=name&page_size=100`) } const url = typeof platform === "string" ? "/preset" : null diff --git a/frontend/src/lib/api/types.ts b/frontend/src/lib/api/types.ts index 2422d1513..06917f3bb 100644 --- a/frontend/src/lib/api/types.ts +++ b/frontend/src/lib/api/types.ts @@ -1,3 +1,5 @@ +import { DiffResult as ObjdiffOutput } from "objdiff-wasm" + export interface Page { next: string | null previous: string | null @@ -58,6 +60,9 @@ export interface ClaimableScratch extends Scratch { export type Compilation = { compiler_output: string diff_output: DiffOutput | null + objdiff_output: ObjdiffOutput | null + left_object: string | null // base64 encoded + right_object: string | null // base64 encoded success: boolean } diff --git a/frontend/src/lib/i18n/locales/en/compilers.json b/frontend/src/lib/i18n/locales/en/compilers.json index 3b5f03055..c7cfea0c1 100644 --- a/frontend/src/lib/i18n/locales/en/compilers.json +++ b/frontend/src/lib/i18n/locales/en/compilers.json @@ -34,15 +34,18 @@ "ee-gcc2.96": "EE GCC 2.96 build 001003-1", "ee-gcc3.2-040921": "EE GCC 3.2 build 040921", - "mwcps2-2.3-991202": "MWCPS 2.3 (Built 991202)", - "mwcps2-3.0-011126": "MWCPS 3.0 (Built 011126)", - "mwcps2-3.0.1-020123": "MWCPS 3.0.1 (Built 020123)", - "mwcps2-3.0.3-020716": "MWCPS 3.0.3 (Built 020716)", + "mwcps2-2.3-991202": "MWCPS2 2.3 (Built 991202)", + "mwcps2-2.3.3-000906": "MWCPS2 2.3.3 (Built 000906)", + "mwcps2-2.4-001213": "MWCPS2 2.4 (Built 001213)", + "mwcps2-3.0-011126": "MWCPS2 3.0 (Built 011126)", + "mwcps2-3.0.1-020123": "MWCPS2 3.0.1 (Built 020123)", + "mwcps2-3.0.3-020716": "MWCPS2 3.0.3 (Built 020716)", "mwcps2-3.0b22-020926": "MWCPS2 3.0b22 (Built 020926)", "mwcps2-3.0b38-030307": "MWCPS2 3.0b38 (Built 030307)", "mwcps2-3.0b50-030527": "MWCPS2 3.0b50 (Built 030527)", "mwcps2-3.0b52-030722": "MWCPS2 3.0b52 (Built 030722)", "mwcps2-3.0.1b44-030325": "MWCPS2 3.0.1b44 (Built 030325)", + "mwcps2-3.0.1b51-030512": "MWCPS2 3.0.1b51 (Built 030512)", "mwcps2-3.0.1b74-030811": "MWCPS2 3.0.1b74 (Built 030811)", "mwcps2-3.0.1b75-030916": "MWCPS2 3.0.1b75 (Built 030916)", "mwcps2-3.0.1b87-031208": "MWCPS2 3.0.1b87 (Built 031208)", @@ -94,6 +97,7 @@ "msvc6.6": "Microsoft Visual C/C++ 6.0 Service Pack 6", "msvc7.0": "Microsoft Visual C/C++ 7.0 .NET 2002", "msvc7.1": "Microsoft Visual C/C++ 7.1 .NET 2003", + "msvc8.0": "Microsoft Visual C/C++ 8.0", "mwcc_20_72": "2.0 build 72 (MW 1.2base)", "mwcc_20_79": "2.0 build 79 (MW 1.2sp2)", @@ -105,12 +109,14 @@ "mwcc_233_163": "2.3.3 build 163 (GC MW 1.2.5)", "mwcc_233_163e": "2.3.3 build 163 (GC MW 1.2.5e)", "mwcc_233_163n": "2.3.3 build 163 (GC MW 1.2.5n)", + "mwcc_242_53": "2.4.2 build 53 (GC MW 1.3)", "mwcc_242_81": "2.4.2 build 81 (GC MW 1.3.2)", - "mwcc_242_81r": "2.4.2 build 81 (GC MW 1.3.2r)", + "mwcc_242_81r": "2.4.2 build 81 (Patched GC MW 1.3.2)", "mwcc_247_105": "2.4.7 build 105 (GC MW 2.5)", "mwcc_247_107": "2.4.7 build 107 (GC MW 2.6)", "mwcc_247_108": "2.4.7 build 108 (GC MW 2.7)", "mwcc_247_92": "2.4.7 build 92 (GC MW 2.0)", + "mwcc_247_92p1": "2.4.7 build 92 (Patched GC MW 2.0)", "mwcc_30_114": "3.0 build 114 (MW 2.0base)", "mwcc_30_123": "3.0 build 123 (MW 2.0sp1)", "mwcc_30_126": "3.0 build 126 (MW 2.0sp1p2)", @@ -142,6 +148,7 @@ "mwcc_43_151": "4.3 build 151 (Wii MW 1.1)", "mwcc_43_172": "4.3 build 172 (Wii MW 1.3)", "mwcc_43_188": "4.3 build 188 (Wii MW 1.5)", + "mwcc_43_202": "4.3 build 202 (Wii MW 1.6)", "mwcc_43_213": "4.3 build 213 (Wii MW 1.7)", "mwcppc_23": "MWCPPC 2.3 (CodeWarrior Pro 5)", "mwcppc_24": "MWCPPC 2.4 (CodeWarrior Pro 6)", @@ -170,20 +177,23 @@ "gcc2.7.2.3-mipsel": "gcc 2.7.2.3 + maspsx", "gcc2.8.0-mipsel": "gcc 2.8.0 + maspsx", "gcc2.8.1-mipsel": "gcc 2.8.1 + maspsx", + "gcc2.8.1-psx": "gcc 2.8.1-psx + maspsx", "gcc2.91.66-mipsel": "gcc 2.91.66 + maspsx", "gcc2.95.2-mipsel": "gcc 2.95.2 + maspsx", + "shc-v5.1r11": "SHC v5.1 (Release 11)", + "psyq3.3": "PSYQ3.3 (gcc 2.6.0 + aspsx 2.21)", "psyq3.5": "PSYQ3.5 (gcc 2.6.0 + aspsx 2.34)", "psyq3.6": "PSYQ3.6 (gcc 2.7.2 + aspsx 2.34)", "psyq4.0": "PSYQ4.0 (gcc 2.7.2 + aspsx 2.56)", - "psyq4.1": "PSYQ4.1 (gcc 2.7.2-970404 + aspsx 2.67)", + "psyq4.1": "gcc 2.7.2-970404 + aspsx 2.67 (CCPSX)", "psyq4.3": "PSYQ4.3 (gcc 2.8.0 + aspsx 2.77)", - "psyq4.4": "PSYQ4.4 (gcc 2.8.1 + aspsx 2.79)", - "psyq4.5": "PSYQ4.5 (gcc 2.91.66 + aspsx 2.81)", - "psyq4.6": "PSYQ4.6 (gcc 2.95.2 + aspsx 2.86)", + "psyq4.4": "gcc 2.8.1 + aspsx 2.79 (CCPSX)", + "psyq4.5": "gcc 2.91.66 + aspsx 2.81 (CCPSX)", + "psyq4.6": "gcc 2.95.2 + aspsx 2.86 (CCPSX)", - "psyq4.4-ccpsx": "CCPSX (PSYQ4.4: gcc 2.8.1 + aspsx 2.79)", + "psyq_263_221": "gcc 2.6.3 + aspsx 2.21", "mwccpsp_3.0.1_121": "MWCC 1.0 (3.0.1 121)", "mwccpsp_3.0.1_134": "MWCC 1.0 Hotfix 2 (3.0.1 134)", @@ -352,15 +362,33 @@ "msvc_codegen./G5": "optimize for Pentium", "msvc_codegen./G6": "optimize for Pentium Pro", "msvc_codegen./GB": "optimize for blended model", + "msvc_fp": "Floating point", + "msvc_fp./fp:precise": "favor precision", + "msvc_fp./fp:strict": "favor safety and control", + "msvc_fp./fp:fast": "favor speed", "msvc_compile_cpp": "compile as C++", "msvc_use_rtti": "enable C++ RTTI", "msvc_use_ehsc": "enable C++ EH", "msvc_disable_stack_checking": "disable stack checking calls", + "msvc_disable_buffer_security_checks": "disable buffer security checks", "msvc_runtime_debug_checks": "enable runtime debug checks", "msvc_cdecl": "__cdecl calling convention", "msvc_fastcall": "__fastcall calling convention", "msvc_stdcall": "__stdcall calling convention", + "shc_opt_level": "Optimization level", + "shc_opt_level.-optimize=0": "Optimization: off", + "shc_opt_level.-optimize=1": "Optimization: on", + "shc_opt_type": "Optimization type", + "shc_opt_type.speed": "Optimization for speed", + "shc_opt_type.size": "Optimization for size", + "shc_round": "Floating-point rounding options", + "shc_round.-round=zero": "Round to zero", + "shc_round.-round=nearest": "Round to nearest", + "shc_debug": "Debug", + "shc_loop": "Loop unrolling", + "shc_inline": "Inline static functions", + "psyq_opt_level": "Optimization level", "psyq_opt_level.-O0": "No optimization", "psyq_opt_level.-O1": "Some optimization", diff --git a/frontend/src/lib/objdiff.ts b/frontend/src/lib/objdiff.ts new file mode 100644 index 000000000..35d517ed1 --- /dev/null +++ b/frontend/src/lib/objdiff.ts @@ -0,0 +1,16 @@ +import { runDiff } from "objdiff-wasm" + +import { Compilation } from "./api/types" + +function base64ToBytes(base64: string) { + const binString = atob(base64) + return Uint8Array.from(binString, m => m.codePointAt(0)) +} + +export async function runObjdiff(compilation: Compilation): Promise { + const leftObject = base64ToBytes(compilation.left_object) + const rightObject = base64ToBytes(compilation.right_object) + const output = await runDiff(leftObject, rightObject) + compilation.objdiff_output = output + return compilation +} diff --git a/frontend/src/lib/settings.ts b/frontend/src/lib/settings.ts index 01c3e3b21..d7696a704 100644 --- a/frontend/src/lib/settings.ts +++ b/frontend/src/lib/settings.ts @@ -8,13 +8,14 @@ const theme = createPersistedState("theme") const autoRecompile = createPersistedState("autoRecompile") const autoRecompileDelay = createPersistedState("autoRecompileDelay") const codeFontSize = createPersistedState("codeFontSize") -const monospaceFont = createPersistedState("monospaceFont") +const monospaceFont = createPersistedState("monospaceFont") const codeLineHeight = createPersistedState("codeLineHeight") const codeColorScheme = createPersistedState("codeColorScheme") const languageServerEnabled = createPersistedState("languageServerEnabled") const matchProgressBarEnabled = createPersistedState("matchProgressBarEnabled") const vimModeEnabled = createPersistedState("vimModeEnabled") const threeWayDiffBase = createPersistedState("threeWayDiffBase") +const objdiffClientEnabled = createPersistedState("objdiffClientEnabled") export enum ThreeWayDiffBase { SAVED = "saved", @@ -32,6 +33,7 @@ export const useLanguageServerEnabled = () => languageServerEnabled(false) export const useMatchProgressBarEnabled = () => matchProgressBarEnabled(true) export const useVimModeEnabled = () => vimModeEnabled(false) export const useThreeWayDiffBase = () => threeWayDiffBase(ThreeWayDiffBase.SAVED) +export const useObjdiffClientEnabled = () => objdiffClientEnabled(false) export function useIsSiteThemeDark() { const [theme] = useTheme() diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 4e39d9d08..68ca5e980 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1415,6 +1415,11 @@ resolved "https://registry.yarnpkg.com/@primer/octicons-react/-/octicons-react-19.9.0.tgz#eb90a9b47da924c0ab33055d050e6ea21104d219" integrity sha512-Uk4XrHyfylyfzZN9d8VFjF8FpfYHEyT4sabw+9+oP+GWAJHhPvNPTz6gXvUzJZmoblAvgcTrDslIPjz8zMh76w== +"@protobuf-ts/runtime@2.9.4": + version "2.9.4" + resolved "https://registry.yarnpkg.com/@protobuf-ts/runtime/-/runtime-2.9.4.tgz#db8a78b1c409e26d258ca39464f4757d804add8f" + integrity sha512-vHRFWtJJB/SiogWDF0ypoKfRIZ41Kq+G9cEFj6Qm1eQaAhJ1LDFvgZ7Ja4tb3iLOQhz0PaoPnnOijF1qmEqTxg== + "@radix-ui/colors@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/colors/-/colors-2.1.0.tgz#8aa6f233f68076a92c57db93d7235172e88fda44" @@ -4643,7 +4648,7 @@ mdn-data@2.0.30: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== -"memoize-one@>=3.1.1 <6": +"memoize-one@>=3.1.1 <6", memoize-one@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== @@ -4839,6 +4844,13 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" +objdiff-wasm@2.0.0-beta.9: + version "2.0.0-beta.9" + resolved "https://registry.yarnpkg.com/objdiff-wasm/-/objdiff-wasm-2.0.0-beta.9.tgz#8a97d0b1562b5d427f2f643f63b7ea73cb5b0f00" + integrity sha512-P3DaL0cle4dp/Bpb3aVt1hbd+eX1w/4pU07aG8PyTwdMom7oja01kqzkQPoul9BjcUbRW9g2Xj/m3AWHpLBPZA== + dependencies: + "@protobuf-ts/runtime" "2.9.4" + object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"