From e6ce63d19c878a76236f7c9fbd3a2483f296075a Mon Sep 17 00:00:00 2001 From: n0rdye Date: Sun, 1 Dec 2024 22:06:02 +0000 Subject: [PATCH] asd --- __pycache__/screen.cpython-312.pyc | Bin 0 -> 2696 bytes __pycache__/screen.cpython-313.pyc | Bin 2746 -> 2744 bytes server.py | 9 +- venv/bin/Activate.ps1 | 247 + venv/bin/activate | 70 + venv/bin/activate.csh | 27 + venv/bin/activate.fish | 69 + venv/bin/flask | 8 + venv/bin/pip | 8 + venv/bin/pip3 | 8 + venv/bin/pip3.12 | 8 + venv/bin/python | 1 + venv/bin/python3 | 1 + venv/bin/python3.12 | 1 + .../MarkupSafe-3.0.2.dist-info/INSTALLER | 1 + .../MarkupSafe-3.0.2.dist-info/LICENSE.txt | 28 + .../MarkupSafe-3.0.2.dist-info/METADATA | 92 + .../MarkupSafe-3.0.2.dist-info/RECORD | 14 + .../MarkupSafe-3.0.2.dist-info/WHEEL | 6 + .../MarkupSafe-3.0.2.dist-info/top_level.txt | 1 + .../site-packages/PIL/BdfFontFile.py | 133 + .../site-packages/PIL/BlpImagePlugin.py | 493 + .../site-packages/PIL/BmpImagePlugin.py | 511 + .../site-packages/PIL/BufrStubImagePlugin.py | 76 + .../site-packages/PIL/ContainerIO.py | 173 + .../site-packages/PIL/CurImagePlugin.py | 75 + .../site-packages/PIL/DcxImagePlugin.py | 80 + .../site-packages/PIL/DdsImagePlugin.py | 575 ++ .../site-packages/PIL/EpsImagePlugin.py | 474 + .../python3.12/site-packages/PIL/ExifTags.py | 381 + .../site-packages/PIL/FitsImagePlugin.py | 152 + .../site-packages/PIL/FliImagePlugin.py | 175 + .../python3.12/site-packages/PIL/FontFile.py | 134 + .../site-packages/PIL/FpxImagePlugin.py | 257 + .../site-packages/PIL/FtexImagePlugin.py | 115 + .../site-packages/PIL/GbrImagePlugin.py | 103 + .../site-packages/PIL/GdImageFile.py | 102 + .../site-packages/PIL/GifImagePlugin.py | 1197 +++ .../site-packages/PIL/GimpGradientFile.py | 149 + .../site-packages/PIL/GimpPaletteFile.py | 58 + .../site-packages/PIL/GribStubImagePlugin.py | 76 + .../site-packages/PIL/Hdf5StubImagePlugin.py | 76 + .../site-packages/PIL/IcnsImagePlugin.py | 412 + .../site-packages/PIL/IcoImagePlugin.py | 381 + .../site-packages/PIL/ImImagePlugin.py | 386 + .../lib/python3.12/site-packages/PIL/Image.py | 4198 ++++++++ .../site-packages/PIL/ImageChops.py | 311 + .../python3.12/site-packages/PIL/ImageCms.py | 1125 +++ .../site-packages/PIL/ImageColor.py | 320 + .../python3.12/site-packages/PIL/ImageDraw.py | 1218 +++ .../site-packages/PIL/ImageDraw2.py | 243 + .../site-packages/PIL/ImageEnhance.py | 113 + .../python3.12/site-packages/PIL/ImageFile.py | 832 ++ .../site-packages/PIL/ImageFilter.py | 605 ++ .../python3.12/site-packages/PIL/ImageFont.py | 1338 +++ .../python3.12/site-packages/PIL/ImageGrab.py | 194 + .../python3.12/site-packages/PIL/ImageMath.py | 368 + .../python3.12/site-packages/PIL/ImageMode.py | 92 + .../site-packages/PIL/ImageMorph.py | 265 + .../python3.12/site-packages/PIL/ImageOps.py | 730 ++ .../site-packages/PIL/ImagePalette.py | 285 + .../python3.12/site-packages/PIL/ImagePath.py | 20 + .../python3.12/site-packages/PIL/ImageQt.py | 216 + .../site-packages/PIL/ImageSequence.py | 86 + .../python3.12/site-packages/PIL/ImageShow.py | 360 + .../python3.12/site-packages/PIL/ImageStat.py | 160 + .../python3.12/site-packages/PIL/ImageTk.py | 290 + .../site-packages/PIL/ImageTransform.py | 136 + .../python3.12/site-packages/PIL/ImageWin.py | 247 + .../site-packages/PIL/ImtImagePlugin.py | 103 + .../site-packages/PIL/IptcImagePlugin.py | 249 + .../site-packages/PIL/Jpeg2KImagePlugin.py | 443 + .../site-packages/PIL/JpegImagePlugin.py | 895 ++ .../site-packages/PIL/JpegPresets.py | 242 + .../site-packages/PIL/McIdasImagePlugin.py | 80 + .../site-packages/PIL/MicImagePlugin.py | 107 + .../site-packages/PIL/MpegImagePlugin.py | 88 + .../site-packages/PIL/MpoImagePlugin.py | 190 + .../site-packages/PIL/MspImagePlugin.py | 200 + .../python3.12/site-packages/PIL/PSDraw.py | 234 + .../site-packages/PIL/PaletteFile.py | 54 + .../site-packages/PIL/PalmImagePlugin.py | 232 + .../site-packages/PIL/PcdImagePlugin.py | 64 + .../site-packages/PIL/PcfFontFile.py | 254 + .../site-packages/PIL/PcxImagePlugin.py | 229 + .../site-packages/PIL/PdfImagePlugin.py | 311 + .../python3.12/site-packages/PIL/PdfParser.py | 1073 ++ .../site-packages/PIL/PixarImagePlugin.py | 74 + .../site-packages/PIL/PngImagePlugin.py | 1544 +++ .../site-packages/PIL/PpmImagePlugin.py | 375 + .../site-packages/PIL/PsdImagePlugin.py | 332 + .../site-packages/PIL/QoiImagePlugin.py | 115 + .../site-packages/PIL/SgiImagePlugin.py | 247 + .../site-packages/PIL/SpiderImagePlugin.py | 329 + .../site-packages/PIL/SunImagePlugin.py | 145 + .../lib/python3.12/site-packages/PIL/TarIO.py | 57 + .../site-packages/PIL/TgaImagePlugin.py | 264 + .../site-packages/PIL/TiffImagePlugin.py | 2271 +++++ .../python3.12/site-packages/PIL/TiffTags.py | 562 ++ .../site-packages/PIL/WalImageFile.py | 127 + .../site-packages/PIL/WebPImagePlugin.py | 323 + .../site-packages/PIL/WmfImagePlugin.py | 181 + .../site-packages/PIL/XVThumbImagePlugin.py | 85 + .../site-packages/PIL/XbmImagePlugin.py | 98 + .../site-packages/PIL/XpmImagePlugin.py | 127 + .../python3.12/site-packages/PIL/__init__.py | 86 + .../python3.12/site-packages/PIL/__main__.py | 7 + .../__pycache__/BdfFontFile.cpython-312.pyc | Bin 0 -> 4379 bytes .../BlpImagePlugin.cpython-312.pyc | Bin 0 -> 24093 bytes .../BmpImagePlugin.cpython-312.pyc | Bin 0 -> 17954 bytes .../BufrStubImagePlugin.cpython-312.pyc | Bin 0 -> 2699 bytes .../__pycache__/ContainerIO.cpython-312.pyc | Bin 0 -> 7027 bytes .../CurImagePlugin.cpython-312.pyc | Bin 0 -> 2377 bytes .../DcxImagePlugin.cpython-312.pyc | Bin 0 -> 2708 bytes .../DdsImagePlugin.cpython-312.pyc | Bin 0 -> 22701 bytes .../EpsImagePlugin.cpython-312.pyc | Bin 0 -> 15662 bytes .../PIL/__pycache__/ExifTags.cpython-312.pyc | Bin 0 -> 11562 bytes .../FitsImagePlugin.cpython-312.pyc | Bin 0 -> 6023 bytes .../FliImagePlugin.cpython-312.pyc | Bin 0 -> 6774 bytes .../PIL/__pycache__/FontFile.cpython-312.pyc | Bin 0 -> 4498 bytes .../FpxImagePlugin.cpython-312.pyc | Bin 0 -> 7697 bytes .../FtexImagePlugin.cpython-312.pyc | Bin 0 -> 5309 bytes .../GbrImagePlugin.cpython-312.pyc | Bin 0 -> 3710 bytes .../__pycache__/GdImageFile.cpython-312.pyc | Bin 0 -> 3442 bytes .../GifImagePlugin.cpython-312.pyc | Bin 0 -> 44813 bytes .../GimpGradientFile.cpython-312.pyc | Bin 0 -> 5464 bytes .../GimpPaletteFile.cpython-312.pyc | Bin 0 -> 2116 bytes .../GribStubImagePlugin.cpython-312.pyc | Bin 0 -> 2697 bytes .../Hdf5StubImagePlugin.cpython-312.pyc | Bin 0 -> 2672 bytes .../IcnsImagePlugin.cpython-312.pyc | Bin 0 -> 17275 bytes .../IcoImagePlugin.cpython-312.pyc | Bin 0 -> 15173 bytes .../__pycache__/ImImagePlugin.cpython-312.pyc | Bin 0 -> 12733 bytes .../PIL/__pycache__/Image.cpython-312.pyc | Bin 0 -> 172279 bytes .../__pycache__/ImageChops.cpython-312.pyc | Bin 0 -> 11247 bytes .../PIL/__pycache__/ImageCms.cpython-312.pyc | Bin 0 -> 43999 bytes .../__pycache__/ImageColor.cpython-312.pyc | Bin 0 -> 12496 bytes .../PIL/__pycache__/ImageDraw.cpython-312.pyc | Bin 0 -> 44209 bytes .../__pycache__/ImageDraw2.cpython-312.pyc | Bin 0 -> 9804 bytes .../__pycache__/ImageEnhance.cpython-312.pyc | Bin 0 -> 5409 bytes .../PIL/__pycache__/ImageFile.cpython-312.pyc | Bin 0 -> 31245 bytes .../__pycache__/ImageFilter.cpython-312.pyc | Bin 0 -> 23178 bytes .../PIL/__pycache__/ImageFont.cpython-312.pyc | Bin 0 -> 69187 bytes .../PIL/__pycache__/ImageGrab.cpython-312.pyc | Bin 0 -> 7016 bytes .../PIL/__pycache__/ImageMath.cpython-312.pyc | Bin 0 -> 16323 bytes .../PIL/__pycache__/ImageMode.cpython-312.pyc | Bin 0 -> 2821 bytes .../__pycache__/ImageMorph.cpython-312.pyc | Bin 0 -> 11334 bytes .../PIL/__pycache__/ImageOps.cpython-312.pyc | Bin 0 -> 29364 bytes .../__pycache__/ImagePalette.cpython-312.pyc | Bin 0 -> 12174 bytes .../PIL/__pycache__/ImagePath.cpython-312.pyc | Bin 0 -> 357 bytes .../PIL/__pycache__/ImageQt.cpython-312.pyc | Bin 0 -> 8457 bytes .../__pycache__/ImageSequence.cpython-312.pyc | Bin 0 -> 3388 bytes .../PIL/__pycache__/ImageShow.cpython-312.pyc | Bin 0 -> 13678 bytes .../PIL/__pycache__/ImageStat.cpython-312.pyc | Bin 0 -> 7380 bytes .../PIL/__pycache__/ImageTk.cpython-312.pyc | Bin 0 -> 10852 bytes .../ImageTransform.cpython-312.pyc | Bin 0 -> 5360 bytes .../PIL/__pycache__/ImageWin.cpython-312.pyc | Bin 0 -> 11870 bytes .../ImtImagePlugin.cpython-312.pyc | Bin 0 -> 2569 bytes .../IptcImagePlugin.cpython-312.pyc | Bin 0 -> 8881 bytes .../Jpeg2KImagePlugin.cpython-312.pyc | Bin 0 -> 18169 bytes .../JpegImagePlugin.cpython-312.pyc | Bin 0 -> 33085 bytes .../__pycache__/JpegPresets.cpython-312.pyc | Bin 0 -> 8136 bytes .../McIdasImagePlugin.cpython-312.pyc | Bin 0 -> 2241 bytes .../MicImagePlugin.cpython-312.pyc | Bin 0 -> 3806 bytes .../MpegImagePlugin.cpython-312.pyc | Bin 0 -> 3690 bytes .../MpoImagePlugin.cpython-312.pyc | Bin 0 -> 8133 bytes .../MspImagePlugin.cpython-312.pyc | Bin 0 -> 5965 bytes .../PIL/__pycache__/PSDraw.cpython-312.pyc | Bin 0 -> 7952 bytes .../__pycache__/PaletteFile.cpython-312.pyc | Bin 0 -> 1917 bytes .../PalmImagePlugin.cpython-312.pyc | Bin 0 -> 9706 bytes .../PcdImagePlugin.cpython-312.pyc | Bin 0 -> 2050 bytes .../__pycache__/PcfFontFile.cpython-312.pyc | Bin 0 -> 9919 bytes .../PcxImagePlugin.cpython-312.pyc | Bin 0 -> 7389 bytes .../PdfImagePlugin.cpython-312.pyc | Bin 0 -> 9778 bytes .../PIL/__pycache__/PdfParser.cpython-312.pyc | Bin 0 -> 52814 bytes .../PixarImagePlugin.cpython-312.pyc | Bin 0 -> 1974 bytes .../PngImagePlugin.cpython-312.pyc | Bin 0 -> 61928 bytes .../PpmImagePlugin.cpython-312.pyc | Bin 0 -> 14124 bytes .../PsdImagePlugin.cpython-312.pyc | Bin 0 -> 10843 bytes .../QoiImagePlugin.cpython-312.pyc | Bin 0 -> 6058 bytes .../SgiImagePlugin.cpython-312.pyc | Bin 0 -> 8429 bytes .../SpiderImagePlugin.cpython-312.pyc | Bin 0 -> 12244 bytes .../SunImagePlugin.cpython-312.pyc | Bin 0 -> 3428 bytes .../PIL/__pycache__/TarIO.cpython-312.pyc | Bin 0 -> 1913 bytes .../TgaImagePlugin.cpython-312.pyc | Bin 0 -> 8104 bytes .../TiffImagePlugin.cpython-312.pyc | Bin 0 -> 99266 bytes .../PIL/__pycache__/TiffTags.cpython-312.pyc | Bin 0 -> 18818 bytes .../__pycache__/WalImageFile.cpython-312.pyc | Bin 0 -> 4098 bytes .../WebPImagePlugin.cpython-312.pyc | Bin 0 -> 13226 bytes .../WmfImagePlugin.cpython-312.pyc | Bin 0 -> 6180 bytes .../XVThumbImagePlugin.cpython-312.pyc | Bin 0 -> 2616 bytes .../XbmImagePlugin.cpython-312.pyc | Bin 0 -> 4105 bytes .../XpmImagePlugin.cpython-312.pyc | Bin 0 -> 4255 bytes .../PIL/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2036 bytes .../PIL/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 401 bytes .../PIL/__pycache__/_binary.cpython-312.pyc | Bin 0 -> 3444 bytes .../__pycache__/_deprecate.cpython-312.pyc | Bin 0 -> 2478 bytes .../_tkinter_finder.cpython-312.pyc | Bin 0 -> 774 bytes .../PIL/__pycache__/_typing.cpython-312.pyc | Bin 0 -> 2113 bytes .../PIL/__pycache__/_util.cpython-312.pyc | Bin 0 -> 1553 bytes .../PIL/__pycache__/_version.cpython-312.pyc | Bin 0 -> 273 bytes .../PIL/__pycache__/features.cpython-312.pyc | Bin 0 -> 13858 bytes .../PIL/__pycache__/report.cpython-312.pyc | Bin 0 -> 335 bytes .../python3.12/site-packages/PIL/_binary.py | 112 + .../site-packages/PIL/_deprecate.py | 69 + .../_imaging.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 3115489 bytes .../python3.12/site-packages/PIL/_imaging.pyi | 31 + ...imagingcms.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 145465 bytes .../site-packages/PIL/_imagingcms.pyi | 143 + ..._imagingft.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 298281 bytes .../site-packages/PIL/_imagingft.pyi | 69 + ...magingmath.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 156856 bytes .../site-packages/PIL/_imagingmath.pyi | 3 + ...agingmorph.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 36112 bytes .../site-packages/PIL/_imagingmorph.pyi | 3 + ..._imagingtk.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 46352 bytes .../site-packages/PIL/_imagingtk.pyi | 3 + .../site-packages/PIL/_tkinter_finder.py | 21 + .../python3.12/site-packages/PIL/_typing.py | 53 + .../lib/python3.12/site-packages/PIL/_util.py | 26 + .../python3.12/site-packages/PIL/_version.py | 4 + .../PIL/_webp.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 84193 bytes .../python3.12/site-packages/PIL/_webp.pyi | 3 + .../python3.12/site-packages/PIL/features.py | 352 + .../lib/python3.12/site-packages/PIL/py.typed | 0 .../python3.12/site-packages/PIL/report.py | 5 + .../blinker-1.9.0.dist-info/INSTALLER | 1 + .../blinker-1.9.0.dist-info/LICENSE.txt | 20 + .../blinker-1.9.0.dist-info/METADATA | 60 + .../blinker-1.9.0.dist-info/RECORD | 12 + .../blinker-1.9.0.dist-info/WHEEL | 4 + .../site-packages/blinker/__init__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 510 bytes .../__pycache__/_utilities.cpython-312.pyc | Bin 0 -> 2737 bytes .../blinker/__pycache__/base.cpython-312.pyc | Bin 0 -> 21980 bytes .../site-packages/blinker/_utilities.py | 64 + .../python3.12/site-packages/blinker/base.py | 512 + .../python3.12/site-packages/blinker/py.typed | 0 .../click-8.1.7.dist-info/INSTALLER | 1 + .../click-8.1.7.dist-info/LICENSE.rst | 28 + .../click-8.1.7.dist-info/METADATA | 103 + .../click-8.1.7.dist-info/RECORD | 39 + .../site-packages/click-8.1.7.dist-info/WHEEL | 5 + .../click-8.1.7.dist-info/top_level.txt | 1 + .../site-packages/click/__init__.py | 73 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2715 bytes .../click/__pycache__/_compat.cpython-312.pyc | Bin 0 -> 27460 bytes .../__pycache__/_termui_impl.cpython-312.pyc | Bin 0 -> 30538 bytes .../__pycache__/_textwrap.cpython-312.pyc | Bin 0 -> 2456 bytes .../__pycache__/_winconsole.cpython-312.pyc | Bin 0 -> 11995 bytes .../click/__pycache__/core.cpython-312.pyc | Bin 0 -> 135516 bytes .../__pycache__/decorators.cpython-312.pyc | Bin 0 -> 23988 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 14751 bytes .../__pycache__/formatting.cpython-312.pyc | Bin 0 -> 14070 bytes .../click/__pycache__/globals.cpython-312.pyc | Bin 0 -> 3135 bytes .../click/__pycache__/parser.cpython-312.pyc | Bin 0 -> 21500 bytes .../shell_completion.cpython-312.pyc | Bin 0 -> 22772 bytes .../click/__pycache__/termui.cpython-312.pyc | Bin 0 -> 32805 bytes .../click/__pycache__/testing.cpython-312.pyc | Bin 0 -> 24577 bytes .../click/__pycache__/types.cpython-312.pyc | Bin 0 -> 49457 bytes .../click/__pycache__/utils.cpython-312.pyc | Bin 0 -> 26307 bytes .../python3.12/site-packages/click/_compat.py | 623 ++ .../site-packages/click/_termui_impl.py | 739 ++ .../site-packages/click/_textwrap.py | 49 + .../site-packages/click/_winconsole.py | 279 + .../python3.12/site-packages/click/core.py | 3042 ++++++ .../site-packages/click/decorators.py | 561 ++ .../site-packages/click/exceptions.py | 288 + .../site-packages/click/formatting.py | 301 + .../python3.12/site-packages/click/globals.py | 68 + .../python3.12/site-packages/click/parser.py | 529 + .../python3.12/site-packages/click/py.typed | 0 .../site-packages/click/shell_completion.py | 596 ++ .../python3.12/site-packages/click/termui.py | 784 ++ .../python3.12/site-packages/click/testing.py | 479 + .../python3.12/site-packages/click/types.py | 1089 +++ .../python3.12/site-packages/click/utils.py | 624 ++ .../flask-3.1.0.dist-info/INSTALLER | 1 + .../flask-3.1.0.dist-info/LICENSE.txt | 28 + .../flask-3.1.0.dist-info/METADATA | 81 + .../flask-3.1.0.dist-info/RECORD | 58 + .../flask-3.1.0.dist-info/REQUESTED | 0 .../site-packages/flask-3.1.0.dist-info/WHEEL | 4 + .../flask-3.1.0.dist-info/entry_points.txt | 3 + .../site-packages/flask/__init__.py | 60 + .../site-packages/flask/__main__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2489 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 250 bytes .../flask/__pycache__/app.cpython-312.pyc | Bin 0 -> 62427 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 0 -> 5009 bytes .../flask/__pycache__/cli.cpython-312.pyc | Bin 0 -> 43388 bytes .../flask/__pycache__/config.cpython-312.pyc | Bin 0 -> 16218 bytes .../flask/__pycache__/ctx.cpython-312.pyc | Bin 0 -> 19836 bytes .../__pycache__/debughelpers.cpython-312.pyc | Bin 0 -> 9141 bytes .../flask/__pycache__/globals.cpython-312.pyc | Bin 0 -> 1874 bytes .../flask/__pycache__/helpers.cpython-312.pyc | Bin 0 -> 25445 bytes .../flask/__pycache__/logging.cpython-312.pyc | Bin 0 -> 3279 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 17142 bytes .../flask/__pycache__/signals.cpython-312.pyc | Bin 0 -> 1231 bytes .../__pycache__/templating.cpython-312.pyc | Bin 0 -> 9916 bytes .../flask/__pycache__/testing.cpython-312.pyc | Bin 0 -> 13585 bytes .../flask/__pycache__/typing.cpython-312.pyc | Bin 0 -> 3997 bytes .../flask/__pycache__/views.cpython-312.pyc | Bin 0 -> 7015 bytes .../__pycache__/wrappers.cpython-312.pyc | Bin 0 -> 10062 bytes .../lib/python3.12/site-packages/flask/app.py | 1536 +++ .../site-packages/flask/blueprints.py | 128 + .../lib/python3.12/site-packages/flask/cli.py | 1133 +++ .../python3.12/site-packages/flask/config.py | 367 + .../lib/python3.12/site-packages/flask/ctx.py | 449 + .../site-packages/flask/debughelpers.py | 178 + .../python3.12/site-packages/flask/globals.py | 51 + .../python3.12/site-packages/flask/helpers.py | 634 ++ .../site-packages/flask/json/__init__.py | 170 + .../json/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6702 bytes .../json/__pycache__/provider.cpython-312.pyc | Bin 0 -> 9269 bytes .../json/__pycache__/tag.cpython-312.pyc | Bin 0 -> 13964 bytes .../site-packages/flask/json/provider.py | 215 + .../site-packages/flask/json/tag.py | 327 + .../python3.12/site-packages/flask/logging.py | 79 + .../python3.12/site-packages/flask/py.typed | 0 .../site-packages/flask/sansio/README.md | 6 + .../sansio/__pycache__/app.cpython-312.pyc | Bin 0 -> 33696 bytes .../__pycache__/blueprints.cpython-312.pyc | Bin 0 -> 31193 bytes .../__pycache__/scaffold.cpython-312.pyc | Bin 0 -> 30233 bytes .../site-packages/flask/sansio/app.py | 964 ++ .../site-packages/flask/sansio/blueprints.py | 632 ++ .../site-packages/flask/sansio/scaffold.py | 792 ++ .../site-packages/flask/sessions.py | 398 + .../python3.12/site-packages/flask/signals.py | 17 + .../site-packages/flask/templating.py | 219 + .../python3.12/site-packages/flask/testing.py | 297 + .../python3.12/site-packages/flask/typing.py | 90 + .../python3.12/site-packages/flask/views.py | 191 + .../site-packages/flask/wrappers.py | 257 + .../itsdangerous-2.2.0.dist-info/INSTALLER | 1 + .../itsdangerous-2.2.0.dist-info/LICENSE.txt | 28 + .../itsdangerous-2.2.0.dist-info/METADATA | 60 + .../itsdangerous-2.2.0.dist-info/RECORD | 22 + .../itsdangerous-2.2.0.dist-info/WHEEL | 4 + .../site-packages/itsdangerous/__init__.py | 38 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1641 bytes .../__pycache__/_json.cpython-312.pyc | Bin 0 -> 1195 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 0 -> 2695 bytes .../__pycache__/exc.cpython-312.pyc | Bin 0 -> 3955 bytes .../__pycache__/serializer.cpython-312.pyc | Bin 0 -> 15423 bytes .../__pycache__/signer.cpython-312.pyc | Bin 0 -> 11300 bytes .../__pycache__/timed.cpython-312.pyc | Bin 0 -> 8744 bytes .../__pycache__/url_safe.cpython-312.pyc | Bin 0 -> 3545 bytes .../site-packages/itsdangerous/_json.py | 18 + .../site-packages/itsdangerous/encoding.py | 54 + .../site-packages/itsdangerous/exc.py | 106 + .../site-packages/itsdangerous/py.typed | 0 .../site-packages/itsdangerous/serializer.py | 406 + .../site-packages/itsdangerous/signer.py | 266 + .../site-packages/itsdangerous/timed.py | 228 + .../site-packages/itsdangerous/url_safe.py | 83 + .../jinja2-3.1.4.dist-info/INSTALLER | 1 + .../jinja2-3.1.4.dist-info/LICENSE.txt | 28 + .../jinja2-3.1.4.dist-info/METADATA | 76 + .../jinja2-3.1.4.dist-info/RECORD | 57 + .../jinja2-3.1.4.dist-info/WHEEL | 4 + .../jinja2-3.1.4.dist-info/entry_points.txt | 3 + .../site-packages/jinja2/__init__.py | 38 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1666 bytes .../__pycache__/_identifier.cpython-312.pyc | Bin 0 -> 2147 bytes .../__pycache__/async_utils.cpython-312.pyc | Bin 0 -> 4091 bytes .../__pycache__/bccache.cpython-312.pyc | Bin 0 -> 19338 bytes .../__pycache__/compiler.cpython-312.pyc | Bin 0 -> 102271 bytes .../__pycache__/constants.cpython-312.pyc | Bin 0 -> 1569 bytes .../jinja2/__pycache__/debug.cpython-312.pyc | Bin 0 -> 6579 bytes .../__pycache__/defaults.cpython-312.pyc | Bin 0 -> 1619 bytes .../__pycache__/environment.cpython-312.pyc | Bin 0 -> 76715 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7728 bytes .../jinja2/__pycache__/ext.cpython-312.pyc | Bin 0 -> 41881 bytes .../__pycache__/filters.cpython-312.pyc | Bin 0 -> 72033 bytes .../__pycache__/idtracking.cpython-312.pyc | Bin 0 -> 19162 bytes .../jinja2/__pycache__/lexer.cpython-312.pyc | Bin 0 -> 32050 bytes .../__pycache__/loaders.cpython-312.pyc | Bin 0 -> 30976 bytes .../jinja2/__pycache__/meta.cpython-312.pyc | Bin 0 -> 5483 bytes .../__pycache__/nativetypes.cpython-312.pyc | Bin 0 -> 7032 bytes .../jinja2/__pycache__/nodes.cpython-312.pyc | Bin 0 -> 58232 bytes .../__pycache__/optimizer.cpython-312.pyc | Bin 0 -> 2702 bytes .../jinja2/__pycache__/parser.cpython-312.pyc | Bin 0 -> 60824 bytes .../__pycache__/runtime.cpython-312.pyc | Bin 0 -> 48505 bytes .../__pycache__/sandbox.cpython-312.pyc | Bin 0 -> 17903 bytes .../jinja2/__pycache__/tests.cpython-312.pyc | Bin 0 -> 9063 bytes .../jinja2/__pycache__/utils.cpython-312.pyc | Bin 0 -> 34481 bytes .../__pycache__/visitor.cpython-312.pyc | Bin 0 -> 5366 bytes .../site-packages/jinja2/_identifier.py | 6 + .../site-packages/jinja2/async_utils.py | 84 + .../site-packages/jinja2/bccache.py | 408 + .../site-packages/jinja2/compiler.py | 1960 ++++ .../site-packages/jinja2/constants.py | 20 + .../python3.12/site-packages/jinja2/debug.py | 191 + .../site-packages/jinja2/defaults.py | 48 + .../site-packages/jinja2/environment.py | 1675 ++++ .../site-packages/jinja2/exceptions.py | 166 + .../python3.12/site-packages/jinja2/ext.py | 870 ++ .../site-packages/jinja2/filters.py | 1866 ++++ .../site-packages/jinja2/idtracking.py | 318 + .../python3.12/site-packages/jinja2/lexer.py | 868 ++ .../site-packages/jinja2/loaders.py | 667 ++ .../python3.12/site-packages/jinja2/meta.py | 112 + .../site-packages/jinja2/nativetypes.py | 130 + .../python3.12/site-packages/jinja2/nodes.py | 1206 +++ .../site-packages/jinja2/optimizer.py | 48 + .../python3.12/site-packages/jinja2/parser.py | 1041 ++ .../python3.12/site-packages/jinja2/py.typed | 0 .../site-packages/jinja2/runtime.py | 1056 ++ .../site-packages/jinja2/sandbox.py | 429 + .../python3.12/site-packages/jinja2/tests.py | 256 + .../python3.12/site-packages/jinja2/utils.py | 755 ++ .../site-packages/jinja2/visitor.py | 92 + .../site-packages/markupsafe/__init__.py | 395 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 20966 bytes .../__pycache__/_native.cpython-312.pyc | Bin 0 -> 628 bytes .../site-packages/markupsafe/_native.py | 8 + .../site-packages/markupsafe/_speedups.c | 204 + .../_speedups.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 43432 bytes .../site-packages/markupsafe/_speedups.pyi | 1 + .../site-packages/markupsafe/py.typed | 0 .../pillow-11.0.0.dist-info/INSTALLER | 1 + .../pillow-11.0.0.dist-info/LICENSE | 1343 +++ .../pillow-11.0.0.dist-info/METADATA | 175 + .../pillow-11.0.0.dist-info/RECORD | 229 + .../pillow-11.0.0.dist-info/REQUESTED | 0 .../pillow-11.0.0.dist-info/WHEEL | 5 + .../pillow-11.0.0.dist-info/top_level.txt | 1 + .../pillow-11.0.0.dist-info/zip-safe | 1 + .../pillow.libs/libXau-154567c4.so.6.0.0 | Bin 0 -> 22081 bytes .../pillow.libs/libbrotlicommon-3ecfe81c.so.1 | Bin 0 -> 144425 bytes .../pillow.libs/libbrotlidec-ba690955.so.1 | Bin 0 -> 58225 bytes .../libfreetype-e7d5437d.so.6.20.1 | Bin 0 -> 1422625 bytes .../pillow.libs/libharfbuzz-144af51e.so.0 | Bin 0 -> 1583281 bytes .../pillow.libs/libjpeg-45e70d75.so.62.4.0 | Bin 0 -> 815793 bytes .../pillow.libs/liblcms2-e69eef39.so.2.0.16 | Bin 0 -> 514977 bytes .../pillow.libs/liblzma-c9407571.so.5.6.3 | Bin 0 -> 266201 bytes .../pillow.libs/libopenjp2-05423b53.so | Bin 0 -> 581737 bytes .../pillow.libs/libpng16-4cc6a9fc.so.16.44.0 | Bin 0 -> 281913 bytes .../pillow.libs/libsharpyuv-898c0cb5.so.0.1.0 | Bin 0 -> 42049 bytes .../pillow.libs/libtiff-0a86184d.so.6.0.2 | Bin 0 -> 725697 bytes .../pillow.libs/libwebp-2fd3cdca.so.7.1.9 | Bin 0 -> 759849 bytes .../libwebpdemux-f2642bcc.so.2.0.15 | Bin 0 -> 26121 bytes .../pillow.libs/libwebpmux-d524b4d5.so.3.1.0 | Bin 0 -> 54521 bytes .../pillow.libs/libxcb-b8a56d01.so.1.1.0 | Bin 0 -> 251425 bytes .../pip-24.2.dist-info/AUTHORS.txt | 796 ++ .../pip-24.2.dist-info/INSTALLER | 1 + .../pip-24.2.dist-info/LICENSE.txt | 20 + .../site-packages/pip-24.2.dist-info/METADATA | 89 + .../site-packages/pip-24.2.dist-info/RECORD | 853 ++ .../pip-24.2.dist-info/REQUESTED | 0 .../site-packages/pip-24.2.dist-info/WHEEL | 5 + .../pip-24.2.dist-info/entry_points.txt | 3 + .../pip-24.2.dist-info/top_level.txt | 1 + .../python3.12/site-packages/pip/__init__.py | 13 + .../python3.12/site-packages/pip/__main__.py | 24 + .../site-packages/pip/__pip-runner__.py | 50 + .../pip/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 703 bytes .../pip/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 859 bytes .../__pip-runner__.cpython-312.pyc | Bin 0 -> 2223 bytes .../site-packages/pip/_internal/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 805 bytes .../__pycache__/build_env.cpython-312.pyc | Bin 0 -> 14490 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 12685 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 17650 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 35569 bytes .../__pycache__/main.cpython-312.pyc | Bin 0 -> 688 bytes .../__pycache__/pyproject.cpython-312.pyc | Bin 0 -> 5136 bytes .../self_outdated_check.cpython-312.pyc | Bin 0 -> 10226 bytes .../__pycache__/wheel_builder.cpython-312.pyc | Bin 0 -> 13633 bytes .../site-packages/pip/_internal/build_env.py | 315 + .../site-packages/pip/_internal/cache.py | 290 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 296 bytes .../autocompletion.cpython-312.pyc | Bin 0 -> 8624 bytes .../__pycache__/base_command.cpython-312.pyc | Bin 0 -> 10212 bytes .../__pycache__/cmdoptions.cpython-312.pyc | Bin 0 -> 30413 bytes .../command_context.cpython-312.pyc | Bin 0 -> 1792 bytes .../__pycache__/index_command.cpython-312.pyc | Bin 0 -> 7142 bytes .../cli/__pycache__/main.cpython-312.pyc | Bin 0 -> 2318 bytes .../__pycache__/main_parser.cpython-312.pyc | Bin 0 -> 4924 bytes .../cli/__pycache__/parser.cpython-312.pyc | Bin 0 -> 15031 bytes .../__pycache__/progress_bars.cpython-312.pyc | Bin 0 -> 3852 bytes .../__pycache__/req_command.cpython-312.pyc | Bin 0 -> 12259 bytes .../cli/__pycache__/spinners.cpython-312.pyc | Bin 0 -> 7851 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 393 bytes .../pip/_internal/cli/autocompletion.py | 176 + .../pip/_internal/cli/base_command.py | 231 + .../pip/_internal/cli/cmdoptions.py | 1075 +++ .../pip/_internal/cli/command_context.py | 27 + .../pip/_internal/cli/index_command.py | 170 + .../site-packages/pip/_internal/cli/main.py | 80 + .../pip/_internal/cli/main_parser.py | 134 + .../site-packages/pip/_internal/cli/parser.py | 294 + .../pip/_internal/cli/progress_bars.py | 94 + .../pip/_internal/cli/req_command.py | 329 + .../pip/_internal/cli/spinners.py | 159 + .../pip/_internal/cli/status_codes.py | 6 + .../pip/_internal/commands/__init__.py | 132 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4020 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 9719 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 2610 bytes .../__pycache__/completion.cpython-312.pyc | Bin 0 -> 5211 bytes .../__pycache__/configuration.cpython-312.pyc | Bin 0 -> 13181 bytes .../__pycache__/debug.cpython-312.pyc | Bin 0 -> 10086 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 7521 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 4403 bytes .../commands/__pycache__/hash.cpython-312.pyc | Bin 0 -> 2986 bytes .../commands/__pycache__/help.cpython-312.pyc | Bin 0 -> 1691 bytes .../__pycache__/index.cpython-312.pyc | Bin 0 -> 6689 bytes .../__pycache__/inspect.cpython-312.pyc | Bin 0 -> 3998 bytes .../__pycache__/install.cpython-312.pyc | Bin 0 -> 29132 bytes .../commands/__pycache__/list.cpython-312.pyc | Bin 0 -> 15775 bytes .../__pycache__/search.cpython-312.pyc | Bin 0 -> 7536 bytes .../commands/__pycache__/show.cpython-312.pyc | Bin 0 -> 10495 bytes .../__pycache__/uninstall.cpython-312.pyc | Bin 0 -> 4727 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 8883 bytes .../pip/_internal/commands/cache.py | 225 + .../pip/_internal/commands/check.py | 67 + .../pip/_internal/commands/completion.py | 130 + .../pip/_internal/commands/configuration.py | 280 + .../pip/_internal/commands/debug.py | 201 + .../pip/_internal/commands/download.py | 146 + .../pip/_internal/commands/freeze.py | 109 + .../pip/_internal/commands/hash.py | 59 + .../pip/_internal/commands/help.py | 41 + .../pip/_internal/commands/index.py | 139 + .../pip/_internal/commands/inspect.py | 92 + .../pip/_internal/commands/install.py | 783 ++ .../pip/_internal/commands/list.py | 375 + .../pip/_internal/commands/search.py | 172 + .../pip/_internal/commands/show.py | 217 + .../pip/_internal/commands/uninstall.py | 114 + .../pip/_internal/commands/wheel.py | 182 + .../pip/_internal/configuration.py | 383 + .../pip/_internal/distributions/__init__.py | 21 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 959 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 2911 bytes .../__pycache__/installed.cpython-312.pyc | Bin 0 -> 1718 bytes .../__pycache__/sdist.cpython-312.pyc | Bin 0 -> 8445 bytes .../__pycache__/wheel.cpython-312.pyc | Bin 0 -> 2299 bytes .../pip/_internal/distributions/base.py | 53 + .../pip/_internal/distributions/installed.py | 29 + .../pip/_internal/distributions/sdist.py | 158 + .../pip/_internal/distributions/wheel.py | 42 + .../site-packages/pip/_internal/exceptions.py | 777 ++ .../pip/_internal/index/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 250 bytes .../__pycache__/collector.cpython-312.pyc | Bin 0 -> 21635 bytes .../package_finder.cpython-312.pyc | Bin 0 -> 40666 bytes .../index/__pycache__/sources.cpython-312.pyc | Bin 0 -> 12606 bytes .../pip/_internal/index/collector.py | 494 + .../pip/_internal/index/package_finder.py | 1020 ++ .../pip/_internal/index/sources.py | 285 + .../pip/_internal/locations/__init__.py | 456 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 16458 bytes .../__pycache__/_distutils.cpython-312.pyc | Bin 0 -> 6870 bytes .../__pycache__/_sysconfig.cpython-312.pyc | Bin 0 -> 8046 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 3799 bytes .../pip/_internal/locations/_distutils.py | 172 + .../pip/_internal/locations/_sysconfig.py | 214 + .../pip/_internal/locations/base.py | 81 + .../site-packages/pip/_internal/main.py | 12 + .../pip/_internal/metadata/__init__.py | 128 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5887 bytes .../__pycache__/_json.cpython-312.pyc | Bin 0 -> 2944 bytes .../metadata/__pycache__/base.cpython-312.pyc | Bin 0 -> 35216 bytes .../__pycache__/pkg_resources.cpython-312.pyc | Bin 0 -> 16102 bytes .../pip/_internal/metadata/_json.py | 84 + .../pip/_internal/metadata/base.py | 688 ++ .../_internal/metadata/importlib/__init__.py | 6 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 376 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 4509 bytes .../__pycache__/_dists.cpython-312.pyc | Bin 0 -> 12583 bytes .../__pycache__/_envs.cpython-312.pyc | Bin 0 -> 11097 bytes .../_internal/metadata/importlib/_compat.py | 85 + .../_internal/metadata/importlib/_dists.py | 221 + .../pip/_internal/metadata/importlib/_envs.py | 189 + .../pip/_internal/metadata/pkg_resources.py | 301 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 284 bytes .../__pycache__/candidate.cpython-312.pyc | Bin 0 -> 1622 bytes .../__pycache__/direct_url.cpython-312.pyc | Bin 0 -> 10862 bytes .../format_control.cpython-312.pyc | Bin 0 -> 4241 bytes .../models/__pycache__/index.cpython-312.pyc | Bin 0 -> 1712 bytes .../installation_report.cpython-312.pyc | Bin 0 -> 2295 bytes .../models/__pycache__/link.cpython-312.pyc | Bin 0 -> 26635 bytes .../models/__pycache__/scheme.cpython-312.pyc | Bin 0 -> 1041 bytes .../__pycache__/search_scope.cpython-312.pyc | Bin 0 -> 5005 bytes .../selection_prefs.cpython-312.pyc | Bin 0 -> 1869 bytes .../__pycache__/target_python.cpython-312.pyc | Bin 0 -> 4971 bytes .../models/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5778 bytes .../pip/_internal/models/candidate.py | 25 + .../pip/_internal/models/direct_url.py | 224 + .../pip/_internal/models/format_control.py | 78 + .../pip/_internal/models/index.py | 28 + .../_internal/models/installation_report.py | 56 + .../pip/_internal/models/link.py | 590 ++ .../pip/_internal/models/scheme.py | 25 + .../pip/_internal/models/search_scope.py | 127 + .../pip/_internal/models/selection_prefs.py | 53 + .../pip/_internal/models/target_python.py | 121 + .../pip/_internal/models/wheel.py | 93 + .../pip/_internal/network/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 272 bytes .../network/__pycache__/auth.cpython-312.pyc | Bin 0 -> 22117 bytes .../network/__pycache__/cache.cpython-312.pyc | Bin 0 -> 6469 bytes .../__pycache__/download.cpython-312.pyc | Bin 0 -> 8497 bytes .../__pycache__/lazy_wheel.cpython-312.pyc | Bin 0 -> 11625 bytes .../__pycache__/session.cpython-312.pyc | Bin 0 -> 18892 bytes .../network/__pycache__/utils.cpython-312.pyc | Bin 0 -> 2273 bytes .../__pycache__/xmlrpc.cpython-312.pyc | Bin 0 -> 2967 bytes .../pip/_internal/network/auth.py | 566 ++ .../pip/_internal/network/cache.py | 106 + .../pip/_internal/network/download.py | 187 + .../pip/_internal/network/lazy_wheel.py | 210 + .../pip/_internal/network/session.py | 522 + .../pip/_internal/network/utils.py | 98 + .../pip/_internal/network/xmlrpc.py | 62 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 215 bytes .../__pycache__/check.cpython-312.pyc | Bin 0 -> 7122 bytes .../__pycache__/freeze.cpython-312.pyc | Bin 0 -> 10146 bytes .../__pycache__/prepare.cpython-312.pyc | Bin 0 -> 25790 bytes .../_internal/operations/build/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 221 bytes .../__pycache__/build_tracker.cpython-312.pyc | Bin 0 -> 7685 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 1875 bytes .../metadata_editable.cpython-312.pyc | Bin 0 -> 1909 bytes .../metadata_legacy.cpython-312.pyc | Bin 0 -> 3029 bytes .../build/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 1695 bytes .../wheel_editable.cpython-312.pyc | Bin 0 -> 2034 bytes .../__pycache__/wheel_legacy.cpython-312.pyc | Bin 0 -> 3864 bytes .../operations/build/build_tracker.py | 138 + .../_internal/operations/build/metadata.py | 39 + .../operations/build/metadata_editable.py | 41 + .../operations/build/metadata_legacy.py | 74 + .../pip/_internal/operations/build/wheel.py | 37 + .../operations/build/wheel_editable.py | 46 + .../operations/build/wheel_legacy.py | 102 + .../pip/_internal/operations/check.py | 181 + .../pip/_internal/operations/freeze.py | 258 + .../_internal/operations/install/__init__.py | 2 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 284 bytes .../editable_legacy.cpython-312.pyc | Bin 0 -> 1816 bytes .../install/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 34121 bytes .../operations/install/editable_legacy.py | 47 + .../pip/_internal/operations/install/wheel.py | 741 ++ .../pip/_internal/operations/prepare.py | 732 ++ .../site-packages/pip/_internal/pyproject.py | 185 + .../pip/_internal/req/__init__.py | 90 + .../req/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3463 bytes .../__pycache__/constructors.cpython-312.pyc | Bin 0 -> 21236 bytes .../req/__pycache__/req_file.cpython-312.pyc | Bin 0 -> 21450 bytes .../__pycache__/req_install.cpython-312.pyc | Bin 0 -> 38493 bytes .../req/__pycache__/req_set.cpython-312.pyc | Bin 0 -> 5501 bytes .../__pycache__/req_uninstall.cpython-312.pyc | Bin 0 -> 32112 bytes .../pip/_internal/req/constructors.py | 560 ++ .../pip/_internal/req/req_file.py | 551 ++ .../pip/_internal/req/req_install.py | 934 ++ .../pip/_internal/req/req_set.py | 82 + .../pip/_internal/req/req_uninstall.py | 633 ++ .../pip/_internal/resolution/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 215 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 1203 bytes .../pip/_internal/resolution/base.py | 20 + .../_internal/resolution/legacy/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 222 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 22597 bytes .../_internal/resolution/legacy/resolver.py | 597 ++ .../resolution/resolvelib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 226 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 8167 bytes .../__pycache__/candidates.cpython-312.pyc | Bin 0 -> 29190 bytes .../__pycache__/factory.cpython-312.pyc | Bin 0 -> 32304 bytes .../found_candidates.cpython-312.pyc | Bin 0 -> 6811 bytes .../__pycache__/provider.cpython-312.pyc | Bin 0 -> 10541 bytes .../__pycache__/reporter.cpython-312.pyc | Bin 0 -> 5058 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 15374 bytes .../__pycache__/resolver.cpython-312.pyc | Bin 0 -> 12332 bytes .../_internal/resolution/resolvelib/base.py | 139 + .../resolution/resolvelib/candidates.py | 569 ++ .../resolution/resolvelib/factory.py | 817 ++ .../resolution/resolvelib/found_candidates.py | 174 + .../resolution/resolvelib/provider.py | 258 + .../resolution/resolvelib/reporter.py | 81 + .../resolution/resolvelib/requirements.py | 245 + .../resolution/resolvelib/resolver.py | 317 + .../pip/_internal/self_outdated_check.py | 244 + .../pip/_internal/utils/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 210 bytes .../__pycache__/_jaraco_text.cpython-312.pyc | Bin 0 -> 4545 bytes .../utils/__pycache__/_log.cpython-312.pyc | Bin 0 -> 1881 bytes .../utils/__pycache__/appdirs.cpython-312.pyc | Bin 0 -> 2425 bytes .../utils/__pycache__/compat.cpython-312.pyc | Bin 0 -> 2922 bytes .../compatibility_tags.cpython-312.pyc | Bin 0 -> 5578 bytes .../__pycache__/datetime.cpython-312.pyc | Bin 0 -> 699 bytes .../__pycache__/deprecation.cpython-312.pyc | Bin 0 -> 4206 bytes .../direct_url_helpers.cpython-312.pyc | Bin 0 -> 3551 bytes .../__pycache__/egg_link.cpython-312.pyc | Bin 0 -> 3221 bytes .../__pycache__/encoding.cpython-312.pyc | Bin 0 -> 2163 bytes .../__pycache__/entrypoints.cpython-312.pyc | Bin 0 -> 4008 bytes .../__pycache__/filesystem.cpython-312.pyc | Bin 0 -> 7344 bytes .../__pycache__/filetypes.cpython-312.pyc | Bin 0 -> 1179 bytes .../utils/__pycache__/glibc.cpython-312.pyc | Bin 0 -> 2434 bytes .../utils/__pycache__/hashes.cpython-312.pyc | Bin 0 -> 7618 bytes .../utils/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13573 bytes .../utils/__pycache__/misc.cpython-312.pyc | Bin 0 -> 33566 bytes .../__pycache__/packaging.cpython-312.pyc | Bin 0 -> 2598 bytes .../utils/__pycache__/retry.cpython-312.pyc | Bin 0 -> 2123 bytes .../setuptools_build.cpython-312.pyc | Bin 0 -> 4565 bytes .../__pycache__/subprocess.cpython-312.pyc | Bin 0 -> 8654 bytes .../__pycache__/temp_dir.cpython-312.pyc | Bin 0 -> 12039 bytes .../__pycache__/unpacking.cpython-312.pyc | Bin 0 -> 13513 bytes .../utils/__pycache__/urls.cpython-312.pyc | Bin 0 -> 2092 bytes .../__pycache__/virtualenv.cpython-312.pyc | Bin 0 -> 4481 bytes .../utils/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 5918 bytes .../pip/_internal/utils/_jaraco_text.py | 109 + .../site-packages/pip/_internal/utils/_log.py | 38 + .../pip/_internal/utils/appdirs.py | 52 + .../pip/_internal/utils/compat.py | 79 + .../pip/_internal/utils/compatibility_tags.py | 165 + .../pip/_internal/utils/datetime.py | 11 + .../pip/_internal/utils/deprecation.py | 124 + .../pip/_internal/utils/direct_url_helpers.py | 87 + .../pip/_internal/utils/egg_link.py | 80 + .../pip/_internal/utils/encoding.py | 36 + .../pip/_internal/utils/entrypoints.py | 84 + .../pip/_internal/utils/filesystem.py | 149 + .../pip/_internal/utils/filetypes.py | 27 + .../pip/_internal/utils/glibc.py | 101 + .../pip/_internal/utils/hashes.py | 147 + .../pip/_internal/utils/logging.py | 347 + .../site-packages/pip/_internal/utils/misc.py | 777 ++ .../pip/_internal/utils/packaging.py | 57 + .../pip/_internal/utils/retry.py | 42 + .../pip/_internal/utils/setuptools_build.py | 146 + .../pip/_internal/utils/subprocess.py | 245 + .../pip/_internal/utils/temp_dir.py | 296 + .../pip/_internal/utils/unpacking.py | 337 + .../site-packages/pip/_internal/utils/urls.py | 55 + .../pip/_internal/utils/virtualenv.py | 104 + .../pip/_internal/utils/wheel.py | 134 + .../pip/_internal/vcs/__init__.py | 15 + .../vcs/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 549 bytes .../vcs/__pycache__/bazaar.cpython-312.pyc | Bin 0 -> 5070 bytes .../vcs/__pycache__/git.cpython-312.pyc | Bin 0 -> 19035 bytes .../vcs/__pycache__/mercurial.cpython-312.pyc | Bin 0 -> 7623 bytes .../__pycache__/subversion.cpython-312.pyc | Bin 0 -> 12542 bytes .../versioncontrol.cpython-312.pyc | Bin 0 -> 29015 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 527 + .../pip/_internal/vcs/mercurial.py | 163 + .../pip/_internal/vcs/subversion.py | 324 + .../pip/_internal/vcs/versioncontrol.py | 688 ++ .../pip/_internal/wheel_builder.py | 354 + .../site-packages/pip/_vendor/__init__.py | 116 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4568 bytes .../typing_extensions.cpython-312.pyc | Bin 0 -> 139470 bytes .../pip/_vendor/cachecontrol/__init__.py | 28 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 921 bytes .../__pycache__/_cmd.cpython-312.pyc | Bin 0 -> 2665 bytes .../__pycache__/adapter.cpython-312.pyc | Bin 0 -> 6483 bytes .../__pycache__/cache.cpython-312.pyc | Bin 0 -> 3806 bytes .../__pycache__/controller.cpython-312.pyc | Bin 0 -> 16243 bytes .../__pycache__/filewrapper.cpython-312.pyc | Bin 0 -> 4366 bytes .../__pycache__/heuristics.cpython-312.pyc | Bin 0 -> 6713 bytes .../__pycache__/serialize.cpython-312.pyc | Bin 0 -> 5280 bytes .../__pycache__/wrapper.cpython-312.pyc | Bin 0 -> 1693 bytes .../pip/_vendor/cachecontrol/_cmd.py | 70 + .../pip/_vendor/cachecontrol/adapter.py | 161 + .../pip/_vendor/cachecontrol/cache.py | 74 + .../_vendor/cachecontrol/caches/__init__.py | 8 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 454 bytes .../__pycache__/file_cache.cpython-312.pyc | Bin 0 -> 7782 bytes .../__pycache__/redis_cache.cpython-312.pyc | Bin 0 -> 2752 bytes .../_vendor/cachecontrol/caches/file_cache.py | 182 + .../cachecontrol/caches/redis_cache.py | 48 + .../pip/_vendor/cachecontrol/controller.py | 499 + .../pip/_vendor/cachecontrol/filewrapper.py | 119 + .../pip/_vendor/cachecontrol/heuristics.py | 154 + .../pip/_vendor/cachecontrol/py.typed | 0 .../pip/_vendor/cachecontrol/serialize.py | 146 + .../pip/_vendor/cachecontrol/wrapper.py | 43 + .../pip/_vendor/certifi/__init__.py | 4 + .../pip/_vendor/certifi/__main__.py | 12 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 337 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 664 bytes .../certifi/__pycache__/core.cpython-312.pyc | Bin 0 -> 3230 bytes .../pip/_vendor/certifi/cacert.pem | 4798 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 114 + .../pip/_vendor/certifi/py.typed | 0 .../pip/_vendor/distlib/__init__.py | 33 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1288 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 45550 bytes .../__pycache__/database.cpython-312.pyc | Bin 0 -> 65700 bytes .../distlib/__pycache__/index.cpython-312.pyc | Bin 0 -> 24335 bytes .../__pycache__/locators.cpython-312.pyc | Bin 0 -> 59949 bytes .../__pycache__/manifest.cpython-312.pyc | Bin 0 -> 15095 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 7697 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 41685 bytes .../__pycache__/resources.cpython-312.pyc | Bin 0 -> 17331 bytes .../__pycache__/scripts.cpython-312.pyc | Bin 0 -> 19788 bytes .../distlib/__pycache__/util.cpython-312.pyc | Bin 0 -> 88036 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 30364 bytes .../distlib/__pycache__/wheel.cpython-312.pyc | Bin 0 -> 51467 bytes .../pip/_vendor/distlib/compat.py | 1138 +++ .../pip/_vendor/distlib/database.py | 1359 +++ .../pip/_vendor/distlib/index.py | 508 + .../pip/_vendor/distlib/locators.py | 1303 +++ .../pip/_vendor/distlib/manifest.py | 384 + .../pip/_vendor/distlib/markers.py | 167 + .../pip/_vendor/distlib/metadata.py | 1068 ++ .../pip/_vendor/distlib/resources.py | 358 + .../pip/_vendor/distlib/scripts.py | 466 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 97792 bytes .../pip/_vendor/distlib/t64-arm.exe | Bin 0 -> 182784 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 108032 bytes .../site-packages/pip/_vendor/distlib/util.py | 2025 ++++ .../pip/_vendor/distlib/version.py | 751 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 91648 bytes .../pip/_vendor/distlib/w64-arm.exe | Bin 0 -> 168448 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 101888 bytes .../pip/_vendor/distlib/wheel.py | 1099 +++ .../pip/_vendor/distro/__init__.py | 54 + .../pip/_vendor/distro/__main__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 979 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 311 bytes .../distro/__pycache__/distro.cpython-312.pyc | Bin 0 -> 53811 bytes .../pip/_vendor/distro/distro.py | 1403 +++ .../site-packages/pip/_vendor/distro/py.typed | 0 .../pip/_vendor/idna/__init__.py | 44 + .../idna/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 900 bytes .../idna/__pycache__/codec.cpython-312.pyc | Bin 0 -> 4995 bytes .../idna/__pycache__/compat.cpython-312.pyc | Bin 0 -> 906 bytes .../idna/__pycache__/core.cpython-312.pyc | Bin 0 -> 15810 bytes .../idna/__pycache__/idnadata.cpython-312.pyc | Bin 0 -> 99495 bytes .../__pycache__/intranges.cpython-312.pyc | Bin 0 -> 2652 bytes .../__pycache__/package_data.cpython-312.pyc | Bin 0 -> 235 bytes .../__pycache__/uts46data.cpython-312.pyc | Bin 0 -> 158867 bytes .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 13 + .../site-packages/pip/_vendor/idna/core.py | 395 + .../pip/_vendor/idna/idnadata.py | 4245 ++++++++ .../pip/_vendor/idna/intranges.py | 54 + .../pip/_vendor/idna/package_data.py | 2 + .../site-packages/pip/_vendor/idna/py.typed | 0 .../pip/_vendor/idna/uts46data.py | 8598 +++++++++++++++++ .../pip/_vendor/msgpack/__init__.py | 55 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1760 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 2044 bytes .../msgpack/__pycache__/ext.cpython-312.pyc | Bin 0 -> 8189 bytes .../__pycache__/fallback.cpython-312.pyc | Bin 0 -> 42062 bytes .../pip/_vendor/msgpack/exceptions.py | 48 + .../site-packages/pip/_vendor/msgpack/ext.py | 168 + .../pip/_vendor/msgpack/fallback.py | 951 ++ .../pip/_vendor/packaging/__init__.py | 15 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 577 bytes .../__pycache__/_elffile.cpython-312.pyc | Bin 0 -> 4986 bytes .../__pycache__/_manylinux.cpython-312.pyc | Bin 0 -> 9704 bytes .../__pycache__/_musllinux.cpython-312.pyc | Bin 0 -> 4573 bytes .../__pycache__/_parser.cpython-312.pyc | Bin 0 -> 14004 bytes .../__pycache__/_structures.cpython-312.pyc | Bin 0 -> 3260 bytes .../__pycache__/_tokenizer.cpython-312.pyc | Bin 0 -> 7934 bytes .../__pycache__/markers.cpython-312.pyc | Bin 0 -> 11030 bytes .../__pycache__/metadata.cpython-312.pyc | Bin 0 -> 24972 bytes .../__pycache__/requirements.cpython-312.pyc | Bin 0 -> 4429 bytes .../__pycache__/specifiers.cpython-312.pyc | Bin 0 -> 38758 bytes .../__pycache__/tags.cpython-312.pyc | Bin 0 -> 21363 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 7360 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 19526 bytes .../pip/_vendor/packaging/_elffile.py | 110 + .../pip/_vendor/packaging/_manylinux.py | 262 + .../pip/_vendor/packaging/_musllinux.py | 85 + .../pip/_vendor/packaging/_parser.py | 354 + .../pip/_vendor/packaging/_structures.py | 61 + .../pip/_vendor/packaging/_tokenizer.py | 194 + .../pip/_vendor/packaging/markers.py | 325 + .../pip/_vendor/packaging/metadata.py | 804 ++ .../pip/_vendor/packaging/py.typed | 0 .../pip/_vendor/packaging/requirements.py | 91 + .../pip/_vendor/packaging/specifiers.py | 1009 ++ .../pip/_vendor/packaging/tags.py | 568 ++ .../pip/_vendor/packaging/utils.py | 174 + .../pip/_vendor/packaging/version.py | 563 ++ .../pip/_vendor/pkg_resources/__init__.py | 3676 +++++++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 161280 bytes .../pip/_vendor/platformdirs/__init__.py | 627 ++ .../pip/_vendor/platformdirs/__main__.py | 55 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 19848 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 1967 bytes .../__pycache__/android.cpython-312.pyc | Bin 0 -> 10716 bytes .../__pycache__/api.cpython-312.pyc | Bin 0 -> 12930 bytes .../__pycache__/macos.cpython-312.pyc | Bin 0 -> 8026 bytes .../__pycache__/unix.cpython-312.pyc | Bin 0 -> 15056 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 616 bytes .../__pycache__/windows.cpython-312.pyc | Bin 0 -> 13693 bytes .../pip/_vendor/platformdirs/android.py | 249 + .../pip/_vendor/platformdirs/api.py | 292 + .../pip/_vendor/platformdirs/macos.py | 130 + .../pip/_vendor/platformdirs/py.typed | 0 .../pip/_vendor/platformdirs/unix.py | 275 + .../pip/_vendor/platformdirs/version.py | 16 + .../pip/_vendor/platformdirs/windows.py | 272 + .../pip/_vendor/pygments/__init__.py | 82 + .../pip/_vendor/pygments/__main__.py | 17 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3508 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 754 bytes .../__pycache__/cmdline.cpython-312.pyc | Bin 0 -> 26604 bytes .../__pycache__/console.cpython-312.pyc | Bin 0 -> 2648 bytes .../__pycache__/filter.cpython-312.pyc | Bin 0 -> 3241 bytes .../__pycache__/formatter.cpython-312.pyc | Bin 0 -> 4740 bytes .../__pycache__/lexer.cpython-312.pyc | Bin 0 -> 38381 bytes .../__pycache__/modeline.cpython-312.pyc | Bin 0 -> 1579 bytes .../__pycache__/plugin.cpython-312.pyc | Bin 0 -> 2628 bytes .../__pycache__/regexopt.cpython-312.pyc | Bin 0 -> 4097 bytes .../__pycache__/scanner.cpython-312.pyc | Bin 0 -> 4776 bytes .../__pycache__/sphinxext.cpython-312.pyc | Bin 0 -> 12118 bytes .../__pycache__/style.cpython-312.pyc | Bin 0 -> 6713 bytes .../__pycache__/token.cpython-312.pyc | Bin 0 -> 8209 bytes .../__pycache__/unistring.cpython-312.pyc | Bin 0 -> 32992 bytes .../pygments/__pycache__/util.cpython-312.pyc | Bin 0 -> 14089 bytes .../pip/_vendor/pygments/cmdline.py | 668 ++ .../pip/_vendor/pygments/console.py | 70 + .../pip/_vendor/pygments/filter.py | 70 + .../pip/_vendor/pygments/filters/__init__.py | 940 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 37931 bytes .../pip/_vendor/pygments/formatter.py | 129 + .../_vendor/pygments/formatters/__init__.py | 157 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 6922 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 4235 bytes .../__pycache__/bbcode.cpython-312.pyc | Bin 0 -> 4242 bytes .../__pycache__/groff.cpython-312.pyc | Bin 0 -> 7313 bytes .../__pycache__/html.cpython-312.pyc | Bin 0 -> 41046 bytes .../__pycache__/img.cpython-312.pyc | Bin 0 -> 28568 bytes .../__pycache__/irc.cpython-312.pyc | Bin 0 -> 6075 bytes .../__pycache__/latex.cpython-312.pyc | Bin 0 -> 20145 bytes .../__pycache__/other.cpython-312.pyc | Bin 0 -> 6897 bytes .../__pycache__/pangomarkup.cpython-312.pyc | Bin 0 -> 2978 bytes .../__pycache__/rtf.cpython-312.pyc | Bin 0 -> 13793 bytes .../__pycache__/svg.cpython-312.pyc | Bin 0 -> 9159 bytes .../__pycache__/terminal.cpython-312.pyc | Bin 0 -> 5839 bytes .../__pycache__/terminal256.cpython-312.pyc | Bin 0 -> 15138 bytes .../_vendor/pygments/formatters/_mapping.py | 23 + .../pip/_vendor/pygments/formatters/bbcode.py | 108 + .../pip/_vendor/pygments/formatters/groff.py | 170 + .../pip/_vendor/pygments/formatters/html.py | 987 ++ .../pip/_vendor/pygments/formatters/img.py | 685 ++ .../pip/_vendor/pygments/formatters/irc.py | 154 + .../pip/_vendor/pygments/formatters/latex.py | 518 + .../pip/_vendor/pygments/formatters/other.py | 160 + .../pygments/formatters/pangomarkup.py | 83 + .../pip/_vendor/pygments/formatters/rtf.py | 349 + .../pip/_vendor/pygments/formatters/svg.py | 185 + .../_vendor/pygments/formatters/terminal.py | 127 + .../pygments/formatters/terminal256.py | 338 + .../pip/_vendor/pygments/lexer.py | 963 ++ .../pip/_vendor/pygments/lexers/__init__.py | 362 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 14641 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 68283 bytes .../lexers/__pycache__/python.cpython-312.pyc | Bin 0 -> 42987 bytes .../pip/_vendor/pygments/lexers/_mapping.py | 589 ++ .../pip/_vendor/pygments/lexers/python.py | 1198 +++ .../pip/_vendor/pygments/modeline.py | 43 + .../pip/_vendor/pygments/plugin.py | 72 + .../pip/_vendor/pygments/regexopt.py | 91 + .../pip/_vendor/pygments/scanner.py | 104 + .../pip/_vendor/pygments/sphinxext.py | 247 + .../pip/_vendor/pygments/style.py | 203 + .../pip/_vendor/pygments/styles/__init__.py | 61 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2684 bytes .../__pycache__/_mapping.cpython-312.pyc | Bin 0 -> 3668 bytes .../pip/_vendor/pygments/styles/_mapping.py | 54 + .../pip/_vendor/pygments/token.py | 214 + .../pip/_vendor/pygments/unistring.py | 153 + .../pip/_vendor/pygments/util.py | 324 + .../pip/_vendor/pyproject_hooks/__init__.py | 23 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 633 bytes .../__pycache__/_compat.cpython-312.pyc | Bin 0 -> 394 bytes .../__pycache__/_impl.cpython-312.pyc | Bin 0 -> 14713 bytes .../pip/_vendor/pyproject_hooks/_compat.py | 8 + .../pip/_vendor/pyproject_hooks/_impl.py | 330 + .../pyproject_hooks/_in_process/__init__.py | 18 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1100 bytes .../__pycache__/_in_process.cpython-312.pyc | Bin 0 -> 14373 bytes .../_in_process/_in_process.py | 353 + .../pip/_vendor/requests/__init__.py | 179 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 5273 bytes .../__pycache__/__version__.cpython-312.pyc | Bin 0 -> 604 bytes .../_internal_utils.cpython-312.pyc | Bin 0 -> 2044 bytes .../__pycache__/adapters.cpython-312.pyc | Bin 0 -> 28451 bytes .../requests/__pycache__/api.cpython-312.pyc | Bin 0 -> 7211 bytes .../requests/__pycache__/auth.cpython-312.pyc | Bin 0 -> 13941 bytes .../__pycache__/certs.cpython-312.pyc | Bin 0 -> 942 bytes .../__pycache__/compat.cpython-312.pyc | Bin 0 -> 1697 bytes .../__pycache__/cookies.cpython-312.pyc | Bin 0 -> 25218 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7618 bytes .../requests/__pycache__/help.cpython-312.pyc | Bin 0 -> 4248 bytes .../__pycache__/hooks.cpython-312.pyc | Bin 0 -> 1071 bytes .../__pycache__/models.cpython-312.pyc | Bin 0 -> 35448 bytes .../__pycache__/packages.cpython-312.pyc | Bin 0 -> 1286 bytes .../__pycache__/sessions.cpython-312.pyc | Bin 0 -> 27866 bytes .../__pycache__/status_codes.cpython-312.pyc | Bin 0 -> 6043 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 5643 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 36386 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 50 + .../pip/_vendor/requests/adapters.py | 719 ++ .../site-packages/pip/_vendor/requests/api.py | 157 + .../pip/_vendor/requests/auth.py | 314 + .../pip/_vendor/requests/certs.py | 24 + .../pip/_vendor/requests/compat.py | 78 + .../pip/_vendor/requests/cookies.py | 561 ++ .../pip/_vendor/requests/exceptions.py | 151 + .../pip/_vendor/requests/help.py | 127 + .../pip/_vendor/requests/hooks.py | 33 + .../pip/_vendor/requests/models.py | 1037 ++ .../pip/_vendor/requests/packages.py | 25 + .../pip/_vendor/requests/sessions.py | 831 ++ .../pip/_vendor/requests/status_codes.py | 128 + .../pip/_vendor/requests/structures.py | 99 + .../pip/_vendor/requests/utils.py | 1096 +++ .../pip/_vendor/resolvelib/__init__.py | 26 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 654 bytes .../__pycache__/providers.cpython-312.pyc | Bin 0 -> 6871 bytes .../__pycache__/reporters.cpython-312.pyc | Bin 0 -> 2674 bytes .../__pycache__/resolvers.cpython-312.pyc | Bin 0 -> 25900 bytes .../__pycache__/structs.cpython-312.pyc | Bin 0 -> 10520 bytes .../pip/_vendor/resolvelib/compat/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 220 bytes .../collections_abc.cpython-312.pyc | Bin 0 -> 440 bytes .../resolvelib/compat/collections_abc.py | 6 + .../pip/_vendor/resolvelib/providers.py | 133 + .../pip/_vendor/resolvelib/py.typed | 0 .../pip/_vendor/resolvelib/reporters.py | 43 + .../pip/_vendor/resolvelib/resolvers.py | 547 ++ .../pip/_vendor/resolvelib/structs.py | 170 + .../pip/_vendor/rich/__init__.py | 177 + .../pip/_vendor/rich/__main__.py | 273 + .../rich/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 7035 bytes .../rich/__pycache__/__main__.cpython-312.pyc | Bin 0 -> 10312 bytes .../__pycache__/_cell_widths.cpython-312.pyc | Bin 0 -> 7892 bytes .../__pycache__/_emoji_codes.cpython-312.pyc | Bin 0 -> 205996 bytes .../_emoji_replace.cpython-312.pyc | Bin 0 -> 1749 bytes .../_export_format.cpython-312.pyc | Bin 0 -> 2369 bytes .../__pycache__/_extension.cpython-312.pyc | Bin 0 -> 557 bytes .../rich/__pycache__/_fileno.cpython-312.pyc | Bin 0 -> 875 bytes .../rich/__pycache__/_inspect.cpython-312.pyc | Bin 0 -> 12093 bytes .../__pycache__/_log_render.cpython-312.pyc | Bin 0 -> 4167 bytes .../rich/__pycache__/_loop.cpython-312.pyc | Bin 0 -> 1890 bytes .../__pycache__/_null_file.cpython-312.pyc | Bin 0 -> 3640 bytes .../__pycache__/_palettes.cpython-312.pyc | Bin 0 -> 5180 bytes .../rich/__pycache__/_pick.cpython-312.pyc | Bin 0 -> 741 bytes .../rich/__pycache__/_ratio.cpython-312.pyc | Bin 0 -> 6590 bytes .../__pycache__/_spinners.cpython-312.pyc | Bin 0 -> 13199 bytes .../rich/__pycache__/_stack.cpython-312.pyc | Bin 0 -> 985 bytes .../rich/__pycache__/_timer.cpython-312.pyc | Bin 0 -> 885 bytes .../_win32_console.cpython-312.pyc | Bin 0 -> 28996 bytes .../rich/__pycache__/_windows.cpython-312.pyc | Bin 0 -> 2510 bytes .../_windows_renderer.cpython-312.pyc | Bin 0 -> 3583 bytes .../rich/__pycache__/_wrap.cpython-312.pyc | Bin 0 -> 3346 bytes .../rich/__pycache__/abc.cpython-312.pyc | Bin 0 -> 1628 bytes .../rich/__pycache__/align.cpython-312.pyc | Bin 0 -> 12307 bytes .../rich/__pycache__/ansi.cpython-312.pyc | Bin 0 -> 9086 bytes .../rich/__pycache__/bar.cpython-312.pyc | Bin 0 -> 4292 bytes .../rich/__pycache__/box.cpython-312.pyc | Bin 0 -> 11858 bytes .../rich/__pycache__/cells.cpython-312.pyc | Bin 0 -> 5830 bytes .../rich/__pycache__/color.cpython-312.pyc | Bin 0 -> 26589 bytes .../__pycache__/color_triplet.cpython-312.pyc | Bin 0 -> 1721 bytes .../rich/__pycache__/columns.cpython-312.pyc | Bin 0 -> 8604 bytes .../rich/__pycache__/console.cpython-312.pyc | Bin 0 -> 113456 bytes .../__pycache__/constrain.cpython-312.pyc | Bin 0 -> 2278 bytes .../__pycache__/containers.cpython-312.pyc | Bin 0 -> 9230 bytes .../rich/__pycache__/control.cpython-312.pyc | Bin 0 -> 10961 bytes .../default_styles.cpython-312.pyc | Bin 0 -> 10386 bytes .../rich/__pycache__/diagnose.cpython-312.pyc | Bin 0 -> 1508 bytes .../rich/__pycache__/emoji.cpython-312.pyc | Bin 0 -> 4232 bytes .../rich/__pycache__/errors.cpython-312.pyc | Bin 0 -> 1865 bytes .../__pycache__/file_proxy.cpython-312.pyc | Bin 0 -> 3591 bytes .../rich/__pycache__/filesize.cpython-312.pyc | Bin 0 -> 3092 bytes .../__pycache__/highlighter.cpython-312.pyc | Bin 0 -> 9907 bytes .../rich/__pycache__/json.cpython-312.pyc | Bin 0 -> 6055 bytes .../rich/__pycache__/jupyter.cpython-312.pyc | Bin 0 -> 5228 bytes .../rich/__pycache__/layout.cpython-312.pyc | Bin 0 -> 20178 bytes .../rich/__pycache__/live.cpython-312.pyc | Bin 0 -> 19029 bytes .../__pycache__/live_render.cpython-312.pyc | Bin 0 -> 4909 bytes .../rich/__pycache__/logging.cpython-312.pyc | Bin 0 -> 13574 bytes .../rich/__pycache__/markup.cpython-312.pyc | Bin 0 -> 9587 bytes .../rich/__pycache__/measure.cpython-312.pyc | Bin 0 -> 6398 bytes .../rich/__pycache__/padding.cpython-312.pyc | Bin 0 -> 7144 bytes .../rich/__pycache__/pager.cpython-312.pyc | Bin 0 -> 1831 bytes .../rich/__pycache__/palette.cpython-312.pyc | Bin 0 -> 5317 bytes .../rich/__pycache__/panel.cpython-312.pyc | Bin 0 -> 12203 bytes .../rich/__pycache__/pretty.cpython-312.pyc | Bin 0 -> 40167 bytes .../rich/__pycache__/progress.cpython-312.pyc | Bin 0 -> 74955 bytes .../__pycache__/progress_bar.cpython-312.pyc | Bin 0 -> 10397 bytes .../rich/__pycache__/prompt.cpython-312.pyc | Bin 0 -> 14807 bytes .../rich/__pycache__/protocol.cpython-312.pyc | Bin 0 -> 1812 bytes .../rich/__pycache__/region.cpython-312.pyc | Bin 0 -> 587 bytes .../rich/__pycache__/repr.cpython-312.pyc | Bin 0 -> 6633 bytes .../rich/__pycache__/rule.cpython-312.pyc | Bin 0 -> 6588 bytes .../rich/__pycache__/scope.cpython-312.pyc | Bin 0 -> 3845 bytes .../rich/__pycache__/screen.cpython-312.pyc | Bin 0 -> 2499 bytes .../rich/__pycache__/segment.cpython-312.pyc | Bin 0 -> 28135 bytes .../rich/__pycache__/spinner.cpython-312.pyc | Bin 0 -> 6084 bytes .../rich/__pycache__/status.cpython-312.pyc | Bin 0 -> 6081 bytes .../rich/__pycache__/style.cpython-312.pyc | Bin 0 -> 33520 bytes .../rich/__pycache__/styled.cpython-312.pyc | Bin 0 -> 2159 bytes .../rich/__pycache__/syntax.cpython-312.pyc | Bin 0 -> 39968 bytes .../rich/__pycache__/table.cpython-312.pyc | Bin 0 -> 43559 bytes .../terminal_theme.cpython-312.pyc | Bin 0 -> 3368 bytes .../rich/__pycache__/text.cpython-312.pyc | Bin 0 -> 60869 bytes .../rich/__pycache__/theme.cpython-312.pyc | Bin 0 -> 6355 bytes .../rich/__pycache__/themes.cpython-312.pyc | Bin 0 -> 334 bytes .../__pycache__/traceback.cpython-312.pyc | Bin 0 -> 31531 bytes .../rich/__pycache__/tree.cpython-312.pyc | Bin 0 -> 11456 bytes .../pip/_vendor/rich/_cell_widths.py | 454 + .../pip/_vendor/rich/_emoji_codes.py | 3610 +++++++ .../pip/_vendor/rich/_emoji_replace.py | 32 + .../pip/_vendor/rich/_export_format.py | 76 + .../pip/_vendor/rich/_extension.py | 10 + .../site-packages/pip/_vendor/rich/_fileno.py | 24 + .../pip/_vendor/rich/_inspect.py | 270 + .../pip/_vendor/rich/_log_render.py | 94 + .../site-packages/pip/_vendor/rich/_loop.py | 43 + .../pip/_vendor/rich/_null_file.py | 69 + .../pip/_vendor/rich/_palettes.py | 309 + .../site-packages/pip/_vendor/rich/_pick.py | 17 + .../site-packages/pip/_vendor/rich/_ratio.py | 159 + .../pip/_vendor/rich/_spinners.py | 482 + .../site-packages/pip/_vendor/rich/_stack.py | 16 + .../site-packages/pip/_vendor/rich/_timer.py | 19 + .../pip/_vendor/rich/_win32_console.py | 662 ++ .../pip/_vendor/rich/_windows.py | 71 + .../pip/_vendor/rich/_windows_renderer.py | 56 + .../site-packages/pip/_vendor/rich/_wrap.py | 93 + .../site-packages/pip/_vendor/rich/abc.py | 33 + .../site-packages/pip/_vendor/rich/align.py | 311 + .../site-packages/pip/_vendor/rich/ansi.py | 240 + .../site-packages/pip/_vendor/rich/bar.py | 93 + .../site-packages/pip/_vendor/rich/box.py | 480 + .../site-packages/pip/_vendor/rich/cells.py | 167 + .../site-packages/pip/_vendor/rich/color.py | 621 ++ .../pip/_vendor/rich/color_triplet.py | 38 + .../site-packages/pip/_vendor/rich/columns.py | 187 + .../site-packages/pip/_vendor/rich/console.py | 2633 +++++ .../pip/_vendor/rich/constrain.py | 37 + .../pip/_vendor/rich/containers.py | 167 + .../site-packages/pip/_vendor/rich/control.py | 225 + .../pip/_vendor/rich/default_styles.py | 190 + .../pip/_vendor/rich/diagnose.py | 37 + .../site-packages/pip/_vendor/rich/emoji.py | 96 + .../site-packages/pip/_vendor/rich/errors.py | 34 + .../pip/_vendor/rich/file_proxy.py | 57 + .../pip/_vendor/rich/filesize.py | 89 + .../pip/_vendor/rich/highlighter.py | 232 + .../site-packages/pip/_vendor/rich/json.py | 139 + .../site-packages/pip/_vendor/rich/jupyter.py | 101 + .../site-packages/pip/_vendor/rich/layout.py | 442 + .../site-packages/pip/_vendor/rich/live.py | 375 + .../pip/_vendor/rich/live_render.py | 112 + .../site-packages/pip/_vendor/rich/logging.py | 289 + .../site-packages/pip/_vendor/rich/markup.py | 251 + .../site-packages/pip/_vendor/rich/measure.py | 151 + .../site-packages/pip/_vendor/rich/padding.py | 141 + .../site-packages/pip/_vendor/rich/pager.py | 34 + .../site-packages/pip/_vendor/rich/palette.py | 100 + .../site-packages/pip/_vendor/rich/panel.py | 312 + .../site-packages/pip/_vendor/rich/pretty.py | 995 ++ .../pip/_vendor/rich/progress.py | 1699 ++++ .../pip/_vendor/rich/progress_bar.py | 223 + .../site-packages/pip/_vendor/rich/prompt.py | 375 + .../pip/_vendor/rich/protocol.py | 42 + .../site-packages/pip/_vendor/rich/py.typed | 0 .../site-packages/pip/_vendor/rich/region.py | 10 + .../site-packages/pip/_vendor/rich/repr.py | 149 + .../site-packages/pip/_vendor/rich/rule.py | 130 + .../site-packages/pip/_vendor/rich/scope.py | 86 + .../site-packages/pip/_vendor/rich/screen.py | 54 + .../site-packages/pip/_vendor/rich/segment.py | 738 ++ .../site-packages/pip/_vendor/rich/spinner.py | 137 + .../site-packages/pip/_vendor/rich/status.py | 131 + .../site-packages/pip/_vendor/rich/style.py | 796 ++ .../site-packages/pip/_vendor/rich/styled.py | 42 + .../site-packages/pip/_vendor/rich/syntax.py | 958 ++ .../site-packages/pip/_vendor/rich/table.py | 1000 ++ .../pip/_vendor/rich/terminal_theme.py | 153 + .../site-packages/pip/_vendor/rich/text.py | 1357 +++ .../site-packages/pip/_vendor/rich/theme.py | 115 + .../site-packages/pip/_vendor/rich/themes.py | 5 + .../pip/_vendor/rich/traceback.py | 753 ++ .../site-packages/pip/_vendor/rich/tree.py | 249 + .../pip/_vendor/tomli/__init__.py | 11 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 404 bytes .../tomli/__pycache__/_parser.cpython-312.pyc | Bin 0 -> 26919 bytes .../tomli/__pycache__/_re.cpython-312.pyc | Bin 0 -> 3928 bytes .../tomli/__pycache__/_types.cpython-312.pyc | Bin 0 -> 386 bytes .../pip/_vendor/tomli/_parser.py | 691 ++ .../site-packages/pip/_vendor/tomli/_re.py | 107 + .../site-packages/pip/_vendor/tomli/_types.py | 10 + .../site-packages/pip/_vendor/tomli/py.typed | 1 + .../pip/_vendor/truststore/__init__.py | 13 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 638 bytes .../__pycache__/_api.cpython-312.pyc | Bin 0 -> 16560 bytes .../__pycache__/_macos.cpython-312.pyc | Bin 0 -> 16592 bytes .../__pycache__/_openssl.cpython-312.pyc | Bin 0 -> 2225 bytes .../_ssl_constants.cpython-312.pyc | Bin 0 -> 1119 bytes .../__pycache__/_windows.cpython-312.pyc | Bin 0 -> 15760 bytes .../pip/_vendor/truststore/_api.py | 313 + .../pip/_vendor/truststore/_macos.py | 499 + .../pip/_vendor/truststore/_openssl.py | 66 + .../pip/_vendor/truststore/_ssl_constants.py | 31 + .../pip/_vendor/truststore/_windows.py | 564 ++ .../pip/_vendor/truststore/py.typed | 0 .../pip/_vendor/typing_extensions.py | 3641 +++++++ .../pip/_vendor/urllib3/__init__.py | 102 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3425 bytes .../__pycache__/_collections.cpython-312.pyc | Bin 0 -> 16384 bytes .../__pycache__/_version.cpython-312.pyc | Bin 0 -> 238 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 20423 bytes .../connectionpool.cpython-312.pyc | Bin 0 -> 36457 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 13513 bytes .../__pycache__/fields.cpython-312.pyc | Bin 0 -> 10422 bytes .../__pycache__/filepost.cpython-312.pyc | Bin 0 -> 4032 bytes .../__pycache__/poolmanager.cpython-312.pyc | Bin 0 -> 20449 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 7314 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 33963 bytes .../pip/_vendor/urllib3/_collections.py | 355 + .../pip/_vendor/urllib3/_version.py | 2 + .../pip/_vendor/urllib3/connection.py | 572 ++ .../pip/_vendor/urllib3/connectionpool.py | 1137 +++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 218 bytes .../_appengine_environ.cpython-312.pyc | Bin 0 -> 1868 bytes .../__pycache__/appengine.cpython-312.pyc | Bin 0 -> 11584 bytes .../__pycache__/ntlmpool.cpython-312.pyc | Bin 0 -> 5734 bytes .../__pycache__/pyopenssl.cpython-312.pyc | Bin 0 -> 24468 bytes .../securetransport.cpython-312.pyc | Bin 0 -> 35521 bytes .../contrib/__pycache__/socks.cpython-312.pyc | Bin 0 -> 7531 bytes .../urllib3/contrib/_appengine_environ.py | 36 + .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 235 bytes .../__pycache__/bindings.cpython-312.pyc | Bin 0 -> 17447 bytes .../__pycache__/low_level.cpython-312.pyc | Bin 0 -> 14783 bytes .../contrib/_securetransport/bindings.py | 519 + .../contrib/_securetransport/low_level.py | 397 + .../pip/_vendor/urllib3/contrib/appengine.py | 314 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 130 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 518 + .../urllib3/contrib/securetransport.py | 920 ++ .../pip/_vendor/urllib3/contrib/socks.py | 216 + .../pip/_vendor/urllib3/exceptions.py | 323 + .../pip/_vendor/urllib3/fields.py | 274 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 219 bytes .../packages/__pycache__/six.cpython-312.pyc | Bin 0 -> 41275 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 229 bytes .../__pycache__/makefile.cpython-312.pyc | Bin 0 -> 1845 bytes .../weakref_finalize.cpython-312.pyc | Bin 0 -> 7356 bytes .../urllib3/packages/backports/makefile.py | 51 + .../packages/backports/weakref_finalize.py | 155 + .../pip/_vendor/urllib3/packages/six.py | 1076 +++ .../pip/_vendor/urllib3/poolmanager.py | 540 ++ .../pip/_vendor/urllib3/request.py | 191 + .../pip/_vendor/urllib3/response.py | 879 ++ .../pip/_vendor/urllib3/util/__init__.py | 49 + .../util/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 1166 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 4767 bytes .../util/__pycache__/proxy.cpython-312.pyc | Bin 0 -> 1572 bytes .../util/__pycache__/queue.cpython-312.pyc | Bin 0 -> 1372 bytes .../util/__pycache__/request.cpython-312.pyc | Bin 0 -> 4203 bytes .../util/__pycache__/response.cpython-312.pyc | Bin 0 -> 3012 bytes .../util/__pycache__/retry.cpython-312.pyc | Bin 0 -> 21721 bytes .../util/__pycache__/ssl_.cpython-312.pyc | Bin 0 -> 15104 bytes .../ssl_match_hostname.cpython-312.pyc | Bin 0 -> 5071 bytes .../__pycache__/ssltransport.cpython-312.pyc | Bin 0 -> 10773 bytes .../util/__pycache__/timeout.cpython-312.pyc | Bin 0 -> 11159 bytes .../util/__pycache__/url.cpython-312.pyc | Bin 0 -> 15805 bytes .../util/__pycache__/wait.cpython-312.pyc | Bin 0 -> 4423 bytes .../pip/_vendor/urllib3/util/connection.py | 149 + .../pip/_vendor/urllib3/util/proxy.py | 57 + .../pip/_vendor/urllib3/util/queue.py | 22 + .../pip/_vendor/urllib3/util/request.py | 137 + .../pip/_vendor/urllib3/util/response.py | 107 + .../pip/_vendor/urllib3/util/retry.py | 620 ++ .../pip/_vendor/urllib3/util/ssl_.py | 495 + .../urllib3/util/ssl_match_hostname.py | 159 + .../pip/_vendor/urllib3/util/ssltransport.py | 221 + .../pip/_vendor/urllib3/util/timeout.py | 271 + .../pip/_vendor/urllib3/util/url.py | 435 + .../pip/_vendor/urllib3/util/wait.py | 152 + .../site-packages/pip/_vendor/vendor.txt | 18 + .../lib/python3.12/site-packages/pip/py.typed | 4 + .../websockets-14.1.dist-info/INSTALLER | 1 + .../websockets-14.1.dist-info/LICENSE | 24 + .../websockets-14.1.dist-info/METADATA | 176 + .../websockets-14.1.dist-info/RECORD | 99 + .../websockets-14.1.dist-info/REQUESTED | 0 .../websockets-14.1.dist-info/WHEEL | 8 + .../websockets-14.1.dist-info/top_level.txt | 1 + .../site-packages/websockets/__init__.py | 172 + .../site-packages/websockets/__main__.py | 159 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 3343 bytes .../__pycache__/__main__.cpython-312.pyc | Bin 0 -> 6145 bytes .../__pycache__/auth.cpython-312.pyc | Bin 0 -> 814 bytes .../__pycache__/client.cpython-312.pyc | Bin 0 -> 16083 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 570 bytes .../datastructures.cpython-312.pyc | Bin 0 -> 8924 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 15939 bytes .../__pycache__/frames.cpython-312.pyc | Bin 0 -> 16020 bytes .../__pycache__/headers.cpython-312.pyc | Bin 0 -> 18029 bytes .../__pycache__/http.cpython-312.pyc | Bin 0 -> 926 bytes .../__pycache__/http11.cpython-312.pyc | Bin 0 -> 13849 bytes .../__pycache__/imports.cpython-312.pyc | Bin 0 -> 3425 bytes .../__pycache__/protocol.cpython-312.pyc | Bin 0 -> 25412 bytes .../__pycache__/server.cpython-312.pyc | Bin 0 -> 22492 bytes .../__pycache__/streams.cpython-312.pyc | Bin 0 -> 5464 bytes .../__pycache__/typing.cpython-312.pyc | Bin 0 -> 1286 bytes .../__pycache__/uri.cpython-312.pyc | Bin 0 -> 4185 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 2247 bytes .../__pycache__/version.cpython-312.pyc | Bin 0 -> 2993 bytes .../websockets/asyncio/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 209 bytes .../__pycache__/async_timeout.cpython-312.pyc | Bin 0 -> 10650 bytes .../__pycache__/client.cpython-312.pyc | Bin 0 -> 22757 bytes .../__pycache__/compatibility.cpython-312.pyc | Bin 0 -> 1085 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 50889 bytes .../__pycache__/messages.cpython-312.pyc | Bin 0 -> 12585 bytes .../__pycache__/server.cpython-312.pyc | Bin 0 -> 38964 bytes .../websockets/asyncio/async_timeout.py | 282 + .../websockets/asyncio/client.py | 565 ++ .../websockets/asyncio/compatibility.py | 30 + .../websockets/asyncio/connection.py | 1221 +++ .../websockets/asyncio/messages.py | 296 + .../websockets/asyncio/server.py | 975 ++ .../site-packages/websockets/auth.py | 18 + .../site-packages/websockets/client.py | 400 + .../site-packages/websockets/connection.py | 12 + .../websockets/datastructures.py | 183 + .../site-packages/websockets/exceptions.py | 418 + .../websockets/extensions/__init__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 324 bytes .../__pycache__/base.cpython-312.pyc | Bin 0 -> 3959 bytes .../permessage_deflate.cpython-312.pyc | Bin 0 -> 19419 bytes .../websockets/extensions/base.py | 123 + .../extensions/permessage_deflate.py | 697 ++ .../site-packages/websockets/frames.py | 429 + .../site-packages/websockets/headers.py | 580 ++ .../site-packages/websockets/http.py | 20 + .../site-packages/websockets/http11.py | 386 + .../site-packages/websockets/imports.py | 100 + .../websockets/legacy/__init__.py | 11 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 494 bytes .../legacy/__pycache__/auth.cpython-312.pyc | Bin 0 -> 7709 bytes .../legacy/__pycache__/client.cpython-312.pyc | Bin 0 -> 27863 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 3559 bytes .../__pycache__/framing.cpython-312.pyc | Bin 0 -> 8204 bytes .../__pycache__/handshake.cpython-312.pyc | Bin 0 -> 6353 bytes .../legacy/__pycache__/http.cpython-312.pyc | Bin 0 -> 7711 bytes .../__pycache__/protocol.cpython-312.pyc | Bin 0 -> 64015 bytes .../legacy/__pycache__/server.cpython-312.pyc | Bin 0 -> 46706 bytes .../site-packages/websockets/legacy/auth.py | 190 + .../site-packages/websockets/legacy/client.py | 704 ++ .../websockets/legacy/exceptions.py | 78 + .../websockets/legacy/framing.py | 225 + .../websockets/legacy/handshake.py | 158 + .../site-packages/websockets/legacy/http.py | 201 + .../websockets/legacy/protocol.py | 1641 ++++ .../site-packages/websockets/legacy/server.py | 1190 +++ .../site-packages/websockets/protocol.py | 758 ++ .../site-packages/websockets/py.typed | 0 .../site-packages/websockets/server.py | 590 ++ .../site-packages/websockets/speedups.c | 222 + .../speedups.cpython-312-x86_64-linux-gnu.so | Bin 0 -> 35968 bytes .../site-packages/websockets/speedups.pyi | 1 + .../site-packages/websockets/streams.py | 151 + .../site-packages/websockets/sync/__init__.py | 0 .../sync/__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../sync/__pycache__/client.cpython-312.pyc | Bin 0 -> 12840 bytes .../__pycache__/connection.cpython-312.pyc | Bin 0 -> 34354 bytes .../sync/__pycache__/messages.cpython-312.pyc | Bin 0 -> 11960 bytes .../sync/__pycache__/server.cpython-312.pyc | Bin 0 -> 27577 bytes .../sync/__pycache__/utils.cpython-312.pyc | Bin 0 -> 1675 bytes .../site-packages/websockets/sync/client.py | 348 + .../websockets/sync/connection.py | 931 ++ .../site-packages/websockets/sync/messages.py | 306 + .../site-packages/websockets/sync/server.py | 744 ++ .../site-packages/websockets/sync/utils.py | 45 + .../site-packages/websockets/typing.py | 75 + .../site-packages/websockets/uri.py | 107 + .../site-packages/websockets/utils.py | 51 + .../site-packages/websockets/version.py | 92 + .../werkzeug-3.1.3.dist-info/INSTALLER | 1 + .../werkzeug-3.1.3.dist-info/LICENSE.txt | 28 + .../werkzeug-3.1.3.dist-info/METADATA | 99 + .../werkzeug-3.1.3.dist-info/RECORD | 116 + .../werkzeug-3.1.3.dist-info/WHEEL | 4 + .../site-packages/werkzeug/__init__.py | 4 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 353 bytes .../__pycache__/_internal.cpython-312.pyc | Bin 0 -> 9776 bytes .../__pycache__/_reloader.cpython-312.pyc | Bin 0 -> 20566 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 33337 bytes .../__pycache__/formparser.cpython-312.pyc | Bin 0 -> 17034 bytes .../werkzeug/__pycache__/http.cpython-312.pyc | Bin 0 -> 50225 bytes .../__pycache__/local.cpython-312.pyc | Bin 0 -> 28477 bytes .../__pycache__/security.cpython-312.pyc | Bin 0 -> 7144 bytes .../__pycache__/serving.cpython-312.pyc | Bin 0 -> 46102 bytes .../werkzeug/__pycache__/test.cpython-312.pyc | Bin 0 -> 59825 bytes .../__pycache__/testapp.cpython-312.pyc | Bin 0 -> 8876 bytes .../werkzeug/__pycache__/urls.cpython-312.pyc | Bin 0 -> 8277 bytes .../__pycache__/user_agent.cpython-312.pyc | Bin 0 -> 2166 bytes .../__pycache__/utils.cpython-312.pyc | Bin 0 -> 28145 bytes .../werkzeug/__pycache__/wsgi.cpython-312.pyc | Bin 0 -> 25222 bytes .../site-packages/werkzeug/_internal.py | 211 + .../site-packages/werkzeug/_reloader.py | 471 + .../werkzeug/datastructures/__init__.py | 64 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 2430 bytes .../__pycache__/accept.cpython-312.pyc | Bin 0 -> 15930 bytes .../__pycache__/auth.cpython-312.pyc | Bin 0 -> 14463 bytes .../__pycache__/cache_control.cpython-312.pyc | Bin 0 -> 12236 bytes .../__pycache__/csp.cpython-312.pyc | Bin 0 -> 6199 bytes .../__pycache__/etag.cpython-312.pyc | Bin 0 -> 5423 bytes .../__pycache__/file_storage.cpython-312.pyc | Bin 0 -> 8837 bytes .../__pycache__/headers.cpython-312.pyc | Bin 0 -> 30470 bytes .../__pycache__/mixins.cpython-312.pyc | Bin 0 -> 16413 bytes .../__pycache__/range.cpython-312.pyc | Bin 0 -> 10056 bytes .../__pycache__/structures.cpython-312.pyc | Bin 0 -> 58951 bytes .../werkzeug/datastructures/accept.py | 350 + .../werkzeug/datastructures/auth.py | 317 + .../werkzeug/datastructures/cache_control.py | 273 + .../werkzeug/datastructures/csp.py | 100 + .../werkzeug/datastructures/etag.py | 106 + .../werkzeug/datastructures/file_storage.py | 209 + .../werkzeug/datastructures/headers.py | 662 ++ .../werkzeug/datastructures/mixins.py | 317 + .../werkzeug/datastructures/range.py | 214 + .../werkzeug/datastructures/structures.py | 1239 +++ .../site-packages/werkzeug/debug/__init__.py | 565 ++ .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 23420 bytes .../debug/__pycache__/console.cpython-312.pyc | Bin 0 -> 11645 bytes .../debug/__pycache__/repr.cpython-312.pyc | Bin 0 -> 13787 bytes .../debug/__pycache__/tbtools.cpython-312.pyc | Bin 0 -> 16988 bytes .../site-packages/werkzeug/debug/console.py | 219 + .../site-packages/werkzeug/debug/repr.py | 282 + .../werkzeug/debug/shared/ICON_LICENSE.md | 6 + .../werkzeug/debug/shared/console.png | Bin 0 -> 507 bytes .../werkzeug/debug/shared/debugger.js | 344 + .../werkzeug/debug/shared/less.png | Bin 0 -> 191 bytes .../werkzeug/debug/shared/more.png | Bin 0 -> 200 bytes .../werkzeug/debug/shared/style.css | 150 + .../site-packages/werkzeug/debug/tbtools.py | 450 + .../site-packages/werkzeug/exceptions.py | 894 ++ .../site-packages/werkzeug/formparser.py | 430 + .../python3.12/site-packages/werkzeug/http.py | 1405 +++ .../site-packages/werkzeug/local.py | 653 ++ .../werkzeug/middleware/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 210 bytes .../__pycache__/dispatcher.cpython-312.pyc | Bin 0 -> 3328 bytes .../__pycache__/http_proxy.cpython-312.pyc | Bin 0 -> 9424 bytes .../__pycache__/lint.cpython-312.pyc | Bin 0 -> 17770 bytes .../__pycache__/profiler.cpython-312.pyc | Bin 0 -> 7214 bytes .../__pycache__/proxy_fix.cpython-312.pyc | Bin 0 -> 7211 bytes .../__pycache__/shared_data.cpython-312.pyc | Bin 0 -> 12746 bytes .../werkzeug/middleware/dispatcher.py | 81 + .../werkzeug/middleware/http_proxy.py | 236 + .../site-packages/werkzeug/middleware/lint.py | 439 + .../werkzeug/middleware/profiler.py | 155 + .../werkzeug/middleware/proxy_fix.py | 183 + .../werkzeug/middleware/shared_data.py | 283 + .../site-packages/werkzeug/py.typed | 0 .../werkzeug/routing/__init__.py | 134 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 4683 bytes .../__pycache__/converters.cpython-312.pyc | Bin 0 -> 10930 bytes .../__pycache__/exceptions.cpython-312.pyc | Bin 0 -> 7926 bytes .../routing/__pycache__/map.cpython-312.pyc | Bin 0 -> 39811 bytes .../__pycache__/matcher.cpython-312.pyc | Bin 0 -> 8249 bytes .../routing/__pycache__/rules.cpython-312.pyc | Bin 0 -> 39095 bytes .../werkzeug/routing/converters.py | 261 + .../werkzeug/routing/exceptions.py | 152 + .../site-packages/werkzeug/routing/map.py | 951 ++ .../site-packages/werkzeug/routing/matcher.py | 202 + .../site-packages/werkzeug/routing/rules.py | 928 ++ .../site-packages/werkzeug/sansio/__init__.py | 0 .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 206 bytes .../sansio/__pycache__/http.cpython-312.pyc | Bin 0 -> 5652 bytes .../__pycache__/multipart.cpython-312.pyc | Bin 0 -> 14055 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 21899 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 31743 bytes .../sansio/__pycache__/utils.cpython-312.pyc | Bin 0 -> 6191 bytes .../site-packages/werkzeug/sansio/http.py | 170 + .../werkzeug/sansio/multipart.py | 323 + .../site-packages/werkzeug/sansio/request.py | 534 + .../site-packages/werkzeug/sansio/response.py | 763 ++ .../site-packages/werkzeug/sansio/utils.py | 167 + .../site-packages/werkzeug/security.py | 166 + .../site-packages/werkzeug/serving.py | 1125 +++ .../python3.12/site-packages/werkzeug/test.py | 1464 +++ .../site-packages/werkzeug/testapp.py | 194 + .../python3.12/site-packages/werkzeug/urls.py | 203 + .../site-packages/werkzeug/user_agent.py | 47 + .../site-packages/werkzeug/utils.py | 691 ++ .../werkzeug/wrappers/__init__.py | 3 + .../__pycache__/__init__.cpython-312.pyc | Bin 0 -> 330 bytes .../__pycache__/request.cpython-312.pyc | Bin 0 -> 26139 bytes .../__pycache__/response.cpython-312.pyc | Bin 0 -> 34571 bytes .../werkzeug/wrappers/request.py | 650 ++ .../werkzeug/wrappers/response.py | 831 ++ .../python3.12/site-packages/werkzeug/wsgi.py | 595 ++ venv/lib64 | 1 + venv/pyvenv.cfg | 5 + 1511 files changed, 248810 insertions(+), 2 deletions(-) create mode 100644 __pycache__/screen.cpython-312.pyc create mode 100644 venv/bin/Activate.ps1 create mode 100644 venv/bin/activate create mode 100644 venv/bin/activate.csh create mode 100644 venv/bin/activate.fish create mode 100755 venv/bin/flask create mode 100755 venv/bin/pip create mode 100755 venv/bin/pip3 create mode 100755 venv/bin/pip3.12 create mode 120000 venv/bin/python create mode 120000 venv/bin/python3 create mode 120000 venv/bin/python3.12 create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/PIL/BdfFontFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/BlpImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/BmpImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/BufrStubImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ContainerIO.py create mode 100644 venv/lib/python3.12/site-packages/PIL/CurImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/DcxImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/DdsImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/EpsImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ExifTags.py create mode 100644 venv/lib/python3.12/site-packages/PIL/FitsImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/FliImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/FontFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/FpxImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/FtexImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GbrImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GdImageFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GifImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GimpGradientFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GimpPaletteFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/GribStubImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/Hdf5StubImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/IcnsImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/IcoImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/Image.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageChops.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageCms.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageColor.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageDraw.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageDraw2.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageEnhance.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageFilter.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageFont.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageGrab.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageMath.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageMode.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageMorph.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageOps.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImagePalette.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImagePath.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageQt.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageSequence.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageShow.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageStat.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageTk.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageTransform.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImageWin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/ImtImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/IptcImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/Jpeg2KImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/JpegImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/JpegPresets.py create mode 100644 venv/lib/python3.12/site-packages/PIL/McIdasImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/MicImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/MpegImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/MpoImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/MspImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PSDraw.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PaletteFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PalmImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PcdImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PcfFontFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PcxImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PdfImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PdfParser.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PixarImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PngImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PpmImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/PsdImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/QoiImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/SgiImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/SpiderImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/SunImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/TarIO.py create mode 100644 venv/lib/python3.12/site-packages/PIL/TgaImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/TiffImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/TiffTags.py create mode 100644 venv/lib/python3.12/site-packages/PIL/WalImageFile.py create mode 100644 venv/lib/python3.12/site-packages/PIL/WebPImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/WmfImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/XVThumbImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/XbmImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/XpmImagePlugin.py create mode 100644 venv/lib/python3.12/site-packages/PIL/__init__.py create mode 100644 venv/lib/python3.12/site-packages/PIL/__main__.py create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/BdfFontFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/BlpImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/BmpImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ContainerIO.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/CurImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/DcxImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/DdsImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/EpsImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ExifTags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/FitsImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/FliImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/FontFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/FpxImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/FtexImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GbrImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GdImageFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GifImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GimpGradientFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GimpPaletteFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/IcnsImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/IcoImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/Image.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageChops.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageCms.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageColor.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw2.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageEnhance.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageFilter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageFont.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageGrab.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageMath.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageMode.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageMorph.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageOps.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePalette.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePath.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageQt.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageSequence.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageShow.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageStat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTk.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTransform.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImageWin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/ImtImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/IptcImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/Jpeg2KImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/JpegImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/JpegPresets.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/McIdasImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/MicImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/MpegImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/MpoImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/MspImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PSDraw.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PaletteFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PalmImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PcdImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PcfFontFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PcxImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PdfImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PdfParser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PixarImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PngImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PpmImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/PsdImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/QoiImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/SgiImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/SpiderImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/SunImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/TarIO.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/TgaImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/TiffImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/TiffTags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/WalImageFile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/WebPImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/WmfImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/XVThumbImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/XbmImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/XpmImagePlugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_binary.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_deprecate.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_tkinter_finder.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_typing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/_version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/features.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/__pycache__/report.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/PIL/_binary.py create mode 100644 venv/lib/python3.12/site-packages/PIL/_deprecate.py create mode 100755 venv/lib/python3.12/site-packages/PIL/_imaging.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imaging.pyi create mode 100755 venv/lib/python3.12/site-packages/PIL/_imagingcms.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imagingcms.pyi create mode 100755 venv/lib/python3.12/site-packages/PIL/_imagingft.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imagingft.pyi create mode 100755 venv/lib/python3.12/site-packages/PIL/_imagingmath.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imagingmath.pyi create mode 100755 venv/lib/python3.12/site-packages/PIL/_imagingmorph.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imagingmorph.pyi create mode 100755 venv/lib/python3.12/site-packages/PIL/_imagingtk.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_imagingtk.pyi create mode 100644 venv/lib/python3.12/site-packages/PIL/_tkinter_finder.py create mode 100644 venv/lib/python3.12/site-packages/PIL/_typing.py create mode 100644 venv/lib/python3.12/site-packages/PIL/_util.py create mode 100644 venv/lib/python3.12/site-packages/PIL/_version.py create mode 100755 venv/lib/python3.12/site-packages/PIL/_webp.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/PIL/_webp.pyi create mode 100644 venv/lib/python3.12/site-packages/PIL/features.py create mode 100644 venv/lib/python3.12/site-packages/PIL/py.typed create mode 100644 venv/lib/python3.12/site-packages/PIL/report.py create mode 100644 venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/blinker/__init__.py create mode 100644 venv/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/blinker/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/blinker/_utilities.py create mode 100644 venv/lib/python3.12/site-packages/blinker/base.py create mode 100644 venv/lib/python3.12/site-packages/blinker/py.typed create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/click/__init__.py create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/termui.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/click/_compat.py create mode 100644 venv/lib/python3.12/site-packages/click/_termui_impl.py create mode 100644 venv/lib/python3.12/site-packages/click/_textwrap.py create mode 100644 venv/lib/python3.12/site-packages/click/_winconsole.py create mode 100644 venv/lib/python3.12/site-packages/click/core.py create mode 100644 venv/lib/python3.12/site-packages/click/decorators.py create mode 100644 venv/lib/python3.12/site-packages/click/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/click/formatting.py create mode 100644 venv/lib/python3.12/site-packages/click/globals.py create mode 100644 venv/lib/python3.12/site-packages/click/parser.py create mode 100644 venv/lib/python3.12/site-packages/click/py.typed create mode 100644 venv/lib/python3.12/site-packages/click/shell_completion.py create mode 100644 venv/lib/python3.12/site-packages/click/termui.py create mode 100644 venv/lib/python3.12/site-packages/click/testing.py create mode 100644 venv/lib/python3.12/site-packages/click/types.py create mode 100644 venv/lib/python3.12/site-packages/click/utils.py create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/flask/__init__.py create mode 100644 venv/lib/python3.12/site-packages/flask/__main__.py create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/app.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/blueprints.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/cli.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/config.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/ctx.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/debughelpers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/globals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/helpers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/signals.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/testing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/typing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/__pycache__/wrappers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/app.py create mode 100644 venv/lib/python3.12/site-packages/flask/blueprints.py create mode 100644 venv/lib/python3.12/site-packages/flask/cli.py create mode 100644 venv/lib/python3.12/site-packages/flask/config.py create mode 100644 venv/lib/python3.12/site-packages/flask/ctx.py create mode 100644 venv/lib/python3.12/site-packages/flask/debughelpers.py create mode 100644 venv/lib/python3.12/site-packages/flask/globals.py create mode 100644 venv/lib/python3.12/site-packages/flask/helpers.py create mode 100644 venv/lib/python3.12/site-packages/flask/json/__init__.py create mode 100644 venv/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/json/__pycache__/tag.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/json/provider.py create mode 100644 venv/lib/python3.12/site-packages/flask/json/tag.py create mode 100644 venv/lib/python3.12/site-packages/flask/logging.py create mode 100644 venv/lib/python3.12/site-packages/flask/py.typed create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/README.md create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/__pycache__/scaffold.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/app.py create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/blueprints.py create mode 100644 venv/lib/python3.12/site-packages/flask/sansio/scaffold.py create mode 100644 venv/lib/python3.12/site-packages/flask/sessions.py create mode 100644 venv/lib/python3.12/site-packages/flask/signals.py create mode 100644 venv/lib/python3.12/site-packages/flask/templating.py create mode 100644 venv/lib/python3.12/site-packages/flask/testing.py create mode 100644 venv/lib/python3.12/site-packages/flask/typing.py create mode 100644 venv/lib/python3.12/site-packages/flask/views.py create mode 100644 venv/lib/python3.12/site-packages/flask/wrappers.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__init__.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/__pycache__/url_safe.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/_json.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/encoding.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/exc.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/py.typed create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/serializer.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/signer.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/timed.py create mode 100644 venv/lib/python3.12/site-packages/itsdangerous/url_safe.py create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/jinja2/__init__.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/debug.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/defaults.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/filters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/lexer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/loaders.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/nodes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/optimizer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/jinja2/_identifier.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/async_utils.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/bccache.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/compiler.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/constants.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/debug.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/defaults.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/environment.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/ext.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/filters.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/idtracking.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/lexer.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/loaders.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/meta.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/nativetypes.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/nodes.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/optimizer.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/parser.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/py.typed create mode 100644 venv/lib/python3.12/site-packages/jinja2/runtime.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/sandbox.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/tests.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/utils.py create mode 100644 venv/lib/python3.12/site-packages/jinja2/visitor.py create mode 100644 venv/lib/python3.12/site-packages/markupsafe/__init__.py create mode 100644 venv/lib/python3.12/site-packages/markupsafe/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/markupsafe/__pycache__/_native.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/markupsafe/_native.py create mode 100644 venv/lib/python3.12/site-packages/markupsafe/_speedups.c create mode 100755 venv/lib/python3.12/site-packages/markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/markupsafe/_speedups.pyi create mode 100644 venv/lib/python3.12/site-packages/markupsafe/py.typed create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/LICENSE create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/pillow-11.0.0.dist-info/zip-safe create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libXau-154567c4.so.6.0.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libbrotlicommon-3ecfe81c.so.1 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libbrotlidec-ba690955.so.1 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libfreetype-e7d5437d.so.6.20.1 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libharfbuzz-144af51e.so.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libjpeg-45e70d75.so.62.4.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/liblcms2-e69eef39.so.2.0.16 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/liblzma-c9407571.so.5.6.3 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libopenjp2-05423b53.so create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libpng16-4cc6a9fc.so.16.44.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libsharpyuv-898c0cb5.so.0.1.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libtiff-0a86184d.so.6.0.2 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libwebp-2fd3cdca.so.7.1.9 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libwebpdemux-f2642bcc.so.2.0.15 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libwebpmux-d524b4d5.so.3.1.0 create mode 100755 venv/lib/python3.12/site-packages/pillow.libs/libxcb-b8a56d01.so.1.1.0 create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/AUTHORS.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/entry_points.txt create mode 100644 venv/lib/python3.12/site-packages/pip-24.2.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/pip/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__pip-runner__.py create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/__pycache__/__pip-runner__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/build_env.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/configuration.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/pyproject.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/self_outdated_check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/__pycache__/wheel_builder.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/build_env.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/command_context.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/index_command.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/progress_bars.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/req_command.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/spinners.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/base_command.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/command_context.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/index_command.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/main.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/main_parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/progress_bars.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/req_command.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/spinners.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/cli/status_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/completion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/debug.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/download.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/hash.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/help.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/inspect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/install.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/list.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/search.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/show.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/completion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/configuration.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/debug.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/download.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/freeze.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/hash.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/help.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/inspect.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/install.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/list.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/search.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/show.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/uninstall.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/commands/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/configuration.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/installed.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/sdist.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/installed.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/sdist.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/distributions/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/collector.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/package_finder.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/__pycache__/sources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/collector.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/package_finder.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/index/sources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_distutils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/_sysconfig.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/_distutils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/_sysconfig.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/locations/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/main.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/_json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/__pycache__/pkg_resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/_json.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_dists.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/__pycache__/_envs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_dists.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/importlib/_envs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/metadata/pkg_resources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/candidate.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/direct_url.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/format_control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/installation_report.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/link.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/scheme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/search_scope.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/selection_prefs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/target_python.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/candidate.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/direct_url.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/format_control.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/installation_report.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/link.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/scheme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/search_scope.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/selection_prefs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/target_python.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/models/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/download.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/lazy_wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/session.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/__pycache__/xmlrpc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/auth.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/download.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/lazy_wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/session.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/network/xmlrpc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/check.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/build_tracker.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_editable.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/metadata_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_editable.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/__pycache__/wheel_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/build_tracker.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_editable.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/metadata_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_editable.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/build/wheel_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/freeze.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/editable_legacy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/editable_legacy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/install/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/operations/prepare.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/pyproject.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/constructors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_file.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_install.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_set.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/constructors.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_file.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_install.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_set.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/__pycache__/resolver.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/legacy/resolver.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/candidates.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/factory.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/found_candidates.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/provider.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/reporter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/requirements.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/__pycache__/resolver.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/base.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/candidates.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/factory.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/provider.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/reporter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/requirements.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/resolution/resolvelib/resolver.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/self_outdated_check.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_jaraco_text.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/_log.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/compatibility_tags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/datetime.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/direct_url_helpers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/egg_link.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/entrypoints.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/filetypes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/misc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/retry.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/subprocess.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/unpacking.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/urls.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/virtualenv.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/_jaraco_text.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/_log.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/appdirs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/compatibility_tags.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/datetime.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/deprecation.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/direct_url_helpers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/egg_link.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/encoding.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/entrypoints.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/filesystem.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/filetypes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/glibc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/hashes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/logging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/misc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/packaging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/retry.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/subprocess.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/unpacking.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/urls.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/virtualenv.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/utils/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/git.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/__pycache__/versioncontrol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/git.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/subversion.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/vcs/versioncontrol.py create mode 100644 venv/lib/python3.12/site-packages/pip/_internal/wheel_builder.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/__pycache__/typing_extensions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/core.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/certifi/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/database.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/index.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/locators.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/markers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/resources.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/t64-arm.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/util.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64-arm.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/__pycache__/distro.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/distro.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/distro/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/core.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/codec.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/core.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/intranges.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/package_data.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/ext.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/ext.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_elffile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/_tokenizer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/metadata.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/tags.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_elffile.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_manylinux.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_musllinux.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/_tokenizer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/markers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/metadata.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/tags.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/packaging/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/android.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/android.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/macos.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/unix.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/platformdirs/windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/cmdline.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/filter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/formatter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/lexer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/modeline.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/plugin.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/regexopt.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/scanner.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/sphinxext.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/style.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/token.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/unistring.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/__pycache__/util.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/cmdline.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/filters/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/_mapping.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/bbcode.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/groff.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/html.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/img.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/irc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/latex.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/other.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/pangomarkup.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/rtf.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/svg.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/__pycache__/terminal256.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/_mapping.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/bbcode.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/groff.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/html.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/img.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/irc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/latex.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/other.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/pangomarkup.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/rtf.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/svg.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/formatters/terminal256.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/_mapping.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/__pycache__/python.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/_mapping.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/lexers/python.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/modeline.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/plugin.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/regexopt.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/scanner.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/sphinxext.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/style.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/__pycache__/_mapping.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/styles/_mapping.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/token.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/unistring.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pygments/util.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/__pycache__/_impl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_impl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/__pycache__/_in_process.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/help.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/models.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/__version__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/adapters.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/auth.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/certs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/compat.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/cookies.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/help.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/hooks.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/models.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/packages.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/sessions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/structures.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/requests/utils.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/providers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/reporters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/resolvers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/__pycache__/structs.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/__pycache__/collections_abc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/compat/collections_abc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/providers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/reporters.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/resolvers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/resolvelib/structs.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__main__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_cell_widths.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_codes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_emoji_replace.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_export_format.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_extension.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_fileno.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_inspect.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_log_render.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_loop.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_null_file.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_palettes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_pick.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_ratio.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_spinners.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_stack.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_timer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_win32_console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_windows_renderer.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/_wrap.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/abc.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/align.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/ansi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/bar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/box.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/cells.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/color_triplet.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/columns.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/constrain.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/containers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/default_styles.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/diagnose.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/emoji.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/errors.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/file_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/filesize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/highlighter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/json.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/jupyter.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/layout.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/live_render.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/logging.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/markup.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/measure.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/padding.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pager.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/palette.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/panel.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/pretty.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/progress_bar.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/prompt.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/protocol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/region.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/repr.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/rule.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/scope.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/screen.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/segment.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/spinner.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/status.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/style.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/styled.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/syntax.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/table.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/terminal_theme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/text.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/theme.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/themes.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/traceback.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/__pycache__/tree.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_cell_widths.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_codes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_emoji_replace.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_export_format.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_extension.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_fileno.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_inspect.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_log_render.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_loop.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_null_file.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_palettes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_pick.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_ratio.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_spinners.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_stack.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_timer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_win32_console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_windows_renderer.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/_wrap.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/abc.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/align.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/ansi.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/bar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/box.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/cells.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/color.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/color_triplet.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/columns.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/console.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/constrain.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/containers.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/control.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/default_styles.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/diagnose.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/emoji.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/errors.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/file_proxy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/filesize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/highlighter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/json.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/jupyter.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/layout.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/live.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/live_render.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/logging.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/markup.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/measure.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/padding.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/pager.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/palette.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/panel.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/pretty.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/progress.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/progress_bar.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/prompt.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/protocol.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/region.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/repr.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/rule.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/scope.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/screen.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/segment.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/spinner.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/status.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/style.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/styled.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/syntax.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/table.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/terminal_theme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/text.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/theme.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/themes.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/traceback.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/rich/tree.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_parser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_re.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/__pycache__/_types.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_parser.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_re.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/_types.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/tomli/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_api.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_macos.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_openssl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_ssl_constants.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/__pycache__/_windows.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_api.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_macos.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_openssl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_ssl_constants.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/_windows.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/truststore/py.typed create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/typing_extensions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/_version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/_version.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/_appengine_environ.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_appengine_environ.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/weakref_finalize.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/backports/weakref_finalize.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/request.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/response.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_match_hostname.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/ssltransport.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/proxy.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/ssltransport.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 venv/lib/python3.12/site-packages/pip/_vendor/vendor.txt create mode 100644 venv/lib/python3.12/site-packages/pip/py.typed create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/LICENSE create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/REQUESTED create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/websockets-14.1.dist-info/top_level.txt create mode 100644 venv/lib/python3.12/site-packages/websockets/__init__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/__main__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/__main__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/client.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/datastructures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/frames.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/headers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/http.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/http11.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/imports.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/protocol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/server.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/streams.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/typing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/uri.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/__pycache__/version.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__init__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/async_timeout.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/client.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/compatibility.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/messages.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/__pycache__/server.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/async_timeout.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/client.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/compatibility.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/connection.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/messages.py create mode 100644 venv/lib/python3.12/site-packages/websockets/asyncio/server.py create mode 100644 venv/lib/python3.12/site-packages/websockets/auth.py create mode 100644 venv/lib/python3.12/site-packages/websockets/client.py create mode 100644 venv/lib/python3.12/site-packages/websockets/connection.py create mode 100644 venv/lib/python3.12/site-packages/websockets/datastructures.py create mode 100644 venv/lib/python3.12/site-packages/websockets/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/__init__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/__pycache__/base.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/__pycache__/permessage_deflate.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/base.py create mode 100644 venv/lib/python3.12/site-packages/websockets/extensions/permessage_deflate.py create mode 100644 venv/lib/python3.12/site-packages/websockets/frames.py create mode 100644 venv/lib/python3.12/site-packages/websockets/headers.py create mode 100644 venv/lib/python3.12/site-packages/websockets/http.py create mode 100644 venv/lib/python3.12/site-packages/websockets/http11.py create mode 100644 venv/lib/python3.12/site-packages/websockets/imports.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__init__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/client.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/framing.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/handshake.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/http.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/protocol.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/__pycache__/server.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/auth.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/client.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/framing.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/handshake.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/http.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/protocol.py create mode 100644 venv/lib/python3.12/site-packages/websockets/legacy/server.py create mode 100644 venv/lib/python3.12/site-packages/websockets/protocol.py create mode 100644 venv/lib/python3.12/site-packages/websockets/py.typed create mode 100644 venv/lib/python3.12/site-packages/websockets/server.py create mode 100644 venv/lib/python3.12/site-packages/websockets/speedups.c create mode 100755 venv/lib/python3.12/site-packages/websockets/speedups.cpython-312-x86_64-linux-gnu.so create mode 100644 venv/lib/python3.12/site-packages/websockets/speedups.pyi create mode 100644 venv/lib/python3.12/site-packages/websockets/streams.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__init__.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/client.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/connection.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/messages.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/server.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/client.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/connection.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/messages.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/server.py create mode 100644 venv/lib/python3.12/site-packages/websockets/sync/utils.py create mode 100644 venv/lib/python3.12/site-packages/websockets/typing.py create mode 100644 venv/lib/python3.12/site-packages/websockets/uri.py create mode 100644 venv/lib/python3.12/site-packages/websockets/utils.py create mode 100644 venv/lib/python3.12/site-packages/websockets/version.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/INSTALLER create mode 100644 venv/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/LICENSE.txt create mode 100644 venv/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/METADATA create mode 100644 venv/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/RECORD create mode 100644 venv/lib/python3.12/site-packages/werkzeug-3.1.3.dist-info/WHEEL create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/_internal.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/_reloader.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/formparser.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/http.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/local.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/security.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/serving.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/test.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/testapp.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/urls.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/user_agent.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/__pycache__/wsgi.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/_internal.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/_reloader.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/accept.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/auth.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/cache_control.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/csp.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/etag.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/file_storage.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/headers.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/mixins.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/range.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/__pycache__/structures.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/accept.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/auth.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/cache_control.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/csp.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/etag.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/file_storage.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/headers.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/mixins.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/range.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/datastructures/structures.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/__pycache__/console.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/__pycache__/repr.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/console.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/repr.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/ICON_LICENSE.md create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/console.png create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/debugger.js create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/less.png create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/more.png create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/shared/style.css create mode 100644 venv/lib/python3.12/site-packages/werkzeug/debug/tbtools.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/formparser.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/http.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/local.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/dispatcher.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/http_proxy.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/lint.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/profiler.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/proxy_fix.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/__pycache__/shared_data.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/dispatcher.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/http_proxy.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/lint.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/profiler.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/proxy_fix.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/middleware/shared_data.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/py.typed create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/converters.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/exceptions.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/map.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/matcher.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/__pycache__/rules.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/converters.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/exceptions.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/map.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/matcher.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/routing/rules.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/http.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/multipart.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/__pycache__/utils.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/http.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/multipart.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/request.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/response.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/sansio/utils.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/security.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/serving.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/test.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/testapp.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/urls.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/user_agent.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/utils.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/__init__.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/__init__.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/request.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/__pycache__/response.cpython-312.pyc create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/request.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wrappers/response.py create mode 100644 venv/lib/python3.12/site-packages/werkzeug/wsgi.py create mode 120000 venv/lib64 create mode 100644 venv/pyvenv.cfg diff --git a/__pycache__/screen.cpython-312.pyc b/__pycache__/screen.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ecebd00180ecca208b1b49673842dc64452fb129 GIT binary patch literal 2696 zcmZt{O>YxNbk@6Guak{qlawR`2U8MJwb3-oAM= z?{j`@X=y?L*D9BCnGiyMvV{+V$83EM%py{e%H>hYrCf@0)`3*Op?r$Rye|1$8&r4f zH`a_xiC9zv({CX}g3j(xN;1MA;~kmc$fT46RLF-5O{r!M1<(bg2Ja$Od>(MErQ`s@ z@^jC0s-?&!LmO;0w!t(uctA;xhDQtO9KJx(nJoM01LrYYy}&FYjF>~<40ji$cr^f6 zPk@fd76YLcB-)aXb1c_Tf3X?ma24Gd!c2?fy5wgX)mh1Kb zJM2sL3YzaISgh|f-rQzIaDvyh%}T_#*Pwe@v19&seV@-Y=mOH)8!MlC5q$3XrFZzU z2K7(jP!T1?v5g-1L=jYBu#R>V zAS)=R0EdBDM363~vI}&ku?u!2i5p7>2+KYVX7i?nNhk1btjGZ-4k?O?^Wb!(?zFQ$ z%JkSq@L7@{w%%*4Nb#~1e<>Xz2SL2!uB>pKyS{LmC5-HPbLjQP038q1fXc&9fMR1+ z18@u4OZRwJ;$j_U*KUAG;aTTcRQB3cZ@9+Z9lJQax$(v4)R1rYR$w8ZxA^h~-TO3E zQo}0uqRID#Lw2jbN00hkgYIobZ)<4yoS#YmUN9o+Q`fGyr_NHk3)E&fh2?h_%!A*) zH4Z&kPs(Fgk^*5la*%c#0Ou+5D`Em3+F0309RGnxUFE zEZUsT=e>rqsB}}+tQk;oY*GHR3+Jey&*0p~DL5d>Q*qKHg|tmW*Jsmt%`VdB8Di!L zwk&N9=iIw)o=HYvIOM31gW2xZE_67arjku&jcnS62?6a4GsK40PtRd0X3`cO8l>UO z&>)O)Q^iz*IWd>c&tk&zNCjIfV3-(rjAw}KT!wV94*{(}Wv!ri2C-_fI!+`KPIr*~ zu$Yf}olze>Z-dnO4iNN4WM3`Tw%GBwW3}h_uYIduWL68;*JGq~t|~_#j^7)v$ceI? zSc$F6N9vN^vfR7!>AHNh+8tj$xpZ;`uXVp$x>S`rD{{On$DgRn=92mILMJ;=PNHtS5uZ!%M@D7uMz8 z%~sUf_Wxe3&y_F10rs%n;%wkt@Lul-RL>rL3th@hpl#aT1Gl%f9`vm?s9({prKB)M zSV3=lKzPD>$4#23VwOu7U{0zy%VKx(QbYM1Hs+h^sWArOn{^rxBt?#tIBzIdqwR~4 z$C1+6O%X+7CF!3aip1Dt_C8diedTE1TJ&h?Y_&C7lAM5zB}42vFyNh06xyUH1yh~P zGhS8{R=e&O(#`IAh#^)eHukYm9uA2z)RLu_JNOy@3o6_A3%uiCj_;*}@``?lJ} zV9edZ6q6CcUS-0(A@2dAyj8TQ4ApLF@OEj&q)CH?v~ChNQtXW0O;l?X&?e7u-0NP%^;Xc4Kg4iF++P;=SHy#5 x@!)N~%8MoL&QMM0ss^Rf;X7A<7h3*8hh7UkT literal 0 HcmV?d00001 diff --git a/__pycache__/screen.cpython-313.pyc b/__pycache__/screen.cpython-313.pyc index 192e3889958d5ecf1aa86678a575a4495a6273f6..a8de4011f0fa14759ff1dfde3debc7c660fd292f 100644 GIT binary patch delta 35 pcmdlbxG|33UJf delta 37 rcmdlXx=WPnGcPX}0}wP_-N?nl%p;*+T3n=GT$HSzTe(?+c>y~B!Ho)q diff --git a/server.py b/server.py index 0785dec..dedf7ea 100644 --- a/server.py +++ b/server.py @@ -33,6 +33,11 @@ def views(): global watchers_last_seen return str(len(watchers_last_seen)) +@api.route("/mode", methods=["GET"]) +def mode(): + global watchers_last_seen + return str(stream) + def ws_server(websocket): global stream, watchers_last_seen @@ -60,7 +65,7 @@ def ws_server(websocket): if debug: print("Internal Server Error.") def run_ws_server(): - with serve(ws_server, "0.0.0.0", 7890) as server: + with serve(ws_server, "0.0.0.0", 5621) as server: server.serve_forever() def timeout_task(): @@ -76,7 +81,7 @@ def timeout_task(): sleep(10) def run_flask_server(): - api.run() + api.run(host="0.0.0.0", port=5622) def main(): t1 = threading.Thread(target=run_ws_server) diff --git a/venv/bin/Activate.ps1 b/venv/bin/Activate.ps1 new file mode 100644 index 0000000..b49d77b --- /dev/null +++ b/venv/bin/Activate.ps1 @@ -0,0 +1,247 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" diff --git a/venv/bin/activate b/venv/bin/activate new file mode 100644 index 0000000..66680e0 --- /dev/null +++ b/venv/bin/activate @@ -0,0 +1,70 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +if [ "${OSTYPE:-}" = "cygwin" ] || [ "${OSTYPE:-}" = "msys" ] ; then + # transform D:\path\to\venv to /d/path/to/venv on MSYS + # and to /cygdrive/d/path/to/venv on Cygwin + export VIRTUAL_ENV=$(cygpath "/home/n0rdye/Documents/cons/python_screen_share/venv") +else + # use the path as-is + export VIRTUAL_ENV="/home/n0rdye/Documents/cons/python_screen_share/venv" +fi + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="(venv) ${PS1:-}" + export PS1 + VIRTUAL_ENV_PROMPT="(venv) " + export VIRTUAL_ENV_PROMPT +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/venv/bin/activate.csh b/venv/bin/activate.csh new file mode 100644 index 0000000..874e687 --- /dev/null +++ b/venv/bin/activate.csh @@ -0,0 +1,27 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. + +# Created by Davide Di Blasi . +# Ported to Python 3.3 venv by Andrew Svetlov + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; unsetenv VIRTUAL_ENV_PROMPT; test "\!:*" != "nondestructive" && unalias deactivate' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/n0rdye/Documents/cons/python_screen_share/venv" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + +set _OLD_VIRTUAL_PROMPT="$prompt" + +if (! "$?VIRTUAL_ENV_DISABLE_PROMPT") then + set prompt = "(venv) $prompt" + setenv VIRTUAL_ENV_PROMPT "(venv) " +endif + +alias pydoc python -m pydoc + +rehash diff --git a/venv/bin/activate.fish b/venv/bin/activate.fish new file mode 100644 index 0000000..004b43d --- /dev/null +++ b/venv/bin/activate.fish @@ -0,0 +1,69 @@ +# This file must be used with "source /bin/activate.fish" *from fish* +# (https://fishshell.com/). You cannot run it directly. + +function deactivate -d "Exit virtual environment and return to normal shell environment" + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + set -e _OLD_FISH_PROMPT_OVERRIDE + # prevents error when using nested fish instances (Issue #93858) + if functions -q _old_fish_prompt + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + end + end + + set -e VIRTUAL_ENV + set -e VIRTUAL_ENV_PROMPT + if test "$argv[1]" != "nondestructive" + # Self-destruct! + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/n0rdye/Documents/cons/python_screen_share/venv" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset PYTHONHOME if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # fish uses a function instead of an env var to generate the prompt. + + # Save the current fish_prompt function as the function _old_fish_prompt. + functions -c fish_prompt _old_fish_prompt + + # With the original prompt function renamed, we can override with our own. + function fish_prompt + # Save the return status of the last command. + set -l old_status $status + + # Output the venv prompt; color taken from the blue of the Python logo. + printf "%s%s%s" (set_color 4B8BBE) "(venv) " (set_color normal) + + # Restore the return status of the previous command. + echo "exit $old_status" | . + # Output the original/"old" prompt. + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" + set -gx VIRTUAL_ENV_PROMPT "(venv) " +end diff --git a/venv/bin/flask b/venv/bin/flask new file mode 100755 index 0000000..9434eb5 --- /dev/null +++ b/venv/bin/flask @@ -0,0 +1,8 @@ +#!/home/n0rdye/Documents/cons/python_screen_share/venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from flask.cli import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip b/venv/bin/pip new file mode 100755 index 0000000..9e399c7 --- /dev/null +++ b/venv/bin/pip @@ -0,0 +1,8 @@ +#!/home/n0rdye/Documents/cons/python_screen_share/venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3 b/venv/bin/pip3 new file mode 100755 index 0000000..9e399c7 --- /dev/null +++ b/venv/bin/pip3 @@ -0,0 +1,8 @@ +#!/home/n0rdye/Documents/cons/python_screen_share/venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/pip3.12 b/venv/bin/pip3.12 new file mode 100755 index 0000000..9e399c7 --- /dev/null +++ b/venv/bin/pip3.12 @@ -0,0 +1,8 @@ +#!/home/n0rdye/Documents/cons/python_screen_share/venv/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from pip._internal.cli.main import main +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/venv/bin/python b/venv/bin/python new file mode 120000 index 0000000..af674c4 --- /dev/null +++ b/venv/bin/python @@ -0,0 +1 @@ +/sbin/python \ No newline at end of file diff --git a/venv/bin/python3 b/venv/bin/python3 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/venv/bin/python3 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv/bin/python3.12 b/venv/bin/python3.12 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/venv/bin/python3.12 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA new file mode 100644 index 0000000..82261f2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/METADATA @@ -0,0 +1,92 @@ +Metadata-Version: 2.1 +Name: MarkupSafe +Version: 3.0.2 +Summary: Safely add untrusted strings to HTML/XML markup. +Maintainer-email: Pallets +License: Copyright 2010 Pallets + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://markupsafe.palletsprojects.com/ +Project-URL: Changes, https://markupsafe.palletsprojects.com/changes/ +Project-URL: Source, https://github.com/pallets/markupsafe/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +License-File: LICENSE.txt + +# MarkupSafe + +MarkupSafe implements a text object that escapes characters so it is +safe to use in HTML and XML. Characters that have special meanings are +replaced so that they display as the actual characters. This mitigates +injection attacks, meaning untrusted user input can safely be displayed +on a page. + + +## Examples + +```pycon +>>> from markupsafe import Markup, escape + +>>> # escape replaces special characters and wraps in Markup +>>> escape("") +Markup('<script>alert(document.cookie);</script>') + +>>> # wrap in Markup to mark text "safe" and prevent escaping +>>> Markup("Hello") +Markup('hello') + +>>> escape(Markup("Hello")) +Markup('hello') + +>>> # Markup is a str subclass +>>> # methods and operators escape their arguments +>>> template = Markup("Hello {name}") +>>> template.format(name='"World"') +Markup('Hello "World"') +``` + +## Donate + +The Pallets organization develops and supports MarkupSafe and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +[please donate today][]. + +[please donate today]: https://palletsprojects.com/donate diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD new file mode 100644 index 0000000..b7ba0b7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/RECORD @@ -0,0 +1,14 @@ +MarkupSafe-3.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +MarkupSafe-3.0.2.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +MarkupSafe-3.0.2.dist-info/METADATA,sha256=aAwbZhSmXdfFuMM-rEHpeiHRkBOGESyVLJIuwzHP-nw,3975 +MarkupSafe-3.0.2.dist-info/RECORD,, +MarkupSafe-3.0.2.dist-info/WHEEL,sha256=OVgtqZzfzIXXtylXP90gxCZ6CKBCwKYyHM8PpMEjN1M,151 +MarkupSafe-3.0.2.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11 +markupsafe/__init__.py,sha256=sr-U6_27DfaSrj5jnHYxWN-pvhM27sjlDplMDPZKm7k,13214 +markupsafe/__pycache__/__init__.cpython-312.pyc,, +markupsafe/__pycache__/_native.cpython-312.pyc,, +markupsafe/_native.py,sha256=hSLs8Jmz5aqayuengJJ3kdT5PwNpBWpKrmQSdipndC8,210 +markupsafe/_speedups.c,sha256=O7XulmTo-epI6n2FtMVOrJXl8EAaIwD2iNYmBI5SEoQ,4149 +markupsafe/_speedups.cpython-312-x86_64-linux-gnu.so,sha256=t1DBZlpsjFA30BOOvXfXfT1wvO_4cS16VbHz1-49q5U,43432 +markupsafe/_speedups.pyi,sha256=ENd1bYe7gbBUf2ywyYWOGUpnXOHNJ-cgTNqetlW8h5k,41 +markupsafe/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL new file mode 100644 index 0000000..057fef6 --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: setuptools (75.2.0) +Root-Is-Purelib: false +Tag: cp312-cp312-manylinux_2_17_x86_64 +Tag: cp312-cp312-manylinux2014_x86_64 + diff --git a/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt new file mode 100644 index 0000000..75bf729 --- /dev/null +++ b/venv/lib/python3.12/site-packages/MarkupSafe-3.0.2.dist-info/top_level.txt @@ -0,0 +1 @@ +markupsafe diff --git a/venv/lib/python3.12/site-packages/PIL/BdfFontFile.py b/venv/lib/python3.12/site-packages/PIL/BdfFontFile.py new file mode 100644 index 0000000..bc1416c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/BdfFontFile.py @@ -0,0 +1,133 @@ +# +# The Python Imaging Library +# $Id$ +# +# bitmap distribution font (bdf) file parser +# +# history: +# 1996-05-16 fl created (as bdf2pil) +# 1997-08-25 fl converted to FontFile driver +# 2001-05-25 fl removed bogus __init__ call +# 2002-11-20 fl robustification (from Kevin Cazabon, Dmitry Vasiliev) +# 2003-04-22 fl more robustification (from Graham Dumpleton) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1997-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +""" +Parse X Bitmap Distribution Format (BDF) +""" +from __future__ import annotations + +from typing import BinaryIO + +from . import FontFile, Image + +bdf_slant = { + "R": "Roman", + "I": "Italic", + "O": "Oblique", + "RI": "Reverse Italic", + "RO": "Reverse Oblique", + "OT": "Other", +} + +bdf_spacing = {"P": "Proportional", "M": "Monospaced", "C": "Cell"} + + +def bdf_char( + f: BinaryIO, +) -> ( + tuple[ + str, + int, + tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]], + Image.Image, + ] + | None +): + # skip to STARTCHAR + while True: + s = f.readline() + if not s: + return None + if s[:9] == b"STARTCHAR": + break + id = s[9:].strip().decode("ascii") + + # load symbol properties + props = {} + while True: + s = f.readline() + if not s or s[:6] == b"BITMAP": + break + i = s.find(b" ") + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") + + # load bitmap + bitmap = bytearray() + while True: + s = f.readline() + if not s or s[:7] == b"ENDCHAR": + break + bitmap += s[:-1] + + # The word BBX + # followed by the width in x (BBw), height in y (BBh), + # and x and y displacement (BBxoff0, BByoff0) + # of the lower left corner from the origin of the character. + width, height, x_disp, y_disp = (int(p) for p in props["BBX"].split()) + + # The word DWIDTH + # followed by the width in x and y of the character in device pixels. + dwx, dwy = (int(p) for p in props["DWIDTH"].split()) + + bbox = ( + (dwx, dwy), + (x_disp, -y_disp - height, width + x_disp, -y_disp), + (0, 0, width, height), + ) + + try: + im = Image.frombytes("1", (width, height), bitmap, "hex", "1") + except ValueError: + # deal with zero-width characters + im = Image.new("1", (width, height)) + + return id, int(props["ENCODING"]), bbox, im + + +class BdfFontFile(FontFile.FontFile): + """Font file plugin for the X11 BDF format.""" + + def __init__(self, fp: BinaryIO) -> None: + super().__init__() + + s = fp.readline() + if s[:13] != b"STARTFONT 2.1": + msg = "not a valid BDF file" + raise SyntaxError(msg) + + props = {} + comments = [] + + while True: + s = fp.readline() + if not s or s[:13] == b"ENDPROPERTIES": + break + i = s.find(b" ") + props[s[:i].decode("ascii")] = s[i + 1 : -1].decode("ascii") + if s[:i] in [b"COMMENT", b"COPYRIGHT"]: + if s.find(b"LogicalFontDescription") < 0: + comments.append(s[i + 1 : -1].decode("ascii")) + + while True: + c = bdf_char(fp) + if not c: + break + id, ch, (xy, dst, src), im = c + if 0 <= ch < len(self.glyph): + self.glyph[ch] = xy, dst, src, im diff --git a/venv/lib/python3.12/site-packages/PIL/BlpImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/BlpImagePlugin.py new file mode 100644 index 0000000..e560563 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/BlpImagePlugin.py @@ -0,0 +1,493 @@ +""" +Blizzard Mipmap Format (.blp) +Jerome Leclanche + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: + https://creativecommons.org/publicdomain/zero/1.0/ + +BLP1 files, used mostly in Warcraft III, are not fully supported. +All types of BLP2 files used in World of Warcraft are supported. + +The BLP file structure consists of a header, up to 16 mipmaps of the +texture + +Texture sizes must be powers of two, though the two dimensions do +not have to be equal; 512x256 is valid, but 512x200 is not. +The first mipmap (mipmap #0) is the full size image; each subsequent +mipmap halves both dimensions. The final mipmap should be 1x1. + +BLP files come in many different flavours: +* JPEG-compressed (type == 0) - only supported for BLP1. +* RAW images (type == 1, encoding == 1). Each mipmap is stored as an + array of 8-bit values, one per pixel, left to right, top to bottom. + Each value is an index to the palette. +* DXT-compressed (type == 1, encoding == 2): +- DXT1 compression is used if alpha_encoding == 0. + - An additional alpha bit is used if alpha_depth == 1. + - DXT3 compression is used if alpha_encoding == 1. + - DXT5 compression is used if alpha_encoding == 7. +""" + +from __future__ import annotations + +import abc +import os +import struct +from enum import IntEnum +from io import BytesIO +from typing import IO + +from . import Image, ImageFile + + +class Format(IntEnum): + JPEG = 0 + + +class Encoding(IntEnum): + UNCOMPRESSED = 1 + DXT = 2 + UNCOMPRESSED_RAW_BGRA = 3 + + +class AlphaEncoding(IntEnum): + DXT1 = 0 + DXT3 = 1 + DXT5 = 7 + + +def unpack_565(i: int) -> tuple[int, int, int]: + return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3 + + +def decode_dxt1( + data: bytes, alpha: bool = False +) -> tuple[bytearray, bytearray, bytearray, bytearray]: + """ + input: one "row" of data (i.e. will produce 4*width pixels) + """ + + blocks = len(data) // 8 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block_index in range(blocks): + # Decode next 8-byte block. + idx = block_index * 8 + color0, color1, bits = struct.unpack_from("> 2 + + a = 0xFF + if control == 0: + r, g, b = r0, g0, b0 + elif control == 1: + r, g, b = r1, g1, b1 + elif control == 2: + if color0 > color1: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + else: + r = (r0 + r1) // 2 + g = (g0 + g1) // 2 + b = (b0 + b1) // 2 + elif control == 3: + if color0 > color1: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + else: + r, g, b, a = 0, 0, 0, 0 + + if alpha: + ret[j].extend([r, g, b, a]) + else: + ret[j].extend([r, g, b]) + + return ret + + +def decode_dxt3(data: bytes) -> tuple[bytearray, bytearray, bytearray, bytearray]: + """ + input: one "row" of data (i.e. will produce 4*width pixels) + """ + + blocks = len(data) // 16 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block_index in range(blocks): + idx = block_index * 16 + block = data[idx : idx + 16] + # Decode next 16-byte block. + bits = struct.unpack_from("<8B", block) + color0, color1 = struct.unpack_from(">= 4 + else: + high = True + a &= 0xF + a *= 17 # We get a value between 0 and 15 + + color_code = (code >> 2 * (4 * j + i)) & 0x03 + + if color_code == 0: + r, g, b = r0, g0, b0 + elif color_code == 1: + r, g, b = r1, g1, b1 + elif color_code == 2: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + elif color_code == 3: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + + ret[j].extend([r, g, b, a]) + + return ret + + +def decode_dxt5(data: bytes) -> tuple[bytearray, bytearray, bytearray, bytearray]: + """ + input: one "row" of data (i.e. will produce 4 * width pixels) + """ + + blocks = len(data) // 16 # number of blocks in row + ret = (bytearray(), bytearray(), bytearray(), bytearray()) + + for block_index in range(blocks): + idx = block_index * 16 + block = data[idx : idx + 16] + # Decode next 16-byte block. + a0, a1 = struct.unpack_from("> alphacode_index) & 0x07 + elif alphacode_index == 15: + alphacode = (alphacode2 >> 15) | ((alphacode1 << 1) & 0x06) + else: # alphacode_index >= 18 and alphacode_index <= 45 + alphacode = (alphacode1 >> (alphacode_index - 16)) & 0x07 + + if alphacode == 0: + a = a0 + elif alphacode == 1: + a = a1 + elif a0 > a1: + a = ((8 - alphacode) * a0 + (alphacode - 1) * a1) // 7 + elif alphacode == 6: + a = 0 + elif alphacode == 7: + a = 255 + else: + a = ((6 - alphacode) * a0 + (alphacode - 1) * a1) // 5 + + color_code = (code >> 2 * (4 * j + i)) & 0x03 + + if color_code == 0: + r, g, b = r0, g0, b0 + elif color_code == 1: + r, g, b = r1, g1, b1 + elif color_code == 2: + r = (2 * r0 + r1) // 3 + g = (2 * g0 + g1) // 3 + b = (2 * b0 + b1) // 3 + elif color_code == 3: + r = (2 * r1 + r0) // 3 + g = (2 * g1 + g0) // 3 + b = (2 * b1 + b0) // 3 + + ret[j].extend([r, g, b, a]) + + return ret + + +class BLPFormatError(NotImplementedError): + pass + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] in (b"BLP1", b"BLP2") + + +class BlpImageFile(ImageFile.ImageFile): + """ + Blizzard Mipmap Format + """ + + format = "BLP" + format_description = "Blizzard Mipmap Format" + + def _open(self) -> None: + self.magic = self.fp.read(4) + + self.fp.seek(5, os.SEEK_CUR) + (self._blp_alpha_depth,) = struct.unpack(" tuple[int, int]: + try: + self._read_blp_header() + self._load() + except struct.error as e: + msg = "Truncated BLP file" + raise OSError(msg) from e + return -1, 0 + + @abc.abstractmethod + def _load(self) -> None: + pass + + def _read_blp_header(self) -> None: + assert self.fd is not None + self.fd.seek(4) + (self._blp_compression,) = struct.unpack(" bytes: + assert self.fd is not None + return ImageFile._safe_read(self.fd, length) + + def _read_palette(self) -> list[tuple[int, int, int, int]]: + ret = [] + for i in range(256): + try: + b, g, r, a = struct.unpack("<4B", self._safe_read(4)) + except struct.error: + break + ret.append((b, g, r, a)) + return ret + + def _read_bgra(self, palette: list[tuple[int, int, int, int]]) -> bytearray: + data = bytearray() + _data = BytesIO(self._safe_read(self._blp_lengths[0])) + while True: + try: + (offset,) = struct.unpack(" None: + if self._blp_compression == Format.JPEG: + self._decode_jpeg_stream() + + elif self._blp_compression == 1: + if self._blp_encoding in (4, 5): + palette = self._read_palette() + data = self._read_bgra(palette) + self.set_as_raw(data) + else: + msg = f"Unsupported BLP encoding {repr(self._blp_encoding)}" + raise BLPFormatError(msg) + else: + msg = f"Unsupported BLP compression {repr(self._blp_encoding)}" + raise BLPFormatError(msg) + + def _decode_jpeg_stream(self) -> None: + from .JpegImagePlugin import JpegImageFile + + (jpeg_header_size,) = struct.unpack(" None: + palette = self._read_palette() + + assert self.fd is not None + self.fd.seek(self._blp_offsets[0]) + + if self._blp_compression == 1: + # Uncompressed or DirectX compression + + if self._blp_encoding == Encoding.UNCOMPRESSED: + data = self._read_bgra(palette) + + elif self._blp_encoding == Encoding.DXT: + data = bytearray() + if self._blp_alpha_encoding == AlphaEncoding.DXT1: + linesize = (self.size[0] + 3) // 4 * 8 + for yb in range((self.size[1] + 3) // 4): + for d in decode_dxt1( + self._safe_read(linesize), alpha=bool(self._blp_alpha_depth) + ): + data += d + + elif self._blp_alpha_encoding == AlphaEncoding.DXT3: + linesize = (self.size[0] + 3) // 4 * 16 + for yb in range((self.size[1] + 3) // 4): + for d in decode_dxt3(self._safe_read(linesize)): + data += d + + elif self._blp_alpha_encoding == AlphaEncoding.DXT5: + linesize = (self.size[0] + 3) // 4 * 16 + for yb in range((self.size[1] + 3) // 4): + for d in decode_dxt5(self._safe_read(linesize)): + data += d + else: + msg = f"Unsupported alpha encoding {repr(self._blp_alpha_encoding)}" + raise BLPFormatError(msg) + else: + msg = f"Unknown BLP encoding {repr(self._blp_encoding)}" + raise BLPFormatError(msg) + + else: + msg = f"Unknown BLP compression {repr(self._blp_compression)}" + raise BLPFormatError(msg) + + self.set_as_raw(data) + + +class BLPEncoder(ImageFile.PyEncoder): + _pushes_fd = True + + def _write_palette(self) -> bytes: + data = b"" + assert self.im is not None + palette = self.im.getpalette("RGBA", "RGBA") + for i in range(len(palette) // 4): + r, g, b, a = palette[i * 4 : (i + 1) * 4] + data += struct.pack("<4B", b, g, r, a) + while len(data) < 256 * 4: + data += b"\x00" * 4 + return data + + def encode(self, bufsize: int) -> tuple[int, int, bytes]: + palette_data = self._write_palette() + + offset = 20 + 16 * 4 * 2 + len(palette_data) + data = struct.pack("<16I", offset, *((0,) * 15)) + + assert self.im is not None + w, h = self.im.size + data += struct.pack("<16I", w * h, *((0,) * 15)) + + data += palette_data + + for y in range(h): + for x in range(w): + data += struct.pack(" None: + if im.mode != "P": + msg = "Unsupported BLP image mode" + raise ValueError(msg) + + magic = b"BLP1" if im.encoderinfo.get("blp_version") == "BLP1" else b"BLP2" + fp.write(magic) + + assert im.palette is not None + fp.write(struct.pack(" mode, rawmode + 1: ("P", "P;1"), + 4: ("P", "P;4"), + 8: ("P", "P"), + 16: ("RGB", "BGR;15"), + 24: ("RGB", "BGR"), + 32: ("RGB", "BGRX"), +} + + +def _accept(prefix: bytes) -> bool: + return prefix[:2] == b"BM" + + +def _dib_accept(prefix: bytes) -> bool: + return i32(prefix) in [12, 40, 52, 56, 64, 108, 124] + + +# ============================================================================= +# Image plugin for the Windows BMP format. +# ============================================================================= +class BmpImageFile(ImageFile.ImageFile): + """Image plugin for the Windows Bitmap format (BMP)""" + + # ------------------------------------------------------------- Description + format_description = "Windows Bitmap" + format = "BMP" + + # -------------------------------------------------- BMP Compression values + COMPRESSIONS = {"RAW": 0, "RLE8": 1, "RLE4": 2, "BITFIELDS": 3, "JPEG": 4, "PNG": 5} + for k, v in COMPRESSIONS.items(): + vars()[k] = v + + def _bitmap(self, header: int = 0, offset: int = 0) -> None: + """Read relevant info about the BMP""" + read, seek = self.fp.read, self.fp.seek + if header: + seek(header) + # read bmp header size @offset 14 (this is part of the header size) + file_info: dict[str, bool | int | tuple[int, ...]] = { + "header_size": i32(read(4)), + "direction": -1, + } + + # -------------------- If requested, read header at a specific position + # read the rest of the bmp header, without its size + assert isinstance(file_info["header_size"], int) + header_data = ImageFile._safe_read(self.fp, file_info["header_size"] - 4) + + # ------------------------------- Windows Bitmap v2, IBM OS/2 Bitmap v1 + # ----- This format has different offsets because of width/height types + # 12: BITMAPCOREHEADER/OS21XBITMAPHEADER + if file_info["header_size"] == 12: + file_info["width"] = i16(header_data, 0) + file_info["height"] = i16(header_data, 2) + file_info["planes"] = i16(header_data, 4) + file_info["bits"] = i16(header_data, 6) + file_info["compression"] = self.COMPRESSIONS["RAW"] + file_info["palette_padding"] = 3 + + # --------------------------------------------- Windows Bitmap v3 to v5 + # 40: BITMAPINFOHEADER + # 52: BITMAPV2HEADER + # 56: BITMAPV3HEADER + # 64: BITMAPCOREHEADER2/OS22XBITMAPHEADER + # 108: BITMAPV4HEADER + # 124: BITMAPV5HEADER + elif file_info["header_size"] in (40, 52, 56, 64, 108, 124): + file_info["y_flip"] = header_data[7] == 0xFF + file_info["direction"] = 1 if file_info["y_flip"] else -1 + file_info["width"] = i32(header_data, 0) + file_info["height"] = ( + i32(header_data, 4) + if not file_info["y_flip"] + else 2**32 - i32(header_data, 4) + ) + file_info["planes"] = i16(header_data, 8) + file_info["bits"] = i16(header_data, 10) + file_info["compression"] = i32(header_data, 12) + # byte size of pixel data + file_info["data_size"] = i32(header_data, 16) + file_info["pixels_per_meter"] = ( + i32(header_data, 20), + i32(header_data, 24), + ) + file_info["colors"] = i32(header_data, 28) + file_info["palette_padding"] = 4 + assert isinstance(file_info["pixels_per_meter"], tuple) + self.info["dpi"] = tuple(x / 39.3701 for x in file_info["pixels_per_meter"]) + if file_info["compression"] == self.COMPRESSIONS["BITFIELDS"]: + masks = ["r_mask", "g_mask", "b_mask"] + if len(header_data) >= 48: + if len(header_data) >= 52: + masks.append("a_mask") + else: + file_info["a_mask"] = 0x0 + for idx, mask in enumerate(masks): + file_info[mask] = i32(header_data, 36 + idx * 4) + else: + # 40 byte headers only have the three components in the + # bitfields masks, ref: + # https://msdn.microsoft.com/en-us/library/windows/desktop/dd183376(v=vs.85).aspx + # See also + # https://github.com/python-pillow/Pillow/issues/1293 + # There is a 4th component in the RGBQuad, in the alpha + # location, but it is listed as a reserved component, + # and it is not generally an alpha channel + file_info["a_mask"] = 0x0 + for mask in masks: + file_info[mask] = i32(read(4)) + assert isinstance(file_info["r_mask"], int) + assert isinstance(file_info["g_mask"], int) + assert isinstance(file_info["b_mask"], int) + assert isinstance(file_info["a_mask"], int) + file_info["rgb_mask"] = ( + file_info["r_mask"], + file_info["g_mask"], + file_info["b_mask"], + ) + file_info["rgba_mask"] = ( + file_info["r_mask"], + file_info["g_mask"], + file_info["b_mask"], + file_info["a_mask"], + ) + else: + msg = f"Unsupported BMP header type ({file_info['header_size']})" + raise OSError(msg) + + # ------------------ Special case : header is reported 40, which + # ---------------------- is shorter than real size for bpp >= 16 + assert isinstance(file_info["width"], int) + assert isinstance(file_info["height"], int) + self._size = file_info["width"], file_info["height"] + + # ------- If color count was not found in the header, compute from bits + assert isinstance(file_info["bits"], int) + file_info["colors"] = ( + file_info["colors"] + if file_info.get("colors", 0) + else (1 << file_info["bits"]) + ) + assert isinstance(file_info["colors"], int) + if offset == 14 + file_info["header_size"] and file_info["bits"] <= 8: + offset += 4 * file_info["colors"] + + # ---------------------- Check bit depth for unusual unsupported values + self._mode, raw_mode = BIT2MODE.get(file_info["bits"], ("", "")) + if not self.mode: + msg = f"Unsupported BMP pixel depth ({file_info['bits']})" + raise OSError(msg) + + # ---------------- Process BMP with Bitfields compression (not palette) + decoder_name = "raw" + if file_info["compression"] == self.COMPRESSIONS["BITFIELDS"]: + SUPPORTED: dict[int, list[tuple[int, ...]]] = { + 32: [ + (0xFF0000, 0xFF00, 0xFF, 0x0), + (0xFF000000, 0xFF0000, 0xFF00, 0x0), + (0xFF000000, 0xFF00, 0xFF, 0x0), + (0xFF000000, 0xFF0000, 0xFF00, 0xFF), + (0xFF, 0xFF00, 0xFF0000, 0xFF000000), + (0xFF0000, 0xFF00, 0xFF, 0xFF000000), + (0xFF000000, 0xFF00, 0xFF, 0xFF0000), + (0x0, 0x0, 0x0, 0x0), + ], + 24: [(0xFF0000, 0xFF00, 0xFF)], + 16: [(0xF800, 0x7E0, 0x1F), (0x7C00, 0x3E0, 0x1F)], + } + MASK_MODES = { + (32, (0xFF0000, 0xFF00, 0xFF, 0x0)): "BGRX", + (32, (0xFF000000, 0xFF0000, 0xFF00, 0x0)): "XBGR", + (32, (0xFF000000, 0xFF00, 0xFF, 0x0)): "BGXR", + (32, (0xFF000000, 0xFF0000, 0xFF00, 0xFF)): "ABGR", + (32, (0xFF, 0xFF00, 0xFF0000, 0xFF000000)): "RGBA", + (32, (0xFF0000, 0xFF00, 0xFF, 0xFF000000)): "BGRA", + (32, (0xFF000000, 0xFF00, 0xFF, 0xFF0000)): "BGAR", + (32, (0x0, 0x0, 0x0, 0x0)): "BGRA", + (24, (0xFF0000, 0xFF00, 0xFF)): "BGR", + (16, (0xF800, 0x7E0, 0x1F)): "BGR;16", + (16, (0x7C00, 0x3E0, 0x1F)): "BGR;15", + } + if file_info["bits"] in SUPPORTED: + if ( + file_info["bits"] == 32 + and file_info["rgba_mask"] in SUPPORTED[file_info["bits"]] + ): + assert isinstance(file_info["rgba_mask"], tuple) + raw_mode = MASK_MODES[(file_info["bits"], file_info["rgba_mask"])] + self._mode = "RGBA" if "A" in raw_mode else self.mode + elif ( + file_info["bits"] in (24, 16) + and file_info["rgb_mask"] in SUPPORTED[file_info["bits"]] + ): + assert isinstance(file_info["rgb_mask"], tuple) + raw_mode = MASK_MODES[(file_info["bits"], file_info["rgb_mask"])] + else: + msg = "Unsupported BMP bitfields layout" + raise OSError(msg) + else: + msg = "Unsupported BMP bitfields layout" + raise OSError(msg) + elif file_info["compression"] == self.COMPRESSIONS["RAW"]: + if file_info["bits"] == 32 and header == 22: # 32-bit .cur offset + raw_mode, self._mode = "BGRA", "RGBA" + elif file_info["compression"] in ( + self.COMPRESSIONS["RLE8"], + self.COMPRESSIONS["RLE4"], + ): + decoder_name = "bmp_rle" + else: + msg = f"Unsupported BMP compression ({file_info['compression']})" + raise OSError(msg) + + # --------------- Once the header is processed, process the palette/LUT + if self.mode == "P": # Paletted for 1, 4 and 8 bit images + # ---------------------------------------------------- 1-bit images + if not (0 < file_info["colors"] <= 65536): + msg = f"Unsupported BMP Palette size ({file_info['colors']})" + raise OSError(msg) + else: + assert isinstance(file_info["palette_padding"], int) + padding = file_info["palette_padding"] + palette = read(padding * file_info["colors"]) + grayscale = True + indices = ( + (0, 255) + if file_info["colors"] == 2 + else list(range(file_info["colors"])) + ) + + # ----------------- Check if grayscale and ignore palette if so + for ind, val in enumerate(indices): + rgb = palette[ind * padding : ind * padding + 3] + if rgb != o8(val) * 3: + grayscale = False + + # ------- If all colors are gray, white or black, ditch palette + if grayscale: + self._mode = "1" if file_info["colors"] == 2 else "L" + raw_mode = self.mode + else: + self._mode = "P" + self.palette = ImagePalette.raw( + "BGRX" if padding == 4 else "BGR", palette + ) + + # ---------------------------- Finally set the tile data for the plugin + self.info["compression"] = file_info["compression"] + args: list[Any] = [raw_mode] + if decoder_name == "bmp_rle": + args.append(file_info["compression"] == self.COMPRESSIONS["RLE4"]) + else: + assert isinstance(file_info["width"], int) + args.append(((file_info["width"] * file_info["bits"] + 31) >> 3) & (~3)) + args.append(file_info["direction"]) + self.tile = [ + ImageFile._Tile( + decoder_name, + (0, 0, file_info["width"], file_info["height"]), + offset or self.fp.tell(), + tuple(args), + ) + ] + + def _open(self) -> None: + """Open file, check magic number and read header""" + # read 14 bytes: magic number, filesize, reserved, header final offset + head_data = self.fp.read(14) + # choke if the file does not have the required magic bytes + if not _accept(head_data): + msg = "Not a BMP file" + raise SyntaxError(msg) + # read the start position of the BMP image data (u32) + offset = i32(head_data, 10) + # load bitmap information (offset=raster info) + self._bitmap(offset=offset) + + +class BmpRleDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + rle4 = self.args[1] + data = bytearray() + x = 0 + dest_length = self.state.xsize * self.state.ysize + while len(data) < dest_length: + pixels = self.fd.read(1) + byte = self.fd.read(1) + if not pixels or not byte: + break + num_pixels = pixels[0] + if num_pixels: + # encoded mode + if x + num_pixels > self.state.xsize: + # Too much data for row + num_pixels = max(0, self.state.xsize - x) + if rle4: + first_pixel = o8(byte[0] >> 4) + second_pixel = o8(byte[0] & 0x0F) + for index in range(num_pixels): + if index % 2 == 0: + data += first_pixel + else: + data += second_pixel + else: + data += byte * num_pixels + x += num_pixels + else: + if byte[0] == 0: + # end of line + while len(data) % self.state.xsize != 0: + data += b"\x00" + x = 0 + elif byte[0] == 1: + # end of bitmap + break + elif byte[0] == 2: + # delta + bytes_read = self.fd.read(2) + if len(bytes_read) < 2: + break + right, up = self.fd.read(2) + data += b"\x00" * (right + up * self.state.xsize) + x = len(data) % self.state.xsize + else: + # absolute mode + if rle4: + # 2 pixels per byte + byte_count = byte[0] // 2 + bytes_read = self.fd.read(byte_count) + for byte_read in bytes_read: + data += o8(byte_read >> 4) + data += o8(byte_read & 0x0F) + else: + byte_count = byte[0] + bytes_read = self.fd.read(byte_count) + data += bytes_read + if len(bytes_read) < byte_count: + break + x += byte[0] + + # align to 16-bit word boundary + if self.fd.tell() % 2 != 0: + self.fd.seek(1, os.SEEK_CUR) + rawmode = "L" if self.mode == "L" else "P" + self.set_as_raw(bytes(data), rawmode, (0, self.args[-1])) + return -1, 0 + + +# ============================================================================= +# Image plugin for the DIB format (BMP alias) +# ============================================================================= +class DibImageFile(BmpImageFile): + format = "DIB" + format_description = "Windows Bitmap" + + def _open(self) -> None: + self._bitmap() + + +# +# -------------------------------------------------------------------- +# Write BMP file + + +SAVE = { + "1": ("1", 1, 2), + "L": ("L", 8, 256), + "P": ("P", 8, 256), + "RGB": ("BGR", 24, 0), + "RGBA": ("BGRA", 32, 0), +} + + +def _dib_save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + _save(im, fp, filename, False) + + +def _save( + im: Image.Image, fp: IO[bytes], filename: str | bytes, bitmap_header: bool = True +) -> None: + try: + rawmode, bits, colors = SAVE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as BMP" + raise OSError(msg) from e + + info = im.encoderinfo + + dpi = info.get("dpi", (96, 96)) + + # 1 meter == 39.3701 inches + ppm = tuple(int(x * 39.3701 + 0.5) for x in dpi) + + stride = ((im.size[0] * bits + 7) // 8 + 3) & (~3) + header = 40 # or 64 for OS/2 version 2 + image = stride * im.size[1] + + if im.mode == "1": + palette = b"".join(o8(i) * 4 for i in (0, 255)) + elif im.mode == "L": + palette = b"".join(o8(i) * 4 for i in range(256)) + elif im.mode == "P": + palette = im.im.getpalette("RGB", "BGRX") + colors = len(palette) // 4 + else: + palette = None + + # bitmap header + if bitmap_header: + offset = 14 + header + colors * 4 + file_size = offset + image + if file_size > 2**32 - 1: + msg = "File size is too large for the BMP format" + raise ValueError(msg) + fp.write( + b"BM" # file type (magic) + + o32(file_size) # file size + + o32(0) # reserved + + o32(offset) # image data offset + ) + + # bitmap info header + fp.write( + o32(header) # info header size + + o32(im.size[0]) # width + + o32(im.size[1]) # height + + o16(1) # planes + + o16(bits) # depth + + o32(0) # compression (0=uncompressed) + + o32(image) # size of bitmap + + o32(ppm[0]) # resolution + + o32(ppm[1]) # resolution + + o32(colors) # colors used + + o32(colors) # colors important + ) + + fp.write(b"\0" * (header - 40)) # padding (for OS/2 format) + + if palette: + fp.write(palette) + + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, stride, -1))] + ) + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(BmpImageFile.format, BmpImageFile, _accept) +Image.register_save(BmpImageFile.format, _save) + +Image.register_extension(BmpImageFile.format, ".bmp") + +Image.register_mime(BmpImageFile.format, "image/bmp") + +Image.register_decoder("bmp_rle", BmpRleDecoder) + +Image.register_open(DibImageFile.format, DibImageFile, _dib_accept) +Image.register_save(DibImageFile.format, _dib_save) + +Image.register_extension(DibImageFile.format, ".dib") + +Image.register_mime(DibImageFile.format, "image/bmp") diff --git a/venv/lib/python3.12/site-packages/PIL/BufrStubImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/BufrStubImagePlugin.py new file mode 100644 index 0000000..0ee2f65 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/BufrStubImagePlugin.py @@ -0,0 +1,76 @@ +# +# The Python Imaging Library +# $Id$ +# +# BUFR stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler: ImageFile.StubHandler | None) -> None: + """ + Install application-specific BUFR image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"BUFR" or prefix[:4] == b"ZCZC" + + +class BufrStubImageFile(ImageFile.StubImageFile): + format = "BUFR" + format_description = "BUFR" + + def _open(self) -> None: + offset = self.fp.tell() + + if not _accept(self.fp.read(4)): + msg = "Not a BUFR file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self) -> ImageFile.StubHandler | None: + return _handler + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if _handler is None or not hasattr(_handler, "save"): + msg = "BUFR save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(BufrStubImageFile.format, BufrStubImageFile, _accept) +Image.register_save(BufrStubImageFile.format, _save) + +Image.register_extension(BufrStubImageFile.format, ".bufr") diff --git a/venv/lib/python3.12/site-packages/PIL/ContainerIO.py b/venv/lib/python3.12/site-packages/PIL/ContainerIO.py new file mode 100644 index 0000000..ec9e66c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ContainerIO.py @@ -0,0 +1,173 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a class to read from a container file +# +# History: +# 1995-06-18 fl Created +# 1995-09-07 fl Added readline(), readlines() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from collections.abc import Iterable +from typing import IO, AnyStr, NoReturn + + +class ContainerIO(IO[AnyStr]): + """ + A file object that provides read access to a part of an existing + file (for example a TAR file). + """ + + def __init__(self, file: IO[AnyStr], offset: int, length: int) -> None: + """ + Create file object. + + :param file: Existing file. + :param offset: Start of region, in bytes. + :param length: Size of region, in bytes. + """ + self.fh: IO[AnyStr] = file + self.pos = 0 + self.offset = offset + self.length = length + self.fh.seek(offset) + + ## + # Always false. + + def isatty(self) -> bool: + return False + + def seekable(self) -> bool: + return True + + def seek(self, offset: int, mode: int = io.SEEK_SET) -> int: + """ + Move file pointer. + + :param offset: Offset in bytes. + :param mode: Starting position. Use 0 for beginning of region, 1 + for current offset, and 2 for end of region. You cannot move + the pointer outside the defined region. + :returns: Offset from start of region, in bytes. + """ + if mode == 1: + self.pos = self.pos + offset + elif mode == 2: + self.pos = self.length + offset + else: + self.pos = offset + # clamp + self.pos = max(0, min(self.pos, self.length)) + self.fh.seek(self.offset + self.pos) + return self.pos + + def tell(self) -> int: + """ + Get current file pointer. + + :returns: Offset from start of region, in bytes. + """ + return self.pos + + def readable(self) -> bool: + return True + + def read(self, n: int = -1) -> AnyStr: + """ + Read data. + + :param n: Number of bytes to read. If omitted, zero or negative, + read until end of region. + :returns: An 8-bit string. + """ + if n > 0: + n = min(n, self.length - self.pos) + else: + n = self.length - self.pos + if n <= 0: # EOF + return b"" if "b" in self.fh.mode else "" # type: ignore[return-value] + self.pos = self.pos + n + return self.fh.read(n) + + def readline(self, n: int = -1) -> AnyStr: + """ + Read a line of text. + + :param n: Number of bytes to read. If omitted, zero or negative, + read until end of line. + :returns: An 8-bit string. + """ + s: AnyStr = b"" if "b" in self.fh.mode else "" # type: ignore[assignment] + newline_character = b"\n" if "b" in self.fh.mode else "\n" + while True: + c = self.read(1) + if not c: + break + s = s + c + if c == newline_character or len(s) == n: + break + return s + + def readlines(self, n: int | None = -1) -> list[AnyStr]: + """ + Read multiple lines of text. + + :param n: Number of lines to read. If omitted, zero, negative or None, + read until end of region. + :returns: A list of 8-bit strings. + """ + lines = [] + while True: + s = self.readline() + if not s: + break + lines.append(s) + if len(lines) == n: + break + return lines + + def writable(self) -> bool: + return False + + def write(self, b: AnyStr) -> NoReturn: + raise NotImplementedError() + + def writelines(self, lines: Iterable[AnyStr]) -> NoReturn: + raise NotImplementedError() + + def truncate(self, size: int | None = None) -> int: + raise NotImplementedError() + + def __enter__(self) -> ContainerIO[AnyStr]: + return self + + def __exit__(self, *args: object) -> None: + self.close() + + def __iter__(self) -> ContainerIO[AnyStr]: + return self + + def __next__(self) -> AnyStr: + line = self.readline() + if not line: + msg = "end of region" + raise StopIteration(msg) + return line + + def fileno(self) -> int: + return self.fh.fileno() + + def flush(self) -> None: + self.fh.flush() + + def close(self) -> None: + self.fh.close() diff --git a/venv/lib/python3.12/site-packages/PIL/CurImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/CurImagePlugin.py new file mode 100644 index 0000000..c4be0ce --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/CurImagePlugin.py @@ -0,0 +1,75 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Cursor support for PIL +# +# notes: +# uses BmpImagePlugin.py to read the bitmap data. +# +# history: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import BmpImagePlugin, Image, ImageFile +from ._binary import i16le as i16 +from ._binary import i32le as i32 + +# +# -------------------------------------------------------------------- + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"\0\0\2\0" + + +## +# Image plugin for Windows Cursor files. + + +class CurImageFile(BmpImagePlugin.BmpImageFile): + format = "CUR" + format_description = "Windows Cursor" + + def _open(self) -> None: + offset = self.fp.tell() + + # check magic + s = self.fp.read(6) + if not _accept(s): + msg = "not a CUR file" + raise SyntaxError(msg) + + # pick the largest cursor in the file + m = b"" + for i in range(i16(s, 4)): + s = self.fp.read(16) + if not m: + m = s + elif s[0] > m[0] and s[1] > m[1]: + m = s + if not m: + msg = "No cursors were found" + raise TypeError(msg) + + # load as bitmap + self._bitmap(i32(m, 12) + offset) + + # patch up the bitmap height + self._size = self.size[0], self.size[1] // 2 + d, e, o, a = self.tile[0] + self.tile[0] = ImageFile._Tile(d, (0, 0) + self.size, o, a) + + +# +# -------------------------------------------------------------------- + +Image.register_open(CurImageFile.format, CurImageFile, _accept) + +Image.register_extension(CurImageFile.format, ".cur") diff --git a/venv/lib/python3.12/site-packages/PIL/DcxImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/DcxImagePlugin.py new file mode 100644 index 0000000..f67f27d --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/DcxImagePlugin.py @@ -0,0 +1,80 @@ +# +# The Python Imaging Library. +# $Id$ +# +# DCX file handling +# +# DCX is a container file format defined by Intel, commonly used +# for fax applications. Each DCX file consists of a directory +# (a list of file offsets) followed by a set of (usually 1-bit) +# PCX files. +# +# History: +# 1995-09-09 fl Created +# 1996-03-20 fl Properly derived from PcxImageFile. +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2002-07-30 fl Fixed file handling +# +# Copyright (c) 1997-98 by Secret Labs AB. +# Copyright (c) 1995-96 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image +from ._binary import i32le as i32 +from .PcxImagePlugin import PcxImageFile + +MAGIC = 0x3ADE68B1 # QUIZ: what's this value, then? + + +def _accept(prefix: bytes) -> bool: + return len(prefix) >= 4 and i32(prefix) == MAGIC + + +## +# Image plugin for the Intel DCX format. + + +class DcxImageFile(PcxImageFile): + format = "DCX" + format_description = "Intel DCX" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + # Header + s = self.fp.read(4) + if not _accept(s): + msg = "not a DCX file" + raise SyntaxError(msg) + + # Component directory + self._offset = [] + for i in range(1024): + offset = i32(self.fp.read(4)) + if not offset: + break + self._offset.append(offset) + + self._fp = self.fp + self.frame = -1 + self.n_frames = len(self._offset) + self.is_animated = self.n_frames > 1 + self.seek(0) + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + self.frame = frame + self.fp = self._fp + self.fp.seek(self._offset[frame]) + PcxImageFile._open(self) + + def tell(self) -> int: + return self.frame + + +Image.register_open(DcxImageFile.format, DcxImageFile, _accept) + +Image.register_extension(DcxImageFile.format, ".dcx") diff --git a/venv/lib/python3.12/site-packages/PIL/DdsImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/DdsImagePlugin.py new file mode 100644 index 0000000..1b64082 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/DdsImagePlugin.py @@ -0,0 +1,575 @@ +""" +A Pillow loader for .dds files (S3TC-compressed aka DXTC) +Jerome Leclanche + +Documentation: +https://web.archive.org/web/20170802060935/http://oss.sgi.com/projects/ogl-sample/registry/EXT/texture_compression_s3tc.txt + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: +https://creativecommons.org/publicdomain/zero/1.0/ +""" + +from __future__ import annotations + +import io +import struct +import sys +from enum import IntEnum, IntFlag +from typing import IO + +from . import Image, ImageFile, ImagePalette +from ._binary import i32le as i32 +from ._binary import o8 +from ._binary import o32le as o32 + +# Magic ("DDS ") +DDS_MAGIC = 0x20534444 + + +# DDS flags +class DDSD(IntFlag): + CAPS = 0x1 + HEIGHT = 0x2 + WIDTH = 0x4 + PITCH = 0x8 + PIXELFORMAT = 0x1000 + MIPMAPCOUNT = 0x20000 + LINEARSIZE = 0x80000 + DEPTH = 0x800000 + + +# DDS caps +class DDSCAPS(IntFlag): + COMPLEX = 0x8 + TEXTURE = 0x1000 + MIPMAP = 0x400000 + + +class DDSCAPS2(IntFlag): + CUBEMAP = 0x200 + CUBEMAP_POSITIVEX = 0x400 + CUBEMAP_NEGATIVEX = 0x800 + CUBEMAP_POSITIVEY = 0x1000 + CUBEMAP_NEGATIVEY = 0x2000 + CUBEMAP_POSITIVEZ = 0x4000 + CUBEMAP_NEGATIVEZ = 0x8000 + VOLUME = 0x200000 + + +# Pixel Format +class DDPF(IntFlag): + ALPHAPIXELS = 0x1 + ALPHA = 0x2 + FOURCC = 0x4 + PALETTEINDEXED8 = 0x20 + RGB = 0x40 + LUMINANCE = 0x20000 + + +# dxgiformat.h +class DXGI_FORMAT(IntEnum): + UNKNOWN = 0 + R32G32B32A32_TYPELESS = 1 + R32G32B32A32_FLOAT = 2 + R32G32B32A32_UINT = 3 + R32G32B32A32_SINT = 4 + R32G32B32_TYPELESS = 5 + R32G32B32_FLOAT = 6 + R32G32B32_UINT = 7 + R32G32B32_SINT = 8 + R16G16B16A16_TYPELESS = 9 + R16G16B16A16_FLOAT = 10 + R16G16B16A16_UNORM = 11 + R16G16B16A16_UINT = 12 + R16G16B16A16_SNORM = 13 + R16G16B16A16_SINT = 14 + R32G32_TYPELESS = 15 + R32G32_FLOAT = 16 + R32G32_UINT = 17 + R32G32_SINT = 18 + R32G8X24_TYPELESS = 19 + D32_FLOAT_S8X24_UINT = 20 + R32_FLOAT_X8X24_TYPELESS = 21 + X32_TYPELESS_G8X24_UINT = 22 + R10G10B10A2_TYPELESS = 23 + R10G10B10A2_UNORM = 24 + R10G10B10A2_UINT = 25 + R11G11B10_FLOAT = 26 + R8G8B8A8_TYPELESS = 27 + R8G8B8A8_UNORM = 28 + R8G8B8A8_UNORM_SRGB = 29 + R8G8B8A8_UINT = 30 + R8G8B8A8_SNORM = 31 + R8G8B8A8_SINT = 32 + R16G16_TYPELESS = 33 + R16G16_FLOAT = 34 + R16G16_UNORM = 35 + R16G16_UINT = 36 + R16G16_SNORM = 37 + R16G16_SINT = 38 + R32_TYPELESS = 39 + D32_FLOAT = 40 + R32_FLOAT = 41 + R32_UINT = 42 + R32_SINT = 43 + R24G8_TYPELESS = 44 + D24_UNORM_S8_UINT = 45 + R24_UNORM_X8_TYPELESS = 46 + X24_TYPELESS_G8_UINT = 47 + R8G8_TYPELESS = 48 + R8G8_UNORM = 49 + R8G8_UINT = 50 + R8G8_SNORM = 51 + R8G8_SINT = 52 + R16_TYPELESS = 53 + R16_FLOAT = 54 + D16_UNORM = 55 + R16_UNORM = 56 + R16_UINT = 57 + R16_SNORM = 58 + R16_SINT = 59 + R8_TYPELESS = 60 + R8_UNORM = 61 + R8_UINT = 62 + R8_SNORM = 63 + R8_SINT = 64 + A8_UNORM = 65 + R1_UNORM = 66 + R9G9B9E5_SHAREDEXP = 67 + R8G8_B8G8_UNORM = 68 + G8R8_G8B8_UNORM = 69 + BC1_TYPELESS = 70 + BC1_UNORM = 71 + BC1_UNORM_SRGB = 72 + BC2_TYPELESS = 73 + BC2_UNORM = 74 + BC2_UNORM_SRGB = 75 + BC3_TYPELESS = 76 + BC3_UNORM = 77 + BC3_UNORM_SRGB = 78 + BC4_TYPELESS = 79 + BC4_UNORM = 80 + BC4_SNORM = 81 + BC5_TYPELESS = 82 + BC5_UNORM = 83 + BC5_SNORM = 84 + B5G6R5_UNORM = 85 + B5G5R5A1_UNORM = 86 + B8G8R8A8_UNORM = 87 + B8G8R8X8_UNORM = 88 + R10G10B10_XR_BIAS_A2_UNORM = 89 + B8G8R8A8_TYPELESS = 90 + B8G8R8A8_UNORM_SRGB = 91 + B8G8R8X8_TYPELESS = 92 + B8G8R8X8_UNORM_SRGB = 93 + BC6H_TYPELESS = 94 + BC6H_UF16 = 95 + BC6H_SF16 = 96 + BC7_TYPELESS = 97 + BC7_UNORM = 98 + BC7_UNORM_SRGB = 99 + AYUV = 100 + Y410 = 101 + Y416 = 102 + NV12 = 103 + P010 = 104 + P016 = 105 + OPAQUE_420 = 106 + YUY2 = 107 + Y210 = 108 + Y216 = 109 + NV11 = 110 + AI44 = 111 + IA44 = 112 + P8 = 113 + A8P8 = 114 + B4G4R4A4_UNORM = 115 + P208 = 130 + V208 = 131 + V408 = 132 + SAMPLER_FEEDBACK_MIN_MIP_OPAQUE = 189 + SAMPLER_FEEDBACK_MIP_REGION_USED_OPAQUE = 190 + + +class D3DFMT(IntEnum): + UNKNOWN = 0 + R8G8B8 = 20 + A8R8G8B8 = 21 + X8R8G8B8 = 22 + R5G6B5 = 23 + X1R5G5B5 = 24 + A1R5G5B5 = 25 + A4R4G4B4 = 26 + R3G3B2 = 27 + A8 = 28 + A8R3G3B2 = 29 + X4R4G4B4 = 30 + A2B10G10R10 = 31 + A8B8G8R8 = 32 + X8B8G8R8 = 33 + G16R16 = 34 + A2R10G10B10 = 35 + A16B16G16R16 = 36 + A8P8 = 40 + P8 = 41 + L8 = 50 + A8L8 = 51 + A4L4 = 52 + V8U8 = 60 + L6V5U5 = 61 + X8L8V8U8 = 62 + Q8W8V8U8 = 63 + V16U16 = 64 + A2W10V10U10 = 67 + D16_LOCKABLE = 70 + D32 = 71 + D15S1 = 73 + D24S8 = 75 + D24X8 = 77 + D24X4S4 = 79 + D16 = 80 + D32F_LOCKABLE = 82 + D24FS8 = 83 + D32_LOCKABLE = 84 + S8_LOCKABLE = 85 + L16 = 81 + VERTEXDATA = 100 + INDEX16 = 101 + INDEX32 = 102 + Q16W16V16U16 = 110 + R16F = 111 + G16R16F = 112 + A16B16G16R16F = 113 + R32F = 114 + G32R32F = 115 + A32B32G32R32F = 116 + CxV8U8 = 117 + A1 = 118 + A2B10G10R10_XR_BIAS = 119 + BINARYBUFFER = 199 + + UYVY = i32(b"UYVY") + R8G8_B8G8 = i32(b"RGBG") + YUY2 = i32(b"YUY2") + G8R8_G8B8 = i32(b"GRGB") + DXT1 = i32(b"DXT1") + DXT2 = i32(b"DXT2") + DXT3 = i32(b"DXT3") + DXT4 = i32(b"DXT4") + DXT5 = i32(b"DXT5") + DX10 = i32(b"DX10") + BC4S = i32(b"BC4S") + BC4U = i32(b"BC4U") + BC5S = i32(b"BC5S") + BC5U = i32(b"BC5U") + ATI1 = i32(b"ATI1") + ATI2 = i32(b"ATI2") + MULTI2_ARGB8 = i32(b"MET1") + + +# Backward compatibility layer +module = sys.modules[__name__] +for item in DDSD: + assert item.name is not None + setattr(module, f"DDSD_{item.name}", item.value) +for item1 in DDSCAPS: + assert item1.name is not None + setattr(module, f"DDSCAPS_{item1.name}", item1.value) +for item2 in DDSCAPS2: + assert item2.name is not None + setattr(module, f"DDSCAPS2_{item2.name}", item2.value) +for item3 in DDPF: + assert item3.name is not None + setattr(module, f"DDPF_{item3.name}", item3.value) + +DDS_FOURCC = DDPF.FOURCC +DDS_RGB = DDPF.RGB +DDS_RGBA = DDPF.RGB | DDPF.ALPHAPIXELS +DDS_LUMINANCE = DDPF.LUMINANCE +DDS_LUMINANCEA = DDPF.LUMINANCE | DDPF.ALPHAPIXELS +DDS_ALPHA = DDPF.ALPHA +DDS_PAL8 = DDPF.PALETTEINDEXED8 + +DDS_HEADER_FLAGS_TEXTURE = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PIXELFORMAT +DDS_HEADER_FLAGS_MIPMAP = DDSD.MIPMAPCOUNT +DDS_HEADER_FLAGS_VOLUME = DDSD.DEPTH +DDS_HEADER_FLAGS_PITCH = DDSD.PITCH +DDS_HEADER_FLAGS_LINEARSIZE = DDSD.LINEARSIZE + +DDS_HEIGHT = DDSD.HEIGHT +DDS_WIDTH = DDSD.WIDTH + +DDS_SURFACE_FLAGS_TEXTURE = DDSCAPS.TEXTURE +DDS_SURFACE_FLAGS_MIPMAP = DDSCAPS.COMPLEX | DDSCAPS.MIPMAP +DDS_SURFACE_FLAGS_CUBEMAP = DDSCAPS.COMPLEX + +DDS_CUBEMAP_POSITIVEX = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEX +DDS_CUBEMAP_NEGATIVEX = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEX +DDS_CUBEMAP_POSITIVEY = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEY +DDS_CUBEMAP_NEGATIVEY = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEY +DDS_CUBEMAP_POSITIVEZ = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_POSITIVEZ +DDS_CUBEMAP_NEGATIVEZ = DDSCAPS2.CUBEMAP | DDSCAPS2.CUBEMAP_NEGATIVEZ + +DXT1_FOURCC = D3DFMT.DXT1 +DXT3_FOURCC = D3DFMT.DXT3 +DXT5_FOURCC = D3DFMT.DXT5 + +DXGI_FORMAT_R8G8B8A8_TYPELESS = DXGI_FORMAT.R8G8B8A8_TYPELESS +DXGI_FORMAT_R8G8B8A8_UNORM = DXGI_FORMAT.R8G8B8A8_UNORM +DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = DXGI_FORMAT.R8G8B8A8_UNORM_SRGB +DXGI_FORMAT_BC5_TYPELESS = DXGI_FORMAT.BC5_TYPELESS +DXGI_FORMAT_BC5_UNORM = DXGI_FORMAT.BC5_UNORM +DXGI_FORMAT_BC5_SNORM = DXGI_FORMAT.BC5_SNORM +DXGI_FORMAT_BC6H_UF16 = DXGI_FORMAT.BC6H_UF16 +DXGI_FORMAT_BC6H_SF16 = DXGI_FORMAT.BC6H_SF16 +DXGI_FORMAT_BC7_TYPELESS = DXGI_FORMAT.BC7_TYPELESS +DXGI_FORMAT_BC7_UNORM = DXGI_FORMAT.BC7_UNORM +DXGI_FORMAT_BC7_UNORM_SRGB = DXGI_FORMAT.BC7_UNORM_SRGB + + +class DdsImageFile(ImageFile.ImageFile): + format = "DDS" + format_description = "DirectDraw Surface" + + def _open(self) -> None: + if not _accept(self.fp.read(4)): + msg = "not a DDS file" + raise SyntaxError(msg) + (header_size,) = struct.unpack(" None: + pass + + +class DdsRgbDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + bitcount, masks = self.args + + # Some masks will be padded with zeros, e.g. R 0b11 G 0b1100 + # Calculate how many zeros each mask is padded with + mask_offsets = [] + # And the maximum value of each channel without the padding + mask_totals = [] + for mask in masks: + offset = 0 + if mask != 0: + while mask >> (offset + 1) << (offset + 1) == mask: + offset += 1 + mask_offsets.append(offset) + mask_totals.append(mask >> offset) + + data = bytearray() + bytecount = bitcount // 8 + dest_length = self.state.xsize * self.state.ysize * len(masks) + while len(data) < dest_length: + value = int.from_bytes(self.fd.read(bytecount), "little") + for i, mask in enumerate(masks): + masked_value = value & mask + # Remove the zero padding, and scale it to 8 bits + data += o8( + int(((masked_value >> mask_offsets[i]) / mask_totals[i]) * 255) + ) + self.set_as_raw(data) + return -1, 0 + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode not in ("RGB", "RGBA", "L", "LA"): + msg = f"cannot write mode {im.mode} as DDS" + raise OSError(msg) + + alpha = im.mode[-1] == "A" + if im.mode[0] == "L": + pixel_flags = DDPF.LUMINANCE + rawmode = im.mode + if alpha: + rgba_mask = [0x000000FF, 0x000000FF, 0x000000FF] + else: + rgba_mask = [0xFF000000, 0xFF000000, 0xFF000000] + else: + pixel_flags = DDPF.RGB + rawmode = im.mode[::-1] + rgba_mask = [0x00FF0000, 0x0000FF00, 0x000000FF] + + if alpha: + r, g, b, a = im.split() + im = Image.merge("RGBA", (a, r, g, b)) + if alpha: + pixel_flags |= DDPF.ALPHAPIXELS + rgba_mask.append(0xFF000000 if alpha else 0) + + flags = DDSD.CAPS | DDSD.HEIGHT | DDSD.WIDTH | DDSD.PITCH | DDSD.PIXELFORMAT + bitcount = len(im.getbands()) * 8 + pitch = (im.width * bitcount + 7) // 8 + + fp.write( + o32(DDS_MAGIC) + + struct.pack( + "<7I", + 124, # header size + flags, # flags + im.height, + im.width, + pitch, + 0, # depth + 0, # mipmaps + ) + + struct.pack("11I", *((0,) * 11)) # reserved + # pfsize, pfflags, fourcc, bitcount + + struct.pack("<4I", 32, pixel_flags, 0, bitcount) + + struct.pack("<4I", *rgba_mask) # dwRGBABitMask + + struct.pack("<5I", DDSCAPS.TEXTURE, 0, 0, 0, 0) + ) + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))] + ) + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"DDS " + + +Image.register_open(DdsImageFile.format, DdsImageFile, _accept) +Image.register_decoder("dds_rgb", DdsRgbDecoder) +Image.register_save(DdsImageFile.format, _save) +Image.register_extension(DdsImageFile.format, ".dds") diff --git a/venv/lib/python3.12/site-packages/PIL/EpsImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/EpsImagePlugin.py new file mode 100644 index 0000000..fb1e301 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/EpsImagePlugin.py @@ -0,0 +1,474 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EPS file handling +# +# History: +# 1995-09-01 fl Created (0.1) +# 1996-05-18 fl Don't choke on "atend" fields, Ghostscript interface (0.2) +# 1996-08-22 fl Don't choke on floating point BoundingBox values +# 1996-08-23 fl Handle files from Macintosh (0.3) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2003-09-07 fl Check gs.close status (from Federico Di Gregorio) (0.5) +# 2014-05-07 e Handling of EPS with binary preview and fixed resolution +# resizing +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import re +import subprocess +import sys +import tempfile +from typing import IO + +from . import Image, ImageFile +from ._binary import i32le as i32 + +# -------------------------------------------------------------------- + + +split = re.compile(r"^%%([^:]*):[ \t]*(.*)[ \t]*$") +field = re.compile(r"^%[%!\w]([^:]*)[ \t]*$") + +gs_binary: str | bool | None = None +gs_windows_binary = None + + +def has_ghostscript() -> bool: + global gs_binary, gs_windows_binary + if gs_binary is None: + if sys.platform.startswith("win"): + if gs_windows_binary is None: + import shutil + + for binary in ("gswin32c", "gswin64c", "gs"): + if shutil.which(binary) is not None: + gs_windows_binary = binary + break + else: + gs_windows_binary = False + gs_binary = gs_windows_binary + else: + try: + subprocess.check_call(["gs", "--version"], stdout=subprocess.DEVNULL) + gs_binary = "gs" + except OSError: + gs_binary = False + return gs_binary is not False + + +def Ghostscript( + tile: list[ImageFile._Tile], + size: tuple[int, int], + fp: IO[bytes], + scale: int = 1, + transparency: bool = False, +) -> Image.core.ImagingCore: + """Render an image using Ghostscript""" + global gs_binary + if not has_ghostscript(): + msg = "Unable to locate Ghostscript on paths" + raise OSError(msg) + assert isinstance(gs_binary, str) + + # Unpack decoder tile + args = tile[0].args + assert isinstance(args, tuple) + length, bbox = args + + # Hack to support hi-res rendering + scale = int(scale) or 1 + width = size[0] * scale + height = size[1] * scale + # resolution is dependent on bbox and size + res_x = 72.0 * width / (bbox[2] - bbox[0]) + res_y = 72.0 * height / (bbox[3] - bbox[1]) + + out_fd, outfile = tempfile.mkstemp() + os.close(out_fd) + + infile_temp = None + if hasattr(fp, "name") and os.path.exists(fp.name): + infile = fp.name + else: + in_fd, infile_temp = tempfile.mkstemp() + os.close(in_fd) + infile = infile_temp + + # Ignore length and offset! + # Ghostscript can read it + # Copy whole file to read in Ghostscript + with open(infile_temp, "wb") as f: + # fetch length of fp + fp.seek(0, io.SEEK_END) + fsize = fp.tell() + # ensure start position + # go back + fp.seek(0) + lengthfile = fsize + while lengthfile > 0: + s = fp.read(min(lengthfile, 100 * 1024)) + if not s: + break + lengthfile -= len(s) + f.write(s) + + if transparency: + # "RGBA" + device = "pngalpha" + else: + # "pnmraw" automatically chooses between + # PBM ("1"), PGM ("L"), and PPM ("RGB"). + device = "pnmraw" + + # Build Ghostscript command + command = [ + gs_binary, + "-q", # quiet mode + f"-g{width:d}x{height:d}", # set output geometry (pixels) + f"-r{res_x:f}x{res_y:f}", # set input DPI (dots per inch) + "-dBATCH", # exit after processing + "-dNOPAUSE", # don't pause between pages + "-dSAFER", # safe mode + f"-sDEVICE={device}", + f"-sOutputFile={outfile}", # output file + # adjust for image origin + "-c", + f"{-bbox[0]} {-bbox[1]} translate", + "-f", + infile, # input file + # showpage (see https://bugs.ghostscript.com/show_bug.cgi?id=698272) + "-c", + "showpage", + ] + + # push data through Ghostscript + try: + startupinfo = None + if sys.platform.startswith("win"): + startupinfo = subprocess.STARTUPINFO() + startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW + subprocess.check_call(command, startupinfo=startupinfo) + with Image.open(outfile) as out_im: + out_im.load() + return out_im.im.copy() + finally: + try: + os.unlink(outfile) + if infile_temp: + os.unlink(infile_temp) + except OSError: + pass + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"%!PS" or (len(prefix) >= 4 and i32(prefix) == 0xC6D3D0C5) + + +## +# Image plugin for Encapsulated PostScript. This plugin supports only +# a few variants of this format. + + +class EpsImageFile(ImageFile.ImageFile): + """EPS File Parser for the Python Imaging Library""" + + format = "EPS" + format_description = "Encapsulated Postscript" + + mode_map = {1: "L", 2: "LAB", 3: "RGB", 4: "CMYK"} + + def _open(self) -> None: + (length, offset) = self._find_offset(self.fp) + + # go to offset - start of "%!PS" + self.fp.seek(offset) + + self._mode = "RGB" + + # When reading header comments, the first comment is used. + # When reading trailer comments, the last comment is used. + bounding_box: list[int] | None = None + imagedata_size: tuple[int, int] | None = None + + byte_arr = bytearray(255) + bytes_mv = memoryview(byte_arr) + bytes_read = 0 + reading_header_comments = True + reading_trailer_comments = False + trailer_reached = False + + def check_required_header_comments() -> None: + """ + The EPS specification requires that some headers exist. + This should be checked when the header comments formally end, + when image data starts, or when the file ends, whichever comes first. + """ + if "PS-Adobe" not in self.info: + msg = 'EPS header missing "%!PS-Adobe" comment' + raise SyntaxError(msg) + if "BoundingBox" not in self.info: + msg = 'EPS header missing "%%BoundingBox" comment' + raise SyntaxError(msg) + + def read_comment(s: str) -> bool: + nonlocal bounding_box, reading_trailer_comments + try: + m = split.match(s) + except re.error as e: + msg = "not an EPS file" + raise SyntaxError(msg) from e + + if not m: + return False + + k, v = m.group(1, 2) + self.info[k] = v + if k == "BoundingBox": + if v == "(atend)": + reading_trailer_comments = True + elif not bounding_box or (trailer_reached and reading_trailer_comments): + try: + # Note: The DSC spec says that BoundingBox + # fields should be integers, but some drivers + # put floating point values there anyway. + bounding_box = [int(float(i)) for i in v.split()] + except Exception: + pass + return True + + while True: + byte = self.fp.read(1) + if byte == b"": + # if we didn't read a byte we must be at the end of the file + if bytes_read == 0: + if reading_header_comments: + check_required_header_comments() + break + elif byte in b"\r\n": + # if we read a line ending character, ignore it and parse what + # we have already read. if we haven't read any other characters, + # continue reading + if bytes_read == 0: + continue + else: + # ASCII/hexadecimal lines in an EPS file must not exceed + # 255 characters, not including line ending characters + if bytes_read >= 255: + # only enforce this for lines starting with a "%", + # otherwise assume it's binary data + if byte_arr[0] == ord("%"): + msg = "not an EPS file" + raise SyntaxError(msg) + else: + if reading_header_comments: + check_required_header_comments() + reading_header_comments = False + # reset bytes_read so we can keep reading + # data until the end of the line + bytes_read = 0 + byte_arr[bytes_read] = byte[0] + bytes_read += 1 + continue + + if reading_header_comments: + # Load EPS header + + # if this line doesn't start with a "%", + # or does start with "%%EndComments", + # then we've reached the end of the header/comments + if byte_arr[0] != ord("%") or bytes_mv[:13] == b"%%EndComments": + check_required_header_comments() + reading_header_comments = False + continue + + s = str(bytes_mv[:bytes_read], "latin-1") + if not read_comment(s): + m = field.match(s) + if m: + k = m.group(1) + if k[:8] == "PS-Adobe": + self.info["PS-Adobe"] = k[9:] + else: + self.info[k] = "" + elif s[0] == "%": + # handle non-DSC PostScript comments that some + # tools mistakenly put in the Comments section + pass + else: + msg = "bad EPS header" + raise OSError(msg) + elif bytes_mv[:11] == b"%ImageData:": + # Check for an "ImageData" descriptor + # https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577413_pgfId-1035096 + + # If we've already read an "ImageData" descriptor, + # don't read another one. + if imagedata_size: + bytes_read = 0 + continue + + # Values: + # columns + # rows + # bit depth (1 or 8) + # mode (1: L, 2: LAB, 3: RGB, 4: CMYK) + # number of padding channels + # block size (number of bytes per row per channel) + # binary/ascii (1: binary, 2: ascii) + # data start identifier (the image data follows after a single line + # consisting only of this quoted value) + image_data_values = byte_arr[11:bytes_read].split(None, 7) + columns, rows, bit_depth, mode_id = ( + int(value) for value in image_data_values[:4] + ) + + if bit_depth == 1: + self._mode = "1" + elif bit_depth == 8: + try: + self._mode = self.mode_map[mode_id] + except ValueError: + break + else: + break + + # Parse the columns and rows after checking the bit depth and mode + # in case the bit depth and/or mode are invalid. + imagedata_size = columns, rows + elif bytes_mv[:5] == b"%%EOF": + break + elif trailer_reached and reading_trailer_comments: + # Load EPS trailer + s = str(bytes_mv[:bytes_read], "latin-1") + read_comment(s) + elif bytes_mv[:9] == b"%%Trailer": + trailer_reached = True + bytes_read = 0 + + # A "BoundingBox" is always required, + # even if an "ImageData" descriptor size exists. + if not bounding_box: + msg = "cannot determine EPS bounding box" + raise OSError(msg) + + # An "ImageData" size takes precedence over the "BoundingBox". + self._size = imagedata_size or ( + bounding_box[2] - bounding_box[0], + bounding_box[3] - bounding_box[1], + ) + + self.tile = [ + ImageFile._Tile("eps", (0, 0) + self.size, offset, (length, bounding_box)) + ] + + def _find_offset(self, fp: IO[bytes]) -> tuple[int, int]: + s = fp.read(4) + + if s == b"%!PS": + # for HEAD without binary preview + fp.seek(0, io.SEEK_END) + length = fp.tell() + offset = 0 + elif i32(s) == 0xC6D3D0C5: + # FIX for: Some EPS file not handled correctly / issue #302 + # EPS can contain binary data + # or start directly with latin coding + # more info see: + # https://web.archive.org/web/20160528181353/http://partners.adobe.com/public/developer/en/ps/5002.EPSF_Spec.pdf + s = fp.read(8) + offset = i32(s) + length = i32(s, 4) + else: + msg = "not an EPS file" + raise SyntaxError(msg) + + return length, offset + + def load( + self, scale: int = 1, transparency: bool = False + ) -> Image.core.PixelAccess | None: + # Load EPS via Ghostscript + if self.tile: + self.im = Ghostscript(self.tile, self.size, self.fp, scale, transparency) + self._mode = self.im.mode + self._size = self.im.size + self.tile = [] + return Image.Image.load(self) + + def load_seek(self, pos: int) -> None: + # we can't incrementally load, so force ImageFile.parser to + # use our custom load method by defining this method. + pass + + +# -------------------------------------------------------------------- + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes, eps: int = 1) -> None: + """EPS Writer for the Python Imaging Library.""" + + # make sure image data is available + im.load() + + # determine PostScript image mode + if im.mode == "L": + operator = (8, 1, b"image") + elif im.mode == "RGB": + operator = (8, 3, b"false 3 colorimage") + elif im.mode == "CMYK": + operator = (8, 4, b"false 4 colorimage") + else: + msg = "image mode is not supported" + raise ValueError(msg) + + if eps: + # write EPS header + fp.write(b"%!PS-Adobe-3.0 EPSF-3.0\n") + fp.write(b"%%Creator: PIL 0.1 EpsEncode\n") + # fp.write("%%CreationDate: %s"...) + fp.write(b"%%%%BoundingBox: 0 0 %d %d\n" % im.size) + fp.write(b"%%Pages: 1\n") + fp.write(b"%%EndComments\n") + fp.write(b"%%Page: 1 1\n") + fp.write(b"%%ImageData: %d %d " % im.size) + fp.write(b'%d %d 0 1 1 "%s"\n' % operator) + + # image header + fp.write(b"gsave\n") + fp.write(b"10 dict begin\n") + fp.write(b"/buf %d string def\n" % (im.size[0] * operator[1])) + fp.write(b"%d %d scale\n" % im.size) + fp.write(b"%d %d 8\n" % im.size) # <= bits + fp.write(b"[%d 0 0 -%d 0 %d]\n" % (im.size[0], im.size[1], im.size[1])) + fp.write(b"{ currentfile buf readhexstring pop } bind\n") + fp.write(operator[2] + b"\n") + if hasattr(fp, "flush"): + fp.flush() + + ImageFile._save(im, fp, [ImageFile._Tile("eps", (0, 0) + im.size, 0, None)]) + + fp.write(b"\n%%%%EndBinary\n") + fp.write(b"grestore end\n") + if hasattr(fp, "flush"): + fp.flush() + + +# -------------------------------------------------------------------- + + +Image.register_open(EpsImageFile.format, EpsImageFile, _accept) + +Image.register_save(EpsImageFile.format, _save) + +Image.register_extensions(EpsImageFile.format, [".ps", ".eps"]) + +Image.register_mime(EpsImageFile.format, "application/postscript") diff --git a/venv/lib/python3.12/site-packages/PIL/ExifTags.py b/venv/lib/python3.12/site-packages/PIL/ExifTags.py new file mode 100644 index 0000000..39b4aa5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ExifTags.py @@ -0,0 +1,381 @@ +# +# The Python Imaging Library. +# $Id$ +# +# EXIF tags +# +# Copyright (c) 2003 by Secret Labs AB +# +# See the README file for information on usage and redistribution. +# + +""" +This module provides constants and clear-text names for various +well-known EXIF tags. +""" +from __future__ import annotations + +from enum import IntEnum + + +class Base(IntEnum): + # possibly incomplete + InteropIndex = 0x0001 + ProcessingSoftware = 0x000B + NewSubfileType = 0x00FE + SubfileType = 0x00FF + ImageWidth = 0x0100 + ImageLength = 0x0101 + BitsPerSample = 0x0102 + Compression = 0x0103 + PhotometricInterpretation = 0x0106 + Thresholding = 0x0107 + CellWidth = 0x0108 + CellLength = 0x0109 + FillOrder = 0x010A + DocumentName = 0x010D + ImageDescription = 0x010E + Make = 0x010F + Model = 0x0110 + StripOffsets = 0x0111 + Orientation = 0x0112 + SamplesPerPixel = 0x0115 + RowsPerStrip = 0x0116 + StripByteCounts = 0x0117 + MinSampleValue = 0x0118 + MaxSampleValue = 0x0119 + XResolution = 0x011A + YResolution = 0x011B + PlanarConfiguration = 0x011C + PageName = 0x011D + FreeOffsets = 0x0120 + FreeByteCounts = 0x0121 + GrayResponseUnit = 0x0122 + GrayResponseCurve = 0x0123 + T4Options = 0x0124 + T6Options = 0x0125 + ResolutionUnit = 0x0128 + PageNumber = 0x0129 + TransferFunction = 0x012D + Software = 0x0131 + DateTime = 0x0132 + Artist = 0x013B + HostComputer = 0x013C + Predictor = 0x013D + WhitePoint = 0x013E + PrimaryChromaticities = 0x013F + ColorMap = 0x0140 + HalftoneHints = 0x0141 + TileWidth = 0x0142 + TileLength = 0x0143 + TileOffsets = 0x0144 + TileByteCounts = 0x0145 + SubIFDs = 0x014A + InkSet = 0x014C + InkNames = 0x014D + NumberOfInks = 0x014E + DotRange = 0x0150 + TargetPrinter = 0x0151 + ExtraSamples = 0x0152 + SampleFormat = 0x0153 + SMinSampleValue = 0x0154 + SMaxSampleValue = 0x0155 + TransferRange = 0x0156 + ClipPath = 0x0157 + XClipPathUnits = 0x0158 + YClipPathUnits = 0x0159 + Indexed = 0x015A + JPEGTables = 0x015B + OPIProxy = 0x015F + JPEGProc = 0x0200 + JpegIFOffset = 0x0201 + JpegIFByteCount = 0x0202 + JpegRestartInterval = 0x0203 + JpegLosslessPredictors = 0x0205 + JpegPointTransforms = 0x0206 + JpegQTables = 0x0207 + JpegDCTables = 0x0208 + JpegACTables = 0x0209 + YCbCrCoefficients = 0x0211 + YCbCrSubSampling = 0x0212 + YCbCrPositioning = 0x0213 + ReferenceBlackWhite = 0x0214 + XMLPacket = 0x02BC + RelatedImageFileFormat = 0x1000 + RelatedImageWidth = 0x1001 + RelatedImageLength = 0x1002 + Rating = 0x4746 + RatingPercent = 0x4749 + ImageID = 0x800D + CFARepeatPatternDim = 0x828D + BatteryLevel = 0x828F + Copyright = 0x8298 + ExposureTime = 0x829A + FNumber = 0x829D + IPTCNAA = 0x83BB + ImageResources = 0x8649 + ExifOffset = 0x8769 + InterColorProfile = 0x8773 + ExposureProgram = 0x8822 + SpectralSensitivity = 0x8824 + GPSInfo = 0x8825 + ISOSpeedRatings = 0x8827 + OECF = 0x8828 + Interlace = 0x8829 + TimeZoneOffset = 0x882A + SelfTimerMode = 0x882B + SensitivityType = 0x8830 + StandardOutputSensitivity = 0x8831 + RecommendedExposureIndex = 0x8832 + ISOSpeed = 0x8833 + ISOSpeedLatitudeyyy = 0x8834 + ISOSpeedLatitudezzz = 0x8835 + ExifVersion = 0x9000 + DateTimeOriginal = 0x9003 + DateTimeDigitized = 0x9004 + OffsetTime = 0x9010 + OffsetTimeOriginal = 0x9011 + OffsetTimeDigitized = 0x9012 + ComponentsConfiguration = 0x9101 + CompressedBitsPerPixel = 0x9102 + ShutterSpeedValue = 0x9201 + ApertureValue = 0x9202 + BrightnessValue = 0x9203 + ExposureBiasValue = 0x9204 + MaxApertureValue = 0x9205 + SubjectDistance = 0x9206 + MeteringMode = 0x9207 + LightSource = 0x9208 + Flash = 0x9209 + FocalLength = 0x920A + Noise = 0x920D + ImageNumber = 0x9211 + SecurityClassification = 0x9212 + ImageHistory = 0x9213 + TIFFEPStandardID = 0x9216 + MakerNote = 0x927C + UserComment = 0x9286 + SubsecTime = 0x9290 + SubsecTimeOriginal = 0x9291 + SubsecTimeDigitized = 0x9292 + AmbientTemperature = 0x9400 + Humidity = 0x9401 + Pressure = 0x9402 + WaterDepth = 0x9403 + Acceleration = 0x9404 + CameraElevationAngle = 0x9405 + XPTitle = 0x9C9B + XPComment = 0x9C9C + XPAuthor = 0x9C9D + XPKeywords = 0x9C9E + XPSubject = 0x9C9F + FlashPixVersion = 0xA000 + ColorSpace = 0xA001 + ExifImageWidth = 0xA002 + ExifImageHeight = 0xA003 + RelatedSoundFile = 0xA004 + ExifInteroperabilityOffset = 0xA005 + FlashEnergy = 0xA20B + SpatialFrequencyResponse = 0xA20C + FocalPlaneXResolution = 0xA20E + FocalPlaneYResolution = 0xA20F + FocalPlaneResolutionUnit = 0xA210 + SubjectLocation = 0xA214 + ExposureIndex = 0xA215 + SensingMethod = 0xA217 + FileSource = 0xA300 + SceneType = 0xA301 + CFAPattern = 0xA302 + CustomRendered = 0xA401 + ExposureMode = 0xA402 + WhiteBalance = 0xA403 + DigitalZoomRatio = 0xA404 + FocalLengthIn35mmFilm = 0xA405 + SceneCaptureType = 0xA406 + GainControl = 0xA407 + Contrast = 0xA408 + Saturation = 0xA409 + Sharpness = 0xA40A + DeviceSettingDescription = 0xA40B + SubjectDistanceRange = 0xA40C + ImageUniqueID = 0xA420 + CameraOwnerName = 0xA430 + BodySerialNumber = 0xA431 + LensSpecification = 0xA432 + LensMake = 0xA433 + LensModel = 0xA434 + LensSerialNumber = 0xA435 + CompositeImage = 0xA460 + CompositeImageCount = 0xA461 + CompositeImageExposureTimes = 0xA462 + Gamma = 0xA500 + PrintImageMatching = 0xC4A5 + DNGVersion = 0xC612 + DNGBackwardVersion = 0xC613 + UniqueCameraModel = 0xC614 + LocalizedCameraModel = 0xC615 + CFAPlaneColor = 0xC616 + CFALayout = 0xC617 + LinearizationTable = 0xC618 + BlackLevelRepeatDim = 0xC619 + BlackLevel = 0xC61A + BlackLevelDeltaH = 0xC61B + BlackLevelDeltaV = 0xC61C + WhiteLevel = 0xC61D + DefaultScale = 0xC61E + DefaultCropOrigin = 0xC61F + DefaultCropSize = 0xC620 + ColorMatrix1 = 0xC621 + ColorMatrix2 = 0xC622 + CameraCalibration1 = 0xC623 + CameraCalibration2 = 0xC624 + ReductionMatrix1 = 0xC625 + ReductionMatrix2 = 0xC626 + AnalogBalance = 0xC627 + AsShotNeutral = 0xC628 + AsShotWhiteXY = 0xC629 + BaselineExposure = 0xC62A + BaselineNoise = 0xC62B + BaselineSharpness = 0xC62C + BayerGreenSplit = 0xC62D + LinearResponseLimit = 0xC62E + CameraSerialNumber = 0xC62F + LensInfo = 0xC630 + ChromaBlurRadius = 0xC631 + AntiAliasStrength = 0xC632 + ShadowScale = 0xC633 + DNGPrivateData = 0xC634 + MakerNoteSafety = 0xC635 + CalibrationIlluminant1 = 0xC65A + CalibrationIlluminant2 = 0xC65B + BestQualityScale = 0xC65C + RawDataUniqueID = 0xC65D + OriginalRawFileName = 0xC68B + OriginalRawFileData = 0xC68C + ActiveArea = 0xC68D + MaskedAreas = 0xC68E + AsShotICCProfile = 0xC68F + AsShotPreProfileMatrix = 0xC690 + CurrentICCProfile = 0xC691 + CurrentPreProfileMatrix = 0xC692 + ColorimetricReference = 0xC6BF + CameraCalibrationSignature = 0xC6F3 + ProfileCalibrationSignature = 0xC6F4 + AsShotProfileName = 0xC6F6 + NoiseReductionApplied = 0xC6F7 + ProfileName = 0xC6F8 + ProfileHueSatMapDims = 0xC6F9 + ProfileHueSatMapData1 = 0xC6FA + ProfileHueSatMapData2 = 0xC6FB + ProfileToneCurve = 0xC6FC + ProfileEmbedPolicy = 0xC6FD + ProfileCopyright = 0xC6FE + ForwardMatrix1 = 0xC714 + ForwardMatrix2 = 0xC715 + PreviewApplicationName = 0xC716 + PreviewApplicationVersion = 0xC717 + PreviewSettingsName = 0xC718 + PreviewSettingsDigest = 0xC719 + PreviewColorSpace = 0xC71A + PreviewDateTime = 0xC71B + RawImageDigest = 0xC71C + OriginalRawFileDigest = 0xC71D + SubTileBlockSize = 0xC71E + RowInterleaveFactor = 0xC71F + ProfileLookTableDims = 0xC725 + ProfileLookTableData = 0xC726 + OpcodeList1 = 0xC740 + OpcodeList2 = 0xC741 + OpcodeList3 = 0xC74E + NoiseProfile = 0xC761 + + +"""Maps EXIF tags to tag names.""" +TAGS = { + **{i.value: i.name for i in Base}, + 0x920C: "SpatialFrequencyResponse", + 0x9214: "SubjectLocation", + 0x9215: "ExposureIndex", + 0x828E: "CFAPattern", + 0x920B: "FlashEnergy", + 0x9216: "TIFF/EPStandardID", +} + + +class GPS(IntEnum): + GPSVersionID = 0 + GPSLatitudeRef = 1 + GPSLatitude = 2 + GPSLongitudeRef = 3 + GPSLongitude = 4 + GPSAltitudeRef = 5 + GPSAltitude = 6 + GPSTimeStamp = 7 + GPSSatellites = 8 + GPSStatus = 9 + GPSMeasureMode = 10 + GPSDOP = 11 + GPSSpeedRef = 12 + GPSSpeed = 13 + GPSTrackRef = 14 + GPSTrack = 15 + GPSImgDirectionRef = 16 + GPSImgDirection = 17 + GPSMapDatum = 18 + GPSDestLatitudeRef = 19 + GPSDestLatitude = 20 + GPSDestLongitudeRef = 21 + GPSDestLongitude = 22 + GPSDestBearingRef = 23 + GPSDestBearing = 24 + GPSDestDistanceRef = 25 + GPSDestDistance = 26 + GPSProcessingMethod = 27 + GPSAreaInformation = 28 + GPSDateStamp = 29 + GPSDifferential = 30 + GPSHPositioningError = 31 + + +"""Maps EXIF GPS tags to tag names.""" +GPSTAGS = {i.value: i.name for i in GPS} + + +class Interop(IntEnum): + InteropIndex = 1 + InteropVersion = 2 + RelatedImageFileFormat = 4096 + RelatedImageWidth = 4097 + RelatedImageHeight = 4098 + + +class IFD(IntEnum): + Exif = 34665 + GPSInfo = 34853 + Makernote = 37500 + Interop = 40965 + IFD1 = -1 + + +class LightSource(IntEnum): + Unknown = 0 + Daylight = 1 + Fluorescent = 2 + Tungsten = 3 + Flash = 4 + Fine = 9 + Cloudy = 10 + Shade = 11 + DaylightFluorescent = 12 + DayWhiteFluorescent = 13 + CoolWhiteFluorescent = 14 + WhiteFluorescent = 15 + StandardLightA = 17 + StandardLightB = 18 + StandardLightC = 19 + D55 = 20 + D65 = 21 + D75 = 22 + D50 = 23 + ISO = 24 + Other = 255 diff --git a/venv/lib/python3.12/site-packages/PIL/FitsImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/FitsImagePlugin.py new file mode 100644 index 0000000..6bbd264 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/FitsImagePlugin.py @@ -0,0 +1,152 @@ +# +# The Python Imaging Library +# $Id$ +# +# FITS file handling +# +# Copyright (c) 1998-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import gzip +import math + +from . import Image, ImageFile + + +def _accept(prefix: bytes) -> bool: + return prefix[:6] == b"SIMPLE" + + +class FitsImageFile(ImageFile.ImageFile): + format = "FITS" + format_description = "FITS" + + def _open(self) -> None: + assert self.fp is not None + + headers: dict[bytes, bytes] = {} + header_in_progress = False + decoder_name = "" + while True: + header = self.fp.read(80) + if not header: + msg = "Truncated FITS file" + raise OSError(msg) + keyword = header[:8].strip() + if keyword in (b"SIMPLE", b"XTENSION"): + header_in_progress = True + elif headers and not header_in_progress: + # This is now a data unit + break + elif keyword == b"END": + # Seek to the end of the header unit + self.fp.seek(math.ceil(self.fp.tell() / 2880) * 2880) + if not decoder_name: + decoder_name, offset, args = self._parse_headers(headers) + + header_in_progress = False + continue + + if decoder_name: + # Keep going to read past the headers + continue + + value = header[8:].split(b"/")[0].strip() + if value.startswith(b"="): + value = value[1:].strip() + if not headers and (not _accept(keyword) or value != b"T"): + msg = "Not a FITS file" + raise SyntaxError(msg) + headers[keyword] = value + + if not decoder_name: + msg = "No image data" + raise ValueError(msg) + + offset += self.fp.tell() - 80 + self.tile = [ImageFile._Tile(decoder_name, (0, 0) + self.size, offset, args)] + + def _get_size( + self, headers: dict[bytes, bytes], prefix: bytes + ) -> tuple[int, int] | None: + naxis = int(headers[prefix + b"NAXIS"]) + if naxis == 0: + return None + + if naxis == 1: + return 1, int(headers[prefix + b"NAXIS1"]) + else: + return int(headers[prefix + b"NAXIS1"]), int(headers[prefix + b"NAXIS2"]) + + def _parse_headers( + self, headers: dict[bytes, bytes] + ) -> tuple[str, int, tuple[str | int, ...]]: + prefix = b"" + decoder_name = "raw" + offset = 0 + if ( + headers.get(b"XTENSION") == b"'BINTABLE'" + and headers.get(b"ZIMAGE") == b"T" + and headers[b"ZCMPTYPE"] == b"'GZIP_1 '" + ): + no_prefix_size = self._get_size(headers, prefix) or (0, 0) + number_of_bits = int(headers[b"BITPIX"]) + offset = no_prefix_size[0] * no_prefix_size[1] * (number_of_bits // 8) + + prefix = b"Z" + decoder_name = "fits_gzip" + + size = self._get_size(headers, prefix) + if not size: + return "", 0, () + + self._size = size + + number_of_bits = int(headers[prefix + b"BITPIX"]) + if number_of_bits == 8: + self._mode = "L" + elif number_of_bits == 16: + self._mode = "I;16" + elif number_of_bits == 32: + self._mode = "I" + elif number_of_bits in (-32, -64): + self._mode = "F" + + args: tuple[str | int, ...] + if decoder_name == "raw": + args = (self.mode, 0, -1) + else: + args = (number_of_bits,) + return decoder_name, offset, args + + +class FitsGzipDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + value = gzip.decompress(self.fd.read()) + + rows = [] + offset = 0 + number_of_bits = min(self.args[0] // 8, 4) + for y in range(self.state.ysize): + row = bytearray() + for x in range(self.state.xsize): + row += value[offset + (4 - number_of_bits) : offset + 4] + offset += 4 + rows.append(row) + self.set_as_raw(bytes([pixel for row in rows[::-1] for pixel in row])) + return -1, 0 + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(FitsImageFile.format, FitsImageFile, _accept) +Image.register_decoder("fits_gzip", FitsGzipDecoder) + +Image.register_extensions(FitsImageFile.format, [".fit", ".fits"]) diff --git a/venv/lib/python3.12/site-packages/PIL/FliImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/FliImagePlugin.py new file mode 100644 index 0000000..666390b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/FliImagePlugin.py @@ -0,0 +1,175 @@ +# +# The Python Imaging Library. +# $Id$ +# +# FLI/FLC file handling. +# +# History: +# 95-09-01 fl Created +# 97-01-03 fl Fixed parser, setup decoder tile +# 98-07-15 fl Renamed offset attribute to avoid name clash +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import i32le as i32 +from ._binary import o8 + +# +# decoder + + +def _accept(prefix: bytes) -> bool: + return ( + len(prefix) >= 6 + and i16(prefix, 4) in [0xAF11, 0xAF12] + and i16(prefix, 14) in [0, 3] # flags + ) + + +## +# Image plugin for the FLI/FLC animation format. Use the seek +# method to load individual frames. + + +class FliImageFile(ImageFile.ImageFile): + format = "FLI" + format_description = "Autodesk FLI/FLC Animation" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + # HEAD + s = self.fp.read(128) + if not (_accept(s) and s[20:22] == b"\x00\x00"): + msg = "not an FLI/FLC file" + raise SyntaxError(msg) + + # frames + self.n_frames = i16(s, 6) + self.is_animated = self.n_frames > 1 + + # image characteristics + self._mode = "P" + self._size = i16(s, 8), i16(s, 10) + + # animation speed + duration = i32(s, 16) + magic = i16(s, 4) + if magic == 0xAF11: + duration = (duration * 1000) // 70 + self.info["duration"] = duration + + # look for palette + palette = [(a, a, a) for a in range(256)] + + s = self.fp.read(16) + + self.__offset = 128 + + if i16(s, 4) == 0xF100: + # prefix chunk; ignore it + self.__offset = self.__offset + i32(s) + self.fp.seek(self.__offset) + s = self.fp.read(16) + + if i16(s, 4) == 0xF1FA: + # look for palette chunk + number_of_subchunks = i16(s, 6) + chunk_size: int | None = None + for _ in range(number_of_subchunks): + if chunk_size is not None: + self.fp.seek(chunk_size - 6, os.SEEK_CUR) + s = self.fp.read(6) + chunk_type = i16(s, 4) + if chunk_type in (4, 11): + self._palette(palette, 2 if chunk_type == 11 else 0) + break + chunk_size = i32(s) + if not chunk_size: + break + + self.palette = ImagePalette.raw( + "RGB", b"".join(o8(r) + o8(g) + o8(b) for (r, g, b) in palette) + ) + + # set things up to decode first frame + self.__frame = -1 + self._fp = self.fp + self.__rewind = self.fp.tell() + self.seek(0) + + def _palette(self, palette: list[tuple[int, int, int]], shift: int) -> None: + # load palette + + i = 0 + for e in range(i16(self.fp.read(2))): + s = self.fp.read(2) + i = i + s[0] + n = s[1] + if n == 0: + n = 256 + s = self.fp.read(n * 3) + for n in range(0, len(s), 3): + r = s[n] << shift + g = s[n + 1] << shift + b = s[n + 2] << shift + palette[i] = (r, g, b) + i += 1 + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + if frame < self.__frame: + self._seek(0) + + for f in range(self.__frame + 1, frame + 1): + self._seek(f) + + def _seek(self, frame: int) -> None: + if frame == 0: + self.__frame = -1 + self._fp.seek(self.__rewind) + self.__offset = 128 + else: + # ensure that the previous frame was loaded + self.load() + + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + self.__frame = frame + + # move to next frame + self.fp = self._fp + self.fp.seek(self.__offset) + + s = self.fp.read(4) + if not s: + msg = "missing frame size" + raise EOFError(msg) + + framesize = i32(s) + + self.decodermaxblock = framesize + self.tile = [ImageFile._Tile("fli", (0, 0) + self.size, self.__offset, None)] + + self.__offset += framesize + + def tell(self) -> int: + return self.__frame + + +# +# registry + +Image.register_open(FliImageFile.format, FliImageFile, _accept) + +Image.register_extensions(FliImageFile.format, [".fli", ".flc"]) diff --git a/venv/lib/python3.12/site-packages/PIL/FontFile.py b/venv/lib/python3.12/site-packages/PIL/FontFile.py new file mode 100644 index 0000000..1e0c1c1 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/FontFile.py @@ -0,0 +1,134 @@ +# +# The Python Imaging Library +# $Id$ +# +# base class for raster font file parsers +# +# history: +# 1997-06-05 fl created +# 1997-08-19 fl restrict image width +# +# Copyright (c) 1997-1998 by Secret Labs AB +# Copyright (c) 1997-1998 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +from typing import BinaryIO + +from . import Image, _binary + +WIDTH = 800 + + +def puti16( + fp: BinaryIO, values: tuple[int, int, int, int, int, int, int, int, int, int] +) -> None: + """Write network order (big-endian) 16-bit sequence""" + for v in values: + if v < 0: + v += 65536 + fp.write(_binary.o16be(v)) + + +class FontFile: + """Base class for raster font file handlers.""" + + bitmap: Image.Image | None = None + + def __init__(self) -> None: + self.info: dict[bytes, bytes | int] = {} + self.glyph: list[ + tuple[ + tuple[int, int], + tuple[int, int, int, int], + tuple[int, int, int, int], + Image.Image, + ] + | None + ] = [None] * 256 + + def __getitem__(self, ix: int) -> ( + tuple[ + tuple[int, int], + tuple[int, int, int, int], + tuple[int, int, int, int], + Image.Image, + ] + | None + ): + return self.glyph[ix] + + def compile(self) -> None: + """Create metrics and bitmap""" + + if self.bitmap: + return + + # create bitmap large enough to hold all data + h = w = maxwidth = 0 + lines = 1 + for glyph in self.glyph: + if glyph: + d, dst, src, im = glyph + h = max(h, src[3] - src[1]) + w = w + (src[2] - src[0]) + if w > WIDTH: + lines += 1 + w = src[2] - src[0] + maxwidth = max(maxwidth, w) + + xsize = maxwidth + ysize = lines * h + + if xsize == 0 and ysize == 0: + return + + self.ysize = h + + # paste glyphs into bitmap + self.bitmap = Image.new("1", (xsize, ysize)) + self.metrics: list[ + tuple[tuple[int, int], tuple[int, int, int, int], tuple[int, int, int, int]] + | None + ] = [None] * 256 + x = y = 0 + for i in range(256): + glyph = self[i] + if glyph: + d, dst, src, im = glyph + xx = src[2] - src[0] + x0, y0 = x, y + x = x + xx + if x > WIDTH: + x, y = 0, y + h + x0, y0 = x, y + x = xx + s = src[0] + x0, src[1] + y0, src[2] + x0, src[3] + y0 + self.bitmap.paste(im.crop(src), s) + self.metrics[i] = d, dst, s + + def save(self, filename: str) -> None: + """Save font""" + + self.compile() + + # font data + if not self.bitmap: + msg = "No bitmap created" + raise ValueError(msg) + self.bitmap.save(os.path.splitext(filename)[0] + ".pbm", "PNG") + + # font metrics + with open(os.path.splitext(filename)[0] + ".pil", "wb") as fp: + fp.write(b"PILfont\n") + fp.write(f";;;;;;{self.ysize};\n".encode("ascii")) # HACK!!! + fp.write(b"DATA\n") + for id in range(256): + m = self.metrics[id] + if not m: + puti16(fp, (0,) * 10) + else: + puti16(fp, m[0] + m[1] + m[2]) diff --git a/venv/lib/python3.12/site-packages/PIL/FpxImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/FpxImagePlugin.py new file mode 100644 index 0000000..8fef510 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/FpxImagePlugin.py @@ -0,0 +1,257 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library. +# $Id$ +# +# FlashPix support for PIL +# +# History: +# 97-01-25 fl Created (reads uncompressed RGB images only) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import olefile + +from . import Image, ImageFile +from ._binary import i32le as i32 + +# we map from colour field tuples to (mode, rawmode) descriptors +MODES = { + # opacity + (0x00007FFE,): ("A", "L"), + # monochrome + (0x00010000,): ("L", "L"), + (0x00018000, 0x00017FFE): ("RGBA", "LA"), + # photo YCC + (0x00020000, 0x00020001, 0x00020002): ("RGB", "YCC;P"), + (0x00028000, 0x00028001, 0x00028002, 0x00027FFE): ("RGBA", "YCCA;P"), + # standard RGB (NIFRGB) + (0x00030000, 0x00030001, 0x00030002): ("RGB", "RGB"), + (0x00038000, 0x00038001, 0x00038002, 0x00037FFE): ("RGBA", "RGBA"), +} + + +# +# -------------------------------------------------------------------- + + +def _accept(prefix: bytes) -> bool: + return prefix[:8] == olefile.MAGIC + + +## +# Image plugin for the FlashPix images. + + +class FpxImageFile(ImageFile.ImageFile): + format = "FPX" + format_description = "FlashPix" + + def _open(self) -> None: + # + # read the OLE directory and see if this is a likely + # to be a FlashPix file + + try: + self.ole = olefile.OleFileIO(self.fp) + except OSError as e: + msg = "not an FPX file; invalid OLE file" + raise SyntaxError(msg) from e + + root = self.ole.root + if not root or root.clsid != "56616700-C154-11CE-8553-00AA00A1F95B": + msg = "not an FPX file; bad root CLSID" + raise SyntaxError(msg) + + self._open_index(1) + + def _open_index(self, index: int = 1) -> None: + # + # get the Image Contents Property Set + + prop = self.ole.getproperties( + [f"Data Object Store {index:06d}", "\005Image Contents"] + ) + + # size (highest resolution) + + assert isinstance(prop[0x1000002], int) + assert isinstance(prop[0x1000003], int) + self._size = prop[0x1000002], prop[0x1000003] + + size = max(self.size) + i = 1 + while size > 64: + size = size // 2 + i += 1 + self.maxid = i - 1 + + # mode. instead of using a single field for this, flashpix + # requires you to specify the mode for each channel in each + # resolution subimage, and leaves it to the decoder to make + # sure that they all match. for now, we'll cheat and assume + # that this is always the case. + + id = self.maxid << 16 + + s = prop[0x2000002 | id] + + if not isinstance(s, bytes) or (bands := i32(s, 4)) > 4: + msg = "Invalid number of bands" + raise OSError(msg) + + # note: for now, we ignore the "uncalibrated" flag + colors = tuple(i32(s, 8 + i * 4) & 0x7FFFFFFF for i in range(bands)) + + self._mode, self.rawmode = MODES[colors] + + # load JPEG tables, if any + self.jpeg = {} + for i in range(256): + id = 0x3000001 | (i << 16) + if id in prop: + self.jpeg[i] = prop[id] + + self._open_subimage(1, self.maxid) + + def _open_subimage(self, index: int = 1, subimage: int = 0) -> None: + # + # setup tile descriptors for a given subimage + + stream = [ + f"Data Object Store {index:06d}", + f"Resolution {subimage:04d}", + "Subimage 0000 Header", + ] + + fp = self.ole.openstream(stream) + + # skip prefix + fp.read(28) + + # header stream + s = fp.read(36) + + size = i32(s, 4), i32(s, 8) + # tilecount = i32(s, 12) + tilesize = i32(s, 16), i32(s, 20) + # channels = i32(s, 24) + offset = i32(s, 28) + length = i32(s, 32) + + if size != self.size: + msg = "subimage mismatch" + raise OSError(msg) + + # get tile descriptors + fp.seek(28 + offset) + s = fp.read(i32(s, 12) * length) + + x = y = 0 + xsize, ysize = size + xtile, ytile = tilesize + self.tile = [] + + for i in range(0, len(s), length): + x1 = min(xsize, x + xtile) + y1 = min(ysize, y + ytile) + + compression = i32(s, i + 8) + + if compression == 0: + self.tile.append( + ImageFile._Tile( + "raw", + (x, y, x1, y1), + i32(s, i) + 28, + (self.rawmode,), + ) + ) + + elif compression == 1: + # FIXME: the fill decoder is not implemented + self.tile.append( + ImageFile._Tile( + "fill", + (x, y, x1, y1), + i32(s, i) + 28, + (self.rawmode, s[12:16]), + ) + ) + + elif compression == 2: + internal_color_conversion = s[14] + jpeg_tables = s[15] + rawmode = self.rawmode + + if internal_color_conversion: + # The image is stored as usual (usually YCbCr). + if rawmode == "RGBA": + # For "RGBA", data is stored as YCbCrA based on + # negative RGB. The following trick works around + # this problem : + jpegmode, rawmode = "YCbCrK", "CMYK" + else: + jpegmode = None # let the decoder decide + + else: + # The image is stored as defined by rawmode + jpegmode = rawmode + + self.tile.append( + ImageFile._Tile( + "jpeg", + (x, y, x1, y1), + i32(s, i) + 28, + (rawmode, jpegmode), + ) + ) + + # FIXME: jpeg tables are tile dependent; the prefix + # data must be placed in the tile descriptor itself! + + if jpeg_tables: + self.tile_prefix = self.jpeg[jpeg_tables] + + else: + msg = "unknown/invalid compression" + raise OSError(msg) + + x = x + xtile + if x >= xsize: + x, y = 0, y + ytile + if y >= ysize: + break # isn't really required + + self.stream = stream + self._fp = self.fp + self.fp = None + + def load(self) -> Image.core.PixelAccess | None: + if not self.fp: + self.fp = self.ole.openstream(self.stream[:2] + ["Subimage 0000 Data"]) + + return ImageFile.ImageFile.load(self) + + def close(self) -> None: + self.ole.close() + super().close() + + def __exit__(self, *args: object) -> None: + self.ole.close() + super().__exit__() + + +# +# -------------------------------------------------------------------- + + +Image.register_open(FpxImageFile.format, FpxImageFile, _accept) + +Image.register_extension(FpxImageFile.format, ".fpx") diff --git a/venv/lib/python3.12/site-packages/PIL/FtexImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/FtexImagePlugin.py new file mode 100644 index 0000000..ddb469b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/FtexImagePlugin.py @@ -0,0 +1,115 @@ +""" +A Pillow loader for .ftc and .ftu files (FTEX) +Jerome Leclanche + +The contents of this file are hereby released in the public domain (CC0) +Full text of the CC0 license: + https://creativecommons.org/publicdomain/zero/1.0/ + +Independence War 2: Edge Of Chaos - Texture File Format - 16 October 2001 + +The textures used for 3D objects in Independence War 2: Edge Of Chaos are in a +packed custom format called FTEX. This file format uses file extensions FTC +and FTU. +* FTC files are compressed textures (using standard texture compression). +* FTU files are not compressed. +Texture File Format +The FTC and FTU texture files both use the same format. This +has the following structure: +{header} +{format_directory} +{data} +Where: +{header} = { + u32:magic, + u32:version, + u32:width, + u32:height, + u32:mipmap_count, + u32:format_count +} + +* The "magic" number is "FTEX". +* "width" and "height" are the dimensions of the texture. +* "mipmap_count" is the number of mipmaps in the texture. +* "format_count" is the number of texture formats (different versions of the +same texture) in this file. + +{format_directory} = format_count * { u32:format, u32:where } + +The format value is 0 for DXT1 compressed textures and 1 for 24-bit RGB +uncompressed textures. +The texture data for a format starts at the position "where" in the file. + +Each set of texture data in the file has the following structure: +{data} = format_count * { u32:mipmap_size, mipmap_size * { u8 } } +* "mipmap_size" is the number of bytes in that mip level. For compressed +textures this is the size of the texture data compressed with DXT1. For 24 bit +uncompressed textures, this is 3 * width * height. Following this are the image +bytes for that mipmap level. + +Note: All data is stored in little-Endian (Intel) byte order. +""" + +from __future__ import annotations + +import struct +from enum import IntEnum +from io import BytesIO + +from . import Image, ImageFile + +MAGIC = b"FTEX" + + +class Format(IntEnum): + DXT1 = 0 + UNCOMPRESSED = 1 + + +class FtexImageFile(ImageFile.ImageFile): + format = "FTEX" + format_description = "Texture File Format (IW2:EOC)" + + def _open(self) -> None: + if not _accept(self.fp.read(4)): + msg = "not an FTEX file" + raise SyntaxError(msg) + struct.unpack(" None: + pass + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == MAGIC + + +Image.register_open(FtexImageFile.format, FtexImageFile, _accept) +Image.register_extensions(FtexImageFile.format, [".ftc", ".ftu"]) diff --git a/venv/lib/python3.12/site-packages/PIL/GbrImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/GbrImagePlugin.py new file mode 100644 index 0000000..f319d7e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GbrImagePlugin.py @@ -0,0 +1,103 @@ +# +# The Python Imaging Library +# +# load a GIMP brush file +# +# History: +# 96-03-14 fl Created +# 16-01-08 es Version 2 +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# Copyright (c) Eric Soroos 2016. +# +# See the README file for information on usage and redistribution. +# +# +# See https://github.com/GNOME/gimp/blob/mainline/devel-docs/gbr.txt for +# format documentation. +# +# This code Interprets version 1 and 2 .gbr files. +# Version 1 files are obsolete, and should not be used for new +# brushes. +# Version 2 files are saved by GIMP v2.8 (at least) +# Version 3 files have a format specifier of 18 for 16bit floats in +# the color depth field. This is currently unsupported by Pillow. +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i32be as i32 + + +def _accept(prefix: bytes) -> bool: + return len(prefix) >= 8 and i32(prefix, 0) >= 20 and i32(prefix, 4) in (1, 2) + + +## +# Image plugin for the GIMP brush format. + + +class GbrImageFile(ImageFile.ImageFile): + format = "GBR" + format_description = "GIMP brush file" + + def _open(self) -> None: + header_size = i32(self.fp.read(4)) + if header_size < 20: + msg = "not a GIMP brush" + raise SyntaxError(msg) + version = i32(self.fp.read(4)) + if version not in (1, 2): + msg = f"Unsupported GIMP brush version: {version}" + raise SyntaxError(msg) + + width = i32(self.fp.read(4)) + height = i32(self.fp.read(4)) + color_depth = i32(self.fp.read(4)) + if width <= 0 or height <= 0: + msg = "not a GIMP brush" + raise SyntaxError(msg) + if color_depth not in (1, 4): + msg = f"Unsupported GIMP brush color depth: {color_depth}" + raise SyntaxError(msg) + + if version == 1: + comment_length = header_size - 20 + else: + comment_length = header_size - 28 + magic_number = self.fp.read(4) + if magic_number != b"GIMP": + msg = "not a GIMP brush, bad magic number" + raise SyntaxError(msg) + self.info["spacing"] = i32(self.fp.read(4)) + + comment = self.fp.read(comment_length)[:-1] + + if color_depth == 1: + self._mode = "L" + else: + self._mode = "RGBA" + + self._size = width, height + + self.info["comment"] = comment + + # Image might not be small + Image._decompression_bomb_check(self.size) + + # Data is an uncompressed block of w * h * bytes/pixel + self._data_size = width * height * color_depth + + def load(self) -> Image.core.PixelAccess | None: + if self._im is None: + self.im = Image.core.new(self.mode, self.size) + self.frombytes(self.fp.read(self._data_size)) + return Image.Image.load(self) + + +# +# registry + + +Image.register_open(GbrImageFile.format, GbrImageFile, _accept) +Image.register_extension(GbrImageFile.format, ".gbr") diff --git a/venv/lib/python3.12/site-packages/PIL/GdImageFile.py b/venv/lib/python3.12/site-packages/PIL/GdImageFile.py new file mode 100644 index 0000000..f1b4969 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GdImageFile.py @@ -0,0 +1,102 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GD file handling +# +# History: +# 1996-04-12 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + + +""" +.. note:: + This format cannot be automatically recognized, so the + class is not registered for use with :py:func:`PIL.Image.open()`. To open a + gd file, use the :py:func:`PIL.GdImageFile.open()` function instead. + +.. warning:: + THE GD FORMAT IS NOT DESIGNED FOR DATA INTERCHANGE. This + implementation is provided for convenience and demonstrational + purposes only. +""" +from __future__ import annotations + +from typing import IO + +from . import ImageFile, ImagePalette, UnidentifiedImageError +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._typing import StrOrBytesPath + + +class GdImageFile(ImageFile.ImageFile): + """ + Image plugin for the GD uncompressed format. Note that this format + is not supported by the standard :py:func:`PIL.Image.open()` function. To use + this plugin, you have to import the :py:mod:`PIL.GdImageFile` module and + use the :py:func:`PIL.GdImageFile.open()` function. + """ + + format = "GD" + format_description = "GD uncompressed images" + + def _open(self) -> None: + # Header + assert self.fp is not None + + s = self.fp.read(1037) + + if i16(s) not in [65534, 65535]: + msg = "Not a valid GD 2.x .gd file" + raise SyntaxError(msg) + + self._mode = "L" # FIXME: "P" + self._size = i16(s, 2), i16(s, 4) + + true_color = s[6] + true_color_offset = 2 if true_color else 0 + + # transparency index + tindex = i32(s, 7 + true_color_offset) + if tindex < 256: + self.info["transparency"] = tindex + + self.palette = ImagePalette.raw( + "XBGR", s[7 + true_color_offset + 4 : 7 + true_color_offset + 4 + 256 * 4] + ) + + self.tile = [ + ImageFile._Tile( + "raw", + (0, 0) + self.size, + 7 + true_color_offset + 4 + 256 * 4, + ("L", 0, 1), + ) + ] + + +def open(fp: StrOrBytesPath | IO[bytes], mode: str = "r") -> GdImageFile: + """ + Load texture from a GD image file. + + :param fp: GD file name, or an opened file handle. + :param mode: Optional mode. In this version, if the mode argument + is given, it must be "r". + :returns: An image instance. + :raises OSError: If the image could not be read. + """ + if mode != "r": + msg = "bad mode" + raise ValueError(msg) + + try: + return GdImageFile(fp) + except SyntaxError as e: + msg = "cannot identify this image file" + raise UnidentifiedImageError(msg) from e diff --git a/venv/lib/python3.12/site-packages/PIL/GifImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/GifImagePlugin.py new file mode 100644 index 0000000..57c2917 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GifImagePlugin.py @@ -0,0 +1,1197 @@ +# +# The Python Imaging Library. +# $Id$ +# +# GIF file handling +# +# History: +# 1995-09-01 fl Created +# 1996-12-14 fl Added interlace support +# 1996-12-30 fl Added animation support +# 1997-01-05 fl Added write support, fixed local colour map bug +# 1997-02-23 fl Make sure to load raster data in getdata() +# 1997-07-05 fl Support external decoder (0.4) +# 1998-07-09 fl Handle all modes when saving (0.5) +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 2001-04-16 fl Added rewind support (seek to frame 0) (0.6) +# 2001-04-17 fl Added palette optimization (0.7) +# 2002-06-06 fl Added transparency support for save (0.8) +# 2004-02-24 fl Disable interlacing for small images +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import math +import os +import subprocess +from enum import IntEnum +from functools import cached_property +from typing import IO, TYPE_CHECKING, Any, Literal, NamedTuple, Union + +from . import ( + Image, + ImageChops, + ImageFile, + ImageMath, + ImageOps, + ImagePalette, + ImageSequence, +) +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + +if TYPE_CHECKING: + from . import _imaging + from ._typing import Buffer + + +class LoadingStrategy(IntEnum): + """.. versionadded:: 9.1.0""" + + RGB_AFTER_FIRST = 0 + RGB_AFTER_DIFFERENT_PALETTE_ONLY = 1 + RGB_ALWAYS = 2 + + +#: .. versionadded:: 9.1.0 +LOADING_STRATEGY = LoadingStrategy.RGB_AFTER_FIRST + +# -------------------------------------------------------------------- +# Identify/read GIF files + + +def _accept(prefix: bytes) -> bool: + return prefix[:6] in [b"GIF87a", b"GIF89a"] + + +## +# Image plugin for GIF images. This plugin supports both GIF87 and +# GIF89 images. + + +class GifImageFile(ImageFile.ImageFile): + format = "GIF" + format_description = "Compuserve GIF" + _close_exclusive_fp_after_loading = False + + global_palette = None + + def data(self) -> bytes | None: + s = self.fp.read(1) + if s and s[0]: + return self.fp.read(s[0]) + return None + + def _is_palette_needed(self, p: bytes) -> bool: + for i in range(0, len(p), 3): + if not (i // 3 == p[i] == p[i + 1] == p[i + 2]): + return True + return False + + def _open(self) -> None: + # Screen + s = self.fp.read(13) + if not _accept(s): + msg = "not a GIF file" + raise SyntaxError(msg) + + self.info["version"] = s[:6] + self._size = i16(s, 6), i16(s, 8) + self.tile = [] + flags = s[10] + bits = (flags & 7) + 1 + + if flags & 128: + # get global palette + self.info["background"] = s[11] + # check if palette contains colour indices + p = self.fp.read(3 << bits) + if self._is_palette_needed(p): + p = ImagePalette.raw("RGB", p) + self.global_palette = self.palette = p + + self._fp = self.fp # FIXME: hack + self.__rewind = self.fp.tell() + self._n_frames: int | None = None + self._seek(0) # get ready to read first frame + + @property + def n_frames(self) -> int: + if self._n_frames is None: + current = self.tell() + try: + while True: + self._seek(self.tell() + 1, False) + except EOFError: + self._n_frames = self.tell() + 1 + self.seek(current) + return self._n_frames + + @cached_property + def is_animated(self) -> bool: + if self._n_frames is not None: + return self._n_frames != 1 + + current = self.tell() + if current: + return True + + try: + self._seek(1, False) + is_animated = True + except EOFError: + is_animated = False + + self.seek(current) + return is_animated + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + if frame < self.__frame: + self._im = None + self._seek(0) + + last_frame = self.__frame + for f in range(self.__frame + 1, frame + 1): + try: + self._seek(f) + except EOFError as e: + self.seek(last_frame) + msg = "no more images in GIF file" + raise EOFError(msg) from e + + def _seek(self, frame: int, update_image: bool = True) -> None: + if frame == 0: + # rewind + self.__offset = 0 + self.dispose: _imaging.ImagingCore | None = None + self.__frame = -1 + self._fp.seek(self.__rewind) + self.disposal_method = 0 + if "comment" in self.info: + del self.info["comment"] + else: + # ensure that the previous frame was loaded + if self.tile and update_image: + self.load() + + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + + self.fp = self._fp + if self.__offset: + # backup to last frame + self.fp.seek(self.__offset) + while self.data(): + pass + self.__offset = 0 + + s = self.fp.read(1) + if not s or s == b";": + msg = "no more images in GIF file" + raise EOFError(msg) + + palette: ImagePalette.ImagePalette | Literal[False] | None = None + + info: dict[str, Any] = {} + frame_transparency = None + interlace = None + frame_dispose_extent = None + while True: + if not s: + s = self.fp.read(1) + if not s or s == b";": + break + + elif s == b"!": + # + # extensions + # + s = self.fp.read(1) + block = self.data() + if s[0] == 249 and block is not None: + # + # graphic control extension + # + flags = block[0] + if flags & 1: + frame_transparency = block[3] + info["duration"] = i16(block, 1) * 10 + + # disposal method - find the value of bits 4 - 6 + dispose_bits = 0b00011100 & flags + dispose_bits = dispose_bits >> 2 + if dispose_bits: + # only set the dispose if it is not + # unspecified. I'm not sure if this is + # correct, but it seems to prevent the last + # frame from looking odd for some animations + self.disposal_method = dispose_bits + elif s[0] == 254: + # + # comment extension + # + comment = b"" + + # Read this comment block + while block: + comment += block + block = self.data() + + if "comment" in info: + # If multiple comment blocks in frame, separate with \n + info["comment"] += b"\n" + comment + else: + info["comment"] = comment + s = None + continue + elif s[0] == 255 and frame == 0 and block is not None: + # + # application extension + # + info["extension"] = block, self.fp.tell() + if block[:11] == b"NETSCAPE2.0": + block = self.data() + if block and len(block) >= 3 and block[0] == 1: + self.info["loop"] = i16(block, 1) + while self.data(): + pass + + elif s == b",": + # + # local image + # + s = self.fp.read(9) + + # extent + x0, y0 = i16(s, 0), i16(s, 2) + x1, y1 = x0 + i16(s, 4), y0 + i16(s, 6) + if (x1 > self.size[0] or y1 > self.size[1]) and update_image: + self._size = max(x1, self.size[0]), max(y1, self.size[1]) + Image._decompression_bomb_check(self._size) + frame_dispose_extent = x0, y0, x1, y1 + flags = s[8] + + interlace = (flags & 64) != 0 + + if flags & 128: + bits = (flags & 7) + 1 + p = self.fp.read(3 << bits) + if self._is_palette_needed(p): + palette = ImagePalette.raw("RGB", p) + else: + palette = False + + # image data + bits = self.fp.read(1)[0] + self.__offset = self.fp.tell() + break + s = None + + if interlace is None: + msg = "image not found in GIF frame" + raise EOFError(msg) + + self.__frame = frame + if not update_image: + return + + self.tile = [] + + if self.dispose: + self.im.paste(self.dispose, self.dispose_extent) + + self._frame_palette = palette if palette is not None else self.global_palette + self._frame_transparency = frame_transparency + if frame == 0: + if self._frame_palette: + if LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS: + self._mode = "RGBA" if frame_transparency is not None else "RGB" + else: + self._mode = "P" + else: + self._mode = "L" + + if palette: + self.palette = palette + elif self.global_palette: + from copy import copy + + self.palette = copy(self.global_palette) + else: + self.palette = None + else: + if self.mode == "P": + if ( + LOADING_STRATEGY != LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY + or palette + ): + if "transparency" in self.info: + self.im.putpalettealpha(self.info["transparency"], 0) + self.im = self.im.convert("RGBA", Image.Dither.FLOYDSTEINBERG) + self._mode = "RGBA" + del self.info["transparency"] + else: + self._mode = "RGB" + self.im = self.im.convert("RGB", Image.Dither.FLOYDSTEINBERG) + + def _rgb(color: int) -> tuple[int, int, int]: + if self._frame_palette: + if color * 3 + 3 > len(self._frame_palette.palette): + color = 0 + return tuple(self._frame_palette.palette[color * 3 : color * 3 + 3]) + else: + return (color, color, color) + + self.dispose = None + self.dispose_extent = frame_dispose_extent + if self.dispose_extent and self.disposal_method >= 2: + try: + if self.disposal_method == 2: + # replace with background colour + + # only dispose the extent in this frame + x0, y0, x1, y1 = self.dispose_extent + dispose_size = (x1 - x0, y1 - y0) + + Image._decompression_bomb_check(dispose_size) + + # by convention, attempt to use transparency first + dispose_mode = "P" + color = self.info.get("transparency", frame_transparency) + if color is not None: + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGBA" + color = _rgb(color) + (0,) + else: + color = self.info.get("background", 0) + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGB" + color = _rgb(color) + self.dispose = Image.core.fill(dispose_mode, dispose_size, color) + else: + # replace with previous contents + if self._im is not None: + # only dispose the extent in this frame + self.dispose = self._crop(self.im, self.dispose_extent) + elif frame_transparency is not None: + x0, y0, x1, y1 = self.dispose_extent + dispose_size = (x1 - x0, y1 - y0) + + Image._decompression_bomb_check(dispose_size) + dispose_mode = "P" + color = frame_transparency + if self.mode in ("RGB", "RGBA"): + dispose_mode = "RGBA" + color = _rgb(frame_transparency) + (0,) + self.dispose = Image.core.fill( + dispose_mode, dispose_size, color + ) + except AttributeError: + pass + + if interlace is not None: + transparency = -1 + if frame_transparency is not None: + if frame == 0: + if LOADING_STRATEGY != LoadingStrategy.RGB_ALWAYS: + self.info["transparency"] = frame_transparency + elif self.mode not in ("RGB", "RGBA"): + transparency = frame_transparency + self.tile = [ + ImageFile._Tile( + "gif", + (x0, y0, x1, y1), + self.__offset, + (bits, interlace, transparency), + ) + ] + + if info.get("comment"): + self.info["comment"] = info["comment"] + for k in ["duration", "extension"]: + if k in info: + self.info[k] = info[k] + elif k in self.info: + del self.info[k] + + def load_prepare(self) -> None: + temp_mode = "P" if self._frame_palette else "L" + self._prev_im = None + if self.__frame == 0: + if self._frame_transparency is not None: + self.im = Image.core.fill( + temp_mode, self.size, self._frame_transparency + ) + elif self.mode in ("RGB", "RGBA"): + self._prev_im = self.im + if self._frame_palette: + self.im = Image.core.fill("P", self.size, self._frame_transparency or 0) + self.im.putpalette("RGB", *self._frame_palette.getdata()) + else: + self._im = None + if not self._prev_im and self._im is not None and self.size != self.im.size: + expanded_im = Image.core.fill(self.im.mode, self.size) + if self._frame_palette: + expanded_im.putpalette("RGB", *self._frame_palette.getdata()) + expanded_im.paste(self.im, (0, 0) + self.im.size) + + self.im = expanded_im + self._mode = temp_mode + self._frame_palette = None + + super().load_prepare() + + def load_end(self) -> None: + if self.__frame == 0: + if self.mode == "P" and LOADING_STRATEGY == LoadingStrategy.RGB_ALWAYS: + if self._frame_transparency is not None: + self.im.putpalettealpha(self._frame_transparency, 0) + self._mode = "RGBA" + else: + self._mode = "RGB" + self.im = self.im.convert(self.mode, Image.Dither.FLOYDSTEINBERG) + return + if not self._prev_im: + return + if self.size != self._prev_im.size: + if self._frame_transparency is not None: + expanded_im = Image.core.fill("RGBA", self.size) + else: + expanded_im = Image.core.fill("P", self.size) + expanded_im.putpalette("RGB", "RGB", self.im.getpalette()) + expanded_im = expanded_im.convert("RGB") + expanded_im.paste(self._prev_im, (0, 0) + self._prev_im.size) + + self._prev_im = expanded_im + assert self._prev_im is not None + if self._frame_transparency is not None: + self.im.putpalettealpha(self._frame_transparency, 0) + frame_im = self.im.convert("RGBA") + else: + frame_im = self.im.convert("RGB") + + assert self.dispose_extent is not None + frame_im = self._crop(frame_im, self.dispose_extent) + + self.im = self._prev_im + self._mode = self.im.mode + if frame_im.mode == "RGBA": + self.im.paste(frame_im, self.dispose_extent, frame_im) + else: + self.im.paste(frame_im, self.dispose_extent) + + def tell(self) -> int: + return self.__frame + + +# -------------------------------------------------------------------- +# Write GIF files + + +RAWMODE = {"1": "L", "L": "L", "P": "P"} + + +def _normalize_mode(im: Image.Image) -> Image.Image: + """ + Takes an image (or frame), returns an image in a mode that is appropriate + for saving in a Gif. + + It may return the original image, or it may return an image converted to + palette or 'L' mode. + + :param im: Image object + :returns: Image object + """ + if im.mode in RAWMODE: + im.load() + return im + if Image.getmodebase(im.mode) == "RGB": + im = im.convert("P", palette=Image.Palette.ADAPTIVE) + assert im.palette is not None + if im.palette.mode == "RGBA": + for rgba in im.palette.colors: + if rgba[3] == 0: + im.info["transparency"] = im.palette.colors[rgba] + break + return im + return im.convert("L") + + +_Palette = Union[bytes, bytearray, list[int], ImagePalette.ImagePalette] + + +def _normalize_palette( + im: Image.Image, palette: _Palette | None, info: dict[str, Any] +) -> Image.Image: + """ + Normalizes the palette for image. + - Sets the palette to the incoming palette, if provided. + - Ensures that there's a palette for L mode images + - Optimizes the palette if necessary/desired. + + :param im: Image object + :param palette: bytes object containing the source palette, or .... + :param info: encoderinfo + :returns: Image object + """ + source_palette = None + if palette: + # a bytes palette + if isinstance(palette, (bytes, bytearray, list)): + source_palette = bytearray(palette[:768]) + if isinstance(palette, ImagePalette.ImagePalette): + source_palette = bytearray(palette.palette) + + if im.mode == "P": + if not source_palette: + im_palette = im.getpalette(None) + assert im_palette is not None + source_palette = bytearray(im_palette) + else: # L-mode + if not source_palette: + source_palette = bytearray(i // 3 for i in range(768)) + im.palette = ImagePalette.ImagePalette("RGB", palette=source_palette) + assert source_palette is not None + + if palette: + used_palette_colors: list[int | None] = [] + assert im.palette is not None + for i in range(0, len(source_palette), 3): + source_color = tuple(source_palette[i : i + 3]) + index = im.palette.colors.get(source_color) + if index in used_palette_colors: + index = None + used_palette_colors.append(index) + for i, index in enumerate(used_palette_colors): + if index is None: + for j in range(len(used_palette_colors)): + if j not in used_palette_colors: + used_palette_colors[i] = j + break + dest_map: list[int] = [] + for index in used_palette_colors: + assert index is not None + dest_map.append(index) + im = im.remap_palette(dest_map) + else: + optimized_palette_colors = _get_optimize(im, info) + if optimized_palette_colors is not None: + im = im.remap_palette(optimized_palette_colors, source_palette) + if "transparency" in info: + try: + info["transparency"] = optimized_palette_colors.index( + info["transparency"] + ) + except ValueError: + del info["transparency"] + return im + + assert im.palette is not None + im.palette.palette = source_palette + return im + + +def _write_single_frame( + im: Image.Image, + fp: IO[bytes], + palette: _Palette | None, +) -> None: + im_out = _normalize_mode(im) + for k, v in im_out.info.items(): + if isinstance(k, str): + im.encoderinfo.setdefault(k, v) + im_out = _normalize_palette(im_out, palette, im.encoderinfo) + + for s in _get_global_header(im_out, im.encoderinfo): + fp.write(s) + + # local image header + flags = 0 + if get_interlace(im): + flags = flags | 64 + _write_local_header(fp, im, (0, 0), flags) + + im_out.encoderconfig = (8, get_interlace(im)) + ImageFile._save( + im_out, fp, [ImageFile._Tile("gif", (0, 0) + im.size, 0, RAWMODE[im_out.mode])] + ) + + fp.write(b"\0") # end of image data + + +def _getbbox( + base_im: Image.Image, im_frame: Image.Image +) -> tuple[Image.Image, tuple[int, int, int, int] | None]: + palette_bytes = [ + bytes(im.palette.palette) if im.palette else b"" for im in (base_im, im_frame) + ] + if palette_bytes[0] != palette_bytes[1]: + im_frame = im_frame.convert("RGBA") + base_im = base_im.convert("RGBA") + delta = ImageChops.subtract_modulo(im_frame, base_im) + return delta, delta.getbbox(alpha_only=False) + + +class _Frame(NamedTuple): + im: Image.Image + bbox: tuple[int, int, int, int] | None + encoderinfo: dict[str, Any] + + +def _write_multiple_frames( + im: Image.Image, fp: IO[bytes], palette: _Palette | None +) -> bool: + duration = im.encoderinfo.get("duration") + disposal = im.encoderinfo.get("disposal", im.info.get("disposal")) + + im_frames: list[_Frame] = [] + previous_im: Image.Image | None = None + frame_count = 0 + background_im = None + for imSequence in itertools.chain([im], im.encoderinfo.get("append_images", [])): + for im_frame in ImageSequence.Iterator(imSequence): + # a copy is required here since seek can still mutate the image + im_frame = _normalize_mode(im_frame.copy()) + if frame_count == 0: + for k, v in im_frame.info.items(): + if k == "transparency": + continue + if isinstance(k, str): + im.encoderinfo.setdefault(k, v) + + encoderinfo = im.encoderinfo.copy() + if "transparency" in im_frame.info: + encoderinfo.setdefault("transparency", im_frame.info["transparency"]) + im_frame = _normalize_palette(im_frame, palette, encoderinfo) + if isinstance(duration, (list, tuple)): + encoderinfo["duration"] = duration[frame_count] + elif duration is None and "duration" in im_frame.info: + encoderinfo["duration"] = im_frame.info["duration"] + if isinstance(disposal, (list, tuple)): + encoderinfo["disposal"] = disposal[frame_count] + frame_count += 1 + + diff_frame = None + if im_frames and previous_im: + # delta frame + delta, bbox = _getbbox(previous_im, im_frame) + if not bbox: + # This frame is identical to the previous frame + if encoderinfo.get("duration"): + im_frames[-1].encoderinfo["duration"] += encoderinfo["duration"] + continue + if im_frames[-1].encoderinfo.get("disposal") == 2: + if background_im is None: + color = im.encoderinfo.get( + "transparency", im.info.get("transparency", (0, 0, 0)) + ) + background = _get_background(im_frame, color) + background_im = Image.new("P", im_frame.size, background) + assert im_frames[0].im.palette is not None + background_im.putpalette(im_frames[0].im.palette) + bbox = _getbbox(background_im, im_frame)[1] + elif encoderinfo.get("optimize") and im_frame.mode != "1": + if "transparency" not in encoderinfo: + assert im_frame.palette is not None + try: + encoderinfo["transparency"] = ( + im_frame.palette._new_color_index(im_frame) + ) + except ValueError: + pass + if "transparency" in encoderinfo: + # When the delta is zero, fill the image with transparency + diff_frame = im_frame.copy() + fill = Image.new("P", delta.size, encoderinfo["transparency"]) + if delta.mode == "RGBA": + r, g, b, a = delta.split() + mask = ImageMath.lambda_eval( + lambda args: args["convert"]( + args["max"]( + args["max"]( + args["max"](args["r"], args["g"]), args["b"] + ), + args["a"], + ) + * 255, + "1", + ), + r=r, + g=g, + b=b, + a=a, + ) + else: + if delta.mode == "P": + # Convert to L without considering palette + delta_l = Image.new("L", delta.size) + delta_l.putdata(delta.getdata()) + delta = delta_l + mask = ImageMath.lambda_eval( + lambda args: args["convert"](args["im"] * 255, "1"), + im=delta, + ) + diff_frame.paste(fill, mask=ImageOps.invert(mask)) + else: + bbox = None + previous_im = im_frame + im_frames.append(_Frame(diff_frame or im_frame, bbox, encoderinfo)) + + if len(im_frames) == 1: + if "duration" in im.encoderinfo: + # Since multiple frames will not be written, use the combined duration + im.encoderinfo["duration"] = im_frames[0].encoderinfo["duration"] + return False + + for frame_data in im_frames: + im_frame = frame_data.im + if not frame_data.bbox: + # global header + for s in _get_global_header(im_frame, frame_data.encoderinfo): + fp.write(s) + offset = (0, 0) + else: + # compress difference + if not palette: + frame_data.encoderinfo["include_color_table"] = True + + im_frame = im_frame.crop(frame_data.bbox) + offset = frame_data.bbox[:2] + _write_frame_data(fp, im_frame, offset, frame_data.encoderinfo) + return True + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + _save(im, fp, filename, save_all=True) + + +def _save( + im: Image.Image, fp: IO[bytes], filename: str | bytes, save_all: bool = False +) -> None: + # header + if "palette" in im.encoderinfo or "palette" in im.info: + palette = im.encoderinfo.get("palette", im.info.get("palette")) + else: + palette = None + im.encoderinfo.setdefault("optimize", True) + + if not save_all or not _write_multiple_frames(im, fp, palette): + _write_single_frame(im, fp, palette) + + fp.write(b";") # end of file + + if hasattr(fp, "flush"): + fp.flush() + + +def get_interlace(im: Image.Image) -> int: + interlace = im.encoderinfo.get("interlace", 1) + + # workaround for @PIL153 + if min(im.size) < 16: + interlace = 0 + + return interlace + + +def _write_local_header( + fp: IO[bytes], im: Image.Image, offset: tuple[int, int], flags: int +) -> None: + try: + transparency = im.encoderinfo["transparency"] + except KeyError: + transparency = None + + if "duration" in im.encoderinfo: + duration = int(im.encoderinfo["duration"] / 10) + else: + duration = 0 + + disposal = int(im.encoderinfo.get("disposal", 0)) + + if transparency is not None or duration != 0 or disposal: + packed_flag = 1 if transparency is not None else 0 + packed_flag |= disposal << 2 + + fp.write( + b"!" + + o8(249) # extension intro + + o8(4) # length + + o8(packed_flag) # packed fields + + o16(duration) # duration + + o8(transparency or 0) # transparency index + + o8(0) + ) + + include_color_table = im.encoderinfo.get("include_color_table") + if include_color_table: + palette_bytes = _get_palette_bytes(im) + color_table_size = _get_color_table_size(palette_bytes) + if color_table_size: + flags = flags | 128 # local color table flag + flags = flags | color_table_size + + fp.write( + b"," + + o16(offset[0]) # offset + + o16(offset[1]) + + o16(im.size[0]) # size + + o16(im.size[1]) + + o8(flags) # flags + ) + if include_color_table and color_table_size: + fp.write(_get_header_palette(palette_bytes)) + fp.write(o8(8)) # bits + + +def _save_netpbm(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + # Unused by default. + # To use, uncomment the register_save call at the end of the file. + # + # If you need real GIF compression and/or RGB quantization, you + # can use the external NETPBM/PBMPLUS utilities. See comments + # below for information on how to enable this. + tempfile = im._dump() + + try: + with open(filename, "wb") as f: + if im.mode != "RGB": + subprocess.check_call( + ["ppmtogif", tempfile], stdout=f, stderr=subprocess.DEVNULL + ) + else: + # Pipe ppmquant output into ppmtogif + # "ppmquant 256 %s | ppmtogif > %s" % (tempfile, filename) + quant_cmd = ["ppmquant", "256", tempfile] + togif_cmd = ["ppmtogif"] + quant_proc = subprocess.Popen( + quant_cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL + ) + togif_proc = subprocess.Popen( + togif_cmd, + stdin=quant_proc.stdout, + stdout=f, + stderr=subprocess.DEVNULL, + ) + + # Allow ppmquant to receive SIGPIPE if ppmtogif exits + assert quant_proc.stdout is not None + quant_proc.stdout.close() + + retcode = quant_proc.wait() + if retcode: + raise subprocess.CalledProcessError(retcode, quant_cmd) + + retcode = togif_proc.wait() + if retcode: + raise subprocess.CalledProcessError(retcode, togif_cmd) + finally: + try: + os.unlink(tempfile) + except OSError: + pass + + +# Force optimization so that we can test performance against +# cases where it took lots of memory and time previously. +_FORCE_OPTIMIZE = False + + +def _get_optimize(im: Image.Image, info: dict[str, Any]) -> list[int] | None: + """ + Palette optimization is a potentially expensive operation. + + This function determines if the palette should be optimized using + some heuristics, then returns the list of palette entries in use. + + :param im: Image object + :param info: encoderinfo + :returns: list of indexes of palette entries in use, or None + """ + if im.mode in ("P", "L") and info and info.get("optimize"): + # Potentially expensive operation. + + # The palette saves 3 bytes per color not used, but palette + # lengths are restricted to 3*(2**N) bytes. Max saving would + # be 768 -> 6 bytes if we went all the way down to 2 colors. + # * If we're over 128 colors, we can't save any space. + # * If there aren't any holes, it's not worth collapsing. + # * If we have a 'large' image, the palette is in the noise. + + # create the new palette if not every color is used + optimise = _FORCE_OPTIMIZE or im.mode == "L" + if optimise or im.width * im.height < 512 * 512: + # check which colors are used + used_palette_colors = [] + for i, count in enumerate(im.histogram()): + if count: + used_palette_colors.append(i) + + if optimise or max(used_palette_colors) >= len(used_palette_colors): + return used_palette_colors + + assert im.palette is not None + num_palette_colors = len(im.palette.palette) // Image.getmodebands( + im.palette.mode + ) + current_palette_size = 1 << (num_palette_colors - 1).bit_length() + if ( + # check that the palette would become smaller when saved + len(used_palette_colors) <= current_palette_size // 2 + # check that the palette is not already the smallest possible size + and current_palette_size > 2 + ): + return used_palette_colors + return None + + +def _get_color_table_size(palette_bytes: bytes) -> int: + # calculate the palette size for the header + if not palette_bytes: + return 0 + elif len(palette_bytes) < 9: + return 1 + else: + return math.ceil(math.log(len(palette_bytes) // 3, 2)) - 1 + + +def _get_header_palette(palette_bytes: bytes) -> bytes: + """ + Returns the palette, null padded to the next power of 2 (*3) bytes + suitable for direct inclusion in the GIF header + + :param palette_bytes: Unpadded palette bytes, in RGBRGB form + :returns: Null padded palette + """ + color_table_size = _get_color_table_size(palette_bytes) + + # add the missing amount of bytes + # the palette has to be 2< 0: + palette_bytes += o8(0) * 3 * actual_target_size_diff + return palette_bytes + + +def _get_palette_bytes(im: Image.Image) -> bytes: + """ + Gets the palette for inclusion in the gif header + + :param im: Image object + :returns: Bytes, len<=768 suitable for inclusion in gif header + """ + if not im.palette: + return b"" + + palette = bytes(im.palette.palette) + if im.palette.mode == "RGBA": + palette = b"".join(palette[i * 4 : i * 4 + 3] for i in range(len(palette) // 3)) + return palette + + +def _get_background( + im: Image.Image, + info_background: int | tuple[int, int, int] | tuple[int, int, int, int] | None, +) -> int: + background = 0 + if info_background: + if isinstance(info_background, tuple): + # WebPImagePlugin stores an RGBA value in info["background"] + # So it must be converted to the same format as GifImagePlugin's + # info["background"] - a global color table index + assert im.palette is not None + try: + background = im.palette.getcolor(info_background, im) + except ValueError as e: + if str(e) not in ( + # If all 256 colors are in use, + # then there is no need for the background color + "cannot allocate more than 256 colors", + # Ignore non-opaque WebP background + "cannot add non-opaque RGBA color to RGB palette", + ): + raise + else: + background = info_background + return background + + +def _get_global_header(im: Image.Image, info: dict[str, Any]) -> list[bytes]: + """Return a list of strings representing a GIF header""" + + # Header Block + # https://www.matthewflickinger.com/lab/whatsinagif/bits_and_bytes.asp + + version = b"87a" + if im.info.get("version") == b"89a" or ( + info + and ( + "transparency" in info + or info.get("loop") is not None + or info.get("duration") + or info.get("comment") + ) + ): + version = b"89a" + + background = _get_background(im, info.get("background")) + + palette_bytes = _get_palette_bytes(im) + color_table_size = _get_color_table_size(palette_bytes) + + header = [ + b"GIF" # signature + + version # version + + o16(im.size[0]) # canvas width + + o16(im.size[1]), # canvas height + # Logical Screen Descriptor + # size of global color table + global color table flag + o8(color_table_size + 128), # packed fields + # background + reserved/aspect + o8(background) + o8(0), + # Global Color Table + _get_header_palette(palette_bytes), + ] + if info.get("loop") is not None: + header.append( + b"!" + + o8(255) # extension intro + + o8(11) + + b"NETSCAPE2.0" + + o8(3) + + o8(1) + + o16(info["loop"]) # number of loops + + o8(0) + ) + if info.get("comment"): + comment_block = b"!" + o8(254) # extension intro + + comment = info["comment"] + if isinstance(comment, str): + comment = comment.encode() + for i in range(0, len(comment), 255): + subblock = comment[i : i + 255] + comment_block += o8(len(subblock)) + subblock + + comment_block += o8(0) + header.append(comment_block) + return header + + +def _write_frame_data( + fp: IO[bytes], + im_frame: Image.Image, + offset: tuple[int, int], + params: dict[str, Any], +) -> None: + try: + im_frame.encoderinfo = params + + # local image header + _write_local_header(fp, im_frame, offset, 0) + + ImageFile._save( + im_frame, + fp, + [ImageFile._Tile("gif", (0, 0) + im_frame.size, 0, RAWMODE[im_frame.mode])], + ) + + fp.write(b"\0") # end of image data + finally: + del im_frame.encoderinfo + + +# -------------------------------------------------------------------- +# Legacy GIF utilities + + +def getheader( + im: Image.Image, palette: _Palette | None = None, info: dict[str, Any] | None = None +) -> tuple[list[bytes], list[int] | None]: + """ + Legacy Method to get Gif data from image. + + Warning:: May modify image data. + + :param im: Image object + :param palette: bytes object containing the source palette, or .... + :param info: encoderinfo + :returns: tuple of(list of header items, optimized palette) + + """ + if info is None: + info = {} + + used_palette_colors = _get_optimize(im, info) + + if "background" not in info and "background" in im.info: + info["background"] = im.info["background"] + + im_mod = _normalize_palette(im, palette, info) + im.palette = im_mod.palette + im.im = im_mod.im + header = _get_global_header(im, info) + + return header, used_palette_colors + + +def getdata( + im: Image.Image, offset: tuple[int, int] = (0, 0), **params: Any +) -> list[bytes]: + """ + Legacy Method + + Return a list of strings representing this image. + The first string is a local image header, the rest contains + encoded image data. + + To specify duration, add the time in milliseconds, + e.g. ``getdata(im_frame, duration=1000)`` + + :param im: Image object + :param offset: Tuple of (x, y) pixels. Defaults to (0, 0) + :param \\**params: e.g. duration or other encoder info parameters + :returns: List of bytes containing GIF encoded frame data + + """ + from io import BytesIO + + class Collector(BytesIO): + data = [] + + def write(self, data: Buffer) -> int: + self.data.append(data) + return len(data) + + im.load() # make sure raster data is available + + fp = Collector() + + _write_frame_data(fp, im, offset, params) + + return fp.data + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GifImageFile.format, GifImageFile, _accept) +Image.register_save(GifImageFile.format, _save) +Image.register_save_all(GifImageFile.format, _save_all) +Image.register_extension(GifImageFile.format, ".gif") +Image.register_mime(GifImageFile.format, "image/gif") + +# +# Uncomment the following line if you wish to use NETPBM/PBMPLUS +# instead of the built-in "uncompressed" GIF encoder + +# Image.register_save(GifImageFile.format, _save_netpbm) diff --git a/venv/lib/python3.12/site-packages/PIL/GimpGradientFile.py b/venv/lib/python3.12/site-packages/PIL/GimpGradientFile.py new file mode 100644 index 0000000..220eac5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GimpGradientFile.py @@ -0,0 +1,149 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read (and render) GIMP gradient files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# + +""" +Stuff to translate curve segments to palette values (derived from +the corresponding code in GIMP, written by Federico Mena Quintero. +See the GIMP distribution for more information.) +""" +from __future__ import annotations + +from math import log, pi, sin, sqrt +from typing import IO, Callable + +from ._binary import o8 + +EPSILON = 1e-10 +"""""" # Enable auto-doc for data member + + +def linear(middle: float, pos: float) -> float: + if pos <= middle: + if middle < EPSILON: + return 0.0 + else: + return 0.5 * pos / middle + else: + pos = pos - middle + middle = 1.0 - middle + if middle < EPSILON: + return 1.0 + else: + return 0.5 + 0.5 * pos / middle + + +def curved(middle: float, pos: float) -> float: + return pos ** (log(0.5) / log(max(middle, EPSILON))) + + +def sine(middle: float, pos: float) -> float: + return (sin((-pi / 2.0) + pi * linear(middle, pos)) + 1.0) / 2.0 + + +def sphere_increasing(middle: float, pos: float) -> float: + return sqrt(1.0 - (linear(middle, pos) - 1.0) ** 2) + + +def sphere_decreasing(middle: float, pos: float) -> float: + return 1.0 - sqrt(1.0 - linear(middle, pos) ** 2) + + +SEGMENTS = [linear, curved, sine, sphere_increasing, sphere_decreasing] +"""""" # Enable auto-doc for data member + + +class GradientFile: + gradient: ( + list[ + tuple[ + float, + float, + float, + list[float], + list[float], + Callable[[float, float], float], + ] + ] + | None + ) = None + + def getpalette(self, entries: int = 256) -> tuple[bytes, str]: + assert self.gradient is not None + palette = [] + + ix = 0 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + for i in range(entries): + x = i / (entries - 1) + + while x1 < x: + ix += 1 + x0, x1, xm, rgb0, rgb1, segment = self.gradient[ix] + + w = x1 - x0 + + if w < EPSILON: + scale = segment(0.5, 0.5) + else: + scale = segment((xm - x0) / w, (x - x0) / w) + + # expand to RGBA + r = o8(int(255 * ((rgb1[0] - rgb0[0]) * scale + rgb0[0]) + 0.5)) + g = o8(int(255 * ((rgb1[1] - rgb0[1]) * scale + rgb0[1]) + 0.5)) + b = o8(int(255 * ((rgb1[2] - rgb0[2]) * scale + rgb0[2]) + 0.5)) + a = o8(int(255 * ((rgb1[3] - rgb0[3]) * scale + rgb0[3]) + 0.5)) + + # add to palette + palette.append(r + g + b + a) + + return b"".join(palette), "RGBA" + + +class GimpGradientFile(GradientFile): + """File handler for GIMP's gradient format.""" + + def __init__(self, fp: IO[bytes]) -> None: + if fp.readline()[:13] != b"GIMP Gradient": + msg = "not a GIMP gradient file" + raise SyntaxError(msg) + + line = fp.readline() + + # GIMP 1.2 gradient files don't contain a name, but GIMP 1.3 files do + if line.startswith(b"Name: "): + line = fp.readline().strip() + + count = int(line) + + self.gradient = [] + + for i in range(count): + s = fp.readline().split() + w = [float(x) for x in s[:11]] + + x0, x1 = w[0], w[2] + xm = w[1] + rgb0 = w[3:7] + rgb1 = w[7:11] + + segment = SEGMENTS[int(s[11])] + cspace = int(s[12]) + + if cspace != 0: + msg = "cannot handle HSV colour space" + raise OSError(msg) + + self.gradient.append((x0, x1, xm, rgb0, rgb1, segment)) diff --git a/venv/lib/python3.12/site-packages/PIL/GimpPaletteFile.py b/venv/lib/python3.12/site-packages/PIL/GimpPaletteFile.py new file mode 100644 index 0000000..4cad0eb --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GimpPaletteFile.py @@ -0,0 +1,58 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read GIMP palette files +# +# History: +# 1997-08-23 fl Created +# 2004-09-07 fl Support GIMP 2.0 palette files. +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1997-2004. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re +from typing import IO + +from ._binary import o8 + + +class GimpPaletteFile: + """File handler for GIMP's palette format.""" + + rawmode = "RGB" + + def __init__(self, fp: IO[bytes]) -> None: + palette = [o8(i) * 3 for i in range(256)] + + if fp.readline()[:12] != b"GIMP Palette": + msg = "not a GIMP palette file" + raise SyntaxError(msg) + + for i in range(256): + s = fp.readline() + if not s: + break + + # skip fields and comment lines + if re.match(rb"\w+:|#", s): + continue + if len(s) > 100: + msg = "bad palette file" + raise SyntaxError(msg) + + v = tuple(map(int, s.split()[:3])) + if len(v) != 3: + msg = "bad palette entry" + raise ValueError(msg) + + palette[i] = o8(v[0]) + o8(v[1]) + o8(v[2]) + + self.palette = b"".join(palette) + + def getpalette(self) -> tuple[bytes, str]: + return self.palette, self.rawmode diff --git a/venv/lib/python3.12/site-packages/PIL/GribStubImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/GribStubImagePlugin.py new file mode 100644 index 0000000..e9aa084 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/GribStubImagePlugin.py @@ -0,0 +1,76 @@ +# +# The Python Imaging Library +# $Id$ +# +# GRIB stub adapter +# +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler: ImageFile.StubHandler | None) -> None: + """ + Install application-specific GRIB image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"GRIB" and prefix[7] == 1 + + +class GribStubImageFile(ImageFile.StubImageFile): + format = "GRIB" + format_description = "GRIB" + + def _open(self) -> None: + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + msg = "Not a GRIB file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self) -> ImageFile.StubHandler | None: + return _handler + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if _handler is None or not hasattr(_handler, "save"): + msg = "GRIB save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(GribStubImageFile.format, GribStubImageFile, _accept) +Image.register_save(GribStubImageFile.format, _save) + +Image.register_extension(GribStubImageFile.format, ".grib") diff --git a/venv/lib/python3.12/site-packages/PIL/Hdf5StubImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/Hdf5StubImagePlugin.py new file mode 100644 index 0000000..cc9e73d --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/Hdf5StubImagePlugin.py @@ -0,0 +1,76 @@ +# +# The Python Imaging Library +# $Id$ +# +# HDF5 stub adapter +# +# Copyright (c) 2000-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile + +_handler = None + + +def register_handler(handler: ImageFile.StubHandler | None) -> None: + """ + Install application-specific HDF5 image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +# -------------------------------------------------------------------- +# Image adapter + + +def _accept(prefix: bytes) -> bool: + return prefix[:8] == b"\x89HDF\r\n\x1a\n" + + +class HDF5StubImageFile(ImageFile.StubImageFile): + format = "HDF5" + format_description = "HDF5" + + def _open(self) -> None: + offset = self.fp.tell() + + if not _accept(self.fp.read(8)): + msg = "Not an HDF file" + raise SyntaxError(msg) + + self.fp.seek(offset) + + # make something up + self._mode = "F" + self._size = 1, 1 + + loader = self._load() + if loader: + loader.open(self) + + def _load(self) -> ImageFile.StubHandler | None: + return _handler + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if _handler is None or not hasattr(_handler, "save"): + msg = "HDF5 save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(HDF5StubImageFile.format, HDF5StubImageFile, _accept) +Image.register_save(HDF5StubImageFile.format, _save) + +Image.register_extensions(HDF5StubImageFile.format, [".h5", ".hdf"]) diff --git a/venv/lib/python3.12/site-packages/PIL/IcnsImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/IcnsImagePlugin.py new file mode 100644 index 0000000..9757b2b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/IcnsImagePlugin.py @@ -0,0 +1,412 @@ +# +# The Python Imaging Library. +# $Id$ +# +# macOS icns file decoder, based on icns.py by Bob Ippolito. +# +# history: +# 2004-10-09 fl Turned into a PIL plugin; removed 2.3 dependencies. +# 2020-04-04 Allow saving on all operating systems. +# +# Copyright (c) 2004 by Bob Ippolito. +# Copyright (c) 2004 by Secret Labs. +# Copyright (c) 2004 by Fredrik Lundh. +# Copyright (c) 2014 by Alastair Houghton. +# Copyright (c) 2020 by Pan Jing. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import struct +import sys +from typing import IO + +from . import Image, ImageFile, PngImagePlugin, features +from ._deprecate import deprecate + +enable_jpeg2k = features.check_codec("jpg_2000") +if enable_jpeg2k: + from . import Jpeg2KImagePlugin + +MAGIC = b"icns" +HEADERSIZE = 8 + + +def nextheader(fobj: IO[bytes]) -> tuple[bytes, int]: + return struct.unpack(">4sI", fobj.read(HEADERSIZE)) + + +def read_32t( + fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int] +) -> dict[str, Image.Image]: + # The 128x128 icon seems to have an extra header for some reason. + (start, length) = start_length + fobj.seek(start) + sig = fobj.read(4) + if sig != b"\x00\x00\x00\x00": + msg = "Unknown signature, expecting 0x00000000" + raise SyntaxError(msg) + return read_32(fobj, (start + 4, length - 4), size) + + +def read_32( + fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int] +) -> dict[str, Image.Image]: + """ + Read a 32bit RGB icon resource. Seems to be either uncompressed or + an RLE packbits-like scheme. + """ + (start, length) = start_length + fobj.seek(start) + pixel_size = (size[0] * size[2], size[1] * size[2]) + sizesq = pixel_size[0] * pixel_size[1] + if length == sizesq * 3: + # uncompressed ("RGBRGBGB") + indata = fobj.read(length) + im = Image.frombuffer("RGB", pixel_size, indata, "raw", "RGB", 0, 1) + else: + # decode image + im = Image.new("RGB", pixel_size, None) + for band_ix in range(3): + data = [] + bytesleft = sizesq + while bytesleft > 0: + byte = fobj.read(1) + if not byte: + break + byte_int = byte[0] + if byte_int & 0x80: + blocksize = byte_int - 125 + byte = fobj.read(1) + for i in range(blocksize): + data.append(byte) + else: + blocksize = byte_int + 1 + data.append(fobj.read(blocksize)) + bytesleft -= blocksize + if bytesleft <= 0: + break + if bytesleft != 0: + msg = f"Error reading channel [{repr(bytesleft)} left]" + raise SyntaxError(msg) + band = Image.frombuffer("L", pixel_size, b"".join(data), "raw", "L", 0, 1) + im.im.putband(band.im, band_ix) + return {"RGB": im} + + +def read_mk( + fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int] +) -> dict[str, Image.Image]: + # Alpha masks seem to be uncompressed + start = start_length[0] + fobj.seek(start) + pixel_size = (size[0] * size[2], size[1] * size[2]) + sizesq = pixel_size[0] * pixel_size[1] + band = Image.frombuffer("L", pixel_size, fobj.read(sizesq), "raw", "L", 0, 1) + return {"A": band} + + +def read_png_or_jpeg2000( + fobj: IO[bytes], start_length: tuple[int, int], size: tuple[int, int, int] +) -> dict[str, Image.Image]: + (start, length) = start_length + fobj.seek(start) + sig = fobj.read(12) + + im: Image.Image + if sig[:8] == b"\x89PNG\x0d\x0a\x1a\x0a": + fobj.seek(start) + im = PngImagePlugin.PngImageFile(fobj) + Image._decompression_bomb_check(im.size) + return {"RGBA": im} + elif ( + sig[:4] == b"\xff\x4f\xff\x51" + or sig[:4] == b"\x0d\x0a\x87\x0a" + or sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" + ): + if not enable_jpeg2k: + msg = ( + "Unsupported icon subimage format (rebuild PIL " + "with JPEG 2000 support to fix this)" + ) + raise ValueError(msg) + # j2k, jpc or j2c + fobj.seek(start) + jp2kstream = fobj.read(length) + f = io.BytesIO(jp2kstream) + im = Jpeg2KImagePlugin.Jpeg2KImageFile(f) + Image._decompression_bomb_check(im.size) + if im.mode != "RGBA": + im = im.convert("RGBA") + return {"RGBA": im} + else: + msg = "Unsupported icon subimage format" + raise ValueError(msg) + + +class IcnsFile: + SIZES = { + (512, 512, 2): [(b"ic10", read_png_or_jpeg2000)], + (512, 512, 1): [(b"ic09", read_png_or_jpeg2000)], + (256, 256, 2): [(b"ic14", read_png_or_jpeg2000)], + (256, 256, 1): [(b"ic08", read_png_or_jpeg2000)], + (128, 128, 2): [(b"ic13", read_png_or_jpeg2000)], + (128, 128, 1): [ + (b"ic07", read_png_or_jpeg2000), + (b"it32", read_32t), + (b"t8mk", read_mk), + ], + (64, 64, 1): [(b"icp6", read_png_or_jpeg2000)], + (32, 32, 2): [(b"ic12", read_png_or_jpeg2000)], + (48, 48, 1): [(b"ih32", read_32), (b"h8mk", read_mk)], + (32, 32, 1): [ + (b"icp5", read_png_or_jpeg2000), + (b"il32", read_32), + (b"l8mk", read_mk), + ], + (16, 16, 2): [(b"ic11", read_png_or_jpeg2000)], + (16, 16, 1): [ + (b"icp4", read_png_or_jpeg2000), + (b"is32", read_32), + (b"s8mk", read_mk), + ], + } + + def __init__(self, fobj: IO[bytes]) -> None: + """ + fobj is a file-like object as an icns resource + """ + # signature : (start, length) + self.dct = {} + self.fobj = fobj + sig, filesize = nextheader(fobj) + if not _accept(sig): + msg = "not an icns file" + raise SyntaxError(msg) + i = HEADERSIZE + while i < filesize: + sig, blocksize = nextheader(fobj) + if blocksize <= 0: + msg = "invalid block header" + raise SyntaxError(msg) + i += HEADERSIZE + blocksize -= HEADERSIZE + self.dct[sig] = (i, blocksize) + fobj.seek(blocksize, io.SEEK_CUR) + i += blocksize + + def itersizes(self) -> list[tuple[int, int, int]]: + sizes = [] + for size, fmts in self.SIZES.items(): + for fmt, reader in fmts: + if fmt in self.dct: + sizes.append(size) + break + return sizes + + def bestsize(self) -> tuple[int, int, int]: + sizes = self.itersizes() + if not sizes: + msg = "No 32bit icon resources found" + raise SyntaxError(msg) + return max(sizes) + + def dataforsize(self, size: tuple[int, int, int]) -> dict[str, Image.Image]: + """ + Get an icon resource as {channel: array}. Note that + the arrays are bottom-up like windows bitmaps and will likely + need to be flipped or transposed in some way. + """ + dct = {} + for code, reader in self.SIZES[size]: + desc = self.dct.get(code) + if desc is not None: + dct.update(reader(self.fobj, desc, size)) + return dct + + def getimage( + self, size: tuple[int, int] | tuple[int, int, int] | None = None + ) -> Image.Image: + if size is None: + size = self.bestsize() + elif len(size) == 2: + size = (size[0], size[1], 1) + channels = self.dataforsize(size) + + im = channels.get("RGBA") + if im: + return im + + im = channels["RGB"].copy() + try: + im.putalpha(channels["A"]) + except KeyError: + pass + return im + + +## +# Image plugin for Mac OS icons. + + +class IcnsImageFile(ImageFile.ImageFile): + """ + PIL image support for Mac OS .icns files. + Chooses the best resolution, but will possibly load + a different size image if you mutate the size attribute + before calling 'load'. + + The info dictionary has a key 'sizes' that is a list + of sizes that the icns file has. + """ + + format = "ICNS" + format_description = "Mac OS icns resource" + + def _open(self) -> None: + self.icns = IcnsFile(self.fp) + self._mode = "RGBA" + self.info["sizes"] = self.icns.itersizes() + self.best_size = self.icns.bestsize() + self.size = ( + self.best_size[0] * self.best_size[2], + self.best_size[1] * self.best_size[2], + ) + + @property # type: ignore[override] + def size(self) -> tuple[int, int] | tuple[int, int, int]: + return self._size + + @size.setter + def size(self, value: tuple[int, int] | tuple[int, int, int]) -> None: + if len(value) == 3: + deprecate("Setting size to (width, height, scale)", 12, "load(scale)") + if value in self.info["sizes"]: + self._size = value # type: ignore[assignment] + return + else: + # Check that a matching size exists, + # or that there is a scale that would create a size that matches + for size in self.info["sizes"]: + simple_size = size[0] * size[2], size[1] * size[2] + scale = simple_size[0] // value[0] + if simple_size[1] / value[1] == scale: + self._size = value + return + msg = "This is not one of the allowed sizes of this image" + raise ValueError(msg) + + def load(self, scale: int | None = None) -> Image.core.PixelAccess | None: + if scale is not None or len(self.size) == 3: + if scale is None and len(self.size) == 3: + scale = self.size[2] + assert scale is not None + width, height = self.size[:2] + self.size = width * scale, height * scale + self.best_size = width, height, scale + + px = Image.Image.load(self) + if self._im is not None and self.im.size == self.size: + # Already loaded + return px + self.load_prepare() + # This is likely NOT the best way to do it, but whatever. + im = self.icns.getimage(self.best_size) + + # If this is a PNG or JPEG 2000, it won't be loaded yet + px = im.load() + + self.im = im.im + self._mode = im.mode + self.size = im.size + + return px + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + """ + Saves the image as a series of PNG files, + that are then combined into a .icns file. + """ + if hasattr(fp, "flush"): + fp.flush() + + sizes = { + b"ic07": 128, + b"ic08": 256, + b"ic09": 512, + b"ic10": 1024, + b"ic11": 32, + b"ic12": 64, + b"ic13": 256, + b"ic14": 512, + } + provided_images = {im.width: im for im in im.encoderinfo.get("append_images", [])} + size_streams = {} + for size in set(sizes.values()): + image = ( + provided_images[size] + if size in provided_images + else im.resize((size, size)) + ) + + temp = io.BytesIO() + image.save(temp, "png") + size_streams[size] = temp.getvalue() + + entries = [] + for type, size in sizes.items(): + stream = size_streams[size] + entries.append((type, HEADERSIZE + len(stream), stream)) + + # Header + fp.write(MAGIC) + file_length = HEADERSIZE # Header + file_length += HEADERSIZE + 8 * len(entries) # TOC + file_length += sum(entry[1] for entry in entries) + fp.write(struct.pack(">i", file_length)) + + # TOC + fp.write(b"TOC ") + fp.write(struct.pack(">i", HEADERSIZE + len(entries) * HEADERSIZE)) + for entry in entries: + fp.write(entry[0]) + fp.write(struct.pack(">i", entry[1])) + + # Data + for entry in entries: + fp.write(entry[0]) + fp.write(struct.pack(">i", entry[1])) + fp.write(entry[2]) + + if hasattr(fp, "flush"): + fp.flush() + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == MAGIC + + +Image.register_open(IcnsImageFile.format, IcnsImageFile, _accept) +Image.register_extension(IcnsImageFile.format, ".icns") + +Image.register_save(IcnsImageFile.format, _save) +Image.register_mime(IcnsImageFile.format, "image/icns") + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 IcnsImagePlugin.py [file]") + sys.exit() + + with open(sys.argv[1], "rb") as fp: + imf = IcnsImageFile(fp) + for size in imf.info["sizes"]: + width, height, scale = imf.size = size + imf.save(f"out-{width}-{height}-{scale}.png") + with Image.open(sys.argv[1]) as im: + im.save("out.png") + if sys.platform == "windows": + os.startfile("out.png") diff --git a/venv/lib/python3.12/site-packages/PIL/IcoImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/IcoImagePlugin.py new file mode 100644 index 0000000..e879f18 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/IcoImagePlugin.py @@ -0,0 +1,381 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Windows Icon support for PIL +# +# History: +# 96-05-27 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# + +# This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis +# . +# https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki +# +# Icon format references: +# * https://en.wikipedia.org/wiki/ICO_(file_format) +# * https://msdn.microsoft.com/en-us/library/ms997538.aspx +from __future__ import annotations + +import warnings +from io import BytesIO +from math import ceil, log +from typing import IO, NamedTuple + +from . import BmpImagePlugin, Image, ImageFile, PngImagePlugin +from ._binary import i16le as i16 +from ._binary import i32le as i32 +from ._binary import o8 +from ._binary import o16le as o16 +from ._binary import o32le as o32 + +# +# -------------------------------------------------------------------- + +_MAGIC = b"\0\0\1\0" + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + fp.write(_MAGIC) # (2+2) + bmp = im.encoderinfo.get("bitmap_format") == "bmp" + sizes = im.encoderinfo.get( + "sizes", + [(16, 16), (24, 24), (32, 32), (48, 48), (64, 64), (128, 128), (256, 256)], + ) + frames = [] + provided_ims = [im] + im.encoderinfo.get("append_images", []) + width, height = im.size + for size in sorted(set(sizes)): + if size[0] > width or size[1] > height or size[0] > 256 or size[1] > 256: + continue + + for provided_im in provided_ims: + if provided_im.size != size: + continue + frames.append(provided_im) + if bmp: + bits = BmpImagePlugin.SAVE[provided_im.mode][1] + bits_used = [bits] + for other_im in provided_ims: + if other_im.size != size: + continue + bits = BmpImagePlugin.SAVE[other_im.mode][1] + if bits not in bits_used: + # Another image has been supplied for this size + # with a different bit depth + frames.append(other_im) + bits_used.append(bits) + break + else: + # TODO: invent a more convenient method for proportional scalings + frame = provided_im.copy() + frame.thumbnail(size, Image.Resampling.LANCZOS, reducing_gap=None) + frames.append(frame) + fp.write(o16(len(frames))) # idCount(2) + offset = fp.tell() + len(frames) * 16 + for frame in frames: + width, height = frame.size + # 0 means 256 + fp.write(o8(width if width < 256 else 0)) # bWidth(1) + fp.write(o8(height if height < 256 else 0)) # bHeight(1) + + bits, colors = BmpImagePlugin.SAVE[frame.mode][1:] if bmp else (32, 0) + fp.write(o8(colors)) # bColorCount(1) + fp.write(b"\0") # bReserved(1) + fp.write(b"\0\0") # wPlanes(2) + fp.write(o16(bits)) # wBitCount(2) + + image_io = BytesIO() + if bmp: + frame.save(image_io, "dib") + + if bits != 32: + and_mask = Image.new("1", size) + ImageFile._save( + and_mask, + image_io, + [ImageFile._Tile("raw", (0, 0) + size, 0, ("1", 0, -1))], + ) + else: + frame.save(image_io, "png") + image_io.seek(0) + image_bytes = image_io.read() + if bmp: + image_bytes = image_bytes[:8] + o32(height * 2) + image_bytes[12:] + bytes_len = len(image_bytes) + fp.write(o32(bytes_len)) # dwBytesInRes(4) + fp.write(o32(offset)) # dwImageOffset(4) + current = fp.tell() + fp.seek(offset) + fp.write(image_bytes) + offset = offset + bytes_len + fp.seek(current) + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == _MAGIC + + +class IconHeader(NamedTuple): + width: int + height: int + nb_color: int + reserved: int + planes: int + bpp: int + size: int + offset: int + dim: tuple[int, int] + square: int + color_depth: int + + +class IcoFile: + def __init__(self, buf: IO[bytes]) -> None: + """ + Parse image from file-like object containing ico file data + """ + + # check magic + s = buf.read(6) + if not _accept(s): + msg = "not an ICO file" + raise SyntaxError(msg) + + self.buf = buf + self.entry = [] + + # Number of items in file + self.nb_items = i16(s, 4) + + # Get headers for each item + for i in range(self.nb_items): + s = buf.read(16) + + # See Wikipedia + width = s[0] or 256 + height = s[1] or 256 + + # No. of colors in image (0 if >=8bpp) + nb_color = s[2] + bpp = i16(s, 6) + icon_header = IconHeader( + width=width, + height=height, + nb_color=nb_color, + reserved=s[3], + planes=i16(s, 4), + bpp=i16(s, 6), + size=i32(s, 8), + offset=i32(s, 12), + dim=(width, height), + square=width * height, + # See Wikipedia notes about color depth. + # We need this just to differ images with equal sizes + color_depth=bpp or (nb_color != 0 and ceil(log(nb_color, 2))) or 256, + ) + + self.entry.append(icon_header) + + self.entry = sorted(self.entry, key=lambda x: x.color_depth) + # ICO images are usually squares + self.entry = sorted(self.entry, key=lambda x: x.square, reverse=True) + + def sizes(self) -> set[tuple[int, int]]: + """ + Get a set of all available icon sizes and color depths. + """ + return {(h.width, h.height) for h in self.entry} + + def getentryindex(self, size: tuple[int, int], bpp: int | bool = False) -> int: + for i, h in enumerate(self.entry): + if size == h.dim and (bpp is False or bpp == h.color_depth): + return i + return 0 + + def getimage(self, size: tuple[int, int], bpp: int | bool = False) -> Image.Image: + """ + Get an image from the icon + """ + return self.frame(self.getentryindex(size, bpp)) + + def frame(self, idx: int) -> Image.Image: + """ + Get an image from frame idx + """ + + header = self.entry[idx] + + self.buf.seek(header.offset) + data = self.buf.read(8) + self.buf.seek(header.offset) + + im: Image.Image + if data[:8] == PngImagePlugin._MAGIC: + # png frame + im = PngImagePlugin.PngImageFile(self.buf) + Image._decompression_bomb_check(im.size) + else: + # XOR + AND mask bmp frame + im = BmpImagePlugin.DibImageFile(self.buf) + Image._decompression_bomb_check(im.size) + + # change tile dimension to only encompass XOR image + im._size = (im.size[0], int(im.size[1] / 2)) + d, e, o, a = im.tile[0] + im.tile[0] = ImageFile._Tile(d, (0, 0) + im.size, o, a) + + # figure out where AND mask image starts + if header.bpp == 32: + # 32-bit color depth icon image allows semitransparent areas + # PIL's DIB format ignores transparency bits, recover them. + # The DIB is packed in BGRX byte order where X is the alpha + # channel. + + # Back up to start of bmp data + self.buf.seek(o) + # extract every 4th byte (eg. 3,7,11,15,...) + alpha_bytes = self.buf.read(im.size[0] * im.size[1] * 4)[3::4] + + # convert to an 8bpp grayscale image + try: + mask = Image.frombuffer( + "L", # 8bpp + im.size, # (w, h) + alpha_bytes, # source chars + "raw", # raw decoder + ("L", 0, -1), # 8bpp inverted, unpadded, reversed + ) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + mask = None + else: + raise + else: + # get AND image from end of bitmap + w = im.size[0] + if (w % 32) > 0: + # bitmap row data is aligned to word boundaries + w += 32 - (im.size[0] % 32) + + # the total mask data is + # padded row size * height / bits per char + + total_bytes = int((w * im.size[1]) / 8) + and_mask_offset = header.offset + header.size - total_bytes + + self.buf.seek(and_mask_offset) + mask_data = self.buf.read(total_bytes) + + # convert raw data to image + try: + mask = Image.frombuffer( + "1", # 1 bpp + im.size, # (w, h) + mask_data, # source chars + "raw", # raw decoder + ("1;I", int(w / 8), -1), # 1bpp inverted, padded, reversed + ) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + mask = None + else: + raise + + # now we have two images, im is XOR image and mask is AND image + + # apply mask image as alpha channel + if mask: + im = im.convert("RGBA") + im.putalpha(mask) + + return im + + +## +# Image plugin for Windows Icon files. + + +class IcoImageFile(ImageFile.ImageFile): + """ + PIL read-only image support for Microsoft Windows .ico files. + + By default the largest resolution image in the file will be loaded. This + can be changed by altering the 'size' attribute before calling 'load'. + + The info dictionary has a key 'sizes' that is a list of the sizes available + in the icon file. + + Handles classic, XP and Vista icon formats. + + When saving, PNG compression is used. Support for this was only added in + Windows Vista. If you are unable to view the icon in Windows, convert the + image to "RGBA" mode before saving. + + This plugin is a refactored version of Win32IconImagePlugin by Bryan Davis + . + https://code.google.com/archive/p/casadebender/wikis/Win32IconImagePlugin.wiki + """ + + format = "ICO" + format_description = "Windows Icon" + + def _open(self) -> None: + self.ico = IcoFile(self.fp) + self.info["sizes"] = self.ico.sizes() + self.size = self.ico.entry[0].dim + self.load() + + @property + def size(self) -> tuple[int, int]: + return self._size + + @size.setter + def size(self, value: tuple[int, int]) -> None: + if value not in self.info["sizes"]: + msg = "This is not one of the allowed sizes of this image" + raise ValueError(msg) + self._size = value + + def load(self) -> Image.core.PixelAccess | None: + if self._im is not None and self.im.size == self.size: + # Already loaded + return Image.Image.load(self) + im = self.ico.getimage(self.size) + # if tile is PNG, it won't really be loaded yet + im.load() + self.im = im.im + self._mode = im.mode + if im.palette: + self.palette = im.palette + if im.size != self.size: + warnings.warn("Image was not the expected size") + + index = self.ico.getentryindex(self.size) + sizes = list(self.info["sizes"]) + sizes[index] = im.size + self.info["sizes"] = set(sizes) + + self.size = im.size + return None + + def load_seek(self, pos: int) -> None: + # Flag the ImageFile.Parser so that it + # just does all the decode at the end. + pass + + +# +# -------------------------------------------------------------------- + + +Image.register_open(IcoImageFile.format, IcoImageFile, _accept) +Image.register_save(IcoImageFile.format, _save) +Image.register_extension(IcoImageFile.format, ".ico") + +Image.register_mime(IcoImageFile.format, "image/x-icon") diff --git a/venv/lib/python3.12/site-packages/PIL/ImImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/ImImagePlugin.py new file mode 100644 index 0000000..f9f4734 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImImagePlugin.py @@ -0,0 +1,386 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IFUNC IM file handling for PIL +# +# history: +# 1995-09-01 fl Created. +# 1997-01-03 fl Save palette images +# 1997-01-08 fl Added sequence support +# 1997-01-23 fl Added P and RGB save support +# 1997-05-31 fl Read floating point images +# 1997-06-22 fl Save floating point images +# 1997-08-27 fl Read and save 1-bit images +# 1998-06-25 fl Added support for RGB+LUT images +# 1998-07-02 fl Added support for YCC images +# 1998-07-15 fl Renamed offset attribute to avoid name clash +# 1998-12-29 fl Added I;16 support +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# 2003-09-26 fl Added LA/PA support +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +import re +from typing import IO, Any + +from . import Image, ImageFile, ImagePalette + +# -------------------------------------------------------------------- +# Standard tags + +COMMENT = "Comment" +DATE = "Date" +EQUIPMENT = "Digitalization equipment" +FRAMES = "File size (no of images)" +LUT = "Lut" +NAME = "Name" +SCALE = "Scale (x,y)" +SIZE = "Image size (x*y)" +MODE = "Image type" + +TAGS = { + COMMENT: 0, + DATE: 0, + EQUIPMENT: 0, + FRAMES: 0, + LUT: 0, + NAME: 0, + SCALE: 0, + SIZE: 0, + MODE: 0, +} + +OPEN = { + # ifunc93/p3cfunc formats + "0 1 image": ("1", "1"), + "L 1 image": ("1", "1"), + "Greyscale image": ("L", "L"), + "Grayscale image": ("L", "L"), + "RGB image": ("RGB", "RGB;L"), + "RLB image": ("RGB", "RLB"), + "RYB image": ("RGB", "RLB"), + "B1 image": ("1", "1"), + "B2 image": ("P", "P;2"), + "B4 image": ("P", "P;4"), + "X 24 image": ("RGB", "RGB"), + "L 32 S image": ("I", "I;32"), + "L 32 F image": ("F", "F;32"), + # old p3cfunc formats + "RGB3 image": ("RGB", "RGB;T"), + "RYB3 image": ("RGB", "RYB;T"), + # extensions + "LA image": ("LA", "LA;L"), + "PA image": ("LA", "PA;L"), + "RGBA image": ("RGBA", "RGBA;L"), + "RGBX image": ("RGB", "RGBX;L"), + "CMYK image": ("CMYK", "CMYK;L"), + "YCC image": ("YCbCr", "YCbCr;L"), +} + +# ifunc95 extensions +for i in ["8", "8S", "16", "16S", "32", "32F"]: + OPEN[f"L {i} image"] = ("F", f"F;{i}") + OPEN[f"L*{i} image"] = ("F", f"F;{i}") +for i in ["16", "16L", "16B"]: + OPEN[f"L {i} image"] = (f"I;{i}", f"I;{i}") + OPEN[f"L*{i} image"] = (f"I;{i}", f"I;{i}") +for i in ["32S"]: + OPEN[f"L {i} image"] = ("I", f"I;{i}") + OPEN[f"L*{i} image"] = ("I", f"I;{i}") +for j in range(2, 33): + OPEN[f"L*{j} image"] = ("F", f"F;{j}") + + +# -------------------------------------------------------------------- +# Read IM directory + +split = re.compile(rb"^([A-Za-z][^:]*):[ \t]*(.*)[ \t]*$") + + +def number(s: Any) -> float: + try: + return int(s) + except ValueError: + return float(s) + + +## +# Image plugin for the IFUNC IM file format. + + +class ImImageFile(ImageFile.ImageFile): + format = "IM" + format_description = "IFUNC Image Memory" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + # Quick rejection: if there's not an LF among the first + # 100 bytes, this is (probably) not a text header. + + if b"\n" not in self.fp.read(100): + msg = "not an IM file" + raise SyntaxError(msg) + self.fp.seek(0) + + n = 0 + + # Default values + self.info[MODE] = "L" + self.info[SIZE] = (512, 512) + self.info[FRAMES] = 1 + + self.rawmode = "L" + + while True: + s = self.fp.read(1) + + # Some versions of IFUNC uses \n\r instead of \r\n... + if s == b"\r": + continue + + if not s or s == b"\0" or s == b"\x1A": + break + + # FIXME: this may read whole file if not a text file + s = s + self.fp.readline() + + if len(s) > 100: + msg = "not an IM file" + raise SyntaxError(msg) + + if s[-2:] == b"\r\n": + s = s[:-2] + elif s[-1:] == b"\n": + s = s[:-1] + + try: + m = split.match(s) + except re.error as e: + msg = "not an IM file" + raise SyntaxError(msg) from e + + if m: + k, v = m.group(1, 2) + + # Don't know if this is the correct encoding, + # but a decent guess (I guess) + k = k.decode("latin-1", "replace") + v = v.decode("latin-1", "replace") + + # Convert value as appropriate + if k in [FRAMES, SCALE, SIZE]: + v = v.replace("*", ",") + v = tuple(map(number, v.split(","))) + if len(v) == 1: + v = v[0] + elif k == MODE and v in OPEN: + v, self.rawmode = OPEN[v] + + # Add to dictionary. Note that COMMENT tags are + # combined into a list of strings. + if k == COMMENT: + if k in self.info: + self.info[k].append(v) + else: + self.info[k] = [v] + else: + self.info[k] = v + + if k in TAGS: + n += 1 + + else: + msg = f"Syntax error in IM header: {s.decode('ascii', 'replace')}" + raise SyntaxError(msg) + + if not n: + msg = "Not an IM file" + raise SyntaxError(msg) + + # Basic attributes + self._size = self.info[SIZE] + self._mode = self.info[MODE] + + # Skip forward to start of image data + while s and s[:1] != b"\x1A": + s = self.fp.read(1) + if not s: + msg = "File truncated" + raise SyntaxError(msg) + + if LUT in self.info: + # convert lookup table to palette or lut attribute + palette = self.fp.read(768) + greyscale = 1 # greyscale palette + linear = 1 # linear greyscale palette + for i in range(256): + if palette[i] == palette[i + 256] == palette[i + 512]: + if palette[i] != i: + linear = 0 + else: + greyscale = 0 + if self.mode in ["L", "LA", "P", "PA"]: + if greyscale: + if not linear: + self.lut = list(palette[:256]) + else: + if self.mode in ["L", "P"]: + self._mode = self.rawmode = "P" + elif self.mode in ["LA", "PA"]: + self._mode = "PA" + self.rawmode = "PA;L" + self.palette = ImagePalette.raw("RGB;L", palette) + elif self.mode == "RGB": + if not greyscale or not linear: + self.lut = list(palette) + + self.frame = 0 + + self.__offset = offs = self.fp.tell() + + self._fp = self.fp # FIXME: hack + + if self.rawmode[:2] == "F;": + # ifunc95 formats + try: + # use bit decoder (if necessary) + bits = int(self.rawmode[2:]) + if bits not in [8, 16, 32]: + self.tile = [ + ImageFile._Tile( + "bit", (0, 0) + self.size, offs, (bits, 8, 3, 0, -1) + ) + ] + return + except ValueError: + pass + + if self.rawmode in ["RGB;T", "RYB;T"]: + # Old LabEye/3PC files. Would be very surprised if anyone + # ever stumbled upon such a file ;-) + size = self.size[0] * self.size[1] + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offs, ("G", 0, -1)), + ImageFile._Tile("raw", (0, 0) + self.size, offs + size, ("R", 0, -1)), + ImageFile._Tile( + "raw", (0, 0) + self.size, offs + 2 * size, ("B", 0, -1) + ), + ] + else: + # LabEye/IFUNC files + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1)) + ] + + @property + def n_frames(self) -> int: + return self.info[FRAMES] + + @property + def is_animated(self) -> bool: + return self.info[FRAMES] > 1 + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + + self.frame = frame + + if self.mode == "1": + bits = 1 + else: + bits = 8 * len(self.mode) + + size = ((self.size[0] * bits + 7) // 8) * self.size[1] + offs = self.__offset + frame * size + + self.fp = self._fp + + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offs, (self.rawmode, 0, -1)) + ] + + def tell(self) -> int: + return self.frame + + +# +# -------------------------------------------------------------------- +# Save IM files + + +SAVE = { + # mode: (im type, raw mode) + "1": ("0 1", "1"), + "L": ("Greyscale", "L"), + "LA": ("LA", "LA;L"), + "P": ("Greyscale", "P"), + "PA": ("LA", "PA;L"), + "I": ("L 32S", "I;32S"), + "I;16": ("L 16", "I;16"), + "I;16L": ("L 16L", "I;16L"), + "I;16B": ("L 16B", "I;16B"), + "F": ("L 32F", "F;32F"), + "RGB": ("RGB", "RGB;L"), + "RGBA": ("RGBA", "RGBA;L"), + "RGBX": ("RGBX", "RGBX;L"), + "CMYK": ("CMYK", "CMYK;L"), + "YCbCr": ("YCC", "YCbCr;L"), +} + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + try: + image_type, rawmode = SAVE[im.mode] + except KeyError as e: + msg = f"Cannot save {im.mode} images as IM" + raise ValueError(msg) from e + + frames = im.encoderinfo.get("frames", 1) + + fp.write(f"Image type: {image_type} image\r\n".encode("ascii")) + if filename: + # Each line must be 100 characters or less, + # or: SyntaxError("not an IM file") + # 8 characters are used for "Name: " and "\r\n" + # Keep just the filename, ditch the potentially overlong path + if isinstance(filename, bytes): + filename = filename.decode("ascii") + name, ext = os.path.splitext(os.path.basename(filename)) + name = "".join([name[: 92 - len(ext)], ext]) + + fp.write(f"Name: {name}\r\n".encode("ascii")) + fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode("ascii")) + fp.write(f"File size (no of images): {frames}\r\n".encode("ascii")) + if im.mode in ["P", "PA"]: + fp.write(b"Lut: 1\r\n") + fp.write(b"\000" * (511 - fp.tell()) + b"\032") + if im.mode in ["P", "PA"]: + im_palette = im.im.getpalette("RGB", "RGB;L") + colors = len(im_palette) // 3 + palette = b"" + for i in range(3): + palette += im_palette[colors * i : colors * (i + 1)] + palette += b"\x00" * (256 - colors) + fp.write(palette) # 768 bytes + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, -1))] + ) + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(ImImageFile.format, ImImageFile) +Image.register_save(ImImageFile.format, _save) + +Image.register_extension(ImImageFile.format, ".im") diff --git a/venv/lib/python3.12/site-packages/PIL/Image.py b/venv/lib/python3.12/site-packages/PIL/Image.py new file mode 100644 index 0000000..4427039 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/Image.py @@ -0,0 +1,4198 @@ +# +# The Python Imaging Library. +# $Id$ +# +# the Image class wrapper +# +# partial release history: +# 1995-09-09 fl Created +# 1996-03-11 fl PIL release 0.0 (proof of concept) +# 1996-04-30 fl PIL release 0.1b1 +# 1999-07-28 fl PIL release 1.0 final +# 2000-06-07 fl PIL release 1.1 +# 2000-10-20 fl PIL release 1.1.1 +# 2001-05-07 fl PIL release 1.1.2 +# 2002-03-15 fl PIL release 1.1.3 +# 2003-05-10 fl PIL release 1.1.4 +# 2005-03-28 fl PIL release 1.1.5 +# 2006-12-02 fl PIL release 1.1.6 +# 2009-11-15 fl PIL release 1.1.7 +# +# Copyright (c) 1997-2009 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-2009 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +import abc +import atexit +import builtins +import io +import logging +import math +import os +import re +import struct +import sys +import tempfile +import warnings +from collections.abc import Callable, Iterator, MutableMapping, Sequence +from enum import IntEnum +from types import ModuleType +from typing import ( + IO, + TYPE_CHECKING, + Any, + Literal, + Protocol, + cast, +) + +# VERSION was removed in Pillow 6.0.0. +# PILLOW_VERSION was removed in Pillow 9.0.0. +# Use __version__ instead. +from . import ( + ExifTags, + ImageMode, + TiffTags, + UnidentifiedImageError, + __version__, + _plugins, +) +from ._binary import i32le, o32be, o32le +from ._deprecate import deprecate +from ._util import DeferredError, is_path + +ElementTree: ModuleType | None +try: + from defusedxml import ElementTree +except ImportError: + ElementTree = None + +logger = logging.getLogger(__name__) + + +class DecompressionBombWarning(RuntimeWarning): + pass + + +class DecompressionBombError(Exception): + pass + + +WARN_POSSIBLE_FORMATS: bool = False + +# Limit to around a quarter gigabyte for a 24-bit (3 bpp) image +MAX_IMAGE_PIXELS: int | None = int(1024 * 1024 * 1024 // 4 // 3) + + +try: + # If the _imaging C module is not present, Pillow will not load. + # Note that other modules should not refer to _imaging directly; + # import Image and use the Image.core variable instead. + # Also note that Image.core is not a publicly documented interface, + # and should be considered private and subject to change. + from . import _imaging as core + + if __version__ != getattr(core, "PILLOW_VERSION", None): + msg = ( + "The _imaging extension was built for another version of Pillow or PIL:\n" + f"Core version: {getattr(core, 'PILLOW_VERSION', None)}\n" + f"Pillow version: {__version__}" + ) + raise ImportError(msg) + +except ImportError as v: + core = DeferredError.new(ImportError("The _imaging C module is not installed.")) + # Explanations for ways that we know we might have an import error + if str(v).startswith("Module use of python"): + # The _imaging C module is present, but not compiled for + # the right version (windows only). Print a warning, if + # possible. + warnings.warn( + "The _imaging extension was built for another version of Python.", + RuntimeWarning, + ) + elif str(v).startswith("The _imaging extension"): + warnings.warn(str(v), RuntimeWarning) + # Fail here anyway. Don't let people run with a mostly broken Pillow. + # see docs/porting.rst + raise + + +def isImageType(t: Any) -> TypeGuard[Image]: + """ + Checks if an object is an image object. + + .. warning:: + + This function is for internal use only. + + :param t: object to check if it's an image + :returns: True if the object is an image + """ + deprecate("Image.isImageType(im)", 12, "isinstance(im, Image.Image)") + return hasattr(t, "im") + + +# +# Constants + + +# transpose +class Transpose(IntEnum): + FLIP_LEFT_RIGHT = 0 + FLIP_TOP_BOTTOM = 1 + ROTATE_90 = 2 + ROTATE_180 = 3 + ROTATE_270 = 4 + TRANSPOSE = 5 + TRANSVERSE = 6 + + +# transforms (also defined in Imaging.h) +class Transform(IntEnum): + AFFINE = 0 + EXTENT = 1 + PERSPECTIVE = 2 + QUAD = 3 + MESH = 4 + + +# resampling filters (also defined in Imaging.h) +class Resampling(IntEnum): + NEAREST = 0 + BOX = 4 + BILINEAR = 2 + HAMMING = 5 + BICUBIC = 3 + LANCZOS = 1 + + +_filters_support = { + Resampling.BOX: 0.5, + Resampling.BILINEAR: 1.0, + Resampling.HAMMING: 1.0, + Resampling.BICUBIC: 2.0, + Resampling.LANCZOS: 3.0, +} + + +# dithers +class Dither(IntEnum): + NONE = 0 + ORDERED = 1 # Not yet implemented + RASTERIZE = 2 # Not yet implemented + FLOYDSTEINBERG = 3 # default + + +# palettes/quantizers +class Palette(IntEnum): + WEB = 0 + ADAPTIVE = 1 + + +class Quantize(IntEnum): + MEDIANCUT = 0 + MAXCOVERAGE = 1 + FASTOCTREE = 2 + LIBIMAGEQUANT = 3 + + +module = sys.modules[__name__] +for enum in (Transpose, Transform, Resampling, Dither, Palette, Quantize): + for item in enum: + setattr(module, item.name, item.value) + + +if hasattr(core, "DEFAULT_STRATEGY"): + DEFAULT_STRATEGY = core.DEFAULT_STRATEGY + FILTERED = core.FILTERED + HUFFMAN_ONLY = core.HUFFMAN_ONLY + RLE = core.RLE + FIXED = core.FIXED + + +# -------------------------------------------------------------------- +# Registries + +if TYPE_CHECKING: + import mmap + from xml.etree.ElementTree import Element + + from IPython.lib.pretty import PrettyPrinter + + from . import ImageFile, ImageFilter, ImagePalette, ImageQt, TiffImagePlugin + from ._typing import CapsuleType, NumpyArray, StrOrBytesPath, TypeGuard +ID: list[str] = [] +OPEN: dict[ + str, + tuple[ + Callable[[IO[bytes], str | bytes], ImageFile.ImageFile], + Callable[[bytes], bool | str] | None, + ], +] = {} +MIME: dict[str, str] = {} +SAVE: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {} +SAVE_ALL: dict[str, Callable[[Image, IO[bytes], str | bytes], None]] = {} +EXTENSION: dict[str, str] = {} +DECODERS: dict[str, type[ImageFile.PyDecoder]] = {} +ENCODERS: dict[str, type[ImageFile.PyEncoder]] = {} + +# -------------------------------------------------------------------- +# Modes + +_ENDIAN = "<" if sys.byteorder == "little" else ">" + + +def _conv_type_shape(im: Image) -> tuple[tuple[int, ...], str]: + m = ImageMode.getmode(im.mode) + shape: tuple[int, ...] = (im.height, im.width) + extra = len(m.bands) + if extra != 1: + shape += (extra,) + return shape, m.typestr + + +MODES = [ + "1", + "CMYK", + "F", + "HSV", + "I", + "I;16", + "I;16B", + "I;16L", + "I;16N", + "L", + "LA", + "La", + "LAB", + "P", + "PA", + "RGB", + "RGBA", + "RGBa", + "RGBX", + "YCbCr", +] + +# raw modes that may be memory mapped. NOTE: if you change this, you +# may have to modify the stride calculation in map.c too! +_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B") + + +def getmodebase(mode: str) -> str: + """ + Gets the "base" mode for given mode. This function returns "L" for + images that contain grayscale data, and "RGB" for images that + contain color data. + + :param mode: Input mode. + :returns: "L" or "RGB". + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).basemode + + +def getmodetype(mode: str) -> str: + """ + Gets the storage type mode. Given a mode, this function returns a + single-layer mode suitable for storing individual bands. + + :param mode: Input mode. + :returns: "L", "I", or "F". + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).basetype + + +def getmodebandnames(mode: str) -> tuple[str, ...]: + """ + Gets a list of individual band names. Given a mode, this function returns + a tuple containing the names of individual bands (use + :py:method:`~PIL.Image.getmodetype` to get the mode used to store each + individual band. + + :param mode: Input mode. + :returns: A tuple containing band names. The length of the tuple + gives the number of bands in an image of the given mode. + :exception KeyError: If the input mode was not a standard mode. + """ + return ImageMode.getmode(mode).bands + + +def getmodebands(mode: str) -> int: + """ + Gets the number of individual bands for this mode. + + :param mode: Input mode. + :returns: The number of bands in this mode. + :exception KeyError: If the input mode was not a standard mode. + """ + return len(ImageMode.getmode(mode).bands) + + +# -------------------------------------------------------------------- +# Helpers + +_initialized = 0 + + +def preinit() -> None: + """ + Explicitly loads BMP, GIF, JPEG, PPM and PPM file format drivers. + + It is called when opening or saving images. + """ + + global _initialized + if _initialized >= 1: + return + + try: + from . import BmpImagePlugin + + assert BmpImagePlugin + except ImportError: + pass + try: + from . import GifImagePlugin + + assert GifImagePlugin + except ImportError: + pass + try: + from . import JpegImagePlugin + + assert JpegImagePlugin + except ImportError: + pass + try: + from . import PpmImagePlugin + + assert PpmImagePlugin + except ImportError: + pass + try: + from . import PngImagePlugin + + assert PngImagePlugin + except ImportError: + pass + + _initialized = 1 + + +def init() -> bool: + """ + Explicitly initializes the Python Imaging Library. This function + loads all available file format drivers. + + It is called when opening or saving images if :py:meth:`~preinit()` is + insufficient, and by :py:meth:`~PIL.features.pilinfo`. + """ + + global _initialized + if _initialized >= 2: + return False + + parent_name = __name__.rpartition(".")[0] + for plugin in _plugins: + try: + logger.debug("Importing %s", plugin) + __import__(f"{parent_name}.{plugin}", globals(), locals(), []) + except ImportError as e: + logger.debug("Image: failed to import %s: %s", plugin, e) + + if OPEN or SAVE: + _initialized = 2 + return True + return False + + +# -------------------------------------------------------------------- +# Codec factories (used by tobytes/frombytes and ImageFile.load) + + +def _getdecoder( + mode: str, decoder_name: str, args: Any, extra: tuple[Any, ...] = () +) -> core.ImagingDecoder | ImageFile.PyDecoder: + # tweak arguments + if args is None: + args = () + elif not isinstance(args, tuple): + args = (args,) + + try: + decoder = DECODERS[decoder_name] + except KeyError: + pass + else: + return decoder(mode, *args + extra) + + try: + # get decoder + decoder = getattr(core, f"{decoder_name}_decoder") + except AttributeError as e: + msg = f"decoder {decoder_name} not available" + raise OSError(msg) from e + return decoder(mode, *args + extra) + + +def _getencoder( + mode: str, encoder_name: str, args: Any, extra: tuple[Any, ...] = () +) -> core.ImagingEncoder | ImageFile.PyEncoder: + # tweak arguments + if args is None: + args = () + elif not isinstance(args, tuple): + args = (args,) + + try: + encoder = ENCODERS[encoder_name] + except KeyError: + pass + else: + return encoder(mode, *args + extra) + + try: + # get encoder + encoder = getattr(core, f"{encoder_name}_encoder") + except AttributeError as e: + msg = f"encoder {encoder_name} not available" + raise OSError(msg) from e + return encoder(mode, *args + extra) + + +# -------------------------------------------------------------------- +# Simple expression analyzer + + +class ImagePointTransform: + """ + Used with :py:meth:`~PIL.Image.Image.point` for single band images with more than + 8 bits, this represents an affine transformation, where the value is multiplied by + ``scale`` and ``offset`` is added. + """ + + def __init__(self, scale: float, offset: float) -> None: + self.scale = scale + self.offset = offset + + def __neg__(self) -> ImagePointTransform: + return ImagePointTransform(-self.scale, -self.offset) + + def __add__(self, other: ImagePointTransform | float) -> ImagePointTransform: + if isinstance(other, ImagePointTransform): + return ImagePointTransform( + self.scale + other.scale, self.offset + other.offset + ) + return ImagePointTransform(self.scale, self.offset + other) + + __radd__ = __add__ + + def __sub__(self, other: ImagePointTransform | float) -> ImagePointTransform: + return self + -other + + def __rsub__(self, other: ImagePointTransform | float) -> ImagePointTransform: + return other + -self + + def __mul__(self, other: ImagePointTransform | float) -> ImagePointTransform: + if isinstance(other, ImagePointTransform): + return NotImplemented + return ImagePointTransform(self.scale * other, self.offset * other) + + __rmul__ = __mul__ + + def __truediv__(self, other: ImagePointTransform | float) -> ImagePointTransform: + if isinstance(other, ImagePointTransform): + return NotImplemented + return ImagePointTransform(self.scale / other, self.offset / other) + + +def _getscaleoffset( + expr: Callable[[ImagePointTransform], ImagePointTransform | float] +) -> tuple[float, float]: + a = expr(ImagePointTransform(1, 0)) + return (a.scale, a.offset) if isinstance(a, ImagePointTransform) else (0, a) + + +# -------------------------------------------------------------------- +# Implementation wrapper + + +class SupportsGetData(Protocol): + def getdata( + self, + ) -> tuple[Transform, Sequence[int]]: ... + + +class Image: + """ + This class represents an image object. To create + :py:class:`~PIL.Image.Image` objects, use the appropriate factory + functions. There's hardly ever any reason to call the Image constructor + directly. + + * :py:func:`~PIL.Image.open` + * :py:func:`~PIL.Image.new` + * :py:func:`~PIL.Image.frombytes` + """ + + format: str | None = None + format_description: str | None = None + _close_exclusive_fp_after_loading = True + + def __init__(self) -> None: + # FIXME: take "new" parameters / other image? + # FIXME: turn mode and size into delegating properties? + self._im: core.ImagingCore | DeferredError | None = None + self._mode = "" + self._size = (0, 0) + self.palette: ImagePalette.ImagePalette | None = None + self.info: dict[str | tuple[int, int], Any] = {} + self.readonly = 0 + self._exif: Exif | None = None + + @property + def im(self) -> core.ImagingCore: + if isinstance(self._im, DeferredError): + raise self._im.ex + assert self._im is not None + return self._im + + @im.setter + def im(self, im: core.ImagingCore) -> None: + self._im = im + + @property + def width(self) -> int: + return self.size[0] + + @property + def height(self) -> int: + return self.size[1] + + @property + def size(self) -> tuple[int, int]: + return self._size + + @property + def mode(self) -> str: + return self._mode + + def _new(self, im: core.ImagingCore) -> Image: + new = Image() + new.im = im + new._mode = im.mode + new._size = im.size + if im.mode in ("P", "PA"): + if self.palette: + new.palette = self.palette.copy() + else: + from . import ImagePalette + + new.palette = ImagePalette.ImagePalette() + new.info = self.info.copy() + return new + + # Context manager support + def __enter__(self): + return self + + def _close_fp(self): + if getattr(self, "_fp", False): + if self._fp != self.fp: + self._fp.close() + self._fp = DeferredError(ValueError("Operation on closed image")) + if self.fp: + self.fp.close() + + def __exit__(self, *args): + if hasattr(self, "fp"): + if getattr(self, "_exclusive_fp", False): + self._close_fp() + self.fp = None + + def close(self) -> None: + """ + Closes the file pointer, if possible. + + This operation will destroy the image core and release its memory. + The image data will be unusable afterward. + + This function is required to close images that have multiple frames or + have not had their file read and closed by the + :py:meth:`~PIL.Image.Image.load` method. See :ref:`file-handling` for + more information. + """ + if hasattr(self, "fp"): + try: + self._close_fp() + self.fp = None + except Exception as msg: + logger.debug("Error closing: %s", msg) + + if getattr(self, "map", None): + self.map: mmap.mmap | None = None + + # Instead of simply setting to None, we're setting up a + # deferred error that will better explain that the core image + # object is gone. + self._im = DeferredError(ValueError("Operation on closed image")) + + def _copy(self) -> None: + self.load() + self.im = self.im.copy() + self.readonly = 0 + + def _ensure_mutable(self) -> None: + if self.readonly: + self._copy() + else: + self.load() + + def _dump( + self, file: str | None = None, format: str | None = None, **options: Any + ) -> str: + suffix = "" + if format: + suffix = f".{format}" + + if not file: + f, filename = tempfile.mkstemp(suffix) + os.close(f) + else: + filename = file + if not filename.endswith(suffix): + filename = filename + suffix + + self.load() + + if not format or format == "PPM": + self.im.save_ppm(filename) + else: + self.save(filename, format, **options) + + return filename + + def __eq__(self, other: object) -> bool: + if self.__class__ is not other.__class__: + return False + assert isinstance(other, Image) + return ( + self.mode == other.mode + and self.size == other.size + and self.info == other.info + and self.getpalette() == other.getpalette() + and self.tobytes() == other.tobytes() + ) + + def __repr__(self) -> str: + return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % ( + self.__class__.__module__, + self.__class__.__name__, + self.mode, + self.size[0], + self.size[1], + id(self), + ) + + def _repr_pretty_(self, p: PrettyPrinter, cycle: bool) -> None: + """IPython plain text display support""" + + # Same as __repr__ but without unpredictable id(self), + # to keep Jupyter notebook `text/plain` output stable. + p.text( + "<%s.%s image mode=%s size=%dx%d>" + % ( + self.__class__.__module__, + self.__class__.__name__, + self.mode, + self.size[0], + self.size[1], + ) + ) + + def _repr_image(self, image_format: str, **kwargs: Any) -> bytes | None: + """Helper function for iPython display hook. + + :param image_format: Image format. + :returns: image as bytes, saved into the given format. + """ + b = io.BytesIO() + try: + self.save(b, image_format, **kwargs) + except Exception: + return None + return b.getvalue() + + def _repr_png_(self) -> bytes | None: + """iPython display hook support for PNG format. + + :returns: PNG version of the image as bytes + """ + return self._repr_image("PNG", compress_level=1) + + def _repr_jpeg_(self) -> bytes | None: + """iPython display hook support for JPEG format. + + :returns: JPEG version of the image as bytes + """ + return self._repr_image("JPEG") + + @property + def __array_interface__(self) -> dict[str, str | bytes | int | tuple[int, ...]]: + # numpy array interface support + new: dict[str, str | bytes | int | tuple[int, ...]] = {"version": 3} + if self.mode == "1": + # Binary images need to be extended from bits to bytes + # See: https://github.com/python-pillow/Pillow/issues/350 + new["data"] = self.tobytes("raw", "L") + else: + new["data"] = self.tobytes() + new["shape"], new["typestr"] = _conv_type_shape(self) + return new + + def __getstate__(self) -> list[Any]: + im_data = self.tobytes() # load image first + return [self.info, self.mode, self.size, self.getpalette(), im_data] + + def __setstate__(self, state: list[Any]) -> None: + Image.__init__(self) + info, mode, size, palette, data = state + self.info = info + self._mode = mode + self._size = size + self.im = core.new(mode, size) + if mode in ("L", "LA", "P", "PA") and palette: + self.putpalette(palette) + self.frombytes(data) + + def tobytes(self, encoder_name: str = "raw", *args: Any) -> bytes: + """ + Return image as a bytes object. + + .. warning:: + + This method returns the raw image data from the internal + storage. For compressed image data (e.g. PNG, JPEG) use + :meth:`~.save`, with a BytesIO parameter for in-memory + data. + + :param encoder_name: What encoder to use. The default is to + use the standard "raw" encoder. + + A list of C encoders can be seen under + codecs section of the function array in + :file:`_imaging.c`. Python encoders are + registered within the relevant plugins. + :param args: Extra arguments to the encoder. + :returns: A :py:class:`bytes` object. + """ + + encoder_args: Any = args + if len(encoder_args) == 1 and isinstance(encoder_args[0], tuple): + # may pass tuple instead of argument list + encoder_args = encoder_args[0] + + if encoder_name == "raw" and encoder_args == (): + encoder_args = self.mode + + self.load() + + if self.width == 0 or self.height == 0: + return b"" + + # unpack data + e = _getencoder(self.mode, encoder_name, encoder_args) + e.setimage(self.im) + + bufsize = max(65536, self.size[0] * 4) # see RawEncode.c + + output = [] + while True: + bytes_consumed, errcode, data = e.encode(bufsize) + output.append(data) + if errcode: + break + if errcode < 0: + msg = f"encoder error {errcode} in tobytes" + raise RuntimeError(msg) + + return b"".join(output) + + def tobitmap(self, name: str = "image") -> bytes: + """ + Returns the image converted to an X11 bitmap. + + .. note:: This method only works for mode "1" images. + + :param name: The name prefix to use for the bitmap variables. + :returns: A string containing an X11 bitmap. + :raises ValueError: If the mode is not "1" + """ + + self.load() + if self.mode != "1": + msg = "not a bitmap" + raise ValueError(msg) + data = self.tobytes("xbm") + return b"".join( + [ + f"#define {name}_width {self.size[0]}\n".encode("ascii"), + f"#define {name}_height {self.size[1]}\n".encode("ascii"), + f"static char {name}_bits[] = {{\n".encode("ascii"), + data, + b"};", + ] + ) + + def frombytes( + self, + data: bytes | bytearray | SupportsArrayInterface, + decoder_name: str = "raw", + *args: Any, + ) -> None: + """ + Loads this image with pixel data from a bytes object. + + This method is similar to the :py:func:`~PIL.Image.frombytes` function, + but loads data into this image instead of creating a new image object. + """ + + if self.width == 0 or self.height == 0: + return + + decoder_args: Any = args + if len(decoder_args) == 1 and isinstance(decoder_args[0], tuple): + # may pass tuple instead of argument list + decoder_args = decoder_args[0] + + # default format + if decoder_name == "raw" and decoder_args == (): + decoder_args = self.mode + + # unpack data + d = _getdecoder(self.mode, decoder_name, decoder_args) + d.setimage(self.im) + s = d.decode(data) + + if s[0] >= 0: + msg = "not enough image data" + raise ValueError(msg) + if s[1] != 0: + msg = "cannot decode image data" + raise ValueError(msg) + + def load(self) -> core.PixelAccess | None: + """ + Allocates storage for the image and loads the pixel data. In + normal cases, you don't need to call this method, since the + Image class automatically loads an opened image when it is + accessed for the first time. + + If the file associated with the image was opened by Pillow, then this + method will close it. The exception to this is if the image has + multiple frames, in which case the file will be left open for seek + operations. See :ref:`file-handling` for more information. + + :returns: An image access object. + :rtype: :py:class:`.PixelAccess` + """ + if self._im is not None and self.palette and self.palette.dirty: + # realize palette + mode, arr = self.palette.getdata() + self.im.putpalette(self.palette.mode, mode, arr) + self.palette.dirty = 0 + self.palette.rawmode = None + if "transparency" in self.info and mode in ("LA", "PA"): + if isinstance(self.info["transparency"], int): + self.im.putpalettealpha(self.info["transparency"], 0) + else: + self.im.putpalettealphas(self.info["transparency"]) + self.palette.mode = "RGBA" + else: + self.palette.palette = self.im.getpalette( + self.palette.mode, self.palette.mode + ) + + if self._im is not None: + return self.im.pixel_access(self.readonly) + return None + + def verify(self) -> None: + """ + Verifies the contents of a file. For data read from a file, this + method attempts to determine if the file is broken, without + actually decoding the image data. If this method finds any + problems, it raises suitable exceptions. If you need to load + the image after using this method, you must reopen the image + file. + """ + pass + + def convert( + self, + mode: str | None = None, + matrix: tuple[float, ...] | None = None, + dither: Dither | None = None, + palette: Palette = Palette.WEB, + colors: int = 256, + ) -> Image: + """ + Returns a converted copy of this image. For the "P" mode, this + method translates pixels through the palette. If mode is + omitted, a mode is chosen so that all information in the image + and the palette can be represented without a palette. + + This supports all possible conversions between "L", "RGB" and "CMYK". The + ``matrix`` argument only supports "L" and "RGB". + + When translating a color image to grayscale (mode "L"), + the library uses the ITU-R 601-2 luma transform:: + + L = R * 299/1000 + G * 587/1000 + B * 114/1000 + + The default method of converting a grayscale ("L") or "RGB" + image into a bilevel (mode "1") image uses Floyd-Steinberg + dither to approximate the original image luminosity levels. If + dither is ``None``, all values larger than 127 are set to 255 (white), + all other values to 0 (black). To use other thresholds, use the + :py:meth:`~PIL.Image.Image.point` method. + + When converting from "RGBA" to "P" without a ``matrix`` argument, + this passes the operation to :py:meth:`~PIL.Image.Image.quantize`, + and ``dither`` and ``palette`` are ignored. + + When converting from "PA", if an "RGBA" palette is present, the alpha + channel from the image will be used instead of the values from the palette. + + :param mode: The requested mode. See: :ref:`concept-modes`. + :param matrix: An optional conversion matrix. If given, this + should be 4- or 12-tuple containing floating point values. + :param dither: Dithering method, used when converting from + mode "RGB" to "P" or from "RGB" or "L" to "1". + Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` + (default). Note that this is not used when ``matrix`` is supplied. + :param palette: Palette to use when converting from mode "RGB" + to "P". Available palettes are :data:`Palette.WEB` or + :data:`Palette.ADAPTIVE`. + :param colors: Number of colors to use for the :data:`Palette.ADAPTIVE` + palette. Defaults to 256. + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if mode in ("BGR;15", "BGR;16", "BGR;24"): + deprecate(mode, 12) + + self.load() + + has_transparency = "transparency" in self.info + if not mode and self.mode == "P": + # determine default mode + if self.palette: + mode = self.palette.mode + else: + mode = "RGB" + if mode == "RGB" and has_transparency: + mode = "RGBA" + if not mode or (mode == self.mode and not matrix): + return self.copy() + + if matrix: + # matrix conversion + if mode not in ("L", "RGB"): + msg = "illegal conversion" + raise ValueError(msg) + im = self.im.convert_matrix(mode, matrix) + new_im = self._new(im) + if has_transparency and self.im.bands == 3: + transparency = new_im.info["transparency"] + + def convert_transparency( + m: tuple[float, ...], v: tuple[int, int, int] + ) -> int: + value = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3] * 0.5 + return max(0, min(255, int(value))) + + if mode == "L": + transparency = convert_transparency(matrix, transparency) + elif len(mode) == 3: + transparency = tuple( + convert_transparency(matrix[i * 4 : i * 4 + 4], transparency) + for i in range(0, len(transparency)) + ) + new_im.info["transparency"] = transparency + return new_im + + if mode == "P" and self.mode == "RGBA": + return self.quantize(colors) + + trns = None + delete_trns = False + # transparency handling + if has_transparency: + if (self.mode in ("1", "L", "I", "I;16") and mode in ("LA", "RGBA")) or ( + self.mode == "RGB" and mode in ("La", "LA", "RGBa", "RGBA") + ): + # Use transparent conversion to promote from transparent + # color to an alpha channel. + new_im = self._new( + self.im.convert_transparent(mode, self.info["transparency"]) + ) + del new_im.info["transparency"] + return new_im + elif self.mode in ("L", "RGB", "P") and mode in ("L", "RGB", "P"): + t = self.info["transparency"] + if isinstance(t, bytes): + # Dragons. This can't be represented by a single color + warnings.warn( + "Palette images with Transparency expressed in bytes should be " + "converted to RGBA images" + ) + delete_trns = True + else: + # get the new transparency color. + # use existing conversions + trns_im = new(self.mode, (1, 1)) + if self.mode == "P": + assert self.palette is not None + trns_im.putpalette(self.palette, self.palette.mode) + if isinstance(t, tuple): + err = "Couldn't allocate a palette color for transparency" + assert trns_im.palette is not None + try: + t = trns_im.palette.getcolor(t, self) + except ValueError as e: + if str(e) == "cannot allocate more than 256 colors": + # If all 256 colors are in use, + # then there is no need for transparency + t = None + else: + raise ValueError(err) from e + if t is None: + trns = None + else: + trns_im.putpixel((0, 0), t) + + if mode in ("L", "RGB"): + trns_im = trns_im.convert(mode) + else: + # can't just retrieve the palette number, got to do it + # after quantization. + trns_im = trns_im.convert("RGB") + trns = trns_im.getpixel((0, 0)) + + elif self.mode == "P" and mode in ("LA", "PA", "RGBA"): + t = self.info["transparency"] + delete_trns = True + + if isinstance(t, bytes): + self.im.putpalettealphas(t) + elif isinstance(t, int): + self.im.putpalettealpha(t, 0) + else: + msg = "Transparency for P mode should be bytes or int" + raise ValueError(msg) + + if mode == "P" and palette == Palette.ADAPTIVE: + im = self.im.quantize(colors) + new_im = self._new(im) + from . import ImagePalette + + new_im.palette = ImagePalette.ImagePalette( + "RGB", new_im.im.getpalette("RGB") + ) + if delete_trns: + # This could possibly happen if we requantize to fewer colors. + # The transparency would be totally off in that case. + del new_im.info["transparency"] + if trns is not None: + try: + new_im.info["transparency"] = new_im.palette.getcolor( + cast(tuple[int, ...], trns), # trns was converted to RGB + new_im, + ) + except Exception: + # if we can't make a transparent color, don't leave the old + # transparency hanging around to mess us up. + del new_im.info["transparency"] + warnings.warn("Couldn't allocate palette entry for transparency") + return new_im + + if "LAB" in (self.mode, mode): + im = self + if mode == "LAB": + if im.mode not in ("RGB", "RGBA", "RGBX"): + im = im.convert("RGBA") + other_mode = im.mode + else: + other_mode = mode + if other_mode in ("RGB", "RGBA", "RGBX"): + from . import ImageCms + + srgb = ImageCms.createProfile("sRGB") + lab = ImageCms.createProfile("LAB") + profiles = [lab, srgb] if im.mode == "LAB" else [srgb, lab] + transform = ImageCms.buildTransform( + profiles[0], profiles[1], im.mode, mode + ) + return transform.apply(im) + + # colorspace conversion + if dither is None: + dither = Dither.FLOYDSTEINBERG + + try: + im = self.im.convert(mode, dither) + except ValueError: + try: + # normalize source image and try again + modebase = getmodebase(self.mode) + if modebase == self.mode: + raise + im = self.im.convert(modebase) + im = im.convert(mode, dither) + except KeyError as e: + msg = "illegal conversion" + raise ValueError(msg) from e + + new_im = self._new(im) + if mode == "P" and palette != Palette.ADAPTIVE: + from . import ImagePalette + + new_im.palette = ImagePalette.ImagePalette("RGB", im.getpalette("RGB")) + if delete_trns: + # crash fail if we leave a bytes transparency in an rgb/l mode. + del new_im.info["transparency"] + if trns is not None: + if new_im.mode == "P" and new_im.palette: + try: + new_im.info["transparency"] = new_im.palette.getcolor( + cast(tuple[int, ...], trns), new_im # trns was converted to RGB + ) + except ValueError as e: + del new_im.info["transparency"] + if str(e) != "cannot allocate more than 256 colors": + # If all 256 colors are in use, + # then there is no need for transparency + warnings.warn( + "Couldn't allocate palette entry for transparency" + ) + else: + new_im.info["transparency"] = trns + return new_im + + def quantize( + self, + colors: int = 256, + method: int | None = None, + kmeans: int = 0, + palette: Image | None = None, + dither: Dither = Dither.FLOYDSTEINBERG, + ) -> Image: + """ + Convert the image to 'P' mode with the specified number + of colors. + + :param colors: The desired number of colors, <= 256 + :param method: :data:`Quantize.MEDIANCUT` (median cut), + :data:`Quantize.MAXCOVERAGE` (maximum coverage), + :data:`Quantize.FASTOCTREE` (fast octree), + :data:`Quantize.LIBIMAGEQUANT` (libimagequant; check support + using :py:func:`PIL.features.check_feature` with + ``feature="libimagequant"``). + + By default, :data:`Quantize.MEDIANCUT` will be used. + + The exception to this is RGBA images. :data:`Quantize.MEDIANCUT` + and :data:`Quantize.MAXCOVERAGE` do not support RGBA images, so + :data:`Quantize.FASTOCTREE` is used by default instead. + :param kmeans: Integer greater than or equal to zero. + :param palette: Quantize to the palette of given + :py:class:`PIL.Image.Image`. + :param dither: Dithering method, used when converting from + mode "RGB" to "P" or from "RGB" or "L" to "1". + Available methods are :data:`Dither.NONE` or :data:`Dither.FLOYDSTEINBERG` + (default). + :returns: A new image + """ + + self.load() + + if method is None: + # defaults: + method = Quantize.MEDIANCUT + if self.mode == "RGBA": + method = Quantize.FASTOCTREE + + if self.mode == "RGBA" and method not in ( + Quantize.FASTOCTREE, + Quantize.LIBIMAGEQUANT, + ): + # Caller specified an invalid mode. + msg = ( + "Fast Octree (method == 2) and libimagequant (method == 3) " + "are the only valid methods for quantizing RGBA images" + ) + raise ValueError(msg) + + if palette: + # use palette from reference image + palette.load() + if palette.mode != "P": + msg = "bad mode for palette image" + raise ValueError(msg) + if self.mode not in {"RGB", "L"}: + msg = "only RGB or L mode images can be quantized to a palette" + raise ValueError(msg) + im = self.im.convert("P", dither, palette.im) + new_im = self._new(im) + assert palette.palette is not None + new_im.palette = palette.palette.copy() + return new_im + + if kmeans < 0: + msg = "kmeans must not be negative" + raise ValueError(msg) + + im = self._new(self.im.quantize(colors, method, kmeans)) + + from . import ImagePalette + + mode = im.im.getpalettemode() + palette_data = im.im.getpalette(mode, mode)[: colors * len(mode)] + im.palette = ImagePalette.ImagePalette(mode, palette_data) + + return im + + def copy(self) -> Image: + """ + Copies this image. Use this method if you wish to paste things + into an image, but still retain the original. + + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + self.load() + return self._new(self.im.copy()) + + __copy__ = copy + + def crop(self, box: tuple[float, float, float, float] | None = None) -> Image: + """ + Returns a rectangular region from this image. The box is a + 4-tuple defining the left, upper, right, and lower pixel + coordinate. See :ref:`coordinate-system`. + + Note: Prior to Pillow 3.4.0, this was a lazy operation. + + :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. + :rtype: :py:class:`~PIL.Image.Image` + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if box is None: + return self.copy() + + if box[2] < box[0]: + msg = "Coordinate 'right' is less than 'left'" + raise ValueError(msg) + elif box[3] < box[1]: + msg = "Coordinate 'lower' is less than 'upper'" + raise ValueError(msg) + + self.load() + return self._new(self._crop(self.im, box)) + + def _crop( + self, im: core.ImagingCore, box: tuple[float, float, float, float] + ) -> core.ImagingCore: + """ + Returns a rectangular region from the core image object im. + + This is equivalent to calling im.crop((x0, y0, x1, y1)), but + includes additional sanity checks. + + :param im: a core image object + :param box: The crop rectangle, as a (left, upper, right, lower)-tuple. + :returns: A core image object. + """ + + x0, y0, x1, y1 = map(int, map(round, box)) + + absolute_values = (abs(x1 - x0), abs(y1 - y0)) + + _decompression_bomb_check(absolute_values) + + return im.crop((x0, y0, x1, y1)) + + def draft( + self, mode: str | None, size: tuple[int, int] | None + ) -> tuple[str, tuple[int, int, float, float]] | None: + """ + Configures the image file loader so it returns a version of the + image that as closely as possible matches the given mode and + size. For example, you can use this method to convert a color + JPEG to grayscale while loading it. + + If any changes are made, returns a tuple with the chosen ``mode`` and + ``box`` with coordinates of the original image within the altered one. + + Note that this method modifies the :py:class:`~PIL.Image.Image` object + in place. If the image has already been loaded, this method has no + effect. + + Note: This method is not implemented for most images. It is + currently implemented only for JPEG and MPO images. + + :param mode: The requested mode. + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + """ + pass + + def _expand(self, xmargin: int, ymargin: int | None = None) -> Image: + if ymargin is None: + ymargin = xmargin + self.load() + return self._new(self.im.expand(xmargin, ymargin)) + + def filter(self, filter: ImageFilter.Filter | type[ImageFilter.Filter]) -> Image: + """ + Filters this image using the given filter. For a list of + available filters, see the :py:mod:`~PIL.ImageFilter` module. + + :param filter: Filter kernel. + :returns: An :py:class:`~PIL.Image.Image` object.""" + + from . import ImageFilter + + self.load() + + if callable(filter): + filter = filter() + if not hasattr(filter, "filter"): + msg = "filter argument should be ImageFilter.Filter instance or class" + raise TypeError(msg) + + multiband = isinstance(filter, ImageFilter.MultibandFilter) + if self.im.bands == 1 or multiband: + return self._new(filter.filter(self.im)) + + ims = [ + self._new(filter.filter(self.im.getband(c))) for c in range(self.im.bands) + ] + return merge(self.mode, ims) + + def getbands(self) -> tuple[str, ...]: + """ + Returns a tuple containing the name of each band in this image. + For example, ``getbands`` on an RGB image returns ("R", "G", "B"). + + :returns: A tuple containing band names. + :rtype: tuple + """ + return ImageMode.getmode(self.mode).bands + + def getbbox(self, *, alpha_only: bool = True) -> tuple[int, int, int, int] | None: + """ + Calculates the bounding box of the non-zero regions in the + image. + + :param alpha_only: Optional flag, defaulting to ``True``. + If ``True`` and the image has an alpha channel, trim transparent pixels. + Otherwise, trim pixels when all channels are zero. + Keyword-only argument. + :returns: The bounding box is returned as a 4-tuple defining the + left, upper, right, and lower pixel coordinate. See + :ref:`coordinate-system`. If the image is completely empty, this + method returns None. + + """ + + self.load() + return self.im.getbbox(alpha_only) + + def getcolors( + self, maxcolors: int = 256 + ) -> list[tuple[int, tuple[int, ...]]] | list[tuple[int, float]] | None: + """ + Returns a list of colors used in this image. + + The colors will be in the image's mode. For example, an RGB image will + return a tuple of (red, green, blue) color values, and a P image will + return the index of the color in the palette. + + :param maxcolors: Maximum number of colors. If this number is + exceeded, this method returns None. The default limit is + 256 colors. + :returns: An unsorted list of (count, pixel) values. + """ + + self.load() + if self.mode in ("1", "L", "P"): + h = self.im.histogram() + out: list[tuple[int, float]] = [(h[i], i) for i in range(256) if h[i]] + if len(out) > maxcolors: + return None + return out + return self.im.getcolors(maxcolors) + + def getdata(self, band: int | None = None) -> core.ImagingCore: + """ + Returns the contents of this image as a sequence object + containing pixel values. The sequence object is flattened, so + that values for line one follow directly after the values of + line zero, and so on. + + Note that the sequence object returned by this method is an + internal PIL data type, which only supports certain sequence + operations. To convert it to an ordinary sequence (e.g. for + printing), use ``list(im.getdata())``. + + :param band: What band to return. The default is to return + all bands. To return a single band, pass in the index + value (e.g. 0 to get the "R" band from an "RGB" image). + :returns: A sequence-like object. + """ + + self.load() + if band is not None: + return self.im.getband(band) + return self.im # could be abused + + def getextrema(self) -> tuple[float, float] | tuple[tuple[int, int], ...]: + """ + Gets the minimum and maximum pixel values for each band in + the image. + + :returns: For a single-band image, a 2-tuple containing the + minimum and maximum pixel value. For a multi-band image, + a tuple containing one 2-tuple for each band. + """ + + self.load() + if self.im.bands > 1: + return tuple(self.im.getband(i).getextrema() for i in range(self.im.bands)) + return self.im.getextrema() + + def getxmp(self) -> dict[str, Any]: + """ + Returns a dictionary containing the XMP tags. + Requires defusedxml to be installed. + + :returns: XMP tags in a dictionary. + """ + + def get_name(tag: str) -> str: + return re.sub("^{[^}]+}", "", tag) + + def get_value(element: Element) -> str | dict[str, Any] | None: + value: dict[str, Any] = {get_name(k): v for k, v in element.attrib.items()} + children = list(element) + if children: + for child in children: + name = get_name(child.tag) + child_value = get_value(child) + if name in value: + if not isinstance(value[name], list): + value[name] = [value[name]] + value[name].append(child_value) + else: + value[name] = child_value + elif value: + if element.text: + value["text"] = element.text + else: + return element.text + return value + + if ElementTree is None: + warnings.warn("XMP data cannot be read without defusedxml dependency") + return {} + if "xmp" not in self.info: + return {} + root = ElementTree.fromstring(self.info["xmp"].rstrip(b"\x00")) + return {get_name(root.tag): get_value(root)} + + def getexif(self) -> Exif: + """ + Gets EXIF data from the image. + + :returns: an :py:class:`~PIL.Image.Exif` object. + """ + if self._exif is None: + self._exif = Exif() + elif self._exif._loaded: + return self._exif + self._exif._loaded = True + + exif_info = self.info.get("exif") + if exif_info is None: + if "Raw profile type exif" in self.info: + exif_info = bytes.fromhex( + "".join(self.info["Raw profile type exif"].split("\n")[3:]) + ) + elif hasattr(self, "tag_v2"): + self._exif.bigtiff = self.tag_v2._bigtiff + self._exif.endian = self.tag_v2._endian + self._exif.load_from_fp(self.fp, self.tag_v2._offset) + if exif_info is not None: + self._exif.load(exif_info) + + # XMP tags + if ExifTags.Base.Orientation not in self._exif: + xmp_tags = self.info.get("XML:com.adobe.xmp") + if xmp_tags: + match = re.search(r'tiff:Orientation(="|>)([0-9])', xmp_tags) + if match: + self._exif[ExifTags.Base.Orientation] = int(match[2]) + + return self._exif + + def _reload_exif(self) -> None: + if self._exif is None or not self._exif._loaded: + return + self._exif._loaded = False + self.getexif() + + def get_child_images(self) -> list[ImageFile.ImageFile]: + child_images = [] + exif = self.getexif() + ifds = [] + if ExifTags.Base.SubIFDs in exif: + subifd_offsets = exif[ExifTags.Base.SubIFDs] + if subifd_offsets: + if not isinstance(subifd_offsets, tuple): + subifd_offsets = (subifd_offsets,) + for subifd_offset in subifd_offsets: + ifds.append((exif._get_ifd_dict(subifd_offset), subifd_offset)) + ifd1 = exif.get_ifd(ExifTags.IFD.IFD1) + if ifd1 and ifd1.get(513): + assert exif._info is not None + ifds.append((ifd1, exif._info.next)) + + offset = None + for ifd, ifd_offset in ifds: + current_offset = self.fp.tell() + if offset is None: + offset = current_offset + + fp = self.fp + if ifd is not None: + thumbnail_offset = ifd.get(513) + if thumbnail_offset is not None: + thumbnail_offset += getattr(self, "_exif_offset", 0) + self.fp.seek(thumbnail_offset) + data = self.fp.read(ifd.get(514)) + fp = io.BytesIO(data) + + with open(fp) as im: + from . import TiffImagePlugin + + if thumbnail_offset is None and isinstance( + im, TiffImagePlugin.TiffImageFile + ): + im._frame_pos = [ifd_offset] + im._seek(0) + im.load() + child_images.append(im) + + if offset is not None: + self.fp.seek(offset) + return child_images + + def getim(self) -> CapsuleType: + """ + Returns a capsule that points to the internal image memory. + + :returns: A capsule object. + """ + + self.load() + return self.im.ptr + + def getpalette(self, rawmode: str | None = "RGB") -> list[int] | None: + """ + Returns the image palette as a list. + + :param rawmode: The mode in which to return the palette. ``None`` will + return the palette in its current mode. + + .. versionadded:: 9.1.0 + + :returns: A list of color values [r, g, b, ...], or None if the + image has no palette. + """ + + self.load() + try: + mode = self.im.getpalettemode() + except ValueError: + return None # no palette + if rawmode is None: + rawmode = mode + return list(self.im.getpalette(mode, rawmode)) + + @property + def has_transparency_data(self) -> bool: + """ + Determine if an image has transparency data, whether in the form of an + alpha channel, a palette with an alpha channel, or a "transparency" key + in the info dictionary. + + Note the image might still appear solid, if all of the values shown + within are opaque. + + :returns: A boolean. + """ + if ( + self.mode in ("LA", "La", "PA", "RGBA", "RGBa") + or "transparency" in self.info + ): + return True + if self.mode == "P": + assert self.palette is not None + return self.palette.mode.endswith("A") + return False + + def apply_transparency(self) -> None: + """ + If a P mode image has a "transparency" key in the info dictionary, + remove the key and instead apply the transparency to the palette. + Otherwise, the image is unchanged. + """ + if self.mode != "P" or "transparency" not in self.info: + return + + from . import ImagePalette + + palette = self.getpalette("RGBA") + assert palette is not None + transparency = self.info["transparency"] + if isinstance(transparency, bytes): + for i, alpha in enumerate(transparency): + palette[i * 4 + 3] = alpha + else: + palette[transparency * 4 + 3] = 0 + self.palette = ImagePalette.ImagePalette("RGBA", bytes(palette)) + self.palette.dirty = 1 + + del self.info["transparency"] + + def getpixel( + self, xy: tuple[int, int] | list[int] + ) -> float | tuple[int, ...] | None: + """ + Returns the pixel value at a given position. + + :param xy: The coordinate, given as (x, y). See + :ref:`coordinate-system`. + :returns: The pixel value. If the image is a multi-layer image, + this method returns a tuple. + """ + + self.load() + return self.im.getpixel(tuple(xy)) + + def getprojection(self) -> tuple[list[int], list[int]]: + """ + Get projection to x and y axes + + :returns: Two sequences, indicating where there are non-zero + pixels along the X-axis and the Y-axis, respectively. + """ + + self.load() + x, y = self.im.getprojection() + return list(x), list(y) + + def histogram( + self, mask: Image | None = None, extrema: tuple[float, float] | None = None + ) -> list[int]: + """ + Returns a histogram for the image. The histogram is returned as a + list of pixel counts, one for each pixel value in the source + image. Counts are grouped into 256 bins for each band, even if + the image has more than 8 bits per band. If the image has more + than one band, the histograms for all bands are concatenated (for + example, the histogram for an "RGB" image contains 768 values). + + A bilevel image (mode "1") is treated as a grayscale ("L") image + by this method. + + If a mask is provided, the method returns a histogram for those + parts of the image where the mask image is non-zero. The mask + image must have the same size as the image, and be either a + bi-level image (mode "1") or a grayscale image ("L"). + + :param mask: An optional mask. + :param extrema: An optional tuple of manually-specified extrema. + :returns: A list containing pixel counts. + """ + self.load() + if mask: + mask.load() + return self.im.histogram((0, 0), mask.im) + if self.mode in ("I", "F"): + return self.im.histogram( + extrema if extrema is not None else self.getextrema() + ) + return self.im.histogram() + + def entropy( + self, mask: Image | None = None, extrema: tuple[float, float] | None = None + ) -> float: + """ + Calculates and returns the entropy for the image. + + A bilevel image (mode "1") is treated as a grayscale ("L") + image by this method. + + If a mask is provided, the method employs the histogram for + those parts of the image where the mask image is non-zero. + The mask image must have the same size as the image, and be + either a bi-level image (mode "1") or a grayscale image ("L"). + + :param mask: An optional mask. + :param extrema: An optional tuple of manually-specified extrema. + :returns: A float value representing the image entropy + """ + self.load() + if mask: + mask.load() + return self.im.entropy((0, 0), mask.im) + if self.mode in ("I", "F"): + return self.im.entropy( + extrema if extrema is not None else self.getextrema() + ) + return self.im.entropy() + + def paste( + self, + im: Image | str | float | tuple[float, ...], + box: Image | tuple[int, int, int, int] | tuple[int, int] | None = None, + mask: Image | None = None, + ) -> None: + """ + Pastes another image into this image. The box argument is either + a 2-tuple giving the upper left corner, a 4-tuple defining the + left, upper, right, and lower pixel coordinate, or None (same as + (0, 0)). See :ref:`coordinate-system`. If a 4-tuple is given, the size + of the pasted image must match the size of the region. + + If the modes don't match, the pasted image is converted to the mode of + this image (see the :py:meth:`~PIL.Image.Image.convert` method for + details). + + Instead of an image, the source can be a integer or tuple + containing pixel values. The method then fills the region + with the given color. When creating RGB images, you can + also use color strings as supported by the ImageColor module. + + If a mask is given, this method updates only the regions + indicated by the mask. You can use either "1", "L", "LA", "RGBA" + or "RGBa" images (if present, the alpha band is used as mask). + Where the mask is 255, the given image is copied as is. Where + the mask is 0, the current value is preserved. Intermediate + values will mix the two images together, including their alpha + channels if they have them. + + See :py:meth:`~PIL.Image.Image.alpha_composite` if you want to + combine images with respect to their alpha channels. + + :param im: Source image or pixel value (integer, float or tuple). + :param box: An optional 4-tuple giving the region to paste into. + If a 2-tuple is used instead, it's treated as the upper left + corner. If omitted or None, the source is pasted into the + upper left corner. + + If an image is given as the second argument and there is no + third, the box defaults to (0, 0), and the second argument + is interpreted as a mask image. + :param mask: An optional mask image. + """ + + if isinstance(box, Image): + if mask is not None: + msg = "If using second argument as mask, third argument must be None" + raise ValueError(msg) + # abbreviated paste(im, mask) syntax + mask = box + box = None + + if box is None: + box = (0, 0) + + if len(box) == 2: + # upper left corner given; get size from image or mask + if isinstance(im, Image): + size = im.size + elif isinstance(mask, Image): + size = mask.size + else: + # FIXME: use self.size here? + msg = "cannot determine region size; use 4-item box" + raise ValueError(msg) + box += (box[0] + size[0], box[1] + size[1]) + + source: core.ImagingCore | str | float | tuple[float, ...] + if isinstance(im, str): + from . import ImageColor + + source = ImageColor.getcolor(im, self.mode) + elif isinstance(im, Image): + im.load() + if self.mode != im.mode: + if self.mode != "RGB" or im.mode not in ("LA", "RGBA", "RGBa"): + # should use an adapter for this! + im = im.convert(self.mode) + source = im.im + else: + source = im + + self._ensure_mutable() + + if mask: + mask.load() + self.im.paste(source, box, mask.im) + else: + self.im.paste(source, box) + + def alpha_composite( + self, im: Image, dest: Sequence[int] = (0, 0), source: Sequence[int] = (0, 0) + ) -> None: + """'In-place' analog of Image.alpha_composite. Composites an image + onto this image. + + :param im: image to composite over this one + :param dest: Optional 2 tuple (left, top) specifying the upper + left corner in this (destination) image. + :param source: Optional 2 (left, top) tuple for the upper left + corner in the overlay source image, or 4 tuple (left, top, right, + bottom) for the bounds of the source rectangle + + Performance Note: Not currently implemented in-place in the core layer. + """ + + if not isinstance(source, (list, tuple)): + msg = "Source must be a list or tuple" + raise ValueError(msg) + if not isinstance(dest, (list, tuple)): + msg = "Destination must be a list or tuple" + raise ValueError(msg) + + if len(source) == 4: + overlay_crop_box = tuple(source) + elif len(source) == 2: + overlay_crop_box = tuple(source) + im.size + else: + msg = "Source must be a sequence of length 2 or 4" + raise ValueError(msg) + + if not len(dest) == 2: + msg = "Destination must be a sequence of length 2" + raise ValueError(msg) + if min(source) < 0: + msg = "Source must be non-negative" + raise ValueError(msg) + + # over image, crop if it's not the whole image. + if overlay_crop_box == (0, 0) + im.size: + overlay = im + else: + overlay = im.crop(overlay_crop_box) + + # target for the paste + box = tuple(dest) + (dest[0] + overlay.width, dest[1] + overlay.height) + + # destination image. don't copy if we're using the whole image. + if box == (0, 0) + self.size: + background = self + else: + background = self.crop(box) + + result = alpha_composite(background, overlay) + self.paste(result, box) + + def point( + self, + lut: ( + Sequence[float] + | NumpyArray + | Callable[[int], float] + | Callable[[ImagePointTransform], ImagePointTransform | float] + | ImagePointHandler + ), + mode: str | None = None, + ) -> Image: + """ + Maps this image through a lookup table or function. + + :param lut: A lookup table, containing 256 (or 65536 if + self.mode=="I" and mode == "L") values per band in the + image. A function can be used instead, it should take a + single argument. The function is called once for each + possible pixel value, and the resulting table is applied to + all bands of the image. + + It may also be an :py:class:`~PIL.Image.ImagePointHandler` + object:: + + class Example(Image.ImagePointHandler): + def point(self, im: Image) -> Image: + # Return result + :param mode: Output mode (default is same as input). This can only be used if + the source image has mode "L" or "P", and the output has mode "1" or the + source image mode is "I" and the output mode is "L". + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + self.load() + + if isinstance(lut, ImagePointHandler): + return lut.point(self) + + if callable(lut): + # if it isn't a list, it should be a function + if self.mode in ("I", "I;16", "F"): + # check if the function can be used with point_transform + # UNDONE wiredfool -- I think this prevents us from ever doing + # a gamma function point transform on > 8bit images. + scale, offset = _getscaleoffset(lut) # type: ignore[arg-type] + return self._new(self.im.point_transform(scale, offset)) + # for other modes, convert the function to a table + flatLut = [lut(i) for i in range(256)] * self.im.bands # type: ignore[arg-type] + else: + flatLut = lut + + if self.mode == "F": + # FIXME: _imaging returns a confusing error message for this case + msg = "point operation not supported for this mode" + raise ValueError(msg) + + if mode != "F": + flatLut = [round(i) for i in flatLut] + return self._new(self.im.point(flatLut, mode)) + + def putalpha(self, alpha: Image | int) -> None: + """ + Adds or replaces the alpha layer in this image. If the image + does not have an alpha layer, it's converted to "LA" or "RGBA". + The new layer must be either "L" or "1". + + :param alpha: The new alpha layer. This can either be an "L" or "1" + image having the same size as this image, or an integer. + """ + + self._ensure_mutable() + + if self.mode not in ("LA", "PA", "RGBA"): + # attempt to promote self to a matching alpha mode + try: + mode = getmodebase(self.mode) + "A" + try: + self.im.setmode(mode) + except (AttributeError, ValueError) as e: + # do things the hard way + im = self.im.convert(mode) + if im.mode not in ("LA", "PA", "RGBA"): + msg = "alpha channel could not be added" + raise ValueError(msg) from e # sanity check + self.im = im + self._mode = self.im.mode + except KeyError as e: + msg = "illegal image mode" + raise ValueError(msg) from e + + if self.mode in ("LA", "PA"): + band = 1 + else: + band = 3 + + if isinstance(alpha, Image): + # alpha layer + if alpha.mode not in ("1", "L"): + msg = "illegal image mode" + raise ValueError(msg) + alpha.load() + if alpha.mode == "1": + alpha = alpha.convert("L") + else: + # constant alpha + try: + self.im.fillband(band, alpha) + except (AttributeError, ValueError): + # do things the hard way + alpha = new("L", self.size, alpha) + else: + return + + self.im.putband(alpha.im, band) + + def putdata( + self, + data: Sequence[float] | Sequence[Sequence[int]] | core.ImagingCore | NumpyArray, + scale: float = 1.0, + offset: float = 0.0, + ) -> None: + """ + Copies pixel data from a flattened sequence object into the image. The + values should start at the upper left corner (0, 0), continue to the + end of the line, followed directly by the first value of the second + line, and so on. Data will be read until either the image or the + sequence ends. The scale and offset values are used to adjust the + sequence values: **pixel = value*scale + offset**. + + :param data: A flattened sequence object. + :param scale: An optional scale value. The default is 1.0. + :param offset: An optional offset value. The default is 0.0. + """ + + self._ensure_mutable() + + self.im.putdata(data, scale, offset) + + def putpalette( + self, + data: ImagePalette.ImagePalette | bytes | Sequence[int], + rawmode: str = "RGB", + ) -> None: + """ + Attaches a palette to this image. The image must be a "P", "PA", "L" + or "LA" image. + + The palette sequence must contain at most 256 colors, made up of one + integer value for each channel in the raw mode. + For example, if the raw mode is "RGB", then it can contain at most 768 + values, made up of red, green and blue values for the corresponding pixel + index in the 256 colors. + If the raw mode is "RGBA", then it can contain at most 1024 values, + containing red, green, blue and alpha values. + + Alternatively, an 8-bit string may be used instead of an integer sequence. + + :param data: A palette sequence (either a list or a string). + :param rawmode: The raw mode of the palette. Either "RGB", "RGBA", or a mode + that can be transformed to "RGB" or "RGBA" (e.g. "R", "BGR;15", "RGBA;L"). + """ + from . import ImagePalette + + if self.mode not in ("L", "LA", "P", "PA"): + msg = "illegal image mode" + raise ValueError(msg) + if isinstance(data, ImagePalette.ImagePalette): + if data.rawmode is not None: + palette = ImagePalette.raw(data.rawmode, data.palette) + else: + palette = ImagePalette.ImagePalette(palette=data.palette) + palette.dirty = 1 + else: + if not isinstance(data, bytes): + data = bytes(data) + palette = ImagePalette.raw(rawmode, data) + self._mode = "PA" if "A" in self.mode else "P" + self.palette = palette + self.palette.mode = "RGBA" if "A" in rawmode else "RGB" + self.load() # install new palette + + def putpixel( + self, xy: tuple[int, int], value: float | tuple[int, ...] | list[int] + ) -> None: + """ + Modifies the pixel at the given position. The color is given as + a single numerical value for single-band images, and a tuple for + multi-band images. In addition to this, RGB and RGBA tuples are + accepted for P and PA images. + + Note that this method is relatively slow. For more extensive changes, + use :py:meth:`~PIL.Image.Image.paste` or the :py:mod:`~PIL.ImageDraw` + module instead. + + See: + + * :py:meth:`~PIL.Image.Image.paste` + * :py:meth:`~PIL.Image.Image.putdata` + * :py:mod:`~PIL.ImageDraw` + + :param xy: The pixel coordinate, given as (x, y). See + :ref:`coordinate-system`. + :param value: The pixel value. + """ + + if self.readonly: + self._copy() + self.load() + + if ( + self.mode in ("P", "PA") + and isinstance(value, (list, tuple)) + and len(value) in [3, 4] + ): + # RGB or RGBA value for a P or PA image + if self.mode == "PA": + alpha = value[3] if len(value) == 4 else 255 + value = value[:3] + assert self.palette is not None + palette_index = self.palette.getcolor(tuple(value), self) + value = (palette_index, alpha) if self.mode == "PA" else palette_index + return self.im.putpixel(xy, value) + + def remap_palette( + self, dest_map: list[int], source_palette: bytes | bytearray | None = None + ) -> Image: + """ + Rewrites the image to reorder the palette. + + :param dest_map: A list of indexes into the original palette. + e.g. ``[1,0]`` would swap a two item palette, and ``list(range(256))`` + is the identity transform. + :param source_palette: Bytes or None. + :returns: An :py:class:`~PIL.Image.Image` object. + + """ + from . import ImagePalette + + if self.mode not in ("L", "P"): + msg = "illegal image mode" + raise ValueError(msg) + + bands = 3 + palette_mode = "RGB" + if source_palette is None: + if self.mode == "P": + self.load() + palette_mode = self.im.getpalettemode() + if palette_mode == "RGBA": + bands = 4 + source_palette = self.im.getpalette(palette_mode, palette_mode) + else: # L-mode + source_palette = bytearray(i // 3 for i in range(768)) + elif len(source_palette) > 768: + bands = 4 + palette_mode = "RGBA" + + palette_bytes = b"" + new_positions = [0] * 256 + + # pick only the used colors from the palette + for i, oldPosition in enumerate(dest_map): + palette_bytes += source_palette[ + oldPosition * bands : oldPosition * bands + bands + ] + new_positions[oldPosition] = i + + # replace the palette color id of all pixel with the new id + + # Palette images are [0..255], mapped through a 1 or 3 + # byte/color map. We need to remap the whole image + # from palette 1 to palette 2. New_positions is + # an array of indexes into palette 1. Palette 2 is + # palette 1 with any holes removed. + + # We're going to leverage the convert mechanism to use the + # C code to remap the image from palette 1 to palette 2, + # by forcing the source image into 'L' mode and adding a + # mapping 'L' mode palette, then converting back to 'L' + # sans palette thus converting the image bytes, then + # assigning the optimized RGB palette. + + # perf reference, 9500x4000 gif, w/~135 colors + # 14 sec prepatch, 1 sec postpatch with optimization forced. + + mapping_palette = bytearray(new_positions) + + m_im = self.copy() + m_im._mode = "P" + + m_im.palette = ImagePalette.ImagePalette( + palette_mode, palette=mapping_palette * bands + ) + # possibly set palette dirty, then + # m_im.putpalette(mapping_palette, 'L') # converts to 'P' + # or just force it. + # UNDONE -- this is part of the general issue with palettes + m_im.im.putpalette(palette_mode, palette_mode + ";L", m_im.palette.tobytes()) + + m_im = m_im.convert("L") + + m_im.putpalette(palette_bytes, palette_mode) + m_im.palette = ImagePalette.ImagePalette(palette_mode, palette=palette_bytes) + + if "transparency" in self.info: + try: + m_im.info["transparency"] = dest_map.index(self.info["transparency"]) + except ValueError: + if "transparency" in m_im.info: + del m_im.info["transparency"] + + return m_im + + def _get_safe_box( + self, + size: tuple[int, int], + resample: Resampling, + box: tuple[float, float, float, float], + ) -> tuple[int, int, int, int]: + """Expands the box so it includes adjacent pixels + that may be used by resampling with the given resampling filter. + """ + filter_support = _filters_support[resample] - 0.5 + scale_x = (box[2] - box[0]) / size[0] + scale_y = (box[3] - box[1]) / size[1] + support_x = filter_support * scale_x + support_y = filter_support * scale_y + + return ( + max(0, int(box[0] - support_x)), + max(0, int(box[1] - support_y)), + min(self.size[0], math.ceil(box[2] + support_x)), + min(self.size[1], math.ceil(box[3] + support_y)), + ) + + def resize( + self, + size: tuple[int, int] | list[int] | NumpyArray, + resample: int | None = None, + box: tuple[float, float, float, float] | None = None, + reducing_gap: float | None = None, + ) -> Image: + """ + Returns a resized copy of this image. + + :param size: The requested size in pixels, as a tuple or array: + (width, height). + :param resample: An optional resampling filter. This can be + one of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, + :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, + :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. + If the image has mode "1" or "P", it is always set to + :py:data:`Resampling.NEAREST`. If the image mode is "BGR;15", + "BGR;16" or "BGR;24", then the default filter is + :py:data:`Resampling.NEAREST`. Otherwise, the default filter is + :py:data:`Resampling.BICUBIC`. See: :ref:`concept-filters`. + :param box: An optional 4-tuple of floats providing + the source image region to be scaled. + The values must be within (0, 0, width, height) rectangle. + If omitted or None, the entire source is used. + :param reducing_gap: Apply optimization by resizing the image + in two steps. First, reducing the image by integer times + using :py:meth:`~PIL.Image.Image.reduce`. + Second, resizing using regular resampling. The last step + changes size no less than by ``reducing_gap`` times. + ``reducing_gap`` may be None (no first step is performed) + or should be greater than 1.0. The bigger ``reducing_gap``, + the closer the result to the fair resampling. + The smaller ``reducing_gap``, the faster resizing. + With ``reducing_gap`` greater or equal to 3.0, the result is + indistinguishable from fair resampling in most cases. + The default value is None (no optimization). + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if resample is None: + bgr = self.mode.startswith("BGR;") + resample = Resampling.NEAREST if bgr else Resampling.BICUBIC + elif resample not in ( + Resampling.NEAREST, + Resampling.BILINEAR, + Resampling.BICUBIC, + Resampling.LANCZOS, + Resampling.BOX, + Resampling.HAMMING, + ): + msg = f"Unknown resampling filter ({resample})." + + filters = [ + f"{filter[1]} ({filter[0]})" + for filter in ( + (Resampling.NEAREST, "Image.Resampling.NEAREST"), + (Resampling.LANCZOS, "Image.Resampling.LANCZOS"), + (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), + (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), + (Resampling.BOX, "Image.Resampling.BOX"), + (Resampling.HAMMING, "Image.Resampling.HAMMING"), + ) + ] + msg += f" Use {', '.join(filters[:-1])} or {filters[-1]}" + raise ValueError(msg) + + if reducing_gap is not None and reducing_gap < 1.0: + msg = "reducing_gap must be 1.0 or greater" + raise ValueError(msg) + + if box is None: + box = (0, 0) + self.size + + size = tuple(size) + if self.size == size and box == (0, 0) + self.size: + return self.copy() + + if self.mode in ("1", "P"): + resample = Resampling.NEAREST + + if self.mode in ["LA", "RGBA"] and resample != Resampling.NEAREST: + im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + im = im.resize(size, resample, box) + return im.convert(self.mode) + + self.load() + + if reducing_gap is not None and resample != Resampling.NEAREST: + factor_x = int((box[2] - box[0]) / size[0] / reducing_gap) or 1 + factor_y = int((box[3] - box[1]) / size[1] / reducing_gap) or 1 + if factor_x > 1 or factor_y > 1: + reduce_box = self._get_safe_box(size, cast(Resampling, resample), box) + factor = (factor_x, factor_y) + self = ( + self.reduce(factor, box=reduce_box) + if callable(self.reduce) + else Image.reduce(self, factor, box=reduce_box) + ) + box = ( + (box[0] - reduce_box[0]) / factor_x, + (box[1] - reduce_box[1]) / factor_y, + (box[2] - reduce_box[0]) / factor_x, + (box[3] - reduce_box[1]) / factor_y, + ) + + return self._new(self.im.resize(size, resample, box)) + + def reduce( + self, + factor: int | tuple[int, int], + box: tuple[int, int, int, int] | None = None, + ) -> Image: + """ + Returns a copy of the image reduced ``factor`` times. + If the size of the image is not dividable by ``factor``, + the resulting size will be rounded up. + + :param factor: A greater than 0 integer or tuple of two integers + for width and height separately. + :param box: An optional 4-tuple of ints providing + the source image region to be reduced. + The values must be within ``(0, 0, width, height)`` rectangle. + If omitted or ``None``, the entire source is used. + """ + if not isinstance(factor, (list, tuple)): + factor = (factor, factor) + + if box is None: + box = (0, 0) + self.size + + if factor == (1, 1) and box == (0, 0) + self.size: + return self.copy() + + if self.mode in ["LA", "RGBA"]: + im = self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + im = im.reduce(factor, box) + return im.convert(self.mode) + + self.load() + + return self._new(self.im.reduce(factor, box)) + + def rotate( + self, + angle: float, + resample: Resampling = Resampling.NEAREST, + expand: int | bool = False, + center: tuple[float, float] | None = None, + translate: tuple[int, int] | None = None, + fillcolor: float | tuple[float, ...] | str | None = None, + ) -> Image: + """ + Returns a rotated copy of this image. This method returns a + copy of this image, rotated the given number of degrees counter + clockwise around its centre. + + :param angle: In degrees counter clockwise. + :param resample: An optional resampling filter. This can be + one of :py:data:`Resampling.NEAREST` (use nearest neighbour), + :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 + environment), or :py:data:`Resampling.BICUBIC` (cubic spline + interpolation in a 4x4 environment). If omitted, or if the image has + mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. + See :ref:`concept-filters`. + :param expand: Optional expansion flag. If true, expands the output + image to make it large enough to hold the entire rotated image. + If false or omitted, make the output image the same size as the + input image. Note that the expand flag assumes rotation around + the center and no translation. + :param center: Optional center of rotation (a 2-tuple). Origin is + the upper left corner. Default is the center of the image. + :param translate: An optional post-rotate translation (a 2-tuple). + :param fillcolor: An optional color for area outside the rotated image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + angle = angle % 360.0 + + # Fast paths regardless of filter, as long as we're not + # translating or changing the center. + if not (center or translate): + if angle == 0: + return self.copy() + if angle == 180: + return self.transpose(Transpose.ROTATE_180) + if angle in (90, 270) and (expand or self.width == self.height): + return self.transpose( + Transpose.ROTATE_90 if angle == 90 else Transpose.ROTATE_270 + ) + + # Calculate the affine matrix. Note that this is the reverse + # transformation (from destination image to source) because we + # want to interpolate the (discrete) destination pixel from + # the local area around the (floating) source pixel. + + # The matrix we actually want (note that it operates from the right): + # (1, 0, tx) (1, 0, cx) ( cos a, sin a, 0) (1, 0, -cx) + # (0, 1, ty) * (0, 1, cy) * (-sin a, cos a, 0) * (0, 1, -cy) + # (0, 0, 1) (0, 0, 1) ( 0, 0, 1) (0, 0, 1) + + # The reverse matrix is thus: + # (1, 0, cx) ( cos -a, sin -a, 0) (1, 0, -cx) (1, 0, -tx) + # (0, 1, cy) * (-sin -a, cos -a, 0) * (0, 1, -cy) * (0, 1, -ty) + # (0, 0, 1) ( 0, 0, 1) (0, 0, 1) (0, 0, 1) + + # In any case, the final translation may be updated at the end to + # compensate for the expand flag. + + w, h = self.size + + if translate is None: + post_trans = (0, 0) + else: + post_trans = translate + if center is None: + center = (w / 2, h / 2) + + angle = -math.radians(angle) + matrix = [ + round(math.cos(angle), 15), + round(math.sin(angle), 15), + 0.0, + round(-math.sin(angle), 15), + round(math.cos(angle), 15), + 0.0, + ] + + def transform(x: float, y: float, matrix: list[float]) -> tuple[float, float]: + (a, b, c, d, e, f) = matrix + return a * x + b * y + c, d * x + e * y + f + + matrix[2], matrix[5] = transform( + -center[0] - post_trans[0], -center[1] - post_trans[1], matrix + ) + matrix[2] += center[0] + matrix[5] += center[1] + + if expand: + # calculate output size + xx = [] + yy = [] + for x, y in ((0, 0), (w, 0), (w, h), (0, h)): + transformed_x, transformed_y = transform(x, y, matrix) + xx.append(transformed_x) + yy.append(transformed_y) + nw = math.ceil(max(xx)) - math.floor(min(xx)) + nh = math.ceil(max(yy)) - math.floor(min(yy)) + + # We multiply a translation matrix from the right. Because of its + # special form, this is the same as taking the image of the + # translation vector as new translation vector. + matrix[2], matrix[5] = transform(-(nw - w) / 2.0, -(nh - h) / 2.0, matrix) + w, h = nw, nh + + return self.transform( + (w, h), Transform.AFFINE, matrix, resample, fillcolor=fillcolor + ) + + def save( + self, fp: StrOrBytesPath | IO[bytes], format: str | None = None, **params: Any + ) -> None: + """ + Saves this image under the given filename. If no format is + specified, the format to use is determined from the filename + extension, if possible. + + Keyword options can be used to provide additional instructions + to the writer. If a writer doesn't recognise an option, it is + silently ignored. The available options are described in the + :doc:`image format documentation + <../handbook/image-file-formats>` for each writer. + + You can use a file object instead of a filename. In this case, + you must always specify the format. The file object must + implement the ``seek``, ``tell``, and ``write`` + methods, and be opened in binary mode. + + :param fp: A filename (string), os.PathLike object or file object. + :param format: Optional format override. If omitted, the + format to use is determined from the filename extension. + If a file object was used instead of a filename, this + parameter should always be used. + :param params: Extra parameters to the image writer. + :returns: None + :exception ValueError: If the output format could not be determined + from the file name. Use the format option to solve this. + :exception OSError: If the file could not be written. The file + may have been created, and may contain partial data. + """ + + filename: str | bytes = "" + open_fp = False + if is_path(fp): + filename = os.path.realpath(os.fspath(fp)) + open_fp = True + elif fp == sys.stdout: + try: + fp = sys.stdout.buffer + except AttributeError: + pass + if not filename and hasattr(fp, "name") and is_path(fp.name): + # only set the name for metadata purposes + filename = os.path.realpath(os.fspath(fp.name)) + + # may mutate self! + self._ensure_mutable() + + save_all = params.pop("save_all", False) + self.encoderinfo = params + self.encoderconfig: tuple[Any, ...] = () + + preinit() + + filename_ext = os.path.splitext(filename)[1].lower() + ext = filename_ext.decode() if isinstance(filename_ext, bytes) else filename_ext + + if not format: + if ext not in EXTENSION: + init() + try: + format = EXTENSION[ext] + except KeyError as e: + msg = f"unknown file extension: {ext}" + raise ValueError(msg) from e + + if format.upper() not in SAVE: + init() + if save_all: + save_handler = SAVE_ALL[format.upper()] + else: + save_handler = SAVE[format.upper()] + + created = False + if open_fp: + created = not os.path.exists(filename) + if params.get("append", False): + # Open also for reading ("+"), because TIFF save_all + # writer needs to go back and edit the written data. + fp = builtins.open(filename, "r+b") + else: + fp = builtins.open(filename, "w+b") + else: + fp = cast(IO[bytes], fp) + + try: + save_handler(self, fp, filename) + except Exception: + if open_fp: + fp.close() + if created: + try: + os.remove(filename) + except PermissionError: + pass + raise + if open_fp: + fp.close() + + def seek(self, frame: int) -> None: + """ + Seeks to the given frame in this sequence file. If you seek + beyond the end of the sequence, the method raises an + ``EOFError`` exception. When a sequence file is opened, the + library automatically seeks to frame 0. + + See :py:meth:`~PIL.Image.Image.tell`. + + If defined, :attr:`~PIL.Image.Image.n_frames` refers to the + number of available frames. + + :param frame: Frame number, starting at 0. + :exception EOFError: If the call attempts to seek beyond the end + of the sequence. + """ + + # overridden by file handlers + if frame != 0: + msg = "no more images in file" + raise EOFError(msg) + + def show(self, title: str | None = None) -> None: + """ + Displays this image. This method is mainly intended for debugging purposes. + + This method calls :py:func:`PIL.ImageShow.show` internally. You can use + :py:func:`PIL.ImageShow.register` to override its default behaviour. + + The image is first saved to a temporary file. By default, it will be in + PNG format. + + On Unix, the image is then opened using the **xdg-open**, **display**, + **gm**, **eog** or **xv** utility, depending on which one can be found. + + On macOS, the image is opened with the native Preview application. + + On Windows, the image is opened with the standard PNG display utility. + + :param title: Optional title to use for the image window, where possible. + """ + + _show(self, title=title) + + def split(self) -> tuple[Image, ...]: + """ + Split this image into individual bands. This method returns a + tuple of individual image bands from an image. For example, + splitting an "RGB" image creates three new images each + containing a copy of one of the original bands (red, green, + blue). + + If you need only one band, :py:meth:`~PIL.Image.Image.getchannel` + method can be more convenient and faster. + + :returns: A tuple containing bands. + """ + + self.load() + if self.im.bands == 1: + return (self.copy(),) + return tuple(map(self._new, self.im.split())) + + def getchannel(self, channel: int | str) -> Image: + """ + Returns an image containing a single channel of the source image. + + :param channel: What channel to return. Could be index + (0 for "R" channel of "RGB") or channel name + ("A" for alpha channel of "RGBA"). + :returns: An image in "L" mode. + + .. versionadded:: 4.3.0 + """ + self.load() + + if isinstance(channel, str): + try: + channel = self.getbands().index(channel) + except ValueError as e: + msg = f'The image has no channel "{channel}"' + raise ValueError(msg) from e + + return self._new(self.im.getband(channel)) + + def tell(self) -> int: + """ + Returns the current frame number. See :py:meth:`~PIL.Image.Image.seek`. + + If defined, :attr:`~PIL.Image.Image.n_frames` refers to the + number of available frames. + + :returns: Frame number, starting with 0. + """ + return 0 + + def thumbnail( + self, + size: tuple[float, float], + resample: Resampling = Resampling.BICUBIC, + reducing_gap: float | None = 2.0, + ) -> None: + """ + Make this image into a thumbnail. This method modifies the + image to contain a thumbnail version of itself, no larger than + the given size. This method calculates an appropriate thumbnail + size to preserve the aspect of the image, calls the + :py:meth:`~PIL.Image.Image.draft` method to configure the file reader + (where applicable), and finally resizes the image. + + Note that this function modifies the :py:class:`~PIL.Image.Image` + object in place. If you need to use the full resolution image as well, + apply this method to a :py:meth:`~PIL.Image.Image.copy` of the original + image. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param resample: Optional resampling filter. This can be one + of :py:data:`Resampling.NEAREST`, :py:data:`Resampling.BOX`, + :py:data:`Resampling.BILINEAR`, :py:data:`Resampling.HAMMING`, + :py:data:`Resampling.BICUBIC` or :py:data:`Resampling.LANCZOS`. + If omitted, it defaults to :py:data:`Resampling.BICUBIC`. + (was :py:data:`Resampling.NEAREST` prior to version 2.5.0). + See: :ref:`concept-filters`. + :param reducing_gap: Apply optimization by resizing the image + in two steps. First, reducing the image by integer times + using :py:meth:`~PIL.Image.Image.reduce` or + :py:meth:`~PIL.Image.Image.draft` for JPEG images. + Second, resizing using regular resampling. The last step + changes size no less than by ``reducing_gap`` times. + ``reducing_gap`` may be None (no first step is performed) + or should be greater than 1.0. The bigger ``reducing_gap``, + the closer the result to the fair resampling. + The smaller ``reducing_gap``, the faster resizing. + With ``reducing_gap`` greater or equal to 3.0, the result is + indistinguishable from fair resampling in most cases. + The default value is 2.0 (very close to fair resampling + while still being faster in many cases). + :returns: None + """ + + provided_size = tuple(map(math.floor, size)) + + def preserve_aspect_ratio() -> tuple[int, int] | None: + def round_aspect(number: float, key: Callable[[int], float]) -> int: + return max(min(math.floor(number), math.ceil(number), key=key), 1) + + x, y = provided_size + if x >= self.width and y >= self.height: + return None + + aspect = self.width / self.height + if x / y >= aspect: + x = round_aspect(y * aspect, key=lambda n: abs(aspect - n / y)) + else: + y = round_aspect( + x / aspect, key=lambda n: 0 if n == 0 else abs(aspect - x / n) + ) + return x, y + + preserved_size = preserve_aspect_ratio() + if preserved_size is None: + return + final_size = preserved_size + + box = None + if reducing_gap is not None: + res = self.draft( + None, (int(size[0] * reducing_gap), int(size[1] * reducing_gap)) + ) + if res is not None: + box = res[1] + + if self.size != final_size: + im = self.resize(final_size, resample, box=box, reducing_gap=reducing_gap) + + self.im = im.im + self._size = final_size + self._mode = self.im.mode + + self.readonly = 0 + + # FIXME: the different transform methods need further explanation + # instead of bloating the method docs, add a separate chapter. + def transform( + self, + size: tuple[int, int], + method: Transform | ImageTransformHandler | SupportsGetData, + data: Sequence[Any] | None = None, + resample: int = Resampling.NEAREST, + fill: int = 1, + fillcolor: float | tuple[float, ...] | str | None = None, + ) -> Image: + """ + Transforms this image. This method creates a new image with the + given size, and the same mode as the original, and copies data + to the new image using the given transform. + + :param size: The output size in pixels, as a 2-tuple: + (width, height). + :param method: The transformation method. This is one of + :py:data:`Transform.EXTENT` (cut out a rectangular subregion), + :py:data:`Transform.AFFINE` (affine transform), + :py:data:`Transform.PERSPECTIVE` (perspective transform), + :py:data:`Transform.QUAD` (map a quadrilateral to a rectangle), or + :py:data:`Transform.MESH` (map a number of source quadrilaterals + in one operation). + + It may also be an :py:class:`~PIL.Image.ImageTransformHandler` + object:: + + class Example(Image.ImageTransformHandler): + def transform(self, size, data, resample, fill=1): + # Return result + + Implementations of :py:class:`~PIL.Image.ImageTransformHandler` + for some of the :py:class:`Transform` methods are provided + in :py:mod:`~PIL.ImageTransform`. + + It may also be an object with a ``method.getdata`` method + that returns a tuple supplying new ``method`` and ``data`` values:: + + class Example: + def getdata(self): + method = Image.Transform.EXTENT + data = (0, 0, 100, 100) + return method, data + :param data: Extra data to the transformation method. + :param resample: Optional resampling filter. It can be one of + :py:data:`Resampling.NEAREST` (use nearest neighbour), + :py:data:`Resampling.BILINEAR` (linear interpolation in a 2x2 + environment), or :py:data:`Resampling.BICUBIC` (cubic spline + interpolation in a 4x4 environment). If omitted, or if the image + has mode "1" or "P", it is set to :py:data:`Resampling.NEAREST`. + See: :ref:`concept-filters`. + :param fill: If ``method`` is an + :py:class:`~PIL.Image.ImageTransformHandler` object, this is one of + the arguments passed to it. Otherwise, it is unused. + :param fillcolor: Optional fill color for the area outside the + transform in the output image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if self.mode in ("LA", "RGBA") and resample != Resampling.NEAREST: + return ( + self.convert({"LA": "La", "RGBA": "RGBa"}[self.mode]) + .transform(size, method, data, resample, fill, fillcolor) + .convert(self.mode) + ) + + if isinstance(method, ImageTransformHandler): + return method.transform(size, self, resample=resample, fill=fill) + + if hasattr(method, "getdata"): + # compatibility w. old-style transform objects + method, data = method.getdata() + + if data is None: + msg = "missing method data" + raise ValueError(msg) + + im = new(self.mode, size, fillcolor) + if self.mode == "P" and self.palette: + im.palette = self.palette.copy() + im.info = self.info.copy() + if method == Transform.MESH: + # list of quads + for box, quad in data: + im.__transformer( + box, self, Transform.QUAD, quad, resample, fillcolor is None + ) + else: + im.__transformer( + (0, 0) + size, self, method, data, resample, fillcolor is None + ) + + return im + + def __transformer( + self, + box: tuple[int, int, int, int], + image: Image, + method: Transform, + data: Sequence[float], + resample: int = Resampling.NEAREST, + fill: bool = True, + ) -> None: + w = box[2] - box[0] + h = box[3] - box[1] + + if method == Transform.AFFINE: + data = data[:6] + + elif method == Transform.EXTENT: + # convert extent to an affine transform + x0, y0, x1, y1 = data + xs = (x1 - x0) / w + ys = (y1 - y0) / h + method = Transform.AFFINE + data = (xs, 0, x0, 0, ys, y0) + + elif method == Transform.PERSPECTIVE: + data = data[:8] + + elif method == Transform.QUAD: + # quadrilateral warp. data specifies the four corners + # given as NW, SW, SE, and NE. + nw = data[:2] + sw = data[2:4] + se = data[4:6] + ne = data[6:8] + x0, y0 = nw + As = 1.0 / w + At = 1.0 / h + data = ( + x0, + (ne[0] - x0) * As, + (sw[0] - x0) * At, + (se[0] - sw[0] - ne[0] + x0) * As * At, + y0, + (ne[1] - y0) * As, + (sw[1] - y0) * At, + (se[1] - sw[1] - ne[1] + y0) * As * At, + ) + + else: + msg = "unknown transformation method" + raise ValueError(msg) + + if resample not in ( + Resampling.NEAREST, + Resampling.BILINEAR, + Resampling.BICUBIC, + ): + if resample in (Resampling.BOX, Resampling.HAMMING, Resampling.LANCZOS): + unusable: dict[int, str] = { + Resampling.BOX: "Image.Resampling.BOX", + Resampling.HAMMING: "Image.Resampling.HAMMING", + Resampling.LANCZOS: "Image.Resampling.LANCZOS", + } + msg = unusable[resample] + f" ({resample}) cannot be used." + else: + msg = f"Unknown resampling filter ({resample})." + + filters = [ + f"{filter[1]} ({filter[0]})" + for filter in ( + (Resampling.NEAREST, "Image.Resampling.NEAREST"), + (Resampling.BILINEAR, "Image.Resampling.BILINEAR"), + (Resampling.BICUBIC, "Image.Resampling.BICUBIC"), + ) + ] + msg += f" Use {', '.join(filters[:-1])} or {filters[-1]}" + raise ValueError(msg) + + image.load() + + self.load() + + if image.mode in ("1", "P"): + resample = Resampling.NEAREST + + self.im.transform(box, image.im, method, data, resample, fill) + + def transpose(self, method: Transpose) -> Image: + """ + Transpose image (flip or rotate in 90 degree steps) + + :param method: One of :py:data:`Transpose.FLIP_LEFT_RIGHT`, + :py:data:`Transpose.FLIP_TOP_BOTTOM`, :py:data:`Transpose.ROTATE_90`, + :py:data:`Transpose.ROTATE_180`, :py:data:`Transpose.ROTATE_270`, + :py:data:`Transpose.TRANSPOSE` or :py:data:`Transpose.TRANSVERSE`. + :returns: Returns a flipped or rotated copy of this image. + """ + + self.load() + return self._new(self.im.transpose(method)) + + def effect_spread(self, distance: int) -> Image: + """ + Randomly spread pixels in an image. + + :param distance: Distance to spread pixels. + """ + self.load() + return self._new(self.im.effect_spread(distance)) + + def toqimage(self) -> ImageQt.ImageQt: + """Returns a QImage copy of this image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.toqimage(self) + + def toqpixmap(self) -> ImageQt.QPixmap: + """Returns a QPixmap copy of this image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.toqpixmap(self) + + +# -------------------------------------------------------------------- +# Abstract handlers. + + +class ImagePointHandler: + """ + Used as a mixin by point transforms + (for use with :py:meth:`~PIL.Image.Image.point`) + """ + + @abc.abstractmethod + def point(self, im: Image) -> Image: + pass + + +class ImageTransformHandler: + """ + Used as a mixin by geometry transforms + (for use with :py:meth:`~PIL.Image.Image.transform`) + """ + + @abc.abstractmethod + def transform( + self, + size: tuple[int, int], + image: Image, + **options: Any, + ) -> Image: + pass + + +# -------------------------------------------------------------------- +# Factories + +# +# Debugging + + +def _wedge() -> Image: + """Create grayscale wedge (for debugging only)""" + + return Image()._new(core.wedge("L")) + + +def _check_size(size: Any) -> None: + """ + Common check to enforce type and sanity check on size tuples + + :param size: Should be a 2 tuple of (width, height) + :returns: None, or raises a ValueError + """ + + if not isinstance(size, (list, tuple)): + msg = "Size must be a list or tuple" + raise ValueError(msg) + if len(size) != 2: + msg = "Size must be a sequence of length 2" + raise ValueError(msg) + if size[0] < 0 or size[1] < 0: + msg = "Width and height must be >= 0" + raise ValueError(msg) + + +def new( + mode: str, + size: tuple[int, int] | list[int], + color: float | tuple[float, ...] | str | None = 0, +) -> Image: + """ + Creates a new image with the given mode and size. + + :param mode: The mode to use for the new image. See: + :ref:`concept-modes`. + :param size: A 2-tuple, containing (width, height) in pixels. + :param color: What color to use for the image. Default is black. + If given, this should be a single integer or floating point value + for single-band modes, and a tuple for multi-band modes (one value + per band). When creating RGB or HSV images, you can also use color + strings as supported by the ImageColor module. If the color is + None, the image is not initialised. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if mode in ("BGR;15", "BGR;16", "BGR;24"): + deprecate(mode, 12) + + _check_size(size) + + if color is None: + # don't initialize + return Image()._new(core.new(mode, size)) + + if isinstance(color, str): + # css3-style specifier + + from . import ImageColor + + color = ImageColor.getcolor(color, mode) + + im = Image() + if ( + mode == "P" + and isinstance(color, (list, tuple)) + and all(isinstance(i, int) for i in color) + ): + color_ints: tuple[int, ...] = cast(tuple[int, ...], tuple(color)) + if len(color_ints) == 3 or len(color_ints) == 4: + # RGB or RGBA value for a P image + from . import ImagePalette + + im.palette = ImagePalette.ImagePalette() + color = im.palette.getcolor(color_ints) + return im._new(core.fill(mode, size, color)) + + +def frombytes( + mode: str, + size: tuple[int, int], + data: bytes | bytearray | SupportsArrayInterface, + decoder_name: str = "raw", + *args: Any, +) -> Image: + """ + Creates a copy of an image memory from pixel data in a buffer. + + In its simplest form, this function takes three arguments + (mode, size, and unpacked pixel data). + + You can also use any pixel decoder supported by PIL. For more + information on available decoders, see the section + :ref:`Writing Your Own File Codec `. + + Note that this function decodes pixel data only, not entire images. + If you have an entire image in a string, wrap it in a + :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load + it. + + :param mode: The image mode. See: :ref:`concept-modes`. + :param size: The image size. + :param data: A byte buffer containing raw data for the given mode. + :param decoder_name: What decoder to use. + :param args: Additional parameters for the given decoder. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + _check_size(size) + + im = new(mode, size) + if im.width != 0 and im.height != 0: + decoder_args: Any = args + if len(decoder_args) == 1 and isinstance(decoder_args[0], tuple): + # may pass tuple instead of argument list + decoder_args = decoder_args[0] + + if decoder_name == "raw" and decoder_args == (): + decoder_args = mode + + im.frombytes(data, decoder_name, decoder_args) + return im + + +def frombuffer( + mode: str, + size: tuple[int, int], + data: bytes | SupportsArrayInterface, + decoder_name: str = "raw", + *args: Any, +) -> Image: + """ + Creates an image memory referencing pixel data in a byte buffer. + + This function is similar to :py:func:`~PIL.Image.frombytes`, but uses data + in the byte buffer, where possible. This means that changes to the + original buffer object are reflected in this image). Not all modes can + share memory; supported modes include "L", "RGBX", "RGBA", and "CMYK". + + Note that this function decodes pixel data only, not entire images. + If you have an entire image file in a string, wrap it in a + :py:class:`~io.BytesIO` object, and use :py:func:`~PIL.Image.open` to load it. + + The default parameters used for the "raw" decoder differs from that used for + :py:func:`~PIL.Image.frombytes`. This is a bug, and will probably be fixed in a + future release. The current release issues a warning if you do this; to disable + the warning, you should provide the full set of parameters. See below for details. + + :param mode: The image mode. See: :ref:`concept-modes`. + :param size: The image size. + :param data: A bytes or other buffer object containing raw + data for the given mode. + :param decoder_name: What decoder to use. + :param args: Additional parameters for the given decoder. For the + default encoder ("raw"), it's recommended that you provide the + full set of parameters:: + + frombuffer(mode, size, data, "raw", mode, 0, 1) + + :returns: An :py:class:`~PIL.Image.Image` object. + + .. versionadded:: 1.1.4 + """ + + _check_size(size) + + # may pass tuple instead of argument list + if len(args) == 1 and isinstance(args[0], tuple): + args = args[0] + + if decoder_name == "raw": + if args == (): + args = mode, 0, 1 + if args[0] in _MAPMODES: + im = new(mode, (0, 0)) + im = im._new(core.map_buffer(data, size, decoder_name, 0, args)) + if mode == "P": + from . import ImagePalette + + im.palette = ImagePalette.ImagePalette("RGB", im.im.getpalette("RGB")) + im.readonly = 1 + return im + + return frombytes(mode, size, data, decoder_name, args) + + +class SupportsArrayInterface(Protocol): + """ + An object that has an ``__array_interface__`` dictionary. + """ + + @property + def __array_interface__(self) -> dict[str, Any]: + raise NotImplementedError() + + +def fromarray(obj: SupportsArrayInterface, mode: str | None = None) -> Image: + """ + Creates an image memory from an object exporting the array interface + (using the buffer protocol):: + + from PIL import Image + import numpy as np + a = np.zeros((5, 5)) + im = Image.fromarray(a) + + If ``obj`` is not contiguous, then the ``tobytes`` method is called + and :py:func:`~PIL.Image.frombuffer` is used. + + In the case of NumPy, be aware that Pillow modes do not always correspond + to NumPy dtypes. Pillow modes only offer 1-bit pixels, 8-bit pixels, + 32-bit signed integer pixels, and 32-bit floating point pixels. + + Pillow images can also be converted to arrays:: + + from PIL import Image + import numpy as np + im = Image.open("hopper.jpg") + a = np.asarray(im) + + When converting Pillow images to arrays however, only pixel values are + transferred. This means that P and PA mode images will lose their palette. + + :param obj: Object with array interface + :param mode: Optional mode to use when reading ``obj``. Will be determined from + type if ``None``. + + This will not be used to convert the data after reading, but will be used to + change how the data is read:: + + from PIL import Image + import numpy as np + a = np.full((1, 1), 300) + im = Image.fromarray(a, mode="L") + im.getpixel((0, 0)) # 44 + im = Image.fromarray(a, mode="RGB") + im.getpixel((0, 0)) # (44, 1, 0) + + See: :ref:`concept-modes` for general information about modes. + :returns: An image object. + + .. versionadded:: 1.1.6 + """ + arr = obj.__array_interface__ + shape = arr["shape"] + ndim = len(shape) + strides = arr.get("strides", None) + if mode is None: + try: + typekey = (1, 1) + shape[2:], arr["typestr"] + except KeyError as e: + msg = "Cannot handle this data type" + raise TypeError(msg) from e + try: + mode, rawmode = _fromarray_typemap[typekey] + except KeyError as e: + typekey_shape, typestr = typekey + msg = f"Cannot handle this data type: {typekey_shape}, {typestr}" + raise TypeError(msg) from e + else: + rawmode = mode + if mode in ["1", "L", "I", "P", "F"]: + ndmax = 2 + elif mode == "RGB": + ndmax = 3 + else: + ndmax = 4 + if ndim > ndmax: + msg = f"Too many dimensions: {ndim} > {ndmax}." + raise ValueError(msg) + + size = 1 if ndim == 1 else shape[1], shape[0] + if strides is not None: + if hasattr(obj, "tobytes"): + obj = obj.tobytes() + elif hasattr(obj, "tostring"): + obj = obj.tostring() + else: + msg = "'strides' requires either tobytes() or tostring()" + raise ValueError(msg) + + return frombuffer(mode, size, obj, "raw", rawmode, 0, 1) + + +def fromqimage(im: ImageQt.QImage) -> ImageFile.ImageFile: + """Creates an image instance from a QImage image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.fromqimage(im) + + +def fromqpixmap(im: ImageQt.QPixmap) -> ImageFile.ImageFile: + """Creates an image instance from a QPixmap image""" + from . import ImageQt + + if not ImageQt.qt_is_installed: + msg = "Qt bindings are not installed" + raise ImportError(msg) + return ImageQt.fromqpixmap(im) + + +_fromarray_typemap = { + # (shape, typestr) => mode, rawmode + # first two members of shape are set to one + ((1, 1), "|b1"): ("1", "1;8"), + ((1, 1), "|u1"): ("L", "L"), + ((1, 1), "|i1"): ("I", "I;8"), + ((1, 1), "u2"): ("I", "I;16B"), + ((1, 1), "i2"): ("I", "I;16BS"), + ((1, 1), "u4"): ("I", "I;32B"), + ((1, 1), "i4"): ("I", "I;32BS"), + ((1, 1), "f4"): ("F", "F;32BF"), + ((1, 1), "f8"): ("F", "F;64BF"), + ((1, 1, 2), "|u1"): ("LA", "LA"), + ((1, 1, 3), "|u1"): ("RGB", "RGB"), + ((1, 1, 4), "|u1"): ("RGBA", "RGBA"), + # shortcuts: + ((1, 1), f"{_ENDIAN}i4"): ("I", "I"), + ((1, 1), f"{_ENDIAN}f4"): ("F", "F"), +} + + +def _decompression_bomb_check(size: tuple[int, int]) -> None: + if MAX_IMAGE_PIXELS is None: + return + + pixels = max(1, size[0]) * max(1, size[1]) + + if pixels > 2 * MAX_IMAGE_PIXELS: + msg = ( + f"Image size ({pixels} pixels) exceeds limit of {2 * MAX_IMAGE_PIXELS} " + "pixels, could be decompression bomb DOS attack." + ) + raise DecompressionBombError(msg) + + if pixels > MAX_IMAGE_PIXELS: + warnings.warn( + f"Image size ({pixels} pixels) exceeds limit of {MAX_IMAGE_PIXELS} pixels, " + "could be decompression bomb DOS attack.", + DecompressionBombWarning, + ) + + +def open( + fp: StrOrBytesPath | IO[bytes], + mode: Literal["r"] = "r", + formats: list[str] | tuple[str, ...] | None = None, +) -> ImageFile.ImageFile: + """ + Opens and identifies the given image file. + + This is a lazy operation; this function identifies the file, but + the file remains open and the actual image data is not read from + the file until you try to process the data (or call the + :py:meth:`~PIL.Image.Image.load` method). See + :py:func:`~PIL.Image.new`. See :ref:`file-handling`. + + :param fp: A filename (string), os.PathLike object or a file object. + The file object must implement ``file.read``, + ``file.seek``, and ``file.tell`` methods, + and be opened in binary mode. The file object will also seek to zero + before reading. + :param mode: The mode. If given, this argument must be "r". + :param formats: A list or tuple of formats to attempt to load the file in. + This can be used to restrict the set of formats checked. + Pass ``None`` to try all supported formats. You can print the set of + available formats by running ``python3 -m PIL`` or using + the :py:func:`PIL.features.pilinfo` function. + :returns: An :py:class:`~PIL.Image.Image` object. + :exception FileNotFoundError: If the file cannot be found. + :exception PIL.UnidentifiedImageError: If the image cannot be opened and + identified. + :exception ValueError: If the ``mode`` is not "r", or if a ``StringIO`` + instance is used for ``fp``. + :exception TypeError: If ``formats`` is not ``None``, a list or a tuple. + """ + + if mode != "r": + msg = f"bad mode {repr(mode)}" # type: ignore[unreachable] + raise ValueError(msg) + elif isinstance(fp, io.StringIO): + msg = ( # type: ignore[unreachable] + "StringIO cannot be used to open an image. " + "Binary data must be used instead." + ) + raise ValueError(msg) + + if formats is None: + formats = ID + elif not isinstance(formats, (list, tuple)): + msg = "formats must be a list or tuple" # type: ignore[unreachable] + raise TypeError(msg) + + exclusive_fp = False + filename: str | bytes = "" + if is_path(fp): + filename = os.path.realpath(os.fspath(fp)) + + if filename: + fp = builtins.open(filename, "rb") + exclusive_fp = True + else: + fp = cast(IO[bytes], fp) + + try: + fp.seek(0) + except (AttributeError, io.UnsupportedOperation): + fp = io.BytesIO(fp.read()) + exclusive_fp = True + + prefix = fp.read(16) + + preinit() + + warning_messages: list[str] = [] + + def _open_core( + fp: IO[bytes], + filename: str | bytes, + prefix: bytes, + formats: list[str] | tuple[str, ...], + ) -> ImageFile.ImageFile | None: + for i in formats: + i = i.upper() + if i not in OPEN: + init() + try: + factory, accept = OPEN[i] + result = not accept or accept(prefix) + if isinstance(result, str): + warning_messages.append(result) + elif result: + fp.seek(0) + im = factory(fp, filename) + _decompression_bomb_check(im.size) + return im + except (SyntaxError, IndexError, TypeError, struct.error) as e: + if WARN_POSSIBLE_FORMATS: + warning_messages.append(i + " opening failed. " + str(e)) + except BaseException: + if exclusive_fp: + fp.close() + raise + return None + + im = _open_core(fp, filename, prefix, formats) + + if im is None and formats is ID: + checked_formats = ID.copy() + if init(): + im = _open_core( + fp, + filename, + prefix, + tuple(format for format in formats if format not in checked_formats), + ) + + if im: + im._exclusive_fp = exclusive_fp + return im + + if exclusive_fp: + fp.close() + for message in warning_messages: + warnings.warn(message) + msg = "cannot identify image file %r" % (filename if filename else fp) + raise UnidentifiedImageError(msg) + + +# +# Image processing. + + +def alpha_composite(im1: Image, im2: Image) -> Image: + """ + Alpha composite im2 over im1. + + :param im1: The first image. Must have mode RGBA. + :param im2: The second image. Must have mode RGBA, and the same size as + the first image. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + im1.load() + im2.load() + return im1._new(core.alpha_composite(im1.im, im2.im)) + + +def blend(im1: Image, im2: Image, alpha: float) -> Image: + """ + Creates a new image by interpolating between two input images, using + a constant alpha:: + + out = image1 * (1.0 - alpha) + image2 * alpha + + :param im1: The first image. + :param im2: The second image. Must have the same mode and size as + the first image. + :param alpha: The interpolation alpha factor. If alpha is 0.0, a + copy of the first image is returned. If alpha is 1.0, a copy of + the second image is returned. There are no restrictions on the + alpha value. If necessary, the result is clipped to fit into + the allowed output range. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + im1.load() + im2.load() + return im1._new(core.blend(im1.im, im2.im, alpha)) + + +def composite(image1: Image, image2: Image, mask: Image) -> Image: + """ + Create composite image by blending images using a transparency mask. + + :param image1: The first image. + :param image2: The second image. Must have the same mode and + size as the first image. + :param mask: A mask image. This image can have mode + "1", "L", or "RGBA", and must have the same size as the + other two images. + """ + + image = image2.copy() + image.paste(image1, None, mask) + return image + + +def eval(image: Image, *args: Callable[[int], float]) -> Image: + """ + Applies the function (which should take one argument) to each pixel + in the given image. If the image has more than one band, the same + function is applied to each band. Note that the function is + evaluated once for each possible pixel value, so you cannot use + random components or other generators. + + :param image: The input image. + :param function: A function object, taking one integer argument. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + return image.point(args[0]) + + +def merge(mode: str, bands: Sequence[Image]) -> Image: + """ + Merge a set of single band images into a new multiband image. + + :param mode: The mode to use for the output image. See: + :ref:`concept-modes`. + :param bands: A sequence containing one single-band image for + each band in the output image. All bands must have the + same size. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + + if getmodebands(mode) != len(bands) or "*" in mode: + msg = "wrong number of bands" + raise ValueError(msg) + for band in bands[1:]: + if band.mode != getmodetype(mode): + msg = "mode mismatch" + raise ValueError(msg) + if band.size != bands[0].size: + msg = "size mismatch" + raise ValueError(msg) + for band in bands: + band.load() + return bands[0]._new(core.merge(mode, *[b.im for b in bands])) + + +# -------------------------------------------------------------------- +# Plugin registry + + +def register_open( + id: str, + factory: ( + Callable[[IO[bytes], str | bytes], ImageFile.ImageFile] + | type[ImageFile.ImageFile] + ), + accept: Callable[[bytes], bool | str] | None = None, +) -> None: + """ + Register an image file plugin. This function should not be used + in application code. + + :param id: An image format identifier. + :param factory: An image file factory method. + :param accept: An optional function that can be used to quickly + reject images having another format. + """ + id = id.upper() + if id not in ID: + ID.append(id) + OPEN[id] = factory, accept + + +def register_mime(id: str, mimetype: str) -> None: + """ + Registers an image MIME type by populating ``Image.MIME``. This function + should not be used in application code. + + ``Image.MIME`` provides a mapping from image format identifiers to mime + formats, but :py:meth:`~PIL.ImageFile.ImageFile.get_format_mimetype` can + provide a different result for specific images. + + :param id: An image format identifier. + :param mimetype: The image MIME type for this format. + """ + MIME[id.upper()] = mimetype + + +def register_save( + id: str, driver: Callable[[Image, IO[bytes], str | bytes], None] +) -> None: + """ + Registers an image save function. This function should not be + used in application code. + + :param id: An image format identifier. + :param driver: A function to save images in this format. + """ + SAVE[id.upper()] = driver + + +def register_save_all( + id: str, driver: Callable[[Image, IO[bytes], str | bytes], None] +) -> None: + """ + Registers an image function to save all the frames + of a multiframe format. This function should not be + used in application code. + + :param id: An image format identifier. + :param driver: A function to save images in this format. + """ + SAVE_ALL[id.upper()] = driver + + +def register_extension(id: str, extension: str) -> None: + """ + Registers an image extension. This function should not be + used in application code. + + :param id: An image format identifier. + :param extension: An extension used for this format. + """ + EXTENSION[extension.lower()] = id.upper() + + +def register_extensions(id: str, extensions: list[str]) -> None: + """ + Registers image extensions. This function should not be + used in application code. + + :param id: An image format identifier. + :param extensions: A list of extensions used for this format. + """ + for extension in extensions: + register_extension(id, extension) + + +def registered_extensions() -> dict[str, str]: + """ + Returns a dictionary containing all file extensions belonging + to registered plugins + """ + init() + return EXTENSION + + +def register_decoder(name: str, decoder: type[ImageFile.PyDecoder]) -> None: + """ + Registers an image decoder. This function should not be + used in application code. + + :param name: The name of the decoder + :param decoder: An ImageFile.PyDecoder object + + .. versionadded:: 4.1.0 + """ + DECODERS[name] = decoder + + +def register_encoder(name: str, encoder: type[ImageFile.PyEncoder]) -> None: + """ + Registers an image encoder. This function should not be + used in application code. + + :param name: The name of the encoder + :param encoder: An ImageFile.PyEncoder object + + .. versionadded:: 4.1.0 + """ + ENCODERS[name] = encoder + + +# -------------------------------------------------------------------- +# Simple display support. + + +def _show(image: Image, **options: Any) -> None: + from . import ImageShow + + ImageShow.show(image, **options) + + +# -------------------------------------------------------------------- +# Effects + + +def effect_mandelbrot( + size: tuple[int, int], extent: tuple[float, float, float, float], quality: int +) -> Image: + """ + Generate a Mandelbrot set covering the given extent. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param extent: The extent to cover, as a 4-tuple: + (x0, y0, x1, y1). + :param quality: Quality. + """ + return Image()._new(core.effect_mandelbrot(size, extent, quality)) + + +def effect_noise(size: tuple[int, int], sigma: float) -> Image: + """ + Generate Gaussian noise centered around 128. + + :param size: The requested size in pixels, as a 2-tuple: + (width, height). + :param sigma: Standard deviation of noise. + """ + return Image()._new(core.effect_noise(size, sigma)) + + +def linear_gradient(mode: str) -> Image: + """ + Generate 256x256 linear gradient from black to white, top to bottom. + + :param mode: Input mode. + """ + return Image()._new(core.linear_gradient(mode)) + + +def radial_gradient(mode: str) -> Image: + """ + Generate 256x256 radial gradient from black to white, centre to edge. + + :param mode: Input mode. + """ + return Image()._new(core.radial_gradient(mode)) + + +# -------------------------------------------------------------------- +# Resources + + +def _apply_env_variables(env: dict[str, str] | None = None) -> None: + env_dict = env if env is not None else os.environ + + for var_name, setter in [ + ("PILLOW_ALIGNMENT", core.set_alignment), + ("PILLOW_BLOCK_SIZE", core.set_block_size), + ("PILLOW_BLOCKS_MAX", core.set_blocks_max), + ]: + if var_name not in env_dict: + continue + + var = env_dict[var_name].lower() + + units = 1 + for postfix, mul in [("k", 1024), ("m", 1024 * 1024)]: + if var.endswith(postfix): + units = mul + var = var[: -len(postfix)] + + try: + var_int = int(var) * units + except ValueError: + warnings.warn(f"{var_name} is not int") + continue + + try: + setter(var_int) + except ValueError as e: + warnings.warn(f"{var_name}: {e}") + + +_apply_env_variables() +atexit.register(core.clear_cache) + + +if TYPE_CHECKING: + _ExifBase = MutableMapping[int, Any] +else: + _ExifBase = MutableMapping + + +class Exif(_ExifBase): + """ + This class provides read and write access to EXIF image data:: + + from PIL import Image + im = Image.open("exif.png") + exif = im.getexif() # Returns an instance of this class + + Information can be read and written, iterated over or deleted:: + + print(exif[274]) # 1 + exif[274] = 2 + for k, v in exif.items(): + print("Tag", k, "Value", v) # Tag 274 Value 2 + del exif[274] + + To access information beyond IFD0, :py:meth:`~PIL.Image.Exif.get_ifd` + returns a dictionary:: + + from PIL import ExifTags + im = Image.open("exif_gps.jpg") + exif = im.getexif() + gps_ifd = exif.get_ifd(ExifTags.IFD.GPSInfo) + print(gps_ifd) + + Other IFDs include ``ExifTags.IFD.Exif``, ``ExifTags.IFD.Makernote``, + ``ExifTags.IFD.Interop`` and ``ExifTags.IFD.IFD1``. + + :py:mod:`~PIL.ExifTags` also has enum classes to provide names for data:: + + print(exif[ExifTags.Base.Software]) # PIL + print(gps_ifd[ExifTags.GPS.GPSDateStamp]) # 1999:99:99 99:99:99 + """ + + endian: str | None = None + bigtiff = False + _loaded = False + + def __init__(self) -> None: + self._data: dict[int, Any] = {} + self._hidden_data: dict[int, Any] = {} + self._ifds: dict[int, dict[int, Any]] = {} + self._info: TiffImagePlugin.ImageFileDirectory_v2 | None = None + self._loaded_exif: bytes | None = None + + def _fixup(self, value: Any) -> Any: + try: + if len(value) == 1 and isinstance(value, tuple): + return value[0] + except Exception: + pass + return value + + def _fixup_dict(self, src_dict: dict[int, Any]) -> dict[int, Any]: + # Helper function + # returns a dict with any single item tuples/lists as individual values + return {k: self._fixup(v) for k, v in src_dict.items()} + + def _get_ifd_dict( + self, offset: int, group: int | None = None + ) -> dict[int, Any] | None: + try: + # an offset pointer to the location of the nested embedded IFD. + # It should be a long, but may be corrupted. + self.fp.seek(offset) + except (KeyError, TypeError): + return None + else: + from . import TiffImagePlugin + + info = TiffImagePlugin.ImageFileDirectory_v2(self.head, group=group) + info.load(self.fp) + return self._fixup_dict(dict(info)) + + def _get_head(self) -> bytes: + version = b"\x2B" if self.bigtiff else b"\x2A" + if self.endian == "<": + head = b"II" + version + b"\x00" + o32le(8) + else: + head = b"MM\x00" + version + o32be(8) + if self.bigtiff: + head += o32le(8) if self.endian == "<" else o32be(8) + head += b"\x00\x00\x00\x00" + return head + + def load(self, data: bytes) -> None: + # Extract EXIF information. This is highly experimental, + # and is likely to be replaced with something better in a future + # version. + + # The EXIF record consists of a TIFF file embedded in a JPEG + # application marker (!). + if data == self._loaded_exif: + return + self._loaded_exif = data + self._data.clear() + self._hidden_data.clear() + self._ifds.clear() + while data and data.startswith(b"Exif\x00\x00"): + data = data[6:] + if not data: + self._info = None + return + + self.fp: IO[bytes] = io.BytesIO(data) + self.head = self.fp.read(8) + # process dictionary + from . import TiffImagePlugin + + self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) + self.endian = self._info._endian + self.fp.seek(self._info.next) + self._info.load(self.fp) + + def load_from_fp(self, fp: IO[bytes], offset: int | None = None) -> None: + self._loaded_exif = None + self._data.clear() + self._hidden_data.clear() + self._ifds.clear() + + # process dictionary + from . import TiffImagePlugin + + self.fp = fp + if offset is not None: + self.head = self._get_head() + else: + self.head = self.fp.read(8) + self._info = TiffImagePlugin.ImageFileDirectory_v2(self.head) + if self.endian is None: + self.endian = self._info._endian + if offset is None: + offset = self._info.next + self.fp.tell() + self.fp.seek(offset) + self._info.load(self.fp) + + def _get_merged_dict(self) -> dict[int, Any]: + merged_dict = dict(self) + + # get EXIF extension + if ExifTags.IFD.Exif in self: + ifd = self._get_ifd_dict(self[ExifTags.IFD.Exif], ExifTags.IFD.Exif) + if ifd: + merged_dict.update(ifd) + + # GPS + if ExifTags.IFD.GPSInfo in self: + merged_dict[ExifTags.IFD.GPSInfo] = self._get_ifd_dict( + self[ExifTags.IFD.GPSInfo], ExifTags.IFD.GPSInfo + ) + + return merged_dict + + def tobytes(self, offset: int = 8) -> bytes: + from . import TiffImagePlugin + + head = self._get_head() + ifd = TiffImagePlugin.ImageFileDirectory_v2(ifh=head) + for tag, value in self.items(): + if tag in [ + ExifTags.IFD.Exif, + ExifTags.IFD.GPSInfo, + ] and not isinstance(value, dict): + value = self.get_ifd(tag) + if ( + tag == ExifTags.IFD.Exif + and ExifTags.IFD.Interop in value + and not isinstance(value[ExifTags.IFD.Interop], dict) + ): + value = value.copy() + value[ExifTags.IFD.Interop] = self.get_ifd(ExifTags.IFD.Interop) + ifd[tag] = value + return b"Exif\x00\x00" + head + ifd.tobytes(offset) + + def get_ifd(self, tag: int) -> dict[int, Any]: + if tag not in self._ifds: + if tag == ExifTags.IFD.IFD1: + if self._info is not None and self._info.next != 0: + ifd = self._get_ifd_dict(self._info.next) + if ifd is not None: + self._ifds[tag] = ifd + elif tag in [ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo]: + offset = self._hidden_data.get(tag, self.get(tag)) + if offset is not None: + ifd = self._get_ifd_dict(offset, tag) + if ifd is not None: + self._ifds[tag] = ifd + elif tag in [ExifTags.IFD.Interop, ExifTags.IFD.Makernote]: + if ExifTags.IFD.Exif not in self._ifds: + self.get_ifd(ExifTags.IFD.Exif) + tag_data = self._ifds[ExifTags.IFD.Exif][tag] + if tag == ExifTags.IFD.Makernote: + from .TiffImagePlugin import ImageFileDirectory_v2 + + if tag_data[:8] == b"FUJIFILM": + ifd_offset = i32le(tag_data, 8) + ifd_data = tag_data[ifd_offset:] + + makernote = {} + for i in range(0, struct.unpack(" 4: + (offset,) = struct.unpack("H", tag_data[:2])[0]): + ifd_tag, typ, count, data = struct.unpack( + ">HHL4s", tag_data[i * 12 + 2 : (i + 1) * 12 + 2] + ) + if ifd_tag == 0x1101: + # CameraInfo + (offset,) = struct.unpack(">L", data) + self.fp.seek(offset) + + camerainfo: dict[str, int | bytes] = { + "ModelID": self.fp.read(4) + } + + self.fp.read(4) + # Seconds since 2000 + camerainfo["TimeStamp"] = i32le(self.fp.read(12)) + + self.fp.read(4) + camerainfo["InternalSerialNumber"] = self.fp.read(4) + + self.fp.read(12) + parallax = self.fp.read(4) + handler = ImageFileDirectory_v2._load_dispatch[ + TiffTags.FLOAT + ][1] + camerainfo["Parallax"] = handler( + ImageFileDirectory_v2(), parallax, False + )[0] + + self.fp.read(4) + camerainfo["Category"] = self.fp.read(2) + + makernote = {0x1101: camerainfo} + self._ifds[tag] = makernote + else: + # Interop + ifd = self._get_ifd_dict(tag_data, tag) + if ifd is not None: + self._ifds[tag] = ifd + ifd = self._ifds.setdefault(tag, {}) + if tag == ExifTags.IFD.Exif and self._hidden_data: + ifd = { + k: v + for (k, v) in ifd.items() + if k not in (ExifTags.IFD.Interop, ExifTags.IFD.Makernote) + } + return ifd + + def hide_offsets(self) -> None: + for tag in (ExifTags.IFD.Exif, ExifTags.IFD.GPSInfo): + if tag in self: + self._hidden_data[tag] = self[tag] + del self[tag] + + def __str__(self) -> str: + if self._info is not None: + # Load all keys into self._data + for tag in self._info: + self[tag] + + return str(self._data) + + def __len__(self) -> int: + keys = set(self._data) + if self._info is not None: + keys.update(self._info) + return len(keys) + + def __getitem__(self, tag: int) -> Any: + if self._info is not None and tag not in self._data and tag in self._info: + self._data[tag] = self._fixup(self._info[tag]) + del self._info[tag] + return self._data[tag] + + def __contains__(self, tag: object) -> bool: + return tag in self._data or (self._info is not None and tag in self._info) + + def __setitem__(self, tag: int, value: Any) -> None: + if self._info is not None and tag in self._info: + del self._info[tag] + self._data[tag] = value + + def __delitem__(self, tag: int) -> None: + if self._info is not None and tag in self._info: + del self._info[tag] + else: + del self._data[tag] + + def __iter__(self) -> Iterator[int]: + keys = set(self._data) + if self._info is not None: + keys.update(self._info) + return iter(keys) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageChops.py b/venv/lib/python3.12/site-packages/PIL/ImageChops.py new file mode 100644 index 0000000..29a5c99 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageChops.py @@ -0,0 +1,311 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard channel operations +# +# History: +# 1996-03-24 fl Created +# 1996-08-13 fl Added logical operations (for "1" images) +# 2000-10-12 fl Added offset method (from Image.py) +# +# Copyright (c) 1997-2000 by Secret Labs AB +# Copyright (c) 1996-2000 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +from . import Image + + +def constant(image: Image.Image, value: int) -> Image.Image: + """Fill a channel with a given gray level. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.new("L", image.size, value) + + +def duplicate(image: Image.Image) -> Image.Image: + """Copy a channel. Alias for :py:meth:`PIL.Image.Image.copy`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return image.copy() + + +def invert(image: Image.Image) -> Image.Image: + """ + Invert an image (channel). :: + + out = MAX - image + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image.load() + return image._new(image.im.chop_invert()) + + +def lighter(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Compares the two images, pixel by pixel, and returns a new image containing + the lighter values. :: + + out = max(image1, image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_lighter(image2.im)) + + +def darker(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Compares the two images, pixel by pixel, and returns a new image containing + the darker values. :: + + out = min(image1, image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_darker(image2.im)) + + +def difference(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Returns the absolute value of the pixel-by-pixel difference between the two + images. :: + + out = abs(image1 - image2) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_difference(image2.im)) + + +def multiply(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other. + + If you multiply an image with a solid black image, the result is black. If + you multiply with a solid white image, the image is unaffected. :: + + out = image1 * image2 / MAX + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_multiply(image2.im)) + + +def screen(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two inverted images on top of each other. :: + + out = MAX - ((MAX - image1) * (MAX - image2) / MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_screen(image2.im)) + + +def soft_light(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Soft Light algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_soft_light(image2.im)) + + +def hard_light(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Hard Light algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_hard_light(image2.im)) + + +def overlay(image1: Image.Image, image2: Image.Image) -> Image.Image: + """ + Superimposes two images on top of each other using the Overlay algorithm + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_overlay(image2.im)) + + +def add( + image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 +) -> Image.Image: + """ + Adds two images, dividing the result by scale and adding the + offset. If omitted, scale defaults to 1.0, and offset to 0.0. :: + + out = ((image1 + image2) / scale + offset) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_add(image2.im, scale, offset)) + + +def subtract( + image1: Image.Image, image2: Image.Image, scale: float = 1.0, offset: float = 0 +) -> Image.Image: + """ + Subtracts two images, dividing the result by scale and adding the offset. + If omitted, scale defaults to 1.0, and offset to 0.0. :: + + out = ((image1 - image2) / scale + offset) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract(image2.im, scale, offset)) + + +def add_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Add two images, without clipping the result. :: + + out = ((image1 + image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_add_modulo(image2.im)) + + +def subtract_modulo(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Subtract two images, without clipping the result. :: + + out = ((image1 - image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_subtract_modulo(image2.im)) + + +def logical_and(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical AND between two images. + + Both of the images must have mode "1". If you would like to perform a + logical AND on an image with a mode other than "1", try + :py:meth:`~PIL.ImageChops.multiply` instead, using a black-and-white mask + as the second image. :: + + out = ((image1 and image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_and(image2.im)) + + +def logical_or(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical OR between two images. + + Both of the images must have mode "1". :: + + out = ((image1 or image2) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_or(image2.im)) + + +def logical_xor(image1: Image.Image, image2: Image.Image) -> Image.Image: + """Logical XOR between two images. + + Both of the images must have mode "1". :: + + out = ((bool(image1) != bool(image2)) % MAX) + + :rtype: :py:class:`~PIL.Image.Image` + """ + + image1.load() + image2.load() + return image1._new(image1.im.chop_xor(image2.im)) + + +def blend(image1: Image.Image, image2: Image.Image, alpha: float) -> Image.Image: + """Blend images using constant transparency weight. Alias for + :py:func:`PIL.Image.blend`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.blend(image1, image2, alpha) + + +def composite( + image1: Image.Image, image2: Image.Image, mask: Image.Image +) -> Image.Image: + """Create composite using transparency mask. Alias for + :py:func:`PIL.Image.composite`. + + :rtype: :py:class:`~PIL.Image.Image` + """ + + return Image.composite(image1, image2, mask) + + +def offset(image: Image.Image, xoffset: int, yoffset: int | None = None) -> Image.Image: + """Returns a copy of the image where data has been offset by the given + distances. Data wraps around the edges. If ``yoffset`` is omitted, it + is assumed to be equal to ``xoffset``. + + :param image: Input image. + :param xoffset: The horizontal distance. + :param yoffset: The vertical distance. If omitted, both + distances are set to the same value. + :rtype: :py:class:`~PIL.Image.Image` + """ + + if yoffset is None: + yoffset = xoffset + image.load() + return image._new(image.im.offset(xoffset, yoffset)) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageCms.py b/venv/lib/python3.12/site-packages/PIL/ImageCms.py new file mode 100644 index 0000000..fdfbee7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageCms.py @@ -0,0 +1,1125 @@ +# The Python Imaging Library. +# $Id$ + +# Optional color management support, based on Kevin Cazabon's PyCMS +# library. + +# Originally released under LGPL. Graciously donated to PIL in +# March 2009, for distribution under the standard PIL license + +# History: + +# 2009-03-08 fl Added to PIL. + +# Copyright (C) 2002-2003 Kevin Cazabon +# Copyright (c) 2009 by Fredrik Lundh +# Copyright (c) 2013 by Eric Soroos + +# See the README file for information on usage and redistribution. See +# below for the original description. +from __future__ import annotations + +import operator +import sys +from enum import IntEnum, IntFlag +from functools import reduce +from typing import Any, Literal, SupportsFloat, SupportsInt, Union + +from . import Image, __version__ +from ._deprecate import deprecate +from ._typing import SupportsRead + +try: + from . import _imagingcms as core + + _CmsProfileCompatible = Union[ + str, SupportsRead[bytes], core.CmsProfile, "ImageCmsProfile" + ] +except ImportError as ex: + # Allow error import for doc purposes, but error out when accessing + # anything in core. + from ._util import DeferredError + + core = DeferredError.new(ex) + +_DESCRIPTION = """ +pyCMS + + a Python / PIL interface to the littleCMS ICC Color Management System + Copyright (C) 2002-2003 Kevin Cazabon + kevin@cazabon.com + https://www.cazabon.com + + pyCMS home page: https://www.cazabon.com/pyCMS + littleCMS home page: https://www.littlecms.com + (littleCMS is Copyright (C) 1998-2001 Marti Maria) + + Originally released under LGPL. Graciously donated to PIL in + March 2009, for distribution under the standard PIL license + + The pyCMS.py module provides a "clean" interface between Python/PIL and + pyCMSdll, taking care of some of the more complex handling of the direct + pyCMSdll functions, as well as error-checking and making sure that all + relevant data is kept together. + + While it is possible to call pyCMSdll functions directly, it's not highly + recommended. + + Version History: + + 1.0.0 pil Oct 2013 Port to LCMS 2. + + 0.1.0 pil mod March 10, 2009 + + Renamed display profile to proof profile. The proof + profile is the profile of the device that is being + simulated, not the profile of the device which is + actually used to display/print the final simulation + (that'd be the output profile) - also see LCMSAPI.txt + input colorspace -> using 'renderingIntent' -> proof + colorspace -> using 'proofRenderingIntent' -> output + colorspace + + Added LCMS FLAGS support. + Added FLAGS["SOFTPROOFING"] as default flag for + buildProofTransform (otherwise the proof profile/intent + would be ignored). + + 0.1.0 pil March 2009 - added to PIL, as PIL.ImageCms + + 0.0.2 alpha Jan 6, 2002 + + Added try/except statements around type() checks of + potential CObjects... Python won't let you use type() + on them, and raises a TypeError (stupid, if you ask + me!) + + Added buildProofTransformFromOpenProfiles() function. + Additional fixes in DLL, see DLL code for details. + + 0.0.1 alpha first public release, Dec. 26, 2002 + + Known to-do list with current version (of Python interface, not pyCMSdll): + + none + +""" + +_VERSION = "1.0.0 pil" + + +def __getattr__(name: str) -> Any: + if name == "DESCRIPTION": + deprecate("PIL.ImageCms.DESCRIPTION", 12) + return _DESCRIPTION + elif name == "VERSION": + deprecate("PIL.ImageCms.VERSION", 12) + return _VERSION + elif name == "FLAGS": + deprecate("PIL.ImageCms.FLAGS", 12, "PIL.ImageCms.Flags") + return _FLAGS + msg = f"module '{__name__}' has no attribute '{name}'" + raise AttributeError(msg) + + +# --------------------------------------------------------------------. + + +# +# intent/direction values + + +class Intent(IntEnum): + PERCEPTUAL = 0 + RELATIVE_COLORIMETRIC = 1 + SATURATION = 2 + ABSOLUTE_COLORIMETRIC = 3 + + +class Direction(IntEnum): + INPUT = 0 + OUTPUT = 1 + PROOF = 2 + + +# +# flags + + +class Flags(IntFlag): + """Flags and documentation are taken from ``lcms2.h``.""" + + NONE = 0 + NOCACHE = 0x0040 + """Inhibit 1-pixel cache""" + NOOPTIMIZE = 0x0100 + """Inhibit optimizations""" + NULLTRANSFORM = 0x0200 + """Don't transform anyway""" + GAMUTCHECK = 0x1000 + """Out of Gamut alarm""" + SOFTPROOFING = 0x4000 + """Do softproofing""" + BLACKPOINTCOMPENSATION = 0x2000 + NOWHITEONWHITEFIXUP = 0x0004 + """Don't fix scum dot""" + HIGHRESPRECALC = 0x0400 + """Use more memory to give better accuracy""" + LOWRESPRECALC = 0x0800 + """Use less memory to minimize resources""" + # this should be 8BITS_DEVICELINK, but that is not a valid name in Python: + USE_8BITS_DEVICELINK = 0x0008 + """Create 8 bits devicelinks""" + GUESSDEVICECLASS = 0x0020 + """Guess device class (for ``transform2devicelink``)""" + KEEP_SEQUENCE = 0x0080 + """Keep profile sequence for devicelink creation""" + FORCE_CLUT = 0x0002 + """Force CLUT optimization""" + CLUT_POST_LINEARIZATION = 0x0001 + """create postlinearization tables if possible""" + CLUT_PRE_LINEARIZATION = 0x0010 + """create prelinearization tables if possible""" + NONEGATIVES = 0x8000 + """Prevent negative numbers in floating point transforms""" + COPY_ALPHA = 0x04000000 + """Alpha channels are copied on ``cmsDoTransform()``""" + NODEFAULTRESOURCEDEF = 0x01000000 + + _GRIDPOINTS_1 = 1 << 16 + _GRIDPOINTS_2 = 2 << 16 + _GRIDPOINTS_4 = 4 << 16 + _GRIDPOINTS_8 = 8 << 16 + _GRIDPOINTS_16 = 16 << 16 + _GRIDPOINTS_32 = 32 << 16 + _GRIDPOINTS_64 = 64 << 16 + _GRIDPOINTS_128 = 128 << 16 + + @staticmethod + def GRIDPOINTS(n: int) -> Flags: + """ + Fine-tune control over number of gridpoints + + :param n: :py:class:`int` in range ``0 <= n <= 255`` + """ + return Flags.NONE | ((n & 0xFF) << 16) + + +_MAX_FLAG = reduce(operator.or_, Flags) + + +_FLAGS = { + "MATRIXINPUT": 1, + "MATRIXOUTPUT": 2, + "MATRIXONLY": (1 | 2), + "NOWHITEONWHITEFIXUP": 4, # Don't hot fix scum dot + # Don't create prelinearization tables on precalculated transforms + # (internal use): + "NOPRELINEARIZATION": 16, + "GUESSDEVICECLASS": 32, # Guess device class (for transform2devicelink) + "NOTCACHE": 64, # Inhibit 1-pixel cache + "NOTPRECALC": 256, + "NULLTRANSFORM": 512, # Don't transform anyway + "HIGHRESPRECALC": 1024, # Use more memory to give better accuracy + "LOWRESPRECALC": 2048, # Use less memory to minimize resources + "WHITEBLACKCOMPENSATION": 8192, + "BLACKPOINTCOMPENSATION": 8192, + "GAMUTCHECK": 4096, # Out of Gamut alarm + "SOFTPROOFING": 16384, # Do softproofing + "PRESERVEBLACK": 32768, # Black preservation + "NODEFAULTRESOURCEDEF": 16777216, # CRD special + "GRIDPOINTS": lambda n: (n & 0xFF) << 16, # Gridpoints +} + + +# --------------------------------------------------------------------. +# Experimental PIL-level API +# --------------------------------------------------------------------. + +## +# Profile. + + +class ImageCmsProfile: + def __init__(self, profile: str | SupportsRead[bytes] | core.CmsProfile) -> None: + """ + :param profile: Either a string representing a filename, + a file like object containing a profile or a + low-level profile object + + """ + + if isinstance(profile, str): + if sys.platform == "win32": + profile_bytes_path = profile.encode() + try: + profile_bytes_path.decode("ascii") + except UnicodeDecodeError: + with open(profile, "rb") as f: + self._set(core.profile_frombytes(f.read())) + return + self._set(core.profile_open(profile), profile) + elif hasattr(profile, "read"): + self._set(core.profile_frombytes(profile.read())) + elif isinstance(profile, core.CmsProfile): + self._set(profile) + else: + msg = "Invalid type for Profile" # type: ignore[unreachable] + raise TypeError(msg) + + def _set(self, profile: core.CmsProfile, filename: str | None = None) -> None: + self.profile = profile + self.filename = filename + self.product_name = None # profile.product_name + self.product_info = None # profile.product_info + + def tobytes(self) -> bytes: + """ + Returns the profile in a format suitable for embedding in + saved images. + + :returns: a bytes object containing the ICC profile. + """ + + return core.profile_tobytes(self.profile) + + +class ImageCmsTransform(Image.ImagePointHandler): + """ + Transform. This can be used with the procedural API, or with the standard + :py:func:`~PIL.Image.Image.point` method. + + Will return the output profile in the ``output.info['icc_profile']``. + """ + + def __init__( + self, + input: ImageCmsProfile, + output: ImageCmsProfile, + input_mode: str, + output_mode: str, + intent: Intent = Intent.PERCEPTUAL, + proof: ImageCmsProfile | None = None, + proof_intent: Intent = Intent.ABSOLUTE_COLORIMETRIC, + flags: Flags = Flags.NONE, + ): + supported_modes = ( + "RGB", + "RGBA", + "RGBX", + "CMYK", + "I;16", + "I;16L", + "I;16B", + "YCbCr", + "LAB", + "L", + "1", + ) + for mode in (input_mode, output_mode): + if mode not in supported_modes: + deprecate( + mode, + 12, + { + "L;16": "I;16 or I;16L", + "L:16B": "I;16B", + "YCCA": "YCbCr", + "YCC": "YCbCr", + }.get(mode), + ) + if proof is None: + self.transform = core.buildTransform( + input.profile, output.profile, input_mode, output_mode, intent, flags + ) + else: + self.transform = core.buildProofTransform( + input.profile, + output.profile, + proof.profile, + input_mode, + output_mode, + intent, + proof_intent, + flags, + ) + # Note: inputMode and outputMode are for pyCMS compatibility only + self.input_mode = self.inputMode = input_mode + self.output_mode = self.outputMode = output_mode + + self.output_profile = output + + def point(self, im: Image.Image) -> Image.Image: + return self.apply(im) + + def apply(self, im: Image.Image, imOut: Image.Image | None = None) -> Image.Image: + if imOut is None: + imOut = Image.new(self.output_mode, im.size, None) + self.transform.apply(im.getim(), imOut.getim()) + imOut.info["icc_profile"] = self.output_profile.tobytes() + return imOut + + def apply_in_place(self, im: Image.Image) -> Image.Image: + if im.mode != self.output_mode: + msg = "mode mismatch" + raise ValueError(msg) # wrong output mode + self.transform.apply(im.getim(), im.getim()) + im.info["icc_profile"] = self.output_profile.tobytes() + return im + + +def get_display_profile(handle: SupportsInt | None = None) -> ImageCmsProfile | None: + """ + (experimental) Fetches the profile for the current display device. + + :returns: ``None`` if the profile is not known. + """ + + if sys.platform != "win32": + return None + + from . import ImageWin # type: ignore[unused-ignore, unreachable] + + if isinstance(handle, ImageWin.HDC): + profile = core.get_display_profile_win32(int(handle), 1) + else: + profile = core.get_display_profile_win32(int(handle or 0)) + if profile is None: + return None + return ImageCmsProfile(profile) + + +# --------------------------------------------------------------------. +# pyCMS compatible layer +# --------------------------------------------------------------------. + + +class PyCMSError(Exception): + """(pyCMS) Exception class. + This is used for all errors in the pyCMS API.""" + + pass + + +def profileToProfile( + im: Image.Image, + inputProfile: _CmsProfileCompatible, + outputProfile: _CmsProfileCompatible, + renderingIntent: Intent = Intent.PERCEPTUAL, + outputMode: str | None = None, + inPlace: bool = False, + flags: Flags = Flags.NONE, +) -> Image.Image | None: + """ + (pyCMS) Applies an ICC transformation to a given image, mapping from + ``inputProfile`` to ``outputProfile``. + + If the input or output profiles specified are not valid filenames, a + :exc:`PyCMSError` will be raised. If ``inPlace`` is ``True`` and + ``outputMode != im.mode``, a :exc:`PyCMSError` will be raised. + If an error occurs during application of the profiles, + a :exc:`PyCMSError` will be raised. + If ``outputMode`` is not a mode supported by the ``outputProfile`` (or by pyCMS), + a :exc:`PyCMSError` will be raised. + + This function applies an ICC transformation to im from ``inputProfile``'s + color space to ``outputProfile``'s color space using the specified rendering + intent to decide how to handle out-of-gamut colors. + + ``outputMode`` can be used to specify that a color mode conversion is to + be done using these profiles, but the specified profiles must be able + to handle that mode. I.e., if converting im from RGB to CMYK using + profiles, the input profile must handle RGB data, and the output + profile must handle CMYK data. + + :param im: An open :py:class:`~PIL.Image.Image` object (i.e. Image.new(...) + or Image.open(...), etc.) + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this image, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + profile you wish to use for this image, or a profile object + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param outputMode: A valid PIL mode for the output image (i.e. "RGB", + "CMYK", etc.). Note: if rendering the image "inPlace", outputMode + MUST be the same mode as the input, or omitted completely. If + omitted, the outputMode will be the same as the mode of the input + image (im.mode) + :param inPlace: Boolean. If ``True``, the original image is modified in-place, + and ``None`` is returned. If ``False`` (default), a new + :py:class:`~PIL.Image.Image` object is returned with the transform applied. + :param flags: Integer (0-...) specifying additional flags + :returns: Either None or a new :py:class:`~PIL.Image.Image` object, depending on + the value of ``inPlace`` + :exception PyCMSError: + """ + + if outputMode is None: + outputMode = im.mode + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = f"flags must be an integer between 0 and {_MAX_FLAG}" + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + transform = ImageCmsTransform( + inputProfile, + outputProfile, + im.mode, + outputMode, + renderingIntent, + flags=flags, + ) + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + return imOut + + +def getOpenProfile( + profileFilename: str | SupportsRead[bytes] | core.CmsProfile, +) -> ImageCmsProfile: + """ + (pyCMS) Opens an ICC profile file. + + The PyCMSProfile object can be passed back into pyCMS for use in creating + transforms and such (as in ImageCms.buildTransformFromOpenProfiles()). + + If ``profileFilename`` is not a valid filename for an ICC profile, + a :exc:`PyCMSError` will be raised. + + :param profileFilename: String, as a valid filename path to the ICC profile + you wish to open, or a file-like object. + :returns: A CmsProfile class object. + :exception PyCMSError: + """ + + try: + return ImageCmsProfile(profileFilename) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def buildTransform( + inputProfile: _CmsProfileCompatible, + outputProfile: _CmsProfileCompatible, + inMode: str, + outMode: str, + renderingIntent: Intent = Intent.PERCEPTUAL, + flags: Flags = Flags.NONE, +) -> ImageCmsTransform: + """ + (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the + ``outputProfile``. Use applyTransform to apply the transform to a given + image. + + If the input or output profiles specified are not valid filenames, a + :exc:`PyCMSError` will be raised. If an error occurs during creation + of the transform, a :exc:`PyCMSError` will be raised. + + If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` + (or by pyCMS), a :exc:`PyCMSError` will be raised. + + This function builds and returns an ICC transform from the ``inputProfile`` + to the ``outputProfile`` using the ``renderingIntent`` to determine what to do + with out-of-gamut colors. It will ONLY work for converting images that + are in ``inMode`` to images that are in ``outMode`` color format (PIL mode, + i.e. "RGB", "RGBA", "CMYK", etc.). + + Building the transform is a fair part of the overhead in + ImageCms.profileToProfile(), so if you're planning on converting multiple + images using the same input/output settings, this can save you time. + Once you have a transform object, it can be used with + ImageCms.applyProfile() to convert images without the need to re-compute + the lookup table for the transform. + + The reason pyCMS returns a class object rather than a handle directly + to the transform is that it needs to keep track of the PIL input/output + modes that the transform is meant for. These attributes are stored in + the ``inMode`` and ``outMode`` attributes of the object (which can be + manually overridden if you really want to, but I don't know of any + time that would be of use, or would even work). + + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + profile you wish to use for this transform, or a profile object + :param inMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param outMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param flags: Integer (0-...) specifying additional flags + :returns: A CmsTransform class object. + :exception PyCMSError: + """ + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = f"flags must be an integer between 0 and {_MAX_FLAG}" + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + return ImageCmsTransform( + inputProfile, outputProfile, inMode, outMode, renderingIntent, flags=flags + ) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def buildProofTransform( + inputProfile: _CmsProfileCompatible, + outputProfile: _CmsProfileCompatible, + proofProfile: _CmsProfileCompatible, + inMode: str, + outMode: str, + renderingIntent: Intent = Intent.PERCEPTUAL, + proofRenderingIntent: Intent = Intent.ABSOLUTE_COLORIMETRIC, + flags: Flags = Flags.SOFTPROOFING, +) -> ImageCmsTransform: + """ + (pyCMS) Builds an ICC transform mapping from the ``inputProfile`` to the + ``outputProfile``, but tries to simulate the result that would be + obtained on the ``proofProfile`` device. + + If the input, output, or proof profiles specified are not valid + filenames, a :exc:`PyCMSError` will be raised. + + If an error occurs during creation of the transform, + a :exc:`PyCMSError` will be raised. + + If ``inMode`` or ``outMode`` are not a mode supported by the ``outputProfile`` + (or by pyCMS), a :exc:`PyCMSError` will be raised. + + This function builds and returns an ICC transform from the ``inputProfile`` + to the ``outputProfile``, but tries to simulate the result that would be + obtained on the ``proofProfile`` device using ``renderingIntent`` and + ``proofRenderingIntent`` to determine what to do with out-of-gamut + colors. This is known as "soft-proofing". It will ONLY work for + converting images that are in ``inMode`` to images that are in outMode + color format (PIL mode, i.e. "RGB", "RGBA", "CMYK", etc.). + + Usage of the resulting transform object is exactly the same as with + ImageCms.buildTransform(). + + Proof profiling is generally used when using an output device to get a + good idea of what the final printed/displayed image would look like on + the ``proofProfile`` device when it's quicker and easier to use the + output device for judging color. Generally, this means that the + output device is a monitor, or a dye-sub printer (etc.), and the simulated + device is something more expensive, complicated, or time consuming + (making it difficult to make a real print for color judgement purposes). + + Soft-proofing basically functions by adjusting the colors on the + output device to match the colors of the device being simulated. However, + when the simulated device has a much wider gamut than the output + device, you may obtain marginal results. + + :param inputProfile: String, as a valid filename path to the ICC input + profile you wish to use for this transform, or a profile object + :param outputProfile: String, as a valid filename path to the ICC output + (monitor, usually) profile you wish to use for this transform, or a + profile object + :param proofProfile: String, as a valid filename path to the ICC proof + profile you wish to use for this transform, or a profile object + :param inMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param outMode: String, as a valid PIL mode that the appropriate profile + also supports (i.e. "RGB", "RGBA", "CMYK", etc.) + :param renderingIntent: Integer (0-3) specifying the rendering intent you + wish to use for the input->proof (simulated) transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param proofRenderingIntent: Integer (0-3) specifying the rendering intent + you wish to use for proof->output transform + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param flags: Integer (0-...) specifying additional flags + :returns: A CmsTransform class object. + :exception PyCMSError: + """ + + if not isinstance(renderingIntent, int) or not (0 <= renderingIntent <= 3): + msg = "renderingIntent must be an integer between 0 and 3" + raise PyCMSError(msg) + + if not isinstance(flags, int) or not (0 <= flags <= _MAX_FLAG): + msg = f"flags must be an integer between 0 and {_MAX_FLAG}" + raise PyCMSError(msg) + + try: + if not isinstance(inputProfile, ImageCmsProfile): + inputProfile = ImageCmsProfile(inputProfile) + if not isinstance(outputProfile, ImageCmsProfile): + outputProfile = ImageCmsProfile(outputProfile) + if not isinstance(proofProfile, ImageCmsProfile): + proofProfile = ImageCmsProfile(proofProfile) + return ImageCmsTransform( + inputProfile, + outputProfile, + inMode, + outMode, + renderingIntent, + proofProfile, + proofRenderingIntent, + flags, + ) + except (OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +buildTransformFromOpenProfiles = buildTransform +buildProofTransformFromOpenProfiles = buildProofTransform + + +def applyTransform( + im: Image.Image, transform: ImageCmsTransform, inPlace: bool = False +) -> Image.Image | None: + """ + (pyCMS) Applies a transform to a given image. + + If ``im.mode != transform.input_mode``, a :exc:`PyCMSError` is raised. + + If ``inPlace`` is ``True`` and ``transform.input_mode != transform.output_mode``, a + :exc:`PyCMSError` is raised. + + If ``im.mode``, ``transform.input_mode`` or ``transform.output_mode`` is not + supported by pyCMSdll or the profiles you used for the transform, a + :exc:`PyCMSError` is raised. + + If an error occurs while the transform is being applied, + a :exc:`PyCMSError` is raised. + + This function applies a pre-calculated transform (from + ImageCms.buildTransform() or ImageCms.buildTransformFromOpenProfiles()) + to an image. The transform can be used for multiple images, saving + considerable calculation time if doing the same conversion multiple times. + + If you want to modify im in-place instead of receiving a new image as + the return value, set ``inPlace`` to ``True``. This can only be done if + ``transform.input_mode`` and ``transform.output_mode`` are the same, because we + can't change the mode in-place (the buffer sizes for some modes are + different). The default behavior is to return a new :py:class:`~PIL.Image.Image` + object of the same dimensions in mode ``transform.output_mode``. + + :param im: An :py:class:`~PIL.Image.Image` object, and ``im.mode`` must be the same + as the ``input_mode`` supported by the transform. + :param transform: A valid CmsTransform class object + :param inPlace: Bool. If ``True``, ``im`` is modified in place and ``None`` is + returned, if ``False``, a new :py:class:`~PIL.Image.Image` object with the + transform applied is returned (and ``im`` is not changed). The default is + ``False``. + :returns: Either ``None``, or a new :py:class:`~PIL.Image.Image` object, + depending on the value of ``inPlace``. The profile will be returned in + the image's ``info['icc_profile']``. + :exception PyCMSError: + """ + + try: + if inPlace: + transform.apply_in_place(im) + imOut = None + else: + imOut = transform.apply(im) + except (TypeError, ValueError) as v: + raise PyCMSError(v) from v + + return imOut + + +def createProfile( + colorSpace: Literal["LAB", "XYZ", "sRGB"], colorTemp: SupportsFloat = 0 +) -> core.CmsProfile: + """ + (pyCMS) Creates a profile. + + If colorSpace not in ``["LAB", "XYZ", "sRGB"]``, + a :exc:`PyCMSError` is raised. + + If using LAB and ``colorTemp`` is not a positive integer, + a :exc:`PyCMSError` is raised. + + If an error occurs while creating the profile, + a :exc:`PyCMSError` is raised. + + Use this function to create common profiles on-the-fly instead of + having to supply a profile on disk and knowing the path to it. It + returns a normal CmsProfile object that can be passed to + ImageCms.buildTransformFromOpenProfiles() to create a transform to apply + to images. + + :param colorSpace: String, the color space of the profile you wish to + create. + Currently only "LAB", "XYZ", and "sRGB" are supported. + :param colorTemp: Positive number for the white point for the profile, in + degrees Kelvin (i.e. 5000, 6500, 9600, etc.). The default is for D50 + illuminant if omitted (5000k). colorTemp is ONLY applied to LAB + profiles, and is ignored for XYZ and sRGB. + :returns: A CmsProfile class object + :exception PyCMSError: + """ + + if colorSpace not in ["LAB", "XYZ", "sRGB"]: + msg = ( + f"Color space not supported for on-the-fly profile creation ({colorSpace})" + ) + raise PyCMSError(msg) + + if colorSpace == "LAB": + try: + colorTemp = float(colorTemp) + except (TypeError, ValueError) as e: + msg = f'Color temperature must be numeric, "{colorTemp}" not valid' + raise PyCMSError(msg) from e + + try: + return core.createProfile(colorSpace, colorTemp) + except (TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileName(profile: _CmsProfileCompatible) -> str: + """ + + (pyCMS) Gets the internal product name for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, + a :exc:`PyCMSError` is raised If an error occurs while trying + to obtain the name tag, a :exc:`PyCMSError` is raised. + + Use this function to obtain the INTERNAL name of the profile (stored + in an ICC tag in the profile itself), usually the one used when the + profile was originally created. Sometimes this tag also contains + additional information supplied by the creator. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal name of the profile as stored + in an ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # do it in python, not c. + # // name was "%s - %s" (model, manufacturer) || Description , + # // but if the Model and Manufacturer were the same or the model + # // was long, Just the model, in 1.x + model = profile.profile.model + manufacturer = profile.profile.manufacturer + + if not (model or manufacturer): + return (profile.profile.profile_description or "") + "\n" + if not manufacturer or (model and len(model) > 30): + return f"{model}\n" + return f"{model} - {manufacturer}\n" + + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileInfo(profile: _CmsProfileCompatible) -> str: + """ + (pyCMS) Gets the internal product information for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, + a :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the info tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + info tag. This often contains details about the profile, and how it + was created, as supplied by the creator. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # add an extra newline to preserve pyCMS compatibility + # Python, not C. the white point bits weren't working well, + # so skipping. + # info was description \r\n\r\n copyright \r\n\r\n K007 tag \r\n\r\n whitepoint + description = profile.profile.profile_description + cpright = profile.profile.copyright + elements = [element for element in (description, cpright) if element] + return "\r\n\r\n".join(elements) + "\r\n\r\n" + + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileCopyright(profile: _CmsProfileCompatible) -> str: + """ + (pyCMS) Gets the copyright for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the copyright tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + copyright tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.copyright or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileManufacturer(profile: _CmsProfileCompatible) -> str: + """ + (pyCMS) Gets the manufacturer for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the manufacturer tag, a + :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + manufacturer tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.manufacturer or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileModel(profile: _CmsProfileCompatible) -> str: + """ + (pyCMS) Gets the model for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the model tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + model tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in + an ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.model or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getProfileDescription(profile: _CmsProfileCompatible) -> str: + """ + (pyCMS) Gets the description for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the description tag, + a :exc:`PyCMSError` is raised. + + Use this function to obtain the information stored in the profile's + description tag. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: A string containing the internal profile information stored in an + ICC tag. + :exception PyCMSError: + """ + + try: + # add an extra newline to preserve pyCMS compatibility + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return (profile.profile.profile_description or "") + "\n" + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def getDefaultIntent(profile: _CmsProfileCompatible) -> int: + """ + (pyCMS) Gets the default intent name for the given profile. + + If ``profile`` isn't a valid CmsProfile object or filename to a profile, a + :exc:`PyCMSError` is raised. + + If an error occurs while trying to obtain the default intent, a + :exc:`PyCMSError` is raised. + + Use this function to determine the default (and usually best optimized) + rendering intent for this profile. Most profiles support multiple + rendering intents, but are intended mostly for one type of conversion. + If you wish to use a different intent than returned, use + ImageCms.isIntentSupported() to verify it will work first. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :returns: Integer 0-3 specifying the default rendering intent for this + profile. + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + return profile.profile.rendering_intent + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def isIntentSupported( + profile: _CmsProfileCompatible, intent: Intent, direction: Direction +) -> Literal[-1, 1]: + """ + (pyCMS) Checks if a given intent is supported. + + Use this function to verify that you can use your desired + ``intent`` with ``profile``, and that ``profile`` can be used for the + input/output/proof profile as you desire. + + Some profiles are created specifically for one "direction", can cannot + be used for others. Some profiles can only be used for certain + rendering intents, so it's best to either verify this before trying + to create a transform with them (using this function), or catch the + potential :exc:`PyCMSError` that will occur if they don't + support the modes you select. + + :param profile: EITHER a valid CmsProfile object, OR a string of the + filename of an ICC profile. + :param intent: Integer (0-3) specifying the rendering intent you wish to + use with this profile + + ImageCms.Intent.PERCEPTUAL = 0 (DEFAULT) + ImageCms.Intent.RELATIVE_COLORIMETRIC = 1 + ImageCms.Intent.SATURATION = 2 + ImageCms.Intent.ABSOLUTE_COLORIMETRIC = 3 + + see the pyCMS documentation for details on rendering intents and what + they do. + :param direction: Integer specifying if the profile is to be used for + input, output, or proof + + INPUT = 0 (or use ImageCms.Direction.INPUT) + OUTPUT = 1 (or use ImageCms.Direction.OUTPUT) + PROOF = 2 (or use ImageCms.Direction.PROOF) + + :returns: 1 if the intent/direction are supported, -1 if they are not. + :exception PyCMSError: + """ + + try: + if not isinstance(profile, ImageCmsProfile): + profile = ImageCmsProfile(profile) + # FIXME: I get different results for the same data w. different + # compilers. Bug in LittleCMS or in the binding? + if profile.profile.is_intent_supported(intent, direction): + return 1 + else: + return -1 + except (AttributeError, OSError, TypeError, ValueError) as v: + raise PyCMSError(v) from v + + +def versions() -> tuple[str, str | None, str, str]: + """ + (pyCMS) Fetches versions. + """ + + deprecate( + "PIL.ImageCms.versions()", + 12, + '(PIL.features.version("littlecms2"), sys.version, PIL.__version__)', + ) + return _VERSION, core.littlecms_version, sys.version.split()[0], __version__ diff --git a/venv/lib/python3.12/site-packages/PIL/ImageColor.py b/venv/lib/python3.12/site-packages/PIL/ImageColor.py new file mode 100644 index 0000000..9a15a8e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageColor.py @@ -0,0 +1,320 @@ +# +# The Python Imaging Library +# $Id$ +# +# map CSS3-style colour description strings to RGB +# +# History: +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-15 fl Added RGBA support +# 2004-03-27 fl Fixed remaining int() problems for Python 1.5.2 +# 2004-07-19 fl Fixed gray/grey spelling issues +# 2009-03-05 fl Fixed rounding error in grayscale calculation +# +# Copyright (c) 2002-2004 by Secret Labs AB +# Copyright (c) 2002-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re +from functools import lru_cache + +from . import Image + + +@lru_cache +def getrgb(color: str) -> tuple[int, int, int] | tuple[int, int, int, int]: + """ + Convert a color string to an RGB or RGBA tuple. If the string cannot be + parsed, this function raises a :py:exc:`ValueError` exception. + + .. versionadded:: 1.1.4 + + :param color: A color string + :return: ``(red, green, blue[, alpha])`` + """ + if len(color) > 100: + msg = "color specifier is too long" + raise ValueError(msg) + color = color.lower() + + rgb = colormap.get(color, None) + if rgb: + if isinstance(rgb, tuple): + return rgb + rgb_tuple = getrgb(rgb) + assert len(rgb_tuple) == 3 + colormap[color] = rgb_tuple + return rgb_tuple + + # check for known string formats + if re.match("#[a-f0-9]{3}$", color): + return int(color[1] * 2, 16), int(color[2] * 2, 16), int(color[3] * 2, 16) + + if re.match("#[a-f0-9]{4}$", color): + return ( + int(color[1] * 2, 16), + int(color[2] * 2, 16), + int(color[3] * 2, 16), + int(color[4] * 2, 16), + ) + + if re.match("#[a-f0-9]{6}$", color): + return int(color[1:3], 16), int(color[3:5], 16), int(color[5:7], 16) + + if re.match("#[a-f0-9]{8}$", color): + return ( + int(color[1:3], 16), + int(color[3:5], 16), + int(color[5:7], 16), + int(color[7:9], 16), + ) + + m = re.match(r"rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) + if m: + return int(m.group(1)), int(m.group(2)), int(m.group(3)) + + m = re.match(r"rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)$", color) + if m: + return ( + int((int(m.group(1)) * 255) / 100.0 + 0.5), + int((int(m.group(2)) * 255) / 100.0 + 0.5), + int((int(m.group(3)) * 255) / 100.0 + 0.5), + ) + + m = re.match( + r"hsl\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color + ) + if m: + from colorsys import hls_to_rgb + + rgb_floats = hls_to_rgb( + float(m.group(1)) / 360.0, + float(m.group(3)) / 100.0, + float(m.group(2)) / 100.0, + ) + return ( + int(rgb_floats[0] * 255 + 0.5), + int(rgb_floats[1] * 255 + 0.5), + int(rgb_floats[2] * 255 + 0.5), + ) + + m = re.match( + r"hs[bv]\(\s*(\d+\.?\d*)\s*,\s*(\d+\.?\d*)%\s*,\s*(\d+\.?\d*)%\s*\)$", color + ) + if m: + from colorsys import hsv_to_rgb + + rgb_floats = hsv_to_rgb( + float(m.group(1)) / 360.0, + float(m.group(2)) / 100.0, + float(m.group(3)) / 100.0, + ) + return ( + int(rgb_floats[0] * 255 + 0.5), + int(rgb_floats[1] * 255 + 0.5), + int(rgb_floats[2] * 255 + 0.5), + ) + + m = re.match(r"rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$", color) + if m: + return int(m.group(1)), int(m.group(2)), int(m.group(3)), int(m.group(4)) + msg = f"unknown color specifier: {repr(color)}" + raise ValueError(msg) + + +@lru_cache +def getcolor(color: str, mode: str) -> int | tuple[int, ...]: + """ + Same as :py:func:`~PIL.ImageColor.getrgb` for most modes. However, if + ``mode`` is HSV, converts the RGB value to a HSV value, or if ``mode`` is + not color or a palette image, converts the RGB value to a grayscale value. + If the string cannot be parsed, this function raises a :py:exc:`ValueError` + exception. + + .. versionadded:: 1.1.4 + + :param color: A color string + :param mode: Convert result to this mode + :return: ``graylevel, (graylevel, alpha) or (red, green, blue[, alpha])`` + """ + # same as getrgb, but converts the result to the given mode + rgb, alpha = getrgb(color), 255 + if len(rgb) == 4: + alpha = rgb[3] + rgb = rgb[:3] + + if mode == "HSV": + from colorsys import rgb_to_hsv + + r, g, b = rgb + h, s, v = rgb_to_hsv(r / 255, g / 255, b / 255) + return int(h * 255), int(s * 255), int(v * 255) + elif Image.getmodebase(mode) == "L": + r, g, b = rgb + # ITU-R Recommendation 601-2 for nonlinear RGB + # scaled to 24 bits to match the convert's implementation. + graylevel = (r * 19595 + g * 38470 + b * 7471 + 0x8000) >> 16 + if mode[-1] == "A": + return graylevel, alpha + return graylevel + elif mode[-1] == "A": + return rgb + (alpha,) + return rgb + + +colormap: dict[str, str | tuple[int, int, int]] = { + # X11 colour table from https://drafts.csswg.org/css-color-4/, with + # gray/grey spelling issues fixed. This is a superset of HTML 4.0 + # colour names used in CSS 1. + "aliceblue": "#f0f8ff", + "antiquewhite": "#faebd7", + "aqua": "#00ffff", + "aquamarine": "#7fffd4", + "azure": "#f0ffff", + "beige": "#f5f5dc", + "bisque": "#ffe4c4", + "black": "#000000", + "blanchedalmond": "#ffebcd", + "blue": "#0000ff", + "blueviolet": "#8a2be2", + "brown": "#a52a2a", + "burlywood": "#deb887", + "cadetblue": "#5f9ea0", + "chartreuse": "#7fff00", + "chocolate": "#d2691e", + "coral": "#ff7f50", + "cornflowerblue": "#6495ed", + "cornsilk": "#fff8dc", + "crimson": "#dc143c", + "cyan": "#00ffff", + "darkblue": "#00008b", + "darkcyan": "#008b8b", + "darkgoldenrod": "#b8860b", + "darkgray": "#a9a9a9", + "darkgrey": "#a9a9a9", + "darkgreen": "#006400", + "darkkhaki": "#bdb76b", + "darkmagenta": "#8b008b", + "darkolivegreen": "#556b2f", + "darkorange": "#ff8c00", + "darkorchid": "#9932cc", + "darkred": "#8b0000", + "darksalmon": "#e9967a", + "darkseagreen": "#8fbc8f", + "darkslateblue": "#483d8b", + "darkslategray": "#2f4f4f", + "darkslategrey": "#2f4f4f", + "darkturquoise": "#00ced1", + "darkviolet": "#9400d3", + "deeppink": "#ff1493", + "deepskyblue": "#00bfff", + "dimgray": "#696969", + "dimgrey": "#696969", + "dodgerblue": "#1e90ff", + "firebrick": "#b22222", + "floralwhite": "#fffaf0", + "forestgreen": "#228b22", + "fuchsia": "#ff00ff", + "gainsboro": "#dcdcdc", + "ghostwhite": "#f8f8ff", + "gold": "#ffd700", + "goldenrod": "#daa520", + "gray": "#808080", + "grey": "#808080", + "green": "#008000", + "greenyellow": "#adff2f", + "honeydew": "#f0fff0", + "hotpink": "#ff69b4", + "indianred": "#cd5c5c", + "indigo": "#4b0082", + "ivory": "#fffff0", + "khaki": "#f0e68c", + "lavender": "#e6e6fa", + "lavenderblush": "#fff0f5", + "lawngreen": "#7cfc00", + "lemonchiffon": "#fffacd", + "lightblue": "#add8e6", + "lightcoral": "#f08080", + "lightcyan": "#e0ffff", + "lightgoldenrodyellow": "#fafad2", + "lightgreen": "#90ee90", + "lightgray": "#d3d3d3", + "lightgrey": "#d3d3d3", + "lightpink": "#ffb6c1", + "lightsalmon": "#ffa07a", + "lightseagreen": "#20b2aa", + "lightskyblue": "#87cefa", + "lightslategray": "#778899", + "lightslategrey": "#778899", + "lightsteelblue": "#b0c4de", + "lightyellow": "#ffffe0", + "lime": "#00ff00", + "limegreen": "#32cd32", + "linen": "#faf0e6", + "magenta": "#ff00ff", + "maroon": "#800000", + "mediumaquamarine": "#66cdaa", + "mediumblue": "#0000cd", + "mediumorchid": "#ba55d3", + "mediumpurple": "#9370db", + "mediumseagreen": "#3cb371", + "mediumslateblue": "#7b68ee", + "mediumspringgreen": "#00fa9a", + "mediumturquoise": "#48d1cc", + "mediumvioletred": "#c71585", + "midnightblue": "#191970", + "mintcream": "#f5fffa", + "mistyrose": "#ffe4e1", + "moccasin": "#ffe4b5", + "navajowhite": "#ffdead", + "navy": "#000080", + "oldlace": "#fdf5e6", + "olive": "#808000", + "olivedrab": "#6b8e23", + "orange": "#ffa500", + "orangered": "#ff4500", + "orchid": "#da70d6", + "palegoldenrod": "#eee8aa", + "palegreen": "#98fb98", + "paleturquoise": "#afeeee", + "palevioletred": "#db7093", + "papayawhip": "#ffefd5", + "peachpuff": "#ffdab9", + "peru": "#cd853f", + "pink": "#ffc0cb", + "plum": "#dda0dd", + "powderblue": "#b0e0e6", + "purple": "#800080", + "rebeccapurple": "#663399", + "red": "#ff0000", + "rosybrown": "#bc8f8f", + "royalblue": "#4169e1", + "saddlebrown": "#8b4513", + "salmon": "#fa8072", + "sandybrown": "#f4a460", + "seagreen": "#2e8b57", + "seashell": "#fff5ee", + "sienna": "#a0522d", + "silver": "#c0c0c0", + "skyblue": "#87ceeb", + "slateblue": "#6a5acd", + "slategray": "#708090", + "slategrey": "#708090", + "snow": "#fffafa", + "springgreen": "#00ff7f", + "steelblue": "#4682b4", + "tan": "#d2b48c", + "teal": "#008080", + "thistle": "#d8bfd8", + "tomato": "#ff6347", + "turquoise": "#40e0d0", + "violet": "#ee82ee", + "wheat": "#f5deb3", + "white": "#ffffff", + "whitesmoke": "#f5f5f5", + "yellow": "#ffff00", + "yellowgreen": "#9acd32", +} diff --git a/venv/lib/python3.12/site-packages/PIL/ImageDraw.py b/venv/lib/python3.12/site-packages/PIL/ImageDraw.py new file mode 100644 index 0000000..d8e4c0c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageDraw.py @@ -0,0 +1,1218 @@ +# +# The Python Imaging Library +# $Id$ +# +# drawing interface operations +# +# History: +# 1996-04-13 fl Created (experimental) +# 1996-08-07 fl Filled polygons, ellipses. +# 1996-08-13 fl Added text support +# 1998-06-28 fl Handle I and F images +# 1998-12-29 fl Added arc; use arc primitive to draw ellipses +# 1999-01-10 fl Added shape stuff (experimental) +# 1999-02-06 fl Added bitmap support +# 1999-02-11 fl Changed all primitives to take options +# 1999-02-20 fl Fixed backwards compatibility +# 2000-10-12 fl Copy on write, when necessary +# 2001-02-18 fl Use default ink for bitmap/text also in fill mode +# 2002-10-24 fl Added support for CSS-style color strings +# 2002-12-10 fl Added experimental support for RGBA-on-RGB drawing +# 2002-12-11 fl Refactored low-level drawing API (work in progress) +# 2004-08-26 fl Made Draw() a factory function, added getdraw() support +# 2004-09-04 fl Added width support to line primitive +# 2004-09-10 fl Added font mode handling +# 2006-06-19 fl Added font bearing support (getmask2) +# +# Copyright (c) 1997-2006 by Secret Labs AB +# Copyright (c) 1996-2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math +import struct +from collections.abc import Sequence +from types import ModuleType +from typing import TYPE_CHECKING, Any, AnyStr, Callable, Union, cast + +from . import Image, ImageColor +from ._deprecate import deprecate +from ._typing import Coords + +# experimental access to the outline API +Outline: Callable[[], Image.core._Outline] | None +try: + Outline = Image.core.outline +except AttributeError: + Outline = None + +if TYPE_CHECKING: + from . import ImageDraw2, ImageFont + +_Ink = Union[float, tuple[int, ...], str] + +""" +A simple 2D drawing interface for PIL images. +

+Application code should use the Draw factory, instead of +directly. +""" + + +class ImageDraw: + font: ( + ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont | None + ) = None + + def __init__(self, im: Image.Image, mode: str | None = None) -> None: + """ + Create a drawing instance. + + :param im: The image to draw in. + :param mode: Optional mode to use for color values. For RGB + images, this argument can be RGB or RGBA (to blend the + drawing into the image). For all other modes, this argument + must be the same as the image mode. If omitted, the mode + defaults to the mode of the image. + """ + im.load() + if im.readonly: + im._copy() # make it writeable + blend = 0 + if mode is None: + mode = im.mode + if mode != im.mode: + if mode == "RGBA" and im.mode == "RGB": + blend = 1 + else: + msg = "mode mismatch" + raise ValueError(msg) + if mode == "P": + self.palette = im.palette + else: + self.palette = None + self._image = im + self.im = im.im + self.draw = Image.core.draw(self.im, blend) + self.mode = mode + if mode in ("I", "F"): + self.ink = self.draw.draw_ink(1) + else: + self.ink = self.draw.draw_ink(-1) + if mode in ("1", "P", "I", "F"): + # FIXME: fix Fill2 to properly support matte for I+F images + self.fontmode = "1" + else: + self.fontmode = "L" # aliasing is okay for other modes + self.fill = False + + def getfont( + self, + ) -> ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont: + """ + Get the current default font. + + To set the default font for this ImageDraw instance:: + + from PIL import ImageDraw, ImageFont + draw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + + To set the default font for all future ImageDraw instances:: + + from PIL import ImageDraw, ImageFont + ImageDraw.ImageDraw.font = ImageFont.truetype("Tests/fonts/FreeMono.ttf") + + If the current default font is ``None``, + it is initialized with ``ImageFont.load_default()``. + + :returns: An image font.""" + if not self.font: + # FIXME: should add a font repository + from . import ImageFont + + self.font = ImageFont.load_default() + return self.font + + def _getfont( + self, font_size: float | None + ) -> ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont: + if font_size is not None: + from . import ImageFont + + return ImageFont.load_default(font_size) + else: + return self.getfont() + + def _getink( + self, ink: _Ink | None, fill: _Ink | None = None + ) -> tuple[int | None, int | None]: + result_ink = None + result_fill = None + if ink is None and fill is None: + if self.fill: + result_fill = self.ink + else: + result_ink = self.ink + else: + if ink is not None: + if isinstance(ink, str): + ink = ImageColor.getcolor(ink, self.mode) + if self.palette and isinstance(ink, tuple): + ink = self.palette.getcolor(ink, self._image) + result_ink = self.draw.draw_ink(ink) + if fill is not None: + if isinstance(fill, str): + fill = ImageColor.getcolor(fill, self.mode) + if self.palette and isinstance(fill, tuple): + fill = self.palette.getcolor(fill, self._image) + result_fill = self.draw.draw_ink(fill) + return result_ink, result_fill + + def arc( + self, + xy: Coords, + start: float, + end: float, + fill: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw an arc.""" + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_arc(xy, start, end, ink, width) + + def bitmap( + self, xy: Sequence[int], bitmap: Image.Image, fill: _Ink | None = None + ) -> None: + """Draw a bitmap.""" + bitmap.load() + ink, fill = self._getink(fill) + if ink is None: + ink = fill + if ink is not None: + self.draw.draw_bitmap(xy, bitmap.im, ink) + + def chord( + self, + xy: Coords, + start: float, + end: float, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a chord.""" + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_chord(xy, start, end, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + self.draw.draw_chord(xy, start, end, ink, 0, width) + + def ellipse( + self, + xy: Coords, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw an ellipse.""" + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_ellipse(xy, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + self.draw.draw_ellipse(xy, ink, 0, width) + + def circle( + self, + xy: Sequence[float], + radius: float, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a circle given center coordinates and a radius.""" + ellipse_xy = (xy[0] - radius, xy[1] - radius, xy[0] + radius, xy[1] + radius) + self.ellipse(ellipse_xy, fill, outline, width) + + def line( + self, + xy: Coords, + fill: _Ink | None = None, + width: int = 0, + joint: str | None = None, + ) -> None: + """Draw a line, or a connected sequence of line segments.""" + ink = self._getink(fill)[0] + if ink is not None: + self.draw.draw_lines(xy, ink, width) + if joint == "curve" and width > 4: + points: Sequence[Sequence[float]] + if isinstance(xy[0], (list, tuple)): + points = cast(Sequence[Sequence[float]], xy) + else: + points = [ + cast(Sequence[float], tuple(xy[i : i + 2])) + for i in range(0, len(xy), 2) + ] + for i in range(1, len(points) - 1): + point = points[i] + angles = [ + math.degrees(math.atan2(end[0] - start[0], start[1] - end[1])) + % 360 + for start, end in ( + (points[i - 1], point), + (point, points[i + 1]), + ) + ] + if angles[0] == angles[1]: + # This is a straight line, so no joint is required + continue + + def coord_at_angle( + coord: Sequence[float], angle: float + ) -> tuple[float, ...]: + x, y = coord + angle -= 90 + distance = width / 2 - 1 + return tuple( + p + (math.floor(p_d) if p_d > 0 else math.ceil(p_d)) + for p, p_d in ( + (x, distance * math.cos(math.radians(angle))), + (y, distance * math.sin(math.radians(angle))), + ) + ) + + flipped = ( + angles[1] > angles[0] and angles[1] - 180 > angles[0] + ) or (angles[1] < angles[0] and angles[1] + 180 > angles[0]) + coords = [ + (point[0] - width / 2 + 1, point[1] - width / 2 + 1), + (point[0] + width / 2 - 1, point[1] + width / 2 - 1), + ] + if flipped: + start, end = (angles[1] + 90, angles[0] + 90) + else: + start, end = (angles[0] - 90, angles[1] - 90) + self.pieslice(coords, start - 90, end - 90, fill) + + if width > 8: + # Cover potential gaps between the line and the joint + if flipped: + gap_coords = [ + coord_at_angle(point, angles[0] + 90), + point, + coord_at_angle(point, angles[1] + 90), + ] + else: + gap_coords = [ + coord_at_angle(point, angles[0] - 90), + point, + coord_at_angle(point, angles[1] - 90), + ] + self.line(gap_coords, fill, width=3) + + def shape( + self, + shape: Image.core._Outline, + fill: _Ink | None = None, + outline: _Ink | None = None, + ) -> None: + """(Experimental) Draw a shape.""" + shape.close() + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_outline(shape, fill_ink, 1) + if ink is not None and ink != fill_ink: + self.draw.draw_outline(shape, ink, 0) + + def pieslice( + self, + xy: Coords, + start: float, + end: float, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a pieslice.""" + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_pieslice(xy, start, end, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + self.draw.draw_pieslice(xy, start, end, ink, 0, width) + + def point(self, xy: Coords, fill: _Ink | None = None) -> None: + """Draw one or more individual pixels.""" + ink, fill = self._getink(fill) + if ink is not None: + self.draw.draw_points(xy, ink) + + def polygon( + self, + xy: Coords, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a polygon.""" + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_polygon(xy, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + if width == 1: + self.draw.draw_polygon(xy, ink, 0, width) + elif self.im is not None: + # To avoid expanding the polygon outwards, + # use the fill as a mask + mask = Image.new("1", self.im.size) + mask_ink = self._getink(1)[0] + + fill_im = mask.copy() + draw = Draw(fill_im) + draw.draw.draw_polygon(xy, mask_ink, 1) + + ink_im = mask.copy() + draw = Draw(ink_im) + width = width * 2 - 1 + draw.draw.draw_polygon(xy, mask_ink, 0, width) + + mask.paste(ink_im, mask=fill_im) + + im = Image.new(self.mode, self.im.size) + draw = Draw(im) + draw.draw.draw_polygon(xy, ink, 0, width) + self.im.paste(im.im, (0, 0) + im.size, mask.im) + + def regular_polygon( + self, + bounding_circle: Sequence[Sequence[float] | float], + n_sides: int, + rotation: float = 0, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a regular polygon.""" + xy = _compute_regular_polygon_vertices(bounding_circle, n_sides, rotation) + self.polygon(xy, fill, outline, width) + + def rectangle( + self, + xy: Coords, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + ) -> None: + """Draw a rectangle.""" + ink, fill_ink = self._getink(outline, fill) + if fill_ink is not None: + self.draw.draw_rectangle(xy, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + self.draw.draw_rectangle(xy, ink, 0, width) + + def rounded_rectangle( + self, + xy: Coords, + radius: float = 0, + fill: _Ink | None = None, + outline: _Ink | None = None, + width: int = 1, + *, + corners: tuple[bool, bool, bool, bool] | None = None, + ) -> None: + """Draw a rounded rectangle.""" + if isinstance(xy[0], (list, tuple)): + (x0, y0), (x1, y1) = cast(Sequence[Sequence[float]], xy) + else: + x0, y0, x1, y1 = cast(Sequence[float], xy) + if x1 < x0: + msg = "x1 must be greater than or equal to x0" + raise ValueError(msg) + if y1 < y0: + msg = "y1 must be greater than or equal to y0" + raise ValueError(msg) + if corners is None: + corners = (True, True, True, True) + + d = radius * 2 + + x0 = round(x0) + y0 = round(y0) + x1 = round(x1) + y1 = round(y1) + full_x, full_y = False, False + if all(corners): + full_x = d >= x1 - x0 - 1 + if full_x: + # The two left and two right corners are joined + d = x1 - x0 + full_y = d >= y1 - y0 - 1 + if full_y: + # The two top and two bottom corners are joined + d = y1 - y0 + if full_x and full_y: + # If all corners are joined, that is a circle + return self.ellipse(xy, fill, outline, width) + + if d == 0 or not any(corners): + # If the corners have no curve, + # or there are no corners, + # that is a rectangle + return self.rectangle(xy, fill, outline, width) + + r = int(d // 2) + ink, fill_ink = self._getink(outline, fill) + + def draw_corners(pieslice: bool) -> None: + parts: tuple[tuple[tuple[float, float, float, float], int, int], ...] + if full_x: + # Draw top and bottom halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 180, 360), + ((x0, y1 - d, x0 + d, y1), 0, 180), + ) + elif full_y: + # Draw left and right halves + parts = ( + ((x0, y0, x0 + d, y0 + d), 90, 270), + ((x1 - d, y0, x1, y0 + d), 270, 90), + ) + else: + # Draw four separate corners + parts = tuple( + part + for i, part in enumerate( + ( + ((x0, y0, x0 + d, y0 + d), 180, 270), + ((x1 - d, y0, x1, y0 + d), 270, 360), + ((x1 - d, y1 - d, x1, y1), 0, 90), + ((x0, y1 - d, x0 + d, y1), 90, 180), + ) + ) + if corners[i] + ) + for part in parts: + if pieslice: + self.draw.draw_pieslice(*(part + (fill_ink, 1))) + else: + self.draw.draw_arc(*(part + (ink, width))) + + if fill_ink is not None: + draw_corners(True) + + if full_x: + self.draw.draw_rectangle((x0, y0 + r + 1, x1, y1 - r - 1), fill_ink, 1) + elif x1 - r - 1 > x0 + r + 1: + self.draw.draw_rectangle((x0 + r + 1, y0, x1 - r - 1, y1), fill_ink, 1) + if not full_x and not full_y: + left = [x0, y0, x0 + r, y1] + if corners[0]: + left[1] += r + 1 + if corners[3]: + left[3] -= r + 1 + self.draw.draw_rectangle(left, fill_ink, 1) + + right = [x1 - r, y0, x1, y1] + if corners[1]: + right[1] += r + 1 + if corners[2]: + right[3] -= r + 1 + self.draw.draw_rectangle(right, fill_ink, 1) + if ink is not None and ink != fill_ink and width != 0: + draw_corners(False) + + if not full_x: + top = [x0, y0, x1, y0 + width - 1] + if corners[0]: + top[0] += r + 1 + if corners[1]: + top[2] -= r + 1 + self.draw.draw_rectangle(top, ink, 1) + + bottom = [x0, y1 - width + 1, x1, y1] + if corners[3]: + bottom[0] += r + 1 + if corners[2]: + bottom[2] -= r + 1 + self.draw.draw_rectangle(bottom, ink, 1) + if not full_y: + left = [x0, y0, x0 + width - 1, y1] + if corners[0]: + left[1] += r + 1 + if corners[3]: + left[3] -= r + 1 + self.draw.draw_rectangle(left, ink, 1) + + right = [x1 - width + 1, y0, x1, y1] + if corners[1]: + right[1] += r + 1 + if corners[2]: + right[3] -= r + 1 + self.draw.draw_rectangle(right, ink, 1) + + def _multiline_check(self, text: AnyStr) -> bool: + split_character = "\n" if isinstance(text, str) else b"\n" + + return split_character in text + + def _multiline_split(self, text: AnyStr) -> list[AnyStr]: + return text.split("\n" if isinstance(text, str) else b"\n") + + def _multiline_spacing( + self, + font: ImageFont.ImageFont | ImageFont.FreeTypeFont | ImageFont.TransposedFont, + spacing: float, + stroke_width: float, + ) -> float: + return ( + self.textbbox((0, 0), "A", font, stroke_width=stroke_width)[3] + + stroke_width + + spacing + ) + + def text( + self, + xy: tuple[float, float], + text: AnyStr, + fill: _Ink | None = None, + font: ( + ImageFont.ImageFont + | ImageFont.FreeTypeFont + | ImageFont.TransposedFont + | None + ) = None, + anchor: str | None = None, + spacing: float = 4, + align: str = "left", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + stroke_fill: _Ink | None = None, + embedded_color: bool = False, + *args: Any, + **kwargs: Any, + ) -> None: + """Draw text.""" + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(kwargs.get("font_size")) + + if self._multiline_check(text): + return self.multiline_text( + xy, + text, + fill, + font, + anchor, + spacing, + align, + direction, + features, + language, + stroke_width, + stroke_fill, + embedded_color, + ) + + def getink(fill: _Ink | None) -> int: + ink, fill_ink = self._getink(fill) + if ink is None: + assert fill_ink is not None + return fill_ink + return ink + + def draw_text(ink: int, stroke_width: float = 0) -> None: + mode = self.fontmode + if stroke_width == 0 and embedded_color: + mode = "RGBA" + coord = [] + for i in range(2): + coord.append(int(xy[i])) + start = (math.modf(xy[0])[0], math.modf(xy[1])[0]) + try: + mask, offset = font.getmask2( # type: ignore[union-attr,misc] + text, + mode, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + anchor=anchor, + ink=ink, + start=start, + *args, + **kwargs, + ) + coord = [coord[0] + offset[0], coord[1] + offset[1]] + except AttributeError: + try: + mask = font.getmask( # type: ignore[misc] + text, + mode, + direction, + features, + language, + stroke_width, + anchor, + ink, + start=start, + *args, + **kwargs, + ) + except TypeError: + mask = font.getmask(text) + if mode == "RGBA": + # font.getmask2(mode="RGBA") returns color in RGB bands and mask in A + # extract mask and set text alpha + color, mask = mask, mask.getband(3) + ink_alpha = struct.pack("i", ink)[3] + color.fillband(3, ink_alpha) + x, y = coord + if self.im is not None: + self.im.paste( + color, (x, y, x + mask.size[0], y + mask.size[1]), mask + ) + else: + self.draw.draw_bitmap(coord, mask, ink) + + ink = getink(fill) + if ink is not None: + stroke_ink = None + if stroke_width: + stroke_ink = getink(stroke_fill) if stroke_fill is not None else ink + + if stroke_ink is not None: + # Draw stroked text + draw_text(stroke_ink, stroke_width) + + # Draw normal text + draw_text(ink, 0) + else: + # Only draw normal text + draw_text(ink) + + def multiline_text( + self, + xy: tuple[float, float], + text: AnyStr, + fill: _Ink | None = None, + font: ( + ImageFont.ImageFont + | ImageFont.FreeTypeFont + | ImageFont.TransposedFont + | None + ) = None, + anchor: str | None = None, + spacing: float = 4, + align: str = "left", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + stroke_fill: _Ink | None = None, + embedded_color: bool = False, + *, + font_size: float | None = None, + ) -> None: + if direction == "ttb": + msg = "ttb direction is unsupported for multiline text" + raise ValueError(msg) + + if anchor is None: + anchor = "la" + elif len(anchor) != 2: + msg = "anchor must be a 2 character string" + raise ValueError(msg) + elif anchor[1] in "tb": + msg = "anchor not supported for multiline text" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + widths = [] + max_width: float = 0 + lines = self._multiline_split(text) + line_spacing = self._multiline_spacing(font, spacing, stroke_width) + for line in lines: + line_width = self.textlength( + line, font, direction=direction, features=features, language=language + ) + widths.append(line_width) + max_width = max(max_width, line_width) + + top = xy[1] + if anchor[1] == "m": + top -= (len(lines) - 1) * line_spacing / 2.0 + elif anchor[1] == "d": + top -= (len(lines) - 1) * line_spacing + + for idx, line in enumerate(lines): + left = xy[0] + width_difference = max_width - widths[idx] + + # first align left by anchor + if anchor[0] == "m": + left -= width_difference / 2.0 + elif anchor[0] == "r": + left -= width_difference + + # then align by align parameter + if align == "left": + pass + elif align == "center": + left += width_difference / 2.0 + elif align == "right": + left += width_difference + else: + msg = 'align must be "left", "center" or "right"' + raise ValueError(msg) + + self.text( + (left, top), + line, + fill, + font, + anchor, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + stroke_fill=stroke_fill, + embedded_color=embedded_color, + ) + top += line_spacing + + def textlength( + self, + text: AnyStr, + font: ( + ImageFont.ImageFont + | ImageFont.FreeTypeFont + | ImageFont.TransposedFont + | None + ) = None, + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + embedded_color: bool = False, + *, + font_size: float | None = None, + ) -> float: + """Get the length of a given string, in pixels with 1/64 precision.""" + if self._multiline_check(text): + msg = "can't measure length of multiline text" + raise ValueError(msg) + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + mode = "RGBA" if embedded_color else self.fontmode + return font.getlength(text, mode, direction, features, language) + + def textbbox( + self, + xy: tuple[float, float], + text: AnyStr, + font: ( + ImageFont.ImageFont + | ImageFont.FreeTypeFont + | ImageFont.TransposedFont + | None + ) = None, + anchor: str | None = None, + spacing: float = 4, + align: str = "left", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + embedded_color: bool = False, + *, + font_size: float | None = None, + ) -> tuple[float, float, float, float]: + """Get the bounding box of a given string, in pixels.""" + if embedded_color and self.mode not in ("RGB", "RGBA"): + msg = "Embedded color supported only in RGB and RGBA modes" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + if self._multiline_check(text): + return self.multiline_textbbox( + xy, + text, + font, + anchor, + spacing, + align, + direction, + features, + language, + stroke_width, + embedded_color, + ) + + mode = "RGBA" if embedded_color else self.fontmode + bbox = font.getbbox( + text, mode, direction, features, language, stroke_width, anchor + ) + return bbox[0] + xy[0], bbox[1] + xy[1], bbox[2] + xy[0], bbox[3] + xy[1] + + def multiline_textbbox( + self, + xy: tuple[float, float], + text: AnyStr, + font: ( + ImageFont.ImageFont + | ImageFont.FreeTypeFont + | ImageFont.TransposedFont + | None + ) = None, + anchor: str | None = None, + spacing: float = 4, + align: str = "left", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + embedded_color: bool = False, + *, + font_size: float | None = None, + ) -> tuple[float, float, float, float]: + if direction == "ttb": + msg = "ttb direction is unsupported for multiline text" + raise ValueError(msg) + + if anchor is None: + anchor = "la" + elif len(anchor) != 2: + msg = "anchor must be a 2 character string" + raise ValueError(msg) + elif anchor[1] in "tb": + msg = "anchor not supported for multiline text" + raise ValueError(msg) + + if font is None: + font = self._getfont(font_size) + + widths = [] + max_width: float = 0 + lines = self._multiline_split(text) + line_spacing = self._multiline_spacing(font, spacing, stroke_width) + for line in lines: + line_width = self.textlength( + line, + font, + direction=direction, + features=features, + language=language, + embedded_color=embedded_color, + ) + widths.append(line_width) + max_width = max(max_width, line_width) + + top = xy[1] + if anchor[1] == "m": + top -= (len(lines) - 1) * line_spacing / 2.0 + elif anchor[1] == "d": + top -= (len(lines) - 1) * line_spacing + + bbox: tuple[float, float, float, float] | None = None + + for idx, line in enumerate(lines): + left = xy[0] + width_difference = max_width - widths[idx] + + # first align left by anchor + if anchor[0] == "m": + left -= width_difference / 2.0 + elif anchor[0] == "r": + left -= width_difference + + # then align by align parameter + if align == "left": + pass + elif align == "center": + left += width_difference / 2.0 + elif align == "right": + left += width_difference + else: + msg = 'align must be "left", "center" or "right"' + raise ValueError(msg) + + bbox_line = self.textbbox( + (left, top), + line, + font, + anchor, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + embedded_color=embedded_color, + ) + if bbox is None: + bbox = bbox_line + else: + bbox = ( + min(bbox[0], bbox_line[0]), + min(bbox[1], bbox_line[1]), + max(bbox[2], bbox_line[2]), + max(bbox[3], bbox_line[3]), + ) + + top += line_spacing + + if bbox is None: + return xy[0], xy[1], xy[0], xy[1] + return bbox + + +def Draw(im: Image.Image, mode: str | None = None) -> ImageDraw: + """ + A simple 2D drawing interface for PIL images. + + :param im: The image to draw in. + :param mode: Optional mode to use for color values. For RGB + images, this argument can be RGB or RGBA (to blend the + drawing into the image). For all other modes, this argument + must be the same as the image mode. If omitted, the mode + defaults to the mode of the image. + """ + try: + return getattr(im, "getdraw")(mode) + except AttributeError: + return ImageDraw(im, mode) + + +def getdraw( + im: Image.Image | None = None, hints: list[str] | None = None +) -> tuple[ImageDraw2.Draw | None, ModuleType]: + """ + :param im: The image to draw in. + :param hints: An optional list of hints. Deprecated. + :returns: A (drawing context, drawing resource factory) tuple. + """ + if hints is not None: + deprecate("'hints' parameter", 12) + from . import ImageDraw2 + + draw = ImageDraw2.Draw(im) if im is not None else None + return draw, ImageDraw2 + + +def floodfill( + image: Image.Image, + xy: tuple[int, int], + value: float | tuple[int, ...], + border: float | tuple[int, ...] | None = None, + thresh: float = 0, +) -> None: + """ + .. warning:: This method is experimental. + + Fills a bounded region with a given color. + + :param image: Target image. + :param xy: Seed position (a 2-item coordinate tuple). See + :ref:`coordinate-system`. + :param value: Fill color. + :param border: Optional border value. If given, the region consists of + pixels with a color different from the border color. If not given, + the region consists of pixels having the same color as the seed + pixel. + :param thresh: Optional threshold value which specifies a maximum + tolerable difference of a pixel value from the 'background' in + order for it to be replaced. Useful for filling regions of + non-homogeneous, but similar, colors. + """ + # based on an implementation by Eric S. Raymond + # amended by yo1995 @20180806 + pixel = image.load() + assert pixel is not None + x, y = xy + try: + background = pixel[x, y] + if _color_diff(value, background) <= thresh: + return # seed point already has fill color + pixel[x, y] = value + except (ValueError, IndexError): + return # seed point outside image + edge = {(x, y)} + # use a set to keep record of current and previous edge pixels + # to reduce memory consumption + full_edge = set() + while edge: + new_edge = set() + for x, y in edge: # 4 adjacent method + for s, t in ((x + 1, y), (x - 1, y), (x, y + 1), (x, y - 1)): + # If already processed, or if a coordinate is negative, skip + if (s, t) in full_edge or s < 0 or t < 0: + continue + try: + p = pixel[s, t] + except (ValueError, IndexError): + pass + else: + full_edge.add((s, t)) + if border is None: + fill = _color_diff(p, background) <= thresh + else: + fill = p not in (value, border) + if fill: + pixel[s, t] = value + new_edge.add((s, t)) + full_edge = edge # discard pixels processed + edge = new_edge + + +def _compute_regular_polygon_vertices( + bounding_circle: Sequence[Sequence[float] | float], n_sides: int, rotation: float +) -> list[tuple[float, float]]: + """ + Generate a list of vertices for a 2D regular polygon. + + :param bounding_circle: The bounding circle is a sequence defined + by a point and radius. The polygon is inscribed in this circle. + (e.g. ``bounding_circle=(x, y, r)`` or ``((x, y), r)``) + :param n_sides: Number of sides + (e.g. ``n_sides=3`` for a triangle, ``6`` for a hexagon) + :param rotation: Apply an arbitrary rotation to the polygon + (e.g. ``rotation=90``, applies a 90 degree rotation) + :return: List of regular polygon vertices + (e.g. ``[(25, 50), (50, 50), (50, 25), (25, 25)]``) + + How are the vertices computed? + 1. Compute the following variables + - theta: Angle between the apothem & the nearest polygon vertex + - side_length: Length of each polygon edge + - centroid: Center of bounding circle (1st, 2nd elements of bounding_circle) + - polygon_radius: Polygon radius (last element of bounding_circle) + - angles: Location of each polygon vertex in polar grid + (e.g. A square with 0 degree rotation => [225.0, 315.0, 45.0, 135.0]) + + 2. For each angle in angles, get the polygon vertex at that angle + The vertex is computed using the equation below. + X= xcos(φ) + ysin(φ) + Y= −xsin(φ) + ycos(φ) + + Note: + φ = angle in degrees + x = 0 + y = polygon_radius + + The formula above assumes rotation around the origin. + In our case, we are rotating around the centroid. + To account for this, we use the formula below + X = xcos(φ) + ysin(φ) + centroid_x + Y = −xsin(φ) + ycos(φ) + centroid_y + """ + # 1. Error Handling + # 1.1 Check `n_sides` has an appropriate value + if not isinstance(n_sides, int): + msg = "n_sides should be an int" # type: ignore[unreachable] + raise TypeError(msg) + if n_sides < 3: + msg = "n_sides should be an int > 2" + raise ValueError(msg) + + # 1.2 Check `bounding_circle` has an appropriate value + if not isinstance(bounding_circle, (list, tuple)): + msg = "bounding_circle should be a sequence" + raise TypeError(msg) + + if len(bounding_circle) == 3: + if not all(isinstance(i, (int, float)) for i in bounding_circle): + msg = "bounding_circle should only contain numeric data" + raise ValueError(msg) + + *centroid, polygon_radius = cast(list[float], list(bounding_circle)) + elif len(bounding_circle) == 2 and isinstance(bounding_circle[0], (list, tuple)): + if not all( + isinstance(i, (int, float)) for i in bounding_circle[0] + ) or not isinstance(bounding_circle[1], (int, float)): + msg = "bounding_circle should only contain numeric data" + raise ValueError(msg) + + if len(bounding_circle[0]) != 2: + msg = "bounding_circle centre should contain 2D coordinates (e.g. (x, y))" + raise ValueError(msg) + + centroid = cast(list[float], list(bounding_circle[0])) + polygon_radius = cast(float, bounding_circle[1]) + else: + msg = ( + "bounding_circle should contain 2D coordinates " + "and a radius (e.g. (x, y, r) or ((x, y), r) )" + ) + raise ValueError(msg) + + if polygon_radius <= 0: + msg = "bounding_circle radius should be > 0" + raise ValueError(msg) + + # 1.3 Check `rotation` has an appropriate value + if not isinstance(rotation, (int, float)): + msg = "rotation should be an int or float" # type: ignore[unreachable] + raise ValueError(msg) + + # 2. Define Helper Functions + def _apply_rotation(point: list[float], degrees: float) -> tuple[float, float]: + return ( + round( + point[0] * math.cos(math.radians(360 - degrees)) + - point[1] * math.sin(math.radians(360 - degrees)) + + centroid[0], + 2, + ), + round( + point[1] * math.cos(math.radians(360 - degrees)) + + point[0] * math.sin(math.radians(360 - degrees)) + + centroid[1], + 2, + ), + ) + + def _compute_polygon_vertex(angle: float) -> tuple[float, float]: + start_point = [polygon_radius, 0] + return _apply_rotation(start_point, angle) + + def _get_angles(n_sides: int, rotation: float) -> list[float]: + angles = [] + degrees = 360 / n_sides + # Start with the bottom left polygon vertex + current_angle = (270 - 0.5 * degrees) + rotation + for _ in range(0, n_sides): + angles.append(current_angle) + current_angle += degrees + if current_angle > 360: + current_angle -= 360 + return angles + + # 3. Variable Declarations + angles = _get_angles(n_sides, rotation) + + # 4. Compute Vertices + return [_compute_polygon_vertex(angle) for angle in angles] + + +def _color_diff( + color1: float | tuple[int, ...], color2: float | tuple[int, ...] +) -> float: + """ + Uses 1-norm distance to calculate difference between two values. + """ + first = color1 if isinstance(color1, tuple) else (color1,) + second = color2 if isinstance(color2, tuple) else (color2,) + + return sum(abs(first[i] - second[i]) for i in range(0, len(second))) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageDraw2.py b/venv/lib/python3.12/site-packages/PIL/ImageDraw2.py new file mode 100644 index 0000000..3d68658 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageDraw2.py @@ -0,0 +1,243 @@ +# +# The Python Imaging Library +# $Id$ +# +# WCK-style drawing interface operations +# +# History: +# 2003-12-07 fl created +# 2005-05-15 fl updated; added to PIL as ImageDraw2 +# 2005-05-15 fl added text support +# 2005-05-20 fl added arc/chord/pieslice support +# +# Copyright (c) 2003-2005 by Secret Labs AB +# Copyright (c) 2003-2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + + +""" +(Experimental) WCK-style drawing interface operations + +.. seealso:: :py:mod:`PIL.ImageDraw` +""" +from __future__ import annotations + +from typing import Any, AnyStr, BinaryIO + +from . import Image, ImageColor, ImageDraw, ImageFont, ImagePath +from ._typing import Coords, StrOrBytesPath + + +class Pen: + """Stores an outline color and width.""" + + def __init__(self, color: str, width: int = 1, opacity: int = 255) -> None: + self.color = ImageColor.getrgb(color) + self.width = width + + +class Brush: + """Stores a fill color""" + + def __init__(self, color: str, opacity: int = 255) -> None: + self.color = ImageColor.getrgb(color) + + +class Font: + """Stores a TrueType font and color""" + + def __init__( + self, color: str, file: StrOrBytesPath | BinaryIO, size: float = 12 + ) -> None: + # FIXME: add support for bitmap fonts + self.color = ImageColor.getrgb(color) + self.font = ImageFont.truetype(file, size) + + +class Draw: + """ + (Experimental) WCK-style drawing interface + """ + + def __init__( + self, + image: Image.Image | str, + size: tuple[int, int] | list[int] | None = None, + color: float | tuple[float, ...] | str | None = None, + ) -> None: + if isinstance(image, str): + if size is None: + msg = "If image argument is mode string, size must be a list or tuple" + raise ValueError(msg) + image = Image.new(image, size, color) + self.draw = ImageDraw.Draw(image) + self.image = image + self.transform: tuple[float, float, float, float, float, float] | None = None + + def flush(self) -> Image.Image: + return self.image + + def render( + self, + op: str, + xy: Coords, + pen: Pen | Brush | None, + brush: Brush | Pen | None = None, + **kwargs: Any, + ) -> None: + # handle color arguments + outline = fill = None + width = 1 + if isinstance(pen, Pen): + outline = pen.color + width = pen.width + elif isinstance(brush, Pen): + outline = brush.color + width = brush.width + if isinstance(brush, Brush): + fill = brush.color + elif isinstance(pen, Brush): + fill = pen.color + # handle transformation + if self.transform: + path = ImagePath.Path(xy) + path.transform(self.transform) + xy = path + # render the item + if op in ("arc", "line"): + kwargs.setdefault("fill", outline) + else: + kwargs.setdefault("fill", fill) + kwargs.setdefault("outline", outline) + if op == "line": + kwargs.setdefault("width", width) + getattr(self.draw, op)(xy, **kwargs) + + def settransform(self, offset: tuple[float, float]) -> None: + """Sets a transformation offset.""" + (xoffset, yoffset) = offset + self.transform = (1, 0, xoffset, 0, 1, yoffset) + + def arc( + self, + xy: Coords, + pen: Pen | Brush | None, + start: float, + end: float, + *options: Any, + ) -> None: + """ + Draws an arc (a portion of a circle outline) between the start and end + angles, inside the given bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.arc` + """ + self.render("arc", xy, pen, *options, start=start, end=end) + + def chord( + self, + xy: Coords, + pen: Pen | Brush | None, + start: float, + end: float, + *options: Any, + ) -> None: + """ + Same as :py:meth:`~PIL.ImageDraw2.Draw.arc`, but connects the end points + with a straight line. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.chord` + """ + self.render("chord", xy, pen, *options, start=start, end=end) + + def ellipse(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None: + """ + Draws an ellipse inside the given bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.ellipse` + """ + self.render("ellipse", xy, pen, *options) + + def line(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None: + """ + Draws a line between the coordinates in the ``xy`` list. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.line` + """ + self.render("line", xy, pen, *options) + + def pieslice( + self, + xy: Coords, + pen: Pen | Brush | None, + start: float, + end: float, + *options: Any, + ) -> None: + """ + Same as arc, but also draws straight lines between the end points and the + center of the bounding box. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.pieslice` + """ + self.render("pieslice", xy, pen, *options, start=start, end=end) + + def polygon(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None: + """ + Draws a polygon. + + The polygon outline consists of straight lines between the given + coordinates, plus a straight line between the last and the first + coordinate. + + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.polygon` + """ + self.render("polygon", xy, pen, *options) + + def rectangle(self, xy: Coords, pen: Pen | Brush | None, *options: Any) -> None: + """ + Draws a rectangle. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.rectangle` + """ + self.render("rectangle", xy, pen, *options) + + def text(self, xy: tuple[float, float], text: AnyStr, font: Font) -> None: + """ + Draws the string at the given position. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.text` + """ + if self.transform: + path = ImagePath.Path(xy) + path.transform(self.transform) + xy = path + self.draw.text(xy, text, font=font.font, fill=font.color) + + def textbbox( + self, xy: tuple[float, float], text: AnyStr, font: Font + ) -> tuple[float, float, float, float]: + """ + Returns bounding box (in pixels) of given text. + + :return: ``(left, top, right, bottom)`` bounding box + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textbbox` + """ + if self.transform: + path = ImagePath.Path(xy) + path.transform(self.transform) + xy = path + return self.draw.textbbox(xy, text, font=font.font) + + def textlength(self, text: AnyStr, font: Font) -> float: + """ + Returns length (in pixels) of given text. + This is the amount by which following text should be offset. + + .. seealso:: :py:meth:`PIL.ImageDraw.ImageDraw.textlength` + """ + return self.draw.textlength(text, font=font.font) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageEnhance.py b/venv/lib/python3.12/site-packages/PIL/ImageEnhance.py new file mode 100644 index 0000000..0e7e6dd --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageEnhance.py @@ -0,0 +1,113 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image enhancement classes +# +# For a background, see "Image Processing By Interpolation and +# Extrapolation", Paul Haeberli and Douglas Voorhies. Available +# at http://www.graficaobscura.com/interp/index.html +# +# History: +# 1996-03-23 fl Created +# 2009-06-16 fl Fixed mean calculation +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFilter, ImageStat + + +class _Enhance: + image: Image.Image + degenerate: Image.Image + + def enhance(self, factor: float) -> Image.Image: + """ + Returns an enhanced image. + + :param factor: A floating point value controlling the enhancement. + Factor 1.0 always returns a copy of the original image, + lower factors mean less color (brightness, contrast, + etc), and higher values more. There are no restrictions + on this value. + :rtype: :py:class:`~PIL.Image.Image` + """ + return Image.blend(self.degenerate, self.image, factor) + + +class Color(_Enhance): + """Adjust image color balance. + + This class can be used to adjust the colour balance of an image, in + a manner similar to the controls on a colour TV set. An enhancement + factor of 0.0 gives a black and white image. A factor of 1.0 gives + the original image. + """ + + def __init__(self, image: Image.Image) -> None: + self.image = image + self.intermediate_mode = "L" + if "A" in image.getbands(): + self.intermediate_mode = "LA" + + if self.intermediate_mode != image.mode: + image = image.convert(self.intermediate_mode).convert(image.mode) + self.degenerate = image + + +class Contrast(_Enhance): + """Adjust image contrast. + + This class can be used to control the contrast of an image, similar + to the contrast control on a TV set. An enhancement factor of 0.0 + gives a solid gray image. A factor of 1.0 gives the original image. + """ + + def __init__(self, image: Image.Image) -> None: + self.image = image + if image.mode != "L": + image = image.convert("L") + mean = int(ImageStat.Stat(image).mean[0] + 0.5) + self.degenerate = Image.new("L", image.size, mean) + if self.degenerate.mode != self.image.mode: + self.degenerate = self.degenerate.convert(self.image.mode) + + if "A" in self.image.getbands(): + self.degenerate.putalpha(self.image.getchannel("A")) + + +class Brightness(_Enhance): + """Adjust image brightness. + + This class can be used to control the brightness of an image. An + enhancement factor of 0.0 gives a black image. A factor of 1.0 gives the + original image. + """ + + def __init__(self, image: Image.Image) -> None: + self.image = image + self.degenerate = Image.new(image.mode, image.size, 0) + + if "A" in image.getbands(): + self.degenerate.putalpha(image.getchannel("A")) + + +class Sharpness(_Enhance): + """Adjust image sharpness. + + This class can be used to adjust the sharpness of an image. An + enhancement factor of 0.0 gives a blurred image, a factor of 1.0 gives the + original image, and a factor of 2.0 gives a sharpened image. + """ + + def __init__(self, image: Image.Image) -> None: + self.image = image + self.degenerate = image.filter(ImageFilter.SMOOTH) + + if "A" in image.getbands(): + self.degenerate.putalpha(image.getchannel("A")) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageFile.py b/venv/lib/python3.12/site-packages/PIL/ImageFile.py new file mode 100644 index 0000000..d69d845 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageFile.py @@ -0,0 +1,832 @@ +# +# The Python Imaging Library. +# $Id$ +# +# base class for image file handlers +# +# history: +# 1995-09-09 fl Created +# 1996-03-11 fl Fixed load mechanism. +# 1996-04-15 fl Added pcx/xbm decoders. +# 1996-04-30 fl Added encoders. +# 1996-12-14 fl Added load helpers +# 1997-01-11 fl Use encode_to_file where possible +# 1997-08-27 fl Flush output in _save +# 1998-03-05 fl Use memory mapping for some modes +# 1999-02-04 fl Use memory mapping also for "I;16" and "I;16B" +# 1999-05-31 fl Added image parser +# 2000-10-12 fl Set readonly flag on memory-mapped images +# 2002-03-20 fl Use better messages for common decoder errors +# 2003-04-21 fl Fall back on mmap/map_buffer if map is not available +# 2003-10-30 fl Added StubImageFile class +# 2004-02-25 fl Made incremental parser more robust +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1995-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import abc +import io +import itertools +import os +import struct +import sys +from typing import IO, TYPE_CHECKING, Any, NamedTuple, cast + +from . import Image +from ._deprecate import deprecate +from ._util import is_path + +if TYPE_CHECKING: + from ._typing import StrOrBytesPath + +MAXBLOCK = 65536 + +SAFEBLOCK = 1024 * 1024 + +LOAD_TRUNCATED_IMAGES = False +"""Whether or not to load truncated image files. User code may change this.""" + +ERRORS = { + -1: "image buffer overrun error", + -2: "decoding error", + -3: "unknown error", + -8: "bad configuration", + -9: "out of memory error", +} +""" +Dict of known error codes returned from :meth:`.PyDecoder.decode`, +:meth:`.PyEncoder.encode` :meth:`.PyEncoder.encode_to_pyfd` and +:meth:`.PyEncoder.encode_to_file`. +""" + + +# +# -------------------------------------------------------------------- +# Helpers + + +def _get_oserror(error: int, *, encoder: bool) -> OSError: + try: + msg = Image.core.getcodecstatus(error) + except AttributeError: + msg = ERRORS.get(error) + if not msg: + msg = f"{'encoder' if encoder else 'decoder'} error {error}" + msg += f" when {'writing' if encoder else 'reading'} image file" + return OSError(msg) + + +def raise_oserror(error: int) -> OSError: + deprecate( + "raise_oserror", + 12, + action="It is only useful for translating error codes returned by a codec's " + "decode() method, which ImageFile already does automatically.", + ) + raise _get_oserror(error, encoder=False) + + +def _tilesort(t: _Tile) -> int: + # sort on offset + return t[2] + + +class _Tile(NamedTuple): + codec_name: str + extents: tuple[int, int, int, int] | None + offset: int + args: tuple[Any, ...] | str | None + + +# +# -------------------------------------------------------------------- +# ImageFile base class + + +class ImageFile(Image.Image): + """Base class for image file format handlers.""" + + def __init__( + self, fp: StrOrBytesPath | IO[bytes], filename: str | bytes | None = None + ) -> None: + super().__init__() + + self._min_frame = 0 + + self.custom_mimetype: str | None = None + + self.tile: list[_Tile] = [] + """ A list of tile descriptors, or ``None`` """ + + self.readonly = 1 # until we know better + + self.decoderconfig: tuple[Any, ...] = () + self.decodermaxblock = MAXBLOCK + + if is_path(fp): + # filename + self.fp = open(fp, "rb") + self.filename = os.path.realpath(os.fspath(fp)) + self._exclusive_fp = True + else: + # stream + self.fp = cast(IO[bytes], fp) + self.filename = filename if filename is not None else "" + # can be overridden + self._exclusive_fp = False + + try: + try: + self._open() + except ( + IndexError, # end of data + TypeError, # end of data (ord) + KeyError, # unsupported mode + EOFError, # got header but not the first frame + struct.error, + ) as v: + raise SyntaxError(v) from v + + if not self.mode or self.size[0] <= 0 or self.size[1] <= 0: + msg = "not identified by this driver" + raise SyntaxError(msg) + except BaseException: + # close the file only if we have opened it this constructor + if self._exclusive_fp: + self.fp.close() + raise + + def _open(self) -> None: + pass + + def get_format_mimetype(self) -> str | None: + if self.custom_mimetype: + return self.custom_mimetype + if self.format is not None: + return Image.MIME.get(self.format.upper()) + return None + + def __setstate__(self, state: list[Any]) -> None: + self.tile = [] + super().__setstate__(state) + + def verify(self) -> None: + """Check file integrity""" + + # raise exception if something's wrong. must be called + # directly after open, and closes file when finished. + if self._exclusive_fp: + self.fp.close() + self.fp = None + + def load(self) -> Image.core.PixelAccess | None: + """Load image data based on tile list""" + + if not self.tile and self._im is None: + msg = "cannot load this image" + raise OSError(msg) + + pixel = Image.Image.load(self) + if not self.tile: + return pixel + + self.map: mmap.mmap | None = None + use_mmap = self.filename and len(self.tile) == 1 + # As of pypy 2.1.0, memory mapping was failing here. + use_mmap = use_mmap and not hasattr(sys, "pypy_version_info") + + readonly = 0 + + # look for read/seek overrides + if hasattr(self, "load_read"): + read = self.load_read + # don't use mmap if there are custom read/seek functions + use_mmap = False + else: + read = self.fp.read + + if hasattr(self, "load_seek"): + seek = self.load_seek + use_mmap = False + else: + seek = self.fp.seek + + if use_mmap: + # try memory mapping + decoder_name, extents, offset, args = self.tile[0] + if isinstance(args, str): + args = (args, 0, 1) + if ( + decoder_name == "raw" + and isinstance(args, tuple) + and len(args) >= 3 + and args[0] == self.mode + and args[0] in Image._MAPMODES + ): + try: + # use mmap, if possible + import mmap + + with open(self.filename) as fp: + self.map = mmap.mmap(fp.fileno(), 0, access=mmap.ACCESS_READ) + if offset + self.size[1] * args[1] > self.map.size(): + msg = "buffer is not large enough" + raise OSError(msg) + self.im = Image.core.map_buffer( + self.map, self.size, decoder_name, offset, args + ) + readonly = 1 + # After trashing self.im, + # we might need to reload the palette data. + if self.palette: + self.palette.dirty = 1 + except (AttributeError, OSError, ImportError): + self.map = None + + self.load_prepare() + err_code = -3 # initialize to unknown error + if not self.map: + # sort tiles in file order + self.tile.sort(key=_tilesort) + + # FIXME: This is a hack to handle TIFF's JpegTables tag. + prefix = getattr(self, "tile_prefix", b"") + + # Remove consecutive duplicates that only differ by their offset + self.tile = [ + list(tiles)[-1] + for _, tiles in itertools.groupby( + self.tile, lambda tile: (tile[0], tile[1], tile[3]) + ) + ] + for decoder_name, extents, offset, args in self.tile: + seek(offset) + decoder = Image._getdecoder( + self.mode, decoder_name, args, self.decoderconfig + ) + try: + decoder.setimage(self.im, extents) + if decoder.pulls_fd: + decoder.setfd(self.fp) + err_code = decoder.decode(b"")[1] + else: + b = prefix + while True: + try: + s = read(self.decodermaxblock) + except (IndexError, struct.error) as e: + # truncated png/gif + if LOAD_TRUNCATED_IMAGES: + break + else: + msg = "image file is truncated" + raise OSError(msg) from e + + if not s: # truncated jpeg + if LOAD_TRUNCATED_IMAGES: + break + else: + msg = ( + "image file is truncated " + f"({len(b)} bytes not processed)" + ) + raise OSError(msg) + + b = b + s + n, err_code = decoder.decode(b) + if n < 0: + break + b = b[n:] + finally: + # Need to cleanup here to prevent leaks + decoder.cleanup() + + self.tile = [] + self.readonly = readonly + + self.load_end() + + if self._exclusive_fp and self._close_exclusive_fp_after_loading: + self.fp.close() + self.fp = None + + if not self.map and not LOAD_TRUNCATED_IMAGES and err_code < 0: + # still raised if decoder fails to return anything + raise _get_oserror(err_code, encoder=False) + + return Image.Image.load(self) + + def load_prepare(self) -> None: + # create image memory if necessary + if self._im is None: + self.im = Image.core.new(self.mode, self.size) + # create palette (optional) + if self.mode == "P": + Image.Image.load(self) + + def load_end(self) -> None: + # may be overridden + pass + + # may be defined for contained formats + # def load_seek(self, pos: int) -> None: + # pass + + # may be defined for blocked formats (e.g. PNG) + # def load_read(self, read_bytes: int) -> bytes: + # pass + + def _seek_check(self, frame: int) -> bool: + if ( + frame < self._min_frame + # Only check upper limit on frames if additional seek operations + # are not required to do so + or ( + not (hasattr(self, "_n_frames") and self._n_frames is None) + and frame >= getattr(self, "n_frames") + self._min_frame + ) + ): + msg = "attempt to seek outside sequence" + raise EOFError(msg) + + return self.tell() != frame + + +class StubHandler: + def open(self, im: StubImageFile) -> None: + pass + + @abc.abstractmethod + def load(self, im: StubImageFile) -> Image.Image: + pass + + +class StubImageFile(ImageFile): + """ + Base class for stub image loaders. + + A stub loader is an image loader that can identify files of a + certain format, but relies on external code to load the file. + """ + + def _open(self) -> None: + msg = "StubImageFile subclass must implement _open" + raise NotImplementedError(msg) + + def load(self) -> Image.core.PixelAccess | None: + loader = self._load() + if loader is None: + msg = f"cannot find loader for this {self.format} file" + raise OSError(msg) + image = loader.load(self) + assert image is not None + # become the other object (!) + self.__class__ = image.__class__ # type: ignore[assignment] + self.__dict__ = image.__dict__ + return image.load() + + def _load(self) -> StubHandler | None: + """(Hook) Find actual image loader.""" + msg = "StubImageFile subclass must implement _load" + raise NotImplementedError(msg) + + +class Parser: + """ + Incremental image parser. This class implements the standard + feed/close consumer interface. + """ + + incremental = None + image: Image.Image | None = None + data: bytes | None = None + decoder: Image.core.ImagingDecoder | PyDecoder | None = None + offset = 0 + finished = 0 + + def reset(self) -> None: + """ + (Consumer) Reset the parser. Note that you can only call this + method immediately after you've created a parser; parser + instances cannot be reused. + """ + assert self.data is None, "cannot reuse parsers" + + def feed(self, data: bytes) -> None: + """ + (Consumer) Feed data to the parser. + + :param data: A string buffer. + :exception OSError: If the parser failed to parse the image file. + """ + # collect data + + if self.finished: + return + + if self.data is None: + self.data = data + else: + self.data = self.data + data + + # parse what we have + if self.decoder: + if self.offset > 0: + # skip header + skip = min(len(self.data), self.offset) + self.data = self.data[skip:] + self.offset = self.offset - skip + if self.offset > 0 or not self.data: + return + + n, e = self.decoder.decode(self.data) + + if n < 0: + # end of stream + self.data = None + self.finished = 1 + if e < 0: + # decoding error + self.image = None + raise _get_oserror(e, encoder=False) + else: + # end of image + return + self.data = self.data[n:] + + elif self.image: + # if we end up here with no decoder, this file cannot + # be incrementally parsed. wait until we've gotten all + # available data + pass + + else: + # attempt to open this file + try: + with io.BytesIO(self.data) as fp: + im = Image.open(fp) + except OSError: + pass # not enough data + else: + flag = hasattr(im, "load_seek") or hasattr(im, "load_read") + if flag or len(im.tile) != 1: + # custom load code, or multiple tiles + self.decode = None + else: + # initialize decoder + im.load_prepare() + d, e, o, a = im.tile[0] + im.tile = [] + self.decoder = Image._getdecoder(im.mode, d, a, im.decoderconfig) + self.decoder.setimage(im.im, e) + + # calculate decoder offset + self.offset = o + if self.offset <= len(self.data): + self.data = self.data[self.offset :] + self.offset = 0 + + self.image = im + + def __enter__(self) -> Parser: + return self + + def __exit__(self, *args: object) -> None: + self.close() + + def close(self) -> Image.Image: + """ + (Consumer) Close the stream. + + :returns: An image object. + :exception OSError: If the parser failed to parse the image file either + because it cannot be identified or cannot be + decoded. + """ + # finish decoding + if self.decoder: + # get rid of what's left in the buffers + self.feed(b"") + self.data = self.decoder = None + if not self.finished: + msg = "image was incomplete" + raise OSError(msg) + if not self.image: + msg = "cannot parse this image" + raise OSError(msg) + if self.data: + # incremental parsing not possible; reopen the file + # not that we have all data + with io.BytesIO(self.data) as fp: + try: + self.image = Image.open(fp) + finally: + self.image.load() + return self.image + + +# -------------------------------------------------------------------- + + +def _save(im: Image.Image, fp: IO[bytes], tile: list[_Tile], bufsize: int = 0) -> None: + """Helper to save image based on tile list + + :param im: Image object. + :param fp: File object. + :param tile: Tile list. + :param bufsize: Optional buffer size + """ + + im.load() + if not hasattr(im, "encoderconfig"): + im.encoderconfig = () + tile.sort(key=_tilesort) + # FIXME: make MAXBLOCK a configuration parameter + # It would be great if we could have the encoder specify what it needs + # But, it would need at least the image size in most cases. RawEncode is + # a tricky case. + bufsize = max(MAXBLOCK, bufsize, im.size[0] * 4) # see RawEncode.c + try: + fh = fp.fileno() + fp.flush() + _encode_tile(im, fp, tile, bufsize, fh) + except (AttributeError, io.UnsupportedOperation) as exc: + _encode_tile(im, fp, tile, bufsize, None, exc) + if hasattr(fp, "flush"): + fp.flush() + + +def _encode_tile( + im: Image.Image, + fp: IO[bytes], + tile: list[_Tile], + bufsize: int, + fh: int | None, + exc: BaseException | None = None, +) -> None: + for encoder_name, extents, offset, args in tile: + if offset > 0: + fp.seek(offset) + encoder = Image._getencoder(im.mode, encoder_name, args, im.encoderconfig) + try: + encoder.setimage(im.im, extents) + if encoder.pushes_fd: + encoder.setfd(fp) + errcode = encoder.encode_to_pyfd()[1] + else: + if exc: + # compress to Python file-compatible object + while True: + errcode, data = encoder.encode(bufsize)[1:] + fp.write(data) + if errcode: + break + else: + # slight speedup: compress to real file object + assert fh is not None + errcode = encoder.encode_to_file(fh, bufsize) + if errcode < 0: + raise _get_oserror(errcode, encoder=True) from exc + finally: + encoder.cleanup() + + +def _safe_read(fp: IO[bytes], size: int) -> bytes: + """ + Reads large blocks in a safe way. Unlike fp.read(n), this function + doesn't trust the user. If the requested size is larger than + SAFEBLOCK, the file is read block by block. + + :param fp: File handle. Must implement a read method. + :param size: Number of bytes to read. + :returns: A string containing size bytes of data. + + Raises an OSError if the file is truncated and the read cannot be completed + + """ + if size <= 0: + return b"" + if size <= SAFEBLOCK: + data = fp.read(size) + if len(data) < size: + msg = "Truncated File Read" + raise OSError(msg) + return data + blocks: list[bytes] = [] + remaining_size = size + while remaining_size > 0: + block = fp.read(min(remaining_size, SAFEBLOCK)) + if not block: + break + blocks.append(block) + remaining_size -= len(block) + if sum(len(block) for block in blocks) < size: + msg = "Truncated File Read" + raise OSError(msg) + return b"".join(blocks) + + +class PyCodecState: + def __init__(self) -> None: + self.xsize = 0 + self.ysize = 0 + self.xoff = 0 + self.yoff = 0 + + def extents(self) -> tuple[int, int, int, int]: + return self.xoff, self.yoff, self.xoff + self.xsize, self.yoff + self.ysize + + +class PyCodec: + fd: IO[bytes] | None + + def __init__(self, mode: str, *args: Any) -> None: + self.im: Image.core.ImagingCore | None = None + self.state = PyCodecState() + self.fd = None + self.mode = mode + self.init(args) + + def init(self, args: tuple[Any, ...]) -> None: + """ + Override to perform codec specific initialization + + :param args: Tuple of arg items from the tile entry + :returns: None + """ + self.args = args + + def cleanup(self) -> None: + """ + Override to perform codec specific cleanup + + :returns: None + """ + pass + + def setfd(self, fd: IO[bytes]) -> None: + """ + Called from ImageFile to set the Python file-like object + + :param fd: A Python file-like object + :returns: None + """ + self.fd = fd + + def setimage( + self, + im: Image.core.ImagingCore, + extents: tuple[int, int, int, int] | None = None, + ) -> None: + """ + Called from ImageFile to set the core output image for the codec + + :param im: A core image object + :param extents: a 4 tuple of (x0, y0, x1, y1) defining the rectangle + for this tile + :returns: None + """ + + # following c code + self.im = im + + if extents: + (x0, y0, x1, y1) = extents + else: + (x0, y0, x1, y1) = (0, 0, 0, 0) + + if x0 == 0 and x1 == 0: + self.state.xsize, self.state.ysize = self.im.size + else: + self.state.xoff = x0 + self.state.yoff = y0 + self.state.xsize = x1 - x0 + self.state.ysize = y1 - y0 + + if self.state.xsize <= 0 or self.state.ysize <= 0: + msg = "Size cannot be negative" + raise ValueError(msg) + + if ( + self.state.xsize + self.state.xoff > self.im.size[0] + or self.state.ysize + self.state.yoff > self.im.size[1] + ): + msg = "Tile cannot extend outside image" + raise ValueError(msg) + + +class PyDecoder(PyCodec): + """ + Python implementation of a format decoder. Override this class and + add the decoding logic in the :meth:`decode` method. + + See :ref:`Writing Your Own File Codec in Python` + """ + + _pulls_fd = False + + @property + def pulls_fd(self) -> bool: + return self._pulls_fd + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + """ + Override to perform the decoding process. + + :param buffer: A bytes object with the data to be decoded. + :returns: A tuple of ``(bytes consumed, errcode)``. + If finished with decoding return -1 for the bytes consumed. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + msg = "unavailable in base decoder" + raise NotImplementedError(msg) + + def set_as_raw( + self, data: bytes, rawmode: str | None = None, extra: tuple[Any, ...] = () + ) -> None: + """ + Convenience method to set the internal image from a stream of raw data + + :param data: Bytes to be set + :param rawmode: The rawmode to be used for the decoder. + If not specified, it will default to the mode of the image + :param extra: Extra arguments for the decoder. + :returns: None + """ + + if not rawmode: + rawmode = self.mode + d = Image._getdecoder(self.mode, "raw", rawmode, extra) + assert self.im is not None + d.setimage(self.im, self.state.extents()) + s = d.decode(data) + + if s[0] >= 0: + msg = "not enough image data" + raise ValueError(msg) + if s[1] != 0: + msg = "cannot decode image data" + raise ValueError(msg) + + +class PyEncoder(PyCodec): + """ + Python implementation of a format encoder. Override this class and + add the decoding logic in the :meth:`encode` method. + + See :ref:`Writing Your Own File Codec in Python` + """ + + _pushes_fd = False + + @property + def pushes_fd(self) -> bool: + return self._pushes_fd + + def encode(self, bufsize: int) -> tuple[int, int, bytes]: + """ + Override to perform the encoding process. + + :param bufsize: Buffer size. + :returns: A tuple of ``(bytes encoded, errcode, bytes)``. + If finished with encoding return 1 for the error code. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + msg = "unavailable in base encoder" + raise NotImplementedError(msg) + + def encode_to_pyfd(self) -> tuple[int, int]: + """ + If ``pushes_fd`` is ``True``, then this method will be used, + and ``encode()`` will only be called once. + + :returns: A tuple of ``(bytes consumed, errcode)``. + Err codes are from :data:`.ImageFile.ERRORS`. + """ + if not self.pushes_fd: + return 0, -8 # bad configuration + bytes_consumed, errcode, data = self.encode(0) + if data: + assert self.fd is not None + self.fd.write(data) + return bytes_consumed, errcode + + def encode_to_file(self, fh: int, bufsize: int) -> int: + """ + :param fh: File handle. + :param bufsize: Buffer size. + + :returns: If finished successfully, return 0. + Otherwise, return an error code. Err codes are from + :data:`.ImageFile.ERRORS`. + """ + errcode = 0 + while errcode == 0: + status, errcode, buf = self.encode(bufsize) + if status > 0: + os.write(fh, buf[status:]) + return errcode diff --git a/venv/lib/python3.12/site-packages/PIL/ImageFilter.py b/venv/lib/python3.12/site-packages/PIL/ImageFilter.py new file mode 100644 index 0000000..8b0974b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageFilter.py @@ -0,0 +1,605 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard filters +# +# History: +# 1995-11-27 fl Created +# 2002-06-08 fl Added rank and mode filters +# 2003-09-15 fl Fixed rank calculation in rank filter; added expand call +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2002 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import abc +import functools +from collections.abc import Sequence +from types import ModuleType +from typing import TYPE_CHECKING, Any, Callable, cast + +if TYPE_CHECKING: + from . import _imaging + from ._typing import NumpyArray + + +class Filter: + @abc.abstractmethod + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + pass + + +class MultibandFilter(Filter): + pass + + +class BuiltinFilter(MultibandFilter): + filterargs: tuple[Any, ...] + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + if image.mode == "P": + msg = "cannot filter palette images" + raise ValueError(msg) + return image.filter(*self.filterargs) + + +class Kernel(BuiltinFilter): + """ + Create a convolution kernel. This only supports 3x3 and 5x5 integer and floating + point kernels. + + Kernels can only be applied to "L" and "RGB" images. + + :param size: Kernel size, given as (width, height). This must be (3,3) or (5,5). + :param kernel: A sequence containing kernel weights. The kernel will be flipped + vertically before being applied to the image. + :param scale: Scale factor. If given, the result for each pixel is divided by this + value. The default is the sum of the kernel weights. + :param offset: Offset. If given, this value is added to the result, after it has + been divided by the scale factor. + """ + + name = "Kernel" + + def __init__( + self, + size: tuple[int, int], + kernel: Sequence[float], + scale: float | None = None, + offset: float = 0, + ) -> None: + if scale is None: + # default scale is sum of kernel + scale = functools.reduce(lambda a, b: a + b, kernel) + if size[0] * size[1] != len(kernel): + msg = "not enough coefficients in kernel" + raise ValueError(msg) + self.filterargs = size, scale, offset, kernel + + +class RankFilter(Filter): + """ + Create a rank filter. The rank filter sorts all pixels in + a window of the given size, and returns the ``rank``'th value. + + :param size: The kernel size, in pixels. + :param rank: What pixel value to pick. Use 0 for a min filter, + ``size * size / 2`` for a median filter, ``size * size - 1`` + for a max filter, etc. + """ + + name = "Rank" + + def __init__(self, size: int, rank: int) -> None: + self.size = size + self.rank = rank + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + if image.mode == "P": + msg = "cannot filter palette images" + raise ValueError(msg) + image = image.expand(self.size // 2, self.size // 2) + return image.rankfilter(self.size, self.rank) + + +class MedianFilter(RankFilter): + """ + Create a median filter. Picks the median pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Median" + + def __init__(self, size: int = 3) -> None: + self.size = size + self.rank = size * size // 2 + + +class MinFilter(RankFilter): + """ + Create a min filter. Picks the lowest pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Min" + + def __init__(self, size: int = 3) -> None: + self.size = size + self.rank = 0 + + +class MaxFilter(RankFilter): + """ + Create a max filter. Picks the largest pixel value in a window with the + given size. + + :param size: The kernel size, in pixels. + """ + + name = "Max" + + def __init__(self, size: int = 3) -> None: + self.size = size + self.rank = size * size - 1 + + +class ModeFilter(Filter): + """ + Create a mode filter. Picks the most frequent pixel value in a box with the + given size. Pixel values that occur only once or twice are ignored; if no + pixel value occurs more than twice, the original pixel value is preserved. + + :param size: The kernel size, in pixels. + """ + + name = "Mode" + + def __init__(self, size: int = 3) -> None: + self.size = size + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + return image.modefilter(self.size) + + +class GaussianBlur(MultibandFilter): + """Blurs the image with a sequence of extended box filters, which + approximates a Gaussian kernel. For details on accuracy see + + + :param radius: Standard deviation of the Gaussian kernel. Either a sequence of two + numbers for x and y, or a single number for both. + """ + + name = "GaussianBlur" + + def __init__(self, radius: float | Sequence[float] = 2) -> None: + self.radius = radius + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + xy = self.radius + if isinstance(xy, (int, float)): + xy = (xy, xy) + if xy == (0, 0): + return image.copy() + return image.gaussian_blur(xy) + + +class BoxBlur(MultibandFilter): + """Blurs the image by setting each pixel to the average value of the pixels + in a square box extending radius pixels in each direction. + Supports float radius of arbitrary size. Uses an optimized implementation + which runs in linear time relative to the size of the image + for any radius value. + + :param radius: Size of the box in a direction. Either a sequence of two numbers for + x and y, or a single number for both. + + Radius 0 does not blur, returns an identical image. + Radius 1 takes 1 pixel in each direction, i.e. 9 pixels in total. + """ + + name = "BoxBlur" + + def __init__(self, radius: float | Sequence[float]) -> None: + xy = radius if isinstance(radius, (tuple, list)) else (radius, radius) + if xy[0] < 0 or xy[1] < 0: + msg = "radius must be >= 0" + raise ValueError(msg) + self.radius = radius + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + xy = self.radius + if isinstance(xy, (int, float)): + xy = (xy, xy) + if xy == (0, 0): + return image.copy() + return image.box_blur(xy) + + +class UnsharpMask(MultibandFilter): + """Unsharp mask filter. + + See Wikipedia's entry on `digital unsharp masking`_ for an explanation of + the parameters. + + :param radius: Blur Radius + :param percent: Unsharp strength, in percent + :param threshold: Threshold controls the minimum brightness change that + will be sharpened + + .. _digital unsharp masking: https://en.wikipedia.org/wiki/Unsharp_masking#Digital_unsharp_masking + + """ + + name = "UnsharpMask" + + def __init__( + self, radius: float = 2, percent: int = 150, threshold: int = 3 + ) -> None: + self.radius = radius + self.percent = percent + self.threshold = threshold + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + return image.unsharp_mask(self.radius, self.percent, self.threshold) + + +class BLUR(BuiltinFilter): + name = "Blur" + # fmt: off + filterargs = (5, 5), 16, 0, ( + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, + ) + # fmt: on + + +class CONTOUR(BuiltinFilter): + name = "Contour" + # fmt: off + filterargs = (3, 3), 1, 255, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1, + ) + # fmt: on + + +class DETAIL(BuiltinFilter): + name = "Detail" + # fmt: off + filterargs = (3, 3), 6, 0, ( + 0, -1, 0, + -1, 10, -1, + 0, -1, 0, + ) + # fmt: on + + +class EDGE_ENHANCE(BuiltinFilter): + name = "Edge-enhance" + # fmt: off + filterargs = (3, 3), 2, 0, ( + -1, -1, -1, + -1, 10, -1, + -1, -1, -1, + ) + # fmt: on + + +class EDGE_ENHANCE_MORE(BuiltinFilter): + name = "Edge-enhance More" + # fmt: off + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 9, -1, + -1, -1, -1, + ) + # fmt: on + + +class EMBOSS(BuiltinFilter): + name = "Emboss" + # fmt: off + filterargs = (3, 3), 1, 128, ( + -1, 0, 0, + 0, 1, 0, + 0, 0, 0, + ) + # fmt: on + + +class FIND_EDGES(BuiltinFilter): + name = "Find Edges" + # fmt: off + filterargs = (3, 3), 1, 0, ( + -1, -1, -1, + -1, 8, -1, + -1, -1, -1, + ) + # fmt: on + + +class SHARPEN(BuiltinFilter): + name = "Sharpen" + # fmt: off + filterargs = (3, 3), 16, 0, ( + -2, -2, -2, + -2, 32, -2, + -2, -2, -2, + ) + # fmt: on + + +class SMOOTH(BuiltinFilter): + name = "Smooth" + # fmt: off + filterargs = (3, 3), 13, 0, ( + 1, 1, 1, + 1, 5, 1, + 1, 1, 1, + ) + # fmt: on + + +class SMOOTH_MORE(BuiltinFilter): + name = "Smooth More" + # fmt: off + filterargs = (5, 5), 100, 0, ( + 1, 1, 1, 1, 1, + 1, 5, 5, 5, 1, + 1, 5, 44, 5, 1, + 1, 5, 5, 5, 1, + 1, 1, 1, 1, 1, + ) + # fmt: on + + +class Color3DLUT(MultibandFilter): + """Three-dimensional color lookup table. + + Transforms 3-channel pixels using the values of the channels as coordinates + in the 3D lookup table and interpolating the nearest elements. + + This method allows you to apply almost any color transformation + in constant time by using pre-calculated decimated tables. + + .. versionadded:: 5.2.0 + + :param size: Size of the table. One int or tuple of (int, int, int). + Minimal size in any dimension is 2, maximum is 65. + :param table: Flat lookup table. A list of ``channels * size**3`` + float elements or a list of ``size**3`` channels-sized + tuples with floats. Channels are changed first, + then first dimension, then second, then third. + Value 0.0 corresponds lowest value of output, 1.0 highest. + :param channels: Number of channels in the table. Could be 3 or 4. + Default is 3. + :param target_mode: A mode for the result image. Should have not less + than ``channels`` channels. Default is ``None``, + which means that mode wouldn't be changed. + """ + + name = "Color 3D LUT" + + def __init__( + self, + size: int | tuple[int, int, int], + table: Sequence[float] | Sequence[Sequence[int]] | NumpyArray, + channels: int = 3, + target_mode: str | None = None, + **kwargs: bool, + ) -> None: + if channels not in (3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + self.size = size = self._check_size(size) + self.channels = channels + self.mode = target_mode + + # Hidden flag `_copy_table=False` could be used to avoid extra copying + # of the table if the table is specially made for the constructor. + copy_table = kwargs.get("_copy_table", True) + items = size[0] * size[1] * size[2] + wrong_size = False + + numpy: ModuleType | None = None + if hasattr(table, "shape"): + try: + import numpy + except ImportError: + pass + + if numpy and isinstance(table, numpy.ndarray): + numpy_table: NumpyArray = table + if copy_table: + numpy_table = numpy_table.copy() + + if numpy_table.shape in [ + (items * channels,), + (items, channels), + (size[2], size[1], size[0], channels), + ]: + table = numpy_table.reshape(items * channels) + else: + wrong_size = True + + else: + if copy_table: + table = list(table) + + # Convert to a flat list + if table and isinstance(table[0], (list, tuple)): + raw_table = cast(Sequence[Sequence[int]], table) + flat_table: list[int] = [] + for pixel in raw_table: + if len(pixel) != channels: + msg = ( + "The elements of the table should " + f"have a length of {channels}." + ) + raise ValueError(msg) + flat_table.extend(pixel) + table = flat_table + + if wrong_size or len(table) != items * channels: + msg = ( + "The table should have either channels * size**3 float items " + "or size**3 items of channels-sized tuples with floats. " + f"Table should be: {channels}x{size[0]}x{size[1]}x{size[2]}. " + f"Actual length: {len(table)}" + ) + raise ValueError(msg) + self.table = table + + @staticmethod + def _check_size(size: Any) -> tuple[int, int, int]: + try: + _, _, _ = size + except ValueError as e: + msg = "Size should be either an integer or a tuple of three integers." + raise ValueError(msg) from e + except TypeError: + size = (size, size, size) + size = tuple(int(x) for x in size) + for size_1d in size: + if not 2 <= size_1d <= 65: + msg = "Size should be in [2, 65] range." + raise ValueError(msg) + return size + + @classmethod + def generate( + cls, + size: int | tuple[int, int, int], + callback: Callable[[float, float, float], tuple[float, ...]], + channels: int = 3, + target_mode: str | None = None, + ) -> Color3DLUT: + """Generates new LUT using provided callback. + + :param size: Size of the table. Passed to the constructor. + :param callback: Function with three parameters which correspond + three color channels. Will be called ``size**3`` + times with values from 0.0 to 1.0 and should return + a tuple with ``channels`` elements. + :param channels: The number of channels which should return callback. + :param target_mode: Passed to the constructor of the resulting + lookup table. + """ + size_1d, size_2d, size_3d = cls._check_size(size) + if channels not in (3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + + table: list[float] = [0] * (size_1d * size_2d * size_3d * channels) + idx_out = 0 + for b in range(size_3d): + for g in range(size_2d): + for r in range(size_1d): + table[idx_out : idx_out + channels] = callback( + r / (size_1d - 1), g / (size_2d - 1), b / (size_3d - 1) + ) + idx_out += channels + + return cls( + (size_1d, size_2d, size_3d), + table, + channels=channels, + target_mode=target_mode, + _copy_table=False, + ) + + def transform( + self, + callback: Callable[..., tuple[float, ...]], + with_normals: bool = False, + channels: int | None = None, + target_mode: str | None = None, + ) -> Color3DLUT: + """Transforms the table values using provided callback and returns + a new LUT with altered values. + + :param callback: A function which takes old lookup table values + and returns a new set of values. The number + of arguments which function should take is + ``self.channels`` or ``3 + self.channels`` + if ``with_normals`` flag is set. + Should return a tuple of ``self.channels`` or + ``channels`` elements if it is set. + :param with_normals: If true, ``callback`` will be called with + coordinates in the color cube as the first + three arguments. Otherwise, ``callback`` + will be called only with actual color values. + :param channels: The number of channels in the resulting lookup table. + :param target_mode: Passed to the constructor of the resulting + lookup table. + """ + if channels not in (None, 3, 4): + msg = "Only 3 or 4 output channels are supported" + raise ValueError(msg) + ch_in = self.channels + ch_out = channels or ch_in + size_1d, size_2d, size_3d = self.size + + table = [0] * (size_1d * size_2d * size_3d * ch_out) + idx_in = 0 + idx_out = 0 + for b in range(size_3d): + for g in range(size_2d): + for r in range(size_1d): + values = self.table[idx_in : idx_in + ch_in] + if with_normals: + values = callback( + r / (size_1d - 1), + g / (size_2d - 1), + b / (size_3d - 1), + *values, + ) + else: + values = callback(*values) + table[idx_out : idx_out + ch_out] = values + idx_in += ch_in + idx_out += ch_out + + return type(self)( + self.size, + table, + channels=ch_out, + target_mode=target_mode or self.mode, + _copy_table=False, + ) + + def __repr__(self) -> str: + r = [ + f"{self.__class__.__name__} from {self.table.__class__.__name__}", + "size={:d}x{:d}x{:d}".format(*self.size), + f"channels={self.channels:d}", + ] + if self.mode: + r.append(f"target_mode={self.mode}") + return "<{}>".format(" ".join(r)) + + def filter(self, image: _imaging.ImagingCore) -> _imaging.ImagingCore: + from . import Image + + return image.color_lut_3d( + self.mode or image.mode, + Image.Resampling.BILINEAR, + self.channels, + self.size[0], + self.size[1], + self.size[2], + self.table, + ) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageFont.py b/venv/lib/python3.12/site-packages/PIL/ImageFont.py new file mode 100644 index 0000000..b694b81 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageFont.py @@ -0,0 +1,1338 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIL raster font management +# +# History: +# 1996-08-07 fl created (experimental) +# 1997-08-25 fl minor adjustments to handle fonts from pilfont 0.3 +# 1999-02-06 fl rewrote most font management stuff in C +# 1999-03-17 fl take pth files into account in load_path (from Richard Jones) +# 2001-02-17 fl added freetype support +# 2001-05-09 fl added TransposedFont wrapper class +# 2002-03-04 fl make sure we have a "L" or "1" font +# 2002-12-04 fl skip non-directory entries in the system path +# 2003-04-29 fl add embedded default font +# 2003-09-27 fl added support for truetype charmap encodings +# +# Todo: +# Adapt to PILFONT2 format (16-bit fonts, compressed, single file) +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1996-2003 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# + +from __future__ import annotations + +import base64 +import os +import sys +import warnings +from enum import IntEnum +from io import BytesIO +from types import ModuleType +from typing import IO, TYPE_CHECKING, Any, BinaryIO, TypedDict, cast + +from . import Image, features +from ._typing import StrOrBytesPath +from ._util import DeferredError, is_path + +if TYPE_CHECKING: + from . import ImageFile + from ._imaging import ImagingFont + from ._imagingft import Font + + +class Axis(TypedDict): + minimum: int | None + default: int | None + maximum: int | None + name: bytes | None + + +class Layout(IntEnum): + BASIC = 0 + RAQM = 1 + + +MAX_STRING_LENGTH = 1_000_000 + + +core: ModuleType | DeferredError +try: + from . import _imagingft as core +except ImportError as ex: + core = DeferredError.new(ex) + + +def _string_length_check(text: str | bytes | bytearray) -> None: + if MAX_STRING_LENGTH is not None and len(text) > MAX_STRING_LENGTH: + msg = "too many characters in string" + raise ValueError(msg) + + +# FIXME: add support for pilfont2 format (see FontFile.py) + +# -------------------------------------------------------------------- +# Font metrics format: +# "PILfont" LF +# fontdescriptor LF +# (optional) key=value... LF +# "DATA" LF +# binary data: 256*10*2 bytes (dx, dy, dstbox, srcbox) +# +# To place a character, cut out srcbox and paste at dstbox, +# relative to the character position. Then move the character +# position according to dx, dy. +# -------------------------------------------------------------------- + + +class ImageFont: + """PIL font wrapper""" + + font: ImagingFont + + def _load_pilfont(self, filename: str) -> None: + with open(filename, "rb") as fp: + image: ImageFile.ImageFile | None = None + root = os.path.splitext(filename)[0] + + for ext in (".png", ".gif", ".pbm"): + if image: + image.close() + try: + fullname = root + ext + image = Image.open(fullname) + except Exception: + pass + else: + if image and image.mode in ("1", "L"): + break + else: + if image: + image.close() + + msg = f"cannot find glyph data file {root}.{{gif|pbm|png}}" + raise OSError(msg) + + self.file = fullname + + self._load_pilfont_data(fp, image) + image.close() + + def _load_pilfont_data(self, file: IO[bytes], image: Image.Image) -> None: + # read PILfont header + if file.readline() != b"PILfont\n": + msg = "Not a PILfont file" + raise SyntaxError(msg) + file.readline().split(b";") + self.info = [] # FIXME: should be a dictionary + while True: + s = file.readline() + if not s or s == b"DATA\n": + break + self.info.append(s) + + # read PILfont metrics + data = file.read(256 * 20) + + # check image + if image.mode not in ("1", "L"): + msg = "invalid font image mode" + raise TypeError(msg) + + image.load() + + self.font = Image.core.font(image.im, data) + + def getmask( + self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any + ) -> Image.core.ImagingCore: + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :return: An internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module. + """ + _string_length_check(text) + Image._decompression_bomb_check(self.font.getsize(text)) + return self.font.getmask(text, mode) + + def getbbox( + self, text: str | bytes | bytearray, *args: Any, **kwargs: Any + ) -> tuple[int, int, int, int]: + """ + Returns bounding box (in pixels) of given text. + + .. versionadded:: 9.2.0 + + :param text: Text to render. + + :return: ``(left, top, right, bottom)`` bounding box + """ + _string_length_check(text) + width, height = self.font.getsize(text) + return 0, 0, width, height + + def getlength( + self, text: str | bytes | bytearray, *args: Any, **kwargs: Any + ) -> int: + """ + Returns length (in pixels) of given text. + This is the amount by which following text should be offset. + + .. versionadded:: 9.2.0 + """ + _string_length_check(text) + width, height = self.font.getsize(text) + return width + + +## +# Wrapper for FreeType fonts. Application code should use the +# truetype factory function to create font objects. + + +class FreeTypeFont: + """FreeType font wrapper (requires _imagingft service)""" + + font: Font + font_bytes: bytes + + def __init__( + self, + font: StrOrBytesPath | BinaryIO, + size: float = 10, + index: int = 0, + encoding: str = "", + layout_engine: Layout | None = None, + ) -> None: + # FIXME: use service provider instead + + if isinstance(core, DeferredError): + raise core.ex + + if size <= 0: + msg = f"font size must be greater than 0, not {size}" + raise ValueError(msg) + + self.path = font + self.size = size + self.index = index + self.encoding = encoding + + try: + from packaging.version import parse as parse_version + except ImportError: + pass + else: + if freetype_version := features.version_module("freetype2"): + if parse_version(freetype_version) < parse_version("2.9.1"): + warnings.warn( + "Support for FreeType 2.9.0 is deprecated and will be removed " + "in Pillow 12 (2025-10-15). Please upgrade to FreeType 2.9.1 " + "or newer, preferably FreeType 2.10.4 which fixes " + "CVE-2020-15999.", + DeprecationWarning, + ) + + if layout_engine not in (Layout.BASIC, Layout.RAQM): + layout_engine = Layout.BASIC + if core.HAVE_RAQM: + layout_engine = Layout.RAQM + elif layout_engine == Layout.RAQM and not core.HAVE_RAQM: + warnings.warn( + "Raqm layout was requested, but Raqm is not available. " + "Falling back to basic layout." + ) + layout_engine = Layout.BASIC + + self.layout_engine = layout_engine + + def load_from_bytes(f: IO[bytes]) -> None: + self.font_bytes = f.read() + self.font = core.getfont( + "", size, index, encoding, self.font_bytes, layout_engine + ) + + if is_path(font): + font = os.path.realpath(os.fspath(font)) + if sys.platform == "win32": + font_bytes_path = font if isinstance(font, bytes) else font.encode() + try: + font_bytes_path.decode("ascii") + except UnicodeDecodeError: + # FreeType cannot load fonts with non-ASCII characters on Windows + # So load it into memory first + with open(font, "rb") as f: + load_from_bytes(f) + return + self.font = core.getfont( + font, size, index, encoding, layout_engine=layout_engine + ) + else: + load_from_bytes(cast(IO[bytes], font)) + + def __getstate__(self) -> list[Any]: + return [self.path, self.size, self.index, self.encoding, self.layout_engine] + + def __setstate__(self, state: list[Any]) -> None: + path, size, index, encoding, layout_engine = state + FreeTypeFont.__init__(self, path, size, index, encoding, layout_engine) + + def getname(self) -> tuple[str | None, str | None]: + """ + :return: A tuple of the font family (e.g. Helvetica) and the font style + (e.g. Bold) + """ + return self.font.family, self.font.style + + def getmetrics(self) -> tuple[int, int]: + """ + :return: A tuple of the font ascent (the distance from the baseline to + the highest outline point) and descent (the distance from the + baseline to the lowest outline point, a negative value) + """ + return self.font.ascent, self.font.descent + + def getlength( + self, + text: str | bytes, + mode: str = "", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + ) -> float: + """ + Returns length (in pixels with 1/64 precision) of given text when rendered + in font with provided direction, features, and language. + + This is the amount by which following text should be offset. + Text bounding box may extend past the length in some fonts, + e.g. when using italics or accents. + + The result is returned as a float; it is a whole number if using basic layout. + + Note that the sum of two lengths may not equal the length of a concatenated + string due to kerning. If you need to adjust for kerning, include the following + character and subtract its length. + + For example, instead of :: + + hello = font.getlength("Hello") + world = font.getlength("World") + hello_world = hello + world # not adjusted for kerning + assert hello_world == font.getlength("HelloWorld") # may fail + + use :: + + hello = font.getlength("HelloW") - font.getlength("W") # adjusted for kerning + world = font.getlength("World") + hello_world = hello + world # adjusted for kerning + assert hello_world == font.getlength("HelloWorld") # True + + or disable kerning with (requires libraqm) :: + + hello = draw.textlength("Hello", font, features=["-kern"]) + world = draw.textlength("World", font, features=["-kern"]) + hello_world = hello + world # kerning is disabled, no need to adjust + assert hello_world == draw.textlength("HelloWorld", font, features=["-kern"]) + + .. versionadded:: 8.0.0 + + :param text: Text to measure. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + :return: Either width for horizontal text, or height for vertical text. + """ + _string_length_check(text) + return self.font.getlength(text, mode, direction, features, language) / 64 + + def getbbox( + self, + text: str | bytes, + mode: str = "", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + anchor: str | None = None, + ) -> tuple[float, float, float, float]: + """ + Returns bounding box (in pixels) of given text relative to given anchor + when rendered in font with provided direction, features, and language. + + Use :py:meth:`getlength()` to get the offset of following text with + 1/64 pixel precision. The bounding box includes extra margins for + some fonts, e.g. italics or accents. + + .. versionadded:: 8.0.0 + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + :param stroke_width: The width of the text stroke. + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + :return: ``(left, top, right, bottom)`` bounding box + """ + _string_length_check(text) + size, offset = self.font.getsize( + text, mode, direction, features, language, anchor + ) + left, top = offset[0] - stroke_width, offset[1] - stroke_width + width, height = size[0] + 2 * stroke_width, size[1] + 2 * stroke_width + return left, top, left + width, top + height + + def getmask( + self, + text: str | bytes, + mode: str = "", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + anchor: str | None = None, + ink: int = 0, + start: tuple[float, float] | None = None, + ) -> Image.core.ImagingCore: + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. If the font has embedded color data, the bitmap + should have mode ``RGBA``. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + .. versionadded:: 6.0.0 + + :param stroke_width: The width of the text stroke. + + .. versionadded:: 6.2.0 + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + .. versionadded:: 8.0.0 + + :param ink: Foreground ink for rendering in RGBA mode. + + .. versionadded:: 8.0.0 + + :param start: Tuple of horizontal and vertical offset, as text may render + differently when starting at fractional coordinates. + + .. versionadded:: 9.4.0 + + :return: An internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module. + """ + return self.getmask2( + text, + mode, + direction=direction, + features=features, + language=language, + stroke_width=stroke_width, + anchor=anchor, + ink=ink, + start=start, + )[0] + + def getmask2( + self, + text: str | bytes, + mode: str = "", + direction: str | None = None, + features: list[str] | None = None, + language: str | None = None, + stroke_width: float = 0, + anchor: str | None = None, + ink: int = 0, + start: tuple[float, float] | None = None, + *args: Any, + **kwargs: Any, + ) -> tuple[Image.core.ImagingCore, tuple[int, int]]: + """ + Create a bitmap for the text. + + If the font uses antialiasing, the bitmap should have mode ``L`` and use a + maximum value of 255. If the font has embedded color data, the bitmap + should have mode ``RGBA``. Otherwise, it should have mode ``1``. + + :param text: Text to render. + :param mode: Used by some graphics drivers to indicate what mode the + driver prefers; if empty, the renderer may return either + mode. Note that the mode is always a string, to simplify + C-level implementations. + + .. versionadded:: 1.1.5 + + :param direction: Direction of the text. It can be 'rtl' (right to + left), 'ltr' (left to right) or 'ttb' (top to bottom). + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param features: A list of OpenType font features to be used during text + layout. This is usually used to turn on optional + font features that are not enabled by default, + for example 'dlig' or 'ss01', but can be also + used to turn off default font features for + example '-liga' to disable ligatures or '-kern' + to disable kerning. To get all supported + features, see + https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist + Requires libraqm. + + .. versionadded:: 4.2.0 + + :param language: Language of the text. Different languages may use + different glyph shapes or ligatures. This parameter tells + the font which language the text is in, and to apply the + correct substitutions as appropriate, if available. + It should be a `BCP 47 language code + `_ + Requires libraqm. + + .. versionadded:: 6.0.0 + + :param stroke_width: The width of the text stroke. + + .. versionadded:: 6.2.0 + + :param anchor: The text anchor alignment. Determines the relative location of + the anchor to the text. The default alignment is top left, + specifically ``la`` for horizontal text and ``lt`` for + vertical text. See :ref:`text-anchors` for details. + + .. versionadded:: 8.0.0 + + :param ink: Foreground ink for rendering in RGBA mode. + + .. versionadded:: 8.0.0 + + :param start: Tuple of horizontal and vertical offset, as text may render + differently when starting at fractional coordinates. + + .. versionadded:: 9.4.0 + + :return: A tuple of an internal PIL storage memory instance as defined by the + :py:mod:`PIL.Image.core` interface module, and the text offset, the + gap between the starting coordinate and the first marking + """ + _string_length_check(text) + if start is None: + start = (0, 0) + + def fill(width: int, height: int) -> Image.core.ImagingCore: + size = (width, height) + Image._decompression_bomb_check(size) + return Image.core.fill("RGBA" if mode == "RGBA" else "L", size) + + return self.font.render( + text, + fill, + mode, + direction, + features, + language, + stroke_width, + anchor, + ink, + start[0], + start[1], + ) + + def font_variant( + self, + font: StrOrBytesPath | BinaryIO | None = None, + size: float | None = None, + index: int | None = None, + encoding: str | None = None, + layout_engine: Layout | None = None, + ) -> FreeTypeFont: + """ + Create a copy of this FreeTypeFont object, + using any specified arguments to override the settings. + + Parameters are identical to the parameters used to initialize this + object. + + :return: A FreeTypeFont object. + """ + if font is None: + try: + font = BytesIO(self.font_bytes) + except AttributeError: + font = self.path + return FreeTypeFont( + font=font, + size=self.size if size is None else size, + index=self.index if index is None else index, + encoding=self.encoding if encoding is None else encoding, + layout_engine=layout_engine or self.layout_engine, + ) + + def get_variation_names(self) -> list[bytes]: + """ + :returns: A list of the named styles in a variation font. + :exception OSError: If the font is not a variation font. + """ + try: + names = self.font.getvarnames() + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + return [name.replace(b"\x00", b"") for name in names] + + def set_variation_by_name(self, name: str | bytes) -> None: + """ + :param name: The name of the style. + :exception OSError: If the font is not a variation font. + """ + names = self.get_variation_names() + if not isinstance(name, bytes): + name = name.encode() + index = names.index(name) + 1 + + if index == getattr(self, "_last_variation_index", None): + # When the same name is set twice in a row, + # there is an 'unknown freetype error' + # https://savannah.nongnu.org/bugs/?56186 + return + self._last_variation_index = index + + self.font.setvarname(index) + + def get_variation_axes(self) -> list[Axis]: + """ + :returns: A list of the axes in a variation font. + :exception OSError: If the font is not a variation font. + """ + try: + axes = self.font.getvaraxes() + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + for axis in axes: + if axis["name"]: + axis["name"] = axis["name"].replace(b"\x00", b"") + return axes + + def set_variation_by_axes(self, axes: list[float]) -> None: + """ + :param axes: A list of values for each axis. + :exception OSError: If the font is not a variation font. + """ + try: + self.font.setvaraxes(axes) + except AttributeError as e: + msg = "FreeType 2.9.1 or greater is required" + raise NotImplementedError(msg) from e + + +class TransposedFont: + """Wrapper for writing rotated or mirrored text""" + + def __init__( + self, font: ImageFont | FreeTypeFont, orientation: Image.Transpose | None = None + ): + """ + Wrapper that creates a transposed font from any existing font + object. + + :param font: A font object. + :param orientation: An optional orientation. If given, this should + be one of Image.Transpose.FLIP_LEFT_RIGHT, Image.Transpose.FLIP_TOP_BOTTOM, + Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_180, or + Image.Transpose.ROTATE_270. + """ + self.font = font + self.orientation = orientation # any 'transpose' argument, or None + + def getmask( + self, text: str | bytes, mode: str = "", *args: Any, **kwargs: Any + ) -> Image.core.ImagingCore: + im = self.font.getmask(text, mode, *args, **kwargs) + if self.orientation is not None: + return im.transpose(self.orientation) + return im + + def getbbox( + self, text: str | bytes, *args: Any, **kwargs: Any + ) -> tuple[int, int, float, float]: + # TransposedFont doesn't support getmask2, move top-left point to (0, 0) + # this has no effect on ImageFont and simulates anchor="lt" for FreeTypeFont + left, top, right, bottom = self.font.getbbox(text, *args, **kwargs) + width = right - left + height = bottom - top + if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): + return 0, 0, height, width + return 0, 0, width, height + + def getlength(self, text: str | bytes, *args: Any, **kwargs: Any) -> float: + if self.orientation in (Image.Transpose.ROTATE_90, Image.Transpose.ROTATE_270): + msg = "text length is undefined for text rotated by 90 or 270 degrees" + raise ValueError(msg) + return self.font.getlength(text, *args, **kwargs) + + +def load(filename: str) -> ImageFont: + """ + Load a font file. This function loads a font object from the given + bitmap font file, and returns the corresponding font object. For loading TrueType + or OpenType fonts instead, see :py:func:`~PIL.ImageFont.truetype`. + + :param filename: Name of font file. + :return: A font object. + :exception OSError: If the file could not be read. + """ + f = ImageFont() + f._load_pilfont(filename) + return f + + +def truetype( + font: StrOrBytesPath | BinaryIO, + size: float = 10, + index: int = 0, + encoding: str = "", + layout_engine: Layout | None = None, +) -> FreeTypeFont: + """ + Load a TrueType or OpenType font from a file or file-like object, + and create a font object. This function loads a font object from the given + file or file-like object, and creates a font object for a font of the given + size. For loading bitmap fonts instead, see :py:func:`~PIL.ImageFont.load` + and :py:func:`~PIL.ImageFont.load_path`. + + Pillow uses FreeType to open font files. On Windows, be aware that FreeType + will keep the file open as long as the FreeTypeFont object exists. Windows + limits the number of files that can be open in C at once to 512, so if many + fonts are opened simultaneously and that limit is approached, an + ``OSError`` may be thrown, reporting that FreeType "cannot open resource". + A workaround would be to copy the file(s) into memory, and open that instead. + + This function requires the _imagingft service. + + :param font: A filename or file-like object containing a TrueType font. + If the file is not found in this filename, the loader may also + search in other directories, such as: + + * The :file:`fonts/` directory on Windows, + * :file:`/Library/Fonts/`, :file:`/System/Library/Fonts/` + and :file:`~/Library/Fonts/` on macOS. + * :file:`~/.local/share/fonts`, :file:`/usr/local/share/fonts`, + and :file:`/usr/share/fonts` on Linux; or those specified by + the ``XDG_DATA_HOME`` and ``XDG_DATA_DIRS`` environment variables + for user-installed and system-wide fonts, respectively. + + :param size: The requested size, in pixels. + :param index: Which font face to load (default is first available face). + :param encoding: Which font encoding to use (default is Unicode). Possible + encodings include (see the FreeType documentation for more + information): + + * "unic" (Unicode) + * "symb" (Microsoft Symbol) + * "ADOB" (Adobe Standard) + * "ADBE" (Adobe Expert) + * "ADBC" (Adobe Custom) + * "armn" (Apple Roman) + * "sjis" (Shift JIS) + * "gb " (PRC) + * "big5" + * "wans" (Extended Wansung) + * "joha" (Johab) + * "lat1" (Latin-1) + + This specifies the character set to use. It does not alter the + encoding of any text provided in subsequent operations. + :param layout_engine: Which layout engine to use, if available: + :attr:`.ImageFont.Layout.BASIC` or :attr:`.ImageFont.Layout.RAQM`. + If it is available, Raqm layout will be used by default. + Otherwise, basic layout will be used. + + Raqm layout is recommended for all non-English text. If Raqm layout + is not required, basic layout will have better performance. + + You can check support for Raqm layout using + :py:func:`PIL.features.check_feature` with ``feature="raqm"``. + + .. versionadded:: 4.2.0 + :return: A font object. + :exception OSError: If the file could not be read. + :exception ValueError: If the font size is not greater than zero. + """ + + def freetype(font: StrOrBytesPath | BinaryIO) -> FreeTypeFont: + return FreeTypeFont(font, size, index, encoding, layout_engine) + + try: + return freetype(font) + except OSError: + if not is_path(font): + raise + ttf_filename = os.path.basename(font) + + dirs = [] + if sys.platform == "win32": + # check the windows font repository + # NOTE: must use uppercase WINDIR, to work around bugs in + # 1.5.2's os.environ.get() + windir = os.environ.get("WINDIR") + if windir: + dirs.append(os.path.join(windir, "fonts")) + elif sys.platform in ("linux", "linux2"): + data_home = os.environ.get("XDG_DATA_HOME") + if not data_home: + # The freedesktop spec defines the following default directory for + # when XDG_DATA_HOME is unset or empty. This user-level directory + # takes precedence over system-level directories. + data_home = os.path.expanduser("~/.local/share") + xdg_dirs = [data_home] + + data_dirs = os.environ.get("XDG_DATA_DIRS") + if not data_dirs: + # Similarly, defaults are defined for the system-level directories + data_dirs = "/usr/local/share:/usr/share" + xdg_dirs += data_dirs.split(":") + + dirs += [os.path.join(xdg_dir, "fonts") for xdg_dir in xdg_dirs] + elif sys.platform == "darwin": + dirs += [ + "/Library/Fonts", + "/System/Library/Fonts", + os.path.expanduser("~/Library/Fonts"), + ] + + ext = os.path.splitext(ttf_filename)[1] + first_font_with_a_different_extension = None + for directory in dirs: + for walkroot, walkdir, walkfilenames in os.walk(directory): + for walkfilename in walkfilenames: + if ext and walkfilename == ttf_filename: + return freetype(os.path.join(walkroot, walkfilename)) + elif not ext and os.path.splitext(walkfilename)[0] == ttf_filename: + fontpath = os.path.join(walkroot, walkfilename) + if os.path.splitext(fontpath)[1] == ".ttf": + return freetype(fontpath) + if not ext and first_font_with_a_different_extension is None: + first_font_with_a_different_extension = fontpath + if first_font_with_a_different_extension: + return freetype(first_font_with_a_different_extension) + raise + + +def load_path(filename: str | bytes) -> ImageFont: + """ + Load font file. Same as :py:func:`~PIL.ImageFont.load`, but searches for a + bitmap font along the Python path. + + :param filename: Name of font file. + :return: A font object. + :exception OSError: If the file could not be read. + """ + if not isinstance(filename, str): + filename = filename.decode("utf-8") + for directory in sys.path: + try: + return load(os.path.join(directory, filename)) + except OSError: + pass + msg = f'cannot find font file "{filename}" in sys.path' + if os.path.exists(filename): + msg += f', did you mean ImageFont.load("{filename}") instead?' + + raise OSError(msg) + + +def load_default_imagefont() -> ImageFont: + f = ImageFont() + f._load_pilfont_data( + # courB08 + BytesIO( + base64.b64decode( + b""" +UElMZm9udAo7Ozs7OzsxMDsKREFUQQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAA//8AAQAAAAAAAAABAAEA +BgAAAAH/+gADAAAAAQAAAAMABgAGAAAAAf/6AAT//QADAAAABgADAAYAAAAA//kABQABAAYAAAAL +AAgABgAAAAD/+AAFAAEACwAAABAACQAGAAAAAP/5AAUAAAAQAAAAFQAHAAYAAP////oABQAAABUA +AAAbAAYABgAAAAH/+QAE//wAGwAAAB4AAwAGAAAAAf/5AAQAAQAeAAAAIQAIAAYAAAAB//kABAAB +ACEAAAAkAAgABgAAAAD/+QAE//0AJAAAACgABAAGAAAAAP/6AAX//wAoAAAALQAFAAYAAAAB//8A +BAACAC0AAAAwAAMABgAAAAD//AAF//0AMAAAADUAAQAGAAAAAf//AAMAAAA1AAAANwABAAYAAAAB +//kABQABADcAAAA7AAgABgAAAAD/+QAFAAAAOwAAAEAABwAGAAAAAP/5AAYAAABAAAAARgAHAAYA +AAAA//kABQAAAEYAAABLAAcABgAAAAD/+QAFAAAASwAAAFAABwAGAAAAAP/5AAYAAABQAAAAVgAH +AAYAAAAA//kABQAAAFYAAABbAAcABgAAAAD/+QAFAAAAWwAAAGAABwAGAAAAAP/5AAUAAABgAAAA +ZQAHAAYAAAAA//kABQAAAGUAAABqAAcABgAAAAD/+QAFAAAAagAAAG8ABwAGAAAAAf/8AAMAAABv +AAAAcQAEAAYAAAAA//wAAwACAHEAAAB0AAYABgAAAAD/+gAE//8AdAAAAHgABQAGAAAAAP/7AAT/ +/gB4AAAAfAADAAYAAAAB//oABf//AHwAAACAAAUABgAAAAD/+gAFAAAAgAAAAIUABgAGAAAAAP/5 +AAYAAQCFAAAAiwAIAAYAAP////oABgAAAIsAAACSAAYABgAA////+gAFAAAAkgAAAJgABgAGAAAA +AP/6AAUAAACYAAAAnQAGAAYAAP////oABQAAAJ0AAACjAAYABgAA////+gAFAAAAowAAAKkABgAG +AAD////6AAUAAACpAAAArwAGAAYAAAAA//oABQAAAK8AAAC0AAYABgAA////+gAGAAAAtAAAALsA +BgAGAAAAAP/6AAQAAAC7AAAAvwAGAAYAAP////oABQAAAL8AAADFAAYABgAA////+gAGAAAAxQAA +AMwABgAGAAD////6AAUAAADMAAAA0gAGAAYAAP////oABQAAANIAAADYAAYABgAA////+gAGAAAA +2AAAAN8ABgAGAAAAAP/6AAUAAADfAAAA5AAGAAYAAP////oABQAAAOQAAADqAAYABgAAAAD/+gAF +AAEA6gAAAO8ABwAGAAD////6AAYAAADvAAAA9gAGAAYAAAAA//oABQAAAPYAAAD7AAYABgAA//// ++gAFAAAA+wAAAQEABgAGAAD////6AAYAAAEBAAABCAAGAAYAAP////oABgAAAQgAAAEPAAYABgAA +////+gAGAAABDwAAARYABgAGAAAAAP/6AAYAAAEWAAABHAAGAAYAAP////oABgAAARwAAAEjAAYA +BgAAAAD/+gAFAAABIwAAASgABgAGAAAAAf/5AAQAAQEoAAABKwAIAAYAAAAA//kABAABASsAAAEv +AAgABgAAAAH/+QAEAAEBLwAAATIACAAGAAAAAP/5AAX//AEyAAABNwADAAYAAAAAAAEABgACATcA +AAE9AAEABgAAAAH/+QAE//wBPQAAAUAAAwAGAAAAAP/7AAYAAAFAAAABRgAFAAYAAP////kABQAA +AUYAAAFMAAcABgAAAAD/+wAFAAABTAAAAVEABQAGAAAAAP/5AAYAAAFRAAABVwAHAAYAAAAA//sA +BQAAAVcAAAFcAAUABgAAAAD/+QAFAAABXAAAAWEABwAGAAAAAP/7AAYAAgFhAAABZwAHAAYAAP// +//kABQAAAWcAAAFtAAcABgAAAAD/+QAGAAABbQAAAXMABwAGAAAAAP/5AAQAAgFzAAABdwAJAAYA +AP////kABgAAAXcAAAF+AAcABgAAAAD/+QAGAAABfgAAAYQABwAGAAD////7AAUAAAGEAAABigAF +AAYAAP////sABQAAAYoAAAGQAAUABgAAAAD/+wAFAAABkAAAAZUABQAGAAD////7AAUAAgGVAAAB +mwAHAAYAAAAA//sABgACAZsAAAGhAAcABgAAAAD/+wAGAAABoQAAAacABQAGAAAAAP/7AAYAAAGn +AAABrQAFAAYAAAAA//kABgAAAa0AAAGzAAcABgAA////+wAGAAABswAAAboABQAGAAD////7AAUA +AAG6AAABwAAFAAYAAP////sABgAAAcAAAAHHAAUABgAAAAD/+wAGAAABxwAAAc0ABQAGAAD////7 +AAYAAgHNAAAB1AAHAAYAAAAA//sABQAAAdQAAAHZAAUABgAAAAH/+QAFAAEB2QAAAd0ACAAGAAAA +Av/6AAMAAQHdAAAB3gAHAAYAAAAA//kABAABAd4AAAHiAAgABgAAAAD/+wAF//0B4gAAAecAAgAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAB +//sAAwACAecAAAHpAAcABgAAAAD/+QAFAAEB6QAAAe4ACAAGAAAAAP/5AAYAAAHuAAAB9AAHAAYA +AAAA//oABf//AfQAAAH5AAUABgAAAAD/+QAGAAAB+QAAAf8ABwAGAAAAAv/5AAMAAgH/AAACAAAJ +AAYAAAAA//kABQABAgAAAAIFAAgABgAAAAH/+gAE//sCBQAAAggAAQAGAAAAAP/5AAYAAAIIAAAC +DgAHAAYAAAAB//kABf/+Ag4AAAISAAUABgAA////+wAGAAACEgAAAhkABQAGAAAAAP/7AAX//gIZ +AAACHgADAAYAAAAA//wABf/9Ah4AAAIjAAEABgAAAAD/+QAHAAACIwAAAioABwAGAAAAAP/6AAT/ ++wIqAAACLgABAAYAAAAA//kABP/8Ai4AAAIyAAMABgAAAAD/+gAFAAACMgAAAjcABgAGAAAAAf/5 +AAT//QI3AAACOgAEAAYAAAAB//kABP/9AjoAAAI9AAQABgAAAAL/+QAE//sCPQAAAj8AAgAGAAD/ +///7AAYAAgI/AAACRgAHAAYAAAAA//kABgABAkYAAAJMAAgABgAAAAH//AAD//0CTAAAAk4AAQAG +AAAAAf//AAQAAgJOAAACUQADAAYAAAAB//kABP/9AlEAAAJUAAQABgAAAAH/+QAF//4CVAAAAlgA +BQAGAAD////7AAYAAAJYAAACXwAFAAYAAP////kABgAAAl8AAAJmAAcABgAA////+QAGAAACZgAA +Am0ABwAGAAD////5AAYAAAJtAAACdAAHAAYAAAAA//sABQACAnQAAAJ5AAcABgAA////9wAGAAAC +eQAAAoAACQAGAAD////3AAYAAAKAAAAChwAJAAYAAP////cABgAAAocAAAKOAAkABgAA////9wAG +AAACjgAAApUACQAGAAD////4AAYAAAKVAAACnAAIAAYAAP////cABgAAApwAAAKjAAkABgAA//// ++gAGAAACowAAAqoABgAGAAAAAP/6AAUAAgKqAAACrwAIAAYAAP////cABQAAAq8AAAK1AAkABgAA +////9wAFAAACtQAAArsACQAGAAD////3AAUAAAK7AAACwQAJAAYAAP////gABQAAAsEAAALHAAgA +BgAAAAD/9wAEAAACxwAAAssACQAGAAAAAP/3AAQAAALLAAACzwAJAAYAAAAA//cABAAAAs8AAALT +AAkABgAAAAD/+AAEAAAC0wAAAtcACAAGAAD////6AAUAAALXAAAC3QAGAAYAAP////cABgAAAt0A +AALkAAkABgAAAAD/9wAFAAAC5AAAAukACQAGAAAAAP/3AAUAAALpAAAC7gAJAAYAAAAA//cABQAA +Au4AAALzAAkABgAAAAD/9wAFAAAC8wAAAvgACQAGAAAAAP/4AAUAAAL4AAAC/QAIAAYAAAAA//oA +Bf//Av0AAAMCAAUABgAA////+gAGAAADAgAAAwkABgAGAAD////3AAYAAAMJAAADEAAJAAYAAP// +//cABgAAAxAAAAMXAAkABgAA////9wAGAAADFwAAAx4ACQAGAAD////4AAYAAAAAAAoABwASAAYA +AP////cABgAAAAcACgAOABMABgAA////+gAFAAAADgAKABQAEAAGAAD////6AAYAAAAUAAoAGwAQ +AAYAAAAA//gABgAAABsACgAhABIABgAAAAD/+AAGAAAAIQAKACcAEgAGAAAAAP/4AAYAAAAnAAoA +LQASAAYAAAAA//gABgAAAC0ACgAzABIABgAAAAD/+QAGAAAAMwAKADkAEQAGAAAAAP/3AAYAAAA5 +AAoAPwATAAYAAP////sABQAAAD8ACgBFAA8ABgAAAAD/+wAFAAIARQAKAEoAEQAGAAAAAP/4AAUA +AABKAAoATwASAAYAAAAA//gABQAAAE8ACgBUABIABgAAAAD/+AAFAAAAVAAKAFkAEgAGAAAAAP/5 +AAUAAABZAAoAXgARAAYAAAAA//gABgAAAF4ACgBkABIABgAAAAD/+AAGAAAAZAAKAGoAEgAGAAAA +AP/4AAYAAABqAAoAcAASAAYAAAAA//kABgAAAHAACgB2ABEABgAAAAD/+AAFAAAAdgAKAHsAEgAG +AAD////4AAYAAAB7AAoAggASAAYAAAAA//gABQAAAIIACgCHABIABgAAAAD/+AAFAAAAhwAKAIwA +EgAGAAAAAP/4AAUAAACMAAoAkQASAAYAAAAA//gABQAAAJEACgCWABIABgAAAAD/+QAFAAAAlgAK +AJsAEQAGAAAAAP/6AAX//wCbAAoAoAAPAAYAAAAA//oABQABAKAACgClABEABgAA////+AAGAAAA +pQAKAKwAEgAGAAD////4AAYAAACsAAoAswASAAYAAP////gABgAAALMACgC6ABIABgAA////+QAG +AAAAugAKAMEAEQAGAAD////4AAYAAgDBAAoAyAAUAAYAAP////kABQACAMgACgDOABMABgAA//// ++QAGAAIAzgAKANUAEw== +""" + ) + ), + Image.open( + BytesIO( + base64.b64decode( + b""" +iVBORw0KGgoAAAANSUhEUgAAAx4AAAAUAQAAAAArMtZoAAAEwElEQVR4nABlAJr/AHVE4czCI/4u +Mc4b7vuds/xzjz5/3/7u/n9vMe7vnfH/9++vPn/xyf5zhxzjt8GHw8+2d83u8x27199/nxuQ6Od9 +M43/5z2I+9n9ZtmDBwMQECDRQw/eQIQohJXxpBCNVE6QCCAAAAD//wBlAJr/AgALyj1t/wINwq0g +LeNZUworuN1cjTPIzrTX6ofHWeo3v336qPzfEwRmBnHTtf95/fglZK5N0PDgfRTslpGBvz7LFc4F +IUXBWQGjQ5MGCx34EDFPwXiY4YbYxavpnhHFrk14CDAAAAD//wBlAJr/AgKqRooH2gAgPeggvUAA +Bu2WfgPoAwzRAABAAAAAAACQgLz/3Uv4Gv+gX7BJgDeeGP6AAAD1NMDzKHD7ANWr3loYbxsAD791 +NAADfcoIDyP44K/jv4Y63/Z+t98Ovt+ub4T48LAAAAD//wBlAJr/AuplMlADJAAAAGuAphWpqhMx +in0A/fRvAYBABPgBwBUgABBQ/sYAyv9g0bCHgOLoGAAAAAAAREAAwI7nr0ArYpow7aX8//9LaP/9 +SjdavWA8ePHeBIKB//81/83ndznOaXx379wAAAD//wBlAJr/AqDxW+D3AABAAbUh/QMnbQag/gAY +AYDAAACgtgD/gOqAAAB5IA/8AAAk+n9w0AAA8AAAmFRJuPo27ciC0cD5oeW4E7KA/wD3ECMAn2tt +y8PgwH8AfAxFzC0JzeAMtratAsC/ffwAAAD//wBlAJr/BGKAyCAA4AAAAvgeYTAwHd1kmQF5chkG +ABoMIHcL5xVpTfQbUqzlAAAErwAQBgAAEOClA5D9il08AEh/tUzdCBsXkbgACED+woQg8Si9VeqY +lODCn7lmF6NhnAEYgAAA/NMIAAAAAAD//2JgjLZgVGBg5Pv/Tvpc8hwGBjYGJADjHDrAwPzAjv/H +/Wf3PzCwtzcwHmBgYGcwbZz8wHaCAQMDOwMDQ8MCBgYOC3W7mp+f0w+wHOYxO3OG+e376hsMZjk3 +AAAAAP//YmCMY2A4wMAIN5e5gQETPD6AZisDAwMDgzSDAAPjByiHcQMDAwMDg1nOze1lByRu5/47 +c4859311AYNZzg0AAAAA//9iYGDBYihOIIMuwIjGL39/fwffA8b//xv/P2BPtzzHwCBjUQAAAAD/ +/yLFBrIBAAAA//9i1HhcwdhizX7u8NZNzyLbvT97bfrMf/QHI8evOwcSqGUJAAAA//9iYBB81iSw +pEE170Qrg5MIYydHqwdDQRMrAwcVrQAAAAD//2J4x7j9AAMDn8Q/BgYLBoaiAwwMjPdvMDBYM1Tv +oJodAAAAAP//Yqo/83+dxePWlxl3npsel9lvLfPcqlE9725C+acfVLMEAAAA//9i+s9gwCoaaGMR +evta/58PTEWzr21hufPjA8N+qlnBwAAAAAD//2JiWLci5v1+HmFXDqcnULE/MxgYGBj+f6CaJQAA +AAD//2Ji2FrkY3iYpYC5qDeGgeEMAwPDvwQBBoYvcTwOVLMEAAAA//9isDBgkP///0EOg9z35v// +Gc/eeW7BwPj5+QGZhANUswMAAAD//2JgqGBgYGBgqEMXlvhMPUsAAAAA//8iYDd1AAAAAP//AwDR +w7IkEbzhVQAAAABJRU5ErkJggg== +""" + ) + ) + ), + ) + return f + + +def load_default(size: float | None = None) -> FreeTypeFont | ImageFont: + """If FreeType support is available, load a version of Aileron Regular, + https://dotcolon.net/font/aileron, with a more limited character set. + + Otherwise, load a "better than nothing" font. + + .. versionadded:: 1.1.4 + + :param size: The font size of Aileron Regular. + + .. versionadded:: 10.1.0 + + :return: A font object. + """ + if isinstance(core, ModuleType) or size is not None: + return truetype( + BytesIO( + base64.b64decode( + b""" +AAEAAAAPAIAAAwBwRkZUTYwDlUAAADFoAAAAHEdERUYAqADnAAAo8AAAACRHUE9ThhmITwAAKfgAA +AduR1NVQnHxefoAACkUAAAA4k9TLzJovoHLAAABeAAAAGBjbWFw5lFQMQAAA6gAAAGqZ2FzcP//AA +MAACjoAAAACGdseWYmRXoPAAAGQAAAHfhoZWFkE18ayQAAAPwAAAA2aGhlYQboArEAAAE0AAAAJGh +tdHjjERZ8AAAB2AAAAdBsb2NhuOexrgAABVQAAADqbWF4cAC7AEYAAAFYAAAAIG5hbWUr+h5lAAAk +OAAAA6Jwb3N0D3oPTQAAJ9wAAAEKAAEAAAABGhxJDqIhXw889QALA+gAAAAA0Bqf2QAAAADhCh2h/ +2r/LgOxAyAAAAAIAAIAAAAAAAAAAQAAA8r/GgAAA7j/av9qA7EAAQAAAAAAAAAAAAAAAAAAAHQAAQ +AAAHQAQwAFAAAAAAACAAAAAQABAAAAQAAAAAAAAAADAfoBkAAFAAgCigJYAAAASwKKAlgAAAFeADI +BPgAAAAAFAAAAAAAAAAAAAAcAAAAAAAAAAAAAAABVS1dOAEAAIPsCAwL/GgDIA8oA5iAAAJMAAAAA +AhICsgAAACAAAwH0AAAAAAAAAU0AAADYAAAA8gA5AVMAVgJEAEYCRAA1AuQAKQKOAEAAsAArATsAZ +AE7AB4CMABVAkQAUADc/+EBEgAgANwAJQEv//sCRAApAkQAggJEADwCRAAtAkQAIQJEADkCRAArAk +QAMgJEACwCRAAxANwAJQDc/+ECRABnAkQAUAJEAEQB8wAjA1QANgJ/AB0CcwBkArsALwLFAGQCSwB +kAjcAZALGAC8C2gBkAQgAZAIgADcCYQBkAj8AZANiAGQCzgBkAuEALwJWAGQC3QAvAmsAZAJJADQC +ZAAiAqoAXgJuACADuAAaAnEAGQJFABMCTwAuATMAYgEv//sBJwAiAkQAUAH0ADIBLAApAhMAJAJjA +EoCEQAeAmcAHgIlAB4BIgAVAmcAHgJRAEoA7gA+AOn/8wIKAEoA9wBGA1cASgJRAEoCSgAeAmMASg +JnAB4BSgBKAcsAGAE5ABQCUABCAgIAAQMRAAEB4v/6AgEAAQHOABQBLwBAAPoAYAEvACECRABNA0Y +AJAItAHgBKgAcAkQAUAEsAHQAygAgAi0AOQD3ADYA9wAWAaEANgGhABYCbAAlAYMAeAGDADkA6/9q +AhsAFAIKABUB/QAVAAAAAwAAAAMAAAAcAAEAAAAAAKQAAwABAAAAHAAEAIgAAAAeABAAAwAOAH4Aq +QCrALEAtAC3ALsgGSAdICYgOiBEISL7Av//AAAAIACpAKsAsAC0ALcAuyAYIBwgJiA5IEQhIvsB// +//4/+5/7j/tP+y/7D/reBR4E/gR+A14CzfTwVxAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAEGAAABAAAAAAAAAAECAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAMEBQYHCAkKCwwNDg8QERIT +FBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMT +U5PUFFSU1RVVldYWVpbXF1eX2BhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGQAAA +AAAAAAYnFmAAAAAABlAAAAAAAAAAAAAAAAAAAAAAAAAAAAY2htAAAAAAAAAABrbGlqAAAAAHAAbm9 +ycwBnAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmACYAJgAmAD4AUgCCAMoBCgFO +AVwBcgGIAaYBvAHKAdYB6AH2AgwCIAJKAogCpgLWAw4DIgNkA5wDugPUA+gD/AQQBEYEogS8BPoFJ +gVSBWoFgAWwBcoF1gX6BhQGJAZMBmgGiga0BuIHGgdUB2YHkAeiB8AH3AfyCAoIHAgqCDoITghcCG +oIogjSCPoJKglYCXwJwgnqCgIKKApACl4Klgq8CtwLDAs8C1YLjAuyC9oL7gwMDCYMSAxgDKAMrAz +qDQoNTA1mDYQNoA2uDcAN2g3oDfYODA4iDkoOXA5sDnoOnA7EDvwAAAAFAAAAAAH0ArwAAwAGAAkA +DAAPAAAxESERAxMhExcRASELARETAfT6qv6syKr+jgFUqsiqArz9RAGLAP/+1P8B/v3VAP8BLP4CA +P8AAgA5//IAuQKyAAMACwAANyMDMwIyFhQGIiY0oE4MZk84JCQ4JLQB/v3AJDgkJDgAAgBWAeUBPA +LfAAMABwAAEyMnMxcjJzOmRgpagkYKWgHl+vr6AAAAAAIARgAAAf4CsgAbAB8AAAEHMxUjByM3Iwc +jNyM1MzcjNTM3MwczNzMHMxUrAQczAZgdZXEvOi9bLzovWmYdZXEvOi9bLzovWp9bHlsBn4w429vb +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 +EQQ/BCQvEjQCFQZWFSEWQv40AcxCDiUblhP9uSEAAAAAAAAWAQ4AAQAAAAAAAAATACgAAQAAAAAAA +QAHAEwAAQAAAAAAAgAHAGQAAQAAAAAAAwAaAKIAAQAAAAAABAAHAM0AAQAAAAAABQA8AU8AAQAAAA +AABgAPAawAAQAAAAAACAALAdQAAQAAAAAACQALAfgAAQAAAAAACwAXAjQAAQAAAAAADAAXAnwAAwA +BBAkAAAAmAAAAAwABBAkAAQAOADwAAwABBAkAAgAOAFQAAwABBAkAAwA0AGwAAwABBAkABAAOAL0A +AwABBAkABQB4ANUAAwABBAkABgAeAYwAAwABBAkACAAWAbwAAwABBAkACQAWAeAAAwABBAkACwAuA +gQAAwABBAkADAAuAkwATgBvACAAUgBpAGcAaAB0AHMAIABSAGUAcwBlAHIAdgBlAGQALgAATm8gUm +lnaHRzIFJlc2VydmVkLgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAUgBlAGcAdQBsAGEAcgAAUmV +ndWxhcgAAMQAuADEAMAAyADsAVQBLAFcATgA7AEEAaQBsAGUAcgBvAG4ALQBSAGUAZwB1AGwAYQBy +AAAxLjEwMjtVS1dOO0FpbGVyb24tUmVndWxhcgAAQQBpAGwAZQByAG8AbgAAQWlsZXJvbgAAVgBlA +HIAcwBpAG8AbgAgADEALgAxADAAMgA7AFAAUwAgADAAMAAxAC4AMQAwADIAOwBoAG8AdABjAG8Abg +B2ACAAMQAuADAALgA3ADAAOwBtAGEAawBlAG8AdABmAC4AbABpAGIAMgAuADUALgA1ADgAMwAyADk +AAFZlcnNpb24gMS4xMDI7UFMgMDAxLjEwMjtob3Rjb252IDEuMC43MDttYWtlb3RmLmxpYjIuNS41 +ODMyOQAAQQBpAGwAZQByAG8AbgAtAFIAZQBnAHUAbABhAHIAAEFpbGVyb24tUmVndWxhcgAAUwBvA +HIAYQAgAFMAYQBnAGEAbgBvAABTb3JhIFNhZ2FubwAAUwBvAHIAYQAgAFMAYQBnAGEAbgBvAABTb3 +JhIFNhZ2FubwAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBsAG8AbgAuAG4AZQB0AAB +odHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGQAbwB0AGMAbwBs +AG8AbgAuAG4AZQB0AABodHRwOi8vd3d3LmRvdGNvbG9uLm5ldAAAAAACAAAAAAAA/4MAMgAAAAAAA +AAAAAAAAAAAAAAAAAAAAHQAAAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAEgATAB +QAFQAWABcAGAAZABoAGwAcAB0AHgAfACAAIQAiACMAJAAlACYAJwAoACkAKgArACwALQAuAC8AMAA +xADIAMwA0ADUANgA3ADgAOQA6ADsAPAA9AD4APwBAAEEAQgBDAEQARQBGAEcASABJAEoASwBMAE0A +TgBPAFAAUQBSAFMAVABVAFYAVwBYAFkAWgBbAFwAXQBeAF8AYABhAIsAqQCDAJMAjQDDAKoAtgC3A +LQAtQCrAL4AvwC8AIwAwADBAAAAAAAB//8AAgABAAAADAAAABwAAAACAAIAAwBxAAEAcgBzAAIABA +AAAAIAAAABAAAACgBMAGYAAkRGTFQADmxhdG4AGgAEAAAAAP//AAEAAAAWAANDQVQgAB5NT0wgABZ +ST00gABYAAP//AAEAAAAA//8AAgAAAAEAAmxpZ2EADmxvY2wAFAAAAAEAAQAAAAEAAAACAAYAEAAG +AAAAAgASADQABAAAAAEATAADAAAAAgAQABYAAQAcAAAAAQABAE8AAQABAGcAAQABAE8AAwAAAAIAE +AAWAAEAHAAAAAEAAQAvAAEAAQBnAAEAAQAvAAEAGgABAAgAAgAGAAwAcwACAE8AcgACAEwAAQABAE +kAAAABAAAACgBGAGAAAkRGTFQADmxhdG4AHAAEAAAAAP//AAIAAAABABYAA0NBVCAAFk1PTCAAFlJ +PTSAAFgAA//8AAgAAAAEAAmNwc3AADmtlcm4AFAAAAAEAAAAAAAEAAQACAAYADgABAAAAAQASAAIA +AAACAB4ANgABAAoABQAFAAoAAgABACQAPQAAAAEAEgAEAAAAAQAMAAEAOP/nAAEAAQAkAAIGigAEA +AAFJAXKABoAGQAA//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAD/sv+4/+z/7v/MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAD/xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9T/6AAAAAD/8QAA +ABD/vQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAA//MAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAP/5AAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAD/4AAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//L/9AAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAA/+gAAAAAAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/zAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/mAAAAAAAAAAAAAAAAAAD +/4gAA//AAAAAA//YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/+AAAAAAAAP/OAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/zv/qAAAAAP/0AAAACAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/ZAAD/egAA/1kAAAAA/5D/rgAAAAAAAAAAAA +AAAAAAAAAAAAAAAAD/9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAD/8AAA/7b/8P+wAAD/8P/E/98AAAAA/8P/+P/0//oAAAAAAAAAAAAA//gA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/+AAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/w//C/9MAAP/SAAD/9wAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAD/yAAA/+kAAAAA//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/9wAAAAD//QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAP/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAP/cAAAAAAAAAAAAAAAA/7YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAP/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/6AAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAkAFAAEAAAAAQACwAAABcA +BgAAAAAAAAAIAA4AAAAAAAsAEgAAAAAAAAATABkAAwANAAAAAQAJAAAAAAAAAAAAAAAAAAAAGAAAA +AAABwAAAAAAAAAAAAAAFQAFAAAAAAAYABgAAAAUAAAACgAAAAwAAgAPABEAFgAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAEAEQBdAAYAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAcAAAAAAAAABwAAAAAACAAAAAAAAAAAAAcAAAAHAAAAEwAJ +ABUADgAPAAAACwAQAAAAAAAAAAAAAAAAAAUAGAACAAIAAgAAAAIAGAAXAAAAGAAAABYAFgACABYAA +gAWAAAAEQADAAoAFAAMAA0ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAAEgAGAAEAHgAkAC +YAJwApACoALQAuAC8AMgAzADcAOAA5ADoAPAA9AEUASABOAE8AUgBTAFUAVwBZAFoAWwBcAF0AcwA +AAAAAAQAAAADa3tfFAAAAANAan9kAAAAA4QodoQ== +""" + ) + ), + 10 if size is None else size, + layout_engine=Layout.BASIC, + ) + return load_default_imagefont() diff --git a/venv/lib/python3.12/site-packages/PIL/ImageGrab.py b/venv/lib/python3.12/site-packages/PIL/ImageGrab.py new file mode 100644 index 0000000..e27ca7e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageGrab.py @@ -0,0 +1,194 @@ +# +# The Python Imaging Library +# $Id$ +# +# screen grabber +# +# History: +# 2001-04-26 fl created +# 2001-09-17 fl use builtin driver, if present +# 2002-11-19 fl added grabclipboard support +# +# Copyright (c) 2001-2002 by Secret Labs AB +# Copyright (c) 2001-2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import shutil +import subprocess +import sys +import tempfile + +from . import Image + + +def grab( + bbox: tuple[int, int, int, int] | None = None, + include_layered_windows: bool = False, + all_screens: bool = False, + xdisplay: str | None = None, +) -> Image.Image: + im: Image.Image + if xdisplay is None: + if sys.platform == "darwin": + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + args = ["screencapture"] + if bbox: + left, top, right, bottom = bbox + args += ["-R", f"{left},{top},{right-left},{bottom-top}"] + subprocess.call(args + ["-x", filepath]) + im = Image.open(filepath) + im.load() + os.unlink(filepath) + if bbox: + im_resized = im.resize((right - left, bottom - top)) + im.close() + return im_resized + return im + elif sys.platform == "win32": + offset, size, data = Image.core.grabscreen_win32( + include_layered_windows, all_screens + ) + im = Image.frombytes( + "RGB", + size, + data, + # RGB, 32-bit line padding, origin lower left corner + "raw", + "BGR", + (size[0] * 3 + 3) & -4, + -1, + ) + if bbox: + x0, y0 = offset + left, top, right, bottom = bbox + im = im.crop((left - x0, top - y0, right - x0, bottom - y0)) + return im + # Cast to Optional[str] needed for Windows and macOS. + display_name: str | None = xdisplay + try: + if not Image.core.HAVE_XCB: + msg = "Pillow was built without XCB support" + raise OSError(msg) + size, data = Image.core.grabscreen_x11(display_name) + except OSError: + if ( + display_name is None + and sys.platform not in ("darwin", "win32") + and shutil.which("gnome-screenshot") + ): + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + subprocess.call(["gnome-screenshot", "-f", filepath]) + im = Image.open(filepath) + im.load() + os.unlink(filepath) + if bbox: + im_cropped = im.crop(bbox) + im.close() + return im_cropped + return im + else: + raise + else: + im = Image.frombytes("RGB", size, data, "raw", "BGRX", size[0] * 4, 1) + if bbox: + im = im.crop(bbox) + return im + + +def grabclipboard() -> Image.Image | list[str] | None: + if sys.platform == "darwin": + fh, filepath = tempfile.mkstemp(".png") + os.close(fh) + commands = [ + 'set theFile to (open for access POSIX file "' + + filepath + + '" with write permission)', + "try", + " write (the clipboard as «class PNGf») to theFile", + "end try", + "close access theFile", + ] + script = ["osascript"] + for command in commands: + script += ["-e", command] + subprocess.call(script) + + im = None + if os.stat(filepath).st_size != 0: + im = Image.open(filepath) + im.load() + os.unlink(filepath) + return im + elif sys.platform == "win32": + fmt, data = Image.core.grabclipboard_win32() + if fmt == "file": # CF_HDROP + import struct + + o = struct.unpack_from("I", data)[0] + if data[16] != 0: + files = data[o:].decode("utf-16le").split("\0") + else: + files = data[o:].decode("mbcs").split("\0") + return files[: files.index("")] + if isinstance(data, bytes): + data = io.BytesIO(data) + if fmt == "png": + from . import PngImagePlugin + + return PngImagePlugin.PngImageFile(data) + elif fmt == "DIB": + from . import BmpImagePlugin + + return BmpImagePlugin.DibImageFile(data) + return None + else: + if os.getenv("WAYLAND_DISPLAY"): + session_type = "wayland" + elif os.getenv("DISPLAY"): + session_type = "x11" + else: # Session type check failed + session_type = None + + if shutil.which("wl-paste") and session_type in ("wayland", None): + args = ["wl-paste", "-t", "image"] + elif shutil.which("xclip") and session_type in ("x11", None): + args = ["xclip", "-selection", "clipboard", "-t", "image/png", "-o"] + else: + msg = "wl-paste or xclip is required for ImageGrab.grabclipboard() on Linux" + raise NotImplementedError(msg) + + p = subprocess.run(args, capture_output=True) + if p.returncode != 0: + err = p.stderr + for silent_error in [ + # wl-paste, when the clipboard is empty + b"Nothing is copied", + # Ubuntu/Debian wl-paste, when the clipboard is empty + b"No selection", + # Ubuntu/Debian wl-paste, when an image isn't available + b"No suitable type of content copied", + # wl-paste or Ubuntu/Debian xclip, when an image isn't available + b" not available", + # xclip, when an image isn't available + b"cannot convert ", + # xclip, when the clipboard isn't initialized + b"xclip: Error: There is no owner for the ", + ]: + if silent_error in err: + return None + msg = f"{args[0]} error" + if err: + msg += f": {err.strip().decode()}" + raise ChildProcessError(msg) + + data = io.BytesIO(p.stdout) + im = Image.open(data) + im.load() + return im diff --git a/venv/lib/python3.12/site-packages/PIL/ImageMath.py b/venv/lib/python3.12/site-packages/PIL/ImageMath.py new file mode 100644 index 0000000..484797f --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageMath.py @@ -0,0 +1,368 @@ +# +# The Python Imaging Library +# $Id$ +# +# a simple math add-on for the Python Imaging Library +# +# History: +# 1999-02-15 fl Original PIL Plus release +# 2005-05-05 fl Simplified and cleaned up for PIL 1.1.6 +# 2005-09-12 fl Fixed int() and float() for Python 2.4.1 +# +# Copyright (c) 1999-2005 by Secret Labs AB +# Copyright (c) 2005 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import builtins +from types import CodeType +from typing import Any, Callable + +from . import Image, _imagingmath +from ._deprecate import deprecate + + +class _Operand: + """Wraps an image operand, providing standard operators""" + + def __init__(self, im: Image.Image): + self.im = im + + def __fixup(self, im1: _Operand | float) -> Image.Image: + # convert image to suitable mode + if isinstance(im1, _Operand): + # argument was an image. + if im1.im.mode in ("1", "L"): + return im1.im.convert("I") + elif im1.im.mode in ("I", "F"): + return im1.im + else: + msg = f"unsupported mode: {im1.im.mode}" + raise ValueError(msg) + else: + # argument was a constant + if isinstance(im1, (int, float)) and self.im.mode in ("1", "L", "I"): + return Image.new("I", self.im.size, im1) + else: + return Image.new("F", self.im.size, im1) + + def apply( + self, + op: str, + im1: _Operand | float, + im2: _Operand | float | None = None, + mode: str | None = None, + ) -> _Operand: + im_1 = self.__fixup(im1) + if im2 is None: + # unary operation + out = Image.new(mode or im_1.mode, im_1.size, None) + try: + op = getattr(_imagingmath, f"{op}_{im_1.mode}") + except AttributeError as e: + msg = f"bad operand type for '{op}'" + raise TypeError(msg) from e + _imagingmath.unop(op, out.getim(), im_1.getim()) + else: + # binary operation + im_2 = self.__fixup(im2) + if im_1.mode != im_2.mode: + # convert both arguments to floating point + if im_1.mode != "F": + im_1 = im_1.convert("F") + if im_2.mode != "F": + im_2 = im_2.convert("F") + if im_1.size != im_2.size: + # crop both arguments to a common size + size = ( + min(im_1.size[0], im_2.size[0]), + min(im_1.size[1], im_2.size[1]), + ) + if im_1.size != size: + im_1 = im_1.crop((0, 0) + size) + if im_2.size != size: + im_2 = im_2.crop((0, 0) + size) + out = Image.new(mode or im_1.mode, im_1.size, None) + try: + op = getattr(_imagingmath, f"{op}_{im_1.mode}") + except AttributeError as e: + msg = f"bad operand type for '{op}'" + raise TypeError(msg) from e + _imagingmath.binop(op, out.getim(), im_1.getim(), im_2.getim()) + return _Operand(out) + + # unary operators + def __bool__(self) -> bool: + # an image is "true" if it contains at least one non-zero pixel + return self.im.getbbox() is not None + + def __abs__(self) -> _Operand: + return self.apply("abs", self) + + def __pos__(self) -> _Operand: + return self + + def __neg__(self) -> _Operand: + return self.apply("neg", self) + + # binary operators + def __add__(self, other: _Operand | float) -> _Operand: + return self.apply("add", self, other) + + def __radd__(self, other: _Operand | float) -> _Operand: + return self.apply("add", other, self) + + def __sub__(self, other: _Operand | float) -> _Operand: + return self.apply("sub", self, other) + + def __rsub__(self, other: _Operand | float) -> _Operand: + return self.apply("sub", other, self) + + def __mul__(self, other: _Operand | float) -> _Operand: + return self.apply("mul", self, other) + + def __rmul__(self, other: _Operand | float) -> _Operand: + return self.apply("mul", other, self) + + def __truediv__(self, other: _Operand | float) -> _Operand: + return self.apply("div", self, other) + + def __rtruediv__(self, other: _Operand | float) -> _Operand: + return self.apply("div", other, self) + + def __mod__(self, other: _Operand | float) -> _Operand: + return self.apply("mod", self, other) + + def __rmod__(self, other: _Operand | float) -> _Operand: + return self.apply("mod", other, self) + + def __pow__(self, other: _Operand | float) -> _Operand: + return self.apply("pow", self, other) + + def __rpow__(self, other: _Operand | float) -> _Operand: + return self.apply("pow", other, self) + + # bitwise + def __invert__(self) -> _Operand: + return self.apply("invert", self) + + def __and__(self, other: _Operand | float) -> _Operand: + return self.apply("and", self, other) + + def __rand__(self, other: _Operand | float) -> _Operand: + return self.apply("and", other, self) + + def __or__(self, other: _Operand | float) -> _Operand: + return self.apply("or", self, other) + + def __ror__(self, other: _Operand | float) -> _Operand: + return self.apply("or", other, self) + + def __xor__(self, other: _Operand | float) -> _Operand: + return self.apply("xor", self, other) + + def __rxor__(self, other: _Operand | float) -> _Operand: + return self.apply("xor", other, self) + + def __lshift__(self, other: _Operand | float) -> _Operand: + return self.apply("lshift", self, other) + + def __rshift__(self, other: _Operand | float) -> _Operand: + return self.apply("rshift", self, other) + + # logical + def __eq__(self, other: _Operand | float) -> _Operand: # type: ignore[override] + return self.apply("eq", self, other) + + def __ne__(self, other: _Operand | float) -> _Operand: # type: ignore[override] + return self.apply("ne", self, other) + + def __lt__(self, other: _Operand | float) -> _Operand: + return self.apply("lt", self, other) + + def __le__(self, other: _Operand | float) -> _Operand: + return self.apply("le", self, other) + + def __gt__(self, other: _Operand | float) -> _Operand: + return self.apply("gt", self, other) + + def __ge__(self, other: _Operand | float) -> _Operand: + return self.apply("ge", self, other) + + +# conversions +def imagemath_int(self: _Operand) -> _Operand: + return _Operand(self.im.convert("I")) + + +def imagemath_float(self: _Operand) -> _Operand: + return _Operand(self.im.convert("F")) + + +# logical +def imagemath_equal(self: _Operand, other: _Operand | float | None) -> _Operand: + return self.apply("eq", self, other, mode="I") + + +def imagemath_notequal(self: _Operand, other: _Operand | float | None) -> _Operand: + return self.apply("ne", self, other, mode="I") + + +def imagemath_min(self: _Operand, other: _Operand | float | None) -> _Operand: + return self.apply("min", self, other) + + +def imagemath_max(self: _Operand, other: _Operand | float | None) -> _Operand: + return self.apply("max", self, other) + + +def imagemath_convert(self: _Operand, mode: str) -> _Operand: + return _Operand(self.im.convert(mode)) + + +ops = { + "int": imagemath_int, + "float": imagemath_float, + "equal": imagemath_equal, + "notequal": imagemath_notequal, + "min": imagemath_min, + "max": imagemath_max, + "convert": imagemath_convert, +} + + +def lambda_eval( + expression: Callable[[dict[str, Any]], Any], + options: dict[str, Any] = {}, + **kw: Any, +) -> Any: + """ + Returns the result of an image function. + + :py:mod:`~PIL.ImageMath` only supports single-layer images. To process multi-band + images, use the :py:meth:`~PIL.Image.Image.split` method or + :py:func:`~PIL.Image.merge` function. + + :param expression: A function that receives a dictionary. + :param options: Values to add to the function's dictionary. Deprecated. + You can instead use one or more keyword arguments. + :param **kw: Values to add to the function's dictionary. + :return: The expression result. This is usually an image object, but can + also be an integer, a floating point value, or a pixel tuple, + depending on the expression. + """ + + if options: + deprecate( + "ImageMath.lambda_eval options", + 12, + "ImageMath.lambda_eval keyword arguments", + ) + + args: dict[str, Any] = ops.copy() + args.update(options) + args.update(kw) + for k, v in args.items(): + if isinstance(v, Image.Image): + args[k] = _Operand(v) + + out = expression(args) + try: + return out.im + except AttributeError: + return out + + +def unsafe_eval( + expression: str, + options: dict[str, Any] = {}, + **kw: Any, +) -> Any: + """ + Evaluates an image expression. This uses Python's ``eval()`` function to process + the expression string, and carries the security risks of doing so. It is not + recommended to process expressions without considering this. + :py:meth:`~lambda_eval` is a more secure alternative. + + :py:mod:`~PIL.ImageMath` only supports single-layer images. To process multi-band + images, use the :py:meth:`~PIL.Image.Image.split` method or + :py:func:`~PIL.Image.merge` function. + + :param expression: A string containing a Python-style expression. + :param options: Values to add to the evaluation context. Deprecated. + You can instead use one or more keyword arguments. + :param **kw: Values to add to the evaluation context. + :return: The evaluated expression. This is usually an image object, but can + also be an integer, a floating point value, or a pixel tuple, + depending on the expression. + """ + + if options: + deprecate( + "ImageMath.unsafe_eval options", + 12, + "ImageMath.unsafe_eval keyword arguments", + ) + + # build execution namespace + args: dict[str, Any] = ops.copy() + for k in list(options.keys()) + list(kw.keys()): + if "__" in k or hasattr(builtins, k): + msg = f"'{k}' not allowed" + raise ValueError(msg) + + args.update(options) + args.update(kw) + for k, v in args.items(): + if isinstance(v, Image.Image): + args[k] = _Operand(v) + + compiled_code = compile(expression, "", "eval") + + def scan(code: CodeType) -> None: + for const in code.co_consts: + if type(const) is type(compiled_code): + scan(const) + + for name in code.co_names: + if name not in args and name != "abs": + msg = f"'{name}' not allowed" + raise ValueError(msg) + + scan(compiled_code) + out = builtins.eval(expression, {"__builtins": {"abs": abs}}, args) + try: + return out.im + except AttributeError: + return out + + +def eval( + expression: str, + _dict: dict[str, Any] = {}, + **kw: Any, +) -> Any: + """ + Evaluates an image expression. + + Deprecated. Use lambda_eval() or unsafe_eval() instead. + + :param expression: A string containing a Python-style expression. + :param _dict: Values to add to the evaluation context. You + can either use a dictionary, or one or more keyword + arguments. + :return: The evaluated expression. This is usually an image object, but can + also be an integer, a floating point value, or a pixel tuple, + depending on the expression. + + .. deprecated:: 10.3.0 + """ + + deprecate( + "ImageMath.eval", + 12, + "ImageMath.lambda_eval or ImageMath.unsafe_eval", + ) + return unsafe_eval(expression, _dict, **kw) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageMode.py b/venv/lib/python3.12/site-packages/PIL/ImageMode.py new file mode 100644 index 0000000..92a08d2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageMode.py @@ -0,0 +1,92 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard mode descriptors +# +# History: +# 2006-03-20 fl Added +# +# Copyright (c) 2006 by Secret Labs AB. +# Copyright (c) 2006 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys +from functools import lru_cache +from typing import NamedTuple + +from ._deprecate import deprecate + + +class ModeDescriptor(NamedTuple): + """Wrapper for mode strings.""" + + mode: str + bands: tuple[str, ...] + basemode: str + basetype: str + typestr: str + + def __str__(self) -> str: + return self.mode + + +@lru_cache +def getmode(mode: str) -> ModeDescriptor: + """Gets a mode descriptor for the given mode.""" + endian = "<" if sys.byteorder == "little" else ">" + + modes = { + # core modes + # Bits need to be extended to bytes + "1": ("L", "L", ("1",), "|b1"), + "L": ("L", "L", ("L",), "|u1"), + "I": ("L", "I", ("I",), f"{endian}i4"), + "F": ("L", "F", ("F",), f"{endian}f4"), + "P": ("P", "L", ("P",), "|u1"), + "RGB": ("RGB", "L", ("R", "G", "B"), "|u1"), + "RGBX": ("RGB", "L", ("R", "G", "B", "X"), "|u1"), + "RGBA": ("RGB", "L", ("R", "G", "B", "A"), "|u1"), + "CMYK": ("RGB", "L", ("C", "M", "Y", "K"), "|u1"), + "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr"), "|u1"), + # UNDONE - unsigned |u1i1i1 + "LAB": ("RGB", "L", ("L", "A", "B"), "|u1"), + "HSV": ("RGB", "L", ("H", "S", "V"), "|u1"), + # extra experimental modes + "RGBa": ("RGB", "L", ("R", "G", "B", "a"), "|u1"), + "BGR;15": ("RGB", "L", ("B", "G", "R"), "|u1"), + "BGR;16": ("RGB", "L", ("B", "G", "R"), "|u1"), + "BGR;24": ("RGB", "L", ("B", "G", "R"), "|u1"), + "LA": ("L", "L", ("L", "A"), "|u1"), + "La": ("L", "L", ("L", "a"), "|u1"), + "PA": ("RGB", "L", ("P", "A"), "|u1"), + } + if mode in modes: + if mode in ("BGR;15", "BGR;16", "BGR;24"): + deprecate(mode, 12) + base_mode, base_type, bands, type_str = modes[mode] + return ModeDescriptor(mode, bands, base_mode, base_type, type_str) + + mapping_modes = { + # I;16 == I;16L, and I;32 == I;32L + "I;16": "u2", + "I;16BS": ">i2", + "I;16N": f"{endian}u2", + "I;16NS": f"{endian}i2", + "I;32": "u4", + "I;32L": "i4", + "I;32LS": " +from __future__ import annotations + +import re + +from . import Image, _imagingmorph + +LUT_SIZE = 1 << 9 + +# fmt: off +ROTATION_MATRIX = [ + 6, 3, 0, + 7, 4, 1, + 8, 5, 2, +] +MIRROR_MATRIX = [ + 2, 1, 0, + 5, 4, 3, + 8, 7, 6, +] +# fmt: on + + +class LutBuilder: + """A class for building a MorphLut from a descriptive language + + The input patterns is a list of a strings sequences like these:: + + 4:(... + .1. + 111)->1 + + (whitespaces including linebreaks are ignored). The option 4 + describes a series of symmetry operations (in this case a + 4-rotation), the pattern is described by: + + - . or X - Ignore + - 1 - Pixel is on + - 0 - Pixel is off + + The result of the operation is described after "->" string. + + The default is to return the current pixel value, which is + returned if no other match is found. + + Operations: + + - 4 - 4 way rotation + - N - Negate + - 1 - Dummy op for no other operation (an op must always be given) + - M - Mirroring + + Example:: + + lb = LutBuilder(patterns = ["4:(... .1. 111)->1"]) + lut = lb.build_lut() + + """ + + def __init__( + self, patterns: list[str] | None = None, op_name: str | None = None + ) -> None: + if patterns is not None: + self.patterns = patterns + else: + self.patterns = [] + self.lut: bytearray | None = None + if op_name is not None: + known_patterns = { + "corner": ["1:(... ... ...)->0", "4:(00. 01. ...)->1"], + "dilation4": ["4:(... .0. .1.)->1"], + "dilation8": ["4:(... .0. .1.)->1", "4:(... .0. ..1)->1"], + "erosion4": ["4:(... .1. .0.)->0"], + "erosion8": ["4:(... .1. .0.)->0", "4:(... .1. ..0)->0"], + "edge": [ + "1:(... ... ...)->0", + "4:(.0. .1. ...)->1", + "4:(01. .1. ...)->1", + ], + } + if op_name not in known_patterns: + msg = f"Unknown pattern {op_name}!" + raise Exception(msg) + + self.patterns = known_patterns[op_name] + + def add_patterns(self, patterns: list[str]) -> None: + self.patterns += patterns + + def build_default_lut(self) -> None: + symbols = [0, 1] + m = 1 << 4 # pos of current pixel + self.lut = bytearray(symbols[(i & m) > 0] for i in range(LUT_SIZE)) + + def get_lut(self) -> bytearray | None: + return self.lut + + def _string_permute(self, pattern: str, permutation: list[int]) -> str: + """string_permute takes a pattern and a permutation and returns the + string permuted according to the permutation list. + """ + assert len(permutation) == 9 + return "".join(pattern[p] for p in permutation) + + def _pattern_permute( + self, basic_pattern: str, options: str, basic_result: int + ) -> list[tuple[str, int]]: + """pattern_permute takes a basic pattern and its result and clones + the pattern according to the modifications described in the $options + parameter. It returns a list of all cloned patterns.""" + patterns = [(basic_pattern, basic_result)] + + # rotations + if "4" in options: + res = patterns[-1][1] + for i in range(4): + patterns.append( + (self._string_permute(patterns[-1][0], ROTATION_MATRIX), res) + ) + # mirror + if "M" in options: + n = len(patterns) + for pattern, res in patterns[:n]: + patterns.append((self._string_permute(pattern, MIRROR_MATRIX), res)) + + # negate + if "N" in options: + n = len(patterns) + for pattern, res in patterns[:n]: + # Swap 0 and 1 + pattern = pattern.replace("0", "Z").replace("1", "0").replace("Z", "1") + res = 1 - int(res) + patterns.append((pattern, res)) + + return patterns + + def build_lut(self) -> bytearray: + """Compile all patterns into a morphology lut. + + TBD :Build based on (file) morphlut:modify_lut + """ + self.build_default_lut() + assert self.lut is not None + patterns = [] + + # Parse and create symmetries of the patterns strings + for p in self.patterns: + m = re.search(r"(\w*):?\s*\((.+?)\)\s*->\s*(\d)", p.replace("\n", "")) + if not m: + msg = 'Syntax error in pattern "' + p + '"' + raise Exception(msg) + options = m.group(1) + pattern = m.group(2) + result = int(m.group(3)) + + # Get rid of spaces + pattern = pattern.replace(" ", "").replace("\n", "") + + patterns += self._pattern_permute(pattern, options, result) + + # compile the patterns into regular expressions for speed + compiled_patterns = [] + for pattern in patterns: + p = pattern[0].replace(".", "X").replace("X", "[01]") + compiled_patterns.append((re.compile(p), pattern[1])) + + # Step through table and find patterns that match. + # Note that all the patterns are searched. The last one + # caught overrides + for i in range(LUT_SIZE): + # Build the bit pattern + bitpattern = bin(i)[2:] + bitpattern = ("0" * (9 - len(bitpattern)) + bitpattern)[::-1] + + for pattern, r in compiled_patterns: + if pattern.match(bitpattern): + self.lut[i] = [0, 1][r] + + return self.lut + + +class MorphOp: + """A class for binary morphological operators""" + + def __init__( + self, + lut: bytearray | None = None, + op_name: str | None = None, + patterns: list[str] | None = None, + ) -> None: + """Create a binary morphological operator""" + self.lut = lut + if op_name is not None: + self.lut = LutBuilder(op_name=op_name).build_lut() + elif patterns is not None: + self.lut = LutBuilder(patterns=patterns).build_lut() + + def apply(self, image: Image.Image) -> tuple[int, Image.Image]: + """Run a single morphological operation on an image + + Returns a tuple of the number of changed pixels and the + morphed image""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + outimage = Image.new(image.mode, image.size, None) + count = _imagingmorph.apply(bytes(self.lut), image.getim(), outimage.getim()) + return count, outimage + + def match(self, image: Image.Image) -> list[tuple[int, int]]: + """Get a list of coordinates matching the morphological operation on + an image. + + Returns a list of tuples of (x,y) coordinates + of all matching pixels. See :ref:`coordinate-system`.""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + return _imagingmorph.match(bytes(self.lut), image.getim()) + + def get_on_pixels(self, image: Image.Image) -> list[tuple[int, int]]: + """Get a list of all turned on pixels in a binary image + + Returns a list of tuples of (x,y) coordinates + of all matching pixels. See :ref:`coordinate-system`.""" + + if image.mode != "L": + msg = "Image mode must be L" + raise ValueError(msg) + return _imagingmorph.get_on_pixels(image.getim()) + + def load_lut(self, filename: str) -> None: + """Load an operator from an mrl file""" + with open(filename, "rb") as f: + self.lut = bytearray(f.read()) + + if len(self.lut) != LUT_SIZE: + self.lut = None + msg = "Wrong size operator file!" + raise Exception(msg) + + def save_lut(self, filename: str) -> None: + """Save an operator to an mrl file""" + if self.lut is None: + msg = "No operator loaded" + raise Exception(msg) + with open(filename, "wb") as f: + f.write(self.lut) + + def set_lut(self, lut: bytearray | None) -> None: + """Set the lut from an external source""" + self.lut = lut diff --git a/venv/lib/python3.12/site-packages/PIL/ImageOps.py b/venv/lib/python3.12/site-packages/PIL/ImageOps.py new file mode 100644 index 0000000..44aad0c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageOps.py @@ -0,0 +1,730 @@ +# +# The Python Imaging Library. +# $Id$ +# +# standard image operations +# +# History: +# 2001-10-20 fl Created +# 2001-10-23 fl Added autocontrast operator +# 2001-12-18 fl Added Kevin's fit operator +# 2004-03-14 fl Fixed potential division by zero in equalize +# 2005-05-05 fl Fixed equalize for low number of values +# +# Copyright (c) 2001-2004 by Secret Labs AB +# Copyright (c) 2001-2004 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import functools +import operator +import re +from collections.abc import Sequence +from typing import Protocol, cast + +from . import ExifTags, Image, ImagePalette + +# +# helpers + + +def _border(border: int | tuple[int, ...]) -> tuple[int, int, int, int]: + if isinstance(border, tuple): + if len(border) == 2: + left, top = right, bottom = border + elif len(border) == 4: + left, top, right, bottom = border + else: + left = top = right = bottom = border + return left, top, right, bottom + + +def _color(color: str | int | tuple[int, ...], mode: str) -> int | tuple[int, ...]: + if isinstance(color, str): + from . import ImageColor + + color = ImageColor.getcolor(color, mode) + return color + + +def _lut(image: Image.Image, lut: list[int]) -> Image.Image: + if image.mode == "P": + # FIXME: apply to lookup table, not image data + msg = "mode P support coming soon" + raise NotImplementedError(msg) + elif image.mode in ("L", "RGB"): + if image.mode == "RGB" and len(lut) == 256: + lut = lut + lut + lut + return image.point(lut) + else: + msg = f"not supported for mode {image.mode}" + raise OSError(msg) + + +# +# actions + + +def autocontrast( + image: Image.Image, + cutoff: float | tuple[float, float] = 0, + ignore: int | Sequence[int] | None = None, + mask: Image.Image | None = None, + preserve_tone: bool = False, +) -> Image.Image: + """ + Maximize (normalize) image contrast. This function calculates a + histogram of the input image (or mask region), removes ``cutoff`` percent of the + lightest and darkest pixels from the histogram, and remaps the image + so that the darkest pixel becomes black (0), and the lightest + becomes white (255). + + :param image: The image to process. + :param cutoff: The percent to cut off from the histogram on the low and + high ends. Either a tuple of (low, high), or a single + number for both. + :param ignore: The background pixel value (use None for no background). + :param mask: Histogram used in contrast operation is computed using pixels + within the mask. If no mask is given the entire image is used + for histogram computation. + :param preserve_tone: Preserve image tone in Photoshop-like style autocontrast. + + .. versionadded:: 8.2.0 + + :return: An image. + """ + if preserve_tone: + histogram = image.convert("L").histogram(mask) + else: + histogram = image.histogram(mask) + + lut = [] + for layer in range(0, len(histogram), 256): + h = histogram[layer : layer + 256] + if ignore is not None: + # get rid of outliers + if isinstance(ignore, int): + h[ignore] = 0 + else: + for ix in ignore: + h[ix] = 0 + if cutoff: + # cut off pixels from both ends of the histogram + if not isinstance(cutoff, tuple): + cutoff = (cutoff, cutoff) + # get number of pixels + n = 0 + for ix in range(256): + n = n + h[ix] + # remove cutoff% pixels from the low end + cut = int(n * cutoff[0] // 100) + for lo in range(256): + if cut > h[lo]: + cut = cut - h[lo] + h[lo] = 0 + else: + h[lo] -= cut + cut = 0 + if cut <= 0: + break + # remove cutoff% samples from the high end + cut = int(n * cutoff[1] // 100) + for hi in range(255, -1, -1): + if cut > h[hi]: + cut = cut - h[hi] + h[hi] = 0 + else: + h[hi] -= cut + cut = 0 + if cut <= 0: + break + # find lowest/highest samples after preprocessing + for lo in range(256): + if h[lo]: + break + for hi in range(255, -1, -1): + if h[hi]: + break + if hi <= lo: + # don't bother + lut.extend(list(range(256))) + else: + scale = 255.0 / (hi - lo) + offset = -lo * scale + for ix in range(256): + ix = int(ix * scale + offset) + if ix < 0: + ix = 0 + elif ix > 255: + ix = 255 + lut.append(ix) + return _lut(image, lut) + + +def colorize( + image: Image.Image, + black: str | tuple[int, ...], + white: str | tuple[int, ...], + mid: str | int | tuple[int, ...] | None = None, + blackpoint: int = 0, + whitepoint: int = 255, + midpoint: int = 127, +) -> Image.Image: + """ + Colorize grayscale image. + This function calculates a color wedge which maps all black pixels in + the source image to the first color and all white pixels to the + second color. If ``mid`` is specified, it uses three-color mapping. + The ``black`` and ``white`` arguments should be RGB tuples or color names; + optionally you can use three-color mapping by also specifying ``mid``. + Mapping positions for any of the colors can be specified + (e.g. ``blackpoint``), where these parameters are the integer + value corresponding to where the corresponding color should be mapped. + These parameters must have logical order, such that + ``blackpoint <= midpoint <= whitepoint`` (if ``mid`` is specified). + + :param image: The image to colorize. + :param black: The color to use for black input pixels. + :param white: The color to use for white input pixels. + :param mid: The color to use for midtone input pixels. + :param blackpoint: an int value [0, 255] for the black mapping. + :param whitepoint: an int value [0, 255] for the white mapping. + :param midpoint: an int value [0, 255] for the midtone mapping. + :return: An image. + """ + + # Initial asserts + assert image.mode == "L" + if mid is None: + assert 0 <= blackpoint <= whitepoint <= 255 + else: + assert 0 <= blackpoint <= midpoint <= whitepoint <= 255 + + # Define colors from arguments + rgb_black = cast(Sequence[int], _color(black, "RGB")) + rgb_white = cast(Sequence[int], _color(white, "RGB")) + rgb_mid = cast(Sequence[int], _color(mid, "RGB")) if mid is not None else None + + # Empty lists for the mapping + red = [] + green = [] + blue = [] + + # Create the low-end values + for i in range(0, blackpoint): + red.append(rgb_black[0]) + green.append(rgb_black[1]) + blue.append(rgb_black[2]) + + # Create the mapping (2-color) + if rgb_mid is None: + range_map = range(0, whitepoint - blackpoint) + + for i in range_map: + red.append( + rgb_black[0] + i * (rgb_white[0] - rgb_black[0]) // len(range_map) + ) + green.append( + rgb_black[1] + i * (rgb_white[1] - rgb_black[1]) // len(range_map) + ) + blue.append( + rgb_black[2] + i * (rgb_white[2] - rgb_black[2]) // len(range_map) + ) + + # Create the mapping (3-color) + else: + range_map1 = range(0, midpoint - blackpoint) + range_map2 = range(0, whitepoint - midpoint) + + for i in range_map1: + red.append( + rgb_black[0] + i * (rgb_mid[0] - rgb_black[0]) // len(range_map1) + ) + green.append( + rgb_black[1] + i * (rgb_mid[1] - rgb_black[1]) // len(range_map1) + ) + blue.append( + rgb_black[2] + i * (rgb_mid[2] - rgb_black[2]) // len(range_map1) + ) + for i in range_map2: + red.append(rgb_mid[0] + i * (rgb_white[0] - rgb_mid[0]) // len(range_map2)) + green.append( + rgb_mid[1] + i * (rgb_white[1] - rgb_mid[1]) // len(range_map2) + ) + blue.append(rgb_mid[2] + i * (rgb_white[2] - rgb_mid[2]) // len(range_map2)) + + # Create the high-end values + for i in range(0, 256 - whitepoint): + red.append(rgb_white[0]) + green.append(rgb_white[1]) + blue.append(rgb_white[2]) + + # Return converted image + image = image.convert("RGB") + return _lut(image, red + green + blue) + + +def contain( + image: Image.Image, size: tuple[int, int], method: int = Image.Resampling.BICUBIC +) -> Image.Image: + """ + Returns a resized version of the image, set to the maximum width and height + within the requested size, while maintaining the original aspect ratio. + + :param image: The image to resize. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :return: An image. + """ + + im_ratio = image.width / image.height + dest_ratio = size[0] / size[1] + + if im_ratio != dest_ratio: + if im_ratio > dest_ratio: + new_height = round(image.height / image.width * size[0]) + if new_height != size[1]: + size = (size[0], new_height) + else: + new_width = round(image.width / image.height * size[1]) + if new_width != size[0]: + size = (new_width, size[1]) + return image.resize(size, resample=method) + + +def cover( + image: Image.Image, size: tuple[int, int], method: int = Image.Resampling.BICUBIC +) -> Image.Image: + """ + Returns a resized version of the image, so that the requested size is + covered, while maintaining the original aspect ratio. + + :param image: The image to resize. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :return: An image. + """ + + im_ratio = image.width / image.height + dest_ratio = size[0] / size[1] + + if im_ratio != dest_ratio: + if im_ratio < dest_ratio: + new_height = round(image.height / image.width * size[0]) + if new_height != size[1]: + size = (size[0], new_height) + else: + new_width = round(image.width / image.height * size[1]) + if new_width != size[0]: + size = (new_width, size[1]) + return image.resize(size, resample=method) + + +def pad( + image: Image.Image, + size: tuple[int, int], + method: int = Image.Resampling.BICUBIC, + color: str | int | tuple[int, ...] | None = None, + centering: tuple[float, float] = (0.5, 0.5), +) -> Image.Image: + """ + Returns a resized and padded version of the image, expanded to fill the + requested aspect ratio and size. + + :param image: The image to resize and crop. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :param color: The background color of the padded image. + :param centering: Control the position of the original image within the + padded version. + + (0.5, 0.5) will keep the image centered + (0, 0) will keep the image aligned to the top left + (1, 1) will keep the image aligned to the bottom + right + :return: An image. + """ + + resized = contain(image, size, method) + if resized.size == size: + out = resized + else: + out = Image.new(image.mode, size, color) + if resized.palette: + palette = resized.getpalette() + if palette is not None: + out.putpalette(palette) + if resized.width != size[0]: + x = round((size[0] - resized.width) * max(0, min(centering[0], 1))) + out.paste(resized, (x, 0)) + else: + y = round((size[1] - resized.height) * max(0, min(centering[1], 1))) + out.paste(resized, (0, y)) + return out + + +def crop(image: Image.Image, border: int = 0) -> Image.Image: + """ + Remove border from image. The same amount of pixels are removed + from all four sides. This function works on all image modes. + + .. seealso:: :py:meth:`~PIL.Image.Image.crop` + + :param image: The image to crop. + :param border: The number of pixels to remove. + :return: An image. + """ + left, top, right, bottom = _border(border) + return image.crop((left, top, image.size[0] - right, image.size[1] - bottom)) + + +def scale( + image: Image.Image, factor: float, resample: int = Image.Resampling.BICUBIC +) -> Image.Image: + """ + Returns a rescaled image by a specific factor given in parameter. + A factor greater than 1 expands the image, between 0 and 1 contracts the + image. + + :param image: The image to rescale. + :param factor: The expansion factor, as a float. + :param resample: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :returns: An :py:class:`~PIL.Image.Image` object. + """ + if factor == 1: + return image.copy() + elif factor <= 0: + msg = "the factor must be greater than 0" + raise ValueError(msg) + else: + size = (round(factor * image.width), round(factor * image.height)) + return image.resize(size, resample) + + +class SupportsGetMesh(Protocol): + """ + An object that supports the ``getmesh`` method, taking an image as an + argument, and returning a list of tuples. Each tuple contains two tuples, + the source box as a tuple of 4 integers, and a tuple of 8 integers for the + final quadrilateral, in order of top left, bottom left, bottom right, top + right. + """ + + def getmesh( + self, image: Image.Image + ) -> list[ + tuple[tuple[int, int, int, int], tuple[int, int, int, int, int, int, int, int]] + ]: ... + + +def deform( + image: Image.Image, + deformer: SupportsGetMesh, + resample: int = Image.Resampling.BILINEAR, +) -> Image.Image: + """ + Deform the image. + + :param image: The image to deform. + :param deformer: A deformer object. Any object that implements a + ``getmesh`` method can be used. + :param resample: An optional resampling filter. Same values possible as + in the PIL.Image.transform function. + :return: An image. + """ + return image.transform( + image.size, Image.Transform.MESH, deformer.getmesh(image), resample + ) + + +def equalize(image: Image.Image, mask: Image.Image | None = None) -> Image.Image: + """ + Equalize the image histogram. This function applies a non-linear + mapping to the input image, in order to create a uniform + distribution of grayscale values in the output image. + + :param image: The image to equalize. + :param mask: An optional mask. If given, only the pixels selected by + the mask are included in the analysis. + :return: An image. + """ + if image.mode == "P": + image = image.convert("RGB") + h = image.histogram(mask) + lut = [] + for b in range(0, len(h), 256): + histo = [_f for _f in h[b : b + 256] if _f] + if len(histo) <= 1: + lut.extend(list(range(256))) + else: + step = (functools.reduce(operator.add, histo) - histo[-1]) // 255 + if not step: + lut.extend(list(range(256))) + else: + n = step // 2 + for i in range(256): + lut.append(n // step) + n = n + h[i + b] + return _lut(image, lut) + + +def expand( + image: Image.Image, + border: int | tuple[int, ...] = 0, + fill: str | int | tuple[int, ...] = 0, +) -> Image.Image: + """ + Add border to the image + + :param image: The image to expand. + :param border: Border width, in pixels. + :param fill: Pixel fill value (a color value). Default is 0 (black). + :return: An image. + """ + left, top, right, bottom = _border(border) + width = left + image.size[0] + right + height = top + image.size[1] + bottom + color = _color(fill, image.mode) + if image.palette: + palette = ImagePalette.ImagePalette(palette=image.getpalette()) + if isinstance(color, tuple) and (len(color) == 3 or len(color) == 4): + color = palette.getcolor(color) + else: + palette = None + out = Image.new(image.mode, (width, height), color) + if palette: + out.putpalette(palette.palette) + out.paste(image, (left, top)) + return out + + +def fit( + image: Image.Image, + size: tuple[int, int], + method: int = Image.Resampling.BICUBIC, + bleed: float = 0.0, + centering: tuple[float, float] = (0.5, 0.5), +) -> Image.Image: + """ + Returns a resized and cropped version of the image, cropped to the + requested aspect ratio and size. + + This function was contributed by Kevin Cazabon. + + :param image: The image to resize and crop. + :param size: The requested output size in pixels, given as a + (width, height) tuple. + :param method: Resampling method to use. Default is + :py:attr:`~PIL.Image.Resampling.BICUBIC`. + See :ref:`concept-filters`. + :param bleed: Remove a border around the outside of the image from all + four edges. The value is a decimal percentage (use 0.01 for + one percent). The default value is 0 (no border). + Cannot be greater than or equal to 0.5. + :param centering: Control the cropping position. Use (0.5, 0.5) for + center cropping (e.g. if cropping the width, take 50% off + of the left side, and therefore 50% off the right side). + (0.0, 0.0) will crop from the top left corner (i.e. if + cropping the width, take all of the crop off of the right + side, and if cropping the height, take all of it off the + bottom). (1.0, 0.0) will crop from the bottom left + corner, etc. (i.e. if cropping the width, take all of the + crop off the left side, and if cropping the height take + none from the top, and therefore all off the bottom). + :return: An image. + """ + + # by Kevin Cazabon, Feb 17/2000 + # kevin@cazabon.com + # https://www.cazabon.com + + centering_x, centering_y = centering + + if not 0.0 <= centering_x <= 1.0: + centering_x = 0.5 + if not 0.0 <= centering_y <= 1.0: + centering_y = 0.5 + + if not 0.0 <= bleed < 0.5: + bleed = 0.0 + + # calculate the area to use for resizing and cropping, subtracting + # the 'bleed' around the edges + + # number of pixels to trim off on Top and Bottom, Left and Right + bleed_pixels = (bleed * image.size[0], bleed * image.size[1]) + + live_size = ( + image.size[0] - bleed_pixels[0] * 2, + image.size[1] - bleed_pixels[1] * 2, + ) + + # calculate the aspect ratio of the live_size + live_size_ratio = live_size[0] / live_size[1] + + # calculate the aspect ratio of the output image + output_ratio = size[0] / size[1] + + # figure out if the sides or top/bottom will be cropped off + if live_size_ratio == output_ratio: + # live_size is already the needed ratio + crop_width = live_size[0] + crop_height = live_size[1] + elif live_size_ratio >= output_ratio: + # live_size is wider than what's needed, crop the sides + crop_width = output_ratio * live_size[1] + crop_height = live_size[1] + else: + # live_size is taller than what's needed, crop the top and bottom + crop_width = live_size[0] + crop_height = live_size[0] / output_ratio + + # make the crop + crop_left = bleed_pixels[0] + (live_size[0] - crop_width) * centering_x + crop_top = bleed_pixels[1] + (live_size[1] - crop_height) * centering_y + + crop = (crop_left, crop_top, crop_left + crop_width, crop_top + crop_height) + + # resize the image and return it + return image.resize(size, method, box=crop) + + +def flip(image: Image.Image) -> Image.Image: + """ + Flip the image vertically (top to bottom). + + :param image: The image to flip. + :return: An image. + """ + return image.transpose(Image.Transpose.FLIP_TOP_BOTTOM) + + +def grayscale(image: Image.Image) -> Image.Image: + """ + Convert the image to grayscale. + + :param image: The image to convert. + :return: An image. + """ + return image.convert("L") + + +def invert(image: Image.Image) -> Image.Image: + """ + Invert (negate) the image. + + :param image: The image to invert. + :return: An image. + """ + lut = list(range(255, -1, -1)) + return image.point(lut) if image.mode == "1" else _lut(image, lut) + + +def mirror(image: Image.Image) -> Image.Image: + """ + Flip image horizontally (left to right). + + :param image: The image to mirror. + :return: An image. + """ + return image.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + + +def posterize(image: Image.Image, bits: int) -> Image.Image: + """ + Reduce the number of bits for each color channel. + + :param image: The image to posterize. + :param bits: The number of bits to keep for each channel (1-8). + :return: An image. + """ + mask = ~(2 ** (8 - bits) - 1) + lut = [i & mask for i in range(256)] + return _lut(image, lut) + + +def solarize(image: Image.Image, threshold: int = 128) -> Image.Image: + """ + Invert all pixel values above a threshold. + + :param image: The image to solarize. + :param threshold: All pixels above this grayscale level are inverted. + :return: An image. + """ + lut = [] + for i in range(256): + if i < threshold: + lut.append(i) + else: + lut.append(255 - i) + return _lut(image, lut) + + +def exif_transpose(image: Image.Image, *, in_place: bool = False) -> Image.Image | None: + """ + If an image has an EXIF Orientation tag, other than 1, transpose the image + accordingly, and remove the orientation data. + + :param image: The image to transpose. + :param in_place: Boolean. Keyword-only argument. + If ``True``, the original image is modified in-place, and ``None`` is returned. + If ``False`` (default), a new :py:class:`~PIL.Image.Image` object is returned + with the transposition applied. If there is no transposition, a copy of the + image will be returned. + """ + image.load() + image_exif = image.getexif() + orientation = image_exif.get(ExifTags.Base.Orientation, 1) + method = { + 2: Image.Transpose.FLIP_LEFT_RIGHT, + 3: Image.Transpose.ROTATE_180, + 4: Image.Transpose.FLIP_TOP_BOTTOM, + 5: Image.Transpose.TRANSPOSE, + 6: Image.Transpose.ROTATE_270, + 7: Image.Transpose.TRANSVERSE, + 8: Image.Transpose.ROTATE_90, + }.get(orientation) + if method is not None: + transposed_image = image.transpose(method) + if in_place: + image.im = transposed_image.im + image._size = transposed_image._size + exif_image = image if in_place else transposed_image + + exif = exif_image.getexif() + if ExifTags.Base.Orientation in exif: + del exif[ExifTags.Base.Orientation] + if "exif" in exif_image.info: + exif_image.info["exif"] = exif.tobytes() + elif "Raw profile type exif" in exif_image.info: + exif_image.info["Raw profile type exif"] = exif.tobytes().hex() + for key in ("XML:com.adobe.xmp", "xmp"): + if key in exif_image.info: + for pattern in ( + r'tiff:Orientation="([0-9])"', + r"([0-9])", + ): + value = exif_image.info[key] + exif_image.info[key] = ( + re.sub(pattern, "", value) + if isinstance(value, str) + else re.sub(pattern.encode(), b"", value) + ) + if not in_place: + return transposed_image + elif not in_place: + return image.copy() + return None diff --git a/venv/lib/python3.12/site-packages/PIL/ImagePalette.py b/venv/lib/python3.12/site-packages/PIL/ImagePalette.py new file mode 100644 index 0000000..183f855 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImagePalette.py @@ -0,0 +1,285 @@ +# +# The Python Imaging Library. +# $Id$ +# +# image palette object +# +# History: +# 1996-03-11 fl Rewritten. +# 1997-01-03 fl Up and running. +# 1997-08-23 fl Added load hack +# 2001-04-16 fl Fixed randint shadow bug in random() +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import array +from collections.abc import Sequence +from typing import IO, TYPE_CHECKING + +from . import GimpGradientFile, GimpPaletteFile, ImageColor, PaletteFile + +if TYPE_CHECKING: + from . import Image + + +class ImagePalette: + """ + Color palette for palette mapped images + + :param mode: The mode to use for the palette. See: + :ref:`concept-modes`. Defaults to "RGB" + :param palette: An optional palette. If given, it must be a bytearray, + an array or a list of ints between 0-255. The list must consist of + all channels for one color followed by the next color (e.g. RGBRGBRGB). + Defaults to an empty palette. + """ + + def __init__( + self, + mode: str = "RGB", + palette: Sequence[int] | bytes | bytearray | None = None, + ) -> None: + self.mode = mode + self.rawmode: str | None = None # if set, palette contains raw data + self.palette = palette or bytearray() + self.dirty: int | None = None + + @property + def palette(self) -> Sequence[int] | bytes | bytearray: + return self._palette + + @palette.setter + def palette(self, palette: Sequence[int] | bytes | bytearray) -> None: + self._colors: dict[tuple[int, ...], int] | None = None + self._palette = palette + + @property + def colors(self) -> dict[tuple[int, ...], int]: + if self._colors is None: + mode_len = len(self.mode) + self._colors = {} + for i in range(0, len(self.palette), mode_len): + color = tuple(self.palette[i : i + mode_len]) + if color in self._colors: + continue + self._colors[color] = i // mode_len + return self._colors + + @colors.setter + def colors(self, colors: dict[tuple[int, ...], int]) -> None: + self._colors = colors + + def copy(self) -> ImagePalette: + new = ImagePalette() + + new.mode = self.mode + new.rawmode = self.rawmode + if self.palette is not None: + new.palette = self.palette[:] + new.dirty = self.dirty + + return new + + def getdata(self) -> tuple[str, Sequence[int] | bytes | bytearray]: + """ + Get palette contents in format suitable for the low-level + ``im.putpalette`` primitive. + + .. warning:: This method is experimental. + """ + if self.rawmode: + return self.rawmode, self.palette + return self.mode, self.tobytes() + + def tobytes(self) -> bytes: + """Convert palette to bytes. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(self.palette, bytes): + return self.palette + arr = array.array("B", self.palette) + return arr.tobytes() + + # Declare tostring as an alias for tobytes + tostring = tobytes + + def _new_color_index( + self, image: Image.Image | None = None, e: Exception | None = None + ) -> int: + if not isinstance(self.palette, bytearray): + self._palette = bytearray(self.palette) + index = len(self.palette) // 3 + special_colors: tuple[int | tuple[int, ...] | None, ...] = () + if image: + special_colors = ( + image.info.get("background"), + image.info.get("transparency"), + ) + while index in special_colors: + index += 1 + if index >= 256: + if image: + # Search for an unused index + for i, count in reversed(list(enumerate(image.histogram()))): + if count == 0 and i not in special_colors: + index = i + break + if index >= 256: + msg = "cannot allocate more than 256 colors" + raise ValueError(msg) from e + return index + + def getcolor( + self, + color: tuple[int, ...], + image: Image.Image | None = None, + ) -> int: + """Given an rgb tuple, allocate palette entry. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(color, tuple): + if self.mode == "RGB": + if len(color) == 4: + if color[3] != 255: + msg = "cannot add non-opaque RGBA color to RGB palette" + raise ValueError(msg) + color = color[:3] + elif self.mode == "RGBA": + if len(color) == 3: + color += (255,) + try: + return self.colors[color] + except KeyError as e: + # allocate new color slot + index = self._new_color_index(image, e) + assert isinstance(self._palette, bytearray) + self.colors[color] = index + if index * 3 < len(self.palette): + self._palette = ( + self._palette[: index * 3] + + bytes(color) + + self._palette[index * 3 + 3 :] + ) + else: + self._palette += bytes(color) + self.dirty = 1 + return index + else: + msg = f"unknown color specifier: {repr(color)}" # type: ignore[unreachable] + raise ValueError(msg) + + def save(self, fp: str | IO[str]) -> None: + """Save palette to text file. + + .. warning:: This method is experimental. + """ + if self.rawmode: + msg = "palette contains raw palette data" + raise ValueError(msg) + if isinstance(fp, str): + fp = open(fp, "w") + fp.write("# Palette\n") + fp.write(f"# Mode: {self.mode}\n") + for i in range(256): + fp.write(f"{i}") + for j in range(i * len(self.mode), (i + 1) * len(self.mode)): + try: + fp.write(f" {self.palette[j]}") + except IndexError: + fp.write(" 0") + fp.write("\n") + fp.close() + + +# -------------------------------------------------------------------- +# Internal + + +def raw(rawmode: str, data: Sequence[int] | bytes | bytearray) -> ImagePalette: + palette = ImagePalette() + palette.rawmode = rawmode + palette.palette = data + palette.dirty = 1 + return palette + + +# -------------------------------------------------------------------- +# Factories + + +def make_linear_lut(black: int, white: float) -> list[int]: + if black == 0: + return [int(white * i // 255) for i in range(256)] + + msg = "unavailable when black is non-zero" + raise NotImplementedError(msg) # FIXME + + +def make_gamma_lut(exp: float) -> list[int]: + return [int(((i / 255.0) ** exp) * 255.0 + 0.5) for i in range(256)] + + +def negative(mode: str = "RGB") -> ImagePalette: + palette = list(range(256 * len(mode))) + palette.reverse() + return ImagePalette(mode, [i // len(mode) for i in palette]) + + +def random(mode: str = "RGB") -> ImagePalette: + from random import randint + + palette = [randint(0, 255) for _ in range(256 * len(mode))] + return ImagePalette(mode, palette) + + +def sepia(white: str = "#fff0c0") -> ImagePalette: + bands = [make_linear_lut(0, band) for band in ImageColor.getrgb(white)] + return ImagePalette("RGB", [bands[i % 3][i // 3] for i in range(256 * 3)]) + + +def wedge(mode: str = "RGB") -> ImagePalette: + palette = list(range(256 * len(mode))) + return ImagePalette(mode, [i // len(mode) for i in palette]) + + +def load(filename: str) -> tuple[bytes, str]: + # FIXME: supports GIMP gradients only + + with open(filename, "rb") as fp: + paletteHandlers: list[ + type[ + GimpPaletteFile.GimpPaletteFile + | GimpGradientFile.GimpGradientFile + | PaletteFile.PaletteFile + ] + ] = [ + GimpPaletteFile.GimpPaletteFile, + GimpGradientFile.GimpGradientFile, + PaletteFile.PaletteFile, + ] + for paletteHandler in paletteHandlers: + try: + fp.seek(0) + lut = paletteHandler(fp).getpalette() + if lut: + break + except (SyntaxError, ValueError): + pass + else: + msg = "cannot load palette" + raise OSError(msg) + + return lut # data, rawmode diff --git a/venv/lib/python3.12/site-packages/PIL/ImagePath.py b/venv/lib/python3.12/site-packages/PIL/ImagePath.py new file mode 100644 index 0000000..77e8a60 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImagePath.py @@ -0,0 +1,20 @@ +# +# The Python Imaging Library +# $Id$ +# +# path interface +# +# History: +# 1996-11-04 fl Created +# 2002-04-14 fl Added documentation stub class +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image + +Path = Image.core.path diff --git a/venv/lib/python3.12/site-packages/PIL/ImageQt.py b/venv/lib/python3.12/site-packages/PIL/ImageQt.py new file mode 100644 index 0000000..a3d6471 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageQt.py @@ -0,0 +1,216 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a simple Qt image interface. +# +# history: +# 2006-06-03 fl: created +# 2006-06-04 fl: inherit from QImage instead of wrapping it +# 2006-06-05 fl: removed toimage helper; move string support to ImageQt +# 2013-11-13 fl: add support for Qt5 (aurelien.ballier@cyclonit.com) +# +# Copyright (c) 2006 by Secret Labs AB +# Copyright (c) 2006 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys +from io import BytesIO +from typing import TYPE_CHECKING, Any, Callable, Union + +from . import Image +from ._util import is_path + +if TYPE_CHECKING: + import PyQt6 + import PySide6 + + from . import ImageFile + + QBuffer: type + QByteArray = Union[PyQt6.QtCore.QByteArray, PySide6.QtCore.QByteArray] + QIODevice = Union[PyQt6.QtCore.QIODevice, PySide6.QtCore.QIODevice] + QImage = Union[PyQt6.QtGui.QImage, PySide6.QtGui.QImage] + QPixmap = Union[PyQt6.QtGui.QPixmap, PySide6.QtGui.QPixmap] + +qt_version: str | None +qt_versions = [ + ["6", "PyQt6"], + ["side6", "PySide6"], +] + +# If a version has already been imported, attempt it first +qt_versions.sort(key=lambda version: version[1] in sys.modules, reverse=True) +for version, qt_module in qt_versions: + try: + qRgba: Callable[[int, int, int, int], int] + if qt_module == "PyQt6": + from PyQt6.QtCore import QBuffer, QIODevice + from PyQt6.QtGui import QImage, QPixmap, qRgba + elif qt_module == "PySide6": + from PySide6.QtCore import QBuffer, QIODevice + from PySide6.QtGui import QImage, QPixmap, qRgba + except (ImportError, RuntimeError): + continue + qt_is_installed = True + qt_version = version + break +else: + qt_is_installed = False + qt_version = None + + +def rgb(r: int, g: int, b: int, a: int = 255) -> int: + """(Internal) Turns an RGB color into a Qt compatible color integer.""" + # use qRgb to pack the colors, and then turn the resulting long + # into a negative integer with the same bitpattern. + return qRgba(r, g, b, a) & 0xFFFFFFFF + + +def fromqimage(im: QImage | QPixmap) -> ImageFile.ImageFile: + """ + :param im: QImage or PIL ImageQt object + """ + buffer = QBuffer() + qt_openmode: object + if qt_version == "6": + try: + qt_openmode = getattr(QIODevice, "OpenModeFlag") + except AttributeError: + qt_openmode = getattr(QIODevice, "OpenMode") + else: + qt_openmode = QIODevice + buffer.open(getattr(qt_openmode, "ReadWrite")) + # preserve alpha channel with png + # otherwise ppm is more friendly with Image.open + if im.hasAlphaChannel(): + im.save(buffer, "png") + else: + im.save(buffer, "ppm") + + b = BytesIO() + b.write(buffer.data()) + buffer.close() + b.seek(0) + + return Image.open(b) + + +def fromqpixmap(im: QPixmap) -> ImageFile.ImageFile: + return fromqimage(im) + + +def align8to32(bytes: bytes, width: int, mode: str) -> bytes: + """ + converts each scanline of data from 8 bit to 32 bit aligned + """ + + bits_per_pixel = {"1": 1, "L": 8, "P": 8, "I;16": 16}[mode] + + # calculate bytes per line and the extra padding if needed + bits_per_line = bits_per_pixel * width + full_bytes_per_line, remaining_bits_per_line = divmod(bits_per_line, 8) + bytes_per_line = full_bytes_per_line + (1 if remaining_bits_per_line else 0) + + extra_padding = -bytes_per_line % 4 + + # already 32 bit aligned by luck + if not extra_padding: + return bytes + + new_data = [ + bytes[i * bytes_per_line : (i + 1) * bytes_per_line] + b"\x00" * extra_padding + for i in range(len(bytes) // bytes_per_line) + ] + + return b"".join(new_data) + + +def _toqclass_helper(im: Image.Image | str | QByteArray) -> dict[str, Any]: + data = None + colortable = None + exclusive_fp = False + + # handle filename, if given instead of image name + if hasattr(im, "toUtf8"): + # FIXME - is this really the best way to do this? + im = str(im.toUtf8(), "utf-8") + if is_path(im): + im = Image.open(im) + exclusive_fp = True + assert isinstance(im, Image.Image) + + qt_format = getattr(QImage, "Format") if qt_version == "6" else QImage + if im.mode == "1": + format = getattr(qt_format, "Format_Mono") + elif im.mode == "L": + format = getattr(qt_format, "Format_Indexed8") + colortable = [rgb(i, i, i) for i in range(256)] + elif im.mode == "P": + format = getattr(qt_format, "Format_Indexed8") + palette = im.getpalette() + assert palette is not None + colortable = [rgb(*palette[i : i + 3]) for i in range(0, len(palette), 3)] + elif im.mode == "RGB": + # Populate the 4th channel with 255 + im = im.convert("RGBA") + + data = im.tobytes("raw", "BGRA") + format = getattr(qt_format, "Format_RGB32") + elif im.mode == "RGBA": + data = im.tobytes("raw", "BGRA") + format = getattr(qt_format, "Format_ARGB32") + elif im.mode == "I;16": + im = im.point(lambda i: i * 256) + + format = getattr(qt_format, "Format_Grayscale16") + else: + if exclusive_fp: + im.close() + msg = f"unsupported image mode {repr(im.mode)}" + raise ValueError(msg) + + size = im.size + __data = data or align8to32(im.tobytes(), size[0], im.mode) + if exclusive_fp: + im.close() + return {"data": __data, "size": size, "format": format, "colortable": colortable} + + +if qt_is_installed: + + class ImageQt(QImage): # type: ignore[misc] + def __init__(self, im: Image.Image | str | QByteArray) -> None: + """ + An PIL image wrapper for Qt. This is a subclass of PyQt's QImage + class. + + :param im: A PIL Image object, or a file name (given either as + Python string or a PyQt string object). + """ + im_data = _toqclass_helper(im) + # must keep a reference, or Qt will crash! + # All QImage constructors that take data operate on an existing + # buffer, so this buffer has to hang on for the life of the image. + # Fixes https://github.com/python-pillow/Pillow/issues/1370 + self.__data = im_data["data"] + super().__init__( + self.__data, + im_data["size"][0], + im_data["size"][1], + im_data["format"], + ) + if im_data["colortable"]: + self.setColorTable(im_data["colortable"]) + + +def toqimage(im: Image.Image | str | QByteArray) -> ImageQt: + return ImageQt(im) + + +def toqpixmap(im: Image.Image | str | QByteArray) -> QPixmap: + qimage = toqimage(im) + return getattr(QPixmap, "fromImage")(qimage) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageSequence.py b/venv/lib/python3.12/site-packages/PIL/ImageSequence.py new file mode 100644 index 0000000..a6fc340 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageSequence.py @@ -0,0 +1,86 @@ +# +# The Python Imaging Library. +# $Id$ +# +# sequence support classes +# +# history: +# 1997-02-20 fl Created +# +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +from __future__ import annotations + +from typing import Callable + +from . import Image + + +class Iterator: + """ + This class implements an iterator object that can be used to loop + over an image sequence. + + You can use the ``[]`` operator to access elements by index. This operator + will raise an :py:exc:`IndexError` if you try to access a nonexistent + frame. + + :param im: An image object. + """ + + def __init__(self, im: Image.Image) -> None: + if not hasattr(im, "seek"): + msg = "im must have seek method" + raise AttributeError(msg) + self.im = im + self.position = getattr(self.im, "_min_frame", 0) + + def __getitem__(self, ix: int) -> Image.Image: + try: + self.im.seek(ix) + return self.im + except EOFError as e: + msg = "end of sequence" + raise IndexError(msg) from e + + def __iter__(self) -> Iterator: + return self + + def __next__(self) -> Image.Image: + try: + self.im.seek(self.position) + self.position += 1 + return self.im + except EOFError as e: + msg = "end of sequence" + raise StopIteration(msg) from e + + +def all_frames( + im: Image.Image | list[Image.Image], + func: Callable[[Image.Image], Image.Image] | None = None, +) -> list[Image.Image]: + """ + Applies a given function to all frames in an image or a list of images. + The frames are returned as a list of separate images. + + :param im: An image, or a list of images. + :param func: The function to apply to all of the image frames. + :returns: A list of images. + """ + if not isinstance(im, list): + im = [im] + + ims = [] + for imSequence in im: + current = imSequence.tell() + + ims += [im_frame.copy() for im_frame in Iterator(imSequence)] + + imSequence.seek(current) + return [func(im) for im in ims] if func else ims diff --git a/venv/lib/python3.12/site-packages/PIL/ImageShow.py b/venv/lib/python3.12/site-packages/PIL/ImageShow.py new file mode 100644 index 0000000..d62893d --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageShow.py @@ -0,0 +1,360 @@ +# +# The Python Imaging Library. +# $Id$ +# +# im.show() drivers +# +# History: +# 2008-04-06 fl Created +# +# Copyright (c) Secret Labs AB 2008. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import abc +import os +import shutil +import subprocess +import sys +from shlex import quote +from typing import Any + +from . import Image + +_viewers = [] + + +def register(viewer: type[Viewer] | Viewer, order: int = 1) -> None: + """ + The :py:func:`register` function is used to register additional viewers:: + + from PIL import ImageShow + ImageShow.register(MyViewer()) # MyViewer will be used as a last resort + ImageShow.register(MySecondViewer(), 0) # MySecondViewer will be prioritised + ImageShow.register(ImageShow.XVViewer(), 0) # XVViewer will be prioritised + + :param viewer: The viewer to be registered. + :param order: + Zero or a negative integer to prepend this viewer to the list, + a positive integer to append it. + """ + if isinstance(viewer, type) and issubclass(viewer, Viewer): + viewer = viewer() + if order > 0: + _viewers.append(viewer) + else: + _viewers.insert(0, viewer) + + +def show(image: Image.Image, title: str | None = None, **options: Any) -> bool: + r""" + Display a given image. + + :param image: An image object. + :param title: Optional title. Not all viewers can display the title. + :param \**options: Additional viewer options. + :returns: ``True`` if a suitable viewer was found, ``False`` otherwise. + """ + for viewer in _viewers: + if viewer.show(image, title=title, **options): + return True + return False + + +class Viewer: + """Base class for viewers.""" + + # main api + + def show(self, image: Image.Image, **options: Any) -> int: + """ + The main function for displaying an image. + Converts the given image to the target format and displays it. + """ + + if not ( + image.mode in ("1", "RGBA") + or (self.format == "PNG" and image.mode in ("I;16", "LA")) + ): + base = Image.getmodebase(image.mode) + if image.mode != base: + image = image.convert(base) + + return self.show_image(image, **options) + + # hook methods + + format: str | None = None + """The format to convert the image into.""" + options: dict[str, Any] = {} + """Additional options used to convert the image.""" + + def get_format(self, image: Image.Image) -> str | None: + """Return format name, or ``None`` to save as PGM/PPM.""" + return self.format + + def get_command(self, file: str, **options: Any) -> str: + """ + Returns the command used to display the file. + Not implemented in the base class. + """ + msg = "unavailable in base viewer" + raise NotImplementedError(msg) + + def save_image(self, image: Image.Image) -> str: + """Save to temporary file and return filename.""" + return image._dump(format=self.get_format(image), **self.options) + + def show_image(self, image: Image.Image, **options: Any) -> int: + """Display the given image.""" + return self.show_file(self.save_image(image), **options) + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + os.system(self.get_command(path, **options)) # nosec + return 1 + + +# -------------------------------------------------------------------- + + +class WindowsViewer(Viewer): + """The default viewer on Windows is the default system application for PNG files.""" + + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + def get_command(self, file: str, **options: Any) -> str: + return ( + f'start "Pillow" /WAIT "{file}" ' + "&& ping -n 4 127.0.0.1 >NUL " + f'&& del /f "{file}"' + ) + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + subprocess.Popen( + self.get_command(path, **options), + shell=True, + creationflags=getattr(subprocess, "CREATE_NO_WINDOW"), + ) # nosec + return 1 + + +if sys.platform == "win32": + register(WindowsViewer) + + +class MacViewer(Viewer): + """The default viewer on macOS using ``Preview.app``.""" + + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + def get_command(self, file: str, **options: Any) -> str: + # on darwin open returns immediately resulting in the temp + # file removal while app is opening + command = "open -a Preview.app" + command = f"({command} {quote(file)}; sleep 20; rm -f {quote(file)})&" + return command + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + subprocess.call(["open", "-a", "Preview.app", path]) + executable = sys.executable or shutil.which("python3") + if executable: + subprocess.Popen( + [ + executable, + "-c", + "import os, sys, time; time.sleep(20); os.remove(sys.argv[1])", + path, + ] + ) + return 1 + + +if sys.platform == "darwin": + register(MacViewer) + + +class UnixViewer(Viewer): + format = "PNG" + options = {"compress_level": 1, "save_all": True} + + @abc.abstractmethod + def get_command_ex(self, file: str, **options: Any) -> tuple[str, str]: + pass + + def get_command(self, file: str, **options: Any) -> str: + command = self.get_command_ex(file, **options)[0] + return f"{command} {quote(file)}" + + +class XDGViewer(UnixViewer): + """ + The freedesktop.org ``xdg-open`` command. + """ + + def get_command_ex(self, file: str, **options: Any) -> tuple[str, str]: + command = executable = "xdg-open" + return command, executable + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + subprocess.Popen(["xdg-open", path]) + return 1 + + +class DisplayViewer(UnixViewer): + """ + The ImageMagick ``display`` command. + This viewer supports the ``title`` parameter. + """ + + def get_command_ex( + self, file: str, title: str | None = None, **options: Any + ) -> tuple[str, str]: + command = executable = "display" + if title: + command += f" -title {quote(title)}" + return command, executable + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + args = ["display"] + title = options.get("title") + if title: + args += ["-title", title] + args.append(path) + + subprocess.Popen(args) + return 1 + + +class GmDisplayViewer(UnixViewer): + """The GraphicsMagick ``gm display`` command.""" + + def get_command_ex(self, file: str, **options: Any) -> tuple[str, str]: + executable = "gm" + command = "gm display" + return command, executable + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + subprocess.Popen(["gm", "display", path]) + return 1 + + +class EogViewer(UnixViewer): + """The GNOME Image Viewer ``eog`` command.""" + + def get_command_ex(self, file: str, **options: Any) -> tuple[str, str]: + executable = "eog" + command = "eog -n" + return command, executable + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + subprocess.Popen(["eog", "-n", path]) + return 1 + + +class XVViewer(UnixViewer): + """ + The X Viewer ``xv`` command. + This viewer supports the ``title`` parameter. + """ + + def get_command_ex( + self, file: str, title: str | None = None, **options: Any + ) -> tuple[str, str]: + # note: xv is pretty outdated. most modern systems have + # imagemagick's display command instead. + command = executable = "xv" + if title: + command += f" -name {quote(title)}" + return command, executable + + def show_file(self, path: str, **options: Any) -> int: + """ + Display given file. + """ + if not os.path.exists(path): + raise FileNotFoundError + args = ["xv"] + title = options.get("title") + if title: + args += ["-name", title] + args.append(path) + + subprocess.Popen(args) + return 1 + + +if sys.platform not in ("win32", "darwin"): # unixoids + if shutil.which("xdg-open"): + register(XDGViewer) + if shutil.which("display"): + register(DisplayViewer) + if shutil.which("gm"): + register(GmDisplayViewer) + if shutil.which("eog"): + register(EogViewer) + if shutil.which("xv"): + register(XVViewer) + + +class IPythonViewer(Viewer): + """The viewer for IPython frontends.""" + + def show_image(self, image: Image.Image, **options: Any) -> int: + ipython_display(image) + return 1 + + +try: + from IPython.display import display as ipython_display +except ImportError: + pass +else: + register(IPythonViewer) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 ImageShow.py imagefile [title]") + sys.exit() + + with Image.open(sys.argv[1]) as im: + print(show(im, *sys.argv[2:])) diff --git a/venv/lib/python3.12/site-packages/PIL/ImageStat.py b/venv/lib/python3.12/site-packages/PIL/ImageStat.py new file mode 100644 index 0000000..8bc5045 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageStat.py @@ -0,0 +1,160 @@ +# +# The Python Imaging Library. +# $Id$ +# +# global image statistics +# +# History: +# 1996-04-05 fl Created +# 1997-05-21 fl Added mask; added rms, var, stddev attributes +# 1997-08-05 fl Added median +# 1998-07-05 hk Fixed integer overflow error +# +# Notes: +# This class shows how to implement delayed evaluation of attributes. +# To get a certain value, simply access the corresponding attribute. +# The __getattr__ dispatcher takes care of the rest. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math +from functools import cached_property + +from . import Image + + +class Stat: + def __init__( + self, image_or_list: Image.Image | list[int], mask: Image.Image | None = None + ) -> None: + """ + Calculate statistics for the given image. If a mask is included, + only the regions covered by that mask are included in the + statistics. You can also pass in a previously calculated histogram. + + :param image: A PIL image, or a precalculated histogram. + + .. note:: + + For a PIL image, calculations rely on the + :py:meth:`~PIL.Image.Image.histogram` method. The pixel counts are + grouped into 256 bins, even if the image has more than 8 bits per + channel. So ``I`` and ``F`` mode images have a maximum ``mean``, + ``median`` and ``rms`` of 255, and cannot have an ``extrema`` maximum + of more than 255. + + :param mask: An optional mask. + """ + if isinstance(image_or_list, Image.Image): + self.h = image_or_list.histogram(mask) + elif isinstance(image_or_list, list): + self.h = image_or_list + else: + msg = "first argument must be image or list" # type: ignore[unreachable] + raise TypeError(msg) + self.bands = list(range(len(self.h) // 256)) + + @cached_property + def extrema(self) -> list[tuple[int, int]]: + """ + Min/max values for each band in the image. + + .. note:: + This relies on the :py:meth:`~PIL.Image.Image.histogram` method, and + simply returns the low and high bins used. This is correct for + images with 8 bits per channel, but fails for other modes such as + ``I`` or ``F``. Instead, use :py:meth:`~PIL.Image.Image.getextrema` to + return per-band extrema for the image. This is more correct and + efficient because, for non-8-bit modes, the histogram method uses + :py:meth:`~PIL.Image.Image.getextrema` to determine the bins used. + """ + + def minmax(histogram: list[int]) -> tuple[int, int]: + res_min, res_max = 255, 0 + for i in range(256): + if histogram[i]: + res_min = i + break + for i in range(255, -1, -1): + if histogram[i]: + res_max = i + break + return res_min, res_max + + return [minmax(self.h[i:]) for i in range(0, len(self.h), 256)] + + @cached_property + def count(self) -> list[int]: + """Total number of pixels for each band in the image.""" + return [sum(self.h[i : i + 256]) for i in range(0, len(self.h), 256)] + + @cached_property + def sum(self) -> list[float]: + """Sum of all pixels for each band in the image.""" + + v = [] + for i in range(0, len(self.h), 256): + layer_sum = 0.0 + for j in range(256): + layer_sum += j * self.h[i + j] + v.append(layer_sum) + return v + + @cached_property + def sum2(self) -> list[float]: + """Squared sum of all pixels for each band in the image.""" + + v = [] + for i in range(0, len(self.h), 256): + sum2 = 0.0 + for j in range(256): + sum2 += (j**2) * float(self.h[i + j]) + v.append(sum2) + return v + + @cached_property + def mean(self) -> list[float]: + """Average (arithmetic mean) pixel level for each band in the image.""" + return [self.sum[i] / self.count[i] for i in self.bands] + + @cached_property + def median(self) -> list[int]: + """Median pixel level for each band in the image.""" + + v = [] + for i in self.bands: + s = 0 + half = self.count[i] // 2 + b = i * 256 + for j in range(256): + s = s + self.h[b + j] + if s > half: + break + v.append(j) + return v + + @cached_property + def rms(self) -> list[float]: + """RMS (root-mean-square) for each band in the image.""" + return [math.sqrt(self.sum2[i] / self.count[i]) for i in self.bands] + + @cached_property + def var(self) -> list[float]: + """Variance for each band in the image.""" + return [ + (self.sum2[i] - (self.sum[i] ** 2.0) / self.count[i]) / self.count[i] + for i in self.bands + ] + + @cached_property + def stddev(self) -> list[float]: + """Standard deviation for each band in the image.""" + return [math.sqrt(self.var[i]) for i in self.bands] + + +Global = Stat # compatibility diff --git a/venv/lib/python3.12/site-packages/PIL/ImageTk.py b/venv/lib/python3.12/site-packages/PIL/ImageTk.py new file mode 100644 index 0000000..bf29fdb --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageTk.py @@ -0,0 +1,290 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Tk display interface +# +# History: +# 96-04-08 fl Created +# 96-09-06 fl Added getimage method +# 96-11-01 fl Rewritten, removed image attribute and crop method +# 97-05-09 fl Use PyImagingPaste method instead of image type +# 97-05-12 fl Minor tweaks to match the IFUNC95 interface +# 97-05-17 fl Support the "pilbitmap" booster patch +# 97-06-05 fl Added file= and data= argument to image constructors +# 98-03-09 fl Added width and height methods to Image classes +# 98-07-02 fl Use default mode for "P" images without palette attribute +# 98-07-02 fl Explicitly destroy Tkinter image objects +# 99-07-24 fl Support multiple Tk interpreters (from Greg Couch) +# 99-07-26 fl Automatically hook into Tkinter (if possible) +# 99-08-15 fl Hook uses _imagingtk instead of _imaging +# +# Copyright (c) 1997-1999 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import tkinter +from io import BytesIO +from typing import TYPE_CHECKING, Any, cast + +from . import Image, ImageFile + +if TYPE_CHECKING: + from ._typing import CapsuleType + +# -------------------------------------------------------------------- +# Check for Tkinter interface hooks + + +def _get_image_from_kw(kw: dict[str, Any]) -> ImageFile.ImageFile | None: + source = None + if "file" in kw: + source = kw.pop("file") + elif "data" in kw: + source = BytesIO(kw.pop("data")) + if not source: + return None + return Image.open(source) + + +def _pyimagingtkcall( + command: str, photo: PhotoImage | tkinter.PhotoImage, ptr: CapsuleType +) -> None: + tk = photo.tk + try: + tk.call(command, photo, repr(ptr)) + except tkinter.TclError: + # activate Tkinter hook + # may raise an error if it cannot attach to Tkinter + from . import _imagingtk + + _imagingtk.tkinit(tk.interpaddr()) + tk.call(command, photo, repr(ptr)) + + +# -------------------------------------------------------------------- +# PhotoImage + + +class PhotoImage: + """ + A Tkinter-compatible photo image. This can be used + everywhere Tkinter expects an image object. If the image is an RGBA + image, pixels having alpha 0 are treated as transparent. + + The constructor takes either a PIL image, or a mode and a size. + Alternatively, you can use the ``file`` or ``data`` options to initialize + the photo image object. + + :param image: Either a PIL image, or a mode string. If a mode string is + used, a size must also be given. + :param size: If the first argument is a mode string, this defines the size + of the image. + :keyword file: A filename to load the image from (using + ``Image.open(file)``). + :keyword data: An 8-bit string containing image data (as loaded from an + image file). + """ + + def __init__( + self, + image: Image.Image | str | None = None, + size: tuple[int, int] | None = None, + **kw: Any, + ) -> None: + # Tk compatibility: file or data + if image is None: + image = _get_image_from_kw(kw) + + if image is None: + msg = "Image is required" + raise ValueError(msg) + elif isinstance(image, str): + mode = image + image = None + + if size is None: + msg = "If first argument is mode, size is required" + raise ValueError(msg) + else: + # got an image instead of a mode + mode = image.mode + if mode == "P": + # palette mapped data + image.apply_transparency() + image.load() + mode = image.palette.mode if image.palette else "RGB" + size = image.size + kw["width"], kw["height"] = size + + if mode not in ["1", "L", "RGB", "RGBA"]: + mode = Image.getmodebase(mode) + + self.__mode = mode + self.__size = size + self.__photo = tkinter.PhotoImage(**kw) + self.tk = self.__photo.tk + if image: + self.paste(image) + + def __del__(self) -> None: + try: + name = self.__photo.name + except AttributeError: + return + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except Exception: + pass # ignore internal errors + + def __str__(self) -> str: + """ + Get the Tkinter photo image identifier. This method is automatically + called by Tkinter whenever a PhotoImage object is passed to a Tkinter + method. + + :return: A Tkinter photo image identifier (a string). + """ + return str(self.__photo) + + def width(self) -> int: + """ + Get the width of the image. + + :return: The width, in pixels. + """ + return self.__size[0] + + def height(self) -> int: + """ + Get the height of the image. + + :return: The height, in pixels. + """ + return self.__size[1] + + def paste(self, im: Image.Image) -> None: + """ + Paste a PIL image into the photo image. Note that this can + be very slow if the photo image is displayed. + + :param im: A PIL image. The size must match the target region. If the + mode does not match, the image is converted to the mode of + the bitmap image. + """ + # convert to blittable + ptr = im.getim() + image = im.im + if not image.isblock() or im.mode != self.__mode: + block = Image.core.new_block(self.__mode, im.size) + image.convert2(block, image) # convert directly between buffers + ptr = block.ptr + + _pyimagingtkcall("PyImagingPhoto", self.__photo, ptr) + + +# -------------------------------------------------------------------- +# BitmapImage + + +class BitmapImage: + """ + A Tkinter-compatible bitmap image. This can be used everywhere Tkinter + expects an image object. + + The given image must have mode "1". Pixels having value 0 are treated as + transparent. Options, if any, are passed on to Tkinter. The most commonly + used option is ``foreground``, which is used to specify the color for the + non-transparent parts. See the Tkinter documentation for information on + how to specify colours. + + :param image: A PIL image. + """ + + def __init__(self, image: Image.Image | None = None, **kw: Any) -> None: + # Tk compatibility: file or data + if image is None: + image = _get_image_from_kw(kw) + + if image is None: + msg = "Image is required" + raise ValueError(msg) + self.__mode = image.mode + self.__size = image.size + + self.__photo = tkinter.BitmapImage(data=image.tobitmap(), **kw) + + def __del__(self) -> None: + try: + name = self.__photo.name + except AttributeError: + return + self.__photo.name = None + try: + self.__photo.tk.call("image", "delete", name) + except Exception: + pass # ignore internal errors + + def width(self) -> int: + """ + Get the width of the image. + + :return: The width, in pixels. + """ + return self.__size[0] + + def height(self) -> int: + """ + Get the height of the image. + + :return: The height, in pixels. + """ + return self.__size[1] + + def __str__(self) -> str: + """ + Get the Tkinter bitmap image identifier. This method is automatically + called by Tkinter whenever a BitmapImage object is passed to a Tkinter + method. + + :return: A Tkinter bitmap image identifier (a string). + """ + return str(self.__photo) + + +def getimage(photo: PhotoImage) -> Image.Image: + """Copies the contents of a PhotoImage to a PIL image memory.""" + im = Image.new("RGBA", (photo.width(), photo.height())) + + _pyimagingtkcall("PyImagingPhotoGet", photo, im.getim()) + + return im + + +def _show(image: Image.Image, title: str | None) -> None: + """Helper for the Image.show method.""" + + class UI(tkinter.Label): + def __init__(self, master: tkinter.Toplevel, im: Image.Image) -> None: + self.image: BitmapImage | PhotoImage + if im.mode == "1": + self.image = BitmapImage(im, foreground="white", master=master) + else: + self.image = PhotoImage(im, master=master) + if TYPE_CHECKING: + image = cast(tkinter._Image, self.image) + else: + image = self.image + super().__init__(master, image=image, bg="black", bd=0) + + if not getattr(tkinter, "_default_root"): + msg = "tkinter not initialized" + raise OSError(msg) + top = tkinter.Toplevel() + if title: + top.title(title) + UI(top, image).pack() diff --git a/venv/lib/python3.12/site-packages/PIL/ImageTransform.py b/venv/lib/python3.12/site-packages/PIL/ImageTransform.py new file mode 100644 index 0000000..a3d8f44 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageTransform.py @@ -0,0 +1,136 @@ +# +# The Python Imaging Library. +# $Id$ +# +# transform wrappers +# +# History: +# 2002-04-08 fl Created +# +# Copyright (c) 2002 by Secret Labs AB +# Copyright (c) 2002 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from collections.abc import Sequence +from typing import Any + +from . import Image + + +class Transform(Image.ImageTransformHandler): + """Base class for other transforms defined in :py:mod:`~PIL.ImageTransform`.""" + + method: Image.Transform + + def __init__(self, data: Sequence[Any]) -> None: + self.data = data + + def getdata(self) -> tuple[Image.Transform, Sequence[int]]: + return self.method, self.data + + def transform( + self, + size: tuple[int, int], + image: Image.Image, + **options: Any, + ) -> Image.Image: + """Perform the transform. Called from :py:meth:`.Image.transform`.""" + # can be overridden + method, data = self.getdata() + return image.transform(size, method, data, **options) + + +class AffineTransform(Transform): + """ + Define an affine image transform. + + This function takes a 6-tuple (a, b, c, d, e, f) which contain the first + two rows from an affine transform matrix. For each pixel (x, y) in the + output image, the new value is taken from a position (a x + b y + c, + d x + e y + f) in the input image, rounded to nearest pixel. + + This function can be used to scale, translate, rotate, and shear the + original image. + + See :py:meth:`.Image.transform` + + :param matrix: A 6-tuple (a, b, c, d, e, f) containing the first two rows + from an affine transform matrix. + """ + + method = Image.Transform.AFFINE + + +class PerspectiveTransform(Transform): + """ + Define a perspective image transform. + + This function takes an 8-tuple (a, b, c, d, e, f, g, h). For each pixel + (x, y) in the output image, the new value is taken from a position + ((a x + b y + c) / (g x + h y + 1), (d x + e y + f) / (g x + h y + 1)) in + the input image, rounded to nearest pixel. + + This function can be used to scale, translate, rotate, and shear the + original image. + + See :py:meth:`.Image.transform` + + :param matrix: An 8-tuple (a, b, c, d, e, f, g, h). + """ + + method = Image.Transform.PERSPECTIVE + + +class ExtentTransform(Transform): + """ + Define a transform to extract a subregion from an image. + + Maps a rectangle (defined by two corners) from the image to a rectangle of + the given size. The resulting image will contain data sampled from between + the corners, such that (x0, y0) in the input image will end up at (0,0) in + the output image, and (x1, y1) at size. + + This method can be used to crop, stretch, shrink, or mirror an arbitrary + rectangle in the current image. It is slightly slower than crop, but about + as fast as a corresponding resize operation. + + See :py:meth:`.Image.transform` + + :param bbox: A 4-tuple (x0, y0, x1, y1) which specifies two points in the + input image's coordinate system. See :ref:`coordinate-system`. + """ + + method = Image.Transform.EXTENT + + +class QuadTransform(Transform): + """ + Define a quad image transform. + + Maps a quadrilateral (a region defined by four corners) from the image to a + rectangle of the given size. + + See :py:meth:`.Image.transform` + + :param xy: An 8-tuple (x0, y0, x1, y1, x2, y2, x3, y3) which contain the + upper left, lower left, lower right, and upper right corner of the + source quadrilateral. + """ + + method = Image.Transform.QUAD + + +class MeshTransform(Transform): + """ + Define a mesh image transform. A mesh transform consists of one or more + individual quad transforms. + + See :py:meth:`.Image.transform` + + :param data: A list of (bbox, quad) tuples. + """ + + method = Image.Transform.MESH diff --git a/venv/lib/python3.12/site-packages/PIL/ImageWin.py b/venv/lib/python3.12/site-packages/PIL/ImageWin.py new file mode 100644 index 0000000..98c28f2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImageWin.py @@ -0,0 +1,247 @@ +# +# The Python Imaging Library. +# $Id$ +# +# a Windows DIB display interface +# +# History: +# 1996-05-20 fl Created +# 1996-09-20 fl Fixed subregion exposure +# 1997-09-21 fl Added draw primitive (for tzPrint) +# 2003-05-21 fl Added experimental Window/ImageWindow classes +# 2003-09-05 fl Added fromstring/tostring methods +# +# Copyright (c) Secret Labs AB 1997-2003. +# Copyright (c) Fredrik Lundh 1996-2003. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image + + +class HDC: + """ + Wraps an HDC integer. The resulting object can be passed to the + :py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose` + methods. + """ + + def __init__(self, dc: int) -> None: + self.dc = dc + + def __int__(self) -> int: + return self.dc + + +class HWND: + """ + Wraps an HWND integer. The resulting object can be passed to the + :py:meth:`~PIL.ImageWin.Dib.draw` and :py:meth:`~PIL.ImageWin.Dib.expose` + methods, instead of a DC. + """ + + def __init__(self, wnd: int) -> None: + self.wnd = wnd + + def __int__(self) -> int: + return self.wnd + + +class Dib: + """ + A Windows bitmap with the given mode and size. The mode can be one of "1", + "L", "P", or "RGB". + + If the display requires a palette, this constructor creates a suitable + palette and associates it with the image. For an "L" image, 128 graylevels + are allocated. For an "RGB" image, a 6x6x6 colour cube is used, together + with 20 graylevels. + + To make sure that palettes work properly under Windows, you must call the + ``palette`` method upon certain events from Windows. + + :param image: Either a PIL image, or a mode string. If a mode string is + used, a size must also be given. The mode can be one of "1", + "L", "P", or "RGB". + :param size: If the first argument is a mode string, this + defines the size of the image. + """ + + def __init__( + self, image: Image.Image | str, size: tuple[int, int] | None = None + ) -> None: + if isinstance(image, str): + mode = image + image = "" + if size is None: + msg = "If first argument is mode, size is required" + raise ValueError(msg) + else: + mode = image.mode + size = image.size + if mode not in ["1", "L", "P", "RGB"]: + mode = Image.getmodebase(mode) + self.image = Image.core.display(mode, size) + self.mode = mode + self.size = size + if image: + assert not isinstance(image, str) + self.paste(image) + + def expose(self, handle: int | HDC | HWND) -> None: + """ + Copy the bitmap contents to a device context. + + :param handle: Device context (HDC), cast to a Python integer, or an + HDC or HWND instance. In PythonWin, you can use + ``CDC.GetHandleAttrib()`` to get a suitable handle. + """ + handle_int = int(handle) + if isinstance(handle, HWND): + dc = self.image.getdc(handle_int) + try: + self.image.expose(dc) + finally: + self.image.releasedc(handle_int, dc) + else: + self.image.expose(handle_int) + + def draw( + self, + handle: int | HDC | HWND, + dst: tuple[int, int, int, int], + src: tuple[int, int, int, int] | None = None, + ) -> None: + """ + Same as expose, but allows you to specify where to draw the image, and + what part of it to draw. + + The destination and source areas are given as 4-tuple rectangles. If + the source is omitted, the entire image is copied. If the source and + the destination have different sizes, the image is resized as + necessary. + """ + if src is None: + src = (0, 0) + self.size + handle_int = int(handle) + if isinstance(handle, HWND): + dc = self.image.getdc(handle_int) + try: + self.image.draw(dc, dst, src) + finally: + self.image.releasedc(handle_int, dc) + else: + self.image.draw(handle_int, dst, src) + + def query_palette(self, handle: int | HDC | HWND) -> int: + """ + Installs the palette associated with the image in the given device + context. + + This method should be called upon **QUERYNEWPALETTE** and + **PALETTECHANGED** events from Windows. If this method returns a + non-zero value, one or more display palette entries were changed, and + the image should be redrawn. + + :param handle: Device context (HDC), cast to a Python integer, or an + HDC or HWND instance. + :return: The number of entries that were changed (if one or more entries, + this indicates that the image should be redrawn). + """ + handle_int = int(handle) + if isinstance(handle, HWND): + handle = self.image.getdc(handle_int) + try: + result = self.image.query_palette(handle) + finally: + self.image.releasedc(handle, handle) + else: + result = self.image.query_palette(handle_int) + return result + + def paste( + self, im: Image.Image, box: tuple[int, int, int, int] | None = None + ) -> None: + """ + Paste a PIL image into the bitmap image. + + :param im: A PIL image. The size must match the target region. + If the mode does not match, the image is converted to the + mode of the bitmap image. + :param box: A 4-tuple defining the left, upper, right, and + lower pixel coordinate. See :ref:`coordinate-system`. If + None is given instead of a tuple, all of the image is + assumed. + """ + im.load() + if self.mode != im.mode: + im = im.convert(self.mode) + if box: + self.image.paste(im.im, box) + else: + self.image.paste(im.im) + + def frombytes(self, buffer: bytes) -> None: + """ + Load display memory contents from byte data. + + :param buffer: A buffer containing display data (usually + data returned from :py:func:`~PIL.ImageWin.Dib.tobytes`) + """ + self.image.frombytes(buffer) + + def tobytes(self) -> bytes: + """ + Copy display memory contents to bytes object. + + :return: A bytes object containing display data. + """ + return self.image.tobytes() + + +class Window: + """Create a Window with the given title size.""" + + def __init__( + self, title: str = "PIL", width: int | None = None, height: int | None = None + ) -> None: + self.hwnd = Image.core.createwindow( + title, self.__dispatcher, width or 0, height or 0 + ) + + def __dispatcher(self, action: str, *args: int) -> None: + getattr(self, f"ui_handle_{action}")(*args) + + def ui_handle_clear(self, dc: int, x0: int, y0: int, x1: int, y1: int) -> None: + pass + + def ui_handle_damage(self, x0: int, y0: int, x1: int, y1: int) -> None: + pass + + def ui_handle_destroy(self) -> None: + pass + + def ui_handle_repair(self, dc: int, x0: int, y0: int, x1: int, y1: int) -> None: + pass + + def ui_handle_resize(self, width: int, height: int) -> None: + pass + + def mainloop(self) -> None: + Image.core.eventloop() + + +class ImageWindow(Window): + """Create an image window which displays the given image.""" + + def __init__(self, image: Image.Image | Dib, title: str = "PIL") -> None: + if not isinstance(image, Dib): + image = Dib(image) + self.image = image + width, height = image.size + super().__init__(title, width=width, height=height) + + def ui_handle_repair(self, dc: int, x0: int, y0: int, x1: int, y1: int) -> None: + self.image.draw(dc, (x0, y0, x1, y1)) diff --git a/venv/lib/python3.12/site-packages/PIL/ImtImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/ImtImagePlugin.py new file mode 100644 index 0000000..594c565 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/ImtImagePlugin.py @@ -0,0 +1,103 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IM Tools support for PIL +# +# history: +# 1996-05-27 fl Created (read 8-bit images only) +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.2) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from . import Image, ImageFile + +# +# -------------------------------------------------------------------- + +field = re.compile(rb"([a-z]*) ([^ \r\n]*)") + + +## +# Image plugin for IM Tools images. + + +class ImtImageFile(ImageFile.ImageFile): + format = "IMT" + format_description = "IM Tools" + + def _open(self) -> None: + # Quick rejection: if there's not a LF among the first + # 100 bytes, this is (probably) not a text header. + + assert self.fp is not None + + buffer = self.fp.read(100) + if b"\n" not in buffer: + msg = "not an IM file" + raise SyntaxError(msg) + + xsize = ysize = 0 + + while True: + if buffer: + s = buffer[:1] + buffer = buffer[1:] + else: + s = self.fp.read(1) + if not s: + break + + if s == b"\x0C": + # image data begins + self.tile = [ + ImageFile._Tile( + "raw", + (0, 0) + self.size, + self.fp.tell() - len(buffer), + (self.mode, 0, 1), + ) + ] + + break + + else: + # read key/value pair + if b"\n" not in buffer: + buffer += self.fp.read(100) + lines = buffer.split(b"\n") + s += lines.pop(0) + buffer = b"\n".join(lines) + if len(s) == 1 or len(s) > 100: + break + if s[0] == ord(b"*"): + continue # comment + + m = field.match(s) + if not m: + break + k, v = m.group(1, 2) + if k == b"width": + xsize = int(v) + self._size = xsize, ysize + elif k == b"height": + ysize = int(v) + self._size = xsize, ysize + elif k == b"pixel" and v == b"n8": + self._mode = "L" + + +# +# -------------------------------------------------------------------- + +Image.register_open(ImtImageFile.format, ImtImageFile) + +# +# no extension registered (".im" is simply too common) diff --git a/venv/lib/python3.12/site-packages/PIL/IptcImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/IptcImagePlugin.py new file mode 100644 index 0000000..60ab7c8 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/IptcImagePlugin.py @@ -0,0 +1,249 @@ +# +# The Python Imaging Library. +# $Id$ +# +# IPTC/NAA file handling +# +# history: +# 1995-10-01 fl Created +# 1998-03-09 fl Cleaned up and added to PIL +# 2002-06-18 fl Added getiptcinfo helper +# +# Copyright (c) Secret Labs AB 1997-2002. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from collections.abc import Sequence +from io import BytesIO +from typing import cast + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._deprecate import deprecate + +COMPRESSION = {1: "raw", 5: "jpeg"} + + +def __getattr__(name: str) -> bytes: + if name == "PAD": + deprecate("IptcImagePlugin.PAD", 12) + return b"\0\0\0\0" + msg = f"module '{__name__}' has no attribute '{name}'" + raise AttributeError(msg) + + +# +# Helpers + + +def _i(c: bytes) -> int: + return i32((b"\0\0\0\0" + c)[-4:]) + + +def _i8(c: int | bytes) -> int: + return c if isinstance(c, int) else c[0] + + +def i(c: bytes) -> int: + """.. deprecated:: 10.2.0""" + deprecate("IptcImagePlugin.i", 12) + return _i(c) + + +def dump(c: Sequence[int | bytes]) -> None: + """.. deprecated:: 10.2.0""" + deprecate("IptcImagePlugin.dump", 12) + for i in c: + print(f"{_i8(i):02x}", end=" ") + print() + + +## +# Image plugin for IPTC/NAA datastreams. To read IPTC/NAA fields +# from TIFF and JPEG files, use the getiptcinfo function. + + +class IptcImageFile(ImageFile.ImageFile): + format = "IPTC" + format_description = "IPTC/NAA" + + def getint(self, key: tuple[int, int]) -> int: + return _i(self.info[key]) + + def field(self) -> tuple[tuple[int, int] | None, int]: + # + # get a IPTC field header + s = self.fp.read(5) + if not s.strip(b"\x00"): + return None, 0 + + tag = s[1], s[2] + + # syntax + if s[0] != 0x1C or tag[0] not in [1, 2, 3, 4, 5, 6, 7, 8, 9, 240]: + msg = "invalid IPTC/NAA file" + raise SyntaxError(msg) + + # field size + size = s[3] + if size > 132: + msg = "illegal field length in IPTC/NAA file" + raise OSError(msg) + elif size == 128: + size = 0 + elif size > 128: + size = _i(self.fp.read(size - 128)) + else: + size = i16(s, 3) + + return tag, size + + def _open(self) -> None: + # load descriptive fields + while True: + offset = self.fp.tell() + tag, size = self.field() + if not tag or tag == (8, 10): + break + if size: + tagdata = self.fp.read(size) + else: + tagdata = None + if tag in self.info: + if isinstance(self.info[tag], list): + self.info[tag].append(tagdata) + else: + self.info[tag] = [self.info[tag], tagdata] + else: + self.info[tag] = tagdata + + # mode + layers = self.info[(3, 60)][0] + component = self.info[(3, 60)][1] + if (3, 65) in self.info: + id = self.info[(3, 65)][0] - 1 + else: + id = 0 + if layers == 1 and not component: + self._mode = "L" + elif layers == 3 and component: + self._mode = "RGB"[id] + elif layers == 4 and component: + self._mode = "CMYK"[id] + + # size + self._size = self.getint((3, 20)), self.getint((3, 30)) + + # compression + try: + compression = COMPRESSION[self.getint((3, 120))] + except KeyError as e: + msg = "Unknown IPTC image compression" + raise OSError(msg) from e + + # tile + if tag == (8, 10): + self.tile = [ + ImageFile._Tile("iptc", (0, 0) + self.size, offset, compression) + ] + + def load(self) -> Image.core.PixelAccess | None: + if len(self.tile) != 1 or self.tile[0][0] != "iptc": + return ImageFile.ImageFile.load(self) + + offset, compression = self.tile[0][2:] + + self.fp.seek(offset) + + # Copy image data to temporary file + o = BytesIO() + if compression == "raw": + # To simplify access to the extracted file, + # prepend a PPM header + o.write(b"P5\n%d %d\n255\n" % self.size) + while True: + type, size = self.field() + if type != (8, 10): + break + while size > 0: + s = self.fp.read(min(size, 8192)) + if not s: + break + o.write(s) + size -= len(s) + + with Image.open(o) as _im: + _im.load() + self.im = _im.im + return None + + +Image.register_open(IptcImageFile.format, IptcImageFile) + +Image.register_extension(IptcImageFile.format, ".iim") + + +def getiptcinfo( + im: ImageFile.ImageFile, +) -> dict[tuple[int, int], bytes | list[bytes]] | None: + """ + Get IPTC information from TIFF, JPEG, or IPTC file. + + :param im: An image containing IPTC data. + :returns: A dictionary containing IPTC information, or None if + no IPTC information block was found. + """ + from . import JpegImagePlugin, TiffImagePlugin + + data = None + + info: dict[tuple[int, int], bytes | list[bytes]] = {} + if isinstance(im, IptcImageFile): + # return info dictionary right away + for k, v in im.info.items(): + if isinstance(k, tuple): + info[k] = v + return info + + elif isinstance(im, JpegImagePlugin.JpegImageFile): + # extract the IPTC/NAA resource + photoshop = im.info.get("photoshop") + if photoshop: + data = photoshop.get(0x0404) + + elif isinstance(im, TiffImagePlugin.TiffImageFile): + # get raw data from the IPTC/NAA tag (PhotoShop tags the data + # as 4-byte integers, so we cannot use the get method...) + try: + data = im.tag_v2[TiffImagePlugin.IPTC_NAA_CHUNK] + except KeyError: + pass + + if data is None: + return None # no properties + + # create an IptcImagePlugin object without initializing it + class FakeImage: + pass + + fake_im = FakeImage() + fake_im.__class__ = IptcImageFile # type: ignore[assignment] + iptc_im = cast(IptcImageFile, fake_im) + + # parse the IPTC information chunk + iptc_im.info = {} + iptc_im.fp = BytesIO(data) + + try: + iptc_im._open() + except (IndexError, KeyError): + pass # expected failure + + for k, v in iptc_im.info.items(): + if isinstance(k, tuple): + info[k] = v + return info diff --git a/venv/lib/python3.12/site-packages/PIL/Jpeg2KImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/Jpeg2KImagePlugin.py new file mode 100644 index 0000000..b6ebd56 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/Jpeg2KImagePlugin.py @@ -0,0 +1,443 @@ +# +# The Python Imaging Library +# $Id$ +# +# JPEG2000 file handling +# +# History: +# 2014-03-12 ajh Created +# 2021-06-30 rogermb Extract dpi information from the 'resc' header box +# +# Copyright (c) 2014 Coriolis Systems Limited +# Copyright (c) 2014 Alastair Houghton +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import os +import struct +from collections.abc import Callable +from typing import IO, cast + +from . import Image, ImageFile, ImagePalette, _binary + + +class BoxReader: + """ + A small helper class to read fields stored in JPEG2000 header boxes + and to easily step into and read sub-boxes. + """ + + def __init__(self, fp: IO[bytes], length: int = -1) -> None: + self.fp = fp + self.has_length = length >= 0 + self.length = length + self.remaining_in_box = -1 + + def _can_read(self, num_bytes: int) -> bool: + if self.has_length and self.fp.tell() + num_bytes > self.length: + # Outside box: ensure we don't read past the known file length + return False + if self.remaining_in_box >= 0: + # Inside box contents: ensure read does not go past box boundaries + return num_bytes <= self.remaining_in_box + else: + return True # No length known, just read + + def _read_bytes(self, num_bytes: int) -> bytes: + if not self._can_read(num_bytes): + msg = "Not enough data in header" + raise SyntaxError(msg) + + data = self.fp.read(num_bytes) + if len(data) < num_bytes: + msg = f"Expected to read {num_bytes} bytes but only got {len(data)}." + raise OSError(msg) + + if self.remaining_in_box > 0: + self.remaining_in_box -= num_bytes + return data + + def read_fields(self, field_format: str) -> tuple[int | bytes, ...]: + size = struct.calcsize(field_format) + data = self._read_bytes(size) + return struct.unpack(field_format, data) + + def read_boxes(self) -> BoxReader: + size = self.remaining_in_box + data = self._read_bytes(size) + return BoxReader(io.BytesIO(data), size) + + def has_next_box(self) -> bool: + if self.has_length: + return self.fp.tell() + self.remaining_in_box < self.length + else: + return True + + def next_box_type(self) -> bytes: + # Skip the rest of the box if it has not been read + if self.remaining_in_box > 0: + self.fp.seek(self.remaining_in_box, os.SEEK_CUR) + self.remaining_in_box = -1 + + # Read the length and type of the next box + lbox, tbox = cast(tuple[int, bytes], self.read_fields(">I4s")) + if lbox == 1: + lbox = cast(int, self.read_fields(">Q")[0]) + hlen = 16 + else: + hlen = 8 + + if lbox < hlen or not self._can_read(lbox - hlen): + msg = "Invalid header length" + raise SyntaxError(msg) + + self.remaining_in_box = lbox - hlen + return tbox + + +def _parse_codestream(fp: IO[bytes]) -> tuple[tuple[int, int], str]: + """Parse the JPEG 2000 codestream to extract the size and component + count from the SIZ marker segment, returning a PIL (size, mode) tuple.""" + + hdr = fp.read(2) + lsiz = _binary.i16be(hdr) + siz = hdr + fp.read(lsiz - 2) + lsiz, rsiz, xsiz, ysiz, xosiz, yosiz, _, _, _, _, csiz = struct.unpack_from( + ">HHIIIIIIIIH", siz + ) + + size = (xsiz - xosiz, ysiz - yosiz) + if csiz == 1: + ssiz = struct.unpack_from(">B", siz, 38) + if (ssiz[0] & 0x7F) + 1 > 8: + mode = "I;16" + else: + mode = "L" + elif csiz == 2: + mode = "LA" + elif csiz == 3: + mode = "RGB" + elif csiz == 4: + mode = "RGBA" + else: + msg = "unable to determine J2K image mode" + raise SyntaxError(msg) + + return size, mode + + +def _res_to_dpi(num: int, denom: int, exp: int) -> float | None: + """Convert JPEG2000's (numerator, denominator, exponent-base-10) resolution, + calculated as (num / denom) * 10^exp and stored in dots per meter, + to floating-point dots per inch.""" + if denom == 0: + return None + return (254 * num * (10**exp)) / (10000 * denom) + + +def _parse_jp2_header( + fp: IO[bytes], +) -> tuple[ + tuple[int, int], + str, + str | None, + tuple[float, float] | None, + ImagePalette.ImagePalette | None, +]: + """Parse the JP2 header box to extract size, component count, + color space information, and optionally DPI information, + returning a (size, mode, mimetype, dpi) tuple.""" + + # Find the JP2 header box + reader = BoxReader(fp) + header = None + mimetype = None + while reader.has_next_box(): + tbox = reader.next_box_type() + + if tbox == b"jp2h": + header = reader.read_boxes() + break + elif tbox == b"ftyp": + if reader.read_fields(">4s")[0] == b"jpx ": + mimetype = "image/jpx" + assert header is not None + + size = None + mode = None + bpc = None + nc = None + dpi = None # 2-tuple of DPI info, or None + palette = None + + while header.has_next_box(): + tbox = header.next_box_type() + + if tbox == b"ihdr": + height, width, nc, bpc = header.read_fields(">IIHB") + assert isinstance(height, int) + assert isinstance(width, int) + assert isinstance(bpc, int) + size = (width, height) + if nc == 1 and (bpc & 0x7F) > 8: + mode = "I;16" + elif nc == 1: + mode = "L" + elif nc == 2: + mode = "LA" + elif nc == 3: + mode = "RGB" + elif nc == 4: + mode = "RGBA" + elif tbox == b"colr" and nc == 4: + meth, _, _, enumcs = header.read_fields(">BBBI") + if meth == 1 and enumcs == 12: + mode = "CMYK" + elif tbox == b"pclr" and mode in ("L", "LA"): + ne, npc = header.read_fields(">HB") + assert isinstance(ne, int) + assert isinstance(npc, int) + max_bitdepth = 0 + for bitdepth in header.read_fields(">" + ("B" * npc)): + assert isinstance(bitdepth, int) + if bitdepth > max_bitdepth: + max_bitdepth = bitdepth + if max_bitdepth <= 8: + palette = ImagePalette.ImagePalette("RGBA" if npc == 4 else "RGB") + for i in range(ne): + color: list[int] = [] + for value in header.read_fields(">" + ("B" * npc)): + assert isinstance(value, int) + color.append(value) + palette.getcolor(tuple(color)) + mode = "P" if mode == "L" else "PA" + elif tbox == b"res ": + res = header.read_boxes() + while res.has_next_box(): + tres = res.next_box_type() + if tres == b"resc": + vrcn, vrcd, hrcn, hrcd, vrce, hrce = res.read_fields(">HHHHBB") + assert isinstance(vrcn, int) + assert isinstance(vrcd, int) + assert isinstance(hrcn, int) + assert isinstance(hrcd, int) + assert isinstance(vrce, int) + assert isinstance(hrce, int) + hres = _res_to_dpi(hrcn, hrcd, hrce) + vres = _res_to_dpi(vrcn, vrcd, vrce) + if hres is not None and vres is not None: + dpi = (hres, vres) + break + + if size is None or mode is None: + msg = "Malformed JP2 header" + raise SyntaxError(msg) + + return size, mode, mimetype, dpi, palette + + +## +# Image plugin for JPEG2000 images. + + +class Jpeg2KImageFile(ImageFile.ImageFile): + format = "JPEG2000" + format_description = "JPEG 2000 (ISO 15444)" + + def _open(self) -> None: + sig = self.fp.read(4) + if sig == b"\xff\x4f\xff\x51": + self.codec = "j2k" + self._size, self._mode = _parse_codestream(self.fp) + else: + sig = sig + self.fp.read(8) + + if sig == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a": + self.codec = "jp2" + header = _parse_jp2_header(self.fp) + self._size, self._mode, self.custom_mimetype, dpi, self.palette = header + if dpi is not None: + self.info["dpi"] = dpi + if self.fp.read(12).endswith(b"jp2c\xff\x4f\xff\x51"): + self._parse_comment() + else: + msg = "not a JPEG 2000 file" + raise SyntaxError(msg) + + self._reduce = 0 + self.layers = 0 + + fd = -1 + length = -1 + + try: + fd = self.fp.fileno() + length = os.fstat(fd).st_size + except Exception: + fd = -1 + try: + pos = self.fp.tell() + self.fp.seek(0, io.SEEK_END) + length = self.fp.tell() + self.fp.seek(pos) + except Exception: + length = -1 + + self.tile = [ + ImageFile._Tile( + "jpeg2k", + (0, 0) + self.size, + 0, + (self.codec, self._reduce, self.layers, fd, length), + ) + ] + + def _parse_comment(self) -> None: + hdr = self.fp.read(2) + length = _binary.i16be(hdr) + self.fp.seek(length - 2, os.SEEK_CUR) + + while True: + marker = self.fp.read(2) + if not marker: + break + typ = marker[1] + if typ in (0x90, 0xD9): + # Start of tile or end of codestream + break + hdr = self.fp.read(2) + length = _binary.i16be(hdr) + if typ == 0x64: + # Comment + self.info["comment"] = self.fp.read(length - 2)[2:] + break + else: + self.fp.seek(length - 2, os.SEEK_CUR) + + @property # type: ignore[override] + def reduce( + self, + ) -> ( + Callable[[int | tuple[int, int], tuple[int, int, int, int] | None], Image.Image] + | int + ): + # https://github.com/python-pillow/Pillow/issues/4343 found that the + # new Image 'reduce' method was shadowed by this plugin's 'reduce' + # property. This attempts to allow for both scenarios + return self._reduce or super().reduce + + @reduce.setter + def reduce(self, value: int) -> None: + self._reduce = value + + def load(self) -> Image.core.PixelAccess | None: + if self.tile and self._reduce: + power = 1 << self._reduce + adjust = power >> 1 + self._size = ( + int((self.size[0] + adjust) / power), + int((self.size[1] + adjust) / power), + ) + + # Update the reduce and layers settings + t = self.tile[0] + assert isinstance(t[3], tuple) + t3 = (t[3][0], self._reduce, self.layers, t[3][3], t[3][4]) + self.tile = [ImageFile._Tile(t[0], (0, 0) + self.size, t[2], t3)] + + return ImageFile.ImageFile.load(self) + + +def _accept(prefix: bytes) -> bool: + return ( + prefix[:4] == b"\xff\x4f\xff\x51" + or prefix[:12] == b"\x00\x00\x00\x0cjP \x0d\x0a\x87\x0a" + ) + + +# ------------------------------------------------------------ +# Save support + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + # Get the keyword arguments + info = im.encoderinfo + + if isinstance(filename, str): + filename = filename.encode() + if filename.endswith(b".j2k") or info.get("no_jp2", False): + kind = "j2k" + else: + kind = "jp2" + + offset = info.get("offset", None) + tile_offset = info.get("tile_offset", None) + tile_size = info.get("tile_size", None) + quality_mode = info.get("quality_mode", "rates") + quality_layers = info.get("quality_layers", None) + if quality_layers is not None and not ( + isinstance(quality_layers, (list, tuple)) + and all( + isinstance(quality_layer, (int, float)) for quality_layer in quality_layers + ) + ): + msg = "quality_layers must be a sequence of numbers" + raise ValueError(msg) + + num_resolutions = info.get("num_resolutions", 0) + cblk_size = info.get("codeblock_size", None) + precinct_size = info.get("precinct_size", None) + irreversible = info.get("irreversible", False) + progression = info.get("progression", "LRCP") + cinema_mode = info.get("cinema_mode", "no") + mct = info.get("mct", 0) + signed = info.get("signed", False) + comment = info.get("comment") + if isinstance(comment, str): + comment = comment.encode() + plt = info.get("plt", False) + + fd = -1 + if hasattr(fp, "fileno"): + try: + fd = fp.fileno() + except Exception: + fd = -1 + + im.encoderconfig = ( + offset, + tile_offset, + tile_size, + quality_mode, + quality_layers, + num_resolutions, + cblk_size, + precinct_size, + irreversible, + progression, + cinema_mode, + mct, + signed, + fd, + comment, + plt, + ) + + ImageFile._save(im, fp, [ImageFile._Tile("jpeg2k", (0, 0) + im.size, 0, kind)]) + + +# ------------------------------------------------------------ +# Registry stuff + + +Image.register_open(Jpeg2KImageFile.format, Jpeg2KImageFile, _accept) +Image.register_save(Jpeg2KImageFile.format, _save) + +Image.register_extensions( + Jpeg2KImageFile.format, [".jp2", ".j2k", ".jpc", ".jpf", ".jpx", ".j2c"] +) + +Image.register_mime(Jpeg2KImageFile.format, "image/jp2") diff --git a/venv/lib/python3.12/site-packages/PIL/JpegImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/JpegImagePlugin.py new file mode 100644 index 0000000..6510e07 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/JpegImagePlugin.py @@ -0,0 +1,895 @@ +# +# The Python Imaging Library. +# $Id$ +# +# JPEG (JFIF) file handling +# +# See "Digital Compression and Coding of Continuous-Tone Still Images, +# Part 1, Requirements and Guidelines" (CCITT T.81 / ISO 10918-1) +# +# History: +# 1995-09-09 fl Created +# 1995-09-13 fl Added full parser +# 1996-03-25 fl Added hack to use the IJG command line utilities +# 1996-05-05 fl Workaround Photoshop 2.5 CMYK polarity bug +# 1996-05-28 fl Added draft support, JFIF version (0.1) +# 1996-12-30 fl Added encoder options, added progression property (0.2) +# 1997-08-27 fl Save mode 1 images as BW (0.3) +# 1998-07-12 fl Added YCbCr to draft and save methods (0.4) +# 1998-10-19 fl Don't hang on files using 16-bit DQT's (0.4.1) +# 2001-04-16 fl Extract DPI settings from JFIF files (0.4.2) +# 2002-07-01 fl Skip pad bytes before markers; identify Exif files (0.4.3) +# 2003-04-25 fl Added experimental EXIF decoder (0.5) +# 2003-06-06 fl Added experimental EXIF GPSinfo decoder +# 2003-09-13 fl Extract COM markers +# 2009-09-06 fl Added icc_profile support (from Florian Hoech) +# 2009-03-06 fl Changed CMYK handling; always use Adobe polarity (0.6) +# 2009-03-08 fl Added subsampling support (from Justin Huff). +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import array +import io +import math +import os +import struct +import subprocess +import sys +import tempfile +import warnings +from typing import IO, TYPE_CHECKING, Any + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from ._binary import o16be as o16 +from ._deprecate import deprecate +from .JpegPresets import presets + +if TYPE_CHECKING: + from .MpoImagePlugin import MpoImageFile + +# +# Parser + + +def Skip(self: JpegImageFile, marker: int) -> None: + n = i16(self.fp.read(2)) - 2 + ImageFile._safe_read(self.fp, n) + + +def APP(self: JpegImageFile, marker: int) -> None: + # + # Application marker. Store these in the APP dictionary. + # Also look for well-known application markers. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + + app = "APP%d" % (marker & 15) + + self.app[app] = s # compatibility + self.applist.append((app, s)) + + if marker == 0xFFE0 and s[:4] == b"JFIF": + # extract JFIF information + self.info["jfif"] = version = i16(s, 5) # version + self.info["jfif_version"] = divmod(version, 256) + # extract JFIF properties + try: + jfif_unit = s[7] + jfif_density = i16(s, 8), i16(s, 10) + except Exception: + pass + else: + if jfif_unit == 1: + self.info["dpi"] = jfif_density + self.info["jfif_unit"] = jfif_unit + self.info["jfif_density"] = jfif_density + elif marker == 0xFFE1 and s[:6] == b"Exif\0\0": + # extract EXIF information + if "exif" in self.info: + self.info["exif"] += s[6:] + else: + self.info["exif"] = s + self._exif_offset = self.fp.tell() - n + 6 + elif marker == 0xFFE1 and s[:29] == b"http://ns.adobe.com/xap/1.0/\x00": + self.info["xmp"] = s.split(b"\x00", 1)[1] + elif marker == 0xFFE2 and s[:5] == b"FPXR\0": + # extract FlashPix information (incomplete) + self.info["flashpix"] = s # FIXME: value will change + elif marker == 0xFFE2 and s[:12] == b"ICC_PROFILE\0": + # Since an ICC profile can be larger than the maximum size of + # a JPEG marker (64K), we need provisions to split it into + # multiple markers. The format defined by the ICC specifies + # one or more APP2 markers containing the following data: + # Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + # Marker sequence number 1, 2, etc (1 byte) + # Number of markers Total of APP2's used (1 byte) + # Profile data (remainder of APP2 data) + # Decoders should use the marker sequence numbers to + # reassemble the profile, rather than assuming that the APP2 + # markers appear in the correct sequence. + self.icclist.append(s) + elif marker == 0xFFED and s[:14] == b"Photoshop 3.0\x00": + # parse the image resource block + offset = 14 + photoshop = self.info.setdefault("photoshop", {}) + while s[offset : offset + 4] == b"8BIM": + try: + offset += 4 + # resource code + code = i16(s, offset) + offset += 2 + # resource name (usually empty) + name_len = s[offset] + # name = s[offset+1:offset+1+name_len] + offset += 1 + name_len + offset += offset & 1 # align + # resource data block + size = i32(s, offset) + offset += 4 + data = s[offset : offset + size] + if code == 0x03ED: # ResolutionInfo + photoshop[code] = { + "XResolution": i32(data, 0) / 65536, + "DisplayedUnitsX": i16(data, 4), + "YResolution": i32(data, 8) / 65536, + "DisplayedUnitsY": i16(data, 12), + } + else: + photoshop[code] = data + offset += size + offset += offset & 1 # align + except struct.error: + break # insufficient data + + elif marker == 0xFFEE and s[:5] == b"Adobe": + self.info["adobe"] = i16(s, 5) + # extract Adobe custom properties + try: + adobe_transform = s[11] + except IndexError: + pass + else: + self.info["adobe_transform"] = adobe_transform + elif marker == 0xFFE2 and s[:4] == b"MPF\0": + # extract MPO information + self.info["mp"] = s[4:] + # offset is current location minus buffer size + # plus constant header size + self.info["mpoffset"] = self.fp.tell() - n + 4 + + +def COM(self: JpegImageFile, marker: int) -> None: + # + # Comment marker. Store these in the APP dictionary. + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + + self.info["comment"] = s + self.app["COM"] = s # compatibility + self.applist.append(("COM", s)) + + +def SOF(self: JpegImageFile, marker: int) -> None: + # + # Start of frame marker. Defines the size and mode of the + # image. JPEG is colour blind, so we use some simple + # heuristics to map the number of layers to an appropriate + # mode. Note that this could be made a bit brighter, by + # looking for JFIF and Adobe APP markers. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + self._size = i16(s, 3), i16(s, 1) + + self.bits = s[0] + if self.bits != 8: + msg = f"cannot handle {self.bits}-bit layers" + raise SyntaxError(msg) + + self.layers = s[5] + if self.layers == 1: + self._mode = "L" + elif self.layers == 3: + self._mode = "RGB" + elif self.layers == 4: + self._mode = "CMYK" + else: + msg = f"cannot handle {self.layers}-layer images" + raise SyntaxError(msg) + + if marker in [0xFFC2, 0xFFC6, 0xFFCA, 0xFFCE]: + self.info["progressive"] = self.info["progression"] = 1 + + if self.icclist: + # fixup icc profile + self.icclist.sort() # sort by sequence number + if self.icclist[0][13] == len(self.icclist): + profile = [p[14:] for p in self.icclist] + icc_profile = b"".join(profile) + else: + icc_profile = None # wrong number of fragments + self.info["icc_profile"] = icc_profile + self.icclist = [] + + for i in range(6, len(s), 3): + t = s[i : i + 3] + # 4-tuples: id, vsamp, hsamp, qtable + self.layer.append((t[0], t[1] // 16, t[1] & 15, t[2])) + + +def DQT(self: JpegImageFile, marker: int) -> None: + # + # Define quantization table. Note that there might be more + # than one table in each marker. + + # FIXME: The quantization tables can be used to estimate the + # compression quality. + + n = i16(self.fp.read(2)) - 2 + s = ImageFile._safe_read(self.fp, n) + while len(s): + v = s[0] + precision = 1 if (v // 16 == 0) else 2 # in bytes + qt_length = 1 + precision * 64 + if len(s) < qt_length: + msg = "bad quantization table marker" + raise SyntaxError(msg) + data = array.array("B" if precision == 1 else "H", s[1:qt_length]) + if sys.byteorder == "little" and precision > 1: + data.byteswap() # the values are always big-endian + self.quantization[v & 15] = [data[i] for i in zigzag_index] + s = s[qt_length:] + + +# +# JPEG marker table + +MARKER = { + 0xFFC0: ("SOF0", "Baseline DCT", SOF), + 0xFFC1: ("SOF1", "Extended Sequential DCT", SOF), + 0xFFC2: ("SOF2", "Progressive DCT", SOF), + 0xFFC3: ("SOF3", "Spatial lossless", SOF), + 0xFFC4: ("DHT", "Define Huffman table", Skip), + 0xFFC5: ("SOF5", "Differential sequential DCT", SOF), + 0xFFC6: ("SOF6", "Differential progressive DCT", SOF), + 0xFFC7: ("SOF7", "Differential spatial", SOF), + 0xFFC8: ("JPG", "Extension", None), + 0xFFC9: ("SOF9", "Extended sequential DCT (AC)", SOF), + 0xFFCA: ("SOF10", "Progressive DCT (AC)", SOF), + 0xFFCB: ("SOF11", "Spatial lossless DCT (AC)", SOF), + 0xFFCC: ("DAC", "Define arithmetic coding conditioning", Skip), + 0xFFCD: ("SOF13", "Differential sequential DCT (AC)", SOF), + 0xFFCE: ("SOF14", "Differential progressive DCT (AC)", SOF), + 0xFFCF: ("SOF15", "Differential spatial (AC)", SOF), + 0xFFD0: ("RST0", "Restart 0", None), + 0xFFD1: ("RST1", "Restart 1", None), + 0xFFD2: ("RST2", "Restart 2", None), + 0xFFD3: ("RST3", "Restart 3", None), + 0xFFD4: ("RST4", "Restart 4", None), + 0xFFD5: ("RST5", "Restart 5", None), + 0xFFD6: ("RST6", "Restart 6", None), + 0xFFD7: ("RST7", "Restart 7", None), + 0xFFD8: ("SOI", "Start of image", None), + 0xFFD9: ("EOI", "End of image", None), + 0xFFDA: ("SOS", "Start of scan", Skip), + 0xFFDB: ("DQT", "Define quantization table", DQT), + 0xFFDC: ("DNL", "Define number of lines", Skip), + 0xFFDD: ("DRI", "Define restart interval", Skip), + 0xFFDE: ("DHP", "Define hierarchical progression", SOF), + 0xFFDF: ("EXP", "Expand reference component", Skip), + 0xFFE0: ("APP0", "Application segment 0", APP), + 0xFFE1: ("APP1", "Application segment 1", APP), + 0xFFE2: ("APP2", "Application segment 2", APP), + 0xFFE3: ("APP3", "Application segment 3", APP), + 0xFFE4: ("APP4", "Application segment 4", APP), + 0xFFE5: ("APP5", "Application segment 5", APP), + 0xFFE6: ("APP6", "Application segment 6", APP), + 0xFFE7: ("APP7", "Application segment 7", APP), + 0xFFE8: ("APP8", "Application segment 8", APP), + 0xFFE9: ("APP9", "Application segment 9", APP), + 0xFFEA: ("APP10", "Application segment 10", APP), + 0xFFEB: ("APP11", "Application segment 11", APP), + 0xFFEC: ("APP12", "Application segment 12", APP), + 0xFFED: ("APP13", "Application segment 13", APP), + 0xFFEE: ("APP14", "Application segment 14", APP), + 0xFFEF: ("APP15", "Application segment 15", APP), + 0xFFF0: ("JPG0", "Extension 0", None), + 0xFFF1: ("JPG1", "Extension 1", None), + 0xFFF2: ("JPG2", "Extension 2", None), + 0xFFF3: ("JPG3", "Extension 3", None), + 0xFFF4: ("JPG4", "Extension 4", None), + 0xFFF5: ("JPG5", "Extension 5", None), + 0xFFF6: ("JPG6", "Extension 6", None), + 0xFFF7: ("JPG7", "Extension 7", None), + 0xFFF8: ("JPG8", "Extension 8", None), + 0xFFF9: ("JPG9", "Extension 9", None), + 0xFFFA: ("JPG10", "Extension 10", None), + 0xFFFB: ("JPG11", "Extension 11", None), + 0xFFFC: ("JPG12", "Extension 12", None), + 0xFFFD: ("JPG13", "Extension 13", None), + 0xFFFE: ("COM", "Comment", COM), +} + + +def _accept(prefix: bytes) -> bool: + # Magic number was taken from https://en.wikipedia.org/wiki/JPEG + return prefix[:3] == b"\xFF\xD8\xFF" + + +## +# Image plugin for JPEG and JFIF images. + + +class JpegImageFile(ImageFile.ImageFile): + format = "JPEG" + format_description = "JPEG (ISO 10918)" + + def _open(self) -> None: + s = self.fp.read(3) + + if not _accept(s): + msg = "not a JPEG file" + raise SyntaxError(msg) + s = b"\xFF" + + # Create attributes + self.bits = self.layers = 0 + self._exif_offset = 0 + + # JPEG specifics (internal) + self.layer: list[tuple[int, int, int, int]] = [] + self._huffman_dc: dict[Any, Any] = {} + self._huffman_ac: dict[Any, Any] = {} + self.quantization: dict[int, list[int]] = {} + self.app: dict[str, bytes] = {} # compatibility + self.applist: list[tuple[str, bytes]] = [] + self.icclist: list[bytes] = [] + + while True: + i = s[0] + if i == 0xFF: + s = s + self.fp.read(1) + i = i16(s) + else: + # Skip non-0xFF junk + s = self.fp.read(1) + continue + + if i in MARKER: + name, description, handler = MARKER[i] + if handler is not None: + handler(self, i) + if i == 0xFFDA: # start of scan + rawmode = self.mode + if self.mode == "CMYK": + rawmode = "CMYK;I" # assume adobe conventions + self.tile = [ + ImageFile._Tile("jpeg", (0, 0) + self.size, 0, (rawmode, "")) + ] + # self.__offset = self.fp.tell() + break + s = self.fp.read(1) + elif i in {0, 0xFFFF}: + # padded marker or junk; move on + s = b"\xff" + elif i == 0xFF00: # Skip extraneous data (escaped 0xFF) + s = self.fp.read(1) + else: + msg = "no marker found" + raise SyntaxError(msg) + + self._read_dpi_from_exif() + + def __getattr__(self, name: str) -> Any: + if name in ("huffman_ac", "huffman_dc"): + deprecate(name, 12) + return getattr(self, "_" + name) + raise AttributeError(name) + + def load_read(self, read_bytes: int) -> bytes: + """ + internal: read more image data + For premature EOF and LOAD_TRUNCATED_IMAGES adds EOI marker + so libjpeg can finish decoding + """ + s = self.fp.read(read_bytes) + + if not s and ImageFile.LOAD_TRUNCATED_IMAGES and not hasattr(self, "_ended"): + # Premature EOF. + # Pretend file is finished adding EOI marker + self._ended = True + return b"\xFF\xD9" + + return s + + def draft( + self, mode: str | None, size: tuple[int, int] | None + ) -> tuple[str, tuple[int, int, float, float]] | None: + if len(self.tile) != 1: + return None + + # Protect from second call + if self.decoderconfig: + return None + + d, e, o, a = self.tile[0] + scale = 1 + original_size = self.size + + assert isinstance(a, tuple) + if a[0] == "RGB" and mode in ["L", "YCbCr"]: + self._mode = mode + a = mode, "" + + if size: + scale = min(self.size[0] // size[0], self.size[1] // size[1]) + for s in [8, 4, 2, 1]: + if scale >= s: + break + assert e is not None + e = ( + e[0], + e[1], + (e[2] - e[0] + s - 1) // s + e[0], + (e[3] - e[1] + s - 1) // s + e[1], + ) + self._size = ((self.size[0] + s - 1) // s, (self.size[1] + s - 1) // s) + scale = s + + self.tile = [ImageFile._Tile(d, e, o, a)] + self.decoderconfig = (scale, 0) + + box = (0, 0, original_size[0] / scale, original_size[1] / scale) + return self.mode, box + + def load_djpeg(self) -> None: + # ALTERNATIVE: handle JPEGs via the IJG command line utilities + + f, path = tempfile.mkstemp() + os.close(f) + if os.path.exists(self.filename): + subprocess.check_call(["djpeg", "-outfile", path, self.filename]) + else: + try: + os.unlink(path) + except OSError: + pass + + msg = "Invalid Filename" + raise ValueError(msg) + + try: + with Image.open(path) as _im: + _im.load() + self.im = _im.im + finally: + try: + os.unlink(path) + except OSError: + pass + + self._mode = self.im.mode + self._size = self.im.size + + self.tile = [] + + def _getexif(self) -> dict[int, Any] | None: + return _getexif(self) + + def _read_dpi_from_exif(self) -> None: + # If DPI isn't in JPEG header, fetch from EXIF + if "dpi" in self.info or "exif" not in self.info: + return + try: + exif = self.getexif() + resolution_unit = exif[0x0128] + x_resolution = exif[0x011A] + try: + dpi = float(x_resolution[0]) / x_resolution[1] + except TypeError: + dpi = x_resolution + if math.isnan(dpi): + msg = "DPI is not a number" + raise ValueError(msg) + if resolution_unit == 3: # cm + # 1 dpcm = 2.54 dpi + dpi *= 2.54 + self.info["dpi"] = dpi, dpi + except ( + struct.error, # truncated EXIF + KeyError, # dpi not included + SyntaxError, # invalid/unreadable EXIF + TypeError, # dpi is an invalid float + ValueError, # dpi is an invalid float + ZeroDivisionError, # invalid dpi rational value + ): + self.info["dpi"] = 72, 72 + + def _getmp(self) -> dict[int, Any] | None: + return _getmp(self) + + +def _getexif(self: JpegImageFile) -> dict[int, Any] | None: + if "exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + +def _getmp(self: JpegImageFile) -> dict[int, Any] | None: + # Extract MP information. This method was inspired by the "highly + # experimental" _getexif version that's been in use for years now, + # itself based on the ImageFileDirectory class in the TIFF plugin. + + # The MP record essentially consists of a TIFF file embedded in a JPEG + # application marker. + try: + data = self.info["mp"] + except KeyError: + return None + file_contents = io.BytesIO(data) + head = file_contents.read(8) + endianness = ">" if head[:4] == b"\x4d\x4d\x00\x2a" else "<" + # process dictionary + from . import TiffImagePlugin + + try: + info = TiffImagePlugin.ImageFileDirectory_v2(head) + file_contents.seek(info.next) + info.load(file_contents) + mp = dict(info) + except Exception as e: + msg = "malformed MP Index (unreadable directory)" + raise SyntaxError(msg) from e + # it's an error not to have a number of images + try: + quant = mp[0xB001] + except KeyError as e: + msg = "malformed MP Index (no number of images)" + raise SyntaxError(msg) from e + # get MP entries + mpentries = [] + try: + rawmpentries = mp[0xB002] + for entrynum in range(0, quant): + unpackedentry = struct.unpack_from( + f"{endianness}LLLHH", rawmpentries, entrynum * 16 + ) + labels = ("Attribute", "Size", "DataOffset", "EntryNo1", "EntryNo2") + mpentry = dict(zip(labels, unpackedentry)) + mpentryattr = { + "DependentParentImageFlag": bool(mpentry["Attribute"] & (1 << 31)), + "DependentChildImageFlag": bool(mpentry["Attribute"] & (1 << 30)), + "RepresentativeImageFlag": bool(mpentry["Attribute"] & (1 << 29)), + "Reserved": (mpentry["Attribute"] & (3 << 27)) >> 27, + "ImageDataFormat": (mpentry["Attribute"] & (7 << 24)) >> 24, + "MPType": mpentry["Attribute"] & 0x00FFFFFF, + } + if mpentryattr["ImageDataFormat"] == 0: + mpentryattr["ImageDataFormat"] = "JPEG" + else: + msg = "unsupported picture format in MPO" + raise SyntaxError(msg) + mptypemap = { + 0x000000: "Undefined", + 0x010001: "Large Thumbnail (VGA Equivalent)", + 0x010002: "Large Thumbnail (Full HD Equivalent)", + 0x020001: "Multi-Frame Image (Panorama)", + 0x020002: "Multi-Frame Image: (Disparity)", + 0x020003: "Multi-Frame Image: (Multi-Angle)", + 0x030000: "Baseline MP Primary Image", + } + mpentryattr["MPType"] = mptypemap.get(mpentryattr["MPType"], "Unknown") + mpentry["Attribute"] = mpentryattr + mpentries.append(mpentry) + mp[0xB002] = mpentries + except KeyError as e: + msg = "malformed MP Index (bad MP Entry)" + raise SyntaxError(msg) from e + # Next we should try and parse the individual image unique ID list; + # we don't because I've never seen this actually used in a real MPO + # file and so can't test it. + return mp + + +# -------------------------------------------------------------------- +# stuff to save JPEG files + +RAWMODE = { + "1": "L", + "L": "L", + "RGB": "RGB", + "RGBX": "RGB", + "CMYK": "CMYK;I", # assume adobe conventions + "YCbCr": "YCbCr", +} + +# fmt: off +zigzag_index = ( + 0, 1, 5, 6, 14, 15, 27, 28, + 2, 4, 7, 13, 16, 26, 29, 42, + 3, 8, 12, 17, 25, 30, 41, 43, + 9, 11, 18, 24, 31, 40, 44, 53, + 10, 19, 23, 32, 39, 45, 52, 54, + 20, 22, 33, 38, 46, 51, 55, 60, + 21, 34, 37, 47, 50, 56, 59, 61, + 35, 36, 48, 49, 57, 58, 62, 63, +) + +samplings = { + (1, 1, 1, 1, 1, 1): 0, + (2, 1, 1, 1, 1, 1): 1, + (2, 2, 1, 1, 1, 1): 2, +} +# fmt: on + + +def get_sampling(im: Image.Image) -> int: + # There's no subsampling when images have only 1 layer + # (grayscale images) or when they are CMYK (4 layers), + # so set subsampling to the default value. + # + # NOTE: currently Pillow can't encode JPEG to YCCK format. + # If YCCK support is added in the future, subsampling code will have + # to be updated (here and in JpegEncode.c) to deal with 4 layers. + if not isinstance(im, JpegImageFile) or im.layers in (1, 4): + return -1 + sampling = im.layer[0][1:3] + im.layer[1][1:3] + im.layer[2][1:3] + return samplings.get(sampling, -1) + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.width == 0 or im.height == 0: + msg = "cannot write empty image as JPEG" + raise ValueError(msg) + + try: + rawmode = RAWMODE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as JPEG" + raise OSError(msg) from e + + info = im.encoderinfo + + dpi = [round(x) for x in info.get("dpi", (0, 0))] + + quality = info.get("quality", -1) + subsampling = info.get("subsampling", -1) + qtables = info.get("qtables") + + if quality == "keep": + quality = -1 + subsampling = "keep" + qtables = "keep" + elif quality in presets: + preset = presets[quality] + quality = -1 + subsampling = preset.get("subsampling", -1) + qtables = preset.get("quantization") + elif not isinstance(quality, int): + msg = "Invalid quality setting" + raise ValueError(msg) + else: + if subsampling in presets: + subsampling = presets[subsampling].get("subsampling", -1) + if isinstance(qtables, str) and qtables in presets: + qtables = presets[qtables].get("quantization") + + if subsampling == "4:4:4": + subsampling = 0 + elif subsampling == "4:2:2": + subsampling = 1 + elif subsampling == "4:2:0": + subsampling = 2 + elif subsampling == "4:1:1": + # For compatibility. Before Pillow 4.3, 4:1:1 actually meant 4:2:0. + # Set 4:2:0 if someone is still using that value. + subsampling = 2 + elif subsampling == "keep": + if im.format != "JPEG": + msg = "Cannot use 'keep' when original image is not a JPEG" + raise ValueError(msg) + subsampling = get_sampling(im) + + def validate_qtables( + qtables: ( + str | tuple[list[int], ...] | list[list[int]] | dict[int, list[int]] | None + ) + ) -> list[list[int]] | None: + if qtables is None: + return qtables + if isinstance(qtables, str): + try: + lines = [ + int(num) + for line in qtables.splitlines() + for num in line.split("#", 1)[0].split() + ] + except ValueError as e: + msg = "Invalid quantization table" + raise ValueError(msg) from e + else: + qtables = [lines[s : s + 64] for s in range(0, len(lines), 64)] + if isinstance(qtables, (tuple, list, dict)): + if isinstance(qtables, dict): + qtables = [ + qtables[key] for key in range(len(qtables)) if key in qtables + ] + elif isinstance(qtables, tuple): + qtables = list(qtables) + if not (0 < len(qtables) < 5): + msg = "None or too many quantization tables" + raise ValueError(msg) + for idx, table in enumerate(qtables): + try: + if len(table) != 64: + msg = "Invalid quantization table" + raise TypeError(msg) + table_array = array.array("H", table) + except TypeError as e: + msg = "Invalid quantization table" + raise ValueError(msg) from e + else: + qtables[idx] = list(table_array) + return qtables + + if qtables == "keep": + if im.format != "JPEG": + msg = "Cannot use 'keep' when original image is not a JPEG" + raise ValueError(msg) + qtables = getattr(im, "quantization", None) + qtables = validate_qtables(qtables) + + extra = info.get("extra", b"") + + MAX_BYTES_IN_MARKER = 65533 + xmp = info.get("xmp", im.info.get("xmp")) + if xmp: + overhead_len = 29 # b"http://ns.adobe.com/xap/1.0/\x00" + max_data_bytes_in_marker = MAX_BYTES_IN_MARKER - overhead_len + if len(xmp) > max_data_bytes_in_marker: + msg = "XMP data is too long" + raise ValueError(msg) + size = o16(2 + overhead_len + len(xmp)) + extra += b"\xFF\xE1" + size + b"http://ns.adobe.com/xap/1.0/\x00" + xmp + + icc_profile = info.get("icc_profile") + if icc_profile: + overhead_len = 14 # b"ICC_PROFILE\0" + o8(i) + o8(len(markers)) + max_data_bytes_in_marker = MAX_BYTES_IN_MARKER - overhead_len + markers = [] + while icc_profile: + markers.append(icc_profile[:max_data_bytes_in_marker]) + icc_profile = icc_profile[max_data_bytes_in_marker:] + i = 1 + for marker in markers: + size = o16(2 + overhead_len + len(marker)) + extra += ( + b"\xFF\xE2" + + size + + b"ICC_PROFILE\0" + + o8(i) + + o8(len(markers)) + + marker + ) + i += 1 + + comment = info.get("comment", im.info.get("comment")) + + # "progressive" is the official name, but older documentation + # says "progression" + # FIXME: issue a warning if the wrong form is used (post-1.1.7) + progressive = info.get("progressive", False) or info.get("progression", False) + + optimize = info.get("optimize", False) + + exif = info.get("exif", b"") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + if len(exif) > MAX_BYTES_IN_MARKER: + msg = "EXIF data is too long" + raise ValueError(msg) + + # get keyword arguments + im.encoderconfig = ( + quality, + progressive, + info.get("smooth", 0), + optimize, + info.get("keep_rgb", False), + info.get("streamtype", 0), + dpi[0], + dpi[1], + subsampling, + info.get("restart_marker_blocks", 0), + info.get("restart_marker_rows", 0), + qtables, + comment, + extra, + exif, + ) + + # if we optimize, libjpeg needs a buffer big enough to hold the whole image + # in a shot. Guessing on the size, at im.size bytes. (raw pixel size is + # channels*size, this is a value that's been used in a django patch. + # https://github.com/matthewwithanm/django-imagekit/issues/50 + bufsize = 0 + if optimize or progressive: + # CMYK can be bigger + if im.mode == "CMYK": + bufsize = 4 * im.size[0] * im.size[1] + # keep sets quality to -1, but the actual value may be high. + elif quality >= 95 or quality == -1: + bufsize = 2 * im.size[0] * im.size[1] + else: + bufsize = im.size[0] * im.size[1] + if exif: + bufsize += len(exif) + 5 + if extra: + bufsize += len(extra) + 1 + else: + # The EXIF info needs to be written as one block, + APP1, + one spare byte. + # Ensure that our buffer is big enough. Same with the icc_profile block. + bufsize = max(bufsize, len(exif) + 5, len(extra) + 1) + + ImageFile._save( + im, fp, [ImageFile._Tile("jpeg", (0, 0) + im.size, 0, rawmode)], bufsize + ) + + +def _save_cjpeg(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + # ALTERNATIVE: handle JPEGs via the IJG command line utilities. + tempfile = im._dump() + subprocess.check_call(["cjpeg", "-outfile", filename, tempfile]) + try: + os.unlink(tempfile) + except OSError: + pass + + +## +# Factory for making JPEG and MPO instances +def jpeg_factory( + fp: IO[bytes], filename: str | bytes | None = None +) -> JpegImageFile | MpoImageFile: + im = JpegImageFile(fp, filename) + try: + mpheader = im._getmp() + if mpheader is not None and mpheader[45057] > 1: + for segment, content in im.applist: + if segment == "APP1" and b' hdrgm:Version="' in content: + # Ultra HDR images are not yet supported + return im + # It's actually an MPO + from .MpoImagePlugin import MpoImageFile + + # Don't reload everything, just convert it. + im = MpoImageFile.adopt(im, mpheader) + except (TypeError, IndexError): + # It is really a JPEG + pass + except SyntaxError: + warnings.warn( + "Image appears to be a malformed MPO file, it will be " + "interpreted as a base JPEG file" + ) + return im + + +# --------------------------------------------------------------------- +# Registry stuff + +Image.register_open(JpegImageFile.format, jpeg_factory, _accept) +Image.register_save(JpegImageFile.format, _save) + +Image.register_extensions(JpegImageFile.format, [".jfif", ".jpe", ".jpg", ".jpeg"]) + +Image.register_mime(JpegImageFile.format, "image/jpeg") diff --git a/venv/lib/python3.12/site-packages/PIL/JpegPresets.py b/venv/lib/python3.12/site-packages/PIL/JpegPresets.py new file mode 100644 index 0000000..d0e64a3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/JpegPresets.py @@ -0,0 +1,242 @@ +""" +JPEG quality settings equivalent to the Photoshop settings. +Can be used when saving JPEG files. + +The following presets are available by default: +``web_low``, ``web_medium``, ``web_high``, ``web_very_high``, ``web_maximum``, +``low``, ``medium``, ``high``, ``maximum``. +More presets can be added to the :py:data:`presets` dict if needed. + +To apply the preset, specify:: + + quality="preset_name" + +To apply only the quantization table:: + + qtables="preset_name" + +To apply only the subsampling setting:: + + subsampling="preset_name" + +Example:: + + im.save("image_name.jpg", quality="web_high") + +Subsampling +----------- + +Subsampling is the practice of encoding images by implementing less resolution +for chroma information than for luma information. +(ref.: https://en.wikipedia.org/wiki/Chroma_subsampling) + +Possible subsampling values are 0, 1 and 2 that correspond to 4:4:4, 4:2:2 and +4:2:0. + +You can get the subsampling of a JPEG with the +:func:`.JpegImagePlugin.get_sampling` function. + +In JPEG compressed data a JPEG marker is used instead of an EXIF tag. +(ref.: https://exiv2.org/tags.html) + + +Quantization tables +------------------- + +They are values use by the DCT (Discrete cosine transform) to remove +*unnecessary* information from the image (the lossy part of the compression). +(ref.: https://en.wikipedia.org/wiki/Quantization_matrix#Quantization_matrices, +https://en.wikipedia.org/wiki/JPEG#Quantization) + +You can get the quantization tables of a JPEG with:: + + im.quantization + +This will return a dict with a number of lists. You can pass this dict +directly as the qtables argument when saving a JPEG. + +The quantization table format in presets is a list with sublists. These formats +are interchangeable. + +Libjpeg ref.: +https://web.archive.org/web/20120328125543/http://www.jpegcameras.com/libjpeg/libjpeg-3.html + +""" + +from __future__ import annotations + +# fmt: off +presets = { + 'web_low': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [20, 16, 25, 39, 50, 46, 62, 68, + 16, 18, 23, 38, 38, 53, 65, 68, + 25, 23, 31, 38, 53, 65, 68, 68, + 39, 38, 38, 53, 65, 68, 68, 68, + 50, 38, 53, 65, 68, 68, 68, 68, + 46, 53, 65, 68, 68, 68, 68, 68, + 62, 65, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68], + [21, 25, 32, 38, 54, 68, 68, 68, + 25, 28, 24, 38, 54, 68, 68, 68, + 32, 24, 32, 43, 66, 68, 68, 68, + 38, 38, 43, 53, 68, 68, 68, 68, + 54, 54, 66, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68] + ]}, + 'web_medium': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [16, 11, 11, 16, 23, 27, 31, 30, + 11, 12, 12, 15, 20, 23, 23, 30, + 11, 12, 13, 16, 23, 26, 35, 47, + 16, 15, 16, 23, 26, 37, 47, 64, + 23, 20, 23, 26, 39, 51, 64, 64, + 27, 23, 26, 37, 51, 64, 64, 64, + 31, 23, 35, 47, 64, 64, 64, 64, + 30, 30, 47, 64, 64, 64, 64, 64], + [17, 15, 17, 21, 20, 26, 38, 48, + 15, 19, 18, 17, 20, 26, 35, 43, + 17, 18, 20, 22, 26, 30, 46, 53, + 21, 17, 22, 28, 30, 39, 53, 64, + 20, 20, 26, 30, 39, 48, 64, 64, + 26, 26, 30, 39, 48, 63, 64, 64, + 38, 35, 46, 53, 64, 64, 64, 64, + 48, 43, 53, 64, 64, 64, 64, 64] + ]}, + 'web_high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [6, 4, 4, 6, 9, 11, 12, 16, + 4, 5, 5, 6, 8, 10, 12, 12, + 4, 5, 5, 6, 10, 12, 14, 19, + 6, 6, 6, 11, 12, 15, 19, 28, + 9, 8, 10, 12, 16, 20, 27, 31, + 11, 10, 12, 15, 20, 27, 31, 31, + 12, 12, 14, 19, 27, 31, 31, 31, + 16, 12, 19, 28, 31, 31, 31, 31], + [7, 7, 13, 24, 26, 31, 31, 31, + 7, 12, 16, 21, 31, 31, 31, 31, + 13, 16, 17, 31, 31, 31, 31, 31, + 24, 21, 31, 31, 31, 31, 31, 31, + 26, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31] + ]}, + 'web_very_high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 4, 5, 7, 9, + 2, 2, 2, 4, 5, 7, 9, 12, + 3, 3, 4, 5, 8, 10, 12, 12, + 4, 4, 5, 7, 10, 12, 12, 12, + 5, 5, 7, 9, 12, 12, 12, 12, + 6, 6, 9, 12, 12, 12, 12, 12], + [3, 3, 5, 9, 13, 15, 15, 15, + 3, 4, 6, 11, 14, 12, 12, 12, + 5, 6, 9, 14, 12, 12, 12, 12, + 9, 11, 14, 12, 12, 12, 12, 12, + 13, 14, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'web_maximum': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 2, 2, + 1, 1, 1, 1, 1, 2, 2, 3, + 1, 1, 1, 1, 2, 2, 3, 3, + 1, 1, 1, 2, 2, 3, 3, 3, + 1, 1, 2, 2, 3, 3, 3, 3], + [1, 1, 1, 2, 2, 3, 3, 3, + 1, 1, 1, 2, 3, 3, 3, 3, + 1, 1, 1, 3, 3, 3, 3, 3, + 2, 2, 3, 3, 3, 3, 3, 3, + 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3] + ]}, + 'low': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [18, 14, 14, 21, 30, 35, 34, 17, + 14, 16, 16, 19, 26, 23, 12, 12, + 14, 16, 17, 21, 23, 12, 12, 12, + 21, 19, 21, 23, 12, 12, 12, 12, + 30, 26, 23, 12, 12, 12, 12, 12, + 35, 23, 12, 12, 12, 12, 12, 12, + 34, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12], + [20, 19, 22, 27, 20, 20, 17, 17, + 19, 25, 23, 14, 14, 12, 12, 12, + 22, 23, 14, 14, 12, 12, 12, 12, + 27, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'medium': {'subsampling': 2, # "4:2:0" + 'quantization': [ + [12, 8, 8, 12, 17, 21, 24, 17, + 8, 9, 9, 11, 15, 19, 12, 12, + 8, 9, 10, 12, 19, 12, 12, 12, + 12, 11, 12, 21, 12, 12, 12, 12, + 17, 15, 19, 12, 12, 12, 12, 12, + 21, 19, 12, 12, 12, 12, 12, 12, + 24, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12], + [13, 11, 13, 16, 20, 20, 17, 17, + 11, 14, 14, 14, 14, 12, 12, 12, + 13, 14, 14, 14, 12, 12, 12, 12, + 16, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'high': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [6, 4, 4, 6, 9, 11, 12, 16, + 4, 5, 5, 6, 8, 10, 12, 12, + 4, 5, 5, 6, 10, 12, 12, 12, + 6, 6, 6, 11, 12, 12, 12, 12, + 9, 8, 10, 12, 12, 12, 12, 12, + 11, 10, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, + 16, 12, 12, 12, 12, 12, 12, 12], + [7, 7, 13, 24, 20, 20, 17, 17, + 7, 12, 16, 14, 14, 12, 12, 12, + 13, 16, 14, 14, 12, 12, 12, 12, + 24, 14, 14, 12, 12, 12, 12, 12, + 20, 14, 12, 12, 12, 12, 12, 12, + 20, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12, + 17, 12, 12, 12, 12, 12, 12, 12] + ]}, + 'maximum': {'subsampling': 0, # "4:4:4" + 'quantization': [ + [2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 3, 4, 5, 6, + 2, 2, 2, 2, 4, 5, 7, 9, + 2, 2, 2, 4, 5, 7, 9, 12, + 3, 3, 4, 5, 8, 10, 12, 12, + 4, 4, 5, 7, 10, 12, 12, 12, + 5, 5, 7, 9, 12, 12, 12, 12, + 6, 6, 9, 12, 12, 12, 12, 12], + [3, 3, 5, 9, 13, 15, 15, 15, + 3, 4, 6, 10, 14, 12, 12, 12, + 5, 6, 9, 14, 12, 12, 12, 12, + 9, 10, 14, 12, 12, 12, 12, 12, + 13, 14, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12, + 15, 12, 12, 12, 12, 12, 12, 12] + ]}, +} +# fmt: on diff --git a/venv/lib/python3.12/site-packages/PIL/McIdasImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/McIdasImagePlugin.py new file mode 100644 index 0000000..5dd031b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/McIdasImagePlugin.py @@ -0,0 +1,80 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Basic McIdas support for PIL +# +# History: +# 1997-05-05 fl Created (8-bit images only) +# 2009-03-08 fl Added 16/32-bit support. +# +# Thanks to Richard Jones and Craig Swank for specs and samples. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import struct + +from . import Image, ImageFile + + +def _accept(prefix: bytes) -> bool: + return prefix[:8] == b"\x00\x00\x00\x00\x00\x00\x00\x04" + + +## +# Image plugin for McIdas area images. + + +class McIdasImageFile(ImageFile.ImageFile): + format = "MCIDAS" + format_description = "McIdas area file" + + def _open(self) -> None: + # parse area file directory + assert self.fp is not None + + s = self.fp.read(256) + if not _accept(s) or len(s) != 256: + msg = "not an McIdas area file" + raise SyntaxError(msg) + + self.area_descriptor_raw = s + self.area_descriptor = w = [0] + list(struct.unpack("!64i", s)) + + # get mode + if w[11] == 1: + mode = rawmode = "L" + elif w[11] == 2: + # FIXME: add memory map support + mode = "I" + rawmode = "I;16B" + elif w[11] == 4: + # FIXME: add memory map support + mode = "I" + rawmode = "I;32B" + else: + msg = "unsupported McIdas format" + raise SyntaxError(msg) + + self._mode = mode + self._size = w[10], w[9] + + offset = w[34] + w[15] + stride = w[15] + w[10] * w[11] * w[14] + + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offset, (rawmode, stride, 1)) + ] + + +# -------------------------------------------------------------------- +# registry + +Image.register_open(McIdasImageFile.format, McIdasImageFile, _accept) + +# no default extension diff --git a/venv/lib/python3.12/site-packages/PIL/MicImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/MicImagePlugin.py new file mode 100644 index 0000000..5f23a34 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/MicImagePlugin.py @@ -0,0 +1,107 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Microsoft Image Composer support for PIL +# +# Notes: +# uses TiffImagePlugin.py to read the actual image streams +# +# History: +# 97-01-20 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import olefile + +from . import Image, TiffImagePlugin + +# +# -------------------------------------------------------------------- + + +def _accept(prefix: bytes) -> bool: + return prefix[:8] == olefile.MAGIC + + +## +# Image plugin for Microsoft's Image Composer file format. + + +class MicImageFile(TiffImagePlugin.TiffImageFile): + format = "MIC" + format_description = "Microsoft Image Composer" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + # read the OLE directory and see if this is a likely + # to be a Microsoft Image Composer file + + try: + self.ole = olefile.OleFileIO(self.fp) + except OSError as e: + msg = "not an MIC file; invalid OLE file" + raise SyntaxError(msg) from e + + # find ACI subfiles with Image members (maybe not the + # best way to identify MIC files, but what the... ;-) + + self.images = [ + path + for path in self.ole.listdir() + if path[1:] and path[0][-4:] == ".ACI" and path[1] == "Image" + ] + + # if we didn't find any images, this is probably not + # an MIC file. + if not self.images: + msg = "not an MIC file; no image entries" + raise SyntaxError(msg) + + self.frame = -1 + self._n_frames = len(self.images) + self.is_animated = self._n_frames > 1 + + self.__fp = self.fp + self.seek(0) + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + try: + filename = self.images[frame] + except IndexError as e: + msg = "no such frame" + raise EOFError(msg) from e + + self.fp = self.ole.openstream(filename) + + TiffImagePlugin.TiffImageFile._open(self) + + self.frame = frame + + def tell(self) -> int: + return self.frame + + def close(self) -> None: + self.__fp.close() + self.ole.close() + super().close() + + def __exit__(self, *args: object) -> None: + self.__fp.close() + self.ole.close() + super().__exit__() + + +# +# -------------------------------------------------------------------- + +Image.register_open(MicImageFile.format, MicImageFile, _accept) + +Image.register_extension(MicImageFile.format, ".mic") diff --git a/venv/lib/python3.12/site-packages/PIL/MpegImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/MpegImagePlugin.py new file mode 100644 index 0000000..ad4d3e9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/MpegImagePlugin.py @@ -0,0 +1,88 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MPEG file handling +# +# History: +# 95-09-09 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i8 +from ._typing import SupportsRead + +# +# Bitstream parser + + +class BitStream: + def __init__(self, fp: SupportsRead[bytes]) -> None: + self.fp = fp + self.bits = 0 + self.bitbuffer = 0 + + def next(self) -> int: + return i8(self.fp.read(1)) + + def peek(self, bits: int) -> int: + while self.bits < bits: + c = self.next() + if c < 0: + self.bits = 0 + continue + self.bitbuffer = (self.bitbuffer << 8) + c + self.bits += 8 + return self.bitbuffer >> (self.bits - bits) & (1 << bits) - 1 + + def skip(self, bits: int) -> None: + while self.bits < bits: + self.bitbuffer = (self.bitbuffer << 8) + i8(self.fp.read(1)) + self.bits += 8 + self.bits = self.bits - bits + + def read(self, bits: int) -> int: + v = self.peek(bits) + self.bits = self.bits - bits + return v + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"\x00\x00\x01\xb3" + + +## +# Image plugin for MPEG streams. This plugin can identify a stream, +# but it cannot read it. + + +class MpegImageFile(ImageFile.ImageFile): + format = "MPEG" + format_description = "MPEG" + + def _open(self) -> None: + assert self.fp is not None + + s = BitStream(self.fp) + if s.read(32) != 0x1B3: + msg = "not an MPEG file" + raise SyntaxError(msg) + + self._mode = "RGB" + self._size = s.read(12), s.read(12) + + +# -------------------------------------------------------------------- +# Registry stuff + +Image.register_open(MpegImageFile.format, MpegImageFile, _accept) + +Image.register_extensions(MpegImageFile.format, [".mpg", ".mpeg"]) + +Image.register_mime(MpegImageFile.format, "video/mpeg") diff --git a/venv/lib/python3.12/site-packages/PIL/MpoImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/MpoImagePlugin.py new file mode 100644 index 0000000..71f89a0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/MpoImagePlugin.py @@ -0,0 +1,190 @@ +# +# The Python Imaging Library. +# $Id$ +# +# MPO file handling +# +# See "Multi-Picture Format" (CIPA DC-007-Translation 2009, Standard of the +# Camera & Imaging Products Association) +# +# The multi-picture object combines multiple JPEG images (with a modified EXIF +# data format) into a single file. While it can theoretically be used much like +# a GIF animation, it is commonly used to represent 3D photographs and is (as +# of this writing) the most commonly used format by 3D cameras. +# +# History: +# 2014-03-13 Feneric Created +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import os +import struct +from typing import IO, Any, cast + +from . import ( + Image, + ImageFile, + ImageSequence, + JpegImagePlugin, + TiffImagePlugin, +) +from ._binary import o32le + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + JpegImagePlugin._save(im, fp, filename) + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + append_images = im.encoderinfo.get("append_images", []) + if not append_images and not getattr(im, "is_animated", False): + _save(im, fp, filename) + return + + mpf_offset = 28 + offsets: list[int] = [] + for imSequence in itertools.chain([im], append_images): + for im_frame in ImageSequence.Iterator(imSequence): + if not offsets: + # APP2 marker + im_frame.encoderinfo["extra"] = ( + b"\xFF\xE2" + struct.pack(">H", 6 + 82) + b"MPF\0" + b" " * 82 + ) + exif = im_frame.encoderinfo.get("exif") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + im_frame.encoderinfo["exif"] = exif + if exif: + mpf_offset += 4 + len(exif) + + JpegImagePlugin._save(im_frame, fp, filename) + offsets.append(fp.tell()) + else: + im_frame.save(fp, "JPEG") + offsets.append(fp.tell() - offsets[-1]) + + ifd = TiffImagePlugin.ImageFileDirectory_v2() + ifd[0xB000] = b"0100" + ifd[0xB001] = len(offsets) + + mpentries = b"" + data_offset = 0 + for i, size in enumerate(offsets): + if i == 0: + mptype = 0x030000 # Baseline MP Primary Image + else: + mptype = 0x000000 # Undefined + mpentries += struct.pack(" None: + self.fp.seek(0) # prep the fp in order to pass the JPEG test + JpegImagePlugin.JpegImageFile._open(self) + self._after_jpeg_open() + + def _after_jpeg_open(self, mpheader: dict[int, Any] | None = None) -> None: + self.mpinfo = mpheader if mpheader is not None else self._getmp() + if self.mpinfo is None: + msg = "Image appears to be a malformed MPO file" + raise ValueError(msg) + self.n_frames = self.mpinfo[0xB001] + self.__mpoffsets = [ + mpent["DataOffset"] + self.info["mpoffset"] for mpent in self.mpinfo[0xB002] + ] + self.__mpoffsets[0] = 0 + # Note that the following assertion will only be invalid if something + # gets broken within JpegImagePlugin. + assert self.n_frames == len(self.__mpoffsets) + del self.info["mpoffset"] # no longer needed + self.is_animated = self.n_frames > 1 + self._fp = self.fp # FIXME: hack + self._fp.seek(self.__mpoffsets[0]) # get ready to read first frame + self.__frame = 0 + self.offset = 0 + # for now we can only handle reading and individual frame extraction + self.readonly = 1 + + def load_seek(self, pos: int) -> None: + self._fp.seek(pos) + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + self.fp = self._fp + self.offset = self.__mpoffsets[frame] + + original_exif = self.info.get("exif") + if "exif" in self.info: + del self.info["exif"] + + self.fp.seek(self.offset + 2) # skip SOI marker + if not self.fp.read(2): + msg = "No data found for frame" + raise ValueError(msg) + self.fp.seek(self.offset) + JpegImagePlugin.JpegImageFile._open(self) + if self.info.get("exif") != original_exif: + self._reload_exif() + + self.tile = [ + ImageFile._Tile("jpeg", (0, 0) + self.size, self.offset, self.tile[0][-1]) + ] + self.__frame = frame + + def tell(self) -> int: + return self.__frame + + @staticmethod + def adopt( + jpeg_instance: JpegImagePlugin.JpegImageFile, + mpheader: dict[int, Any] | None = None, + ) -> MpoImageFile: + """ + Transform the instance of JpegImageFile into + an instance of MpoImageFile. + After the call, the JpegImageFile is extended + to be an MpoImageFile. + + This is essentially useful when opening a JPEG + file that reveals itself as an MPO, to avoid + double call to _open. + """ + jpeg_instance.__class__ = MpoImageFile + mpo_instance = cast(MpoImageFile, jpeg_instance) + mpo_instance._after_jpeg_open(mpheader) + return mpo_instance + + +# --------------------------------------------------------------------- +# Registry stuff + +# Note that since MPO shares a factory with JPEG, we do not need to do a +# separate registration for it here. +# Image.register_open(MpoImageFile.format, +# JpegImagePlugin.jpeg_factory, _accept) +Image.register_save(MpoImageFile.format, _save) +Image.register_save_all(MpoImageFile.format, _save_all) + +Image.register_extension(MpoImageFile.format, ".mpo") + +Image.register_mime(MpoImageFile.format, "image/mpo") diff --git a/venv/lib/python3.12/site-packages/PIL/MspImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/MspImagePlugin.py new file mode 100644 index 0000000..f3460a7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/MspImagePlugin.py @@ -0,0 +1,200 @@ +# +# The Python Imaging Library. +# +# MSP file handling +# +# This is the format used by the Paint program in Windows 1 and 2. +# +# History: +# 95-09-05 fl Created +# 97-01-03 fl Read/write MSP images +# 17-02-21 es Fixed RLE interpretation +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-97. +# Copyright (c) Eric Soroos 2017. +# +# See the README file for information on usage and redistribution. +# +# More info on this format: https://archive.org/details/gg243631 +# Page 313: +# Figure 205. Windows Paint Version 1: "DanM" Format +# Figure 206. Windows Paint Version 2: "LinS" Format. Used in Windows V2.03 +# +# See also: https://www.fileformat.info/format/mspaint/egff.htm +from __future__ import annotations + +import io +import struct +from typing import IO + +from . import Image, ImageFile +from ._binary import i16le as i16 +from ._binary import o16le as o16 + +# +# read MSP files + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] in [b"DanM", b"LinS"] + + +## +# Image plugin for Windows MSP images. This plugin supports both +# uncompressed (Windows 1.0). + + +class MspImageFile(ImageFile.ImageFile): + format = "MSP" + format_description = "Windows Paint" + + def _open(self) -> None: + # Header + assert self.fp is not None + + s = self.fp.read(32) + if not _accept(s): + msg = "not an MSP file" + raise SyntaxError(msg) + + # Header checksum + checksum = 0 + for i in range(0, 32, 2): + checksum = checksum ^ i16(s, i) + if checksum != 0: + msg = "bad MSP checksum" + raise SyntaxError(msg) + + self._mode = "1" + self._size = i16(s, 4), i16(s, 6) + + if s[:4] == b"DanM": + self.tile = [ImageFile._Tile("raw", (0, 0) + self.size, 32, ("1", 0, 1))] + else: + self.tile = [ImageFile._Tile("MSP", (0, 0) + self.size, 32, None)] + + +class MspDecoder(ImageFile.PyDecoder): + # The algo for the MSP decoder is from + # https://www.fileformat.info/format/mspaint/egff.htm + # cc-by-attribution -- That page references is taken from the + # Encyclopedia of Graphics File Formats and is licensed by + # O'Reilly under the Creative Common/Attribution license + # + # For RLE encoded files, the 32byte header is followed by a scan + # line map, encoded as one 16bit word of encoded byte length per + # line. + # + # NOTE: the encoded length of the line can be 0. This was not + # handled in the previous version of this encoder, and there's no + # mention of how to handle it in the documentation. From the few + # examples I've seen, I've assumed that it is a fill of the + # background color, in this case, white. + # + # + # Pseudocode of the decoder: + # Read a BYTE value as the RunType + # If the RunType value is zero + # Read next byte as the RunCount + # Read the next byte as the RunValue + # Write the RunValue byte RunCount times + # If the RunType value is non-zero + # Use this value as the RunCount + # Read and write the next RunCount bytes literally + # + # e.g.: + # 0x00 03 ff 05 00 01 02 03 04 + # would yield the bytes: + # 0xff ff ff 00 01 02 03 04 + # + # which are then interpreted as a bit packed mode '1' image + + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + + img = io.BytesIO() + blank_line = bytearray((0xFF,) * ((self.state.xsize + 7) // 8)) + try: + self.fd.seek(32) + rowmap = struct.unpack_from( + f"<{self.state.ysize}H", self.fd.read(self.state.ysize * 2) + ) + except struct.error as e: + msg = "Truncated MSP file in row map" + raise OSError(msg) from e + + for x, rowlen in enumerate(rowmap): + try: + if rowlen == 0: + img.write(blank_line) + continue + row = self.fd.read(rowlen) + if len(row) != rowlen: + msg = f"Truncated MSP file, expected {rowlen} bytes on row {x}" + raise OSError(msg) + idx = 0 + while idx < rowlen: + runtype = row[idx] + idx += 1 + if runtype == 0: + (runcount, runval) = struct.unpack_from("Bc", row, idx) + img.write(runval * runcount) + idx += 2 + else: + runcount = runtype + img.write(row[idx : idx + runcount]) + idx += runcount + + except struct.error as e: + msg = f"Corrupted MSP file in row {x}" + raise OSError(msg) from e + + self.set_as_raw(img.getvalue(), "1") + + return -1, 0 + + +Image.register_decoder("MSP", MspDecoder) + + +# +# write MSP files (uncompressed only) + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode != "1": + msg = f"cannot write mode {im.mode} as MSP" + raise OSError(msg) + + # create MSP header + header = [0] * 16 + + header[0], header[1] = i16(b"Da"), i16(b"nM") # version 1 + header[2], header[3] = im.size + header[4], header[5] = 1, 1 + header[6], header[7] = 1, 1 + header[8], header[9] = im.size + + checksum = 0 + for h in header: + checksum = checksum ^ h + header[12] = checksum # FIXME: is this the right field? + + # header + for h in header: + fp.write(o16(h)) + + # image body + ImageFile._save(im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 32, ("1", 0, 1))]) + + +# +# registry + +Image.register_open(MspImageFile.format, MspImageFile, _accept) +Image.register_save(MspImageFile.format, _save) + +Image.register_extension(MspImageFile.format, ".msp") diff --git a/venv/lib/python3.12/site-packages/PIL/PSDraw.py b/venv/lib/python3.12/site-packages/PIL/PSDraw.py new file mode 100644 index 0000000..02939d2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PSDraw.py @@ -0,0 +1,234 @@ +# +# The Python Imaging Library +# $Id$ +# +# Simple PostScript graphics interface +# +# History: +# 1996-04-20 fl Created +# 1999-01-10 fl Added gsave/grestore to image method +# 2005-05-04 fl Fixed floating point issue in image (from Eric Etheridge) +# +# Copyright (c) 1997-2005 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import sys +from typing import IO, TYPE_CHECKING + +from . import EpsImagePlugin + +## +# Simple PostScript graphics interface. + + +class PSDraw: + """ + Sets up printing to the given file. If ``fp`` is omitted, + ``sys.stdout.buffer`` is assumed. + """ + + def __init__(self, fp: IO[bytes] | None = None) -> None: + if not fp: + fp = sys.stdout.buffer + self.fp = fp + + def begin_document(self, id: str | None = None) -> None: + """Set up printing of a document. (Write PostScript DSC header.)""" + # FIXME: incomplete + self.fp.write( + b"%!PS-Adobe-3.0\n" + b"save\n" + b"/showpage { } def\n" + b"%%EndComments\n" + b"%%BeginDocument\n" + ) + # self.fp.write(ERROR_PS) # debugging! + self.fp.write(EDROFF_PS) + self.fp.write(VDI_PS) + self.fp.write(b"%%EndProlog\n") + self.isofont: dict[bytes, int] = {} + + def end_document(self) -> None: + """Ends printing. (Write PostScript DSC footer.)""" + self.fp.write(b"%%EndDocument\nrestore showpage\n%%End\n") + if hasattr(self.fp, "flush"): + self.fp.flush() + + def setfont(self, font: str, size: int) -> None: + """ + Selects which font to use. + + :param font: A PostScript font name + :param size: Size in points. + """ + font_bytes = bytes(font, "UTF-8") + if font_bytes not in self.isofont: + # reencode font + self.fp.write( + b"/PSDraw-%s ISOLatin1Encoding /%s E\n" % (font_bytes, font_bytes) + ) + self.isofont[font_bytes] = 1 + # rough + self.fp.write(b"/F0 %d /PSDraw-%s F\n" % (size, font_bytes)) + + def line(self, xy0: tuple[int, int], xy1: tuple[int, int]) -> None: + """ + Draws a line between the two points. Coordinates are given in + PostScript point coordinates (72 points per inch, (0, 0) is the lower + left corner of the page). + """ + self.fp.write(b"%d %d %d %d Vl\n" % (*xy0, *xy1)) + + def rectangle(self, box: tuple[int, int, int, int]) -> None: + """ + Draws a rectangle. + + :param box: A tuple of four integers, specifying left, bottom, width and + height. + """ + self.fp.write(b"%d %d M 0 %d %d Vr\n" % box) + + def text(self, xy: tuple[int, int], text: str) -> None: + """ + Draws text at the given position. You must use + :py:meth:`~PIL.PSDraw.PSDraw.setfont` before calling this method. + """ + text_bytes = bytes(text, "UTF-8") + text_bytes = b"\\(".join(text_bytes.split(b"(")) + text_bytes = b"\\)".join(text_bytes.split(b")")) + self.fp.write(b"%d %d M (%s) S\n" % (xy + (text_bytes,))) + + if TYPE_CHECKING: + from . import Image + + def image( + self, box: tuple[int, int, int, int], im: Image.Image, dpi: int | None = None + ) -> None: + """Draw a PIL image, centered in the given box.""" + # default resolution depends on mode + if not dpi: + if im.mode == "1": + dpi = 200 # fax + else: + dpi = 100 # grayscale + # image size (on paper) + x = im.size[0] * 72 / dpi + y = im.size[1] * 72 / dpi + # max allowed size + xmax = float(box[2] - box[0]) + ymax = float(box[3] - box[1]) + if x > xmax: + y = y * xmax / x + x = xmax + if y > ymax: + x = x * ymax / y + y = ymax + dx = (xmax - x) / 2 + box[0] + dy = (ymax - y) / 2 + box[1] + self.fp.write(b"gsave\n%f %f translate\n" % (dx, dy)) + if (x, y) != im.size: + # EpsImagePlugin._save prints the image at (0,0,xsize,ysize) + sx = x / im.size[0] + sy = y / im.size[1] + self.fp.write(b"%f %f scale\n" % (sx, sy)) + EpsImagePlugin._save(im, self.fp, "", 0) + self.fp.write(b"\ngrestore\n") + + +# -------------------------------------------------------------------- +# PostScript driver + +# +# EDROFF.PS -- PostScript driver for Edroff 2 +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + + +EDROFF_PS = b"""\ +/S { show } bind def +/P { moveto show } bind def +/M { moveto } bind def +/X { 0 rmoveto } bind def +/Y { 0 exch rmoveto } bind def +/E { findfont + dup maxlength dict begin + { + 1 index /FID ne { def } { pop pop } ifelse + } forall + /Encoding exch def + dup /FontName exch def + currentdict end definefont pop +} bind def +/F { findfont exch scalefont dup setfont + [ exch /setfont cvx ] cvx bind def +} bind def +""" + +# +# VDI.PS -- PostScript driver for VDI meta commands +# +# History: +# 94-01-25 fl: created (edroff 2.04) +# +# Copyright (c) Fredrik Lundh 1994. +# + +VDI_PS = b"""\ +/Vm { moveto } bind def +/Va { newpath arcn stroke } bind def +/Vl { moveto lineto stroke } bind def +/Vc { newpath 0 360 arc closepath } bind def +/Vr { exch dup 0 rlineto + exch dup 0 exch rlineto + exch neg 0 rlineto + 0 exch neg rlineto + setgray fill } bind def +/Tm matrix def +/Ve { Tm currentmatrix pop + translate scale newpath 0 0 .5 0 360 arc closepath + Tm setmatrix +} bind def +/Vf { currentgray exch setgray fill setgray } bind def +""" + +# +# ERROR.PS -- Error handler +# +# History: +# 89-11-21 fl: created (pslist 1.10) +# + +ERROR_PS = b"""\ +/landscape false def +/errorBUF 200 string def +/errorNL { currentpoint 10 sub exch pop 72 exch moveto } def +errordict begin /handleerror { + initmatrix /Courier findfont 10 scalefont setfont + newpath 72 720 moveto $error begin /newerror false def + (PostScript Error) show errorNL errorNL + (Error: ) show + /errorname load errorBUF cvs show errorNL errorNL + (Command: ) show + /command load dup type /stringtype ne { errorBUF cvs } if show + errorNL errorNL + (VMstatus: ) show + vmstatus errorBUF cvs show ( bytes available, ) show + errorBUF cvs show ( bytes used at level ) show + errorBUF cvs show errorNL errorNL + (Operand stargck: ) show errorNL /ostargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall errorNL + (Execution stargck: ) show errorNL /estargck load { + dup type /stringtype ne { errorBUF cvs } if 72 0 rmoveto show errorNL + } forall + end showpage +} def end +""" diff --git a/venv/lib/python3.12/site-packages/PIL/PaletteFile.py b/venv/lib/python3.12/site-packages/PIL/PaletteFile.py new file mode 100644 index 0000000..81652e5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PaletteFile.py @@ -0,0 +1,54 @@ +# +# Python Imaging Library +# $Id$ +# +# stuff to read simple, teragon-style palette files +# +# History: +# 97-08-23 fl Created +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from typing import IO + +from ._binary import o8 + + +class PaletteFile: + """File handler for Teragon-style palette files.""" + + rawmode = "RGB" + + def __init__(self, fp: IO[bytes]) -> None: + palette = [o8(i) * 3 for i in range(256)] + + while True: + s = fp.readline() + + if not s: + break + if s[:1] == b"#": + continue + if len(s) > 100: + msg = "bad palette file" + raise SyntaxError(msg) + + v = [int(x) for x in s.split()] + try: + [i, r, g, b] = v + except ValueError: + [i, r] = v + g = b = r + + if 0 <= i <= 255: + palette[i] = o8(r) + o8(g) + o8(b) + + self.palette = b"".join(palette) + + def getpalette(self) -> tuple[bytes, str]: + return self.palette, self.rawmode diff --git a/venv/lib/python3.12/site-packages/PIL/PalmImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PalmImagePlugin.py new file mode 100644 index 0000000..b332453 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PalmImagePlugin.py @@ -0,0 +1,232 @@ +# +# The Python Imaging Library. +# $Id$ +# + +## +# Image plugin for Palm pixmap images (output only). +## +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile +from ._binary import o8 +from ._binary import o16be as o16b + +# fmt: off +_Palm8BitColormapValues = ( + (255, 255, 255), (255, 204, 255), (255, 153, 255), (255, 102, 255), + (255, 51, 255), (255, 0, 255), (255, 255, 204), (255, 204, 204), + (255, 153, 204), (255, 102, 204), (255, 51, 204), (255, 0, 204), + (255, 255, 153), (255, 204, 153), (255, 153, 153), (255, 102, 153), + (255, 51, 153), (255, 0, 153), (204, 255, 255), (204, 204, 255), + (204, 153, 255), (204, 102, 255), (204, 51, 255), (204, 0, 255), + (204, 255, 204), (204, 204, 204), (204, 153, 204), (204, 102, 204), + (204, 51, 204), (204, 0, 204), (204, 255, 153), (204, 204, 153), + (204, 153, 153), (204, 102, 153), (204, 51, 153), (204, 0, 153), + (153, 255, 255), (153, 204, 255), (153, 153, 255), (153, 102, 255), + (153, 51, 255), (153, 0, 255), (153, 255, 204), (153, 204, 204), + (153, 153, 204), (153, 102, 204), (153, 51, 204), (153, 0, 204), + (153, 255, 153), (153, 204, 153), (153, 153, 153), (153, 102, 153), + (153, 51, 153), (153, 0, 153), (102, 255, 255), (102, 204, 255), + (102, 153, 255), (102, 102, 255), (102, 51, 255), (102, 0, 255), + (102, 255, 204), (102, 204, 204), (102, 153, 204), (102, 102, 204), + (102, 51, 204), (102, 0, 204), (102, 255, 153), (102, 204, 153), + (102, 153, 153), (102, 102, 153), (102, 51, 153), (102, 0, 153), + (51, 255, 255), (51, 204, 255), (51, 153, 255), (51, 102, 255), + (51, 51, 255), (51, 0, 255), (51, 255, 204), (51, 204, 204), + (51, 153, 204), (51, 102, 204), (51, 51, 204), (51, 0, 204), + (51, 255, 153), (51, 204, 153), (51, 153, 153), (51, 102, 153), + (51, 51, 153), (51, 0, 153), (0, 255, 255), (0, 204, 255), + (0, 153, 255), (0, 102, 255), (0, 51, 255), (0, 0, 255), + (0, 255, 204), (0, 204, 204), (0, 153, 204), (0, 102, 204), + (0, 51, 204), (0, 0, 204), (0, 255, 153), (0, 204, 153), + (0, 153, 153), (0, 102, 153), (0, 51, 153), (0, 0, 153), + (255, 255, 102), (255, 204, 102), (255, 153, 102), (255, 102, 102), + (255, 51, 102), (255, 0, 102), (255, 255, 51), (255, 204, 51), + (255, 153, 51), (255, 102, 51), (255, 51, 51), (255, 0, 51), + (255, 255, 0), (255, 204, 0), (255, 153, 0), (255, 102, 0), + (255, 51, 0), (255, 0, 0), (204, 255, 102), (204, 204, 102), + (204, 153, 102), (204, 102, 102), (204, 51, 102), (204, 0, 102), + (204, 255, 51), (204, 204, 51), (204, 153, 51), (204, 102, 51), + (204, 51, 51), (204, 0, 51), (204, 255, 0), (204, 204, 0), + (204, 153, 0), (204, 102, 0), (204, 51, 0), (204, 0, 0), + (153, 255, 102), (153, 204, 102), (153, 153, 102), (153, 102, 102), + (153, 51, 102), (153, 0, 102), (153, 255, 51), (153, 204, 51), + (153, 153, 51), (153, 102, 51), (153, 51, 51), (153, 0, 51), + (153, 255, 0), (153, 204, 0), (153, 153, 0), (153, 102, 0), + (153, 51, 0), (153, 0, 0), (102, 255, 102), (102, 204, 102), + (102, 153, 102), (102, 102, 102), (102, 51, 102), (102, 0, 102), + (102, 255, 51), (102, 204, 51), (102, 153, 51), (102, 102, 51), + (102, 51, 51), (102, 0, 51), (102, 255, 0), (102, 204, 0), + (102, 153, 0), (102, 102, 0), (102, 51, 0), (102, 0, 0), + (51, 255, 102), (51, 204, 102), (51, 153, 102), (51, 102, 102), + (51, 51, 102), (51, 0, 102), (51, 255, 51), (51, 204, 51), + (51, 153, 51), (51, 102, 51), (51, 51, 51), (51, 0, 51), + (51, 255, 0), (51, 204, 0), (51, 153, 0), (51, 102, 0), + (51, 51, 0), (51, 0, 0), (0, 255, 102), (0, 204, 102), + (0, 153, 102), (0, 102, 102), (0, 51, 102), (0, 0, 102), + (0, 255, 51), (0, 204, 51), (0, 153, 51), (0, 102, 51), + (0, 51, 51), (0, 0, 51), (0, 255, 0), (0, 204, 0), + (0, 153, 0), (0, 102, 0), (0, 51, 0), (17, 17, 17), + (34, 34, 34), (68, 68, 68), (85, 85, 85), (119, 119, 119), + (136, 136, 136), (170, 170, 170), (187, 187, 187), (221, 221, 221), + (238, 238, 238), (192, 192, 192), (128, 0, 0), (128, 0, 128), + (0, 128, 0), (0, 128, 128), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0), + (0, 0, 0), (0, 0, 0), (0, 0, 0), (0, 0, 0)) +# fmt: on + + +# so build a prototype image to be used for palette resampling +def build_prototype_image() -> Image.Image: + image = Image.new("L", (1, len(_Palm8BitColormapValues))) + image.putdata(list(range(len(_Palm8BitColormapValues)))) + palettedata: tuple[int, ...] = () + for colormapValue in _Palm8BitColormapValues: + palettedata += colormapValue + palettedata += (0, 0, 0) * (256 - len(_Palm8BitColormapValues)) + image.putpalette(palettedata) + return image + + +Palm8BitColormapImage = build_prototype_image() + +# OK, we now have in Palm8BitColormapImage, +# a "P"-mode image with the right palette +# +# -------------------------------------------------------------------- + +_FLAGS = {"custom-colormap": 0x4000, "is-compressed": 0x8000, "has-transparent": 0x2000} + +_COMPRESSION_TYPES = {"none": 0xFF, "rle": 0x01, "scanline": 0x00} + + +# +# -------------------------------------------------------------------- + +## +# (Internal) Image save plugin for the Palm format. + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode == "P": + # we assume this is a color Palm image with the standard colormap, + # unless the "info" dict has a "custom-colormap" field + + rawmode = "P" + bpp = 8 + version = 1 + + elif im.mode == "L": + if im.encoderinfo.get("bpp") in (1, 2, 4): + # this is 8-bit grayscale, so we shift it to get the high-order bits, + # and invert it because + # Palm does grayscale from white (0) to black (1) + bpp = im.encoderinfo["bpp"] + maxval = (1 << bpp) - 1 + shift = 8 - bpp + im = im.point(lambda x: maxval - (x >> shift)) + elif im.info.get("bpp") in (1, 2, 4): + # here we assume that even though the inherent mode is 8-bit grayscale, + # only the lower bpp bits are significant. + # We invert them to match the Palm. + bpp = im.info["bpp"] + maxval = (1 << bpp) - 1 + im = im.point(lambda x: maxval - (x & maxval)) + else: + msg = f"cannot write mode {im.mode} as Palm" + raise OSError(msg) + + # we ignore the palette here + im._mode = "P" + rawmode = f"P;{bpp}" + version = 1 + + elif im.mode == "1": + # monochrome -- write it inverted, as is the Palm standard + rawmode = "1;I" + bpp = 1 + version = 0 + + else: + msg = f"cannot write mode {im.mode} as Palm" + raise OSError(msg) + + # + # make sure image data is available + im.load() + + # write header + + cols = im.size[0] + rows = im.size[1] + + rowbytes = int((cols + (16 // bpp - 1)) / (16 // bpp)) * 2 + transparent_index = 0 + compression_type = _COMPRESSION_TYPES["none"] + + flags = 0 + if im.mode == "P" and "custom-colormap" in im.info: + assert im.palette is not None + flags = flags & _FLAGS["custom-colormap"] + colormapsize = 4 * 256 + 2 + colormapmode = im.palette.mode + colormap = im.getdata().getpalette() + else: + colormapsize = 0 + + if "offset" in im.info: + offset = (rowbytes * rows + 16 + 3 + colormapsize) // 4 + else: + offset = 0 + + fp.write(o16b(cols) + o16b(rows) + o16b(rowbytes) + o16b(flags)) + fp.write(o8(bpp)) + fp.write(o8(version)) + fp.write(o16b(offset)) + fp.write(o8(transparent_index)) + fp.write(o8(compression_type)) + fp.write(o16b(0)) # reserved by Palm + + # now write colormap if necessary + + if colormapsize > 0: + fp.write(o16b(256)) + for i in range(256): + fp.write(o8(i)) + if colormapmode == "RGB": + fp.write( + o8(colormap[3 * i]) + + o8(colormap[3 * i + 1]) + + o8(colormap[3 * i + 2]) + ) + elif colormapmode == "RGBA": + fp.write( + o8(colormap[4 * i]) + + o8(colormap[4 * i + 1]) + + o8(colormap[4 * i + 2]) + ) + + # now convert data to raw form + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, rowbytes, 1))] + ) + + if hasattr(fp, "flush"): + fp.flush() + + +# +# -------------------------------------------------------------------- + +Image.register_save("Palm", _save) + +Image.register_extension("Palm", ".palm") + +Image.register_mime("Palm", "image/palm") diff --git a/venv/lib/python3.12/site-packages/PIL/PcdImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PcdImagePlugin.py new file mode 100644 index 0000000..e8ea800 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PcdImagePlugin.py @@ -0,0 +1,64 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCD file handling +# +# History: +# 96-05-10 fl Created +# 96-05-27 fl Added draft mode (128x192, 256x384) +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile + +## +# Image plugin for PhotoCD images. This plugin only reads the 768x512 +# image from the file; higher resolutions are encoded in a proprietary +# encoding. + + +class PcdImageFile(ImageFile.ImageFile): + format = "PCD" + format_description = "Kodak PhotoCD" + + def _open(self) -> None: + # rough + assert self.fp is not None + + self.fp.seek(2048) + s = self.fp.read(2048) + + if s[:4] != b"PCD_": + msg = "not a PCD file" + raise SyntaxError(msg) + + orientation = s[1538] & 3 + self.tile_post_rotate = None + if orientation == 1: + self.tile_post_rotate = 90 + elif orientation == 3: + self.tile_post_rotate = -90 + + self._mode = "RGB" + self._size = 768, 512 # FIXME: not correct for rotated images! + self.tile = [ImageFile._Tile("pcd", (0, 0) + self.size, 96 * 2048, None)] + + def load_end(self) -> None: + if self.tile_post_rotate: + # Handle rotated PCDs + self.im = self.im.rotate(self.tile_post_rotate) + self._size = self.im.size + + +# +# registry + +Image.register_open(PcdImageFile.format, PcdImageFile) + +Image.register_extension(PcdImageFile.format, ".pcd") diff --git a/venv/lib/python3.12/site-packages/PIL/PcfFontFile.py b/venv/lib/python3.12/site-packages/PIL/PcfFontFile.py new file mode 100644 index 0000000..0d1968b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PcfFontFile.py @@ -0,0 +1,254 @@ +# +# THIS IS WORK IN PROGRESS +# +# The Python Imaging Library +# $Id$ +# +# portable compiled font file parser +# +# history: +# 1997-08-19 fl created +# 2003-09-13 fl fixed loading of unicode fonts +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1997-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from typing import BinaryIO, Callable + +from . import FontFile, Image +from ._binary import i8 +from ._binary import i16be as b16 +from ._binary import i16le as l16 +from ._binary import i32be as b32 +from ._binary import i32le as l32 + +# -------------------------------------------------------------------- +# declarations + +PCF_MAGIC = 0x70636601 # "\x01fcp" + +PCF_PROPERTIES = 1 << 0 +PCF_ACCELERATORS = 1 << 1 +PCF_METRICS = 1 << 2 +PCF_BITMAPS = 1 << 3 +PCF_INK_METRICS = 1 << 4 +PCF_BDF_ENCODINGS = 1 << 5 +PCF_SWIDTHS = 1 << 6 +PCF_GLYPH_NAMES = 1 << 7 +PCF_BDF_ACCELERATORS = 1 << 8 + +BYTES_PER_ROW: list[Callable[[int], int]] = [ + lambda bits: ((bits + 7) >> 3), + lambda bits: ((bits + 15) >> 3) & ~1, + lambda bits: ((bits + 31) >> 3) & ~3, + lambda bits: ((bits + 63) >> 3) & ~7, +] + + +def sz(s: bytes, o: int) -> bytes: + return s[o : s.index(b"\0", o)] + + +class PcfFontFile(FontFile.FontFile): + """Font file plugin for the X11 PCF format.""" + + name = "name" + + def __init__(self, fp: BinaryIO, charset_encoding: str = "iso8859-1"): + self.charset_encoding = charset_encoding + + magic = l32(fp.read(4)) + if magic != PCF_MAGIC: + msg = "not a PCF file" + raise SyntaxError(msg) + + super().__init__() + + count = l32(fp.read(4)) + self.toc = {} + for i in range(count): + type = l32(fp.read(4)) + self.toc[type] = l32(fp.read(4)), l32(fp.read(4)), l32(fp.read(4)) + + self.fp = fp + + self.info = self._load_properties() + + metrics = self._load_metrics() + bitmaps = self._load_bitmaps(metrics) + encoding = self._load_encoding() + + # + # create glyph structure + + for ch, ix in enumerate(encoding): + if ix is not None: + ( + xsize, + ysize, + left, + right, + width, + ascent, + descent, + attributes, + ) = metrics[ix] + self.glyph[ch] = ( + (width, 0), + (left, descent - ysize, xsize + left, descent), + (0, 0, xsize, ysize), + bitmaps[ix], + ) + + def _getformat( + self, tag: int + ) -> tuple[BinaryIO, int, Callable[[bytes], int], Callable[[bytes], int]]: + format, size, offset = self.toc[tag] + + fp = self.fp + fp.seek(offset) + + format = l32(fp.read(4)) + + if format & 4: + i16, i32 = b16, b32 + else: + i16, i32 = l16, l32 + + return fp, format, i16, i32 + + def _load_properties(self) -> dict[bytes, bytes | int]: + # + # font properties + + properties = {} + + fp, format, i16, i32 = self._getformat(PCF_PROPERTIES) + + nprops = i32(fp.read(4)) + + # read property description + p = [(i32(fp.read(4)), i8(fp.read(1)), i32(fp.read(4))) for _ in range(nprops)] + + if nprops & 3: + fp.seek(4 - (nprops & 3), io.SEEK_CUR) # pad + + data = fp.read(i32(fp.read(4))) + + for k, s, v in p: + property_value: bytes | int = sz(data, v) if s else v + properties[sz(data, k)] = property_value + + return properties + + def _load_metrics(self) -> list[tuple[int, int, int, int, int, int, int, int]]: + # + # font metrics + + metrics: list[tuple[int, int, int, int, int, int, int, int]] = [] + + fp, format, i16, i32 = self._getformat(PCF_METRICS) + + append = metrics.append + + if (format & 0xFF00) == 0x100: + # "compressed" metrics + for i in range(i16(fp.read(2))): + left = i8(fp.read(1)) - 128 + right = i8(fp.read(1)) - 128 + width = i8(fp.read(1)) - 128 + ascent = i8(fp.read(1)) - 128 + descent = i8(fp.read(1)) - 128 + xsize = right - left + ysize = ascent + descent + append((xsize, ysize, left, right, width, ascent, descent, 0)) + + else: + # "jumbo" metrics + for i in range(i32(fp.read(4))): + left = i16(fp.read(2)) + right = i16(fp.read(2)) + width = i16(fp.read(2)) + ascent = i16(fp.read(2)) + descent = i16(fp.read(2)) + attributes = i16(fp.read(2)) + xsize = right - left + ysize = ascent + descent + append((xsize, ysize, left, right, width, ascent, descent, attributes)) + + return metrics + + def _load_bitmaps( + self, metrics: list[tuple[int, int, int, int, int, int, int, int]] + ) -> list[Image.Image]: + # + # bitmap data + + fp, format, i16, i32 = self._getformat(PCF_BITMAPS) + + nbitmaps = i32(fp.read(4)) + + if nbitmaps != len(metrics): + msg = "Wrong number of bitmaps" + raise OSError(msg) + + offsets = [i32(fp.read(4)) for _ in range(nbitmaps)] + + bitmap_sizes = [i32(fp.read(4)) for _ in range(4)] + + # byteorder = format & 4 # non-zero => MSB + bitorder = format & 8 # non-zero => MSB + padindex = format & 3 + + bitmapsize = bitmap_sizes[padindex] + offsets.append(bitmapsize) + + data = fp.read(bitmapsize) + + pad = BYTES_PER_ROW[padindex] + mode = "1;R" + if bitorder: + mode = "1" + + bitmaps = [] + for i in range(nbitmaps): + xsize, ysize = metrics[i][:2] + b, e = offsets[i : i + 2] + bitmaps.append( + Image.frombytes("1", (xsize, ysize), data[b:e], "raw", mode, pad(xsize)) + ) + + return bitmaps + + def _load_encoding(self) -> list[int | None]: + fp, format, i16, i32 = self._getformat(PCF_BDF_ENCODINGS) + + first_col, last_col = i16(fp.read(2)), i16(fp.read(2)) + first_row, last_row = i16(fp.read(2)), i16(fp.read(2)) + + i16(fp.read(2)) # default + + nencoding = (last_col - first_col + 1) * (last_row - first_row + 1) + + # map character code to bitmap index + encoding: list[int | None] = [None] * min(256, nencoding) + + encoding_offsets = [i16(fp.read(2)) for _ in range(nencoding)] + + for i in range(first_col, len(encoding)): + try: + encoding_offset = encoding_offsets[ + ord(bytearray([i]).decode(self.charset_encoding)) + ] + if encoding_offset != 0xFFFF: + encoding[i] = encoding_offset + except UnicodeDecodeError: + # character is not supported in selected encoding + pass + + return encoding diff --git a/venv/lib/python3.12/site-packages/PIL/PcxImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PcxImagePlugin.py new file mode 100644 index 0000000..8445d5c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PcxImagePlugin.py @@ -0,0 +1,229 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PCX file handling +# +# This format was originally used by ZSoft's popular PaintBrush +# program for the IBM PC. It is also supported by many MS-DOS and +# Windows applications, including the Windows PaintBrush program in +# Windows 3. +# +# history: +# 1995-09-01 fl Created +# 1996-05-20 fl Fixed RGB support +# 1997-01-03 fl Fixed 2-bit and 4-bit support +# 1999-02-03 fl Fixed 8-bit support (broken in 1.0b1) +# 1999-02-07 fl Added write support +# 2002-06-09 fl Made 2-bit and 4-bit support a bit more robust +# 2002-07-30 fl Seek from to current position, not beginning of file +# 2003-06-03 fl Extract DPI settings (info["dpi"]) +# +# Copyright (c) 1997-2003 by Secret Labs AB. +# Copyright (c) 1995-2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import logging +from typing import IO + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + +logger = logging.getLogger(__name__) + + +def _accept(prefix: bytes) -> bool: + return prefix[0] == 10 and prefix[1] in [0, 2, 3, 5] + + +## +# Image plugin for Paintbrush images. + + +class PcxImageFile(ImageFile.ImageFile): + format = "PCX" + format_description = "Paintbrush" + + def _open(self) -> None: + # header + assert self.fp is not None + + s = self.fp.read(128) + if not _accept(s): + msg = "not a PCX file" + raise SyntaxError(msg) + + # image + bbox = i16(s, 4), i16(s, 6), i16(s, 8) + 1, i16(s, 10) + 1 + if bbox[2] <= bbox[0] or bbox[3] <= bbox[1]: + msg = "bad PCX image size" + raise SyntaxError(msg) + logger.debug("BBox: %s %s %s %s", *bbox) + + # format + version = s[1] + bits = s[3] + planes = s[65] + provided_stride = i16(s, 66) + logger.debug( + "PCX version %s, bits %s, planes %s, stride %s", + version, + bits, + planes, + provided_stride, + ) + + self.info["dpi"] = i16(s, 12), i16(s, 14) + + if bits == 1 and planes == 1: + mode = rawmode = "1" + + elif bits == 1 and planes in (2, 4): + mode = "P" + rawmode = "P;%dL" % planes + self.palette = ImagePalette.raw("RGB", s[16:64]) + + elif version == 5 and bits == 8 and planes == 1: + mode = rawmode = "L" + # FIXME: hey, this doesn't work with the incremental loader !!! + self.fp.seek(-769, io.SEEK_END) + s = self.fp.read(769) + if len(s) == 769 and s[0] == 12: + # check if the palette is linear grayscale + for i in range(256): + if s[i * 3 + 1 : i * 3 + 4] != o8(i) * 3: + mode = rawmode = "P" + break + if mode == "P": + self.palette = ImagePalette.raw("RGB", s[1:]) + self.fp.seek(128) + + elif version == 5 and bits == 8 and planes == 3: + mode = "RGB" + rawmode = "RGB;L" + + else: + msg = "unknown PCX mode" + raise OSError(msg) + + self._mode = mode + self._size = bbox[2] - bbox[0], bbox[3] - bbox[1] + + # Don't trust the passed in stride. + # Calculate the approximate position for ourselves. + # CVE-2020-35653 + stride = (self._size[0] * bits + 7) // 8 + + # While the specification states that this must be even, + # not all images follow this + if provided_stride != stride: + stride += stride % 2 + + bbox = (0, 0) + self.size + logger.debug("size: %sx%s", *self.size) + + self.tile = [ + ImageFile._Tile("pcx", bbox, self.fp.tell(), (rawmode, planes * stride)) + ] + + +# -------------------------------------------------------------------- +# save PCX files + + +SAVE = { + # mode: (version, bits, planes, raw mode) + "1": (2, 1, 1, "1"), + "L": (5, 8, 1, "L"), + "P": (5, 8, 1, "P"), + "RGB": (5, 8, 3, "RGB;L"), +} + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + try: + version, bits, planes, rawmode = SAVE[im.mode] + except KeyError as e: + msg = f"Cannot save {im.mode} images as PCX" + raise ValueError(msg) from e + + # bytes per plane + stride = (im.size[0] * bits + 7) // 8 + # stride should be even + stride += stride % 2 + # Stride needs to be kept in sync with the PcxEncode.c version. + # Ideally it should be passed in in the state, but the bytes value + # gets overwritten. + + logger.debug( + "PcxImagePlugin._save: xwidth: %d, bits: %d, stride: %d", + im.size[0], + bits, + stride, + ) + + # under windows, we could determine the current screen size with + # "Image.core.display_mode()[1]", but I think that's overkill... + + screen = im.size + + dpi = 100, 100 + + # PCX header + fp.write( + o8(10) + + o8(version) + + o8(1) + + o8(bits) + + o16(0) + + o16(0) + + o16(im.size[0] - 1) + + o16(im.size[1] - 1) + + o16(dpi[0]) + + o16(dpi[1]) + + b"\0" * 24 + + b"\xFF" * 24 + + b"\0" + + o8(planes) + + o16(stride) + + o16(1) + + o16(screen[0]) + + o16(screen[1]) + + b"\0" * 54 + ) + + assert fp.tell() == 128 + + ImageFile._save( + im, fp, [ImageFile._Tile("pcx", (0, 0) + im.size, 0, (rawmode, bits * planes))] + ) + + if im.mode == "P": + # colour palette + fp.write(o8(12)) + palette = im.im.getpalette("RGB", "RGB") + palette += b"\x00" * (768 - len(palette)) + fp.write(palette) # 768 bytes + elif im.mode == "L": + # grayscale palette + fp.write(o8(12)) + for i in range(256): + fp.write(o8(i) * 3) + + +# -------------------------------------------------------------------- +# registry + + +Image.register_open(PcxImageFile.format, PcxImageFile, _accept) +Image.register_save(PcxImageFile.format, _save) + +Image.register_extension(PcxImageFile.format, ".pcx") + +Image.register_mime(PcxImageFile.format, "image/x-pcx") diff --git a/venv/lib/python3.12/site-packages/PIL/PdfImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PdfImagePlugin.py new file mode 100644 index 0000000..e9c20dd --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PdfImagePlugin.py @@ -0,0 +1,311 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PDF (Acrobat) file handling +# +# History: +# 1996-07-16 fl Created +# 1997-01-18 fl Fixed header +# 2004-02-21 fl Fixes for 1/L/CMYK images, etc. +# 2004-02-24 fl Fixes for 1 and P images. +# +# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved. +# Copyright (c) 1996-1997 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +## +# Image plugin for PDF images (output only). +## +from __future__ import annotations + +import io +import math +import os +import time +from typing import IO, Any + +from . import Image, ImageFile, ImageSequence, PdfParser, __version__, features + +# +# -------------------------------------------------------------------- + +# object ids: +# 1. catalogue +# 2. pages +# 3. image +# 4. page +# 5. page contents + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + _save(im, fp, filename, save_all=True) + + +## +# (Internal) Image save plugin for the PDF format. + + +def _write_image( + im: Image.Image, + filename: str | bytes, + existing_pdf: PdfParser.PdfParser, + image_refs: list[PdfParser.IndirectReference], +) -> tuple[PdfParser.IndirectReference, str]: + # FIXME: Should replace ASCIIHexDecode with RunLengthDecode + # (packbits) or LZWDecode (tiff/lzw compression). Note that + # PDF 1.2 also supports Flatedecode (zip compression). + + params = None + decode = None + + # + # Get image characteristics + + width, height = im.size + + dict_obj: dict[str, Any] = {"BitsPerComponent": 8} + if im.mode == "1": + if features.check("libtiff"): + decode_filter = "CCITTFaxDecode" + dict_obj["BitsPerComponent"] = 1 + params = PdfParser.PdfArray( + [ + PdfParser.PdfDict( + { + "K": -1, + "BlackIs1": True, + "Columns": width, + "Rows": height, + } + ) + ] + ) + else: + decode_filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray") + procset = "ImageB" # grayscale + elif im.mode == "L": + decode_filter = "DCTDecode" + # params = f"<< /Predictor 15 /Columns {width-2} >>" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceGray") + procset = "ImageB" # grayscale + elif im.mode == "LA": + decode_filter = "JPXDecode" + # params = f"<< /Predictor 15 /Columns {width-2} >>" + procset = "ImageB" # grayscale + dict_obj["SMaskInData"] = 1 + elif im.mode == "P": + decode_filter = "ASCIIHexDecode" + palette = im.getpalette() + assert palette is not None + dict_obj["ColorSpace"] = [ + PdfParser.PdfName("Indexed"), + PdfParser.PdfName("DeviceRGB"), + len(palette) // 3 - 1, + PdfParser.PdfBinary(palette), + ] + procset = "ImageI" # indexed color + + if "transparency" in im.info: + smask = im.convert("LA").getchannel("A") + smask.encoderinfo = {} + + image_ref = _write_image(smask, filename, existing_pdf, image_refs)[0] + dict_obj["SMask"] = image_ref + elif im.mode == "RGB": + decode_filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceRGB") + procset = "ImageC" # color images + elif im.mode == "RGBA": + decode_filter = "JPXDecode" + procset = "ImageC" # color images + dict_obj["SMaskInData"] = 1 + elif im.mode == "CMYK": + decode_filter = "DCTDecode" + dict_obj["ColorSpace"] = PdfParser.PdfName("DeviceCMYK") + procset = "ImageC" # color images + decode = [1, 0, 1, 0, 1, 0, 1, 0] + else: + msg = f"cannot save mode {im.mode}" + raise ValueError(msg) + + # + # image + + op = io.BytesIO() + + if decode_filter == "ASCIIHexDecode": + ImageFile._save(im, op, [ImageFile._Tile("hex", (0, 0) + im.size, 0, im.mode)]) + elif decode_filter == "CCITTFaxDecode": + im.save( + op, + "TIFF", + compression="group4", + # use a single strip + strip_size=math.ceil(width / 8) * height, + ) + elif decode_filter == "DCTDecode": + Image.SAVE["JPEG"](im, op, filename) + elif decode_filter == "JPXDecode": + del dict_obj["BitsPerComponent"] + Image.SAVE["JPEG2000"](im, op, filename) + else: + msg = f"unsupported PDF filter ({decode_filter})" + raise ValueError(msg) + + stream = op.getvalue() + filter: PdfParser.PdfArray | PdfParser.PdfName + if decode_filter == "CCITTFaxDecode": + stream = stream[8:] + filter = PdfParser.PdfArray([PdfParser.PdfName(decode_filter)]) + else: + filter = PdfParser.PdfName(decode_filter) + + image_ref = image_refs.pop(0) + existing_pdf.write_obj( + image_ref, + stream=stream, + Type=PdfParser.PdfName("XObject"), + Subtype=PdfParser.PdfName("Image"), + Width=width, # * 72.0 / x_resolution, + Height=height, # * 72.0 / y_resolution, + Filter=filter, + Decode=decode, + DecodeParms=params, + **dict_obj, + ) + + return image_ref, procset + + +def _save( + im: Image.Image, fp: IO[bytes], filename: str | bytes, save_all: bool = False +) -> None: + is_appending = im.encoderinfo.get("append", False) + filename_str = filename.decode() if isinstance(filename, bytes) else filename + if is_appending: + existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="r+b") + else: + existing_pdf = PdfParser.PdfParser(f=fp, filename=filename_str, mode="w+b") + + dpi = im.encoderinfo.get("dpi") + if dpi: + x_resolution = dpi[0] + y_resolution = dpi[1] + else: + x_resolution = y_resolution = im.encoderinfo.get("resolution", 72.0) + + info = { + "title": ( + None if is_appending else os.path.splitext(os.path.basename(filename))[0] + ), + "author": None, + "subject": None, + "keywords": None, + "creator": None, + "producer": None, + "creationDate": None if is_appending else time.gmtime(), + "modDate": None if is_appending else time.gmtime(), + } + for k, default in info.items(): + v = im.encoderinfo.get(k) if k in im.encoderinfo else default + if v: + existing_pdf.info[k[0].upper() + k[1:]] = v + + # + # make sure image data is available + im.load() + + existing_pdf.start_writing() + existing_pdf.write_header() + existing_pdf.write_comment(f"created by Pillow {__version__} PDF driver") + + # + # pages + ims = [im] + if save_all: + append_images = im.encoderinfo.get("append_images", []) + for append_im in append_images: + append_im.encoderinfo = im.encoderinfo.copy() + ims.append(append_im) + number_of_pages = 0 + image_refs = [] + page_refs = [] + contents_refs = [] + for im in ims: + im_number_of_pages = 1 + if save_all: + im_number_of_pages = getattr(im, "n_frames", 1) + number_of_pages += im_number_of_pages + for i in range(im_number_of_pages): + image_refs.append(existing_pdf.next_object_id(0)) + if im.mode == "P" and "transparency" in im.info: + image_refs.append(existing_pdf.next_object_id(0)) + + page_refs.append(existing_pdf.next_object_id(0)) + contents_refs.append(existing_pdf.next_object_id(0)) + existing_pdf.pages.append(page_refs[-1]) + + # + # catalog and list of pages + existing_pdf.write_catalog() + + page_number = 0 + for im_sequence in ims: + im_pages: ImageSequence.Iterator | list[Image.Image] = ( + ImageSequence.Iterator(im_sequence) if save_all else [im_sequence] + ) + for im in im_pages: + image_ref, procset = _write_image(im, filename, existing_pdf, image_refs) + + # + # page + + existing_pdf.write_page( + page_refs[page_number], + Resources=PdfParser.PdfDict( + ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)], + XObject=PdfParser.PdfDict(image=image_ref), + ), + MediaBox=[ + 0, + 0, + im.width * 72.0 / x_resolution, + im.height * 72.0 / y_resolution, + ], + Contents=contents_refs[page_number], + ) + + # + # page contents + + page_contents = b"q %f 0 0 %f 0 0 cm /image Do Q\n" % ( + im.width * 72.0 / x_resolution, + im.height * 72.0 / y_resolution, + ) + + existing_pdf.write_obj(contents_refs[page_number], stream=page_contents) + + page_number += 1 + + # + # trailer + existing_pdf.write_xref_and_trailer() + if hasattr(fp, "flush"): + fp.flush() + existing_pdf.close() + + +# +# -------------------------------------------------------------------- + + +Image.register_save("PDF", _save) +Image.register_save_all("PDF", _save_all) + +Image.register_extension("PDF", ".pdf") + +Image.register_mime("PDF", "application/pdf") diff --git a/venv/lib/python3.12/site-packages/PIL/PdfParser.py b/venv/lib/python3.12/site-packages/PIL/PdfParser.py new file mode 100644 index 0000000..7cb2d24 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PdfParser.py @@ -0,0 +1,1073 @@ +from __future__ import annotations + +import calendar +import codecs +import collections +import mmap +import os +import re +import time +import zlib +from typing import IO, TYPE_CHECKING, Any, NamedTuple, Union + + +# see 7.9.2.2 Text String Type on page 86 and D.3 PDFDocEncoding Character Set +# on page 656 +def encode_text(s: str) -> bytes: + return codecs.BOM_UTF16_BE + s.encode("utf_16_be") + + +PDFDocEncoding = { + 0x16: "\u0017", + 0x18: "\u02D8", + 0x19: "\u02C7", + 0x1A: "\u02C6", + 0x1B: "\u02D9", + 0x1C: "\u02DD", + 0x1D: "\u02DB", + 0x1E: "\u02DA", + 0x1F: "\u02DC", + 0x80: "\u2022", + 0x81: "\u2020", + 0x82: "\u2021", + 0x83: "\u2026", + 0x84: "\u2014", + 0x85: "\u2013", + 0x86: "\u0192", + 0x87: "\u2044", + 0x88: "\u2039", + 0x89: "\u203A", + 0x8A: "\u2212", + 0x8B: "\u2030", + 0x8C: "\u201E", + 0x8D: "\u201C", + 0x8E: "\u201D", + 0x8F: "\u2018", + 0x90: "\u2019", + 0x91: "\u201A", + 0x92: "\u2122", + 0x93: "\uFB01", + 0x94: "\uFB02", + 0x95: "\u0141", + 0x96: "\u0152", + 0x97: "\u0160", + 0x98: "\u0178", + 0x99: "\u017D", + 0x9A: "\u0131", + 0x9B: "\u0142", + 0x9C: "\u0153", + 0x9D: "\u0161", + 0x9E: "\u017E", + 0xA0: "\u20AC", +} + + +def decode_text(b: bytes) -> str: + if b[: len(codecs.BOM_UTF16_BE)] == codecs.BOM_UTF16_BE: + return b[len(codecs.BOM_UTF16_BE) :].decode("utf_16_be") + else: + return "".join(PDFDocEncoding.get(byte, chr(byte)) for byte in b) + + +class PdfFormatError(RuntimeError): + """An error that probably indicates a syntactic or semantic error in the + PDF file structure""" + + pass + + +def check_format_condition(condition: bool, error_message: str) -> None: + if not condition: + raise PdfFormatError(error_message) + + +class IndirectReferenceTuple(NamedTuple): + object_id: int + generation: int + + +class IndirectReference(IndirectReferenceTuple): + def __str__(self) -> str: + return f"{self.object_id} {self.generation} R" + + def __bytes__(self) -> bytes: + return self.__str__().encode("us-ascii") + + def __eq__(self, other: object) -> bool: + if self.__class__ is not other.__class__: + return False + assert isinstance(other, IndirectReference) + return other.object_id == self.object_id and other.generation == self.generation + + def __ne__(self, other: object) -> bool: + return not (self == other) + + def __hash__(self) -> int: + return hash((self.object_id, self.generation)) + + +class IndirectObjectDef(IndirectReference): + def __str__(self) -> str: + return f"{self.object_id} {self.generation} obj" + + +class XrefTable: + def __init__(self) -> None: + self.existing_entries: dict[int, tuple[int, int]] = ( + {} + ) # object ID => (offset, generation) + self.new_entries: dict[int, tuple[int, int]] = ( + {} + ) # object ID => (offset, generation) + self.deleted_entries = {0: 65536} # object ID => generation + self.reading_finished = False + + def __setitem__(self, key: int, value: tuple[int, int]) -> None: + if self.reading_finished: + self.new_entries[key] = value + else: + self.existing_entries[key] = value + if key in self.deleted_entries: + del self.deleted_entries[key] + + def __getitem__(self, key: int) -> tuple[int, int]: + try: + return self.new_entries[key] + except KeyError: + return self.existing_entries[key] + + def __delitem__(self, key: int) -> None: + if key in self.new_entries: + generation = self.new_entries[key][1] + 1 + del self.new_entries[key] + self.deleted_entries[key] = generation + elif key in self.existing_entries: + generation = self.existing_entries[key][1] + 1 + self.deleted_entries[key] = generation + elif key in self.deleted_entries: + generation = self.deleted_entries[key] + else: + msg = f"object ID {key} cannot be deleted because it doesn't exist" + raise IndexError(msg) + + def __contains__(self, key: int) -> bool: + return key in self.existing_entries or key in self.new_entries + + def __len__(self) -> int: + return len( + set(self.existing_entries.keys()) + | set(self.new_entries.keys()) + | set(self.deleted_entries.keys()) + ) + + def keys(self) -> set[int]: + return ( + set(self.existing_entries.keys()) - set(self.deleted_entries.keys()) + ) | set(self.new_entries.keys()) + + def write(self, f: IO[bytes]) -> int: + keys = sorted(set(self.new_entries.keys()) | set(self.deleted_entries.keys())) + deleted_keys = sorted(set(self.deleted_entries.keys())) + startxref = f.tell() + f.write(b"xref\n") + while keys: + # find a contiguous sequence of object IDs + prev: int | None = None + for index, key in enumerate(keys): + if prev is None or prev + 1 == key: + prev = key + else: + contiguous_keys = keys[:index] + keys = keys[index:] + break + else: + contiguous_keys = keys + keys = [] + f.write(b"%d %d\n" % (contiguous_keys[0], len(contiguous_keys))) + for object_id in contiguous_keys: + if object_id in self.new_entries: + f.write(b"%010d %05d n \n" % self.new_entries[object_id]) + else: + this_deleted_object_id = deleted_keys.pop(0) + check_format_condition( + object_id == this_deleted_object_id, + f"expected the next deleted object ID to be {object_id}, " + f"instead found {this_deleted_object_id}", + ) + try: + next_in_linked_list = deleted_keys[0] + except IndexError: + next_in_linked_list = 0 + f.write( + b"%010d %05d f \n" + % (next_in_linked_list, self.deleted_entries[object_id]) + ) + return startxref + + +class PdfName: + name: bytes + + def __init__(self, name: PdfName | bytes | str) -> None: + if isinstance(name, PdfName): + self.name = name.name + elif isinstance(name, bytes): + self.name = name + else: + self.name = name.encode("us-ascii") + + def name_as_str(self) -> str: + return self.name.decode("us-ascii") + + def __eq__(self, other: object) -> bool: + return ( + isinstance(other, PdfName) and other.name == self.name + ) or other == self.name + + def __hash__(self) -> int: + return hash(self.name) + + def __repr__(self) -> str: + return f"{self.__class__.__name__}({repr(self.name)})" + + @classmethod + def from_pdf_stream(cls, data: bytes) -> PdfName: + return cls(PdfParser.interpret_name(data)) + + allowed_chars = set(range(33, 127)) - {ord(c) for c in "#%/()<>[]{}"} + + def __bytes__(self) -> bytes: + result = bytearray(b"/") + for b in self.name: + if b in self.allowed_chars: + result.append(b) + else: + result.extend(b"#%02X" % b) + return bytes(result) + + +class PdfArray(list[Any]): + def __bytes__(self) -> bytes: + return b"[ " + b" ".join(pdf_repr(x) for x in self) + b" ]" + + +if TYPE_CHECKING: + _DictBase = collections.UserDict[Union[str, bytes], Any] +else: + _DictBase = collections.UserDict + + +class PdfDict(_DictBase): + def __setattr__(self, key: str, value: Any) -> None: + if key == "data": + collections.UserDict.__setattr__(self, key, value) + else: + self[key.encode("us-ascii")] = value + + def __getattr__(self, key: str) -> str | time.struct_time: + try: + value = self[key.encode("us-ascii")] + except KeyError as e: + raise AttributeError(key) from e + if isinstance(value, bytes): + value = decode_text(value) + if key.endswith("Date"): + if value.startswith("D:"): + value = value[2:] + + relationship = "Z" + if len(value) > 17: + relationship = value[14] + offset = int(value[15:17]) * 60 + if len(value) > 20: + offset += int(value[18:20]) + + format = "%Y%m%d%H%M%S"[: len(value) - 2] + value = time.strptime(value[: len(format) + 2], format) + if relationship in ["+", "-"]: + offset *= 60 + if relationship == "+": + offset *= -1 + value = time.gmtime(calendar.timegm(value) + offset) + return value + + def __bytes__(self) -> bytes: + out = bytearray(b"<<") + for key, value in self.items(): + if value is None: + continue + value = pdf_repr(value) + out.extend(b"\n") + out.extend(bytes(PdfName(key))) + out.extend(b" ") + out.extend(value) + out.extend(b"\n>>") + return bytes(out) + + +class PdfBinary: + def __init__(self, data: list[int] | bytes) -> None: + self.data = data + + def __bytes__(self) -> bytes: + return b"<%s>" % b"".join(b"%02X" % b for b in self.data) + + +class PdfStream: + def __init__(self, dictionary: PdfDict, buf: bytes) -> None: + self.dictionary = dictionary + self.buf = buf + + def decode(self) -> bytes: + try: + filter = self.dictionary[b"Filter"] + except KeyError: + return self.buf + if filter == b"FlateDecode": + try: + expected_length = self.dictionary[b"DL"] + except KeyError: + expected_length = self.dictionary[b"Length"] + return zlib.decompress(self.buf, bufsize=int(expected_length)) + else: + msg = f"stream filter {repr(filter)} unknown/unsupported" + raise NotImplementedError(msg) + + +def pdf_repr(x: Any) -> bytes: + if x is True: + return b"true" + elif x is False: + return b"false" + elif x is None: + return b"null" + elif isinstance(x, (PdfName, PdfDict, PdfArray, PdfBinary)): + return bytes(x) + elif isinstance(x, (int, float)): + return str(x).encode("us-ascii") + elif isinstance(x, time.struct_time): + return b"(D:" + time.strftime("%Y%m%d%H%M%SZ", x).encode("us-ascii") + b")" + elif isinstance(x, dict): + return bytes(PdfDict(x)) + elif isinstance(x, list): + return bytes(PdfArray(x)) + elif isinstance(x, str): + return pdf_repr(encode_text(x)) + elif isinstance(x, bytes): + # XXX escape more chars? handle binary garbage + x = x.replace(b"\\", b"\\\\") + x = x.replace(b"(", b"\\(") + x = x.replace(b")", b"\\)") + return b"(" + x + b")" + else: + return bytes(x) + + +class PdfParser: + """Based on + https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf + Supports PDF up to 1.4 + """ + + def __init__( + self, + filename: str | None = None, + f: IO[bytes] | None = None, + buf: bytes | bytearray | None = None, + start_offset: int = 0, + mode: str = "rb", + ) -> None: + if buf and f: + msg = "specify buf or f or filename, but not both buf and f" + raise RuntimeError(msg) + self.filename = filename + self.buf: bytes | bytearray | mmap.mmap | None = buf + self.f = f + self.start_offset = start_offset + self.should_close_buf = False + self.should_close_file = False + if filename is not None and f is None: + self.f = f = open(filename, mode) + self.should_close_file = True + if f is not None: + self.buf = self.get_buf_from_file(f) + self.should_close_buf = True + if not filename and hasattr(f, "name"): + self.filename = f.name + self.cached_objects: dict[IndirectReference, Any] = {} + self.root_ref: IndirectReference | None + self.info_ref: IndirectReference | None + self.pages_ref: IndirectReference | None + self.last_xref_section_offset: int | None + if self.buf: + self.read_pdf_info() + else: + self.file_size_total = self.file_size_this = 0 + self.root = PdfDict() + self.root_ref = None + self.info = PdfDict() + self.info_ref = None + self.page_tree_root = PdfDict() + self.pages: list[IndirectReference] = [] + self.orig_pages: list[IndirectReference] = [] + self.pages_ref = None + self.last_xref_section_offset = None + self.trailer_dict: dict[bytes, Any] = {} + self.xref_table = XrefTable() + self.xref_table.reading_finished = True + if f: + self.seek_end() + + def __enter__(self) -> PdfParser: + return self + + def __exit__(self, *args: object) -> None: + self.close() + + def start_writing(self) -> None: + self.close_buf() + self.seek_end() + + def close_buf(self) -> None: + if isinstance(self.buf, mmap.mmap): + self.buf.close() + self.buf = None + + def close(self) -> None: + if self.should_close_buf: + self.close_buf() + if self.f is not None and self.should_close_file: + self.f.close() + self.f = None + + def seek_end(self) -> None: + assert self.f is not None + self.f.seek(0, os.SEEK_END) + + def write_header(self) -> None: + assert self.f is not None + self.f.write(b"%PDF-1.4\n") + + def write_comment(self, s: str) -> None: + assert self.f is not None + self.f.write(f"% {s}\n".encode()) + + def write_catalog(self) -> IndirectReference: + assert self.f is not None + self.del_root() + self.root_ref = self.next_object_id(self.f.tell()) + self.pages_ref = self.next_object_id(0) + self.rewrite_pages() + self.write_obj(self.root_ref, Type=PdfName(b"Catalog"), Pages=self.pages_ref) + self.write_obj( + self.pages_ref, + Type=PdfName(b"Pages"), + Count=len(self.pages), + Kids=self.pages, + ) + return self.root_ref + + def rewrite_pages(self) -> None: + pages_tree_nodes_to_delete = [] + for i, page_ref in enumerate(self.orig_pages): + page_info = self.cached_objects[page_ref] + del self.xref_table[page_ref.object_id] + pages_tree_nodes_to_delete.append(page_info[PdfName(b"Parent")]) + if page_ref not in self.pages: + # the page has been deleted + continue + # make dict keys into strings for passing to write_page + stringified_page_info = {} + for key, value in page_info.items(): + # key should be a PdfName + stringified_page_info[key.name_as_str()] = value + stringified_page_info["Parent"] = self.pages_ref + new_page_ref = self.write_page(None, **stringified_page_info) + for j, cur_page_ref in enumerate(self.pages): + if cur_page_ref == page_ref: + # replace the page reference with the new one + self.pages[j] = new_page_ref + # delete redundant Pages tree nodes from xref table + for pages_tree_node_ref in pages_tree_nodes_to_delete: + while pages_tree_node_ref: + pages_tree_node = self.cached_objects[pages_tree_node_ref] + if pages_tree_node_ref.object_id in self.xref_table: + del self.xref_table[pages_tree_node_ref.object_id] + pages_tree_node_ref = pages_tree_node.get(b"Parent", None) + self.orig_pages = [] + + def write_xref_and_trailer( + self, new_root_ref: IndirectReference | None = None + ) -> None: + assert self.f is not None + if new_root_ref: + self.del_root() + self.root_ref = new_root_ref + if self.info: + self.info_ref = self.write_obj(None, self.info) + start_xref = self.xref_table.write(self.f) + num_entries = len(self.xref_table) + trailer_dict: dict[str | bytes, Any] = { + b"Root": self.root_ref, + b"Size": num_entries, + } + if self.last_xref_section_offset is not None: + trailer_dict[b"Prev"] = self.last_xref_section_offset + if self.info: + trailer_dict[b"Info"] = self.info_ref + self.last_xref_section_offset = start_xref + self.f.write( + b"trailer\n" + + bytes(PdfDict(trailer_dict)) + + b"\nstartxref\n%d\n%%%%EOF" % start_xref + ) + + def write_page( + self, ref: int | IndirectReference | None, *objs: Any, **dict_obj: Any + ) -> IndirectReference: + obj_ref = self.pages[ref] if isinstance(ref, int) else ref + if "Type" not in dict_obj: + dict_obj["Type"] = PdfName(b"Page") + if "Parent" not in dict_obj: + dict_obj["Parent"] = self.pages_ref + return self.write_obj(obj_ref, *objs, **dict_obj) + + def write_obj( + self, ref: IndirectReference | None, *objs: Any, **dict_obj: Any + ) -> IndirectReference: + assert self.f is not None + f = self.f + if ref is None: + ref = self.next_object_id(f.tell()) + else: + self.xref_table[ref.object_id] = (f.tell(), ref.generation) + f.write(bytes(IndirectObjectDef(*ref))) + stream = dict_obj.pop("stream", None) + if stream is not None: + dict_obj["Length"] = len(stream) + if dict_obj: + f.write(pdf_repr(dict_obj)) + for obj in objs: + f.write(pdf_repr(obj)) + if stream is not None: + f.write(b"stream\n") + f.write(stream) + f.write(b"\nendstream\n") + f.write(b"endobj\n") + return ref + + def del_root(self) -> None: + if self.root_ref is None: + return + del self.xref_table[self.root_ref.object_id] + del self.xref_table[self.root[b"Pages"].object_id] + + @staticmethod + def get_buf_from_file(f: IO[bytes]) -> bytes | mmap.mmap: + if hasattr(f, "getbuffer"): + return f.getbuffer() + elif hasattr(f, "getvalue"): + return f.getvalue() + else: + try: + return mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) + except ValueError: # cannot mmap an empty file + return b"" + + def read_pdf_info(self) -> None: + assert self.buf is not None + self.file_size_total = len(self.buf) + self.file_size_this = self.file_size_total - self.start_offset + self.read_trailer() + check_format_condition( + self.trailer_dict.get(b"Root") is not None, "Root is missing" + ) + self.root_ref = self.trailer_dict[b"Root"] + assert self.root_ref is not None + self.info_ref = self.trailer_dict.get(b"Info", None) + self.root = PdfDict(self.read_indirect(self.root_ref)) + if self.info_ref is None: + self.info = PdfDict() + else: + self.info = PdfDict(self.read_indirect(self.info_ref)) + check_format_condition(b"Type" in self.root, "/Type missing in Root") + check_format_condition( + self.root[b"Type"] == b"Catalog", "/Type in Root is not /Catalog" + ) + check_format_condition( + self.root.get(b"Pages") is not None, "/Pages missing in Root" + ) + check_format_condition( + isinstance(self.root[b"Pages"], IndirectReference), + "/Pages in Root is not an indirect reference", + ) + self.pages_ref = self.root[b"Pages"] + assert self.pages_ref is not None + self.page_tree_root = self.read_indirect(self.pages_ref) + self.pages = self.linearize_page_tree(self.page_tree_root) + # save the original list of page references + # in case the user modifies, adds or deletes some pages + # and we need to rewrite the pages and their list + self.orig_pages = self.pages[:] + + def next_object_id(self, offset: int | None = None) -> IndirectReference: + try: + # TODO: support reuse of deleted objects + reference = IndirectReference(max(self.xref_table.keys()) + 1, 0) + except ValueError: + reference = IndirectReference(1, 0) + if offset is not None: + self.xref_table[reference.object_id] = (offset, 0) + return reference + + delimiter = rb"[][()<>{}/%]" + delimiter_or_ws = rb"[][()<>{}/%\000\011\012\014\015\040]" + whitespace = rb"[\000\011\012\014\015\040]" + whitespace_or_hex = rb"[\000\011\012\014\015\0400-9a-fA-F]" + whitespace_optional = whitespace + b"*" + whitespace_mandatory = whitespace + b"+" + # No "\012" aka "\n" or "\015" aka "\r": + whitespace_optional_no_nl = rb"[\000\011\014\040]*" + newline_only = rb"[\r\n]+" + newline = whitespace_optional_no_nl + newline_only + whitespace_optional_no_nl + re_trailer_end = re.compile( + whitespace_mandatory + + rb"trailer" + + whitespace_optional + + rb"<<(.*>>)" + + newline + + rb"startxref" + + newline + + rb"([0-9]+)" + + newline + + rb"%%EOF" + + whitespace_optional + + rb"$", + re.DOTALL, + ) + re_trailer_prev = re.compile( + whitespace_optional + + rb"trailer" + + whitespace_optional + + rb"<<(.*?>>)" + + newline + + rb"startxref" + + newline + + rb"([0-9]+)" + + newline + + rb"%%EOF" + + whitespace_optional, + re.DOTALL, + ) + + def read_trailer(self) -> None: + assert self.buf is not None + search_start_offset = len(self.buf) - 16384 + if search_start_offset < self.start_offset: + search_start_offset = self.start_offset + m = self.re_trailer_end.search(self.buf, search_start_offset) + check_format_condition(m is not None, "trailer end not found") + # make sure we found the LAST trailer + last_match = m + while m: + last_match = m + m = self.re_trailer_end.search(self.buf, m.start() + 16) + if not m: + m = last_match + assert m is not None + trailer_data = m.group(1) + self.last_xref_section_offset = int(m.group(2)) + self.trailer_dict = self.interpret_trailer(trailer_data) + self.xref_table = XrefTable() + self.read_xref_table(xref_section_offset=self.last_xref_section_offset) + if b"Prev" in self.trailer_dict: + self.read_prev_trailer(self.trailer_dict[b"Prev"]) + + def read_prev_trailer(self, xref_section_offset: int) -> None: + assert self.buf is not None + trailer_offset = self.read_xref_table(xref_section_offset=xref_section_offset) + m = self.re_trailer_prev.search( + self.buf[trailer_offset : trailer_offset + 16384] + ) + check_format_condition(m is not None, "previous trailer not found") + assert m is not None + trailer_data = m.group(1) + check_format_condition( + int(m.group(2)) == xref_section_offset, + "xref section offset in previous trailer doesn't match what was expected", + ) + trailer_dict = self.interpret_trailer(trailer_data) + if b"Prev" in trailer_dict: + self.read_prev_trailer(trailer_dict[b"Prev"]) + + re_whitespace_optional = re.compile(whitespace_optional) + re_name = re.compile( + whitespace_optional + + rb"/([!-$&'*-.0-;=?-Z\\^-z|~]+)(?=" + + delimiter_or_ws + + rb")" + ) + re_dict_start = re.compile(whitespace_optional + rb"<<") + re_dict_end = re.compile(whitespace_optional + rb">>" + whitespace_optional) + + @classmethod + def interpret_trailer(cls, trailer_data: bytes) -> dict[bytes, Any]: + trailer = {} + offset = 0 + while True: + m = cls.re_name.match(trailer_data, offset) + if not m: + m = cls.re_dict_end.match(trailer_data, offset) + check_format_condition( + m is not None and m.end() == len(trailer_data), + "name not found in trailer, remaining data: " + + repr(trailer_data[offset:]), + ) + break + key = cls.interpret_name(m.group(1)) + assert isinstance(key, bytes) + value, value_offset = cls.get_value(trailer_data, m.end()) + trailer[key] = value + if value_offset is None: + break + offset = value_offset + check_format_condition( + b"Size" in trailer and isinstance(trailer[b"Size"], int), + "/Size not in trailer or not an integer", + ) + check_format_condition( + b"Root" in trailer and isinstance(trailer[b"Root"], IndirectReference), + "/Root not in trailer or not an indirect reference", + ) + return trailer + + re_hashes_in_name = re.compile(rb"([^#]*)(#([0-9a-fA-F]{2}))?") + + @classmethod + def interpret_name(cls, raw: bytes, as_text: bool = False) -> str | bytes: + name = b"" + for m in cls.re_hashes_in_name.finditer(raw): + if m.group(3): + name += m.group(1) + bytearray.fromhex(m.group(3).decode("us-ascii")) + else: + name += m.group(1) + if as_text: + return name.decode("utf-8") + else: + return bytes(name) + + re_null = re.compile(whitespace_optional + rb"null(?=" + delimiter_or_ws + rb")") + re_true = re.compile(whitespace_optional + rb"true(?=" + delimiter_or_ws + rb")") + re_false = re.compile(whitespace_optional + rb"false(?=" + delimiter_or_ws + rb")") + re_int = re.compile( + whitespace_optional + rb"([-+]?[0-9]+)(?=" + delimiter_or_ws + rb")" + ) + re_real = re.compile( + whitespace_optional + + rb"([-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9]+))(?=" + + delimiter_or_ws + + rb")" + ) + re_array_start = re.compile(whitespace_optional + rb"\[") + re_array_end = re.compile(whitespace_optional + rb"]") + re_string_hex = re.compile( + whitespace_optional + rb"<(" + whitespace_or_hex + rb"*)>" + ) + re_string_lit = re.compile(whitespace_optional + rb"\(") + re_indirect_reference = re.compile( + whitespace_optional + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"R(?=" + + delimiter_or_ws + + rb")" + ) + re_indirect_def_start = re.compile( + whitespace_optional + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"([-+]?[0-9]+)" + + whitespace_mandatory + + rb"obj(?=" + + delimiter_or_ws + + rb")" + ) + re_indirect_def_end = re.compile( + whitespace_optional + rb"endobj(?=" + delimiter_or_ws + rb")" + ) + re_comment = re.compile( + rb"(" + whitespace_optional + rb"%[^\r\n]*" + newline + rb")*" + ) + re_stream_start = re.compile(whitespace_optional + rb"stream\r?\n") + re_stream_end = re.compile( + whitespace_optional + rb"endstream(?=" + delimiter_or_ws + rb")" + ) + + @classmethod + def get_value( + cls, + data: bytes | bytearray | mmap.mmap, + offset: int, + expect_indirect: IndirectReference | None = None, + max_nesting: int = -1, + ) -> tuple[Any, int | None]: + if max_nesting == 0: + return None, None + m = cls.re_comment.match(data, offset) + if m: + offset = m.end() + m = cls.re_indirect_def_start.match(data, offset) + if m: + check_format_condition( + int(m.group(1)) > 0, + "indirect object definition: object ID must be greater than 0", + ) + check_format_condition( + int(m.group(2)) >= 0, + "indirect object definition: generation must be non-negative", + ) + check_format_condition( + expect_indirect is None + or expect_indirect + == IndirectReference(int(m.group(1)), int(m.group(2))), + "indirect object definition different than expected", + ) + object, object_offset = cls.get_value( + data, m.end(), max_nesting=max_nesting - 1 + ) + if object_offset is None: + return object, None + m = cls.re_indirect_def_end.match(data, object_offset) + check_format_condition( + m is not None, "indirect object definition end not found" + ) + assert m is not None + return object, m.end() + check_format_condition( + not expect_indirect, "indirect object definition not found" + ) + m = cls.re_indirect_reference.match(data, offset) + if m: + check_format_condition( + int(m.group(1)) > 0, + "indirect object reference: object ID must be greater than 0", + ) + check_format_condition( + int(m.group(2)) >= 0, + "indirect object reference: generation must be non-negative", + ) + return IndirectReference(int(m.group(1)), int(m.group(2))), m.end() + m = cls.re_dict_start.match(data, offset) + if m: + offset = m.end() + result: dict[Any, Any] = {} + m = cls.re_dict_end.match(data, offset) + current_offset: int | None = offset + while not m: + assert current_offset is not None + key, current_offset = cls.get_value( + data, current_offset, max_nesting=max_nesting - 1 + ) + if current_offset is None: + return result, None + value, current_offset = cls.get_value( + data, current_offset, max_nesting=max_nesting - 1 + ) + result[key] = value + if current_offset is None: + return result, None + m = cls.re_dict_end.match(data, current_offset) + current_offset = m.end() + m = cls.re_stream_start.match(data, current_offset) + if m: + stream_len = result.get(b"Length") + if stream_len is None or not isinstance(stream_len, int): + msg = f"bad or missing Length in stream dict ({stream_len})" + raise PdfFormatError(msg) + stream_data = data[m.end() : m.end() + stream_len] + m = cls.re_stream_end.match(data, m.end() + stream_len) + check_format_condition(m is not None, "stream end not found") + assert m is not None + current_offset = m.end() + return PdfStream(PdfDict(result), stream_data), current_offset + return PdfDict(result), current_offset + m = cls.re_array_start.match(data, offset) + if m: + offset = m.end() + results = [] + m = cls.re_array_end.match(data, offset) + current_offset = offset + while not m: + assert current_offset is not None + value, current_offset = cls.get_value( + data, current_offset, max_nesting=max_nesting - 1 + ) + results.append(value) + if current_offset is None: + return results, None + m = cls.re_array_end.match(data, current_offset) + return results, m.end() + m = cls.re_null.match(data, offset) + if m: + return None, m.end() + m = cls.re_true.match(data, offset) + if m: + return True, m.end() + m = cls.re_false.match(data, offset) + if m: + return False, m.end() + m = cls.re_name.match(data, offset) + if m: + return PdfName(cls.interpret_name(m.group(1))), m.end() + m = cls.re_int.match(data, offset) + if m: + return int(m.group(1)), m.end() + m = cls.re_real.match(data, offset) + if m: + # XXX Decimal instead of float??? + return float(m.group(1)), m.end() + m = cls.re_string_hex.match(data, offset) + if m: + # filter out whitespace + hex_string = bytearray( + b for b in m.group(1) if b in b"0123456789abcdefABCDEF" + ) + if len(hex_string) % 2 == 1: + # append a 0 if the length is not even - yes, at the end + hex_string.append(ord(b"0")) + return bytearray.fromhex(hex_string.decode("us-ascii")), m.end() + m = cls.re_string_lit.match(data, offset) + if m: + return cls.get_literal_string(data, m.end()) + # return None, offset # fallback (only for debugging) + msg = f"unrecognized object: {repr(data[offset : offset + 32])}" + raise PdfFormatError(msg) + + re_lit_str_token = re.compile( + rb"(\\[nrtbf()\\])|(\\[0-9]{1,3})|(\\(\r\n|\r|\n))|(\r\n|\r|\n)|(\()|(\))" + ) + escaped_chars = { + b"n": b"\n", + b"r": b"\r", + b"t": b"\t", + b"b": b"\b", + b"f": b"\f", + b"(": b"(", + b")": b")", + b"\\": b"\\", + ord(b"n"): b"\n", + ord(b"r"): b"\r", + ord(b"t"): b"\t", + ord(b"b"): b"\b", + ord(b"f"): b"\f", + ord(b"("): b"(", + ord(b")"): b")", + ord(b"\\"): b"\\", + } + + @classmethod + def get_literal_string( + cls, data: bytes | bytearray | mmap.mmap, offset: int + ) -> tuple[bytes, int]: + nesting_depth = 0 + result = bytearray() + for m in cls.re_lit_str_token.finditer(data, offset): + result.extend(data[offset : m.start()]) + if m.group(1): + result.extend(cls.escaped_chars[m.group(1)[1]]) + elif m.group(2): + result.append(int(m.group(2)[1:], 8)) + elif m.group(3): + pass + elif m.group(5): + result.extend(b"\n") + elif m.group(6): + result.extend(b"(") + nesting_depth += 1 + elif m.group(7): + if nesting_depth == 0: + return bytes(result), m.end() + result.extend(b")") + nesting_depth -= 1 + offset = m.end() + msg = "unfinished literal string" + raise PdfFormatError(msg) + + re_xref_section_start = re.compile(whitespace_optional + rb"xref" + newline) + re_xref_subsection_start = re.compile( + whitespace_optional + + rb"([0-9]+)" + + whitespace_mandatory + + rb"([0-9]+)" + + whitespace_optional + + newline_only + ) + re_xref_entry = re.compile(rb"([0-9]{10}) ([0-9]{5}) ([fn])( \r| \n|\r\n)") + + def read_xref_table(self, xref_section_offset: int) -> int: + assert self.buf is not None + subsection_found = False + m = self.re_xref_section_start.match( + self.buf, xref_section_offset + self.start_offset + ) + check_format_condition(m is not None, "xref section start not found") + assert m is not None + offset = m.end() + while True: + m = self.re_xref_subsection_start.match(self.buf, offset) + if not m: + check_format_condition( + subsection_found, "xref subsection start not found" + ) + break + subsection_found = True + offset = m.end() + first_object = int(m.group(1)) + num_objects = int(m.group(2)) + for i in range(first_object, first_object + num_objects): + m = self.re_xref_entry.match(self.buf, offset) + check_format_condition(m is not None, "xref entry not found") + assert m is not None + offset = m.end() + is_free = m.group(3) == b"f" + if not is_free: + generation = int(m.group(2)) + new_entry = (int(m.group(1)), generation) + if i not in self.xref_table: + self.xref_table[i] = new_entry + return offset + + def read_indirect(self, ref: IndirectReference, max_nesting: int = -1) -> Any: + offset, generation = self.xref_table[ref[0]] + check_format_condition( + generation == ref[1], + f"expected to find generation {ref[1]} for object ID {ref[0]} in xref " + f"table, instead found generation {generation} at offset {offset}", + ) + assert self.buf is not None + value = self.get_value( + self.buf, + offset + self.start_offset, + expect_indirect=IndirectReference(*ref), + max_nesting=max_nesting, + )[0] + self.cached_objects[ref] = value + return value + + def linearize_page_tree( + self, node: PdfDict | None = None + ) -> list[IndirectReference]: + page_node = node if node is not None else self.page_tree_root + check_format_condition( + page_node[b"Type"] == b"Pages", "/Type of page tree node is not /Pages" + ) + pages = [] + for kid in page_node[b"Kids"]: + kid_object = self.read_indirect(kid) + if kid_object[b"Type"] == b"Page": + pages.append(kid) + else: + pages.extend(self.linearize_page_tree(node=kid_object)) + return pages diff --git a/venv/lib/python3.12/site-packages/PIL/PixarImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PixarImagePlugin.py new file mode 100644 index 0000000..36f565f --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PixarImagePlugin.py @@ -0,0 +1,74 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PIXAR raster support for PIL +# +# history: +# 97-01-29 fl Created +# +# notes: +# This is incomplete; it is based on a few samples created with +# Photoshop 2.5 and 3.0, and a summary description provided by +# Greg Coats . Hopefully, "L" and +# "RGBA" support will be added in future versions. +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1997. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile +from ._binary import i16le as i16 + +# +# helpers + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"\200\350\000\000" + + +## +# Image plugin for PIXAR raster images. + + +class PixarImageFile(ImageFile.ImageFile): + format = "PIXAR" + format_description = "PIXAR raster image" + + def _open(self) -> None: + # assuming a 4-byte magic label + assert self.fp is not None + + s = self.fp.read(4) + if not _accept(s): + msg = "not a PIXAR file" + raise SyntaxError(msg) + + # read rest of header + s = s + self.fp.read(508) + + self._size = i16(s, 418), i16(s, 416) + + # get channel/depth descriptions + mode = i16(s, 424), i16(s, 426) + + if mode == (14, 2): + self._mode = "RGB" + # FIXME: to be continued... + + # create tile descriptor (assuming "dumped") + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, 1024, (self.mode, 0, 1)) + ] + + +# +# -------------------------------------------------------------------- + +Image.register_open(PixarImageFile.format, PixarImageFile, _accept) + +Image.register_extension(PixarImageFile.format, ".pxr") diff --git a/venv/lib/python3.12/site-packages/PIL/PngImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PngImagePlugin.py new file mode 100644 index 0000000..4e12272 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PngImagePlugin.py @@ -0,0 +1,1544 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PNG support code +# +# See "PNG (Portable Network Graphics) Specification, version 1.0; +# W3C Recommendation", 1996-10-01, Thomas Boutell (ed.). +# +# history: +# 1996-05-06 fl Created (couldn't resist it) +# 1996-12-14 fl Upgraded, added read and verify support (0.2) +# 1996-12-15 fl Separate PNG stream parser +# 1996-12-29 fl Added write support, added getchunks +# 1996-12-30 fl Eliminated circular references in decoder (0.3) +# 1998-07-12 fl Read/write 16-bit images as mode I (0.4) +# 2001-02-08 fl Added transparency support (from Zircon) (0.5) +# 2001-04-16 fl Don't close data source in "open" method (0.6) +# 2004-02-24 fl Don't even pretend to support interlaced files (0.7) +# 2004-08-31 fl Do basic sanity check on chunk identifiers (0.8) +# 2004-09-20 fl Added PngInfo chunk container +# 2004-12-18 fl Added DPI read support (based on code by Niki Spahiev) +# 2008-08-13 fl Added tRNS support for RGB images +# 2009-03-06 fl Support for preserving ICC profiles (by Florian Hoech) +# 2009-03-08 fl Added zTXT support (from Lowell Alleman) +# 2009-03-29 fl Read interlaced PNG files (from Conrado Porto Lopes Gouvua) +# +# Copyright (c) 1997-2009 by Secret Labs AB +# Copyright (c) 1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import itertools +import logging +import re +import struct +import warnings +import zlib +from collections.abc import Callable +from enum import IntEnum +from typing import IO, TYPE_CHECKING, Any, NamedTuple, NoReturn, cast + +from . import Image, ImageChops, ImageFile, ImagePalette, ImageSequence +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from ._binary import o16be as o16 +from ._binary import o32be as o32 + +if TYPE_CHECKING: + from . import _imaging + +logger = logging.getLogger(__name__) + +is_cid = re.compile(rb"\w\w\w\w").match + + +_MAGIC = b"\211PNG\r\n\032\n" + + +_MODES = { + # supported bits/color combinations, and corresponding modes/rawmodes + # Grayscale + (1, 0): ("1", "1"), + (2, 0): ("L", "L;2"), + (4, 0): ("L", "L;4"), + (8, 0): ("L", "L"), + (16, 0): ("I;16", "I;16B"), + # Truecolour + (8, 2): ("RGB", "RGB"), + (16, 2): ("RGB", "RGB;16B"), + # Indexed-colour + (1, 3): ("P", "P;1"), + (2, 3): ("P", "P;2"), + (4, 3): ("P", "P;4"), + (8, 3): ("P", "P"), + # Grayscale with alpha + (8, 4): ("LA", "LA"), + (16, 4): ("RGBA", "LA;16B"), # LA;16B->LA not yet available + # Truecolour with alpha + (8, 6): ("RGBA", "RGBA"), + (16, 6): ("RGBA", "RGBA;16B"), +} + + +_simple_palette = re.compile(b"^\xff*\x00\xff*$") + +MAX_TEXT_CHUNK = ImageFile.SAFEBLOCK +""" +Maximum decompressed size for a iTXt or zTXt chunk. +Eliminates decompression bombs where compressed chunks can expand 1000x. +See :ref:`Text in PNG File Format`. +""" +MAX_TEXT_MEMORY = 64 * MAX_TEXT_CHUNK +""" +Set the maximum total text chunk size. +See :ref:`Text in PNG File Format`. +""" + + +# APNG frame disposal modes +class Disposal(IntEnum): + OP_NONE = 0 + """ + No disposal is done on this frame before rendering the next frame. + See :ref:`Saving APNG sequences`. + """ + OP_BACKGROUND = 1 + """ + This frame’s modified region is cleared to fully transparent black before rendering + the next frame. + See :ref:`Saving APNG sequences`. + """ + OP_PREVIOUS = 2 + """ + This frame’s modified region is reverted to the previous frame’s contents before + rendering the next frame. + See :ref:`Saving APNG sequences`. + """ + + +# APNG frame blend modes +class Blend(IntEnum): + OP_SOURCE = 0 + """ + All color components of this frame, including alpha, overwrite the previous output + image contents. + See :ref:`Saving APNG sequences`. + """ + OP_OVER = 1 + """ + This frame should be alpha composited with the previous output image contents. + See :ref:`Saving APNG sequences`. + """ + + +def _safe_zlib_decompress(s: bytes) -> bytes: + dobj = zlib.decompressobj() + plaintext = dobj.decompress(s, MAX_TEXT_CHUNK) + if dobj.unconsumed_tail: + msg = "Decompressed data too large for PngImagePlugin.MAX_TEXT_CHUNK" + raise ValueError(msg) + return plaintext + + +def _crc32(data: bytes, seed: int = 0) -> int: + return zlib.crc32(data, seed) & 0xFFFFFFFF + + +# -------------------------------------------------------------------- +# Support classes. Suitable for PNG and related formats like MNG etc. + + +class ChunkStream: + def __init__(self, fp: IO[bytes]) -> None: + self.fp: IO[bytes] | None = fp + self.queue: list[tuple[bytes, int, int]] | None = [] + + def read(self) -> tuple[bytes, int, int]: + """Fetch a new chunk. Returns header information.""" + cid = None + + assert self.fp is not None + if self.queue: + cid, pos, length = self.queue.pop() + self.fp.seek(pos) + else: + s = self.fp.read(8) + cid = s[4:] + pos = self.fp.tell() + length = i32(s) + + if not is_cid(cid): + if not ImageFile.LOAD_TRUNCATED_IMAGES: + msg = f"broken PNG file (chunk {repr(cid)})" + raise SyntaxError(msg) + + return cid, pos, length + + def __enter__(self) -> ChunkStream: + return self + + def __exit__(self, *args: object) -> None: + self.close() + + def close(self) -> None: + self.queue = self.fp = None + + def push(self, cid: bytes, pos: int, length: int) -> None: + assert self.queue is not None + self.queue.append((cid, pos, length)) + + def call(self, cid: bytes, pos: int, length: int) -> bytes: + """Call the appropriate chunk handler""" + + logger.debug("STREAM %r %s %s", cid, pos, length) + return getattr(self, f"chunk_{cid.decode('ascii')}")(pos, length) + + def crc(self, cid: bytes, data: bytes) -> None: + """Read and verify checksum""" + + # Skip CRC checks for ancillary chunks if allowed to load truncated + # images + # 5th byte of first char is 1 [specs, section 5.4] + if ImageFile.LOAD_TRUNCATED_IMAGES and (cid[0] >> 5 & 1): + self.crc_skip(cid, data) + return + + assert self.fp is not None + try: + crc1 = _crc32(data, _crc32(cid)) + crc2 = i32(self.fp.read(4)) + if crc1 != crc2: + msg = f"broken PNG file (bad header checksum in {repr(cid)})" + raise SyntaxError(msg) + except struct.error as e: + msg = f"broken PNG file (incomplete checksum in {repr(cid)})" + raise SyntaxError(msg) from e + + def crc_skip(self, cid: bytes, data: bytes) -> None: + """Read checksum""" + + assert self.fp is not None + self.fp.read(4) + + def verify(self, endchunk: bytes = b"IEND") -> list[bytes]: + # Simple approach; just calculate checksum for all remaining + # blocks. Must be called directly after open. + + cids = [] + + assert self.fp is not None + while True: + try: + cid, pos, length = self.read() + except struct.error as e: + msg = "truncated PNG file" + raise OSError(msg) from e + + if cid == endchunk: + break + self.crc(cid, ImageFile._safe_read(self.fp, length)) + cids.append(cid) + + return cids + + +class iTXt(str): + """ + Subclass of string to allow iTXt chunks to look like strings while + keeping their extra information + + """ + + lang: str | bytes | None + tkey: str | bytes | None + + @staticmethod + def __new__( + cls, text: str, lang: str | None = None, tkey: str | None = None + ) -> iTXt: + """ + :param cls: the class to use when creating the instance + :param text: value for this key + :param lang: language code + :param tkey: UTF-8 version of the key name + """ + + self = str.__new__(cls, text) + self.lang = lang + self.tkey = tkey + return self + + +class PngInfo: + """ + PNG chunk container (for use with save(pnginfo=)) + + """ + + def __init__(self) -> None: + self.chunks: list[tuple[bytes, bytes, bool]] = [] + + def add(self, cid: bytes, data: bytes, after_idat: bool = False) -> None: + """Appends an arbitrary chunk. Use with caution. + + :param cid: a byte string, 4 bytes long. + :param data: a byte string of the encoded data + :param after_idat: for use with private chunks. Whether the chunk + should be written after IDAT + + """ + + self.chunks.append((cid, data, after_idat)) + + def add_itxt( + self, + key: str | bytes, + value: str | bytes, + lang: str | bytes = "", + tkey: str | bytes = "", + zip: bool = False, + ) -> None: + """Appends an iTXt chunk. + + :param key: latin-1 encodable text key name + :param value: value for this key + :param lang: language code + :param tkey: UTF-8 version of the key name + :param zip: compression flag + + """ + + if not isinstance(key, bytes): + key = key.encode("latin-1", "strict") + if not isinstance(value, bytes): + value = value.encode("utf-8", "strict") + if not isinstance(lang, bytes): + lang = lang.encode("utf-8", "strict") + if not isinstance(tkey, bytes): + tkey = tkey.encode("utf-8", "strict") + + if zip: + self.add( + b"iTXt", + key + b"\0\x01\0" + lang + b"\0" + tkey + b"\0" + zlib.compress(value), + ) + else: + self.add(b"iTXt", key + b"\0\0\0" + lang + b"\0" + tkey + b"\0" + value) + + def add_text( + self, key: str | bytes, value: str | bytes | iTXt, zip: bool = False + ) -> None: + """Appends a text chunk. + + :param key: latin-1 encodable text key name + :param value: value for this key, text or an + :py:class:`PIL.PngImagePlugin.iTXt` instance + :param zip: compression flag + + """ + if isinstance(value, iTXt): + return self.add_itxt( + key, + value, + value.lang if value.lang is not None else b"", + value.tkey if value.tkey is not None else b"", + zip=zip, + ) + + # The tEXt chunk stores latin-1 text + if not isinstance(value, bytes): + try: + value = value.encode("latin-1", "strict") + except UnicodeError: + return self.add_itxt(key, value, zip=zip) + + if not isinstance(key, bytes): + key = key.encode("latin-1", "strict") + + if zip: + self.add(b"zTXt", key + b"\0\0" + zlib.compress(value)) + else: + self.add(b"tEXt", key + b"\0" + value) + + +# -------------------------------------------------------------------- +# PNG image stream (IHDR/IEND) + + +class _RewindState(NamedTuple): + info: dict[str | tuple[int, int], Any] + tile: list[ImageFile._Tile] + seq_num: int | None + + +class PngStream(ChunkStream): + def __init__(self, fp: IO[bytes]) -> None: + super().__init__(fp) + + # local copies of Image attributes + self.im_info: dict[str | tuple[int, int], Any] = {} + self.im_text: dict[str, str | iTXt] = {} + self.im_size = (0, 0) + self.im_mode = "" + self.im_tile: list[ImageFile._Tile] = [] + self.im_palette: tuple[str, bytes] | None = None + self.im_custom_mimetype: str | None = None + self.im_n_frames: int | None = None + self._seq_num: int | None = None + self.rewind_state = _RewindState({}, [], None) + + self.text_memory = 0 + + def check_text_memory(self, chunklen: int) -> None: + self.text_memory += chunklen + if self.text_memory > MAX_TEXT_MEMORY: + msg = ( + "Too much memory used in text chunks: " + f"{self.text_memory}>MAX_TEXT_MEMORY" + ) + raise ValueError(msg) + + def save_rewind(self) -> None: + self.rewind_state = _RewindState( + self.im_info.copy(), + self.im_tile, + self._seq_num, + ) + + def rewind(self) -> None: + self.im_info = self.rewind_state.info.copy() + self.im_tile = self.rewind_state.tile + self._seq_num = self.rewind_state.seq_num + + def chunk_iCCP(self, pos: int, length: int) -> bytes: + # ICC profile + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + i = s.find(b"\0") + logger.debug("iCCP profile name %r", s[:i]) + comp_method = s[i + 1] + logger.debug("Compression method %s", comp_method) + if comp_method != 0: + msg = f"Unknown compression method {comp_method} in iCCP chunk" + raise SyntaxError(msg) + try: + icc_profile = _safe_zlib_decompress(s[i + 2 :]) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + icc_profile = None + else: + raise + except zlib.error: + icc_profile = None # FIXME + self.im_info["icc_profile"] = icc_profile + return s + + def chunk_IHDR(self, pos: int, length: int) -> bytes: + # image header + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if length < 13: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated IHDR chunk" + raise ValueError(msg) + self.im_size = i32(s, 0), i32(s, 4) + try: + self.im_mode, self.im_rawmode = _MODES[(s[8], s[9])] + except Exception: + pass + if s[12]: + self.im_info["interlace"] = 1 + if s[11]: + msg = "unknown filter category" + raise SyntaxError(msg) + return s + + def chunk_IDAT(self, pos: int, length: int) -> NoReturn: + # image data + if "bbox" in self.im_info: + tile = [ImageFile._Tile("zip", self.im_info["bbox"], pos, self.im_rawmode)] + else: + if self.im_n_frames is not None: + self.im_info["default_image"] = True + tile = [ImageFile._Tile("zip", (0, 0) + self.im_size, pos, self.im_rawmode)] + self.im_tile = tile + self.im_idat = length + msg = "image data found" + raise EOFError(msg) + + def chunk_IEND(self, pos: int, length: int) -> NoReturn: + msg = "end of PNG image" + raise EOFError(msg) + + def chunk_PLTE(self, pos: int, length: int) -> bytes: + # palette + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if self.im_mode == "P": + self.im_palette = "RGB", s + return s + + def chunk_tRNS(self, pos: int, length: int) -> bytes: + # transparency + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if self.im_mode == "P": + if _simple_palette.match(s): + # tRNS contains only one full-transparent entry, + # other entries are full opaque + i = s.find(b"\0") + if i >= 0: + self.im_info["transparency"] = i + else: + # otherwise, we have a byte string with one alpha value + # for each palette entry + self.im_info["transparency"] = s + elif self.im_mode in ("1", "L", "I;16"): + self.im_info["transparency"] = i16(s) + elif self.im_mode == "RGB": + self.im_info["transparency"] = i16(s), i16(s, 2), i16(s, 4) + return s + + def chunk_gAMA(self, pos: int, length: int) -> bytes: + # gamma setting + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + self.im_info["gamma"] = i32(s) / 100000.0 + return s + + def chunk_cHRM(self, pos: int, length: int) -> bytes: + # chromaticity, 8 unsigned ints, actual value is scaled by 100,000 + # WP x,y, Red x,y, Green x,y Blue x,y + + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + raw_vals = struct.unpack(">%dI" % (len(s) // 4), s) + self.im_info["chromaticity"] = tuple(elt / 100000.0 for elt in raw_vals) + return s + + def chunk_sRGB(self, pos: int, length: int) -> bytes: + # srgb rendering intent, 1 byte + # 0 perceptual + # 1 relative colorimetric + # 2 saturation + # 3 absolute colorimetric + + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if length < 1: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated sRGB chunk" + raise ValueError(msg) + self.im_info["srgb"] = s[0] + return s + + def chunk_pHYs(self, pos: int, length: int) -> bytes: + # pixels per unit + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if length < 9: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "Truncated pHYs chunk" + raise ValueError(msg) + px, py = i32(s, 0), i32(s, 4) + unit = s[8] + if unit == 1: # meter + dpi = px * 0.0254, py * 0.0254 + self.im_info["dpi"] = dpi + elif unit == 0: + self.im_info["aspect"] = px, py + return s + + def chunk_tEXt(self, pos: int, length: int) -> bytes: + # text + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + try: + k, v = s.split(b"\0", 1) + except ValueError: + # fallback for broken tEXt tags + k = s + v = b"" + if k: + k_str = k.decode("latin-1", "strict") + v_str = v.decode("latin-1", "replace") + + self.im_info[k_str] = v if k == b"exif" else v_str + self.im_text[k_str] = v_str + self.check_text_memory(len(v_str)) + + return s + + def chunk_zTXt(self, pos: int, length: int) -> bytes: + # compressed text + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + try: + k, v = s.split(b"\0", 1) + except ValueError: + k = s + v = b"" + if v: + comp_method = v[0] + else: + comp_method = 0 + if comp_method != 0: + msg = f"Unknown compression method {comp_method} in zTXt chunk" + raise SyntaxError(msg) + try: + v = _safe_zlib_decompress(v[1:]) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + v = b"" + else: + raise + except zlib.error: + v = b"" + + if k: + k_str = k.decode("latin-1", "strict") + v_str = v.decode("latin-1", "replace") + + self.im_info[k_str] = self.im_text[k_str] = v_str + self.check_text_memory(len(v_str)) + + return s + + def chunk_iTXt(self, pos: int, length: int) -> bytes: + # international text + assert self.fp is not None + r = s = ImageFile._safe_read(self.fp, length) + try: + k, r = r.split(b"\0", 1) + except ValueError: + return s + if len(r) < 2: + return s + cf, cm, r = r[0], r[1], r[2:] + try: + lang, tk, v = r.split(b"\0", 2) + except ValueError: + return s + if cf != 0: + if cm == 0: + try: + v = _safe_zlib_decompress(v) + except ValueError: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + else: + raise + except zlib.error: + return s + else: + return s + if k == b"XML:com.adobe.xmp": + self.im_info["xmp"] = v + try: + k_str = k.decode("latin-1", "strict") + lang_str = lang.decode("utf-8", "strict") + tk_str = tk.decode("utf-8", "strict") + v_str = v.decode("utf-8", "strict") + except UnicodeError: + return s + + self.im_info[k_str] = self.im_text[k_str] = iTXt(v_str, lang_str, tk_str) + self.check_text_memory(len(v_str)) + + return s + + def chunk_eXIf(self, pos: int, length: int) -> bytes: + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + self.im_info["exif"] = b"Exif\x00\x00" + s + return s + + # APNG chunks + def chunk_acTL(self, pos: int, length: int) -> bytes: + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if length < 8: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "APNG contains truncated acTL chunk" + raise ValueError(msg) + if self.im_n_frames is not None: + self.im_n_frames = None + warnings.warn("Invalid APNG, will use default PNG image if possible") + return s + n_frames = i32(s) + if n_frames == 0 or n_frames > 0x80000000: + warnings.warn("Invalid APNG, will use default PNG image if possible") + return s + self.im_n_frames = n_frames + self.im_info["loop"] = i32(s, 4) + self.im_custom_mimetype = "image/apng" + return s + + def chunk_fcTL(self, pos: int, length: int) -> bytes: + assert self.fp is not None + s = ImageFile._safe_read(self.fp, length) + if length < 26: + if ImageFile.LOAD_TRUNCATED_IMAGES: + return s + msg = "APNG contains truncated fcTL chunk" + raise ValueError(msg) + seq = i32(s) + if (self._seq_num is None and seq != 0) or ( + self._seq_num is not None and self._seq_num != seq - 1 + ): + msg = "APNG contains frame sequence errors" + raise SyntaxError(msg) + self._seq_num = seq + width, height = i32(s, 4), i32(s, 8) + px, py = i32(s, 12), i32(s, 16) + im_w, im_h = self.im_size + if px + width > im_w or py + height > im_h: + msg = "APNG contains invalid frames" + raise SyntaxError(msg) + self.im_info["bbox"] = (px, py, px + width, py + height) + delay_num, delay_den = i16(s, 20), i16(s, 22) + if delay_den == 0: + delay_den = 100 + self.im_info["duration"] = float(delay_num) / float(delay_den) * 1000 + self.im_info["disposal"] = s[24] + self.im_info["blend"] = s[25] + return s + + def chunk_fdAT(self, pos: int, length: int) -> bytes: + assert self.fp is not None + if length < 4: + if ImageFile.LOAD_TRUNCATED_IMAGES: + s = ImageFile._safe_read(self.fp, length) + return s + msg = "APNG contains truncated fDAT chunk" + raise ValueError(msg) + s = ImageFile._safe_read(self.fp, 4) + seq = i32(s) + if self._seq_num != seq - 1: + msg = "APNG contains frame sequence errors" + raise SyntaxError(msg) + self._seq_num = seq + return self.chunk_IDAT(pos + 4, length - 4) + + +# -------------------------------------------------------------------- +# PNG reader + + +def _accept(prefix: bytes) -> bool: + return prefix[:8] == _MAGIC + + +## +# Image plugin for PNG images. + + +class PngImageFile(ImageFile.ImageFile): + format = "PNG" + format_description = "Portable network graphics" + + def _open(self) -> None: + if not _accept(self.fp.read(8)): + msg = "not a PNG file" + raise SyntaxError(msg) + self._fp = self.fp + self.__frame = 0 + + # + # Parse headers up to the first IDAT or fDAT chunk + + self.private_chunks: list[tuple[bytes, bytes] | tuple[bytes, bytes, bool]] = [] + self.png: PngStream | None = PngStream(self.fp) + + while True: + # + # get next chunk + + cid, pos, length = self.png.read() + + try: + s = self.png.call(cid, pos, length) + except EOFError: + break + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + s = ImageFile._safe_read(self.fp, length) + if cid[1:2].islower(): + self.private_chunks.append((cid, s)) + + self.png.crc(cid, s) + + # + # Copy relevant attributes from the PngStream. An alternative + # would be to let the PngStream class modify these attributes + # directly, but that introduces circular references which are + # difficult to break if things go wrong in the decoder... + # (believe me, I've tried ;-) + + self._mode = self.png.im_mode + self._size = self.png.im_size + self.info = self.png.im_info + self._text: dict[str, str | iTXt] | None = None + self.tile = self.png.im_tile + self.custom_mimetype = self.png.im_custom_mimetype + self.n_frames = self.png.im_n_frames or 1 + self.default_image = self.info.get("default_image", False) + + if self.png.im_palette: + rawmode, data = self.png.im_palette + self.palette = ImagePalette.raw(rawmode, data) + + if cid == b"fdAT": + self.__prepare_idat = length - 4 + else: + self.__prepare_idat = length # used by load_prepare() + + if self.png.im_n_frames is not None: + self._close_exclusive_fp_after_loading = False + self.png.save_rewind() + self.__rewind_idat = self.__prepare_idat + self.__rewind = self._fp.tell() + if self.default_image: + # IDAT chunk contains default image and not first animation frame + self.n_frames += 1 + self._seek(0) + self.is_animated = self.n_frames > 1 + + @property + def text(self) -> dict[str, str | iTXt]: + # experimental + if self._text is None: + # iTxt, tEXt and zTXt chunks may appear at the end of the file + # So load the file to ensure that they are read + if self.is_animated: + frame = self.__frame + # for APNG, seek to the final frame before loading + self.seek(self.n_frames - 1) + self.load() + if self.is_animated: + self.seek(frame) + assert self._text is not None + return self._text + + def verify(self) -> None: + """Verify PNG file""" + + if self.fp is None: + msg = "verify must be called directly after open" + raise RuntimeError(msg) + + # back up to beginning of IDAT block + self.fp.seek(self.tile[0][2] - 8) + + assert self.png is not None + self.png.verify() + self.png.close() + + if self._exclusive_fp: + self.fp.close() + self.fp = None + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + if frame < self.__frame: + self._seek(0, True) + + last_frame = self.__frame + for f in range(self.__frame + 1, frame + 1): + try: + self._seek(f) + except EOFError as e: + self.seek(last_frame) + msg = "no more images in APNG file" + raise EOFError(msg) from e + + def _seek(self, frame: int, rewind: bool = False) -> None: + assert self.png is not None + + self.dispose: _imaging.ImagingCore | None + dispose_extent = None + if frame == 0: + if rewind: + self._fp.seek(self.__rewind) + self.png.rewind() + self.__prepare_idat = self.__rewind_idat + self._im = None + self.info = self.png.im_info + self.tile = self.png.im_tile + self.fp = self._fp + self._prev_im = None + self.dispose = None + self.default_image = self.info.get("default_image", False) + self.dispose_op = self.info.get("disposal") + self.blend_op = self.info.get("blend") + dispose_extent = self.info.get("bbox") + self.__frame = 0 + else: + if frame != self.__frame + 1: + msg = f"cannot seek to frame {frame}" + raise ValueError(msg) + + # ensure previous frame was loaded + self.load() + + if self.dispose: + self.im.paste(self.dispose, self.dispose_extent) + self._prev_im = self.im.copy() + + self.fp = self._fp + + # advance to the next frame + if self.__prepare_idat: + ImageFile._safe_read(self.fp, self.__prepare_idat) + self.__prepare_idat = 0 + frame_start = False + while True: + self.fp.read(4) # CRC + + try: + cid, pos, length = self.png.read() + except (struct.error, SyntaxError): + break + + if cid == b"IEND": + msg = "No more images in APNG file" + raise EOFError(msg) + if cid == b"fcTL": + if frame_start: + # there must be at least one fdAT chunk between fcTL chunks + msg = "APNG missing frame data" + raise SyntaxError(msg) + frame_start = True + + try: + self.png.call(cid, pos, length) + except UnicodeDecodeError: + break + except EOFError: + if cid == b"fdAT": + length -= 4 + if frame_start: + self.__prepare_idat = length + break + ImageFile._safe_read(self.fp, length) + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + ImageFile._safe_read(self.fp, length) + + self.__frame = frame + self.tile = self.png.im_tile + self.dispose_op = self.info.get("disposal") + self.blend_op = self.info.get("blend") + dispose_extent = self.info.get("bbox") + + if not self.tile: + msg = "image not found in APNG frame" + raise EOFError(msg) + if dispose_extent: + self.dispose_extent: tuple[float, float, float, float] = dispose_extent + + # setup frame disposal (actual disposal done when needed in the next _seek()) + if self._prev_im is None and self.dispose_op == Disposal.OP_PREVIOUS: + self.dispose_op = Disposal.OP_BACKGROUND + + self.dispose = None + if self.dispose_op == Disposal.OP_PREVIOUS: + if self._prev_im: + self.dispose = self._prev_im.copy() + self.dispose = self._crop(self.dispose, self.dispose_extent) + elif self.dispose_op == Disposal.OP_BACKGROUND: + self.dispose = Image.core.fill(self.mode, self.size) + self.dispose = self._crop(self.dispose, self.dispose_extent) + + def tell(self) -> int: + return self.__frame + + def load_prepare(self) -> None: + """internal: prepare to read PNG file""" + + if self.info.get("interlace"): + self.decoderconfig = self.decoderconfig + (1,) + + self.__idat = self.__prepare_idat # used by load_read() + ImageFile.ImageFile.load_prepare(self) + + def load_read(self, read_bytes: int) -> bytes: + """internal: read more image data""" + + assert self.png is not None + while self.__idat == 0: + # end of chunk, skip forward to next one + + self.fp.read(4) # CRC + + cid, pos, length = self.png.read() + + if cid not in [b"IDAT", b"DDAT", b"fdAT"]: + self.png.push(cid, pos, length) + return b"" + + if cid == b"fdAT": + try: + self.png.call(cid, pos, length) + except EOFError: + pass + self.__idat = length - 4 # sequence_num has already been read + else: + self.__idat = length # empty chunks are allowed + + # read more data from this chunk + if read_bytes <= 0: + read_bytes = self.__idat + else: + read_bytes = min(read_bytes, self.__idat) + + self.__idat = self.__idat - read_bytes + + return self.fp.read(read_bytes) + + def load_end(self) -> None: + """internal: finished reading image data""" + assert self.png is not None + if self.__idat != 0: + self.fp.read(self.__idat) + while True: + self.fp.read(4) # CRC + + try: + cid, pos, length = self.png.read() + except (struct.error, SyntaxError): + break + + if cid == b"IEND": + break + elif cid == b"fcTL" and self.is_animated: + # start of the next frame, stop reading + self.__prepare_idat = 0 + self.png.push(cid, pos, length) + break + + try: + self.png.call(cid, pos, length) + except UnicodeDecodeError: + break + except EOFError: + if cid == b"fdAT": + length -= 4 + try: + ImageFile._safe_read(self.fp, length) + except OSError as e: + if ImageFile.LOAD_TRUNCATED_IMAGES: + break + else: + raise e + except AttributeError: + logger.debug("%r %s %s (unknown)", cid, pos, length) + s = ImageFile._safe_read(self.fp, length) + if cid[1:2].islower(): + self.private_chunks.append((cid, s, True)) + self._text = self.png.im_text + if not self.is_animated: + self.png.close() + self.png = None + else: + if self._prev_im and self.blend_op == Blend.OP_OVER: + updated = self._crop(self.im, self.dispose_extent) + if self.im.mode == "RGB" and "transparency" in self.info: + mask = updated.convert_transparent( + "RGBA", self.info["transparency"] + ) + else: + if self.im.mode == "P" and "transparency" in self.info: + t = self.info["transparency"] + if isinstance(t, bytes): + updated.putpalettealphas(t) + elif isinstance(t, int): + updated.putpalettealpha(t) + mask = updated.convert("RGBA") + self._prev_im.paste(updated, self.dispose_extent, mask) + self.im = self._prev_im + + def _getexif(self) -> dict[int, Any] | None: + if "exif" not in self.info: + self.load() + if "exif" not in self.info and "Raw profile type exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + def getexif(self) -> Image.Exif: + if "exif" not in self.info: + self.load() + + return super().getexif() + + +# -------------------------------------------------------------------- +# PNG writer + +_OUTMODES = { + # supported PIL modes, and corresponding rawmode, bit depth and color type + "1": ("1", b"\x01", b"\x00"), + "L;1": ("L;1", b"\x01", b"\x00"), + "L;2": ("L;2", b"\x02", b"\x00"), + "L;4": ("L;4", b"\x04", b"\x00"), + "L": ("L", b"\x08", b"\x00"), + "LA": ("LA", b"\x08", b"\x04"), + "I": ("I;16B", b"\x10", b"\x00"), + "I;16": ("I;16B", b"\x10", b"\x00"), + "I;16B": ("I;16B", b"\x10", b"\x00"), + "P;1": ("P;1", b"\x01", b"\x03"), + "P;2": ("P;2", b"\x02", b"\x03"), + "P;4": ("P;4", b"\x04", b"\x03"), + "P": ("P", b"\x08", b"\x03"), + "RGB": ("RGB", b"\x08", b"\x02"), + "RGBA": ("RGBA", b"\x08", b"\x06"), +} + + +def putchunk(fp: IO[bytes], cid: bytes, *data: bytes) -> None: + """Write a PNG chunk (including CRC field)""" + + byte_data = b"".join(data) + + fp.write(o32(len(byte_data)) + cid) + fp.write(byte_data) + crc = _crc32(byte_data, _crc32(cid)) + fp.write(o32(crc)) + + +class _idat: + # wrap output from the encoder in IDAT chunks + + def __init__(self, fp: IO[bytes], chunk: Callable[..., None]) -> None: + self.fp = fp + self.chunk = chunk + + def write(self, data: bytes) -> None: + self.chunk(self.fp, b"IDAT", data) + + +class _fdat: + # wrap encoder output in fdAT chunks + + def __init__(self, fp: IO[bytes], chunk: Callable[..., None], seq_num: int) -> None: + self.fp = fp + self.chunk = chunk + self.seq_num = seq_num + + def write(self, data: bytes) -> None: + self.chunk(self.fp, b"fdAT", o32(self.seq_num), data) + self.seq_num += 1 + + +class _Frame(NamedTuple): + im: Image.Image + bbox: tuple[int, int, int, int] | None + encoderinfo: dict[str, Any] + + +def _write_multiple_frames( + im: Image.Image, + fp: IO[bytes], + chunk: Callable[..., None], + mode: str, + rawmode: str, + default_image: Image.Image | None, + append_images: list[Image.Image], +) -> Image.Image | None: + duration = im.encoderinfo.get("duration") + loop = im.encoderinfo.get("loop", im.info.get("loop", 0)) + disposal = im.encoderinfo.get("disposal", im.info.get("disposal", Disposal.OP_NONE)) + blend = im.encoderinfo.get("blend", im.info.get("blend", Blend.OP_SOURCE)) + + if default_image: + chain = itertools.chain(append_images) + else: + chain = itertools.chain([im], append_images) + + im_frames: list[_Frame] = [] + frame_count = 0 + for im_seq in chain: + for im_frame in ImageSequence.Iterator(im_seq): + if im_frame.mode == mode: + im_frame = im_frame.copy() + else: + im_frame = im_frame.convert(mode) + encoderinfo = im.encoderinfo.copy() + if isinstance(duration, (list, tuple)): + encoderinfo["duration"] = duration[frame_count] + elif duration is None and "duration" in im_frame.info: + encoderinfo["duration"] = im_frame.info["duration"] + if isinstance(disposal, (list, tuple)): + encoderinfo["disposal"] = disposal[frame_count] + if isinstance(blend, (list, tuple)): + encoderinfo["blend"] = blend[frame_count] + frame_count += 1 + + if im_frames: + previous = im_frames[-1] + prev_disposal = previous.encoderinfo.get("disposal") + prev_blend = previous.encoderinfo.get("blend") + if prev_disposal == Disposal.OP_PREVIOUS and len(im_frames) < 2: + prev_disposal = Disposal.OP_BACKGROUND + + if prev_disposal == Disposal.OP_BACKGROUND: + base_im = previous.im.copy() + dispose = Image.core.fill("RGBA", im.size, (0, 0, 0, 0)) + bbox = previous.bbox + if bbox: + dispose = dispose.crop(bbox) + else: + bbox = (0, 0) + im.size + base_im.paste(dispose, bbox) + elif prev_disposal == Disposal.OP_PREVIOUS: + base_im = im_frames[-2].im + else: + base_im = previous.im + delta = ImageChops.subtract_modulo( + im_frame.convert("RGBA"), base_im.convert("RGBA") + ) + bbox = delta.getbbox(alpha_only=False) + if ( + not bbox + and prev_disposal == encoderinfo.get("disposal") + and prev_blend == encoderinfo.get("blend") + and "duration" in encoderinfo + ): + previous.encoderinfo["duration"] += encoderinfo["duration"] + continue + else: + bbox = None + im_frames.append(_Frame(im_frame, bbox, encoderinfo)) + + if len(im_frames) == 1 and not default_image: + return im_frames[0].im + + # animation control + chunk( + fp, + b"acTL", + o32(len(im_frames)), # 0: num_frames + o32(loop), # 4: num_plays + ) + + # default image IDAT (if it exists) + if default_image: + if im.mode != mode: + im = im.convert(mode) + ImageFile._save( + im, + cast(IO[bytes], _idat(fp, chunk)), + [ImageFile._Tile("zip", (0, 0) + im.size, 0, rawmode)], + ) + + seq_num = 0 + for frame, frame_data in enumerate(im_frames): + im_frame = frame_data.im + if not frame_data.bbox: + bbox = (0, 0) + im_frame.size + else: + bbox = frame_data.bbox + im_frame = im_frame.crop(bbox) + size = im_frame.size + encoderinfo = frame_data.encoderinfo + frame_duration = int(round(encoderinfo.get("duration", 0))) + frame_disposal = encoderinfo.get("disposal", disposal) + frame_blend = encoderinfo.get("blend", blend) + # frame control + chunk( + fp, + b"fcTL", + o32(seq_num), # sequence_number + o32(size[0]), # width + o32(size[1]), # height + o32(bbox[0]), # x_offset + o32(bbox[1]), # y_offset + o16(frame_duration), # delay_numerator + o16(1000), # delay_denominator + o8(frame_disposal), # dispose_op + o8(frame_blend), # blend_op + ) + seq_num += 1 + # frame data + if frame == 0 and not default_image: + # first frame must be in IDAT chunks for backwards compatibility + ImageFile._save( + im_frame, + cast(IO[bytes], _idat(fp, chunk)), + [ImageFile._Tile("zip", (0, 0) + im_frame.size, 0, rawmode)], + ) + else: + fdat_chunks = _fdat(fp, chunk, seq_num) + ImageFile._save( + im_frame, + cast(IO[bytes], fdat_chunks), + [ImageFile._Tile("zip", (0, 0) + im_frame.size, 0, rawmode)], + ) + seq_num = fdat_chunks.seq_num + return None + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + _save(im, fp, filename, save_all=True) + + +def _save( + im: Image.Image, + fp: IO[bytes], + filename: str | bytes, + chunk: Callable[..., None] = putchunk, + save_all: bool = False, +) -> None: + # save an image to disk (called by the save method) + + if save_all: + default_image = im.encoderinfo.get( + "default_image", im.info.get("default_image") + ) + modes = set() + sizes = set() + append_images = im.encoderinfo.get("append_images", []) + for im_seq in itertools.chain([im], append_images): + for im_frame in ImageSequence.Iterator(im_seq): + modes.add(im_frame.mode) + sizes.add(im_frame.size) + for mode in ("RGBA", "RGB", "P"): + if mode in modes: + break + else: + mode = modes.pop() + size = tuple(max(frame_size[i] for frame_size in sizes) for i in range(2)) + else: + size = im.size + mode = im.mode + + outmode = mode + if mode == "P": + # + # attempt to minimize storage requirements for palette images + if "bits" in im.encoderinfo: + # number of bits specified by user + colors = min(1 << im.encoderinfo["bits"], 256) + else: + # check palette contents + if im.palette: + colors = max(min(len(im.palette.getdata()[1]) // 3, 256), 1) + else: + colors = 256 + + if colors <= 16: + if colors <= 2: + bits = 1 + elif colors <= 4: + bits = 2 + else: + bits = 4 + outmode += f";{bits}" + + # encoder options + im.encoderconfig = ( + im.encoderinfo.get("optimize", False), + im.encoderinfo.get("compress_level", -1), + im.encoderinfo.get("compress_type", -1), + im.encoderinfo.get("dictionary", b""), + ) + + # get the corresponding PNG mode + try: + rawmode, bit_depth, color_type = _OUTMODES[outmode] + except KeyError as e: + msg = f"cannot write mode {mode} as PNG" + raise OSError(msg) from e + + # + # write minimal PNG file + + fp.write(_MAGIC) + + chunk( + fp, + b"IHDR", + o32(size[0]), # 0: size + o32(size[1]), + bit_depth, + color_type, + b"\0", # 10: compression + b"\0", # 11: filter category + b"\0", # 12: interlace flag + ) + + chunks = [b"cHRM", b"gAMA", b"sBIT", b"sRGB", b"tIME"] + + icc = im.encoderinfo.get("icc_profile", im.info.get("icc_profile")) + if icc: + # ICC profile + # according to PNG spec, the iCCP chunk contains: + # Profile name 1-79 bytes (character string) + # Null separator 1 byte (null character) + # Compression method 1 byte (0) + # Compressed profile n bytes (zlib with deflate compression) + name = b"ICC Profile" + data = name + b"\0\0" + zlib.compress(icc) + chunk(fp, b"iCCP", data) + + # You must either have sRGB or iCCP. + # Disallow sRGB chunks when an iCCP-chunk has been emitted. + chunks.remove(b"sRGB") + + info = im.encoderinfo.get("pnginfo") + if info: + chunks_multiple_allowed = [b"sPLT", b"iTXt", b"tEXt", b"zTXt"] + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) + elif cid in chunks_multiple_allowed: + chunk(fp, cid, data) + elif cid[1:2].islower(): + # Private chunk + after_idat = len(info_chunk) == 3 and info_chunk[2] + if not after_idat: + chunk(fp, cid, data) + + if im.mode == "P": + palette_byte_number = colors * 3 + palette_bytes = im.im.getpalette("RGB")[:palette_byte_number] + while len(palette_bytes) < palette_byte_number: + palette_bytes += b"\0" + chunk(fp, b"PLTE", palette_bytes) + + transparency = im.encoderinfo.get("transparency", im.info.get("transparency", None)) + + if transparency or transparency == 0: + if im.mode == "P": + # limit to actual palette size + alpha_bytes = colors + if isinstance(transparency, bytes): + chunk(fp, b"tRNS", transparency[:alpha_bytes]) + else: + transparency = max(0, min(255, transparency)) + alpha = b"\xFF" * transparency + b"\0" + chunk(fp, b"tRNS", alpha[:alpha_bytes]) + elif im.mode in ("1", "L", "I", "I;16"): + transparency = max(0, min(65535, transparency)) + chunk(fp, b"tRNS", o16(transparency)) + elif im.mode == "RGB": + red, green, blue = transparency + chunk(fp, b"tRNS", o16(red) + o16(green) + o16(blue)) + else: + if "transparency" in im.encoderinfo: + # don't bother with transparency if it's an RGBA + # and it's in the info dict. It's probably just stale. + msg = "cannot use transparency for this mode" + raise OSError(msg) + else: + if im.mode == "P" and im.im.getpalettemode() == "RGBA": + alpha = im.im.getpalette("RGBA", "A") + alpha_bytes = colors + chunk(fp, b"tRNS", alpha[:alpha_bytes]) + + dpi = im.encoderinfo.get("dpi") + if dpi: + chunk( + fp, + b"pHYs", + o32(int(dpi[0] / 0.0254 + 0.5)), + o32(int(dpi[1] / 0.0254 + 0.5)), + b"\x01", + ) + + if info: + chunks = [b"bKGD", b"hIST"] + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid in chunks: + chunks.remove(cid) + chunk(fp, cid, data) + + exif = im.encoderinfo.get("exif") + if exif: + if isinstance(exif, Image.Exif): + exif = exif.tobytes(8) + if exif.startswith(b"Exif\x00\x00"): + exif = exif[6:] + chunk(fp, b"eXIf", exif) + + single_im: Image.Image | None = im + if save_all: + single_im = _write_multiple_frames( + im, fp, chunk, mode, rawmode, default_image, append_images + ) + if single_im: + ImageFile._save( + single_im, + cast(IO[bytes], _idat(fp, chunk)), + [ImageFile._Tile("zip", (0, 0) + single_im.size, 0, rawmode)], + ) + + if info: + for info_chunk in info.chunks: + cid, data = info_chunk[:2] + if cid[1:2].islower(): + # Private chunk + after_idat = len(info_chunk) == 3 and info_chunk[2] + if after_idat: + chunk(fp, cid, data) + + chunk(fp, b"IEND", b"") + + if hasattr(fp, "flush"): + fp.flush() + + +# -------------------------------------------------------------------- +# PNG chunk converter + + +def getchunks(im: Image.Image, **params: Any) -> list[tuple[bytes, bytes, bytes]]: + """Return a list of PNG chunks representing this image.""" + from io import BytesIO + + chunks = [] + + def append(fp: IO[bytes], cid: bytes, *data: bytes) -> None: + byte_data = b"".join(data) + crc = o32(_crc32(byte_data, _crc32(cid))) + chunks.append((cid, byte_data, crc)) + + fp = BytesIO() + + try: + im.encoderinfo = params + _save(im, fp, "", append) + finally: + del im.encoderinfo + + return chunks + + +# -------------------------------------------------------------------- +# Registry + +Image.register_open(PngImageFile.format, PngImageFile, _accept) +Image.register_save(PngImageFile.format, _save) +Image.register_save_all(PngImageFile.format, _save_all) + +Image.register_extensions(PngImageFile.format, [".png", ".apng"]) + +Image.register_mime(PngImageFile.format, "image/png") diff --git a/venv/lib/python3.12/site-packages/PIL/PpmImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PpmImagePlugin.py new file mode 100644 index 0000000..4e779df --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PpmImagePlugin.py @@ -0,0 +1,375 @@ +# +# The Python Imaging Library. +# $Id$ +# +# PPM support for PIL +# +# History: +# 96-03-24 fl Created +# 98-03-06 fl Write RGBA images (as RGB, that is) +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import math +from typing import IO + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import o8 +from ._binary import o32le as o32 + +# +# -------------------------------------------------------------------- + +b_whitespace = b"\x20\x09\x0a\x0b\x0c\x0d" + +MODES = { + # standard + b"P1": "1", + b"P2": "L", + b"P3": "RGB", + b"P4": "1", + b"P5": "L", + b"P6": "RGB", + # extensions + b"P0CMYK": "CMYK", + b"Pf": "F", + # PIL extensions (for test purposes only) + b"PyP": "P", + b"PyRGBA": "RGBA", + b"PyCMYK": "CMYK", +} + + +def _accept(prefix: bytes) -> bool: + return prefix[0:1] == b"P" and prefix[1] in b"0123456fy" + + +## +# Image plugin for PBM, PGM, and PPM images. + + +class PpmImageFile(ImageFile.ImageFile): + format = "PPM" + format_description = "Pbmplus image" + + def _read_magic(self) -> bytes: + assert self.fp is not None + + magic = b"" + # read until whitespace or longest available magic number + for _ in range(6): + c = self.fp.read(1) + if not c or c in b_whitespace: + break + magic += c + return magic + + def _read_token(self) -> bytes: + assert self.fp is not None + + token = b"" + while len(token) <= 10: # read until next whitespace or limit of 10 characters + c = self.fp.read(1) + if not c: + break + elif c in b_whitespace: # token ended + if not token: + # skip whitespace at start + continue + break + elif c == b"#": + # ignores rest of the line; stops at CR, LF or EOF + while self.fp.read(1) not in b"\r\n": + pass + continue + token += c + if not token: + # Token was not even 1 byte + msg = "Reached EOF while reading header" + raise ValueError(msg) + elif len(token) > 10: + msg = f"Token too long in file header: {token.decode()}" + raise ValueError(msg) + return token + + def _open(self) -> None: + assert self.fp is not None + + magic_number = self._read_magic() + try: + mode = MODES[magic_number] + except KeyError: + msg = "not a PPM file" + raise SyntaxError(msg) + self._mode = mode + + if magic_number in (b"P1", b"P4"): + self.custom_mimetype = "image/x-portable-bitmap" + elif magic_number in (b"P2", b"P5"): + self.custom_mimetype = "image/x-portable-graymap" + elif magic_number in (b"P3", b"P6"): + self.custom_mimetype = "image/x-portable-pixmap" + + self._size = int(self._read_token()), int(self._read_token()) + + decoder_name = "raw" + if magic_number in (b"P1", b"P2", b"P3"): + decoder_name = "ppm_plain" + + args: str | tuple[str | int, ...] + if mode == "1": + args = "1;I" + elif mode == "F": + scale = float(self._read_token()) + if scale == 0.0 or not math.isfinite(scale): + msg = "scale must be finite and non-zero" + raise ValueError(msg) + self.info["scale"] = abs(scale) + + rawmode = "F;32F" if scale < 0 else "F;32BF" + args = (rawmode, 0, -1) + else: + maxval = int(self._read_token()) + if not 0 < maxval < 65536: + msg = "maxval must be greater than 0 and less than 65536" + raise ValueError(msg) + if maxval > 255 and mode == "L": + self._mode = "I" + + rawmode = mode + if decoder_name != "ppm_plain": + # If maxval matches a bit depth, use the raw decoder directly + if maxval == 65535 and mode == "L": + rawmode = "I;16B" + elif maxval != 255: + decoder_name = "ppm" + + args = rawmode if decoder_name == "raw" else (rawmode, maxval) + self.tile = [ + ImageFile._Tile(decoder_name, (0, 0) + self.size, self.fp.tell(), args) + ] + + +# +# -------------------------------------------------------------------- + + +class PpmPlainDecoder(ImageFile.PyDecoder): + _pulls_fd = True + _comment_spans: bool + + def _read_block(self) -> bytes: + assert self.fd is not None + + return self.fd.read(ImageFile.SAFEBLOCK) + + def _find_comment_end(self, block: bytes, start: int = 0) -> int: + a = block.find(b"\n", start) + b = block.find(b"\r", start) + return min(a, b) if a * b > 0 else max(a, b) # lowest nonnegative index (or -1) + + def _ignore_comments(self, block: bytes) -> bytes: + if self._comment_spans: + # Finish current comment + while block: + comment_end = self._find_comment_end(block) + if comment_end != -1: + # Comment ends in this block + # Delete tail of comment + block = block[comment_end + 1 :] + break + else: + # Comment spans whole block + # So read the next block, looking for the end + block = self._read_block() + + # Search for any further comments + self._comment_spans = False + while True: + comment_start = block.find(b"#") + if comment_start == -1: + # No comment found + break + comment_end = self._find_comment_end(block, comment_start) + if comment_end != -1: + # Comment ends in this block + # Delete comment + block = block[:comment_start] + block[comment_end + 1 :] + else: + # Comment continues to next block(s) + block = block[:comment_start] + self._comment_spans = True + break + return block + + def _decode_bitonal(self) -> bytearray: + """ + This is a separate method because in the plain PBM format, all data tokens are + exactly one byte, so the inter-token whitespace is optional. + """ + data = bytearray() + total_bytes = self.state.xsize * self.state.ysize + + while len(data) != total_bytes: + block = self._read_block() # read next block + if not block: + # eof + break + + block = self._ignore_comments(block) + + tokens = b"".join(block.split()) + for token in tokens: + if token not in (48, 49): + msg = b"Invalid token for this mode: %s" % bytes([token]) + raise ValueError(msg) + data = (data + tokens)[:total_bytes] + invert = bytes.maketrans(b"01", b"\xFF\x00") + return data.translate(invert) + + def _decode_blocks(self, maxval: int) -> bytearray: + data = bytearray() + max_len = 10 + out_byte_count = 4 if self.mode == "I" else 1 + out_max = 65535 if self.mode == "I" else 255 + bands = Image.getmodebands(self.mode) + total_bytes = self.state.xsize * self.state.ysize * bands * out_byte_count + + half_token = b"" + while len(data) != total_bytes: + block = self._read_block() # read next block + if not block: + if half_token: + block = bytearray(b" ") # flush half_token + else: + # eof + break + + block = self._ignore_comments(block) + + if half_token: + block = half_token + block # stitch half_token to new block + half_token = b"" + + tokens = block.split() + + if block and not block[-1:].isspace(): # block might split token + half_token = tokens.pop() # save half token for later + if len(half_token) > max_len: # prevent buildup of half_token + msg = ( + b"Token too long found in data: %s" % half_token[: max_len + 1] + ) + raise ValueError(msg) + + for token in tokens: + if len(token) > max_len: + msg = b"Token too long found in data: %s" % token[: max_len + 1] + raise ValueError(msg) + value = int(token) + if value < 0: + msg_str = f"Channel value is negative: {value}" + raise ValueError(msg_str) + if value > maxval: + msg_str = f"Channel value too large for this mode: {value}" + raise ValueError(msg_str) + value = round(value / maxval * out_max) + data += o32(value) if self.mode == "I" else o8(value) + if len(data) == total_bytes: # finished! + break + return data + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + self._comment_spans = False + if self.mode == "1": + data = self._decode_bitonal() + rawmode = "1;8" + else: + maxval = self.args[-1] + data = self._decode_blocks(maxval) + rawmode = "I;32" if self.mode == "I" else self.mode + self.set_as_raw(bytes(data), rawmode) + return -1, 0 + + +class PpmDecoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + + data = bytearray() + maxval = self.args[-1] + in_byte_count = 1 if maxval < 256 else 2 + out_byte_count = 4 if self.mode == "I" else 1 + out_max = 65535 if self.mode == "I" else 255 + bands = Image.getmodebands(self.mode) + dest_length = self.state.xsize * self.state.ysize * bands * out_byte_count + while len(data) < dest_length: + pixels = self.fd.read(in_byte_count * bands) + if len(pixels) < in_byte_count * bands: + # eof + break + for b in range(bands): + value = ( + pixels[b] if in_byte_count == 1 else i16(pixels, b * in_byte_count) + ) + value = min(out_max, round(value / maxval * out_max)) + data += o32(value) if self.mode == "I" else o8(value) + rawmode = "I;32" if self.mode == "I" else self.mode + self.set_as_raw(bytes(data), rawmode) + return -1, 0 + + +# +# -------------------------------------------------------------------- + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode == "1": + rawmode, head = "1;I", b"P4" + elif im.mode == "L": + rawmode, head = "L", b"P5" + elif im.mode in ("I", "I;16"): + rawmode, head = "I;16B", b"P5" + elif im.mode in ("RGB", "RGBA"): + rawmode, head = "RGB", b"P6" + elif im.mode == "F": + rawmode, head = "F;32F", b"Pf" + else: + msg = f"cannot write mode {im.mode} as PPM" + raise OSError(msg) + fp.write(head + b"\n%d %d\n" % im.size) + if head == b"P6": + fp.write(b"255\n") + elif head == b"P5": + if rawmode == "L": + fp.write(b"255\n") + else: + fp.write(b"65535\n") + elif head == b"Pf": + fp.write(b"-1.0\n") + row_order = -1 if im.mode == "F" else 1 + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, row_order))] + ) + + +# +# -------------------------------------------------------------------- + + +Image.register_open(PpmImageFile.format, PpmImageFile, _accept) +Image.register_save(PpmImageFile.format, _save) + +Image.register_decoder("ppm", PpmDecoder) +Image.register_decoder("ppm_plain", PpmPlainDecoder) + +Image.register_extensions(PpmImageFile.format, [".pbm", ".pgm", ".ppm", ".pnm", ".pfm"]) + +Image.register_mime(PpmImageFile.format, "image/x-portable-anymap") diff --git a/venv/lib/python3.12/site-packages/PIL/PsdImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/PsdImagePlugin.py new file mode 100644 index 0000000..8ff5e39 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/PsdImagePlugin.py @@ -0,0 +1,332 @@ +# +# The Python Imaging Library +# $Id$ +# +# Adobe PSD 2.5/3.0 file handling +# +# History: +# 1995-09-01 fl Created +# 1997-01-03 fl Read most PSD images +# 1997-01-18 fl Fixed P and CMYK support +# 2001-10-21 fl Added seek/tell support (for layers) +# +# Copyright (c) 1997-2001 by Secret Labs AB. +# Copyright (c) 1995-2001 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +from functools import cached_property +from typing import IO + +from . import Image, ImageFile, ImagePalette +from ._binary import i8 +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import si16be as si16 +from ._binary import si32be as si32 + +MODES = { + # (photoshop mode, bits) -> (pil mode, required channels) + (0, 1): ("1", 1), + (0, 8): ("L", 1), + (1, 8): ("L", 1), + (2, 8): ("P", 1), + (3, 8): ("RGB", 3), + (4, 8): ("CMYK", 4), + (7, 8): ("L", 1), # FIXME: multilayer + (8, 8): ("L", 1), # duotone + (9, 8): ("LAB", 3), +} + + +# --------------------------------------------------------------------. +# read PSD images + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"8BPS" + + +## +# Image plugin for Photoshop images. + + +class PsdImageFile(ImageFile.ImageFile): + format = "PSD" + format_description = "Adobe Photoshop" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + read = self.fp.read + + # + # header + + s = read(26) + if not _accept(s) or i16(s, 4) != 1: + msg = "not a PSD file" + raise SyntaxError(msg) + + psd_bits = i16(s, 22) + psd_channels = i16(s, 12) + psd_mode = i16(s, 24) + + mode, channels = MODES[(psd_mode, psd_bits)] + + if channels > psd_channels: + msg = "not enough channels" + raise OSError(msg) + if mode == "RGB" and psd_channels == 4: + mode = "RGBA" + channels = 4 + + self._mode = mode + self._size = i32(s, 18), i32(s, 14) + + # + # color mode data + + size = i32(read(4)) + if size: + data = read(size) + if mode == "P" and size == 768: + self.palette = ImagePalette.raw("RGB;L", data) + + # + # image resources + + self.resources = [] + + size = i32(read(4)) + if size: + # load resources + end = self.fp.tell() + size + while self.fp.tell() < end: + read(4) # signature + id = i16(read(2)) + name = read(i8(read(1))) + if not (len(name) & 1): + read(1) # padding + data = read(i32(read(4))) + if len(data) & 1: + read(1) # padding + self.resources.append((id, name, data)) + if id == 1039: # ICC profile + self.info["icc_profile"] = data + + # + # layer and mask information + + self._layers_position = None + + size = i32(read(4)) + if size: + end = self.fp.tell() + size + size = i32(read(4)) + if size: + self._layers_position = self.fp.tell() + self._layers_size = size + self.fp.seek(end) + self._n_frames: int | None = None + + # + # image descriptor + + self.tile = _maketile(self.fp, mode, (0, 0) + self.size, channels) + + # keep the file open + self._fp = self.fp + self.frame = 1 + self._min_frame = 1 + + @cached_property + def layers( + self, + ) -> list[tuple[str, str, tuple[int, int, int, int], list[ImageFile._Tile]]]: + layers = [] + if self._layers_position is not None: + self._fp.seek(self._layers_position) + _layer_data = io.BytesIO(ImageFile._safe_read(self._fp, self._layers_size)) + layers = _layerinfo(_layer_data, self._layers_size) + self._n_frames = len(layers) + return layers + + @property + def n_frames(self) -> int: + if self._n_frames is None: + self._n_frames = len(self.layers) + return self._n_frames + + @property + def is_animated(self) -> bool: + return len(self.layers) > 1 + + def seek(self, layer: int) -> None: + if not self._seek_check(layer): + return + + # seek to given layer (1..max) + try: + _, mode, _, tile = self.layers[layer - 1] + self._mode = mode + self.tile = tile + self.frame = layer + self.fp = self._fp + except IndexError as e: + msg = "no such layer" + raise EOFError(msg) from e + + def tell(self) -> int: + # return layer number (0=image, 1..max=layers) + return self.frame + + +def _layerinfo( + fp: IO[bytes], ct_bytes: int +) -> list[tuple[str, str, tuple[int, int, int, int], list[ImageFile._Tile]]]: + # read layerinfo block + layers = [] + + def read(size: int) -> bytes: + return ImageFile._safe_read(fp, size) + + ct = si16(read(2)) + + # sanity check + if ct_bytes < (abs(ct) * 20): + msg = "Layer block too short for number of layers requested" + raise SyntaxError(msg) + + for _ in range(abs(ct)): + # bounding box + y0 = si32(read(4)) + x0 = si32(read(4)) + y1 = si32(read(4)) + x1 = si32(read(4)) + + # image info + bands = [] + ct_types = i16(read(2)) + if ct_types > 4: + fp.seek(ct_types * 6 + 12, io.SEEK_CUR) + size = i32(read(4)) + fp.seek(size, io.SEEK_CUR) + continue + + for _ in range(ct_types): + type = i16(read(2)) + + if type == 65535: + b = "A" + else: + b = "RGBA"[type] + + bands.append(b) + read(4) # size + + # figure out the image mode + bands.sort() + if bands == ["R"]: + mode = "L" + elif bands == ["B", "G", "R"]: + mode = "RGB" + elif bands == ["A", "B", "G", "R"]: + mode = "RGBA" + else: + mode = "" # unknown + + # skip over blend flags and extra information + read(12) # filler + name = "" + size = i32(read(4)) # length of the extra data field + if size: + data_end = fp.tell() + size + + length = i32(read(4)) + if length: + fp.seek(length - 16, io.SEEK_CUR) + + length = i32(read(4)) + if length: + fp.seek(length, io.SEEK_CUR) + + length = i8(read(1)) + if length: + # Don't know the proper encoding, + # Latin-1 should be a good guess + name = read(length).decode("latin-1", "replace") + + fp.seek(data_end) + layers.append((name, mode, (x0, y0, x1, y1))) + + # get tiles + layerinfo = [] + for i, (name, mode, bbox) in enumerate(layers): + tile = [] + for m in mode: + t = _maketile(fp, m, bbox, 1) + if t: + tile.extend(t) + layerinfo.append((name, mode, bbox, tile)) + + return layerinfo + + +def _maketile( + file: IO[bytes], mode: str, bbox: tuple[int, int, int, int], channels: int +) -> list[ImageFile._Tile]: + tiles = [] + read = file.read + + compression = i16(read(2)) + + xsize = bbox[2] - bbox[0] + ysize = bbox[3] - bbox[1] + + offset = file.tell() + + if compression == 0: + # + # raw compression + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer += ";I" + tiles.append(ImageFile._Tile("raw", bbox, offset, layer)) + offset = offset + xsize * ysize + + elif compression == 1: + # + # packbits compression + i = 0 + bytecount = read(channels * ysize * 2) + offset = file.tell() + for channel in range(channels): + layer = mode[channel] + if mode == "CMYK": + layer += ";I" + tiles.append(ImageFile._Tile("packbits", bbox, offset, layer)) + for y in range(ysize): + offset = offset + i16(bytecount, i) + i += 2 + + file.seek(offset) + + if offset & 1: + read(1) # padding + + return tiles + + +# -------------------------------------------------------------------- +# registry + + +Image.register_open(PsdImageFile.format, PsdImageFile, _accept) + +Image.register_extension(PsdImageFile.format, ".psd") + +Image.register_mime(PsdImageFile.format, "image/vnd.adobe.photoshop") diff --git a/venv/lib/python3.12/site-packages/PIL/QoiImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/QoiImagePlugin.py new file mode 100644 index 0000000..010d3f9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/QoiImagePlugin.py @@ -0,0 +1,115 @@ +# +# The Python Imaging Library. +# +# QOI support for PIL +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os + +from . import Image, ImageFile +from ._binary import i32be as i32 + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] == b"qoif" + + +class QoiImageFile(ImageFile.ImageFile): + format = "QOI" + format_description = "Quite OK Image" + + def _open(self) -> None: + if not _accept(self.fp.read(4)): + msg = "not a QOI file" + raise SyntaxError(msg) + + self._size = i32(self.fp.read(4)), i32(self.fp.read(4)) + + channels = self.fp.read(1)[0] + self._mode = "RGB" if channels == 3 else "RGBA" + + self.fp.seek(1, os.SEEK_CUR) # colorspace + self.tile = [ImageFile._Tile("qoi", (0, 0) + self._size, self.fp.tell(), None)] + + +class QoiDecoder(ImageFile.PyDecoder): + _pulls_fd = True + _previous_pixel: bytes | bytearray | None = None + _previously_seen_pixels: dict[int, bytes | bytearray] = {} + + def _add_to_previous_pixels(self, value: bytes | bytearray) -> None: + self._previous_pixel = value + + r, g, b, a = value + hash_value = (r * 3 + g * 5 + b * 7 + a * 11) % 64 + self._previously_seen_pixels[hash_value] = value + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + + self._previously_seen_pixels = {} + self._add_to_previous_pixels(bytearray((0, 0, 0, 255))) + + data = bytearray() + bands = Image.getmodebands(self.mode) + dest_length = self.state.xsize * self.state.ysize * bands + while len(data) < dest_length: + byte = self.fd.read(1)[0] + value: bytes | bytearray + if byte == 0b11111110 and self._previous_pixel: # QOI_OP_RGB + value = bytearray(self.fd.read(3)) + self._previous_pixel[3:] + elif byte == 0b11111111: # QOI_OP_RGBA + value = self.fd.read(4) + else: + op = byte >> 6 + if op == 0: # QOI_OP_INDEX + op_index = byte & 0b00111111 + value = self._previously_seen_pixels.get( + op_index, bytearray((0, 0, 0, 0)) + ) + elif op == 1 and self._previous_pixel: # QOI_OP_DIFF + value = bytearray( + ( + (self._previous_pixel[0] + ((byte & 0b00110000) >> 4) - 2) + % 256, + (self._previous_pixel[1] + ((byte & 0b00001100) >> 2) - 2) + % 256, + (self._previous_pixel[2] + (byte & 0b00000011) - 2) % 256, + self._previous_pixel[3], + ) + ) + elif op == 2 and self._previous_pixel: # QOI_OP_LUMA + second_byte = self.fd.read(1)[0] + diff_green = (byte & 0b00111111) - 32 + diff_red = ((second_byte & 0b11110000) >> 4) - 8 + diff_blue = (second_byte & 0b00001111) - 8 + + value = bytearray( + tuple( + (self._previous_pixel[i] + diff_green + diff) % 256 + for i, diff in enumerate((diff_red, 0, diff_blue)) + ) + ) + value += self._previous_pixel[3:] + elif op == 3 and self._previous_pixel: # QOI_OP_RUN + run_length = (byte & 0b00111111) + 1 + value = self._previous_pixel + if bands == 3: + value = value[:3] + data += value * run_length + continue + self._add_to_previous_pixels(value) + + if bands == 3: + value = value[:3] + data += value + self.set_as_raw(data) + return -1, 0 + + +Image.register_open(QoiImageFile.format, QoiImageFile, _accept) +Image.register_decoder("qoi", QoiDecoder) +Image.register_extension(QoiImageFile.format, ".qoi") diff --git a/venv/lib/python3.12/site-packages/PIL/SgiImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/SgiImagePlugin.py new file mode 100644 index 0000000..44254b7 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/SgiImagePlugin.py @@ -0,0 +1,247 @@ +# +# The Python Imaging Library. +# $Id$ +# +# SGI image file handling +# +# See "The SGI Image File Format (Draft version 0.97)", Paul Haeberli. +# +# +# +# History: +# 2017-22-07 mb Add RLE decompression +# 2016-16-10 mb Add save method without compression +# 1995-09-10 fl Created +# +# Copyright (c) 2016 by Mickael Bonfill. +# Copyright (c) 2008 by Karsten Hiddemann. +# Copyright (c) 1997 by Secret Labs AB. +# Copyright (c) 1995 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import os +import struct +from typing import IO + +from . import Image, ImageFile +from ._binary import i16be as i16 +from ._binary import o8 + + +def _accept(prefix: bytes) -> bool: + return len(prefix) >= 2 and i16(prefix) == 474 + + +MODES = { + (1, 1, 1): "L", + (1, 2, 1): "L", + (2, 1, 1): "L;16B", + (2, 2, 1): "L;16B", + (1, 3, 3): "RGB", + (2, 3, 3): "RGB;16B", + (1, 3, 4): "RGBA", + (2, 3, 4): "RGBA;16B", +} + + +## +# Image plugin for SGI images. +class SgiImageFile(ImageFile.ImageFile): + format = "SGI" + format_description = "SGI Image File Format" + + def _open(self) -> None: + # HEAD + assert self.fp is not None + + headlen = 512 + s = self.fp.read(headlen) + + if not _accept(s): + msg = "Not an SGI image file" + raise ValueError(msg) + + # compression : verbatim or RLE + compression = s[2] + + # bpc : 1 or 2 bytes (8bits or 16bits) + bpc = s[3] + + # dimension : 1, 2 or 3 (depending on xsize, ysize and zsize) + dimension = i16(s, 4) + + # xsize : width + xsize = i16(s, 6) + + # ysize : height + ysize = i16(s, 8) + + # zsize : channels count + zsize = i16(s, 10) + + # layout + layout = bpc, dimension, zsize + + # determine mode from bits/zsize + rawmode = "" + try: + rawmode = MODES[layout] + except KeyError: + pass + + if rawmode == "": + msg = "Unsupported SGI image mode" + raise ValueError(msg) + + self._size = xsize, ysize + self._mode = rawmode.split(";")[0] + if self.mode == "RGB": + self.custom_mimetype = "image/rgb" + + # orientation -1 : scanlines begins at the bottom-left corner + orientation = -1 + + # decoder info + if compression == 0: + pagesize = xsize * ysize * bpc + if bpc == 2: + self.tile = [ + ImageFile._Tile( + "SGI16", + (0, 0) + self.size, + headlen, + (self.mode, 0, orientation), + ) + ] + else: + self.tile = [] + offset = headlen + for layer in self.mode: + self.tile.append( + ImageFile._Tile( + "raw", (0, 0) + self.size, offset, (layer, 0, orientation) + ) + ) + offset += pagesize + elif compression == 1: + self.tile = [ + ImageFile._Tile( + "sgi_rle", (0, 0) + self.size, headlen, (rawmode, orientation, bpc) + ) + ] + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode not in {"RGB", "RGBA", "L"}: + msg = "Unsupported SGI image mode" + raise ValueError(msg) + + # Get the keyword arguments + info = im.encoderinfo + + # Byte-per-pixel precision, 1 = 8bits per pixel + bpc = info.get("bpc", 1) + + if bpc not in (1, 2): + msg = "Unsupported number of bytes per pixel" + raise ValueError(msg) + + # Flip the image, since the origin of SGI file is the bottom-left corner + orientation = -1 + # Define the file as SGI File Format + magic_number = 474 + # Run-Length Encoding Compression - Unsupported at this time + rle = 0 + + # Number of dimensions (x,y,z) + dim = 3 + # X Dimension = width / Y Dimension = height + x, y = im.size + if im.mode == "L" and y == 1: + dim = 1 + elif im.mode == "L": + dim = 2 + # Z Dimension: Number of channels + z = len(im.mode) + + if dim in {1, 2}: + z = 1 + + # assert we've got the right number of bands. + if len(im.getbands()) != z: + msg = f"incorrect number of bands in SGI write: {z} vs {len(im.getbands())}" + raise ValueError(msg) + + # Minimum Byte value + pinmin = 0 + # Maximum Byte value (255 = 8bits per pixel) + pinmax = 255 + # Image name (79 characters max, truncated below in write) + img_name = os.path.splitext(os.path.basename(filename))[0] + if isinstance(img_name, str): + img_name = img_name.encode("ascii", "ignore") + # Standard representation of pixel in the file + colormap = 0 + fp.write(struct.pack(">h", magic_number)) + fp.write(o8(rle)) + fp.write(o8(bpc)) + fp.write(struct.pack(">H", dim)) + fp.write(struct.pack(">H", x)) + fp.write(struct.pack(">H", y)) + fp.write(struct.pack(">H", z)) + fp.write(struct.pack(">l", pinmin)) + fp.write(struct.pack(">l", pinmax)) + fp.write(struct.pack("4s", b"")) # dummy + fp.write(struct.pack("79s", img_name)) # truncates to 79 chars + fp.write(struct.pack("s", b"")) # force null byte after img_name + fp.write(struct.pack(">l", colormap)) + fp.write(struct.pack("404s", b"")) # dummy + + rawmode = "L" + if bpc == 2: + rawmode = "L;16B" + + for channel in im.split(): + fp.write(channel.tobytes("raw", rawmode, 0, orientation)) + + if hasattr(fp, "flush"): + fp.flush() + + +class SGI16Decoder(ImageFile.PyDecoder): + _pulls_fd = True + + def decode(self, buffer: bytes | Image.SupportsArrayInterface) -> tuple[int, int]: + assert self.fd is not None + assert self.im is not None + + rawmode, stride, orientation = self.args + pagesize = self.state.xsize * self.state.ysize + zsize = len(self.mode) + self.fd.seek(512) + + for band in range(zsize): + channel = Image.new("L", (self.state.xsize, self.state.ysize)) + channel.frombytes( + self.fd.read(2 * pagesize), "raw", "L;16B", stride, orientation + ) + self.im.putband(channel.im, band) + + return -1, 0 + + +# +# registry + + +Image.register_decoder("SGI16", SGI16Decoder) +Image.register_open(SgiImageFile.format, SgiImageFile, _accept) +Image.register_save(SgiImageFile.format, _save) +Image.register_mime(SgiImageFile.format, "image/sgi") + +Image.register_extensions(SgiImageFile.format, [".bw", ".rgb", ".rgba", ".sgi"]) + +# End of file diff --git a/venv/lib/python3.12/site-packages/PIL/SpiderImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/SpiderImagePlugin.py new file mode 100644 index 0000000..075073f --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/SpiderImagePlugin.py @@ -0,0 +1,329 @@ +# +# The Python Imaging Library. +# +# SPIDER image file handling +# +# History: +# 2004-08-02 Created BB +# 2006-03-02 added save method +# 2006-03-13 added support for stack images +# +# Copyright (c) 2004 by Health Research Inc. (HRI) RENSSELAER, NY 12144. +# Copyright (c) 2004 by William Baxter. +# Copyright (c) 2004 by Secret Labs AB. +# Copyright (c) 2004 by Fredrik Lundh. +# + +## +# Image plugin for the Spider image format. This format is used +# by the SPIDER software, in processing image data from electron +# microscopy and tomography. +## + +# +# SpiderImagePlugin.py +# +# The Spider image format is used by SPIDER software, in processing +# image data from electron microscopy and tomography. +# +# Spider home page: +# https://spider.wadsworth.org/spider_doc/spider/docs/spider.html +# +# Details about the Spider image format: +# https://spider.wadsworth.org/spider_doc/spider/docs/image_doc.html +# +from __future__ import annotations + +import os +import struct +import sys +from typing import IO, TYPE_CHECKING, Any, cast + +from . import Image, ImageFile + + +def isInt(f: Any) -> int: + try: + i = int(f) + if f - i == 0: + return 1 + else: + return 0 + except (ValueError, OverflowError): + return 0 + + +iforms = [1, 3, -11, -12, -21, -22] + + +# There is no magic number to identify Spider files, so just check a +# series of header locations to see if they have reasonable values. +# Returns no. of bytes in the header, if it is a valid Spider header, +# otherwise returns 0 + + +def isSpiderHeader(t: tuple[float, ...]) -> int: + h = (99,) + t # add 1 value so can use spider header index start=1 + # header values 1,2,5,12,13,22,23 should be integers + for i in [1, 2, 5, 12, 13, 22, 23]: + if not isInt(h[i]): + return 0 + # check iform + iform = int(h[5]) + if iform not in iforms: + return 0 + # check other header values + labrec = int(h[13]) # no. records in file header + labbyt = int(h[22]) # total no. of bytes in header + lenbyt = int(h[23]) # record length in bytes + if labbyt != (labrec * lenbyt): + return 0 + # looks like a valid header + return labbyt + + +def isSpiderImage(filename: str) -> int: + with open(filename, "rb") as fp: + f = fp.read(92) # read 23 * 4 bytes + t = struct.unpack(">23f", f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + t = struct.unpack("<23f", f) # little-endian + hdrlen = isSpiderHeader(t) + return hdrlen + + +class SpiderImageFile(ImageFile.ImageFile): + format = "SPIDER" + format_description = "Spider 2D image" + _close_exclusive_fp_after_loading = False + + def _open(self) -> None: + # check header + n = 27 * 4 # read 27 float values + f = self.fp.read(n) + + try: + self.bigendian = 1 + t = struct.unpack(">27f", f) # try big-endian first + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + self.bigendian = 0 + t = struct.unpack("<27f", f) # little-endian + hdrlen = isSpiderHeader(t) + if hdrlen == 0: + msg = "not a valid Spider file" + raise SyntaxError(msg) + except struct.error as e: + msg = "not a valid Spider file" + raise SyntaxError(msg) from e + + h = (99,) + t # add 1 value : spider header index starts at 1 + iform = int(h[5]) + if iform != 1: + msg = "not a Spider 2D image" + raise SyntaxError(msg) + + self._size = int(h[12]), int(h[2]) # size in pixels (width, height) + self.istack = int(h[24]) + self.imgnumber = int(h[27]) + + if self.istack == 0 and self.imgnumber == 0: + # stk=0, img=0: a regular 2D image + offset = hdrlen + self._nimages = 1 + elif self.istack > 0 and self.imgnumber == 0: + # stk>0, img=0: Opening the stack for the first time + self.imgbytes = int(h[12]) * int(h[2]) * 4 + self.hdrlen = hdrlen + self._nimages = int(h[26]) + # Point to the first image in the stack + offset = hdrlen * 2 + self.imgnumber = 1 + elif self.istack == 0 and self.imgnumber > 0: + # stk=0, img>0: an image within the stack + offset = hdrlen + self.stkoffset + self.istack = 2 # So Image knows it's still a stack + else: + msg = "inconsistent stack header values" + raise SyntaxError(msg) + + if self.bigendian: + self.rawmode = "F;32BF" + else: + self.rawmode = "F;32F" + self._mode = "F" + + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offset, (self.rawmode, 0, 1)) + ] + self._fp = self.fp # FIXME: hack + + @property + def n_frames(self) -> int: + return self._nimages + + @property + def is_animated(self) -> bool: + return self._nimages > 1 + + # 1st image index is zero (although SPIDER imgnumber starts at 1) + def tell(self) -> int: + if self.imgnumber < 1: + return 0 + else: + return self.imgnumber - 1 + + def seek(self, frame: int) -> None: + if self.istack == 0: + msg = "attempt to seek in a non-stack file" + raise EOFError(msg) + if not self._seek_check(frame): + return + self.stkoffset = self.hdrlen + frame * (self.hdrlen + self.imgbytes) + self.fp = self._fp + self.fp.seek(self.stkoffset) + self._open() + + # returns a byte image after rescaling to 0..255 + def convert2byte(self, depth: int = 255) -> Image.Image: + extrema = self.getextrema() + assert isinstance(extrema[0], float) + minimum, maximum = cast(tuple[float, float], extrema) + m: float = 1 + if maximum != minimum: + m = depth / (maximum - minimum) + b = -m * minimum + return self.point(lambda i: i * m + b).convert("L") + + if TYPE_CHECKING: + from . import ImageTk + + # returns a ImageTk.PhotoImage object, after rescaling to 0..255 + def tkPhotoImage(self) -> ImageTk.PhotoImage: + from . import ImageTk + + return ImageTk.PhotoImage(self.convert2byte(), palette=256) + + +# -------------------------------------------------------------------- +# Image series + + +# given a list of filenames, return a list of images +def loadImageSeries(filelist: list[str] | None = None) -> list[SpiderImageFile] | None: + """create a list of :py:class:`~PIL.Image.Image` objects for use in a montage""" + if filelist is None or len(filelist) < 1: + return None + + imglist = [] + for img in filelist: + if not os.path.exists(img): + print(f"unable to find {img}") + continue + try: + with Image.open(img) as im: + im = im.convert2byte() + except Exception: + if not isSpiderImage(img): + print(f"{img} is not a Spider image file") + continue + im.info["filename"] = img + imglist.append(im) + return imglist + + +# -------------------------------------------------------------------- +# For saving images in Spider format + + +def makeSpiderHeader(im: Image.Image) -> list[bytes]: + nsam, nrow = im.size + lenbyt = nsam * 4 # There are labrec records in the header + labrec = int(1024 / lenbyt) + if 1024 % lenbyt != 0: + labrec += 1 + labbyt = labrec * lenbyt + nvalues = int(labbyt / 4) + if nvalues < 23: + return [] + + hdr = [0.0] * nvalues + + # NB these are Fortran indices + hdr[1] = 1.0 # nslice (=1 for an image) + hdr[2] = float(nrow) # number of rows per slice + hdr[3] = float(nrow) # number of records in the image + hdr[5] = 1.0 # iform for 2D image + hdr[12] = float(nsam) # number of pixels per line + hdr[13] = float(labrec) # number of records in file header + hdr[22] = float(labbyt) # total number of bytes in header + hdr[23] = float(lenbyt) # record length in bytes + + # adjust for Fortran indexing + hdr = hdr[1:] + hdr.append(0.0) + # pack binary data into a string + return [struct.pack("f", v) for v in hdr] + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode[0] != "F": + im = im.convert("F") + + hdr = makeSpiderHeader(im) + if len(hdr) < 256: + msg = "Error creating Spider header" + raise OSError(msg) + + # write the SPIDER header + fp.writelines(hdr) + + rawmode = "F;32NF" # 32-bit native floating point + ImageFile._save( + im, fp, [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, 1))] + ) + + +def _save_spider(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + # get the filename extension and register it with Image + filename_ext = os.path.splitext(filename)[1] + ext = filename_ext.decode() if isinstance(filename_ext, bytes) else filename_ext + Image.register_extension(SpiderImageFile.format, ext) + _save(im, fp, filename) + + +# -------------------------------------------------------------------- + + +Image.register_open(SpiderImageFile.format, SpiderImageFile) +Image.register_save(SpiderImageFile.format, _save_spider) + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("Syntax: python3 SpiderImagePlugin.py [infile] [outfile]") + sys.exit() + + filename = sys.argv[1] + if not isSpiderImage(filename): + print("input image must be in Spider format") + sys.exit() + + with Image.open(filename) as im: + print(f"image: {im}") + print(f"format: {im.format}") + print(f"size: {im.size}") + print(f"mode: {im.mode}") + print("max, min: ", end=" ") + print(im.getextrema()) + + if len(sys.argv) > 2: + outfile = sys.argv[2] + + # perform some image operation + im = im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + print( + f"saving a flipped version of {os.path.basename(filename)} " + f"as {outfile} " + ) + im.save(outfile, SpiderImageFile.format) diff --git a/venv/lib/python3.12/site-packages/PIL/SunImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/SunImagePlugin.py new file mode 100644 index 0000000..8912379 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/SunImagePlugin.py @@ -0,0 +1,145 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Sun image file handling +# +# History: +# 1995-09-10 fl Created +# 1996-05-28 fl Fixed 32-bit alignment +# 1998-12-29 fl Import ImagePalette module +# 2001-12-18 fl Fixed palette loading (from Jean-Claude Rimbault) +# +# Copyright (c) 1997-2001 by Secret Labs AB +# Copyright (c) 1995-1996 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +from . import Image, ImageFile, ImagePalette +from ._binary import i32be as i32 + + +def _accept(prefix: bytes) -> bool: + return len(prefix) >= 4 and i32(prefix) == 0x59A66A95 + + +## +# Image plugin for Sun raster files. + + +class SunImageFile(ImageFile.ImageFile): + format = "SUN" + format_description = "Sun Raster File" + + def _open(self) -> None: + # The Sun Raster file header is 32 bytes in length + # and has the following format: + + # typedef struct _SunRaster + # { + # DWORD MagicNumber; /* Magic (identification) number */ + # DWORD Width; /* Width of image in pixels */ + # DWORD Height; /* Height of image in pixels */ + # DWORD Depth; /* Number of bits per pixel */ + # DWORD Length; /* Size of image data in bytes */ + # DWORD Type; /* Type of raster file */ + # DWORD ColorMapType; /* Type of color map */ + # DWORD ColorMapLength; /* Size of the color map in bytes */ + # } SUNRASTER; + + assert self.fp is not None + + # HEAD + s = self.fp.read(32) + if not _accept(s): + msg = "not an SUN raster file" + raise SyntaxError(msg) + + offset = 32 + + self._size = i32(s, 4), i32(s, 8) + + depth = i32(s, 12) + # data_length = i32(s, 16) # unreliable, ignore. + file_type = i32(s, 20) + palette_type = i32(s, 24) # 0: None, 1: RGB, 2: Raw/arbitrary + palette_length = i32(s, 28) + + if depth == 1: + self._mode, rawmode = "1", "1;I" + elif depth == 4: + self._mode, rawmode = "L", "L;4" + elif depth == 8: + self._mode = rawmode = "L" + elif depth == 24: + if file_type == 3: + self._mode, rawmode = "RGB", "RGB" + else: + self._mode, rawmode = "RGB", "BGR" + elif depth == 32: + if file_type == 3: + self._mode, rawmode = "RGB", "RGBX" + else: + self._mode, rawmode = "RGB", "BGRX" + else: + msg = "Unsupported Mode/Bit Depth" + raise SyntaxError(msg) + + if palette_length: + if palette_length > 1024: + msg = "Unsupported Color Palette Length" + raise SyntaxError(msg) + + if palette_type != 1: + msg = "Unsupported Palette Type" + raise SyntaxError(msg) + + offset = offset + palette_length + self.palette = ImagePalette.raw("RGB;L", self.fp.read(palette_length)) + if self.mode == "L": + self._mode = "P" + rawmode = rawmode.replace("L", "P") + + # 16 bit boundaries on stride + stride = ((self.size[0] * depth + 15) // 16) * 2 + + # file type: Type is the version (or flavor) of the bitmap + # file. The following values are typically found in the Type + # field: + # 0000h Old + # 0001h Standard + # 0002h Byte-encoded + # 0003h RGB format + # 0004h TIFF format + # 0005h IFF format + # FFFFh Experimental + + # Old and standard are the same, except for the length tag. + # byte-encoded is run-length-encoded + # RGB looks similar to standard, but RGB byte order + # TIFF and IFF mean that they were converted from T/IFF + # Experimental means that it's something else. + # (https://www.fileformat.info/format/sunraster/egff.htm) + + if file_type in (0, 1, 3, 4, 5): + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, offset, (rawmode, stride)) + ] + elif file_type == 2: + self.tile = [ + ImageFile._Tile("sun_rle", (0, 0) + self.size, offset, rawmode) + ] + else: + msg = "Unsupported Sun Raster file type" + raise SyntaxError(msg) + + +# +# registry + + +Image.register_open(SunImageFile.format, SunImageFile, _accept) + +Image.register_extension(SunImageFile.format, ".ras") diff --git a/venv/lib/python3.12/site-packages/PIL/TarIO.py b/venv/lib/python3.12/site-packages/PIL/TarIO.py new file mode 100644 index 0000000..779288b --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/TarIO.py @@ -0,0 +1,57 @@ +# +# The Python Imaging Library. +# $Id$ +# +# read files from within a tar file +# +# History: +# 95-06-18 fl Created +# 96-05-28 fl Open files in binary mode +# +# Copyright (c) Secret Labs AB 1997. +# Copyright (c) Fredrik Lundh 1995-96. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io + +from . import ContainerIO + + +class TarIO(ContainerIO.ContainerIO[bytes]): + """A file object that provides read access to a given member of a TAR file.""" + + def __init__(self, tarfile: str, file: str) -> None: + """ + Create file object. + + :param tarfile: Name of TAR file. + :param file: Name of member file. + """ + self.fh = open(tarfile, "rb") + + while True: + s = self.fh.read(512) + if len(s) != 512: + msg = "unexpected end of tar file" + raise OSError(msg) + + name = s[:100].decode("utf-8") + i = name.find("\0") + if i == 0: + msg = "cannot find subfile" + raise OSError(msg) + if i > 0: + name = name[:i] + + size = int(s[124:135], 8) + + if file == name: + break + + self.fh.seek((size + 511) & (~511), io.SEEK_CUR) + + # Open region + super().__init__(self.fh, self.fh.tell(), size) diff --git a/venv/lib/python3.12/site-packages/PIL/TgaImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/TgaImagePlugin.py new file mode 100644 index 0000000..90d5b5c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/TgaImagePlugin.py @@ -0,0 +1,264 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TGA file handling +# +# History: +# 95-09-01 fl created (reads 24-bit files only) +# 97-01-04 fl support more TGA versions, including compressed images +# 98-07-04 fl fixed orientation and alpha layer bugs +# 98-09-11 fl fixed orientation for runlength decoder +# +# Copyright (c) Secret Labs AB 1997-98. +# Copyright (c) Fredrik Lundh 1995-97. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import warnings +from typing import IO + +from . import Image, ImageFile, ImagePalette +from ._binary import i16le as i16 +from ._binary import o8 +from ._binary import o16le as o16 + +# +# -------------------------------------------------------------------- +# Read RGA file + + +MODES = { + # map imagetype/depth to rawmode + (1, 8): "P", + (3, 1): "1", + (3, 8): "L", + (3, 16): "LA", + (2, 16): "BGRA;15Z", + (2, 24): "BGR", + (2, 32): "BGRA", +} + + +## +# Image plugin for Targa files. + + +class TgaImageFile(ImageFile.ImageFile): + format = "TGA" + format_description = "Targa" + + def _open(self) -> None: + # process header + assert self.fp is not None + + s = self.fp.read(18) + + id_len = s[0] + + colormaptype = s[1] + imagetype = s[2] + + depth = s[16] + + flags = s[17] + + self._size = i16(s, 12), i16(s, 14) + + # validate header fields + if ( + colormaptype not in (0, 1) + or self.size[0] <= 0 + or self.size[1] <= 0 + or depth not in (1, 8, 16, 24, 32) + ): + msg = "not a TGA file" + raise SyntaxError(msg) + + # image mode + if imagetype in (3, 11): + self._mode = "L" + if depth == 1: + self._mode = "1" # ??? + elif depth == 16: + self._mode = "LA" + elif imagetype in (1, 9): + self._mode = "P" if colormaptype else "L" + elif imagetype in (2, 10): + self._mode = "RGB" if depth == 24 else "RGBA" + else: + msg = "unknown TGA mode" + raise SyntaxError(msg) + + # orientation + orientation = flags & 0x30 + self._flip_horizontally = orientation in [0x10, 0x30] + if orientation in [0x20, 0x30]: + orientation = 1 + elif orientation in [0, 0x10]: + orientation = -1 + else: + msg = "unknown TGA orientation" + raise SyntaxError(msg) + + self.info["orientation"] = orientation + + if imagetype & 8: + self.info["compression"] = "tga_rle" + + if id_len: + self.info["id_section"] = self.fp.read(id_len) + + if colormaptype: + # read palette + start, size, mapdepth = i16(s, 3), i16(s, 5), s[7] + if mapdepth == 16: + self.palette = ImagePalette.raw( + "BGRA;15Z", bytes(2 * start) + self.fp.read(2 * size) + ) + self.palette.mode = "RGBA" + elif mapdepth == 24: + self.palette = ImagePalette.raw( + "BGR", bytes(3 * start) + self.fp.read(3 * size) + ) + elif mapdepth == 32: + self.palette = ImagePalette.raw( + "BGRA", bytes(4 * start) + self.fp.read(4 * size) + ) + else: + msg = "unknown TGA map depth" + raise SyntaxError(msg) + + # setup tile descriptor + try: + rawmode = MODES[(imagetype & 7, depth)] + if imagetype & 8: + # compressed + self.tile = [ + ImageFile._Tile( + "tga_rle", + (0, 0) + self.size, + self.fp.tell(), + (rawmode, orientation, depth), + ) + ] + else: + self.tile = [ + ImageFile._Tile( + "raw", + (0, 0) + self.size, + self.fp.tell(), + (rawmode, 0, orientation), + ) + ] + except KeyError: + pass # cannot decode + + def load_end(self) -> None: + if self._flip_horizontally: + self.im = self.im.transpose(Image.Transpose.FLIP_LEFT_RIGHT) + + +# +# -------------------------------------------------------------------- +# Write TGA file + + +SAVE = { + "1": ("1", 1, 0, 3), + "L": ("L", 8, 0, 3), + "LA": ("LA", 16, 0, 3), + "P": ("P", 8, 1, 1), + "RGB": ("BGR", 24, 0, 2), + "RGBA": ("BGRA", 32, 0, 2), +} + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + try: + rawmode, bits, colormaptype, imagetype = SAVE[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as TGA" + raise OSError(msg) from e + + if "rle" in im.encoderinfo: + rle = im.encoderinfo["rle"] + else: + compression = im.encoderinfo.get("compression", im.info.get("compression")) + rle = compression == "tga_rle" + if rle: + imagetype += 8 + + id_section = im.encoderinfo.get("id_section", im.info.get("id_section", "")) + id_len = len(id_section) + if id_len > 255: + id_len = 255 + id_section = id_section[:255] + warnings.warn("id_section has been trimmed to 255 characters") + + if colormaptype: + palette = im.im.getpalette("RGB", "BGR") + colormaplength, colormapentry = len(palette) // 3, 24 + else: + colormaplength, colormapentry = 0, 0 + + if im.mode in ("LA", "RGBA"): + flags = 8 + else: + flags = 0 + + orientation = im.encoderinfo.get("orientation", im.info.get("orientation", -1)) + if orientation > 0: + flags = flags | 0x20 + + fp.write( + o8(id_len) + + o8(colormaptype) + + o8(imagetype) + + o16(0) # colormapfirst + + o16(colormaplength) + + o8(colormapentry) + + o16(0) + + o16(0) + + o16(im.size[0]) + + o16(im.size[1]) + + o8(bits) + + o8(flags) + ) + + if id_section: + fp.write(id_section) + + if colormaptype: + fp.write(palette) + + if rle: + ImageFile._save( + im, + fp, + [ImageFile._Tile("tga_rle", (0, 0) + im.size, 0, (rawmode, orientation))], + ) + else: + ImageFile._save( + im, + fp, + [ImageFile._Tile("raw", (0, 0) + im.size, 0, (rawmode, 0, orientation))], + ) + + # write targa version 2 footer + fp.write(b"\000" * 8 + b"TRUEVISION-XFILE." + b"\000") + + +# +# -------------------------------------------------------------------- +# Registry + + +Image.register_open(TgaImageFile.format, TgaImageFile) +Image.register_save(TgaImageFile.format, _save) + +Image.register_extensions(TgaImageFile.format, [".tga", ".icb", ".vda", ".vst"]) + +Image.register_mime(TgaImageFile.format, "image/x-tga") diff --git a/venv/lib/python3.12/site-packages/PIL/TiffImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/TiffImagePlugin.py new file mode 100644 index 0000000..ff5a6f9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/TiffImagePlugin.py @@ -0,0 +1,2271 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF file handling +# +# TIFF is a flexible, if somewhat aged, image file format originally +# defined by Aldus. Although TIFF supports a wide variety of pixel +# layouts and compression methods, the name doesn't really stand for +# "thousands of incompatible file formats," it just feels that way. +# +# To read TIFF data from a stream, the stream must be seekable. For +# progressive decoding, make sure to use TIFF files where the tag +# directory is placed first in the file. +# +# History: +# 1995-09-01 fl Created +# 1996-05-04 fl Handle JPEGTABLES tag +# 1996-05-18 fl Fixed COLORMAP support +# 1997-01-05 fl Fixed PREDICTOR support +# 1997-08-27 fl Added support for rational tags (from Perry Stoll) +# 1998-01-10 fl Fixed seek/tell (from Jan Blom) +# 1998-07-15 fl Use private names for internal variables +# 1999-06-13 fl Rewritten for PIL 1.0 (1.0) +# 2000-10-11 fl Additional fixes for Python 2.0 (1.1) +# 2001-04-17 fl Fixed rewind support (seek to frame 0) (1.2) +# 2001-05-12 fl Added write support for more tags (from Greg Couch) (1.3) +# 2001-12-18 fl Added workaround for broken Matrox library +# 2002-01-18 fl Don't mess up if photometric tag is missing (D. Alan Stewart) +# 2003-05-19 fl Check FILLORDER tag +# 2003-09-26 fl Added RGBa support +# 2004-02-24 fl Added DPI support; fixed rational write support +# 2005-02-07 fl Added workaround for broken Corel Draw 10 files +# 2006-01-09 fl Added support for float/double tags (from Russell Nelson) +# +# Copyright (c) 1997-2006 by Secret Labs AB. All rights reserved. +# Copyright (c) 1995-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import io +import itertools +import logging +import math +import os +import struct +import warnings +from collections.abc import Iterator, MutableMapping +from fractions import Fraction +from numbers import Number, Rational +from typing import IO, TYPE_CHECKING, Any, Callable, NoReturn, cast + +from . import ExifTags, Image, ImageFile, ImageOps, ImagePalette, TiffTags +from ._binary import i16be as i16 +from ._binary import i32be as i32 +from ._binary import o8 +from ._deprecate import deprecate +from ._typing import StrOrBytesPath +from ._util import is_path +from .TiffTags import TYPES + +if TYPE_CHECKING: + from ._typing import Buffer, IntegralLike + +logger = logging.getLogger(__name__) + +# Set these to true to force use of libtiff for reading or writing. +READ_LIBTIFF = False +WRITE_LIBTIFF = False +STRIP_SIZE = 65536 + +II = b"II" # little-endian (Intel style) +MM = b"MM" # big-endian (Motorola style) + +# +# -------------------------------------------------------------------- +# Read TIFF files + +# a few tag names, just to make the code below a bit more readable +OSUBFILETYPE = 255 +IMAGEWIDTH = 256 +IMAGELENGTH = 257 +BITSPERSAMPLE = 258 +COMPRESSION = 259 +PHOTOMETRIC_INTERPRETATION = 262 +FILLORDER = 266 +IMAGEDESCRIPTION = 270 +STRIPOFFSETS = 273 +SAMPLESPERPIXEL = 277 +ROWSPERSTRIP = 278 +STRIPBYTECOUNTS = 279 +X_RESOLUTION = 282 +Y_RESOLUTION = 283 +PLANAR_CONFIGURATION = 284 +RESOLUTION_UNIT = 296 +TRANSFERFUNCTION = 301 +SOFTWARE = 305 +DATE_TIME = 306 +ARTIST = 315 +PREDICTOR = 317 +COLORMAP = 320 +TILEWIDTH = 322 +TILELENGTH = 323 +TILEOFFSETS = 324 +TILEBYTECOUNTS = 325 +SUBIFD = 330 +EXTRASAMPLES = 338 +SAMPLEFORMAT = 339 +JPEGTABLES = 347 +YCBCRSUBSAMPLING = 530 +REFERENCEBLACKWHITE = 532 +COPYRIGHT = 33432 +IPTC_NAA_CHUNK = 33723 # newsphoto properties +PHOTOSHOP_CHUNK = 34377 # photoshop properties +ICCPROFILE = 34675 +EXIFIFD = 34665 +XMP = 700 +JPEGQUALITY = 65537 # pseudo-tag by libtiff + +# https://github.com/imagej/ImageJA/blob/master/src/main/java/ij/io/TiffDecoder.java +IMAGEJ_META_DATA_BYTE_COUNTS = 50838 +IMAGEJ_META_DATA = 50839 + +COMPRESSION_INFO = { + # Compression => pil compression name + 1: "raw", + 2: "tiff_ccitt", + 3: "group3", + 4: "group4", + 5: "tiff_lzw", + 6: "tiff_jpeg", # obsolete + 7: "jpeg", + 8: "tiff_adobe_deflate", + 32771: "tiff_raw_16", # 16-bit padding + 32773: "packbits", + 32809: "tiff_thunderscan", + 32946: "tiff_deflate", + 34676: "tiff_sgilog", + 34677: "tiff_sgilog24", + 34925: "lzma", + 50000: "zstd", + 50001: "webp", +} + +COMPRESSION_INFO_REV = {v: k for k, v in COMPRESSION_INFO.items()} + +OPEN_INFO = { + # (ByteOrder, PhotoInterpretation, SampleFormat, FillOrder, BitsPerSample, + # ExtraSamples) => mode, rawmode + (II, 0, (1,), 1, (1,), ()): ("1", "1;I"), + (MM, 0, (1,), 1, (1,), ()): ("1", "1;I"), + (II, 0, (1,), 2, (1,), ()): ("1", "1;IR"), + (MM, 0, (1,), 2, (1,), ()): ("1", "1;IR"), + (II, 1, (1,), 1, (1,), ()): ("1", "1"), + (MM, 1, (1,), 1, (1,), ()): ("1", "1"), + (II, 1, (1,), 2, (1,), ()): ("1", "1;R"), + (MM, 1, (1,), 2, (1,), ()): ("1", "1;R"), + (II, 0, (1,), 1, (2,), ()): ("L", "L;2I"), + (MM, 0, (1,), 1, (2,), ()): ("L", "L;2I"), + (II, 0, (1,), 2, (2,), ()): ("L", "L;2IR"), + (MM, 0, (1,), 2, (2,), ()): ("L", "L;2IR"), + (II, 1, (1,), 1, (2,), ()): ("L", "L;2"), + (MM, 1, (1,), 1, (2,), ()): ("L", "L;2"), + (II, 1, (1,), 2, (2,), ()): ("L", "L;2R"), + (MM, 1, (1,), 2, (2,), ()): ("L", "L;2R"), + (II, 0, (1,), 1, (4,), ()): ("L", "L;4I"), + (MM, 0, (1,), 1, (4,), ()): ("L", "L;4I"), + (II, 0, (1,), 2, (4,), ()): ("L", "L;4IR"), + (MM, 0, (1,), 2, (4,), ()): ("L", "L;4IR"), + (II, 1, (1,), 1, (4,), ()): ("L", "L;4"), + (MM, 1, (1,), 1, (4,), ()): ("L", "L;4"), + (II, 1, (1,), 2, (4,), ()): ("L", "L;4R"), + (MM, 1, (1,), 2, (4,), ()): ("L", "L;4R"), + (II, 0, (1,), 1, (8,), ()): ("L", "L;I"), + (MM, 0, (1,), 1, (8,), ()): ("L", "L;I"), + (II, 0, (1,), 2, (8,), ()): ("L", "L;IR"), + (MM, 0, (1,), 2, (8,), ()): ("L", "L;IR"), + (II, 1, (1,), 1, (8,), ()): ("L", "L"), + (MM, 1, (1,), 1, (8,), ()): ("L", "L"), + (II, 1, (2,), 1, (8,), ()): ("L", "L"), + (MM, 1, (2,), 1, (8,), ()): ("L", "L"), + (II, 1, (1,), 2, (8,), ()): ("L", "L;R"), + (MM, 1, (1,), 2, (8,), ()): ("L", "L;R"), + (II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"), + (II, 0, (1,), 1, (16,), ()): ("I;16", "I;16"), + (II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"), + (MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"), + (II, 1, (1,), 2, (16,), ()): ("I;16", "I;16R"), + (II, 1, (2,), 1, (16,), ()): ("I", "I;16S"), + (MM, 1, (2,), 1, (16,), ()): ("I", "I;16BS"), + (II, 0, (3,), 1, (32,), ()): ("F", "F;32F"), + (MM, 0, (3,), 1, (32,), ()): ("F", "F;32BF"), + (II, 1, (1,), 1, (32,), ()): ("I", "I;32N"), + (II, 1, (2,), 1, (32,), ()): ("I", "I;32S"), + (MM, 1, (2,), 1, (32,), ()): ("I", "I;32BS"), + (II, 1, (3,), 1, (32,), ()): ("F", "F;32F"), + (MM, 1, (3,), 1, (32,), ()): ("F", "F;32BF"), + (II, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"), + (MM, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"), + (II, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"), + (MM, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"), + (II, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"), + (MM, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"), + (II, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples + (MM, 2, (1,), 1, (8, 8, 8, 8), ()): ("RGBA", "RGBA"), # missing ExtraSamples + (II, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGB", "RGBX"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (0,)): ("RGB", "RGBX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGB", "RGBXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (0, 0)): ("RGB", "RGBXX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGB", "RGBXXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0, 0)): ("RGB", "RGBXXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (1,)): ("RGBA", "RGBa"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (1, 0)): ("RGBA", "RGBaX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (1, 0, 0)): ("RGBA", "RGBaXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), + (MM, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8), (2, 0)): ("RGBA", "RGBAX"), + (II, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"), + (MM, 2, (1,), 1, (8, 8, 8, 8, 8, 8), (2, 0, 0)): ("RGBA", "RGBAXX"), + (II, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (MM, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10 + (II, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16L"), + (MM, 2, (1,), 1, (16, 16, 16), ()): ("RGB", "RGB;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), ()): ("RGBA", "RGBA;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGB", "RGBX;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (0,)): ("RGB", "RGBX;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (1,)): ("RGBA", "RGBa;16B"), + (II, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16L"), + (MM, 2, (1,), 1, (16, 16, 16, 16), (2,)): ("RGBA", "RGBA;16B"), + (II, 3, (1,), 1, (1,), ()): ("P", "P;1"), + (MM, 3, (1,), 1, (1,), ()): ("P", "P;1"), + (II, 3, (1,), 2, (1,), ()): ("P", "P;1R"), + (MM, 3, (1,), 2, (1,), ()): ("P", "P;1R"), + (II, 3, (1,), 1, (2,), ()): ("P", "P;2"), + (MM, 3, (1,), 1, (2,), ()): ("P", "P;2"), + (II, 3, (1,), 2, (2,), ()): ("P", "P;2R"), + (MM, 3, (1,), 2, (2,), ()): ("P", "P;2R"), + (II, 3, (1,), 1, (4,), ()): ("P", "P;4"), + (MM, 3, (1,), 1, (4,), ()): ("P", "P;4"), + (II, 3, (1,), 2, (4,), ()): ("P", "P;4R"), + (MM, 3, (1,), 2, (4,), ()): ("P", "P;4R"), + (II, 3, (1,), 1, (8,), ()): ("P", "P"), + (MM, 3, (1,), 1, (8,), ()): ("P", "P"), + (II, 3, (1,), 1, (8, 8), (0,)): ("P", "PX"), + (II, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"), + (MM, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"), + (II, 3, (1,), 2, (8,), ()): ("P", "P;R"), + (MM, 3, (1,), 2, (8,), ()): ("P", "P;R"), + (II, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), + (MM, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"), + (II, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"), + (MM, 5, (1,), 1, (8, 8, 8, 8, 8), (0,)): ("CMYK", "CMYKX"), + (II, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"), + (MM, 5, (1,), 1, (8, 8, 8, 8, 8, 8), (0, 0)): ("CMYK", "CMYKXX"), + (II, 5, (1,), 1, (16, 16, 16, 16), ()): ("CMYK", "CMYK;16L"), + (MM, 5, (1,), 1, (16, 16, 16, 16), ()): ("CMYK", "CMYK;16B"), + (II, 6, (1,), 1, (8,), ()): ("L", "L"), + (MM, 6, (1,), 1, (8,), ()): ("L", "L"), + # JPEG compressed images handled by LibTiff and auto-converted to RGBX + # Minimal Baseline TIFF requires YCbCr images to have 3 SamplesPerPixel + (II, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"), + (MM, 6, (1,), 1, (8, 8, 8), ()): ("RGB", "RGBX"), + (II, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"), + (MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"), +} + +MAX_SAMPLESPERPIXEL = max(len(key_tp[4]) for key_tp in OPEN_INFO) + +PREFIXES = [ + b"MM\x00\x2A", # Valid TIFF header with big-endian byte order + b"II\x2A\x00", # Valid TIFF header with little-endian byte order + b"MM\x2A\x00", # Invalid TIFF header, assume big-endian + b"II\x00\x2A", # Invalid TIFF header, assume little-endian + b"MM\x00\x2B", # BigTIFF with big-endian byte order + b"II\x2B\x00", # BigTIFF with little-endian byte order +] + +if not getattr(Image.core, "libtiff_support_custom_tags", True): + deprecate("Support for LibTIFF earlier than version 4", 12) + + +def _accept(prefix: bytes) -> bool: + return prefix[:4] in PREFIXES + + +def _limit_rational( + val: float | Fraction | IFDRational, max_val: int +) -> tuple[IntegralLike, IntegralLike]: + inv = abs(float(val)) > 1 + n_d = IFDRational(1 / val if inv else val).limit_rational(max_val) + return n_d[::-1] if inv else n_d + + +def _limit_signed_rational( + val: IFDRational, max_val: int, min_val: int +) -> tuple[IntegralLike, IntegralLike]: + frac = Fraction(val) + n_d: tuple[IntegralLike, IntegralLike] = frac.numerator, frac.denominator + + if min(float(i) for i in n_d) < min_val: + n_d = _limit_rational(val, abs(min_val)) + + n_d_float = tuple(float(i) for i in n_d) + if max(n_d_float) > max_val: + n_d = _limit_rational(n_d_float[0] / n_d_float[1], max_val) + + return n_d + + +## +# Wrapper for TIFF IFDs. + +_load_dispatch = {} +_write_dispatch = {} + + +def _delegate(op: str) -> Any: + def delegate( + self: IFDRational, *args: tuple[float, ...] + ) -> bool | float | Fraction: + return getattr(self._val, op)(*args) + + return delegate + + +class IFDRational(Rational): + """Implements a rational class where 0/0 is a legal value to match + the in the wild use of exif rationals. + + e.g., DigitalZoomRatio - 0.00/0.00 indicates that no digital zoom was used + """ + + """ If the denominator is 0, store this as a float('nan'), otherwise store + as a fractions.Fraction(). Delegate as appropriate + + """ + + __slots__ = ("_numerator", "_denominator", "_val") + + def __init__( + self, value: float | Fraction | IFDRational, denominator: int = 1 + ) -> None: + """ + :param value: either an integer numerator, a + float/rational/other number, or an IFDRational + :param denominator: Optional integer denominator + """ + self._val: Fraction | float + if isinstance(value, IFDRational): + self._numerator = value.numerator + self._denominator = value.denominator + self._val = value._val + return + + if isinstance(value, Fraction): + self._numerator = value.numerator + self._denominator = value.denominator + else: + if TYPE_CHECKING: + self._numerator = cast(IntegralLike, value) + else: + self._numerator = value + self._denominator = denominator + + if denominator == 0: + self._val = float("nan") + elif denominator == 1: + self._val = Fraction(value) + elif int(value) == value: + self._val = Fraction(int(value), denominator) + else: + self._val = Fraction(value / denominator) + + @property + def numerator(self) -> IntegralLike: + return self._numerator + + @property + def denominator(self) -> int: + return self._denominator + + def limit_rational(self, max_denominator: int) -> tuple[IntegralLike, int]: + """ + + :param max_denominator: Integer, the maximum denominator value + :returns: Tuple of (numerator, denominator) + """ + + if self.denominator == 0: + return self.numerator, self.denominator + + assert isinstance(self._val, Fraction) + f = self._val.limit_denominator(max_denominator) + return f.numerator, f.denominator + + def __repr__(self) -> str: + return str(float(self._val)) + + def __hash__(self) -> int: + return self._val.__hash__() + + def __eq__(self, other: object) -> bool: + val = self._val + if isinstance(other, IFDRational): + other = other._val + if isinstance(other, float): + val = float(val) + return val == other + + def __getstate__(self) -> list[float | Fraction | IntegralLike]: + return [self._val, self._numerator, self._denominator] + + def __setstate__(self, state: list[float | Fraction | IntegralLike]) -> None: + IFDRational.__init__(self, 0) + _val, _numerator, _denominator = state + assert isinstance(_val, (float, Fraction)) + self._val = _val + if TYPE_CHECKING: + self._numerator = cast(IntegralLike, _numerator) + else: + self._numerator = _numerator + assert isinstance(_denominator, int) + self._denominator = _denominator + + """ a = ['add','radd', 'sub', 'rsub', 'mul', 'rmul', + 'truediv', 'rtruediv', 'floordiv', 'rfloordiv', + 'mod','rmod', 'pow','rpow', 'pos', 'neg', + 'abs', 'trunc', 'lt', 'gt', 'le', 'ge', 'bool', + 'ceil', 'floor', 'round'] + print("\n".join("__%s__ = _delegate('__%s__')" % (s,s) for s in a)) + """ + + __add__ = _delegate("__add__") + __radd__ = _delegate("__radd__") + __sub__ = _delegate("__sub__") + __rsub__ = _delegate("__rsub__") + __mul__ = _delegate("__mul__") + __rmul__ = _delegate("__rmul__") + __truediv__ = _delegate("__truediv__") + __rtruediv__ = _delegate("__rtruediv__") + __floordiv__ = _delegate("__floordiv__") + __rfloordiv__ = _delegate("__rfloordiv__") + __mod__ = _delegate("__mod__") + __rmod__ = _delegate("__rmod__") + __pow__ = _delegate("__pow__") + __rpow__ = _delegate("__rpow__") + __pos__ = _delegate("__pos__") + __neg__ = _delegate("__neg__") + __abs__ = _delegate("__abs__") + __trunc__ = _delegate("__trunc__") + __lt__ = _delegate("__lt__") + __gt__ = _delegate("__gt__") + __le__ = _delegate("__le__") + __ge__ = _delegate("__ge__") + __bool__ = _delegate("__bool__") + __ceil__ = _delegate("__ceil__") + __floor__ = _delegate("__floor__") + __round__ = _delegate("__round__") + # Python >= 3.11 + if hasattr(Fraction, "__int__"): + __int__ = _delegate("__int__") + + +_LoaderFunc = Callable[["ImageFileDirectory_v2", bytes, bool], Any] + + +def _register_loader(idx: int, size: int) -> Callable[[_LoaderFunc], _LoaderFunc]: + def decorator(func: _LoaderFunc) -> _LoaderFunc: + from .TiffTags import TYPES + + if func.__name__.startswith("load_"): + TYPES[idx] = func.__name__[5:].replace("_", " ") + _load_dispatch[idx] = size, func # noqa: F821 + return func + + return decorator + + +def _register_writer(idx: int) -> Callable[[Callable[..., Any]], Callable[..., Any]]: + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + _write_dispatch[idx] = func # noqa: F821 + return func + + return decorator + + +def _register_basic(idx_fmt_name: tuple[int, str, str]) -> None: + from .TiffTags import TYPES + + idx, fmt, name = idx_fmt_name + TYPES[idx] = name + size = struct.calcsize(f"={fmt}") + + def basic_handler( + self: ImageFileDirectory_v2, data: bytes, legacy_api: bool = True + ) -> tuple[Any, ...]: + return self._unpack(f"{len(data) // size}{fmt}", data) + + _load_dispatch[idx] = size, basic_handler # noqa: F821 + _write_dispatch[idx] = lambda self, *values: ( # noqa: F821 + b"".join(self._pack(fmt, value) for value in values) + ) + + +if TYPE_CHECKING: + _IFDv2Base = MutableMapping[int, Any] +else: + _IFDv2Base = MutableMapping + + +class ImageFileDirectory_v2(_IFDv2Base): + """This class represents a TIFF tag directory. To speed things up, we + don't decode tags unless they're asked for. + + Exposes a dictionary interface of the tags in the directory:: + + ifd = ImageFileDirectory_v2() + ifd[key] = 'Some Data' + ifd.tagtype[key] = TiffTags.ASCII + print(ifd[key]) + 'Some Data' + + Individual values are returned as the strings or numbers, sequences are + returned as tuples of the values. + + The tiff metadata type of each item is stored in a dictionary of + tag types in + :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v2.tagtype`. The types + are read from a tiff file, guessed from the type added, or added + manually. + + Data Structures: + + * ``self.tagtype = {}`` + + * Key: numerical TIFF tag number + * Value: integer corresponding to the data type from + :py:data:`.TiffTags.TYPES` + + .. versionadded:: 3.0.0 + + 'Internal' data structures: + + * ``self._tags_v2 = {}`` + + * Key: numerical TIFF tag number + * Value: decoded data, as tuple for multiple values + + * ``self._tagdata = {}`` + + * Key: numerical TIFF tag number + * Value: undecoded byte string from file + + * ``self._tags_v1 = {}`` + + * Key: numerical TIFF tag number + * Value: decoded data in the v1 format + + Tags will be found in the private attributes ``self._tagdata``, and in + ``self._tags_v2`` once decoded. + + ``self.legacy_api`` is a value for internal use, and shouldn't be changed + from outside code. In cooperation with + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1`, if ``legacy_api`` + is true, then decoded tags will be populated into both ``_tags_v1`` and + ``_tags_v2``. ``_tags_v2`` will be used if this IFD is used in the TIFF + save routine. Tags should be read from ``_tags_v1`` if + ``legacy_api == true``. + + """ + + _load_dispatch: dict[int, tuple[int, _LoaderFunc]] = {} + _write_dispatch: dict[int, Callable[..., Any]] = {} + + def __init__( + self, + ifh: bytes = b"II\052\0\0\0\0\0", + prefix: bytes | None = None, + group: int | None = None, + ) -> None: + """Initialize an ImageFileDirectory. + + To construct an ImageFileDirectory from a real file, pass the 8-byte + magic header to the constructor. To only set the endianness, pass it + as the 'prefix' keyword argument. + + :param ifh: One of the accepted magic headers (cf. PREFIXES); also sets + endianness. + :param prefix: Override the endianness of the file. + """ + if not _accept(ifh): + msg = f"not a TIFF file (header {repr(ifh)} not valid)" + raise SyntaxError(msg) + self._prefix = prefix if prefix is not None else ifh[:2] + if self._prefix == MM: + self._endian = ">" + elif self._prefix == II: + self._endian = "<" + else: + msg = "not a TIFF IFD" + raise SyntaxError(msg) + self._bigtiff = ifh[2] == 43 + self.group = group + self.tagtype: dict[int, int] = {} + """ Dictionary of tag types """ + self.reset() + self.next = ( + self._unpack("Q", ifh[8:])[0] + if self._bigtiff + else self._unpack("L", ifh[4:])[0] + ) + self._legacy_api = False + + prefix = property(lambda self: self._prefix) + offset = property(lambda self: self._offset) + + @property + def legacy_api(self) -> bool: + return self._legacy_api + + @legacy_api.setter + def legacy_api(self, value: bool) -> NoReturn: + msg = "Not allowing setting of legacy api" + raise Exception(msg) + + def reset(self) -> None: + self._tags_v1: dict[int, Any] = {} # will remain empty if legacy_api is false + self._tags_v2: dict[int, Any] = {} # main tag storage + self._tagdata: dict[int, bytes] = {} + self.tagtype = {} # added 2008-06-05 by Florian Hoech + self._next = None + self._offset: int | None = None + + def __str__(self) -> str: + return str(dict(self)) + + def named(self) -> dict[str, Any]: + """ + :returns: dict of name|key: value + + Returns the complete tag dictionary, with named tags where possible. + """ + return { + TiffTags.lookup(code, self.group).name: value + for code, value in self.items() + } + + def __len__(self) -> int: + return len(set(self._tagdata) | set(self._tags_v2)) + + def __getitem__(self, tag: int) -> Any: + if tag not in self._tags_v2: # unpack on the fly + data = self._tagdata[tag] + typ = self.tagtype[tag] + size, handler = self._load_dispatch[typ] + self[tag] = handler(self, data, self.legacy_api) # check type + val = self._tags_v2[tag] + if self.legacy_api and not isinstance(val, (tuple, bytes)): + val = (val,) + return val + + def __contains__(self, tag: object) -> bool: + return tag in self._tags_v2 or tag in self._tagdata + + def __setitem__(self, tag: int, value: Any) -> None: + self._setitem(tag, value, self.legacy_api) + + def _setitem(self, tag: int, value: Any, legacy_api: bool) -> None: + basetypes = (Number, bytes, str) + + info = TiffTags.lookup(tag, self.group) + values = [value] if isinstance(value, basetypes) else value + + if tag not in self.tagtype: + if info.type: + self.tagtype[tag] = info.type + else: + self.tagtype[tag] = TiffTags.UNDEFINED + if all(isinstance(v, IFDRational) for v in values): + self.tagtype[tag] = ( + TiffTags.RATIONAL + if all(v >= 0 for v in values) + else TiffTags.SIGNED_RATIONAL + ) + elif all(isinstance(v, int) for v in values): + if all(0 <= v < 2**16 for v in values): + self.tagtype[tag] = TiffTags.SHORT + elif all(-(2**15) < v < 2**15 for v in values): + self.tagtype[tag] = TiffTags.SIGNED_SHORT + else: + self.tagtype[tag] = ( + TiffTags.LONG + if all(v >= 0 for v in values) + else TiffTags.SIGNED_LONG + ) + elif all(isinstance(v, float) for v in values): + self.tagtype[tag] = TiffTags.DOUBLE + elif all(isinstance(v, str) for v in values): + self.tagtype[tag] = TiffTags.ASCII + elif all(isinstance(v, bytes) for v in values): + self.tagtype[tag] = TiffTags.BYTE + + if self.tagtype[tag] == TiffTags.UNDEFINED: + values = [ + v.encode("ascii", "replace") if isinstance(v, str) else v + for v in values + ] + elif self.tagtype[tag] == TiffTags.RATIONAL: + values = [float(v) if isinstance(v, int) else v for v in values] + + is_ifd = self.tagtype[tag] == TiffTags.LONG and isinstance(values, dict) + if not is_ifd: + values = tuple(info.cvt_enum(value) for value in values) + + dest = self._tags_v1 if legacy_api else self._tags_v2 + + # Three branches: + # Spec'd length == 1, Actual length 1, store as element + # Spec'd length == 1, Actual > 1, Warn and truncate. Formerly barfed. + # No Spec, Actual length 1, Formerly (<4.2) returned a 1 element tuple. + # Don't mess with the legacy api, since it's frozen. + if not is_ifd and ( + (info.length == 1) + or self.tagtype[tag] == TiffTags.BYTE + or (info.length is None and len(values) == 1 and not legacy_api) + ): + # Don't mess with the legacy api, since it's frozen. + if legacy_api and self.tagtype[tag] in [ + TiffTags.RATIONAL, + TiffTags.SIGNED_RATIONAL, + ]: # rationals + values = (values,) + try: + (dest[tag],) = values + except ValueError: + # We've got a builtin tag with 1 expected entry + warnings.warn( + f"Metadata Warning, tag {tag} had too many entries: " + f"{len(values)}, expected 1" + ) + dest[tag] = values[0] + + else: + # Spec'd length > 1 or undefined + # Unspec'd, and length > 1 + dest[tag] = values + + def __delitem__(self, tag: int) -> None: + self._tags_v2.pop(tag, None) + self._tags_v1.pop(tag, None) + self._tagdata.pop(tag, None) + + def __iter__(self) -> Iterator[int]: + return iter(set(self._tagdata) | set(self._tags_v2)) + + def _unpack(self, fmt: str, data: bytes) -> tuple[Any, ...]: + return struct.unpack(self._endian + fmt, data) + + def _pack(self, fmt: str, *values: Any) -> bytes: + return struct.pack(self._endian + fmt, *values) + + list( + map( + _register_basic, + [ + (TiffTags.SHORT, "H", "short"), + (TiffTags.LONG, "L", "long"), + (TiffTags.SIGNED_BYTE, "b", "signed byte"), + (TiffTags.SIGNED_SHORT, "h", "signed short"), + (TiffTags.SIGNED_LONG, "l", "signed long"), + (TiffTags.FLOAT, "f", "float"), + (TiffTags.DOUBLE, "d", "double"), + (TiffTags.IFD, "L", "long"), + (TiffTags.LONG8, "Q", "long8"), + ], + ) + ) + + @_register_loader(1, 1) # Basic type, except for the legacy API. + def load_byte(self, data: bytes, legacy_api: bool = True) -> bytes: + return data + + @_register_writer(1) # Basic type, except for the legacy API. + def write_byte(self, data: bytes | int | IFDRational) -> bytes: + if isinstance(data, IFDRational): + data = int(data) + if isinstance(data, int): + data = bytes((data,)) + return data + + @_register_loader(2, 1) + def load_string(self, data: bytes, legacy_api: bool = True) -> str: + if data.endswith(b"\0"): + data = data[:-1] + return data.decode("latin-1", "replace") + + @_register_writer(2) + def write_string(self, value: str | bytes | int) -> bytes: + # remerge of https://github.com/python-pillow/Pillow/pull/1416 + if isinstance(value, int): + value = str(value) + if not isinstance(value, bytes): + value = value.encode("ascii", "replace") + return value + b"\0" + + @_register_loader(5, 8) + def load_rational( + self, data: bytes, legacy_api: bool = True + ) -> tuple[tuple[int, int] | IFDRational, ...]: + vals = self._unpack(f"{len(data) // 4}L", data) + + def combine(a: int, b: int) -> tuple[int, int] | IFDRational: + return (a, b) if legacy_api else IFDRational(a, b) + + return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) + + @_register_writer(5) + def write_rational(self, *values: IFDRational) -> bytes: + return b"".join( + self._pack("2L", *_limit_rational(frac, 2**32 - 1)) for frac in values + ) + + @_register_loader(7, 1) + def load_undefined(self, data: bytes, legacy_api: bool = True) -> bytes: + return data + + @_register_writer(7) + def write_undefined(self, value: bytes | int | IFDRational) -> bytes: + if isinstance(value, IFDRational): + value = int(value) + if isinstance(value, int): + value = str(value).encode("ascii", "replace") + return value + + @_register_loader(10, 8) + def load_signed_rational( + self, data: bytes, legacy_api: bool = True + ) -> tuple[tuple[int, int] | IFDRational, ...]: + vals = self._unpack(f"{len(data) // 4}l", data) + + def combine(a: int, b: int) -> tuple[int, int] | IFDRational: + return (a, b) if legacy_api else IFDRational(a, b) + + return tuple(combine(num, denom) for num, denom in zip(vals[::2], vals[1::2])) + + @_register_writer(10) + def write_signed_rational(self, *values: IFDRational) -> bytes: + return b"".join( + self._pack("2l", *_limit_signed_rational(frac, 2**31 - 1, -(2**31))) + for frac in values + ) + + def _ensure_read(self, fp: IO[bytes], size: int) -> bytes: + ret = fp.read(size) + if len(ret) != size: + msg = ( + "Corrupt EXIF data. " + f"Expecting to read {size} bytes but only got {len(ret)}. " + ) + raise OSError(msg) + return ret + + def load(self, fp: IO[bytes]) -> None: + self.reset() + self._offset = fp.tell() + + try: + tag_count = ( + self._unpack("Q", self._ensure_read(fp, 8)) + if self._bigtiff + else self._unpack("H", self._ensure_read(fp, 2)) + )[0] + for i in range(tag_count): + tag, typ, count, data = ( + self._unpack("HHQ8s", self._ensure_read(fp, 20)) + if self._bigtiff + else self._unpack("HHL4s", self._ensure_read(fp, 12)) + ) + + tagname = TiffTags.lookup(tag, self.group).name + typname = TYPES.get(typ, "unknown") + msg = f"tag: {tagname} ({tag}) - type: {typname} ({typ})" + + try: + unit_size, handler = self._load_dispatch[typ] + except KeyError: + logger.debug("%s - unsupported type %s", msg, typ) + continue # ignore unsupported type + size = count * unit_size + if size > (8 if self._bigtiff else 4): + here = fp.tell() + (offset,) = self._unpack("Q" if self._bigtiff else "L", data) + msg += f" Tag Location: {here} - Data Location: {offset}" + fp.seek(offset) + data = ImageFile._safe_read(fp, size) + fp.seek(here) + else: + data = data[:size] + + if len(data) != size: + warnings.warn( + "Possibly corrupt EXIF data. " + f"Expecting to read {size} bytes but only got {len(data)}." + f" Skipping tag {tag}" + ) + logger.debug(msg) + continue + + if not data: + logger.debug(msg) + continue + + self._tagdata[tag] = data + self.tagtype[tag] = typ + + msg += " - value: " + ( + "" % size if size > 32 else repr(data) + ) + logger.debug(msg) + + (self.next,) = ( + self._unpack("Q", self._ensure_read(fp, 8)) + if self._bigtiff + else self._unpack("L", self._ensure_read(fp, 4)) + ) + except OSError as msg: + warnings.warn(str(msg)) + return + + def tobytes(self, offset: int = 0) -> bytes: + # FIXME What about tagdata? + result = self._pack("H", len(self._tags_v2)) + + entries: list[tuple[int, int, int, bytes, bytes]] = [] + offset = offset + len(result) + len(self._tags_v2) * 12 + 4 + stripoffsets = None + + # pass 1: convert tags to binary format + # always write tags in ascending order + for tag, value in sorted(self._tags_v2.items()): + if tag == STRIPOFFSETS: + stripoffsets = len(entries) + typ = self.tagtype[tag] + logger.debug("Tag %s, Type: %s, Value: %s", tag, typ, repr(value)) + is_ifd = typ == TiffTags.LONG and isinstance(value, dict) + if is_ifd: + if self._endian == "<": + ifh = b"II\x2A\x00\x08\x00\x00\x00" + else: + ifh = b"MM\x00\x2A\x00\x00\x00\x08" + ifd = ImageFileDirectory_v2(ifh, group=tag) + values = self._tags_v2[tag] + for ifd_tag, ifd_value in values.items(): + ifd[ifd_tag] = ifd_value + data = ifd.tobytes(offset) + else: + values = value if isinstance(value, tuple) else (value,) + data = self._write_dispatch[typ](self, *values) + + tagname = TiffTags.lookup(tag, self.group).name + typname = "ifd" if is_ifd else TYPES.get(typ, "unknown") + msg = f"save: {tagname} ({tag}) - type: {typname} ({typ})" + msg += " - value: " + ( + "" % len(data) if len(data) >= 16 else str(values) + ) + logger.debug(msg) + + # count is sum of lengths for string and arbitrary data + if is_ifd: + count = 1 + elif typ in [TiffTags.BYTE, TiffTags.ASCII, TiffTags.UNDEFINED]: + count = len(data) + else: + count = len(values) + # figure out if data fits into the entry + if len(data) <= 4: + entries.append((tag, typ, count, data.ljust(4, b"\0"), b"")) + else: + entries.append((tag, typ, count, self._pack("L", offset), data)) + offset += (len(data) + 1) // 2 * 2 # pad to word + + # update strip offset data to point beyond auxiliary data + if stripoffsets is not None: + tag, typ, count, value, data = entries[stripoffsets] + if data: + size, handler = self._load_dispatch[typ] + values = [val + offset for val in handler(self, data, self.legacy_api)] + data = self._write_dispatch[typ](self, *values) + else: + value = self._pack("L", self._unpack("L", value)[0] + offset) + entries[stripoffsets] = tag, typ, count, value, data + + # pass 2: write entries to file + for tag, typ, count, value, data in entries: + logger.debug("%s %s %s %s %s", tag, typ, count, repr(value), repr(data)) + result += self._pack("HHL4s", tag, typ, count, value) + + # -- overwrite here for multi-page -- + result += b"\0\0\0\0" # end of entries + + # pass 3: write auxiliary data to file + for tag, typ, count, value, data in entries: + result += data + if len(data) & 1: + result += b"\0" + + return result + + def save(self, fp: IO[bytes]) -> int: + if fp.tell() == 0: # skip TIFF header on subsequent pages + # tiff header -- PIL always starts the first IFD at offset 8 + fp.write(self._prefix + self._pack("HL", 42, 8)) + + offset = fp.tell() + result = self.tobytes(offset) + fp.write(result) + return offset + len(result) + + +ImageFileDirectory_v2._load_dispatch = _load_dispatch +ImageFileDirectory_v2._write_dispatch = _write_dispatch +for idx, name in TYPES.items(): + name = name.replace(" ", "_") + setattr(ImageFileDirectory_v2, f"load_{name}", _load_dispatch[idx][1]) + setattr(ImageFileDirectory_v2, f"write_{name}", _write_dispatch[idx]) +del _load_dispatch, _write_dispatch, idx, name + + +# Legacy ImageFileDirectory support. +class ImageFileDirectory_v1(ImageFileDirectory_v2): + """This class represents the **legacy** interface to a TIFF tag directory. + + Exposes a dictionary interface of the tags in the directory:: + + ifd = ImageFileDirectory_v1() + ifd[key] = 'Some Data' + ifd.tagtype[key] = TiffTags.ASCII + print(ifd[key]) + ('Some Data',) + + Also contains a dictionary of tag types as read from the tiff image file, + :attr:`~PIL.TiffImagePlugin.ImageFileDirectory_v1.tagtype`. + + Values are returned as a tuple. + + .. deprecated:: 3.0.0 + """ + + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self._legacy_api = True + + tags = property(lambda self: self._tags_v1) + tagdata = property(lambda self: self._tagdata) + + # defined in ImageFileDirectory_v2 + tagtype: dict[int, int] + """Dictionary of tag types""" + + @classmethod + def from_v2(cls, original: ImageFileDirectory_v2) -> ImageFileDirectory_v1: + """Returns an + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + instance with the same data as is contained in the original + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + instance. + + :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + + """ + + ifd = cls(prefix=original.prefix) + ifd._tagdata = original._tagdata + ifd.tagtype = original.tagtype + ifd.next = original.next # an indicator for multipage tiffs + return ifd + + def to_v2(self) -> ImageFileDirectory_v2: + """Returns an + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + instance with the same data as is contained in the original + :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v1` + instance. + + :returns: :py:class:`~PIL.TiffImagePlugin.ImageFileDirectory_v2` + + """ + + ifd = ImageFileDirectory_v2(prefix=self.prefix) + ifd._tagdata = dict(self._tagdata) + ifd.tagtype = dict(self.tagtype) + ifd._tags_v2 = dict(self._tags_v2) + return ifd + + def __contains__(self, tag: object) -> bool: + return tag in self._tags_v1 or tag in self._tagdata + + def __len__(self) -> int: + return len(set(self._tagdata) | set(self._tags_v1)) + + def __iter__(self) -> Iterator[int]: + return iter(set(self._tagdata) | set(self._tags_v1)) + + def __setitem__(self, tag: int, value: Any) -> None: + for legacy_api in (False, True): + self._setitem(tag, value, legacy_api) + + def __getitem__(self, tag: int) -> Any: + if tag not in self._tags_v1: # unpack on the fly + data = self._tagdata[tag] + typ = self.tagtype[tag] + size, handler = self._load_dispatch[typ] + for legacy in (False, True): + self._setitem(tag, handler(self, data, legacy), legacy) + val = self._tags_v1[tag] + if not isinstance(val, (tuple, bytes)): + val = (val,) + return val + + +# undone -- switch this pointer +ImageFileDirectory = ImageFileDirectory_v1 + + +## +# Image plugin for TIFF files. + + +class TiffImageFile(ImageFile.ImageFile): + format = "TIFF" + format_description = "Adobe TIFF" + _close_exclusive_fp_after_loading = False + + def __init__( + self, + fp: StrOrBytesPath | IO[bytes], + filename: str | bytes | None = None, + ) -> None: + self.tag_v2: ImageFileDirectory_v2 + """ Image file directory (tag dictionary) """ + + self.tag: ImageFileDirectory_v1 + """ Legacy tag entries """ + + super().__init__(fp, filename) + + def _open(self) -> None: + """Open the first image in a TIFF file""" + + # Header + ifh = self.fp.read(8) + if ifh[2] == 43: + ifh += self.fp.read(8) + + self.tag_v2 = ImageFileDirectory_v2(ifh) + + # setup frame pointers + self.__first = self.__next = self.tag_v2.next + self.__frame = -1 + self._fp = self.fp + self._frame_pos: list[int] = [] + self._n_frames: int | None = None + + logger.debug("*** TiffImageFile._open ***") + logger.debug("- __first: %s", self.__first) + logger.debug("- ifh: %s", repr(ifh)) # Use repr to avoid str(bytes) + + # and load the first frame + self._seek(0) + + @property + def n_frames(self) -> int: + current_n_frames = self._n_frames + if current_n_frames is None: + current = self.tell() + self._seek(len(self._frame_pos)) + while self._n_frames is None: + self._seek(self.tell() + 1) + self.seek(current) + assert self._n_frames is not None + return self._n_frames + + def seek(self, frame: int) -> None: + """Select a given frame as current image""" + if not self._seek_check(frame): + return + self._seek(frame) + if self._im is not None and ( + self.im.size != self._tile_size or self.im.mode != self.mode + ): + # The core image will no longer be used + self._im = None + + def _seek(self, frame: int) -> None: + self.fp = self._fp + + # reset buffered io handle in case fp + # was passed to libtiff, invalidating the buffer + self.fp.tell() + + while len(self._frame_pos) <= frame: + if not self.__next: + msg = "no more images in TIFF file" + raise EOFError(msg) + logger.debug( + "Seeking to frame %s, on frame %s, __next %s, location: %s", + frame, + self.__frame, + self.__next, + self.fp.tell(), + ) + if self.__next >= 2**63: + msg = "Unable to seek to frame" + raise ValueError(msg) + self.fp.seek(self.__next) + self._frame_pos.append(self.__next) + logger.debug("Loading tags, location: %s", self.fp.tell()) + self.tag_v2.load(self.fp) + if self.tag_v2.next in self._frame_pos: + # This IFD has already been processed + # Declare this to be the end of the image + self.__next = 0 + else: + self.__next = self.tag_v2.next + if self.__next == 0: + self._n_frames = frame + 1 + if len(self._frame_pos) == 1: + self.is_animated = self.__next != 0 + self.__frame += 1 + self.fp.seek(self._frame_pos[frame]) + self.tag_v2.load(self.fp) + if XMP in self.tag_v2: + self.info["xmp"] = self.tag_v2[XMP] + elif "xmp" in self.info: + del self.info["xmp"] + self._reload_exif() + # fill the legacy tag/ifd entries + self.tag = self.ifd = ImageFileDirectory_v1.from_v2(self.tag_v2) + self.__frame = frame + self._setup() + + def tell(self) -> int: + """Return the current frame number""" + return self.__frame + + def get_photoshop_blocks(self) -> dict[int, dict[str, bytes]]: + """ + Returns a dictionary of Photoshop "Image Resource Blocks". + The keys are the image resource ID. For more information, see + https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037727 + + :returns: Photoshop "Image Resource Blocks" in a dictionary. + """ + blocks = {} + val = self.tag_v2.get(ExifTags.Base.ImageResources) + if val: + while val[:4] == b"8BIM": + id = i16(val[4:6]) + n = math.ceil((val[6] + 1) / 2) * 2 + size = i32(val[6 + n : 10 + n]) + data = val[10 + n : 10 + n + size] + blocks[id] = {"data": data} + + val = val[math.ceil((10 + n + size) / 2) * 2 :] + return blocks + + def load(self) -> Image.core.PixelAccess | None: + if self.tile and self.use_load_libtiff: + return self._load_libtiff() + return super().load() + + def load_prepare(self) -> None: + if self._im is None: + Image._decompression_bomb_check(self._tile_size) + self.im = Image.core.new(self.mode, self._tile_size) + ImageFile.ImageFile.load_prepare(self) + + def load_end(self) -> None: + # allow closing if we're on the first frame, there's no next + # This is the ImageFile.load path only, libtiff specific below. + if not self.is_animated: + self._close_exclusive_fp_after_loading = True + + # reset buffered io handle in case fp + # was passed to libtiff, invalidating the buffer + self.fp.tell() + + # load IFD data from fp before it is closed + exif = self.getexif() + for key in TiffTags.TAGS_V2_GROUPS: + if key not in exif: + continue + exif.get_ifd(key) + + ImageOps.exif_transpose(self, in_place=True) + if ExifTags.Base.Orientation in self.tag_v2: + del self.tag_v2[ExifTags.Base.Orientation] + + def _load_libtiff(self) -> Image.core.PixelAccess | None: + """Overload method triggered when we detect a compressed tiff + Calls out to libtiff""" + + Image.Image.load(self) + + self.load_prepare() + + if not len(self.tile) == 1: + msg = "Not exactly one tile" + raise OSError(msg) + + # (self._compression, (extents tuple), + # 0, (rawmode, self._compression, fp)) + extents = self.tile[0][1] + args = self.tile[0][3] + + # To be nice on memory footprint, if there's a + # file descriptor, use that instead of reading + # into a string in python. + try: + fp = hasattr(self.fp, "fileno") and self.fp.fileno() + # flush the file descriptor, prevents error on pypy 2.4+ + # should also eliminate the need for fp.tell + # in _seek + if hasattr(self.fp, "flush"): + self.fp.flush() + except OSError: + # io.BytesIO have a fileno, but returns an OSError if + # it doesn't use a file descriptor. + fp = False + + if fp: + assert isinstance(args, tuple) + args_list = list(args) + args_list[2] = fp + args = tuple(args_list) + + decoder = Image._getdecoder(self.mode, "libtiff", args, self.decoderconfig) + try: + decoder.setimage(self.im, extents) + except ValueError as e: + msg = "Couldn't set the image" + raise OSError(msg) from e + + close_self_fp = self._exclusive_fp and not self.is_animated + if hasattr(self.fp, "getvalue"): + # We've got a stringio like thing passed in. Yay for all in memory. + # The decoder needs the entire file in one shot, so there's not + # a lot we can do here other than give it the entire file. + # unless we could do something like get the address of the + # underlying string for stringio. + # + # Rearranging for supporting byteio items, since they have a fileno + # that returns an OSError if there's no underlying fp. Easier to + # deal with here by reordering. + logger.debug("have getvalue. just sending in a string from getvalue") + n, err = decoder.decode(self.fp.getvalue()) + elif fp: + # we've got a actual file on disk, pass in the fp. + logger.debug("have fileno, calling fileno version of the decoder.") + if not close_self_fp: + self.fp.seek(0) + # 4 bytes, otherwise the trace might error out + n, err = decoder.decode(b"fpfp") + else: + # we have something else. + logger.debug("don't have fileno or getvalue. just reading") + self.fp.seek(0) + # UNDONE -- so much for that buffer size thing. + n, err = decoder.decode(self.fp.read()) + + self.tile = [] + self.readonly = 0 + + self.load_end() + + if close_self_fp: + self.fp.close() + self.fp = None # might be shared + + if err < 0: + raise OSError(err) + + return Image.Image.load(self) + + def _setup(self) -> None: + """Setup this image object based on current tags""" + + if 0xBC01 in self.tag_v2: + msg = "Windows Media Photo files not yet supported" + raise OSError(msg) + + # extract relevant tags + self._compression = COMPRESSION_INFO[self.tag_v2.get(COMPRESSION, 1)] + self._planar_configuration = self.tag_v2.get(PLANAR_CONFIGURATION, 1) + + # photometric is a required tag, but not everyone is reading + # the specification + photo = self.tag_v2.get(PHOTOMETRIC_INTERPRETATION, 0) + + # old style jpeg compression images most certainly are YCbCr + if self._compression == "tiff_jpeg": + photo = 6 + + fillorder = self.tag_v2.get(FILLORDER, 1) + + logger.debug("*** Summary ***") + logger.debug("- compression: %s", self._compression) + logger.debug("- photometric_interpretation: %s", photo) + logger.debug("- planar_configuration: %s", self._planar_configuration) + logger.debug("- fill_order: %s", fillorder) + logger.debug("- YCbCr subsampling: %s", self.tag_v2.get(YCBCRSUBSAMPLING)) + + # size + xsize = self.tag_v2.get(IMAGEWIDTH) + ysize = self.tag_v2.get(IMAGELENGTH) + if not isinstance(xsize, int) or not isinstance(ysize, int): + msg = "Invalid dimensions" + raise ValueError(msg) + self._tile_size = xsize, ysize + orientation = self.tag_v2.get(ExifTags.Base.Orientation) + if orientation in (5, 6, 7, 8): + self._size = ysize, xsize + else: + self._size = xsize, ysize + + logger.debug("- size: %s", self.size) + + sample_format = self.tag_v2.get(SAMPLEFORMAT, (1,)) + if len(sample_format) > 1 and max(sample_format) == min(sample_format) == 1: + # SAMPLEFORMAT is properly per band, so an RGB image will + # be (1,1,1). But, we don't support per band pixel types, + # and anything more than one band is a uint8. So, just + # take the first element. Revisit this if adding support + # for more exotic images. + sample_format = (1,) + + bps_tuple = self.tag_v2.get(BITSPERSAMPLE, (1,)) + extra_tuple = self.tag_v2.get(EXTRASAMPLES, ()) + if photo in (2, 6, 8): # RGB, YCbCr, LAB + bps_count = 3 + elif photo == 5: # CMYK + bps_count = 4 + else: + bps_count = 1 + bps_count += len(extra_tuple) + bps_actual_count = len(bps_tuple) + samples_per_pixel = self.tag_v2.get( + SAMPLESPERPIXEL, + 3 if self._compression == "tiff_jpeg" and photo in (2, 6) else 1, + ) + + if samples_per_pixel > MAX_SAMPLESPERPIXEL: + # DOS check, samples_per_pixel can be a Long, and we extend the tuple below + logger.error( + "More samples per pixel than can be decoded: %s", samples_per_pixel + ) + msg = "Invalid value for samples per pixel" + raise SyntaxError(msg) + + if samples_per_pixel < bps_actual_count: + # If a file has more values in bps_tuple than expected, + # remove the excess. + bps_tuple = bps_tuple[:samples_per_pixel] + elif samples_per_pixel > bps_actual_count and bps_actual_count == 1: + # If a file has only one value in bps_tuple, when it should have more, + # presume it is the same number of bits for all of the samples. + bps_tuple = bps_tuple * samples_per_pixel + + if len(bps_tuple) != samples_per_pixel: + msg = "unknown data organization" + raise SyntaxError(msg) + + # mode: check photometric interpretation and bits per pixel + key = ( + self.tag_v2.prefix, + photo, + sample_format, + fillorder, + bps_tuple, + extra_tuple, + ) + logger.debug("format key: %s", key) + try: + self._mode, rawmode = OPEN_INFO[key] + except KeyError as e: + logger.debug("- unsupported format") + msg = "unknown pixel mode" + raise SyntaxError(msg) from e + + logger.debug("- raw mode: %s", rawmode) + logger.debug("- pil mode: %s", self.mode) + + self.info["compression"] = self._compression + + xres = self.tag_v2.get(X_RESOLUTION, 1) + yres = self.tag_v2.get(Y_RESOLUTION, 1) + + if xres and yres: + resunit = self.tag_v2.get(RESOLUTION_UNIT) + if resunit == 2: # dots per inch + self.info["dpi"] = (xres, yres) + elif resunit == 3: # dots per centimeter. convert to dpi + self.info["dpi"] = (xres * 2.54, yres * 2.54) + elif resunit is None: # used to default to 1, but now 2) + self.info["dpi"] = (xres, yres) + # For backward compatibility, + # we also preserve the old behavior + self.info["resolution"] = xres, yres + else: # No absolute unit of measurement + self.info["resolution"] = xres, yres + + # build tile descriptors + x = y = layer = 0 + self.tile = [] + self.use_load_libtiff = READ_LIBTIFF or self._compression != "raw" + if self.use_load_libtiff: + # Decoder expects entire file as one tile. + # There's a buffer size limit in load (64k) + # so large g4 images will fail if we use that + # function. + # + # Setup the one tile for the whole image, then + # use the _load_libtiff function. + + # libtiff handles the fillmode for us, so 1;IR should + # actually be 1;I. Including the R double reverses the + # bits, so stripes of the image are reversed. See + # https://github.com/python-pillow/Pillow/issues/279 + if fillorder == 2: + # Replace fillorder with fillorder=1 + key = key[:3] + (1,) + key[4:] + logger.debug("format key: %s", key) + # this should always work, since all the + # fillorder==2 modes have a corresponding + # fillorder=1 mode + self._mode, rawmode = OPEN_INFO[key] + # libtiff always returns the bytes in native order. + # we're expecting image byte order. So, if the rawmode + # contains I;16, we need to convert from native to image + # byte order. + if rawmode == "I;16": + rawmode = "I;16N" + if ";16B" in rawmode: + rawmode = rawmode.replace(";16B", ";16N") + if ";16L" in rawmode: + rawmode = rawmode.replace(";16L", ";16N") + + # YCbCr images with new jpeg compression with pixels in one plane + # unpacked straight into RGB values + if ( + photo == 6 + and self._compression == "jpeg" + and self._planar_configuration == 1 + ): + rawmode = "RGB" + + # Offset in the tile tuple is 0, we go from 0,0 to + # w,h, and we only do this once -- eds + a = (rawmode, self._compression, False, self.tag_v2.offset) + self.tile.append(ImageFile._Tile("libtiff", (0, 0, xsize, ysize), 0, a)) + + elif STRIPOFFSETS in self.tag_v2 or TILEOFFSETS in self.tag_v2: + # striped image + if STRIPOFFSETS in self.tag_v2: + offsets = self.tag_v2[STRIPOFFSETS] + h = self.tag_v2.get(ROWSPERSTRIP, ysize) + w = xsize + else: + # tiled image + offsets = self.tag_v2[TILEOFFSETS] + tilewidth = self.tag_v2.get(TILEWIDTH) + h = self.tag_v2.get(TILELENGTH) + if not isinstance(tilewidth, int) or not isinstance(h, int): + msg = "Invalid tile dimensions" + raise ValueError(msg) + w = tilewidth + + for offset in offsets: + if x + w > xsize: + stride = w * sum(bps_tuple) / 8 # bytes per line + else: + stride = 0 + + tile_rawmode = rawmode + if self._planar_configuration == 2: + # each band on it's own layer + tile_rawmode = rawmode[layer] + # adjust stride width accordingly + stride /= bps_count + + args = (tile_rawmode, int(stride), 1) + self.tile.append( + ImageFile._Tile( + self._compression, + (x, y, min(x + w, xsize), min(y + h, ysize)), + offset, + args, + ) + ) + x = x + w + if x >= xsize: + x, y = 0, y + h + if y >= ysize: + x = y = 0 + layer += 1 + else: + logger.debug("- unsupported data organization") + msg = "unknown data organization" + raise SyntaxError(msg) + + # Fix up info. + if ICCPROFILE in self.tag_v2: + self.info["icc_profile"] = self.tag_v2[ICCPROFILE] + + # fixup palette descriptor + + if self.mode in ["P", "PA"]: + palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]] + self.palette = ImagePalette.raw("RGB;L", b"".join(palette)) + + +# +# -------------------------------------------------------------------- +# Write TIFF files + +# little endian is default except for image modes with +# explicit big endian byte-order + +SAVE_INFO = { + # mode => rawmode, byteorder, photometrics, + # sampleformat, bitspersample, extra + "1": ("1", II, 1, 1, (1,), None), + "L": ("L", II, 1, 1, (8,), None), + "LA": ("LA", II, 1, 1, (8, 8), 2), + "P": ("P", II, 3, 1, (8,), None), + "PA": ("PA", II, 3, 1, (8, 8), 2), + "I": ("I;32S", II, 1, 2, (32,), None), + "I;16": ("I;16", II, 1, 1, (16,), None), + "I;16S": ("I;16S", II, 1, 2, (16,), None), + "F": ("F;32F", II, 1, 3, (32,), None), + "RGB": ("RGB", II, 2, 1, (8, 8, 8), None), + "RGBX": ("RGBX", II, 2, 1, (8, 8, 8, 8), 0), + "RGBA": ("RGBA", II, 2, 1, (8, 8, 8, 8), 2), + "CMYK": ("CMYK", II, 5, 1, (8, 8, 8, 8), None), + "YCbCr": ("YCbCr", II, 6, 1, (8, 8, 8), None), + "LAB": ("LAB", II, 8, 1, (8, 8, 8), None), + "I;32BS": ("I;32BS", MM, 1, 2, (32,), None), + "I;16B": ("I;16B", MM, 1, 1, (16,), None), + "I;16BS": ("I;16BS", MM, 1, 2, (16,), None), + "F;32BF": ("F;32BF", MM, 1, 3, (32,), None), +} + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + try: + rawmode, prefix, photo, format, bits, extra = SAVE_INFO[im.mode] + except KeyError as e: + msg = f"cannot write mode {im.mode} as TIFF" + raise OSError(msg) from e + + ifd = ImageFileDirectory_v2(prefix=prefix) + + encoderinfo = im.encoderinfo + encoderconfig = im.encoderconfig + try: + compression = encoderinfo["compression"] + except KeyError: + compression = im.info.get("compression") + if isinstance(compression, int): + # compression value may be from BMP. Ignore it + compression = None + if compression is None: + compression = "raw" + elif compression == "tiff_jpeg": + # OJPEG is obsolete, so use new-style JPEG compression instead + compression = "jpeg" + elif compression == "tiff_deflate": + compression = "tiff_adobe_deflate" + + libtiff = WRITE_LIBTIFF or compression != "raw" + + # required for color libtiff images + ifd[PLANAR_CONFIGURATION] = 1 + + ifd[IMAGEWIDTH] = im.size[0] + ifd[IMAGELENGTH] = im.size[1] + + # write any arbitrary tags passed in as an ImageFileDirectory + if "tiffinfo" in encoderinfo: + info = encoderinfo["tiffinfo"] + elif "exif" in encoderinfo: + info = encoderinfo["exif"] + if isinstance(info, bytes): + exif = Image.Exif() + exif.load(info) + info = exif + else: + info = {} + logger.debug("Tiffinfo Keys: %s", list(info)) + if isinstance(info, ImageFileDirectory_v1): + info = info.to_v2() + for key in info: + if isinstance(info, Image.Exif) and key in TiffTags.TAGS_V2_GROUPS: + ifd[key] = info.get_ifd(key) + else: + ifd[key] = info.get(key) + try: + ifd.tagtype[key] = info.tagtype[key] + except Exception: + pass # might not be an IFD. Might not have populated type + + legacy_ifd = {} + if hasattr(im, "tag"): + legacy_ifd = im.tag.to_v2() + + supplied_tags = {**legacy_ifd, **getattr(im, "tag_v2", {})} + for tag in ( + # IFD offset that may not be correct in the saved image + EXIFIFD, + # Determined by the image format and should not be copied from legacy_ifd. + SAMPLEFORMAT, + ): + if tag in supplied_tags: + del supplied_tags[tag] + + # additions written by Greg Couch, gregc@cgl.ucsf.edu + # inspired by image-sig posting from Kevin Cazabon, kcazabon@home.com + if hasattr(im, "tag_v2"): + # preserve tags from original TIFF image file + for key in ( + RESOLUTION_UNIT, + X_RESOLUTION, + Y_RESOLUTION, + IPTC_NAA_CHUNK, + PHOTOSHOP_CHUNK, + XMP, + ): + if key in im.tag_v2: + if key == IPTC_NAA_CHUNK and im.tag_v2.tagtype[key] not in ( + TiffTags.BYTE, + TiffTags.UNDEFINED, + ): + del supplied_tags[key] + else: + ifd[key] = im.tag_v2[key] + ifd.tagtype[key] = im.tag_v2.tagtype[key] + + # preserve ICC profile (should also work when saving other formats + # which support profiles as TIFF) -- 2008-06-06 Florian Hoech + icc = encoderinfo.get("icc_profile", im.info.get("icc_profile")) + if icc: + ifd[ICCPROFILE] = icc + + for key, name in [ + (IMAGEDESCRIPTION, "description"), + (X_RESOLUTION, "resolution"), + (Y_RESOLUTION, "resolution"), + (X_RESOLUTION, "x_resolution"), + (Y_RESOLUTION, "y_resolution"), + (RESOLUTION_UNIT, "resolution_unit"), + (SOFTWARE, "software"), + (DATE_TIME, "date_time"), + (ARTIST, "artist"), + (COPYRIGHT, "copyright"), + ]: + if name in encoderinfo: + ifd[key] = encoderinfo[name] + + dpi = encoderinfo.get("dpi") + if dpi: + ifd[RESOLUTION_UNIT] = 2 + ifd[X_RESOLUTION] = dpi[0] + ifd[Y_RESOLUTION] = dpi[1] + + if bits != (1,): + ifd[BITSPERSAMPLE] = bits + if len(bits) != 1: + ifd[SAMPLESPERPIXEL] = len(bits) + if extra is not None: + ifd[EXTRASAMPLES] = extra + if format != 1: + ifd[SAMPLEFORMAT] = format + + if PHOTOMETRIC_INTERPRETATION not in ifd: + ifd[PHOTOMETRIC_INTERPRETATION] = photo + elif im.mode in ("1", "L") and ifd[PHOTOMETRIC_INTERPRETATION] == 0: + if im.mode == "1": + inverted_im = im.copy() + px = inverted_im.load() + if px is not None: + for y in range(inverted_im.height): + for x in range(inverted_im.width): + px[x, y] = 0 if px[x, y] == 255 else 255 + im = inverted_im + else: + im = ImageOps.invert(im) + + if im.mode in ["P", "PA"]: + lut = im.im.getpalette("RGB", "RGB;L") + colormap = [] + colors = len(lut) // 3 + for i in range(3): + colormap += [v * 256 for v in lut[colors * i : colors * (i + 1)]] + colormap += [0] * (256 - colors) + ifd[COLORMAP] = colormap + # data orientation + w, h = ifd[IMAGEWIDTH], ifd[IMAGELENGTH] + stride = len(bits) * ((w * bits[0] + 7) // 8) + if ROWSPERSTRIP not in ifd: + # aim for given strip size (64 KB by default) when using libtiff writer + if libtiff: + im_strip_size = encoderinfo.get("strip_size", STRIP_SIZE) + rows_per_strip = 1 if stride == 0 else min(im_strip_size // stride, h) + # JPEG encoder expects multiple of 8 rows + if compression == "jpeg": + rows_per_strip = min(((rows_per_strip + 7) // 8) * 8, h) + else: + rows_per_strip = h + if rows_per_strip == 0: + rows_per_strip = 1 + ifd[ROWSPERSTRIP] = rows_per_strip + strip_byte_counts = 1 if stride == 0 else stride * ifd[ROWSPERSTRIP] + strips_per_image = (h + ifd[ROWSPERSTRIP] - 1) // ifd[ROWSPERSTRIP] + if strip_byte_counts >= 2**16: + ifd.tagtype[STRIPBYTECOUNTS] = TiffTags.LONG + ifd[STRIPBYTECOUNTS] = (strip_byte_counts,) * (strips_per_image - 1) + ( + stride * h - strip_byte_counts * (strips_per_image - 1), + ) + ifd[STRIPOFFSETS] = tuple( + range(0, strip_byte_counts * strips_per_image, strip_byte_counts) + ) # this is adjusted by IFD writer + # no compression by default: + ifd[COMPRESSION] = COMPRESSION_INFO_REV.get(compression, 1) + + if im.mode == "YCbCr": + for tag, default_value in { + YCBCRSUBSAMPLING: (1, 1), + REFERENCEBLACKWHITE: (0, 255, 128, 255, 128, 255), + }.items(): + ifd.setdefault(tag, default_value) + + blocklist = [TILEWIDTH, TILELENGTH, TILEOFFSETS, TILEBYTECOUNTS] + if libtiff: + if "quality" in encoderinfo: + quality = encoderinfo["quality"] + if not isinstance(quality, int) or quality < 0 or quality > 100: + msg = "Invalid quality setting" + raise ValueError(msg) + if compression != "jpeg": + msg = "quality setting only supported for 'jpeg' compression" + raise ValueError(msg) + ifd[JPEGQUALITY] = quality + + logger.debug("Saving using libtiff encoder") + logger.debug("Items: %s", sorted(ifd.items())) + _fp = 0 + if hasattr(fp, "fileno"): + try: + fp.seek(0) + _fp = fp.fileno() + except io.UnsupportedOperation: + pass + + # optional types for non core tags + types = {} + # STRIPOFFSETS and STRIPBYTECOUNTS are added by the library + # based on the data in the strip. + # OSUBFILETYPE is deprecated. + # The other tags expect arrays with a certain length (fixed or depending on + # BITSPERSAMPLE, etc), passing arrays with a different length will result in + # segfaults. Block these tags until we add extra validation. + # SUBIFD may also cause a segfault. + blocklist += [ + OSUBFILETYPE, + REFERENCEBLACKWHITE, + STRIPBYTECOUNTS, + STRIPOFFSETS, + TRANSFERFUNCTION, + SUBIFD, + ] + + # bits per sample is a single short in the tiff directory, not a list. + atts: dict[int, Any] = {BITSPERSAMPLE: bits[0]} + # Merge the ones that we have with (optional) more bits from + # the original file, e.g x,y resolution so that we can + # save(load('')) == original file. + for tag, value in itertools.chain(ifd.items(), supplied_tags.items()): + # Libtiff can only process certain core items without adding + # them to the custom dictionary. + # Custom items are supported for int, float, unicode, string and byte + # values. Other types and tuples require a tagtype. + if tag not in TiffTags.LIBTIFF_CORE: + if not getattr(Image.core, "libtiff_support_custom_tags", False): + continue + + if tag in ifd.tagtype: + types[tag] = ifd.tagtype[tag] + elif not (isinstance(value, (int, float, str, bytes))): + continue + else: + type = TiffTags.lookup(tag).type + if type: + types[tag] = type + if tag not in atts and tag not in blocklist: + if isinstance(value, str): + atts[tag] = value.encode("ascii", "replace") + b"\0" + elif isinstance(value, IFDRational): + atts[tag] = float(value) + else: + atts[tag] = value + + if SAMPLEFORMAT in atts and len(atts[SAMPLEFORMAT]) == 1: + atts[SAMPLEFORMAT] = atts[SAMPLEFORMAT][0] + + logger.debug("Converted items: %s", sorted(atts.items())) + + # libtiff always expects the bytes in native order. + # we're storing image byte order. So, if the rawmode + # contains I;16, we need to convert from native to image + # byte order. + if im.mode in ("I;16B", "I;16"): + rawmode = "I;16N" + + # Pass tags as sorted list so that the tags are set in a fixed order. + # This is required by libtiff for some tags. For example, the JPEGQUALITY + # pseudo tag requires that the COMPRESS tag was already set. + tags = list(atts.items()) + tags.sort() + a = (rawmode, compression, _fp, filename, tags, types) + encoder = Image._getencoder(im.mode, "libtiff", a, encoderconfig) + encoder.setimage(im.im, (0, 0) + im.size) + while True: + errcode, data = encoder.encode(ImageFile.MAXBLOCK)[1:] + if not _fp: + fp.write(data) + if errcode: + break + if errcode < 0: + msg = f"encoder error {errcode} when writing image file" + raise OSError(msg) + + else: + for tag in blocklist: + del ifd[tag] + offset = ifd.save(fp) + + ImageFile._save( + im, + fp, + [ImageFile._Tile("raw", (0, 0) + im.size, offset, (rawmode, stride, 1))], + ) + + # -- helper for multi-page save -- + if "_debug_multipage" in encoderinfo: + # just to access o32 and o16 (using correct byte order) + setattr(im, "_debug_multipage", ifd) + + +class AppendingTiffWriter(io.BytesIO): + fieldSizes = [ + 0, # None + 1, # byte + 1, # ascii + 2, # short + 4, # long + 8, # rational + 1, # sbyte + 1, # undefined + 2, # sshort + 4, # slong + 8, # srational + 4, # float + 8, # double + 4, # ifd + 2, # unicode + 4, # complex + 8, # long8 + ] + + Tags = { + 273, # StripOffsets + 288, # FreeOffsets + 324, # TileOffsets + 519, # JPEGQTables + 520, # JPEGDCTables + 521, # JPEGACTables + } + + def __init__(self, fn: StrOrBytesPath | IO[bytes], new: bool = False) -> None: + self.f: IO[bytes] + if is_path(fn): + self.name = fn + self.close_fp = True + try: + self.f = open(fn, "w+b" if new else "r+b") + except OSError: + self.f = open(fn, "w+b") + else: + self.f = cast(IO[bytes], fn) + self.close_fp = False + self.beginning = self.f.tell() + self.setup() + + def setup(self) -> None: + # Reset everything. + self.f.seek(self.beginning, os.SEEK_SET) + + self.whereToWriteNewIFDOffset: int | None = None + self.offsetOfNewPage = 0 + + self.IIMM = iimm = self.f.read(4) + if not iimm: + # empty file - first page + self.isFirst = True + return + + self.isFirst = False + if iimm == b"II\x2a\x00": + self.setEndian("<") + elif iimm == b"MM\x00\x2a": + self.setEndian(">") + else: + msg = "Invalid TIFF file header" + raise RuntimeError(msg) + + self.skipIFDs() + self.goToEnd() + + def finalize(self) -> None: + if self.isFirst: + return + + # fix offsets + self.f.seek(self.offsetOfNewPage) + + iimm = self.f.read(4) + if not iimm: + # Make it easy to finish a frame without committing to a new one. + return + + if iimm != self.IIMM: + msg = "IIMM of new page doesn't match IIMM of first page" + raise RuntimeError(msg) + + ifd_offset = self.readLong() + ifd_offset += self.offsetOfNewPage + assert self.whereToWriteNewIFDOffset is not None + self.f.seek(self.whereToWriteNewIFDOffset) + self.writeLong(ifd_offset) + self.f.seek(ifd_offset) + self.fixIFD() + + def newFrame(self) -> None: + # Call this to finish a frame. + self.finalize() + self.setup() + + def __enter__(self) -> AppendingTiffWriter: + return self + + def __exit__(self, *args: object) -> None: + if self.close_fp: + self.close() + + def tell(self) -> int: + return self.f.tell() - self.offsetOfNewPage + + def seek(self, offset: int, whence: int = io.SEEK_SET) -> int: + """ + :param offset: Distance to seek. + :param whence: Whether the distance is relative to the start, + end or current position. + :returns: The resulting position, relative to the start. + """ + if whence == os.SEEK_SET: + offset += self.offsetOfNewPage + + self.f.seek(offset, whence) + return self.tell() + + def goToEnd(self) -> None: + self.f.seek(0, os.SEEK_END) + pos = self.f.tell() + + # pad to 16 byte boundary + pad_bytes = 16 - pos % 16 + if 0 < pad_bytes < 16: + self.f.write(bytes(pad_bytes)) + self.offsetOfNewPage = self.f.tell() + + def setEndian(self, endian: str) -> None: + self.endian = endian + self.longFmt = f"{self.endian}L" + self.shortFmt = f"{self.endian}H" + self.tagFormat = f"{self.endian}HHL" + + def skipIFDs(self) -> None: + while True: + ifd_offset = self.readLong() + if ifd_offset == 0: + self.whereToWriteNewIFDOffset = self.f.tell() - 4 + break + + self.f.seek(ifd_offset) + num_tags = self.readShort() + self.f.seek(num_tags * 12, os.SEEK_CUR) + + def write(self, data: Buffer, /) -> int: + return self.f.write(data) + + def _fmt(self, field_size: int) -> str: + try: + return {2: "H", 4: "L", 8: "Q"}[field_size] + except KeyError: + msg = "offset is not supported" + raise RuntimeError(msg) + + def _read(self, field_size: int) -> int: + (value,) = struct.unpack( + self.endian + self._fmt(field_size), self.f.read(field_size) + ) + return value + + def readShort(self) -> int: + return self._read(2) + + def readLong(self) -> int: + return self._read(4) + + @staticmethod + def _verify_bytes_written(bytes_written: int | None, expected: int) -> None: + if bytes_written is not None and bytes_written != expected: + msg = f"wrote only {bytes_written} bytes but wanted {expected}" + raise RuntimeError(msg) + + def rewriteLastShortToLong(self, value: int) -> None: + self.f.seek(-2, os.SEEK_CUR) + bytes_written = self.f.write(struct.pack(self.longFmt, value)) + self._verify_bytes_written(bytes_written, 4) + + def _rewriteLast(self, value: int, field_size: int) -> None: + self.f.seek(-field_size, os.SEEK_CUR) + bytes_written = self.f.write( + struct.pack(self.endian + self._fmt(field_size), value) + ) + self._verify_bytes_written(bytes_written, field_size) + + def rewriteLastShort(self, value: int) -> None: + return self._rewriteLast(value, 2) + + def rewriteLastLong(self, value: int) -> None: + return self._rewriteLast(value, 4) + + def writeShort(self, value: int) -> None: + bytes_written = self.f.write(struct.pack(self.shortFmt, value)) + self._verify_bytes_written(bytes_written, 2) + + def writeLong(self, value: int) -> None: + bytes_written = self.f.write(struct.pack(self.longFmt, value)) + self._verify_bytes_written(bytes_written, 4) + + def close(self) -> None: + self.finalize() + if self.close_fp: + self.f.close() + + def fixIFD(self) -> None: + num_tags = self.readShort() + + for i in range(num_tags): + tag, field_type, count = struct.unpack(self.tagFormat, self.f.read(8)) + + field_size = self.fieldSizes[field_type] + total_size = field_size * count + is_local = total_size <= 4 + if not is_local: + offset = self.readLong() + self.offsetOfNewPage + self.rewriteLastLong(offset) + + if tag in self.Tags: + cur_pos = self.f.tell() + + if is_local: + self._fixOffsets(count, field_size) + self.f.seek(cur_pos + 4) + else: + self.f.seek(offset) + self._fixOffsets(count, field_size) + self.f.seek(cur_pos) + + elif is_local: + # skip the locally stored value that is not an offset + self.f.seek(4, os.SEEK_CUR) + + def _fixOffsets(self, count: int, field_size: int) -> None: + for i in range(count): + offset = self._read(field_size) + offset += self.offsetOfNewPage + if field_size == 2 and offset >= 65536: + # offset is now too large - we must convert shorts to longs + if count != 1: + msg = "not implemented" + raise RuntimeError(msg) # XXX TODO + + # simple case - the offset is just one and therefore it is + # local (not referenced with another offset) + self.rewriteLastShortToLong(offset) + self.f.seek(-10, os.SEEK_CUR) + self.writeShort(TiffTags.LONG) # rewrite the type to LONG + self.f.seek(8, os.SEEK_CUR) + else: + self._rewriteLast(offset, field_size) + + def fixOffsets( + self, count: int, isShort: bool = False, isLong: bool = False + ) -> None: + if isShort: + field_size = 2 + elif isLong: + field_size = 4 + else: + field_size = 0 + return self._fixOffsets(count, field_size) + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + encoderinfo = im.encoderinfo.copy() + encoderconfig = im.encoderconfig + append_images = list(encoderinfo.get("append_images", [])) + if not hasattr(im, "n_frames") and not append_images: + return _save(im, fp, filename) + + cur_idx = im.tell() + try: + with AppendingTiffWriter(fp) as tf: + for ims in [im] + append_images: + ims.encoderinfo = encoderinfo + ims.encoderconfig = encoderconfig + if not hasattr(ims, "n_frames"): + nfr = 1 + else: + nfr = ims.n_frames + + for idx in range(nfr): + ims.seek(idx) + ims.load() + _save(ims, tf, filename) + tf.newFrame() + finally: + im.seek(cur_idx) + + +# +# -------------------------------------------------------------------- +# Register + +Image.register_open(TiffImageFile.format, TiffImageFile, _accept) +Image.register_save(TiffImageFile.format, _save) +Image.register_save_all(TiffImageFile.format, _save_all) + +Image.register_extensions(TiffImageFile.format, [".tif", ".tiff"]) + +Image.register_mime(TiffImageFile.format, "image/tiff") diff --git a/venv/lib/python3.12/site-packages/PIL/TiffTags.py b/venv/lib/python3.12/site-packages/PIL/TiffTags.py new file mode 100644 index 0000000..86adaa4 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/TiffTags.py @@ -0,0 +1,562 @@ +# +# The Python Imaging Library. +# $Id$ +# +# TIFF tags +# +# This module provides clear-text names for various well-known +# TIFF tags. the TIFF codec works just fine without it. +# +# Copyright (c) Secret Labs AB 1999. +# +# See the README file for information on usage and redistribution. +# + +## +# This module provides constants and clear-text names for various +# well-known TIFF tags. +## +from __future__ import annotations + +from typing import NamedTuple + + +class _TagInfo(NamedTuple): + value: int | None + name: str + type: int | None + length: int | None + enum: dict[str, int] + + +class TagInfo(_TagInfo): + __slots__: list[str] = [] + + def __new__( + cls, + value: int | None = None, + name: str = "unknown", + type: int | None = None, + length: int | None = None, + enum: dict[str, int] | None = None, + ) -> TagInfo: + return super().__new__(cls, value, name, type, length, enum or {}) + + def cvt_enum(self, value: str) -> int | str: + # Using get will call hash(value), which can be expensive + # for some types (e.g. Fraction). Since self.enum is rarely + # used, it's usually better to test it first. + return self.enum.get(value, value) if self.enum else value + + +def lookup(tag: int, group: int | None = None) -> TagInfo: + """ + :param tag: Integer tag number + :param group: Which :py:data:`~PIL.TiffTags.TAGS_V2_GROUPS` to look in + + .. versionadded:: 8.3.0 + + :returns: Taginfo namedtuple, From the ``TAGS_V2`` info if possible, + otherwise just populating the value and name from ``TAGS``. + If the tag is not recognized, "unknown" is returned for the name + + """ + + if group is not None: + info = TAGS_V2_GROUPS[group].get(tag) if group in TAGS_V2_GROUPS else None + else: + info = TAGS_V2.get(tag) + return info or TagInfo(tag, TAGS.get(tag, "unknown")) + + +## +# Map tag numbers to tag info. +# +# id: (Name, Type, Length[, enum_values]) +# +# The length here differs from the length in the tiff spec. For +# numbers, the tiff spec is for the number of fields returned. We +# agree here. For string-like types, the tiff spec uses the length of +# field in bytes. In Pillow, we are using the number of expected +# fields, in general 1 for string-like types. + + +BYTE = 1 +ASCII = 2 +SHORT = 3 +LONG = 4 +RATIONAL = 5 +SIGNED_BYTE = 6 +UNDEFINED = 7 +SIGNED_SHORT = 8 +SIGNED_LONG = 9 +SIGNED_RATIONAL = 10 +FLOAT = 11 +DOUBLE = 12 +IFD = 13 +LONG8 = 16 + +_tags_v2: dict[int, tuple[str, int, int] | tuple[str, int, int, dict[str, int]]] = { + 254: ("NewSubfileType", LONG, 1), + 255: ("SubfileType", SHORT, 1), + 256: ("ImageWidth", LONG, 1), + 257: ("ImageLength", LONG, 1), + 258: ("BitsPerSample", SHORT, 0), + 259: ( + "Compression", + SHORT, + 1, + { + "Uncompressed": 1, + "CCITT 1d": 2, + "Group 3 Fax": 3, + "Group 4 Fax": 4, + "LZW": 5, + "JPEG": 6, + "PackBits": 32773, + }, + ), + 262: ( + "PhotometricInterpretation", + SHORT, + 1, + { + "WhiteIsZero": 0, + "BlackIsZero": 1, + "RGB": 2, + "RGB Palette": 3, + "Transparency Mask": 4, + "CMYK": 5, + "YCbCr": 6, + "CieLAB": 8, + "CFA": 32803, # TIFF/EP, Adobe DNG + "LinearRaw": 32892, # Adobe DNG + }, + ), + 263: ("Threshholding", SHORT, 1), + 264: ("CellWidth", SHORT, 1), + 265: ("CellLength", SHORT, 1), + 266: ("FillOrder", SHORT, 1), + 269: ("DocumentName", ASCII, 1), + 270: ("ImageDescription", ASCII, 1), + 271: ("Make", ASCII, 1), + 272: ("Model", ASCII, 1), + 273: ("StripOffsets", LONG, 0), + 274: ("Orientation", SHORT, 1), + 277: ("SamplesPerPixel", SHORT, 1), + 278: ("RowsPerStrip", LONG, 1), + 279: ("StripByteCounts", LONG, 0), + 280: ("MinSampleValue", SHORT, 0), + 281: ("MaxSampleValue", SHORT, 0), + 282: ("XResolution", RATIONAL, 1), + 283: ("YResolution", RATIONAL, 1), + 284: ("PlanarConfiguration", SHORT, 1, {"Contiguous": 1, "Separate": 2}), + 285: ("PageName", ASCII, 1), + 286: ("XPosition", RATIONAL, 1), + 287: ("YPosition", RATIONAL, 1), + 288: ("FreeOffsets", LONG, 1), + 289: ("FreeByteCounts", LONG, 1), + 290: ("GrayResponseUnit", SHORT, 1), + 291: ("GrayResponseCurve", SHORT, 0), + 292: ("T4Options", LONG, 1), + 293: ("T6Options", LONG, 1), + 296: ("ResolutionUnit", SHORT, 1, {"none": 1, "inch": 2, "cm": 3}), + 297: ("PageNumber", SHORT, 2), + 301: ("TransferFunction", SHORT, 0), + 305: ("Software", ASCII, 1), + 306: ("DateTime", ASCII, 1), + 315: ("Artist", ASCII, 1), + 316: ("HostComputer", ASCII, 1), + 317: ("Predictor", SHORT, 1, {"none": 1, "Horizontal Differencing": 2}), + 318: ("WhitePoint", RATIONAL, 2), + 319: ("PrimaryChromaticities", RATIONAL, 6), + 320: ("ColorMap", SHORT, 0), + 321: ("HalftoneHints", SHORT, 2), + 322: ("TileWidth", LONG, 1), + 323: ("TileLength", LONG, 1), + 324: ("TileOffsets", LONG, 0), + 325: ("TileByteCounts", LONG, 0), + 330: ("SubIFDs", LONG, 0), + 332: ("InkSet", SHORT, 1), + 333: ("InkNames", ASCII, 1), + 334: ("NumberOfInks", SHORT, 1), + 336: ("DotRange", SHORT, 0), + 337: ("TargetPrinter", ASCII, 1), + 338: ("ExtraSamples", SHORT, 0), + 339: ("SampleFormat", SHORT, 0), + 340: ("SMinSampleValue", DOUBLE, 0), + 341: ("SMaxSampleValue", DOUBLE, 0), + 342: ("TransferRange", SHORT, 6), + 347: ("JPEGTables", UNDEFINED, 1), + # obsolete JPEG tags + 512: ("JPEGProc", SHORT, 1), + 513: ("JPEGInterchangeFormat", LONG, 1), + 514: ("JPEGInterchangeFormatLength", LONG, 1), + 515: ("JPEGRestartInterval", SHORT, 1), + 517: ("JPEGLosslessPredictors", SHORT, 0), + 518: ("JPEGPointTransforms", SHORT, 0), + 519: ("JPEGQTables", LONG, 0), + 520: ("JPEGDCTables", LONG, 0), + 521: ("JPEGACTables", LONG, 0), + 529: ("YCbCrCoefficients", RATIONAL, 3), + 530: ("YCbCrSubSampling", SHORT, 2), + 531: ("YCbCrPositioning", SHORT, 1), + 532: ("ReferenceBlackWhite", RATIONAL, 6), + 700: ("XMP", BYTE, 0), + 33432: ("Copyright", ASCII, 1), + 33723: ("IptcNaaInfo", UNDEFINED, 1), + 34377: ("PhotoshopInfo", BYTE, 0), + # FIXME add more tags here + 34665: ("ExifIFD", LONG, 1), + 34675: ("ICCProfile", UNDEFINED, 1), + 34853: ("GPSInfoIFD", LONG, 1), + 36864: ("ExifVersion", UNDEFINED, 1), + 37724: ("ImageSourceData", UNDEFINED, 1), + 40965: ("InteroperabilityIFD", LONG, 1), + 41730: ("CFAPattern", UNDEFINED, 1), + # MPInfo + 45056: ("MPFVersion", UNDEFINED, 1), + 45057: ("NumberOfImages", LONG, 1), + 45058: ("MPEntry", UNDEFINED, 1), + 45059: ("ImageUIDList", UNDEFINED, 0), # UNDONE, check + 45060: ("TotalFrames", LONG, 1), + 45313: ("MPIndividualNum", LONG, 1), + 45569: ("PanOrientation", LONG, 1), + 45570: ("PanOverlap_H", RATIONAL, 1), + 45571: ("PanOverlap_V", RATIONAL, 1), + 45572: ("BaseViewpointNum", LONG, 1), + 45573: ("ConvergenceAngle", SIGNED_RATIONAL, 1), + 45574: ("BaselineLength", RATIONAL, 1), + 45575: ("VerticalDivergence", SIGNED_RATIONAL, 1), + 45576: ("AxisDistance_X", SIGNED_RATIONAL, 1), + 45577: ("AxisDistance_Y", SIGNED_RATIONAL, 1), + 45578: ("AxisDistance_Z", SIGNED_RATIONAL, 1), + 45579: ("YawAngle", SIGNED_RATIONAL, 1), + 45580: ("PitchAngle", SIGNED_RATIONAL, 1), + 45581: ("RollAngle", SIGNED_RATIONAL, 1), + 40960: ("FlashPixVersion", UNDEFINED, 1), + 50741: ("MakerNoteSafety", SHORT, 1, {"Unsafe": 0, "Safe": 1}), + 50780: ("BestQualityScale", RATIONAL, 1), + 50838: ("ImageJMetaDataByteCounts", LONG, 0), # Can be more than one + 50839: ("ImageJMetaData", UNDEFINED, 1), # see Issue #2006 +} +_tags_v2_groups = { + # ExifIFD + 34665: { + 36864: ("ExifVersion", UNDEFINED, 1), + 40960: ("FlashPixVersion", UNDEFINED, 1), + 40965: ("InteroperabilityIFD", LONG, 1), + 41730: ("CFAPattern", UNDEFINED, 1), + }, + # GPSInfoIFD + 34853: { + 0: ("GPSVersionID", BYTE, 4), + 1: ("GPSLatitudeRef", ASCII, 2), + 2: ("GPSLatitude", RATIONAL, 3), + 3: ("GPSLongitudeRef", ASCII, 2), + 4: ("GPSLongitude", RATIONAL, 3), + 5: ("GPSAltitudeRef", BYTE, 1), + 6: ("GPSAltitude", RATIONAL, 1), + 7: ("GPSTimeStamp", RATIONAL, 3), + 8: ("GPSSatellites", ASCII, 0), + 9: ("GPSStatus", ASCII, 2), + 10: ("GPSMeasureMode", ASCII, 2), + 11: ("GPSDOP", RATIONAL, 1), + 12: ("GPSSpeedRef", ASCII, 2), + 13: ("GPSSpeed", RATIONAL, 1), + 14: ("GPSTrackRef", ASCII, 2), + 15: ("GPSTrack", RATIONAL, 1), + 16: ("GPSImgDirectionRef", ASCII, 2), + 17: ("GPSImgDirection", RATIONAL, 1), + 18: ("GPSMapDatum", ASCII, 0), + 19: ("GPSDestLatitudeRef", ASCII, 2), + 20: ("GPSDestLatitude", RATIONAL, 3), + 21: ("GPSDestLongitudeRef", ASCII, 2), + 22: ("GPSDestLongitude", RATIONAL, 3), + 23: ("GPSDestBearingRef", ASCII, 2), + 24: ("GPSDestBearing", RATIONAL, 1), + 25: ("GPSDestDistanceRef", ASCII, 2), + 26: ("GPSDestDistance", RATIONAL, 1), + 27: ("GPSProcessingMethod", UNDEFINED, 0), + 28: ("GPSAreaInformation", UNDEFINED, 0), + 29: ("GPSDateStamp", ASCII, 11), + 30: ("GPSDifferential", SHORT, 1), + }, + # InteroperabilityIFD + 40965: {1: ("InteropIndex", ASCII, 1), 2: ("InteropVersion", UNDEFINED, 1)}, +} + +# Legacy Tags structure +# these tags aren't included above, but were in the previous versions +TAGS: dict[int | tuple[int, int], str] = { + 347: "JPEGTables", + 700: "XMP", + # Additional Exif Info + 32932: "Wang Annotation", + 33434: "ExposureTime", + 33437: "FNumber", + 33445: "MD FileTag", + 33446: "MD ScalePixel", + 33447: "MD ColorTable", + 33448: "MD LabName", + 33449: "MD SampleInfo", + 33450: "MD PrepDate", + 33451: "MD PrepTime", + 33452: "MD FileUnits", + 33550: "ModelPixelScaleTag", + 33723: "IptcNaaInfo", + 33918: "INGR Packet Data Tag", + 33919: "INGR Flag Registers", + 33920: "IrasB Transformation Matrix", + 33922: "ModelTiepointTag", + 34264: "ModelTransformationTag", + 34377: "PhotoshopInfo", + 34735: "GeoKeyDirectoryTag", + 34736: "GeoDoubleParamsTag", + 34737: "GeoAsciiParamsTag", + 34850: "ExposureProgram", + 34852: "SpectralSensitivity", + 34855: "ISOSpeedRatings", + 34856: "OECF", + 34864: "SensitivityType", + 34865: "StandardOutputSensitivity", + 34866: "RecommendedExposureIndex", + 34867: "ISOSpeed", + 34868: "ISOSpeedLatitudeyyy", + 34869: "ISOSpeedLatitudezzz", + 34908: "HylaFAX FaxRecvParams", + 34909: "HylaFAX FaxSubAddress", + 34910: "HylaFAX FaxRecvTime", + 36864: "ExifVersion", + 36867: "DateTimeOriginal", + 36868: "DateTimeDigitized", + 37121: "ComponentsConfiguration", + 37122: "CompressedBitsPerPixel", + 37724: "ImageSourceData", + 37377: "ShutterSpeedValue", + 37378: "ApertureValue", + 37379: "BrightnessValue", + 37380: "ExposureBiasValue", + 37381: "MaxApertureValue", + 37382: "SubjectDistance", + 37383: "MeteringMode", + 37384: "LightSource", + 37385: "Flash", + 37386: "FocalLength", + 37396: "SubjectArea", + 37500: "MakerNote", + 37510: "UserComment", + 37520: "SubSec", + 37521: "SubSecTimeOriginal", + 37522: "SubsecTimeDigitized", + 40960: "FlashPixVersion", + 40961: "ColorSpace", + 40962: "PixelXDimension", + 40963: "PixelYDimension", + 40964: "RelatedSoundFile", + 40965: "InteroperabilityIFD", + 41483: "FlashEnergy", + 41484: "SpatialFrequencyResponse", + 41486: "FocalPlaneXResolution", + 41487: "FocalPlaneYResolution", + 41488: "FocalPlaneResolutionUnit", + 41492: "SubjectLocation", + 41493: "ExposureIndex", + 41495: "SensingMethod", + 41728: "FileSource", + 41729: "SceneType", + 41730: "CFAPattern", + 41985: "CustomRendered", + 41986: "ExposureMode", + 41987: "WhiteBalance", + 41988: "DigitalZoomRatio", + 41989: "FocalLengthIn35mmFilm", + 41990: "SceneCaptureType", + 41991: "GainControl", + 41992: "Contrast", + 41993: "Saturation", + 41994: "Sharpness", + 41995: "DeviceSettingDescription", + 41996: "SubjectDistanceRange", + 42016: "ImageUniqueID", + 42032: "CameraOwnerName", + 42033: "BodySerialNumber", + 42034: "LensSpecification", + 42035: "LensMake", + 42036: "LensModel", + 42037: "LensSerialNumber", + 42112: "GDAL_METADATA", + 42113: "GDAL_NODATA", + 42240: "Gamma", + 50215: "Oce Scanjob Description", + 50216: "Oce Application Selector", + 50217: "Oce Identification Number", + 50218: "Oce ImageLogic Characteristics", + # Adobe DNG + 50706: "DNGVersion", + 50707: "DNGBackwardVersion", + 50708: "UniqueCameraModel", + 50709: "LocalizedCameraModel", + 50710: "CFAPlaneColor", + 50711: "CFALayout", + 50712: "LinearizationTable", + 50713: "BlackLevelRepeatDim", + 50714: "BlackLevel", + 50715: "BlackLevelDeltaH", + 50716: "BlackLevelDeltaV", + 50717: "WhiteLevel", + 50718: "DefaultScale", + 50719: "DefaultCropOrigin", + 50720: "DefaultCropSize", + 50721: "ColorMatrix1", + 50722: "ColorMatrix2", + 50723: "CameraCalibration1", + 50724: "CameraCalibration2", + 50725: "ReductionMatrix1", + 50726: "ReductionMatrix2", + 50727: "AnalogBalance", + 50728: "AsShotNeutral", + 50729: "AsShotWhiteXY", + 50730: "BaselineExposure", + 50731: "BaselineNoise", + 50732: "BaselineSharpness", + 50733: "BayerGreenSplit", + 50734: "LinearResponseLimit", + 50735: "CameraSerialNumber", + 50736: "LensInfo", + 50737: "ChromaBlurRadius", + 50738: "AntiAliasStrength", + 50740: "DNGPrivateData", + 50778: "CalibrationIlluminant1", + 50779: "CalibrationIlluminant2", + 50784: "Alias Layer Metadata", +} + +TAGS_V2: dict[int, TagInfo] = {} +TAGS_V2_GROUPS: dict[int, dict[int, TagInfo]] = {} + + +def _populate() -> None: + for k, v in _tags_v2.items(): + # Populate legacy structure. + TAGS[k] = v[0] + if len(v) == 4: + for sk, sv in v[3].items(): + TAGS[(k, sv)] = sk + + TAGS_V2[k] = TagInfo(k, *v) + + for group, tags in _tags_v2_groups.items(): + TAGS_V2_GROUPS[group] = {k: TagInfo(k, *v) for k, v in tags.items()} + + +_populate() +## +# Map type numbers to type names -- defined in ImageFileDirectory. + +TYPES: dict[int, str] = {} + +# +# These tags are handled by default in libtiff, without +# adding to the custom dictionary. From tif_dir.c, searching for +# case TIFFTAG in the _TIFFVSetField function: +# Line: item. +# 148: case TIFFTAG_SUBFILETYPE: +# 151: case TIFFTAG_IMAGEWIDTH: +# 154: case TIFFTAG_IMAGELENGTH: +# 157: case TIFFTAG_BITSPERSAMPLE: +# 181: case TIFFTAG_COMPRESSION: +# 202: case TIFFTAG_PHOTOMETRIC: +# 205: case TIFFTAG_THRESHHOLDING: +# 208: case TIFFTAG_FILLORDER: +# 214: case TIFFTAG_ORIENTATION: +# 221: case TIFFTAG_SAMPLESPERPIXEL: +# 228: case TIFFTAG_ROWSPERSTRIP: +# 238: case TIFFTAG_MINSAMPLEVALUE: +# 241: case TIFFTAG_MAXSAMPLEVALUE: +# 244: case TIFFTAG_SMINSAMPLEVALUE: +# 247: case TIFFTAG_SMAXSAMPLEVALUE: +# 250: case TIFFTAG_XRESOLUTION: +# 256: case TIFFTAG_YRESOLUTION: +# 262: case TIFFTAG_PLANARCONFIG: +# 268: case TIFFTAG_XPOSITION: +# 271: case TIFFTAG_YPOSITION: +# 274: case TIFFTAG_RESOLUTIONUNIT: +# 280: case TIFFTAG_PAGENUMBER: +# 284: case TIFFTAG_HALFTONEHINTS: +# 288: case TIFFTAG_COLORMAP: +# 294: case TIFFTAG_EXTRASAMPLES: +# 298: case TIFFTAG_MATTEING: +# 305: case TIFFTAG_TILEWIDTH: +# 316: case TIFFTAG_TILELENGTH: +# 327: case TIFFTAG_TILEDEPTH: +# 333: case TIFFTAG_DATATYPE: +# 344: case TIFFTAG_SAMPLEFORMAT: +# 361: case TIFFTAG_IMAGEDEPTH: +# 364: case TIFFTAG_SUBIFD: +# 376: case TIFFTAG_YCBCRPOSITIONING: +# 379: case TIFFTAG_YCBCRSUBSAMPLING: +# 383: case TIFFTAG_TRANSFERFUNCTION: +# 389: case TIFFTAG_REFERENCEBLACKWHITE: +# 393: case TIFFTAG_INKNAMES: + +# Following pseudo-tags are also handled by default in libtiff: +# TIFFTAG_JPEGQUALITY 65537 + +# some of these are not in our TAGS_V2 dict and were included from tiff.h + +# This list also exists in encode.c +LIBTIFF_CORE = { + 255, + 256, + 257, + 258, + 259, + 262, + 263, + 266, + 274, + 277, + 278, + 280, + 281, + 340, + 341, + 282, + 283, + 284, + 286, + 287, + 296, + 297, + 321, + 320, + 338, + 32995, + 322, + 323, + 32998, + 32996, + 339, + 32997, + 330, + 531, + 530, + 301, + 532, + 333, + # as above + 269, # this has been in our tests forever, and works + 65537, +} + +LIBTIFF_CORE.remove(255) # We don't have support for subfiletypes +LIBTIFF_CORE.remove(322) # We don't have support for writing tiled images with libtiff +LIBTIFF_CORE.remove(323) # Tiled images +LIBTIFF_CORE.remove(333) # Ink Names either + +# Note to advanced users: There may be combinations of these +# parameters and values that when added properly, will work and +# produce valid tiff images that may work in your application. +# It is safe to add and remove tags from this set from Pillow's point +# of view so long as you test against libtiff. diff --git a/venv/lib/python3.12/site-packages/PIL/WalImageFile.py b/venv/lib/python3.12/site-packages/PIL/WalImageFile.py new file mode 100644 index 0000000..87e3287 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/WalImageFile.py @@ -0,0 +1,127 @@ +# +# The Python Imaging Library. +# $Id$ +# +# WAL file handling +# +# History: +# 2003-04-23 fl created +# +# Copyright (c) 2003 by Fredrik Lundh. +# +# See the README file for information on usage and redistribution. +# + +""" +This reader is based on the specification available from: +https://www.flipcode.com/archives/Quake_2_BSP_File_Format.shtml +and has been tested with a few sample files found using google. + +.. note:: + This format cannot be automatically recognized, so the reader + is not registered for use with :py:func:`PIL.Image.open()`. + To open a WAL file, use the :py:func:`PIL.WalImageFile.open()` function instead. +""" +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile +from ._binary import i32le as i32 +from ._typing import StrOrBytesPath + + +class WalImageFile(ImageFile.ImageFile): + format = "WAL" + format_description = "Quake2 Texture" + + def _open(self) -> None: + self._mode = "P" + + # read header fields + header = self.fp.read(32 + 24 + 32 + 12) + self._size = i32(header, 32), i32(header, 36) + Image._decompression_bomb_check(self.size) + + # load pixel data + offset = i32(header, 40) + self.fp.seek(offset) + + # strings are null-terminated + self.info["name"] = header[:32].split(b"\0", 1)[0] + next_name = header[56 : 56 + 32].split(b"\0", 1)[0] + if next_name: + self.info["next_name"] = next_name + + def load(self) -> Image.core.PixelAccess | None: + if self._im is None: + self.im = Image.core.new(self.mode, self.size) + self.frombytes(self.fp.read(self.size[0] * self.size[1])) + self.putpalette(quake2palette) + return Image.Image.load(self) + + +def open(filename: StrOrBytesPath | IO[bytes]) -> WalImageFile: + """ + Load texture from a Quake2 WAL texture file. + + By default, a Quake2 standard palette is attached to the texture. + To override the palette, use the :py:func:`PIL.Image.Image.putpalette()` method. + + :param filename: WAL file name, or an opened file handle. + :returns: An image instance. + """ + return WalImageFile(filename) + + +quake2palette = ( + # default palette taken from piffo 0.93 by Hans Häggström + b"\x01\x01\x01\x0b\x0b\x0b\x12\x12\x12\x17\x17\x17\x1b\x1b\x1b\x1e" + b"\x1e\x1e\x22\x22\x22\x26\x26\x26\x29\x29\x29\x2c\x2c\x2c\x2f\x2f" + b"\x2f\x32\x32\x32\x35\x35\x35\x37\x37\x37\x3a\x3a\x3a\x3c\x3c\x3c" + b"\x24\x1e\x13\x22\x1c\x12\x20\x1b\x12\x1f\x1a\x10\x1d\x19\x10\x1b" + b"\x17\x0f\x1a\x16\x0f\x18\x14\x0d\x17\x13\x0d\x16\x12\x0d\x14\x10" + b"\x0b\x13\x0f\x0b\x10\x0d\x0a\x0f\x0b\x0a\x0d\x0b\x07\x0b\x0a\x07" + b"\x23\x23\x26\x22\x22\x25\x22\x20\x23\x21\x1f\x22\x20\x1e\x20\x1f" + b"\x1d\x1e\x1d\x1b\x1c\x1b\x1a\x1a\x1a\x19\x19\x18\x17\x17\x17\x16" + b"\x16\x14\x14\x14\x13\x13\x13\x10\x10\x10\x0f\x0f\x0f\x0d\x0d\x0d" + b"\x2d\x28\x20\x29\x24\x1c\x27\x22\x1a\x25\x1f\x17\x38\x2e\x1e\x31" + b"\x29\x1a\x2c\x25\x17\x26\x20\x14\x3c\x30\x14\x37\x2c\x13\x33\x28" + b"\x12\x2d\x24\x10\x28\x1f\x0f\x22\x1a\x0b\x1b\x14\x0a\x13\x0f\x07" + b"\x31\x1a\x16\x30\x17\x13\x2e\x16\x10\x2c\x14\x0d\x2a\x12\x0b\x27" + b"\x0f\x0a\x25\x0f\x07\x21\x0d\x01\x1e\x0b\x01\x1c\x0b\x01\x1a\x0b" + b"\x01\x18\x0a\x01\x16\x0a\x01\x13\x0a\x01\x10\x07\x01\x0d\x07\x01" + b"\x29\x23\x1e\x27\x21\x1c\x26\x20\x1b\x25\x1f\x1a\x23\x1d\x19\x21" + b"\x1c\x18\x20\x1b\x17\x1e\x19\x16\x1c\x18\x14\x1b\x17\x13\x19\x14" + b"\x10\x17\x13\x0f\x14\x10\x0d\x12\x0f\x0b\x0f\x0b\x0a\x0b\x0a\x07" + b"\x26\x1a\x0f\x23\x19\x0f\x20\x17\x0f\x1c\x16\x0f\x19\x13\x0d\x14" + b"\x10\x0b\x10\x0d\x0a\x0b\x0a\x07\x33\x22\x1f\x35\x29\x26\x37\x2f" + b"\x2d\x39\x35\x34\x37\x39\x3a\x33\x37\x39\x30\x34\x36\x2b\x31\x34" + b"\x27\x2e\x31\x22\x2b\x2f\x1d\x28\x2c\x17\x25\x2a\x0f\x20\x26\x0d" + b"\x1e\x25\x0b\x1c\x22\x0a\x1b\x20\x07\x19\x1e\x07\x17\x1b\x07\x14" + b"\x18\x01\x12\x16\x01\x0f\x12\x01\x0b\x0d\x01\x07\x0a\x01\x01\x01" + b"\x2c\x21\x21\x2a\x1f\x1f\x29\x1d\x1d\x27\x1c\x1c\x26\x1a\x1a\x24" + b"\x18\x18\x22\x17\x17\x21\x16\x16\x1e\x13\x13\x1b\x12\x12\x18\x10" + b"\x10\x16\x0d\x0d\x12\x0b\x0b\x0d\x0a\x0a\x0a\x07\x07\x01\x01\x01" + b"\x2e\x30\x29\x2d\x2e\x27\x2b\x2c\x26\x2a\x2a\x24\x28\x29\x23\x27" + b"\x27\x21\x26\x26\x1f\x24\x24\x1d\x22\x22\x1c\x1f\x1f\x1a\x1c\x1c" + b"\x18\x19\x19\x16\x17\x17\x13\x13\x13\x10\x0f\x0f\x0d\x0b\x0b\x0a" + b"\x30\x1e\x1b\x2d\x1c\x19\x2c\x1a\x17\x2a\x19\x14\x28\x17\x13\x26" + b"\x16\x10\x24\x13\x0f\x21\x12\x0d\x1f\x10\x0b\x1c\x0f\x0a\x19\x0d" + b"\x0a\x16\x0b\x07\x12\x0a\x07\x0f\x07\x01\x0a\x01\x01\x01\x01\x01" + b"\x28\x29\x38\x26\x27\x36\x25\x26\x34\x24\x24\x31\x22\x22\x2f\x20" + b"\x21\x2d\x1e\x1f\x2a\x1d\x1d\x27\x1b\x1b\x25\x19\x19\x21\x17\x17" + b"\x1e\x14\x14\x1b\x13\x12\x17\x10\x0f\x13\x0d\x0b\x0f\x0a\x07\x07" + b"\x2f\x32\x29\x2d\x30\x26\x2b\x2e\x24\x29\x2c\x21\x27\x2a\x1e\x25" + b"\x28\x1c\x23\x26\x1a\x21\x25\x18\x1e\x22\x14\x1b\x1f\x10\x19\x1c" + b"\x0d\x17\x1a\x0a\x13\x17\x07\x10\x13\x01\x0d\x0f\x01\x0a\x0b\x01" + b"\x01\x3f\x01\x13\x3c\x0b\x1b\x39\x10\x20\x35\x14\x23\x31\x17\x23" + b"\x2d\x18\x23\x29\x18\x3f\x3f\x3f\x3f\x3f\x39\x3f\x3f\x31\x3f\x3f" + b"\x2a\x3f\x3f\x20\x3f\x3f\x14\x3f\x3c\x12\x3f\x39\x0f\x3f\x35\x0b" + b"\x3f\x32\x07\x3f\x2d\x01\x3d\x2a\x01\x3b\x26\x01\x39\x21\x01\x37" + b"\x1d\x01\x34\x1a\x01\x32\x16\x01\x2f\x12\x01\x2d\x0f\x01\x2a\x0b" + b"\x01\x27\x07\x01\x23\x01\x01\x1d\x01\x01\x17\x01\x01\x10\x01\x01" + b"\x3d\x01\x01\x19\x19\x3f\x3f\x01\x01\x01\x01\x3f\x16\x16\x13\x10" + b"\x10\x0f\x0d\x0d\x0b\x3c\x2e\x2a\x36\x27\x20\x30\x21\x18\x29\x1b" + b"\x10\x3c\x39\x37\x37\x32\x2f\x31\x2c\x28\x2b\x26\x21\x30\x22\x20" +) diff --git a/venv/lib/python3.12/site-packages/PIL/WebPImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/WebPImagePlugin.py new file mode 100644 index 0000000..64188f2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/WebPImagePlugin.py @@ -0,0 +1,323 @@ +from __future__ import annotations + +from io import BytesIO +from typing import IO, Any + +from . import Image, ImageFile + +try: + from . import _webp + + SUPPORTED = True +except ImportError: + SUPPORTED = False + + +_VP8_MODES_BY_IDENTIFIER = { + b"VP8 ": "RGB", + b"VP8X": "RGBA", + b"VP8L": "RGBA", # lossless +} + + +def _accept(prefix: bytes) -> bool | str: + is_riff_file_format = prefix[:4] == b"RIFF" + is_webp_file = prefix[8:12] == b"WEBP" + is_valid_vp8_mode = prefix[12:16] in _VP8_MODES_BY_IDENTIFIER + + if is_riff_file_format and is_webp_file and is_valid_vp8_mode: + if not SUPPORTED: + return ( + "image file could not be identified because WEBP support not installed" + ) + return True + return False + + +class WebPImageFile(ImageFile.ImageFile): + format = "WEBP" + format_description = "WebP image" + __loaded = 0 + __logical_frame = 0 + + def _open(self) -> None: + # Use the newer AnimDecoder API to parse the (possibly) animated file, + # and access muxed chunks like ICC/EXIF/XMP. + self._decoder = _webp.WebPAnimDecoder(self.fp.read()) + + # Get info from decoder + width, height, loop_count, bgcolor, frame_count, mode = self._decoder.get_info() + self._size = width, height + self.info["loop"] = loop_count + bg_a, bg_r, bg_g, bg_b = ( + (bgcolor >> 24) & 0xFF, + (bgcolor >> 16) & 0xFF, + (bgcolor >> 8) & 0xFF, + bgcolor & 0xFF, + ) + self.info["background"] = (bg_r, bg_g, bg_b, bg_a) + self.n_frames = frame_count + self.is_animated = self.n_frames > 1 + self._mode = "RGB" if mode == "RGBX" else mode + self.rawmode = mode + self.tile = [] + + # Attempt to read ICC / EXIF / XMP chunks from file + icc_profile = self._decoder.get_chunk("ICCP") + exif = self._decoder.get_chunk("EXIF") + xmp = self._decoder.get_chunk("XMP ") + if icc_profile: + self.info["icc_profile"] = icc_profile + if exif: + self.info["exif"] = exif + if xmp: + self.info["xmp"] = xmp + + # Initialize seek state + self._reset(reset=False) + + def _getexif(self) -> dict[int, Any] | None: + if "exif" not in self.info: + return None + return self.getexif()._get_merged_dict() + + def seek(self, frame: int) -> None: + if not self._seek_check(frame): + return + + # Set logical frame to requested position + self.__logical_frame = frame + + def _reset(self, reset: bool = True) -> None: + if reset: + self._decoder.reset() + self.__physical_frame = 0 + self.__loaded = -1 + self.__timestamp = 0 + + def _get_next(self) -> tuple[bytes, int, int]: + # Get next frame + ret = self._decoder.get_next() + self.__physical_frame += 1 + + # Check if an error occurred + if ret is None: + self._reset() # Reset just to be safe + self.seek(0) + msg = "failed to decode next frame in WebP file" + raise EOFError(msg) + + # Compute duration + data, timestamp = ret + duration = timestamp - self.__timestamp + self.__timestamp = timestamp + + # libwebp gives frame end, adjust to start of frame + timestamp -= duration + return data, timestamp, duration + + def _seek(self, frame: int) -> None: + if self.__physical_frame == frame: + return # Nothing to do + if frame < self.__physical_frame: + self._reset() # Rewind to beginning + while self.__physical_frame < frame: + self._get_next() # Advance to the requested frame + + def load(self) -> Image.core.PixelAccess | None: + if self.__loaded != self.__logical_frame: + self._seek(self.__logical_frame) + + # We need to load the image data for this frame + data, timestamp, duration = self._get_next() + self.info["timestamp"] = timestamp + self.info["duration"] = duration + self.__loaded = self.__logical_frame + + # Set tile + if self.fp and self._exclusive_fp: + self.fp.close() + self.fp = BytesIO(data) + self.tile = [ImageFile._Tile("raw", (0, 0) + self.size, 0, self.rawmode)] + + return super().load() + + def load_seek(self, pos: int) -> None: + pass + + def tell(self) -> int: + return self.__logical_frame + + +def _convert_frame(im: Image.Image) -> Image.Image: + # Make sure image mode is supported + if im.mode not in ("RGBX", "RGBA", "RGB"): + im = im.convert("RGBA" if im.has_transparency_data else "RGB") + return im + + +def _save_all(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + encoderinfo = im.encoderinfo.copy() + append_images = list(encoderinfo.get("append_images", [])) + + # If total frame count is 1, then save using the legacy API, which + # will preserve non-alpha modes + total = 0 + for ims in [im] + append_images: + total += getattr(ims, "n_frames", 1) + if total == 1: + _save(im, fp, filename) + return + + background: int | tuple[int, ...] = (0, 0, 0, 0) + if "background" in encoderinfo: + background = encoderinfo["background"] + elif "background" in im.info: + background = im.info["background"] + if isinstance(background, int): + # GifImagePlugin stores a global color table index in + # info["background"]. So it must be converted to an RGBA value + palette = im.getpalette() + if palette: + r, g, b = palette[background * 3 : (background + 1) * 3] + background = (r, g, b, 255) + else: + background = (background, background, background, 255) + + duration = im.encoderinfo.get("duration", im.info.get("duration", 0)) + loop = im.encoderinfo.get("loop", 0) + minimize_size = im.encoderinfo.get("minimize_size", False) + kmin = im.encoderinfo.get("kmin", None) + kmax = im.encoderinfo.get("kmax", None) + allow_mixed = im.encoderinfo.get("allow_mixed", False) + verbose = False + lossless = im.encoderinfo.get("lossless", False) + quality = im.encoderinfo.get("quality", 80) + alpha_quality = im.encoderinfo.get("alpha_quality", 100) + method = im.encoderinfo.get("method", 0) + icc_profile = im.encoderinfo.get("icc_profile") or "" + exif = im.encoderinfo.get("exif", "") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + xmp = im.encoderinfo.get("xmp", "") + if allow_mixed: + lossless = False + + # Sensible keyframe defaults are from gif2webp.c script + if kmin is None: + kmin = 9 if lossless else 3 + if kmax is None: + kmax = 17 if lossless else 5 + + # Validate background color + if ( + not isinstance(background, (list, tuple)) + or len(background) != 4 + or not all(0 <= v < 256 for v in background) + ): + msg = f"Background color is not an RGBA tuple clamped to (0-255): {background}" + raise OSError(msg) + + # Convert to packed uint + bg_r, bg_g, bg_b, bg_a = background + background = (bg_a << 24) | (bg_r << 16) | (bg_g << 8) | (bg_b << 0) + + # Setup the WebP animation encoder + enc = _webp.WebPAnimEncoder( + im.size[0], + im.size[1], + background, + loop, + minimize_size, + kmin, + kmax, + allow_mixed, + verbose, + ) + + # Add each frame + frame_idx = 0 + timestamp = 0 + cur_idx = im.tell() + try: + for ims in [im] + append_images: + # Get # of frames in this image + nfr = getattr(ims, "n_frames", 1) + + for idx in range(nfr): + ims.seek(idx) + + frame = _convert_frame(ims) + + # Append the frame to the animation encoder + enc.add( + frame.getim(), + round(timestamp), + lossless, + quality, + alpha_quality, + method, + ) + + # Update timestamp and frame index + if isinstance(duration, (list, tuple)): + timestamp += duration[frame_idx] + else: + timestamp += duration + frame_idx += 1 + + finally: + im.seek(cur_idx) + + # Force encoder to flush frames + enc.add(None, round(timestamp), lossless, quality, alpha_quality, 0) + + # Get the final output from the encoder + data = enc.assemble(icc_profile, exif, xmp) + if data is None: + msg = "cannot write file as WebP (encoder returned None)" + raise OSError(msg) + + fp.write(data) + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + lossless = im.encoderinfo.get("lossless", False) + quality = im.encoderinfo.get("quality", 80) + alpha_quality = im.encoderinfo.get("alpha_quality", 100) + icc_profile = im.encoderinfo.get("icc_profile") or "" + exif = im.encoderinfo.get("exif", b"") + if isinstance(exif, Image.Exif): + exif = exif.tobytes() + if exif.startswith(b"Exif\x00\x00"): + exif = exif[6:] + xmp = im.encoderinfo.get("xmp", "") + method = im.encoderinfo.get("method", 4) + exact = 1 if im.encoderinfo.get("exact") else 0 + + im = _convert_frame(im) + + data = _webp.WebPEncode( + im.getim(), + lossless, + float(quality), + float(alpha_quality), + icc_profile, + method, + exact, + exif, + xmp, + ) + if data is None: + msg = "cannot write file as WebP (encoder returned None)" + raise OSError(msg) + + fp.write(data) + + +Image.register_open(WebPImageFile.format, WebPImageFile, _accept) +if SUPPORTED: + Image.register_save(WebPImageFile.format, _save) + Image.register_save_all(WebPImageFile.format, _save_all) + Image.register_extension(WebPImageFile.format, ".webp") + Image.register_mime(WebPImageFile.format, "image/webp") diff --git a/venv/lib/python3.12/site-packages/PIL/WmfImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/WmfImagePlugin.py new file mode 100644 index 0000000..68f8a74 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/WmfImagePlugin.py @@ -0,0 +1,181 @@ +# +# The Python Imaging Library +# $Id$ +# +# WMF stub codec +# +# history: +# 1996-12-14 fl Created +# 2004-02-22 fl Turned into a stub driver +# 2004-02-23 fl Added EMF support +# +# Copyright (c) Secret Labs AB 1997-2004. All rights reserved. +# Copyright (c) Fredrik Lundh 1996. +# +# See the README file for information on usage and redistribution. +# +# WMF/EMF reference documentation: +# https://winprotocoldoc.blob.core.windows.net/productionwindowsarchives/MS-WMF/[MS-WMF].pdf +# http://wvware.sourceforge.net/caolan/index.html +# http://wvware.sourceforge.net/caolan/ora-wmf.html +from __future__ import annotations + +from typing import IO + +from . import Image, ImageFile +from ._binary import i16le as word +from ._binary import si16le as short +from ._binary import si32le as _long + +_handler = None + + +def register_handler(handler: ImageFile.StubHandler | None) -> None: + """ + Install application-specific WMF image handler. + + :param handler: Handler object. + """ + global _handler + _handler = handler + + +if hasattr(Image.core, "drawwmf"): + # install default handler (windows only) + + class WmfHandler(ImageFile.StubHandler): + def open(self, im: ImageFile.StubImageFile) -> None: + im._mode = "RGB" + self.bbox = im.info["wmf_bbox"] + + def load(self, im: ImageFile.StubImageFile) -> Image.Image: + im.fp.seek(0) # rewind + return Image.frombytes( + "RGB", + im.size, + Image.core.drawwmf(im.fp.read(), im.size, self.bbox), + "raw", + "BGR", + (im.size[0] * 3 + 3) & -4, + -1, + ) + + register_handler(WmfHandler()) + +# +# -------------------------------------------------------------------- +# Read WMF file + + +def _accept(prefix: bytes) -> bool: + return ( + prefix[:6] == b"\xd7\xcd\xc6\x9a\x00\x00" or prefix[:4] == b"\x01\x00\x00\x00" + ) + + +## +# Image plugin for Windows metafiles. + + +class WmfStubImageFile(ImageFile.StubImageFile): + format = "WMF" + format_description = "Windows Metafile" + + def _open(self) -> None: + self._inch = None + + # check placable header + s = self.fp.read(80) + + if s[:6] == b"\xd7\xcd\xc6\x9a\x00\x00": + # placeable windows metafile + + # get units per inch + self._inch = word(s, 14) + + # get bounding box + x0 = short(s, 6) + y0 = short(s, 8) + x1 = short(s, 10) + y1 = short(s, 12) + + # normalize size to 72 dots per inch + self.info["dpi"] = 72 + size = ( + (x1 - x0) * self.info["dpi"] // self._inch, + (y1 - y0) * self.info["dpi"] // self._inch, + ) + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + # sanity check (standard metafile header) + if s[22:26] != b"\x01\x00\t\x00": + msg = "Unsupported WMF file format" + raise SyntaxError(msg) + + elif s[:4] == b"\x01\x00\x00\x00" and s[40:44] == b" EMF": + # enhanced metafile + + # get bounding box + x0 = _long(s, 8) + y0 = _long(s, 12) + x1 = _long(s, 16) + y1 = _long(s, 20) + + # get frame (in 0.01 millimeter units) + frame = _long(s, 24), _long(s, 28), _long(s, 32), _long(s, 36) + + size = x1 - x0, y1 - y0 + + # calculate dots per inch from bbox and frame + xdpi = 2540.0 * (x1 - y0) / (frame[2] - frame[0]) + ydpi = 2540.0 * (y1 - y0) / (frame[3] - frame[1]) + + self.info["wmf_bbox"] = x0, y0, x1, y1 + + if xdpi == ydpi: + self.info["dpi"] = xdpi + else: + self.info["dpi"] = xdpi, ydpi + + else: + msg = "Unsupported file format" + raise SyntaxError(msg) + + self._mode = "RGB" + self._size = size + + loader = self._load() + if loader: + loader.open(self) + + def _load(self) -> ImageFile.StubHandler | None: + return _handler + + def load(self, dpi: int | None = None) -> Image.core.PixelAccess | None: + if dpi is not None and self._inch is not None: + self.info["dpi"] = dpi + x0, y0, x1, y1 = self.info["wmf_bbox"] + self._size = ( + (x1 - x0) * self.info["dpi"] // self._inch, + (y1 - y0) * self.info["dpi"] // self._inch, + ) + return super().load() + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if _handler is None or not hasattr(_handler, "save"): + msg = "WMF save handler not installed" + raise OSError(msg) + _handler.save(im, fp, filename) + + +# +# -------------------------------------------------------------------- +# Registry stuff + + +Image.register_open(WmfStubImageFile.format, WmfStubImageFile, _accept) +Image.register_save(WmfStubImageFile.format, _save) + +Image.register_extensions(WmfStubImageFile.format, [".wmf", ".emf"]) diff --git a/venv/lib/python3.12/site-packages/PIL/XVThumbImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/XVThumbImagePlugin.py new file mode 100644 index 0000000..5d1f201 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/XVThumbImagePlugin.py @@ -0,0 +1,85 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XV Thumbnail file handler by Charles E. "Gene" Cash +# (gcash@magicnet.net) +# +# see xvcolor.c and xvbrowse.c in the sources to John Bradley's XV, +# available from ftp://ftp.cis.upenn.edu/pub/xv/ +# +# history: +# 98-08-15 cec created (b/w only) +# 98-12-09 cec added color palette +# 98-12-28 fl added to PIL (with only a few very minor modifications) +# +# To do: +# FIXME: make save work (this requires quantization support) +# +from __future__ import annotations + +from . import Image, ImageFile, ImagePalette +from ._binary import o8 + +_MAGIC = b"P7 332" + +# standard color palette for thumbnails (RGB332) +PALETTE = b"" +for r in range(8): + for g in range(8): + for b in range(4): + PALETTE = PALETTE + ( + o8((r * 255) // 7) + o8((g * 255) // 7) + o8((b * 255) // 3) + ) + + +def _accept(prefix: bytes) -> bool: + return prefix[:6] == _MAGIC + + +## +# Image plugin for XV thumbnail images. + + +class XVThumbImageFile(ImageFile.ImageFile): + format = "XVThumb" + format_description = "XV thumbnail image" + + def _open(self) -> None: + # check magic + assert self.fp is not None + + if not _accept(self.fp.read(6)): + msg = "not an XV thumbnail file" + raise SyntaxError(msg) + + # Skip to beginning of next line + self.fp.readline() + + # skip info comments + while True: + s = self.fp.readline() + if not s: + msg = "Unexpected EOF reading XV thumbnail file" + raise SyntaxError(msg) + if s[0] != 35: # ie. when not a comment: '#' + break + + # parse header line (already read) + s = s.strip().split() + + self._mode = "P" + self._size = int(s[0]), int(s[1]) + + self.palette = ImagePalette.raw("RGB", PALETTE) + + self.tile = [ + ImageFile._Tile( + "raw", (0, 0) + self.size, self.fp.tell(), (self.mode, 0, 1) + ) + ] + + +# -------------------------------------------------------------------- + +Image.register_open(XVThumbImageFile.format, XVThumbImageFile, _accept) diff --git a/venv/lib/python3.12/site-packages/PIL/XbmImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/XbmImagePlugin.py new file mode 100644 index 0000000..f3d490a --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/XbmImagePlugin.py @@ -0,0 +1,98 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XBM File handling +# +# History: +# 1995-09-08 fl Created +# 1996-11-01 fl Added save support +# 1997-07-07 fl Made header parser more tolerant +# 1997-07-22 fl Fixed yet another parser bug +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.4) +# 2001-05-13 fl Added hotspot handling (based on code from Bernhard Herzog) +# 2004-02-24 fl Allow some whitespace before first #define +# +# Copyright (c) 1997-2004 by Secret Labs AB +# Copyright (c) 1996-1997 by Fredrik Lundh +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re +from typing import IO + +from . import Image, ImageFile + +# XBM header +xbm_head = re.compile( + rb"\s*#define[ \t]+.*_width[ \t]+(?P[0-9]+)[\r\n]+" + b"#define[ \t]+.*_height[ \t]+(?P[0-9]+)[\r\n]+" + b"(?P" + b"#define[ \t]+[^_]*_x_hot[ \t]+(?P[0-9]+)[\r\n]+" + b"#define[ \t]+[^_]*_y_hot[ \t]+(?P[0-9]+)[\r\n]+" + b")?" + rb"[\000-\377]*_bits\[]" +) + + +def _accept(prefix: bytes) -> bool: + return prefix.lstrip()[:7] == b"#define" + + +## +# Image plugin for X11 bitmaps. + + +class XbmImageFile(ImageFile.ImageFile): + format = "XBM" + format_description = "X11 Bitmap" + + def _open(self) -> None: + assert self.fp is not None + + m = xbm_head.match(self.fp.read(512)) + + if not m: + msg = "not a XBM file" + raise SyntaxError(msg) + + xsize = int(m.group("width")) + ysize = int(m.group("height")) + + if m.group("hotspot"): + self.info["hotspot"] = (int(m.group("xhot")), int(m.group("yhot"))) + + self._mode = "1" + self._size = xsize, ysize + + self.tile = [ImageFile._Tile("xbm", (0, 0) + self.size, m.end(), None)] + + +def _save(im: Image.Image, fp: IO[bytes], filename: str | bytes) -> None: + if im.mode != "1": + msg = f"cannot write mode {im.mode} as XBM" + raise OSError(msg) + + fp.write(f"#define im_width {im.size[0]}\n".encode("ascii")) + fp.write(f"#define im_height {im.size[1]}\n".encode("ascii")) + + hotspot = im.encoderinfo.get("hotspot") + if hotspot: + fp.write(f"#define im_x_hot {hotspot[0]}\n".encode("ascii")) + fp.write(f"#define im_y_hot {hotspot[1]}\n".encode("ascii")) + + fp.write(b"static char im_bits[] = {\n") + + ImageFile._save(im, fp, [ImageFile._Tile("xbm", (0, 0) + im.size, 0, None)]) + + fp.write(b"};\n") + + +Image.register_open(XbmImageFile.format, XbmImageFile, _accept) +Image.register_save(XbmImageFile.format, _save) + +Image.register_extension(XbmImageFile.format, ".xbm") + +Image.register_mime(XbmImageFile.format, "image/xbm") diff --git a/venv/lib/python3.12/site-packages/PIL/XpmImagePlugin.py b/venv/lib/python3.12/site-packages/PIL/XpmImagePlugin.py new file mode 100644 index 0000000..1fc6c0c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/XpmImagePlugin.py @@ -0,0 +1,127 @@ +# +# The Python Imaging Library. +# $Id$ +# +# XPM File handling +# +# History: +# 1996-12-29 fl Created +# 2001-02-17 fl Use 're' instead of 'regex' (Python 2.1) (0.7) +# +# Copyright (c) Secret Labs AB 1997-2001. +# Copyright (c) Fredrik Lundh 1996-2001. +# +# See the README file for information on usage and redistribution. +# +from __future__ import annotations + +import re + +from . import Image, ImageFile, ImagePalette +from ._binary import o8 + +# XPM header +xpm_head = re.compile(b'"([0-9]*) ([0-9]*) ([0-9]*) ([0-9]*)') + + +def _accept(prefix: bytes) -> bool: + return prefix[:9] == b"/* XPM */" + + +## +# Image plugin for X11 pixel maps. + + +class XpmImageFile(ImageFile.ImageFile): + format = "XPM" + format_description = "X11 Pixel Map" + + def _open(self) -> None: + if not _accept(self.fp.read(9)): + msg = "not an XPM file" + raise SyntaxError(msg) + + # skip forward to next string + while True: + s = self.fp.readline() + if not s: + msg = "broken XPM file" + raise SyntaxError(msg) + m = xpm_head.match(s) + if m: + break + + self._size = int(m.group(1)), int(m.group(2)) + + pal = int(m.group(3)) + bpp = int(m.group(4)) + + if pal > 256 or bpp != 1: + msg = "cannot read this XPM file" + raise ValueError(msg) + + # + # load palette description + + palette = [b"\0\0\0"] * 256 + + for _ in range(pal): + s = self.fp.readline() + if s[-2:] == b"\r\n": + s = s[:-2] + elif s[-1:] in b"\r\n": + s = s[:-1] + + c = s[1] + s = s[2:-2].split() + + for i in range(0, len(s), 2): + if s[i] == b"c": + # process colour key + rgb = s[i + 1] + if rgb == b"None": + self.info["transparency"] = c + elif rgb[:1] == b"#": + # FIXME: handle colour names (see ImagePalette.py) + rgb = int(rgb[1:], 16) + palette[c] = ( + o8((rgb >> 16) & 255) + o8((rgb >> 8) & 255) + o8(rgb & 255) + ) + else: + # unknown colour + msg = "cannot read this XPM file" + raise ValueError(msg) + break + + else: + # missing colour key + msg = "cannot read this XPM file" + raise ValueError(msg) + + self._mode = "P" + self.palette = ImagePalette.raw("RGB", b"".join(palette)) + + self.tile = [ + ImageFile._Tile("raw", (0, 0) + self.size, self.fp.tell(), ("P", 0, 1)) + ] + + def load_read(self, read_bytes: int) -> bytes: + # + # load all image data in one chunk + + xsize, ysize = self.size + + s = [self.fp.readline()[1 : xsize + 1].ljust(xsize) for i in range(ysize)] + + return b"".join(s) + + +# +# Registry + + +Image.register_open(XpmImageFile.format, XpmImageFile, _accept) + +Image.register_extension(XpmImageFile.format, ".xpm") + +Image.register_mime(XpmImageFile.format, "image/xpm") diff --git a/venv/lib/python3.12/site-packages/PIL/__init__.py b/venv/lib/python3.12/site-packages/PIL/__init__.py new file mode 100644 index 0000000..09546fe --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/__init__.py @@ -0,0 +1,86 @@ +"""Pillow (Fork of the Python Imaging Library) + +Pillow is the friendly PIL fork by Jeffrey A. Clark and contributors. + https://github.com/python-pillow/Pillow/ + +Pillow is forked from PIL 1.1.7. + +PIL is the Python Imaging Library by Fredrik Lundh and contributors. +Copyright (c) 1999 by Secret Labs AB. + +Use PIL.__version__ for this Pillow version. + +;-) +""" + +from __future__ import annotations + +from . import _version + +# VERSION was removed in Pillow 6.0.0. +# PILLOW_VERSION was removed in Pillow 9.0.0. +# Use __version__ instead. +__version__ = _version.__version__ +del _version + + +_plugins = [ + "BlpImagePlugin", + "BmpImagePlugin", + "BufrStubImagePlugin", + "CurImagePlugin", + "DcxImagePlugin", + "DdsImagePlugin", + "EpsImagePlugin", + "FitsImagePlugin", + "FliImagePlugin", + "FpxImagePlugin", + "FtexImagePlugin", + "GbrImagePlugin", + "GifImagePlugin", + "GribStubImagePlugin", + "Hdf5StubImagePlugin", + "IcnsImagePlugin", + "IcoImagePlugin", + "ImImagePlugin", + "ImtImagePlugin", + "IptcImagePlugin", + "JpegImagePlugin", + "Jpeg2KImagePlugin", + "McIdasImagePlugin", + "MicImagePlugin", + "MpegImagePlugin", + "MpoImagePlugin", + "MspImagePlugin", + "PalmImagePlugin", + "PcdImagePlugin", + "PcxImagePlugin", + "PdfImagePlugin", + "PixarImagePlugin", + "PngImagePlugin", + "PpmImagePlugin", + "PsdImagePlugin", + "QoiImagePlugin", + "SgiImagePlugin", + "SpiderImagePlugin", + "SunImagePlugin", + "TgaImagePlugin", + "TiffImagePlugin", + "WebPImagePlugin", + "WmfImagePlugin", + "XbmImagePlugin", + "XpmImagePlugin", + "XVThumbImagePlugin", +] + + +class UnidentifiedImageError(OSError): + """ + Raised in :py:meth:`PIL.Image.open` if an image cannot be opened and identified. + + If a PNG image raises this error, setting :data:`.ImageFile.LOAD_TRUNCATED_IMAGES` + to true may allow the image to be opened after all. The setting will ignore missing + data and checksum failures. + """ + + pass diff --git a/venv/lib/python3.12/site-packages/PIL/__main__.py b/venv/lib/python3.12/site-packages/PIL/__main__.py new file mode 100644 index 0000000..043156e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/__main__.py @@ -0,0 +1,7 @@ +from __future__ import annotations + +import sys + +from .features import pilinfo + +pilinfo(supported_formats="--report" not in sys.argv) diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/BdfFontFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/BdfFontFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ecf232e2c9097594b7545a15dacbc45931322d7 GIT binary patch literal 4379 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/BmpImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/BmpImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09913a30de4796d48759d61d2f62da1d47adcabe GIT binary patch literal 17954 zcmb_@YfxKfmf*d5KhXmrfdC`kh?fnCab=k2Id3sNdj=n3MuQKW&jx z)Ln|97nVab?eKmt$cm~>n=ARCtt$N?{7>AUiQVhQC@j&`Q^BfuWp=z(llPoCH# zO_92#dUjs* z_^$38^Il9A?rv;q-s$%SJPniXq07Ka|ISmr$9EnapA`5wc4frtYn+_om4oh~A}I_kvsW=2!z>6HET7c7yP4equ)qh_0U)m(WV{!}an=I{>-v$kH>g!@ zPUz~*eQ|qxT-zR(wXN-h#z+U`sHPbOqhwT! zn$dt-Rd^JmhExkF;G-nuqTYnkH(>P!R0C>{8WfX8Ec2*vH{UYJD59pdp!Bq$taYFo zbyIq$iPwpXfO0*(i>!xZk}Qa0c!G5VE_od1y*_5*n%{BI8yI&_B6{2%aMT<;amx8+ z&elSZ)Dx#z6eJ>_Y#~7FD1U4oLUPEQ3J~$G^StcL@t$^)xA5wNy=M>g_8fQh^RlC- zdJgl_Q+O8HGqM?JkY-g9DkuxmqR`M( zAh~7~sQjRmNtK8cjD(SXAeoT|)MA4{Si=H%36Re>VnvnZmmH=s>4zk zHSU3o#ORR^(0dNjFb05(2!$oS{M5)zSE(?~{v(XnjMPjn&IC#=q+NI-mX$DhKAMpL z-ir9mRmnC_tc|t&x-E36Ir(xJTlNy&lzycXbVy&c{;-)1Dj!VcD zLhYhN?IP{~SbM8Tx%p(uuwST^gMDlxALUqv>kSfM7@?SoAJH?)03t~WD#SjR%FAzn z6!c{+t0HCQpmG!yPDWy?#WrZl2bvW|R89C*ED{ElA_eGDyP!*FR5R)=9IpwgVDEtj zn}%v4pMvrrk(66SGRo)JY&)ogmVhVeZDiLTsTT5O)RvWTl9ky`gQV-4+LxxRduht* z7f}KS$>`uo`i3WIc~}ZieR9>aQb0Lrc~}Ne15)}dOe4TVU%pQgK@kO)yySUL3Jz&3nJ zCJ$iJ-ZXsE5KrVWeSU;;yYEL(!t8=tgl8y?MDyp0Z8G_nL55i^P~n~@EfKkeug;7l zP$7;l+lW(bG>PNJa|Q4O&tW9ZXkjPg!6_s8Eljgm`^D?X?4Hp9}B>boy>mb0P_m`f0gNC4l>;zXlHW7Q3Ul@DfW)|#<&QV z4#Rr`u0l{Rmf#yu?%lH5gl0Rv7~Je5+1juKTba=^JwYwBC1Ljaw&7DcFMSWiF))Xq z7OrW1*0Ggu85^N_sj(4CacsVCGl#d^Tichwm|nC}u@BgReql6RLPZh_oY*+$3lQPF=bf7~{h^@U?_Oi<^(?`bnzlr`P`(;RS zU2+-5%*vUQxSRY|A39b}K`*5I#l37#vIuE-kC)#e5I3V z`o&Joy{!*-k3tOcvCR&@@egx^BS%U@E^V!%=u|BaW{M1 zwiPSN+9q9^9nzX)RN4bL0Tu+zSL|E(Ldt@Y>$KlaFVo)-hD^JLH} zj^d-FB{o9CdZi?E>Voqd(~dJ9H{)PEW1g#SU%=t@4No}S7bmU+h*gS)CNV0%f&_jO z?Ioc0u!DZ@H27*5FY6gXj}E&J#=+u8kC>&r{F;{uTq1@kuejv#j$8_Ww`0uh^Z3`% zrNYZDdINrTH-g%siE(g*`2E-pN+EBU6ns8|lWvCb`bNMHQ;AJiVFo*iV)4_+Ix(w- zY#nXK^{*h~6;p%5W8O)@F2?Wum}uY1C>Dis9nX5K4QbVkJK!cWS;wO}i+&y6IO)Ca z8S@WL!X(E%0S~)gglNUk#MlJuf6n6rGoYX1xQYC--+}6WoYvn`zr8`lD=u(*&o7*go{ri6^mPD#=SK;6 z$6x|~3p43uQ4+!FrhrMh{g-*gNb-4+JlD}TOxVpU+yaKI?O8;h!|XN4cojP$(DQ15 z1j6a!b3Xr-$;k;e;9(pfJ`O=*9D%7xkE4dCo$F|ggD6q#9{}(?Jy`$;0}iT7Krdz8 z*PN;cvUQ63idu*N6x)LXKz2Ql{atc(-`8-%)8LUb_);3|O@mP_L7TW~*vkTp;>V(E5AX!`Ap%Fh(_JDh7EC)bg#_e!*y|Z% z{EjjA6eyo{+^bN*wWxE0f^cmZ6^IrDGl+?6Ap6 zkB{Ni9v^soS$Dw0D^K?Kul10Cs$Wfi{GE%>!RsnN*}u<1BjAWdYCF7~}vuZ8(*&VN}nk(Rszh@UY(#U}v!Q+gMvY z40MBJprYDGjmgVVW%yyr%yk$8st@V7e+0CF`kC|g1hJE&fk4w?u}^6{kHkG`v)0C1K52W_kaj~u>GHyFa@z7JyQp=pmR3YxUnpHF zZ3*>;M>yS%)w0Uy<%OoDvOR#f#OX?&M>xu(#}-UWj@>{p%;|~~)paY??Ob*H!#u9~ z6+n)2x{5?yeW*8XtzOdAY?!GWTX=@kSH_*)i~8%47*2i<*{=ZEW8|$x`*cUAa#|_P^h631AM>u=K$Npu*?zn1q+^{~$aaFB_WTs;0Q13B=S`aC>HUCUPPA*0R9~JVS|G z)RnB6bHh_nD`%_W%rzjWYIC@TQx$@sl6EpXg^RE=$^FgcH7{zL7p5Lrxwa#pbuG4? zNa)OAcXFhhwSm($gbu-g95o*X?*(JM3&ULf{)g9>N{(=WZ5WrE>-MSaC>~&{_l)5lC+ALaw@JQQPzPGIgGL!$Mgbwsz}a~1Ij-b2m}_0*Ld}C$=BXQKed`Clr%@Pp`wZ^XOFLuHQi3q zVNG?$+a0qV5$U3~aLtmJ)C|j(me>`@68WtlS@~Ss(ReHF6YGied63;6uiwv=9r!QO zWt%H*bj5A1guOgov4^v_hLvB~VRIyR23OL#WZxfFCW;(kby8n*w%V9`(Y6y*OkVNh zg5nQ6(cai4uA*&eNBdGi2kZk=K77kcYh%^FbTrQ$33o?w6Ufz=a=u}q{GsyGhDW6+ zu69?rJ7Keba50+u{z#0zcX`R?OjJ1UsiBF|-A{Csr8rU3v{1vTm<6awH1NBefw}LTih3ENUxYJ#HVHJqC(vxRxFe*A^6` z&vku|QSZl;+>Tv8Enm)Ujq6(DxvgR?XB3rAZ0ezv+xaSIfAvu_XYcu}lq)zEKXr!7 z?_buPO{jFYwX<4K#+Nxu?Xs%wu`ciS$=Q<$V^P9n4tIebv2iw({tH~)fw=LNgweWa ztcg^7SbeYh!}@#m?>DX*^TNy>?NhZ}pR*xV=4nE*@2Q1bY8uWTVv+#>=YIO>p8Pvk-Z6B^Gj!PjaU0$t2OM56dRT|sht34>Co?kr+fkTb#ekGCvElt(#zOC#!@vlJctKT z_J>#x8zIIm9twpcpnPxw#yD->dH_V+Zs5QF2-LVi!5)DF;NiK$caP5pIP8WMV;N^G`=zmBRu-Z|O$kfhtn8*D^wxLP@ZB|4K2r=!<(g-wlv;U(&?ELU z1piYB*#(JyibiBcn1+mzK=_1gO6rvJdRWLaV;+}aRh%74)+3cs$YG1nPya%({U*9W z0s=t9(`%CIcx8(QDr}e3M*1jOG6TUPGcu?JEoY`twDmI5Hk9aa%1G#1gir>w)<_CU z#Z4BJqeDC_VgD1fCKjhXvxTUnsRPCDRZAIEu#%wCFM)u8x8b5+xMooWRqPKSNJE7# z&~4_Hg$tKmAX4Rz6jZ%^mo) zR%k}%`y8b7#3sL{VgJq;UVdglgUA`Uu+@Q7RzQ7YP?{#y#;p>cl)bGKTO>XyvsECo zmEy>L?=eY(y60pswVFW#xxk}+7hx|X_a~u7y(wQRZv6sgKG! zBQbO!bpB@+i55Iu`>GGZLdrUVSOy>PrQegw!aWQ!-MZTtuX4 za}&{i*}gi-K#0xA-YJb!+b7&xAiZ$wf&q!-7Ud~9II^gUiC>f53lR86@j-l-PBS(JP`uV_d=e{mD4a11LgBkJtNhbWf zs=ue_*kJd$GwdHBtp>bY#P3MC8?eWN5^^m$()Ir{Jl!AVKngqw$pMgi->bD{;#6%Z8* z#{0F|YjHzaTvY}+G3IBdBBt43NVaOozxhotPIUSZov_;Pj?Rs)SgSZ|Rm}2<{egYO z*}=h|wIifm%`t^5Zh9kiOF5N^G|yw{ox#wdM6T^_+g#h-&biJgedm>s>x;%x!rLUc}Qe*(aI@nw6S%uBQEA z6Iau@RJuQW^ov~EYFS0}Y^-$t`~p4y#!^{x_}FTBWt53E&5ta|=6y@$d&0+8ORJ*O zzbtKz$PJI@0 z3_OX2JF-$O+4rsG7rfU6Y>Jf5osZJ*z42>HLE76|Y2|&}yzPF`d{NB(ftOsVb^MYVZ`;mI-SE@e#>0f6L8HGtyMZjMn*J=O6UFa^XKosG5^Lw?Na6b zh~`($-H~44+P^*+om%Lce|xE-l`CqExI|P7SKYQ$(asgM10&^BZ3{RMs%o*tY^@=e zG+cfyI0BPXvoG3qgPRdf*%3>`ea|*`Jlut5e$m})bJy+$=Yn_Mj?rkBo?f&yLiG=o z_mspZdHQ3?C)x+v<@}asS7^#$7Nl@Fr*h*eP1$#RSa7c(I<#2eoGXv{LrS!M4YP(1 zMTvLmp!8OdH7E$LnxaQV;jcfj6CU_TQn#`S+Op6cvVgaPrC++`fV)`xPQH z%$5I)ILx|mf1)yfmr58dH+rARx@mcyU}j)>b~6LN4H;$zMuW>4DVQ4aDH#M!>s;Q8 zWFi=;%}ZUq2U!fr*mCcS>Y11v@TC^)cA}i&B`t{`HL#k&)a?Unml&}$(U@tG?!+vc zHm7&nNX*wcoT3(51QjHhoZrh4IM03xSTHlU@{au(VA(&%>?fFIuH%eB%Jsg&^d&>%OQlE%4RdpsDtWkju%GC$i#CC z*e|Jb3nPaRVa@Zw!6aZXCu0Ec$|!IYK{=jz86|R_QQ--dQ4?5$cG8TF(az|DIv8QL z7E-}5aOTcBPexD9M+HpIC@yG5Vhr#rGGmqz8+_y2v}Ypim2K0W`CV%BY|P|}r{}Ca zbZ*mwh4fGdrFgxbk+PjpnLNgtS`R~7cy#LY&e+JwU*Usa1j1Qc%ARNPgL>pLSkyMr z_JEVUF_?o`I7gb80%9%e8T*VXkP4~}rfk%AAdqAfH*!W|3e$pjO(F-d)lEDE#lqTR z+KPwJtu(v{L!eRCo;KSH>P6Z#Ty}{eGAB}J^q##2k+Cf`N` zr|G~Wy<=MGaKn$JAS|sPhUb*5{~_CYbm#6Vhm1;6Dt0Af!<=10As^gFX>0G`e#U!p7#TK@sI zogc+ch|n^$d@7AKeP0^xiYVufMa$t9ZpB#jsWcg>Rai_5F)1#nA$(<<5c(!&m6(xl z^Atj5kZqYgE(w`^I{>NK!$*JX?8O-iTu9E_BF3tLlN#M-eJp~#Rh5#yhKBJBUdws98h-$C{@ zCh!*-6XtONCe_n-}>rXQfk_X$4VjU$m@3m zCMF=Bzeguf|a!Fr49#+{$m9* zkvAB$!`{Ry?;=`8tbf_)gxAN05&Iai8i*=N1_%+C0Izw?J$A*Dj65QHj+equY9VWC zCBaSXZ?N)vkb&usZ3tI4{{vgo3!#aF$$K9jOS>>Tj-|9mxUKn@h{2u9OD8ACd4)f~ zdLdHi2Z)h-@fW}(9*A6=Bm@Tw9g+bxS?&EUBU`OKZj!a&*>ZpjGK|5_;(- z%CIGT6@zecZXcLEaKp8x$+=xKTNBR3jwN$P28rcv z(~4a>K)Og^{apS3Av_ zoFPTRVvn4g>kFwdzF=xm>qwaQ;}us?r2o#&xUMvz(%e?fsuDUAIx3tueNUvczW6b~ zr8kG4$R+wb;0_p%RW~m`QA+jpXHvOZvtgv<%I_Tc_K{VUHgxEwc2%PfUA#RqI}&!! zj^2c8XIgE4oPm=|)OKWaPRM<;3Yt=zARGkVn48WgYMI&sAsNXstsKg9_~yA;`$Vr$ z=fPbyybXm*XNParJuxWN)@R0aj7bF;Gh(njR}F6#@hwjSZ&ICHu~C#9bm&}oIKs|d z=JaLDvhrUmbCNs=+m=-Yk7fGroc#7lK!px|zu<1kTuC%9rdTll%=W1boh+pfM;=}M zjE(O(pmnVlE}*v#Kk0dXB39 zuT&}dvk3rfE0rao%uOgw2~|NtWlgATPYf!Zin!nbD^By!po?tDhU1B73bmrz^rPg{`C6+Y1_RFWIA zr)HWi2i16nevRIc9;9hSLY12Y3d)i|V@DD=+9v>Oa`jU=5^tQ9P_*TSe1*#8sNC>z zq5oLX!nI}Ul?0XhTuI(CwR4TiM|?g<1Kta7iC+ fSf+MmqbyqZ<}%fttWcm5?_X literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/BufrStubImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f2cc0657f1d808b8ee844b1f953338dbc137944 GIT binary patch literal 2699 zcmZ`*O>7fK6rS<^*omE(I6qFJ5LST}jKC(8{t&8CpiM~ugBrC5SCzH#juVIV+MV4% z92qqr)CRQ@i8v&O9ys&>%7s(Uz4wx|K?$oIBDGb;EmG)(Q{S8Q+Jv8pJnzlC_r}lP zeD6(uZ)s^JFn(RXIQ~Q>4Ge8MhBnC04Ns2T>De3_;P?Rzf=#n9ua#6`B zMKz#87X`nUK+91VJ_h$Y;a|-6lp8Qztw8FKEbR$xtW?M6|m7pQvm5Fyjl z4$;P*gnOeTA*Y|p;BDiC7z!nGE_3c7-lSUQEMJ)RaNrT}af4Ysmt$pzx5H`xL-)fp zOE$u7^8@pPb3;q<)v)$Q_~iZJ2ge_rx&Qg2gR2KluE-~OEBNK$Qy)I!m3XWwP2$D9G^)hUi;@cbC6qMZ13oj+bji_lue$OGHXTj` zIASBFM6(;nmtEOmrYQ*F%ADzj8y>A#jz0Y<=OymSHe**^C0i^R41`^nL1C7_PcD_2 zm5|ZJ%)4qSpSPLgN=19zRndWQ!AGoqk9|rOBWB{SuplW6haoZBfeHB7*0~s8h%fdn z^xf;9Q~!>3%{z7pnKq-1}}VdT=AQf9~97Z0}O;&)C39WMC^4xf{F_yc@X_ zng41n)VHmYuAVvhr{;}LA-3Si-i6+KeRJxQaN9;CcK5=a3rq6j$lh&^vTW9E&f@({nW#sy*>9(Gvu08A zC0^7WH|EK#!JyX_%GljGHX4yHN8*WG#69s&T;hZtb{wYLWTT~hc6g&_--_I|BS)3~ zX9HB}_F~X8_hLQPD|i|#FCuqyk5l(+;0cviYbK)Nq!+4J@|k^$HvA{+H3P@jMwL`4 z)MxEG<24?El*vvlhyrAkoBpSSMTETmfn30e<{vUx4hpjsfcY~Kl1^M|PYy-gq zg(B}kj}TT7BFnMqy~1w%3jQ8gPNVf0OmNS^=t?mD^Yve*A9bzm`(UFrH79MhcFyO1 zG*?2sn{wobOE)h;?;Tq@^jO|60G&~iWAM5_TG&oFmW3b$Pk;uyF%YgYR&kgu_FZ|b zR5BAGegX_LVZoZDm_^nzO(U1T7T(|RcZG-TaILB}4)6|cLmK6$fQLXMj!3$yQz;j$ zaW3P6aO_+h!54Umm(A-NE%lcWd%DLT#KCQ;KZjWPJh^)h@p5Bz7dGuM%SLAI=A#?> z&|~*U{9`x(i_QKXrfrE*`d=5J`~M-G|C0W#aCA1bqXubwr;pO1XQ3|Iz0|bcom%Zq zJtMH#IWE%!+Z}{<%qr`oeU-GYbiB3Rab&gQ$V&3`Z}BxUvO(Hku{~gG0aqMyxudo+B5j*{m0~#xU&BN2<=an literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ContainerIO.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ContainerIO.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b948b6742b3d12b155f02b9ab8ba095dcda734d GIT binary patch literal 7027 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 O`cJGTe?)H?S^Eczcn0nO literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/DcxImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/DcxImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1d596ef547a5245df0c54391a4e0f7726a73f00 GIT binary patch literal 2708 zcmbUjO>Y}TbjG`Duj9=}osT*nRg#vrF|;w1R!Dplm8OY`OsG^2$SSP1p0VR(y*9I( z5=W^Np&k-Zl=MPUacCqsv?>yC;ZMLJrmfhzYDNV*oQX1xMXt%2mJpdBOua@}l&g0oUvDNBB3znI1lKh&k4^VAzXFQKcuOEl zi6=V{oHg;k%d(ccA)kkmN-Wv>1V570jTx3zatx@XOTAm^ap-)cN~Z{;xx_{$lW^4=*%TT=BS8M;?(^oqn5GtdyNC za?7z(S@0=Ut~gUAOSiLvb3jvu;HfLzx{@*rm+ObGj=pjtWfvTNyliA=z;!!y;e0wZ zR`>aWIh!w7qveVl(T!}DmmSfL_rlK}gk_Oz$J&;zeE!Dza5dKdOYGz~(#H7Lv2SOq zLnk-ole@q|vbY2gBx3hv*jXc-WGEw<5ThB1g)%aeG73|f3}q8$QKkTnuoe~utX3k) zn5zYrVK!W8?Cgj0(eswW%^@JipUX@bZtybmGlXgl;yoQ0@eH1BH9Dc~6+ADtuQs^qi=XaC2tK-*P$LAFDb zSO-9h8fa|dX-wB1Sdas0O0G}H{}CDRqoI$<@D&ZzINbsD?{@~;L8jq9aP|aJP0W;; zG3*3g3-*AoKcJhKg#(??!6X@(6llzR8?^6`fter5VRI4){FA={1ZF^BttH#sP_FFC zf*Z^$T{m{IVmZd#IUz~{s=AcR+1zmzVOV)C&|Wuel*`;=uB3yck`qRe3mlZLYU$pW z?ZyhWZdiq);c({4Hs>=*1+kfPsqIQdJMYqh8}^mkSVKbyq7Bt3dI|K;$Db|bQE%@! z9NXW)vPd3l9V-*d6D#TE^!mQf-(RBJ?LDiXT%WJS4=$bEjvrXh-isgH)DG^1NuqB_ zzOHTW>sfWa>|Z*w-JMwPy0!o2{#ye#2R4ka2Jdwzm&PA<_CD z1MTQel*AA0XrwE#_S%itK#^MO-Vdl{JJG*Bb}M}|eJ_!O@77xX;H|fAzIFSRYX7k% z`M#Q{soF|(Il4Ohg(f<{=4`#Ufh3p-zxjRv!fU?zFvP=e(= zhyx%X@J$j}=wb*Lyg=Zb5JzB1hQu(^$Z2D+>ILEP&hLA!98mE)$d`s?k<{8dx7r7* z?SmW2{q`d@Ene%!q_@=KJ!>O3Mu3c9IwH%F6>V8t{b23VjY}JctKB2_)#SF?wWan| z)xPzU57Z$)RgEx%cBH*IiO=qT&B=>Iz}p0`re{4M^u&LI{Gyg&2Ag}Fz^!+Y58K;w zVr71LepBuBjF?P@+_2!ztgu{pvSjh3>?w!$&T_;t5E0l95H*h;MLO!Lx^6*3>bl#a z>%|hAHIdeI{gYY4te=E)B>}DJ#(k_a4o_gAj1Rp#tY^)V&2>JPHD~R@6%I|V8##vy z-7FcbVCB7B`T2VZ?z}@hYdtST9Ie6ygJBe1c=bbBGE|tt=J35t{g^++#0xR7m0;dNI zs>=n-5EX$X?~kdr;E##_Nc(k$k@n`CXQkUJc)nnxb2xIu2~-tt?D08=TQ)>RoI){d zVn3Pcn|@?Zi_@@&1!8{;%Z@}T{d1JiL%);GM`ZXB8F{S67nR*GrKg^D9HM=zZ$2e} zcG8s4u0>^wbXG~{YI>{dXtnF;?Sbzc C?JUp$ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/DdsImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/DdsImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1890c845f691e452482aa7bab4e3f4204f20f583 GIT binary patch literal 22701 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 Dxx{IMQzlW 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 JsdjRb{yz;fVWI#4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ExifTags.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ExifTags.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b640bcf1cca4a63c6d29bcd1323f0123dfc5d4e8 GIT binary patch literal 11562 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

c5r=892i8gh|6 z8B^SxoLyvArEtJe#T2BX)9z;%%P{0pkIVK&pVDyBo)m5O%L$Cf?6?(^)jcOGY)PwS zKMco_p9m+%x4BKCv{}oXQw`T^iE4A}sq(zMo9KD~@cJvmka`In}1@*40OSO$&|f^CJs&E%WCu)Hctbr$Y^G^TRsS zvGJ&H<$_8cZkiv|X;etbnpYn6H7o>c=ld2yb@Tl?p(?Ct#r&v_s*tLsP?bv3)^XI= zyin6Pzem@lUh5KDRvq;t*pjS8t8DypDbub^J2B&vWyDXLxSMWHB_Lw9iHx}(0f1szuP7Yf(i)Lqil z$y9@NKAl7lm1?ePhHAY|t4dQDR7ky1DCkU=QPd>$Ud7eW6;!MWS12fYS1MRkjBc>bta_xA=@d#ah4IjapsAB7#p@z8RZ~?q zouJqNwMlBl>p|6e(sgOM%Bq#41;yi3+(p$Y1zknQ#$)0q+d7WRYcHa`0tOyYCOehkq3K z81NAA0l}eK9K^edPvV{BRtO(~8h}RNwrd4J2|2ZrB_{t%e^LSdypP`^{QvV)i|m@t zwQi~0NI50aE~i4Uh|ppw-~(hC^DJU%TU2lT2vq|3?U19Q_(jiR6@XvyEY<*F0BTsQ z1L}bW0E^>d6VME_0P@oy&tec>@D_QO1S)S&T;F-+^XB6!Db9a#1(T3lY{@8_LiscyTLHPf zKvcdc$W9*(7?!=UoSfAWyjs*{FGSkWn%|WA;c=;)=6kEG1X@| za@{2ND|n067t2&$Y)hrygvuc&?R0VHk)v4V*5?JqN(e6(%EtwruNMc+q}()5s&1jE zoM@@KrGtE~fk=~=sp@3^mHV)iyVO9}aC*Q=2^a3TJ;FF(W2u#^nr%(03uN5KxDE1p zPto;qzvI}BgOBlg%Hm_ZvndaJhEF{xrg6Pzp}s-3U5!oHaMjC(tEm}#q?2VT+R!Nb zuW+sGw;G!zaaE1%aq1c*M@=m@OG}~FcI@DqTBH~yEQ+_Sz~-vC75lT6HteQUQKzKP zg8D{jm@21T98`<$2fFa=?xI7w^Pk;Cw!E`K{k#hw_0$Y@@bd%*lhVPYbTBDLI{nM$ zkAvwaSKRu3EH{yyX=JeQ=A`R)eaE(3^OL9tz;6&zn5!pgex+;#+7?H;T2WP_XK7pY9VAYGBaD4-EIpdZ`;&z6!ZW(Sw zOt(ItwKyY$>RP8**buSp_$kuxDU#~^y}7!emk&B8#e0{-Z()6?cDo<}Jim=?{XYzc^=RM&`&)P&(Z;CWOiR3#_2U`Q-TIhatjM77({Y?s4b zOU{KT=TSf)G#^=bHiT*p_iN)r3r0Gt-HM3`wqyF^|6~SNxDyi&7IN2TCNl{K%emU+ zxMlL)P`+XNlK6)18}Hd2RbEtmn^G|~v(-F6;qv=Yua%NMdbT=nxvu}Lg!PRRzFrF;(6bR zrVj6_n>L;B$m7ugugAOT`1(x`2R7dyx%;Y{x^Lfg^R6R3cMaSzaPv9$MUDkF&sUr% zFOv*YCp_{v5iavqBeOhCgd4r#Bb%P^$m7Y!A|;-RjZZ#ynb#BSOyO5(_pRz(RsOm5 JRlVzc{{#L{E!zM9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/FitsImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/FitsImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9dace18495ab17ed5c38fee2f6ab6a6fa13372f4 GIT binary patch literal 6023 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 D2PH+Q literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/FliImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/FliImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83e7f29c6b2bf805aa30c850b414eccd605dca73 GIT binary patch literal 6774 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/FontFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/FontFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b1cfa99b28e5de36f08968c7136d66de6befba1d GIT binary patch literal 4498 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/GifImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/GifImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0cf225f6419cde5d66b6c1132d1d89cab72cb18c GIT binary patch literal 44813 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/GimpGradientFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/GimpGradientFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dda6e499285930d904169310221edd5bd6b802d0 GIT binary patch literal 5464 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 RkZEIlOiuX*k&>?7e*m=G-(3Iz literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/GimpPaletteFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/GimpPaletteFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d30c2ddd9103043f26044aadd08705e105c1ca0f GIT binary patch literal 2116 zcmaJ?&2JM&6rcUH6UW4M$S0+k1Om%POoA$)&`O51X(}2}sd{h|tv23`vu3?Ev+E>w z*Al8Yn2$C=L5&fWFe-;s>49E)s`?M~Vwy?~t5iaQ9(+TDs%lStil%k`ZL4VvJ13SeciZD{PFDJu(X;pW_6t-8!PCGUp{tF-_%NRa5f& z2oFz7x~wTUJe9`bk#q43_3zb8{6MPs{|p7r;tZNX`m#y>utv!m6x^9J%Dlz7TZpL}1E$}# zgTDU%vgaZo1nTtuXPvEXlo@;}gf?Eykixf!B>6StR?D#N0p@27FM2&0$GTD448hd$A(PnyM?d??O&DrMY)7PGg(K zip{}siBH>%rsy_jW;2>%Gbt%!GpcUdoRQH~({BD)(z1#Z!zRPKgYsY!Eu>Jx58HGZt@j^XK65|08XCNpEC+85El7)Rlm-`1l#@kIB{cZh=bt}$_2l)p zN^Payif?Cm*U!EqYoUY1GwY$9rTA*7x6;!4G}y6VeA!cst_4C%zMH;9e=+)~ZTq7@ z`wJcgLi2N1=St1x=r67PYk{uy*3iP>^_dcL&06c&zrd__>@N4McJx;Q{Z9k!x8h&* zl`h?#y*+y;w;WpDT`H`099|6!6r*lj@Y<(q9Ri69m)jQ8mB8Mo-8)Lrl5~6cPS^d@ zgK4UwuE9enB z_;_2}<&h1xhZ9~Lr?>-70C9uo4iZjfp-f1K$?btjl+ByDjH)LvOC}z1Qq?6m^yFMS zIU+U)BkenaiQqs~A1Uh2Se1gsYR55Iuw At^fc4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/GribStubImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..520a0e84e987287c1542a85f0a3d9e86dbc47ca7 GIT binary patch literal 2697 zcmZ`*O>7fK6rS<^*omE(I3Z5b0NX%YOu;4u6$Digv;`s{pdumFRcmd$<7C5n?apo> zj*J=*YJ*ydL>!Vs4mYEmZA8^VnZx+nFcIJ!0Q<{mpYooetSd6Ee#j0avo$JM5@|bqkw`!%~ zF_w4J!e{6a^&+|2I*2%2QymOQdtqfpOGTEk4|1czGM|<5<3(n>P9_iEmnm1=(UP5W z@|-acqdI4qYs|iuvCQF`aUk7)DC3weJ5bj1S0O|vb7}B=<_tH7FT3Nz0*p)6_=stz z%N1`MXCtQLG9CoPTObM~jnf3(6xnDc+mbiWZo+`P1Rs(}!1q2V2p>|m2dH{=FCi0@ zM<~uo-C#9joV!d?%FwzDV+T9La6JqPN9sSqqg2bB70d}A2p)rJFPzi!c~*8ghSUd- zqd_-CR-$b)eKY;j$L5oZQSFcD!2K%^Pd@na$-57}S&#>KD>&uhskeZ1n|oktjxds? z2FZpDnw8*@4aEpSA}EGxNFddUoCGaS}GJA=6X`m8SzwfU|i4=bKj?)lEW2~$=6tr7KVKgv*SVsWNh0$mz+(`_0IO* z+c~ZN9q*iR=dRCQpR3MR@1MN)-BSF6mBjApPgfH==JQVzeG9R^wMgu4_)hq4>`rXv z%2K3vLnWQv)ACQvE8B%wgDrbzd+zm4tA9q@R$_^}=kA=Fm!HLUY)B-Q@CjaHfIt>? z!9%3}9Kpc+25Co!IMO0TIkJCCdU4FCH+~@^avYuU#HYw=JUJZ~FCBuys&eLzbK8@L zN;ZQtLMUGJ*2`=f>r7Djs+w>LL&?k8dXeRFUULr5XWT+PmdkxRu3I&WS}5_N?s^Gd z<_rdv&MaeX=TJe2h?gf&!_O4w#5+;L4hxZ!gzh$3X=$H2z0$pFLGIj?|FL?`!1lFPB~=RfS=$}+ zASDd}Gxck1a+kPVPz|mT4emG1^zS2Pq-2i&BJkR9bl2rx_~KcCnRwEUy0EKsWe(y7Rw*YifNsqwY0%2h};rp>eLhuivgIO#Ao-$lz7H*P~36~=*wKqHPwda7F~oAwCD z5A_Jg%Eb|UftR?~{JPOnzX!3V`}{#1yq5Z9h?&n3k}Y$HmzSu!unCvh4l?s)K6;Ul zeRhAsPr(M5m(KUlZAg^T|2hfX{SVpxFWI>kjZZ~3)i6zN_ELKId8Cte%{MJ~Wfr?K z&j}1R56N`TMhBrCQ_3=FUnK1d9q%o7>|gBIzmPuhTXKmEu8{WEY!BHIIlM-?(9pF= Wx)!?kEqC`XcK1Iy@{Al8NA^F9S56fG literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/Hdf5StubImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e209595e3be0c4ab2c1d32c13eecc2516c71188c GIT binary patch literal 2672 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 EzjzQ8j{pDw literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..175a501d0b93ddebde7c10433cdc34ec7cbee41b GIT binary patch literal 12733 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/Image.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/Image.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c5070cec44fbd5eaa020257f78557dc95bc0447 GIT binary patch literal 172279 zcmeFa2~?cdoiA8B1yxY&i$J14NPq-LXhTAa4G0hxLJLT?%2H5?uRw(;z+V-Tz=b2* zS-_TKh?587zvMGim2d zzxn;|{WgjZ**V=kGiT0}#JAk-yX*h{_xqQrsVN5hzQ54kS6y#1{1De@3@|f7&>@l;u#baT2tH;XjHjjhio1CrE#UIF0_mRgK!ztHkm<=}-?a>61+qQa?Abby6Ug=C zvS-^sULfC-A1Lq?1Xg)g1qwZdfg(>)V6|s8;*$jXz?wj@r#RsDxC14gl0d1aG_cmQ zHc;j%WAVuY>jLXN>jUMU@<4^Bf`z3FR0cM9Hn3;Mz{Wt8rz%kGsm8n0S0kkEL0=_P zU!)Ce3T*alHX2L@pRHezyHLIRw!UTLZ=P)?L#sh>ea0Z9`?kMjmO^*1& zokEspmynHb<t!v9!(m!CYReFfqM zfgr%AJfFgS>p*wljOPqig+bUh;0>JhoMkI!JLY4LrzaqIgn-ZE3-o$=1AU%87Pn*I zT)^+~2l_qzf%Bg8fdS8e(a>k`1cW-w>76vE{RYpVunTYX(%X=*8*h80w_#x~-u6jv z&#<@0q&JbJd|Y}93JplvD7}S*CcN#ZH;n23Cbvqx3(e;%uvSb$%b-zc^;{6XBeY=! zT=eRID`6AD9|@mA$&Zbqvq*7;)u0D85H$6FMfelpPX!<1zaacOp%=Ay zRrvQpAMR6rgK$ppzh)Hrh4Z)$2mxFNg&|yrg=cUTg&?jWVFcF;!bMy!38T1<3D4ph z7RGUXPWUvgmxbqXeL;8;*Ut!_#r1Q-=W(47CUJd9cv-mOy8t-(%Il_Hlkf%U?N# zui$=F_;cYZ?lUOiPZCP_kHQQ}xF)HS!haI3<320=wJ?kO4dHKu8@PW%TLwJ~5#bvM|E3TXzKQ!A!d>AF z+`onUw{ZV9MrU65Hfr`JpwpXgNsEZ>gXSq?{}FXn$xpt$2tOvjsdstL!R}Qc+I<9x_v}S@qwjI~z5nxadi5@>kz>Vdq)zRhP~+q$ zp%{C-1h0*T7YK%bT&ZrQ)Pj{tU0TZ0FQ5+|fBNx@M!5$n@BNZ0Q)!Glyn};7A#cb( zG#Kotw8ZUA-hlz{*#TeN-WKwS-q4U3PdhXcqM$?G;bH$^U)0nz&Yuwy0I2uoC_fxq8ar+T* zC^XbFG!VD+c!Qx|5-Nmz_U23e-Y#!nFrM5N@b>voDC*MX@8yBH#|Qm_Z!qNV_4@>t zpji}AM@M(}1)ms1GrGIu_U_?HP7 z(iBhK@9Xu6qEFyuCHaHh!`{%ju?)3E?y$RKXwVmTG!OU!_4I`8eWdNF=Jrku zxxL$u2}Kh)4b5#o{ABlu=3||0hdaiOcb)UOc_ypf6W!80a}V{pkN5`$hAz4hi4yBmnubK599{1o%Se&pr5p$!XKj=o` zZp_#amY+|k8O!EV&pi_K(TDh`jy<*{`|nawHY;kza`g-7k)|zr+F+mo2L)n$xD5|i z4Iw2?FbXEYEJInNAtcc$21D2&SY(LSX{fZ0MN-`OHJ$VIoDaJFz34ml(Aj=p584={ z7a9pPj0M%Cu*5Yr=x??h>g#z3O6WR=^t~g4Jp`aAFAW67*(VNq2YBZU4vb1A)DL?_ zZ@?X@m%kMna`#Xbs0RK}x%y@H!Ftgb8W9JB_3kcl#7Ai`ymD4eHCf`Z9KJmKL3Sq~ zSK$v-{*spYSfM}2h7KSRfmLpvlwB+1CL}Y7tB@|9bj};}hC(7HqcIeueszm9_2Ujr zvEp`wjN>mz>+rJS!(4+kEt0lwR*Y;saL>|q-;p_0J0;9J3L}<6wtV!LBhXb101}L# z$4#Kc&7i|Apuw%6ziptslRU|z_R8dVa+l~G3=R(keIjj5VmdCrq^DofDF4zz7n&Kr zwBgcGnIe|pE|$_|EiQ3aOMBaq?)K)EuI^)Ptp~cKfUd(wx*HF7bsatwPd;|ItD&p8 zd)MZ8iu72!Q+?i2w;7c<*3i+3<=q@lVUM&zn-c*Ah*pD0mudV334j1T<>p;J%rEH~ zm)l|)nU|m77wPr+Cpf5~eEJ>cMvMxv^*U_SR+%Jq6y{+-?I>|4@`}6YQjbeVr9H8G zYz-|fZ5_>VTk}(0%^h8F#}TybNOMzH+ll75<>>K-{c+2o=FS6&ZEdD9>GE~_1q*RO zTT|06xA045*5!jShx77&T%O<0TS%$(TSx%+(JiDYF`86q#|Zg?-oWqxz$I@cwTm}% zH$Abo(j4iiOipZTQb%*cvF6UMxViE0Q*nD^TRU3ba4ep5pyALVLIjc;+nSE!56D16 zN0aApXJV_{=@WGM7XE^6T+r$?*X7n&isN!q%$0um0Dom+X|Cs6dDAJ&-{TLz#mA(F z2l9jA@jf19e_X$NiV(eW_l#PBo!IvK0VG7dk?*KXO6&+r$6*Y4(&1zKn~yc`#{y{R z>}o#N=4pj*^!;CtP^#uf==`g?tP=I(!3p)OA zQ`fQP=6Gs*TO&gZu;x0t5}V{jbw#@T8UEysXWh+K8iOj?InN*BjiZF|^!?2(4aeKN zx;p`}x|&;00=g$jSRx)%k6@b#jUEx%u2pH3(ApM1kWvTRBJhY|h&$PfG%CQWX@@)- zin|E)98${7N8c*vCiHF6;(U32A1o$gJ6}G9?5w9qG zlsw=MhMo?F#M8jc_m2$;{vP&PE)eFIzRO0^+uoXYKN z006bqwY#CcJ)X?qE5qu_)M7*Eho_ZV*Bluoyj1XsD8RnIx#=+0XXn_X(l-w(>6<%v z`nYYt9|~avcN*Oc*U(sa_x?U$QlNzN(b z3u7^R>eRZad}N)l#vJKWC08q_DE6%NOZFOmOivT=ZwwYQi5ZtBc7nX}t1Uv^TLCysR0Z@L*u@uXvn$^4828TyNyjm=miqlhVkdb|$ zhR69X_4tMvA#u<*$_P;uz_EV6QVt{fh#2z%f}x54o|^J2&1}YtFQDJ!cIqRl$4#U7 zA_9W6SY?b}S`w5*{3gPS5y|j3VD#ArXU>A7DC#Jh>6&+xE;u$u9UCK-jcix>Hyvol zvVjhQ!$Y(ftuc9gTiIZH*()}PB{Y~k+FsVDpnLiTeANTqQ4q##vIIx`j9J8H4Hb?Q zpx6Ze1-}4JhMU2G-+3sj+@)=$Rct_8O8+f~le$6t#tMVUBEOBuD$QVK{y#RD3rhym z>!vN9m<0*F?I!L~5X<%x3@aN{FUJYwg-ZiSlrbwtr~IJ10$d8d#D+)f13oaIg!(hj zfhEE*g&JusQ1_j2gDA&4E0IkYB4?#N)2f^Ari>ZxNY~rGCHS7zXRRbD%C;ThJ8S(R&am(gpx&mMZ z1vWC`9FpzSOw9bmiCGbKR75Nl%b|=FIT@mI3=i7vMCI`4Z5?65TlgIP^iUHyjy9OF zzh*ttD(^08uOf=2sbSWw;|j% zZbrCyNq7>%lg2Fwx5(jw(Q6=)OGv>`A$md1lZGq%WRZhzY{MgC_dhbWb%j_feV5lr zPElze3$qE>dxx2x;{%q3(=v*Av6OzJx?ah69NqgG`Z2UL=Gj333big7`-We~PB@U*dsHV|(`0Gk25n zWA?NM7OOS&=k~H+xK>B(t0$j(VAFkH_Y2pWh<(lEr&owq^V3CkF$)p z_Ml+pmxL#_jGtI>8HW_|u%8AY;Rg;pa?($*kR)_mv+ST*vIikp@*#yR>{kdumWf>i zYuG6B>%qqd!N-4L1LWD}un~Gc=8#Jcl_j{LjKq*W!&?NF@PkImK8qnl3@7#r+Cs#( zVm}cCCIEz;frv~w6d}inbD4*h%B2=S){Z0=sJ@n#p7ToVdi*1;O|7 zBTNXwxbw6^+x=%nuQ*z>RLH;z;lKgw+wHyJ^)q?szX~`YAw#`{BLPE_mQ+RM8HhI6 zhapB7>FouGfw;rz82G4n_o6i%-SV?&#MR@kqpQ*>zJvUX0T@paAxQ}VnhXt!G>Tw#4E6PaM`aa! zXGi)-Ldmm3LYdSzFm%>C5TrDKh(YlWsTkUw#EZB<0_#9wXbux^#%)|O8#nrbSOo-N zIHhl4u;mVdK1;BL=wU`E$*{$h{Xyoch0Jx)%yqLp^O+mwYNMIemk<6gnX4vj4@{Qi z7UO+q=Bw?K?K5lUa_>1e-*@KDY@As=>z%XBUW(*x{-g3gto+jxfAZ8F@n_B_9wZsE z3jZ<9V0XR}isj``IAg9X@Bn`EVX7g$5MV|vEmE-S_KrKX3(n@Kv-!7xJc#-zn1|YZ zZ&$-k)4My98%wP}Hs&?1w*Gjv70*4=dO!+|Bn`VIw(PL!GFHO4X)sHbsfA7IYL{1J z&>S}PA{|z-Qd-!^*1E-nZ8vP_!>S0I$MA`77{6!xf}zu(x4jNp6g6VaW{M~WO;98WUFpIE4^Tw?l9tf7#&Eqx|CWLJ=6bf5kfX3&z^*O7$8ds`i zrL}``Tp^1UI0tUbE0^8@TD)RkP<)vplB5XnNAzY61p9&ns4+e1Ckg4g zfzHY4{syscU{oK{HhS6cz>djuIUI9kOj_=z=FM2X?z@*-7E8~bxHw^3LJ3h->4FFnj#kz+KnIh<)R4K1?z=vzP2~A3aF1T1!93Eckla?4H@0 zTlR>1*L-IEWYTZ$I|_bnFj-4u>G?B7GikGfk+kg-=KEGBu2DDzXw&*rE2R}{^srxebnr})Hag4{5wofF+ycTap}RI@{u z;vg$^r~9lw6qI;XBB}NSNhOA8buaeQK_n&dHpk|%tyK})&I*9ShIfF(|3PBaJhn_r&^OR4{w-38_ih>ctOEM5heW`AT9Oy0S<$_ zlXM!yI1+5BC#vqQgmkcUu5CH!bZLVAVrRilw! zCzR5w-Sn~FT%qKprSQ(SaA=dz<0jVQ(0>D$OAJ!?$om<39&>o*o@bH&m3p2iBlNr@ zXUcbP_2zqy+WT4SvA11KnNFEGe*NidPe;=$=E~mQcyr@z>yMm2bVfJqe`q#kr# zQqw-P8PeCzZhN!-M*Upq?PqU3d;55FQ{%j=DPnJ0K4!}5A<+|1CLk#e1GQF~Qe0sB zUl5Skmf*N0!#RlR00cA z4wsHf8|&`4wHHKch;0wzuMiQpamh^FLXvT4oc)@z5HNtO^#j~=0W1Xcyc{)kYN8Sd z;Dj*LgSq`bQ;ENz%irNb8ml6M5#rxd*e~hwzsnJ9T*U_zRz?@9J42)SjzIN_(>fq! zqR$w9WwKc951l6K>W6ltb>Bm%(}GkqeNYGg-Nr%gPy5 zj-g=S`6sBBx@v#{SbUd;#kkSC1gN=);9#f$M-0T@A{!_`Ll8_JtQ8>l$*K2J-Lo09 z4fCn%=k4W}8}64@%^khBx#?c%{)vWHTPItmj$VCg`l*OxO~i8Kz1sJ@@2$rJUo|L1 z`APex@nJrKRE&`EjzP2nvonvHpnKx#92q9QLJ++C{SeA7>2@lOb-RTXGRm<4J^>aH zv}E5WVhRO}|8mDsc%E9Oco3T|2DmQ~W92I6@7H2S#& zIaT#U@qf^38C}$w_!g36^$Fyqb2-Ux?2#c*c3FIhNE81q}KESQ4O%P@F^jA zNvdR_TS(D_I8jo!;LwDmBIJzV)P$rV#4Ds~LR`XGAq}INPDY2G3?UuYOaZ2bo-EWb z6EWGiXW^cMdp7R5kRtTZd{F-hf{+6E; zLL)+3gejp3-*07QOsnzi{fokWq&a|`pH*Xo*Mw$-wy7bA|B}#xQl3co#+QXwq&%oi z$;$nTZ~&>>dAM*jF&?GNz$nn_Ih0V|HQ@<_cK8nW&#LoCei9Dy*}BraVqg9$3=6HE zqf5(WF<*nJq1AIt_&PH+?8Gd19ma-MPnYm}%+T<-aGe<%o&bzEhT1=gTHKPqt=@&s zUa%Xr|Abkg3+0@|I?%88alzDU(dJnCEZl$rq7~+)`nhe1-_zz6z9Bq`yiW_?6rMtz zPYG`bCviV5d`s}){wd+x!qd2SV@G;Z{4`qO-H+X$QS8iMpl84v47!)H0T}Ni8%HwUE>{<2KGOiD&XVc(yPr@-r2xt|c2k zVGnHM@5RGanEYya9s+Sd6zmLmk)d0{Hn6)vR!XVR)1$y@ zJH$Ugx|=4h!AwPR94jeqhIk@wB`YfE6?O+95sfDeb9Lu91P#4IaXZFA7=q~t;(ahU z6Bm(PgPt&4cPxz!jlxk`M`*$hBm}?LX4u&GY z1-PZgO4oz$lERTLr6W)dHI;SSSMacez|-Zss05yZmga&OQ92WaNIyN2?*&pJ)k%Aq zDGBJu$$T7%wE$~MgGg+cxXE{ES(gz3H)iKu<_~P9&ZO`m%s^`4_9 zmYI9CV!Gn$#_5d_=V}n*uU?wG6mhMM*w^AJy-&D!Z)xjG&#bpH@c`Dq62_W@Yr-Ut zDv3!!d?u!2szs?;fLg~osv`+TfMRClV2rqpoBq^x^RF8EaZmgSOgh6AW2u@qjbP!C z-ufb5wA1Rdcpu|x-!)7-b~lngXjyHGfA1y?P&AZ1`6F7hu3OKx=l&q!HrSgxSSxZkK zTDur!3>`Yr5WA_6Yz2zYq{1_#(BrR|RH&w3hG4v45D#F06;YgANmSgeAKtHs>(#V! z%~5Lwat;;&-!Ko@1IeV@1IpOkPwOe+rS+^Oqfem%d?fP2CIv>!NGw=GW|+GJnYt%gVdD zYkJq!ebf8qv(}T!`%$bnPNRHu@oy`ZwXnj0jfg=jf;EB>dz_ z1`QNdI_;1Xsd_FllLqJjbrJjN*FY@P4}bL6M-2>}0NT(y-11SuVQ2s|gLpR(wVnZ3 zL<(Fx9jrGdyIV_B(bPK}x3XBiBc_}nF%s9bT0|9>4i!s?;+3J213pDVCD}5-uyfl? z&aCyGW4*Ku&TPA0cdhQO3xeM4tM+O8)wJofd+F}`d1Y^SBAXA+uWO&rJ2bKX%7K`} z^=jQqbuni;@qAuAG2JpcyIio%qbpG*q?=@NgMK3Ia~Y89*mi)MKxF>F{_8mfX-C`&F|u*%b4zGE3E zP<5Hsr5l_~WzW%7{epUzJjzU=$~10#&UodR!0xIFN2SgCEer;uEeMV_(L&&QR7^3F ziD-Rd6{$4AYB=bJg9wRMq2!DX19c*;q>C_=cY}Ngi9@4|=Njop_S<|lGciF zSpkZQX_~XOr!_bMm39Hf4_y2UnhsXvXsSerQEON{8HJqlq68pKB3B0^DuUIY6-i=a zidAZ%QT0-l;W?}(4YM<7D(TACfP3k4!*r#${tWePHKf`CS>7@UxKbLEcoX$P8mW+B zt3AY)O~+UUgFXyoAv5W9L6gNhESAxta`2_5tTI^2$>uQPZA>=thjd}^4X(^MnlF~q z6Cu>{n*3`d(ymEyJtAdaPbNcf zEz)6cw>w`=o=m>tAd;$ly8LR@bk%D$pg5Bl;rUAHasa0^{ZlAmC3IfQ_&D%3N&xVY zn}AG@nR&x%sdaFLx4eliU@<|cGj<2KlNs63LP9VcLCG2bwAbx@X)o<{PfR}XO8X)n z+9umxkz|2NU!#RoMIaQ$hh!H4zJzhy5;loeKwT45Tupd025ZzEP;Z>WmbZ|Xey31{ zaVwPIl!oh(*kEjMTl+rk!-@gl834`yrTB5EJTZp@sK ztww4c3PBGeSJm~Pw{PoY60v?FI}?7W37lDh4`Y7A_yr?RD|1@J?;~;C4ApqJi?D}$ zfnfqx@ua}{Aicy*LqP@(;?RN;f~2IwN1XTqaXZxFeci*u0T9M`g2EH+@o@_kA;S0o zDtJSTu>?g@rUH8@ZtRWQDVkZg&>l&U7(cF!XYCeX_^d1qdif&Fk=K!s@nq4tCI;bs z#0a~OrLs#Zjs4_Zo?B_4RD}kVQ(zYA>Zs7{x?~i`F#aoO2jH2^;lRhx`pHg)wnjpnMAYim`+t<^Bn(!^zVZ z>4_1gM0&0>Q4#$hqp8cFm`k%pPA@w>`RU`~14PXnNhRlPKCw(b!a9OPgKyX7!Eg zZ*GdF*FJFAl69z5f@N&B{umDgQ!#FMO8n`HTcQy(pQjJCq1@BeM z5zG{)v4vMm)_QGY_yXfej8*Je7pz$aM@0-NB|gz!yb-Hv?>gbqI-qzV_vTCMp4!J* z%>*|=3u4Mj66O*FaHa)K4S4(!mhI%EECIDdE$zbJzfbev7z!X-eHTHLj>(P%=enqK zo$|64BTg>>C(>=oJK3&z1PGf5y?o$7YSP}6Um23pQyv(SF+4!_<{@|# za0~t*-bUR)uC_4d{+OZG3^7z~;ub1o#gT@7BiqG{#0nVg8Az~cNaaHgWmGr-=^o=s zu{BEq@6hOzlo?xAiXl1WRokR3=B%Mb40?4Ty)v3!DPheE>E&4C(wdi-e#x{`^N1De zO8b>LDK+gM&B^lkYsW{yhrWnUYUx|OQIw(LxH*~Q3wrAm)Fi_fOcK6e*28t=lJw0K zMpd_jrm@!#_y#~Vsw5POo}FSdHSIe7%bezunRn@TCE{sH(} zCkJmN{erI(U?t%53_>yo5{_8_4@%a5YIeBD!Rj7@10%}Rc39j^Fn|m)<92KXOp{pR zN5-An`owMLL7~E_q48`2XVSsv14}%X!D=l{5f&7o338B45LmpWx(MZcxqZU;z+_I& zk2!NBB*Qxc6lC*U?p^0*!20wIVyeGPVuas(Xf>q6SiqQ^|9(~;8L;Gk#8h3rl3j23 z;+eG)Kxrdz2%L#isxNBBlexk$ti-ZtfR{CuyRMqa0;Dd8XNf7 zP9js(NA(hm|AgISp~T|Tdfg$-yndLQb}yZIEa(I3kep>5Vw-0;$@0EXCe625Ul1GF zZ)ARJ@SgaSC>Ro7YWF888F*w?d18f)f{k>i2D9|j%CJRFr&4FCc{)*Uh)<$&aJTb2 zMkBc+o+Nc7_h|MCQpC-o_abx461Nb?Nqh-`;sh>$_b<|O3w7re3XoWpYY?Dii^Q{_ zTTL#Rps5e$6qE$u*mJBvnsdve{u}l6DHO;km&c85#`j8Y4?-pZ%y8G_t{L-PMgifk7U&kZCY)oEB=4cyuJ5|GYgTyE zf5Q*sg5r0I=W849v_@R*5qmqI@!Aehy6+!Q9(Gfu3-so+IvYWw7*8SZxM|!xZXu2W zvkFm44wK%4vMR{jPt}P~F2#6v|I}eox*)q z5`b$ULor}m7=(_S7Vf%;bQe^a9vnlGLJrpzW~0aCcuX$*9!1bnVQjB>3S9Td#8a}O zhaz(ZtZWdOgikX8ND3&@UbWo*2}2LtoMl6=hW&RM`g5oQqy+ZVSJNibrb74ZMX?Q= zqW1C$%Y-nsf2MqPTP!=D>2BnZ?nX+C-|lmzg_&(|)Q|~n4zSo9u1Hp8)KPh}j}Y<0 zlZR(o?>WneC&xCJQf@YtHw}N9}pPPT4|1h z3uo!qo0A4z$utI^eh?bc=EQyi@y&AOH}%f@Oh_VI2f4q-t$pCLL4srHrw&c{sq5er zYB!!VZXZtu|BiHC5`N)ibv=abqH)l8WkcAG9>BPUhQU{e0|tD8P@0@tmZRDRD&z$K^WERg}{eoL!qH1<+7gAUSz#Lz!vTgtQ7rKDi^D%f;N-#+@SbnYLc@A zq5L;UGOQqcbVHB@)6qxQfUHY$DPAo)R-d=@G4Erx16ZMis}z$&n-T3(?`|d+ zfA~fpcUVpXLb;`{Ycff5v)D-ymPblA?(d9+DFlohS>FG0c`Omn3i|q?Bf`sp2kgi=~ z+`zbvmmjx5Hx%6OxbxTu9G3{%g!BW8hkk1izJjyt7F0Uv}N`j03m>Fh`^ z(^s?&VRIY_#nV`$$qix99nKHHQYTb0*J$vB?nJ_7w>AHUM+R52xuAQ1|h_0@l&#ak9 zT7)u=EtZxUtEztcz|8}>B952LH9@G_3wTW@zJw=LLJ zXt&ejj3v>AhIsqyRy|(1pzK&uIVmfY;1>HFWb(dxIB+Kyh0?x8TD|UzLn0i{ z6Yq$)x$e^1Qog^*9-L^sNT7+tOH=}PaOVcMuGfEwK1*PqN+1x$zYSAyXnjNH0L92F zPGw#+kjq>0w<5W&q{oD+tC_rh(xy;#h7?bftiEUsX&a#0%6CK}O~;%RjE$dlMcjPp zY=A+!G5cEVXJqC+mekGkO5F?~#*Ha)t2fx=_mA1Txvr<1fy*%`ANoICgs23SH;@G(bm8HgVS)Cma zh}BqD+>zh+5J>t%qy5t#Zn@?|x0ak=&dS^Q#>01}l>!a!Qx9jH9n?N2Cka5^j(;k}b z#9g<`+*LF{`6<}_40?t^4<$-{0CbQsXnoj$Sn}l-25qQ;9*PuN!tnD$3IqvTxcafG z_ao!Fpbexrl6y-OK?cIC3T>bRNAO)m(xwj~K(AU9?A;o+>dDlQQ%Alm!$81Jt1gvk zlv9x0oVQEzZKb$0|1U!X}9lCdASS!q(~yAuR9eu`*-ja3Fv-#Q40Gjp-X{fSTW9Aana$NI6Ap)s`jN_vCPUPfJ+-wrHz5EfHP+~JC%S5nrVDUOn{Yu z$&~T=F)TD4Kr&?%1Nt#~+&ZK_u|jGE%%DEfPv+M#g&6p$LQWdEgrA-w%L?DnVI?f} z`$lS#dacwL60Km}qB6nAoJbEOfid=3FitGEKd-7?>Zg^&$%-1h0%$iNy&fjy6^(sTxS&d~y;Q?PS z++w3cSYyF*Ij3 z2;mwHY&6a&MRsuH-N}4bG4F{zqc=?=n_|d+Yr6*2Vmy z>&|P=h5V{$e${+_&1Boe{wb#T0-J^f=bES!*!lJFweUjm=4kQeTV=P+_ndoTC8ZF8 z!}H@k=bG5sa{1XEbFH4uezV|4LDaQjE_5p#-PCkHYc+TjbT&j9%ya%U>t5DgaQn&J zXCZrIG<)OR{+O>_Pu_YiTHSIlyERs}Vah@( zQ$I^DSuEf9=EWNq7s_`<%Xd+M?bGcG+3TX&>t;i5hHr!y%6CS~cfuo5MJCU4FTD&Z zSG*@8j$$$p0zYISt2~-j4jLx)X6k&_j)-#ysGa4A0l_MU7+COdl>n8=OHyuS_MGsE zbUGr3Lqv-*PiR0IfzDzj*D$s%Lok{8x`g6V6!)K|6eKNJ_*aB_ClvF6*9ydw4G^IT zwSQWkY^7nfo)w4A`^c>t__$zQDP_Ps8eabani$GQ7^}Ld83Py4kxEhk9!iAvCHz8`_&>GS!YF97mqWb!+wMpi^dS_-Ow%?za{{$w-_8$Y2wG+h#Y7f9pS7~G3kZ5^ak z61`Z1SRK?x%+n9oD{0&~XcDXtAVccGC{Ih+hNF~i6atAPp>8_gXDKr$O+m6aA|_|T zPi|kQVbUc26lEt}Fp8;y9kicHziO#OgWh>Ix{@d3q|&?Nc6?n=9%_FJV@E%d5Q(2h zsx8?0&2eX_M4o?PXQ)(umPb-72(6RD`q#@(>Rrf|YYV86Gwzr&4vvK?<@gn9m@Ah) zp1MK`J`bKntPUi(%pDM<_HUHGqu%v%=!fc!xLh+xi?#hiPOjKbju)$iyz#Vf>dN(l z#8@}BzgjL!y@w%nmrEXZhMjQxj2S%mGn7E8Cka2HAncS=lWqv$7_5Ylc56aHys9gE zJasTbKMi!Jr1gvONbTRgyc9uM;i%P1A2Vh~VHN6g5vd+A>u9bl>EY!wuLvdRLCCu0 z^+SJ1EdUu@zoguqa%#E9M6!a>D|fe?QoVIsS4Zmpo35Xj3EPYIx9_3^qo+SZtn4nL3o51&j@Fr9Jsv4 zSe0U|){Vo$FPzzbNN&A)7uL%2dOT}|6v{#G3xBf08wUQRVx|;~%>=0b2msKiL|x_y6m!mjG6a9v;H$e^`GliT`g|WhpDc z0(l)K92QV9?h0*^=SA2h&vhZ6twGuYor6vdZk{Hm2)kY|;mn@2ao2OMDf5+U{7JP% z$9E3M<>F9+^;lmkVp1Q2-xSN=B-?kwy5u7g654Xn2ybYiC*`kVHtUR|T-JDAn5ZG0 z6s+aO7k-!3kf)SNaOY#!%V05T{*+u#^iI~eYb6?p`Z=+0PXfEV@+T|w!tQa`BYIkY ztZB{V{4S%wYeZv_Shvb`-oM3WlOi+FWIX||Mn9kj2GU$1ig46%$g-;%Y$6vuTEuNC|hd`PZPijtj)A0@*ka7^$;*%5=(KS3yq zfi>d`T_im-oQR2I6xo5B^x;xE+O(80V3iWjoB=Oc^j|syhxd|}7M!4fd!u}Xj@4wj zsT>Wf_({g@B_I3fQ7)L|CwFolF<3|H@t+l3C!@WzQWbqtHw^Ftc}VesGq2jZj#nRZ z@7P>hy~RB+67Z@{{Ojx0ZlKxG4$XyQ?hWoOyLN4=-Mo3Td!xG*uiJOl$*+xgt*zb0 zUe&x^_^hl6DC>_vy2`arcr!HhM&m1$Lq(NN<1J*uTGGs5CMa&HjkUdp{O(!!~NeM%7mxMt9GL@zPlf|rm5z6GgIaDHZ=9~ziaDd+|N;84&X0rE^Mv+>Ls@&bJZij_1im|arP4cRmf@uB%S=&s#TN6LOsDFoMl$h~Fzc6SAs=pmnG zOeiaJ8!s1tgqz(JX9v7J=PNOBxQYx-qG;ZqIm5?_RtS5Q zmL*#;;EMJ^z(dDED2-O3!9ge| zu>PR=!6%n2>cAu;8#YBvfKo_O-~)P_B!VJcRg!hF)kLt!&7lj2sqEOy1jvknFo{M6;7P^j-d0U( zt#(T_bM{Qd&@sZaD4EN0dSKH>YN19Yi)jzT^ph4wwl9En_-G74rrENpph@K9lun76jr5cGICI z%Q{G!3H9zH+&3n*1%=SjC~$nG!a&w&wL7$(#CrwTHs8!v1R)XO&2Yf z)oBj2Z6iEG9i1g2K!PbB<4ack%uVx{t+Dmk?%M6reFwj9*(MUFNck{LXZDhb!C0v*NNR`Qb|B%5o< z6^KrxF!D%(v`n)KY1v&9&JG_Gta1o+T_v6k>0zmsD}u&f3XbxV(#Vv)e1}eG5|?^% zZEj){aErW7JpJ;2-~y@RFml7Ck$+Hp2~P-^M0nhIA#UYBj)WjsDO~9=TbjW*Y5`b@ zBt;$D$cC;)imTbf53SoL2P{eaPbg2d%3Hl=#(Qo5Z0+pP8{4iOoGY1YxLI~9<5ulE z**7;vi?-i3-Y)r}<@PgoGJY8Pp(9$0#Rlvv#;Zmg%vflFl<<4zi;xsDZFnxWB2(s?&2gh&yhhz>OxwMT&H$R6K!3j%>m4b>58amJK!muW6yw;=CfmElG>e;Lpj$9 zIN1)KD=1nqLO0C`3IJm@OBz5$AK|-}T5)DQK-&z^Q(n^|6jd{}d3jYOmiR8NkN7{0SzfFN49Q&YW;1`1yZZ#d(B(W`$dpxtjF-C)5Wj)fcq(^EencE1IWufO zM*IT;8)OVFJX(V|7#J0aDIq>hmv7SL&vB_-#q}&%XT45E**NyYwL@%tr;MjVjb;gi z;~LwnJ8jS-CAZm@kT@8OI|Nwtz=oDy#BKOOJc%ADff*Jk{2V%JM?8h$|IF7mZ-gZ% z_MMHJacC;~h_@sdPiFniT45(l;w`298S+P!aPJZQz@+E3LKHb9T9u}`>rg>G^O)yeg%0U zCXcRpg;&GV;f1`4XkNv%WihX43M%F}DC(v0Xi04>Z}pUg<(svm}c= zukDUF*Zjhffr4z&WoKG6u% z(yJ$@PtJ(1ot|iUAHD|mzu9`D_02;!4&6F>w`@nOc-{49uRS}rFIrqb<$PeVWbBOP zRXi}$y}E(j7jyC-TJiqCX~@o>+4{xZ@2{=9ZM)-~Uwde}{eDjVO!jLhXG^~Lsrzdy z{*mDD2PNxgpZV_Exq@A;KJ>t3EZF*?*_@M$udglt;z4*GEH0fbd$aOJ<=lz+HQT0I zY4k^@M`xSv=9R~a*OH!5q_{4UUx#Zfzjz^kLo|QG+_ty(+}v|J`$t7TELzz0M0D2^ z_wozIndHBZRg|a=- zvOTwt-m%P=HP0F!q#N=Jrbh9-YnDa&NJTWiVlMYq#=ZQli-pCrd!i_Gef66|H->Hr z^XqqCYeoIbYuLMQe*K=A)>!fSh2l-o;!U?~^Tl;2h4;=(&)tlYSs_x>7+v4Ev~%FN zc*^mC(nHE9FeRs>Kg-^9Kc{%s_{P?IIpszF)}O z7|q)_*F2xM1;f84ZKCB$2M#$(C*KF!S>VcoPmTws*p{6?sClPmVM|+dOWXbY zqOTu+W9yuGcIUP3IblA3Yb<{aX8G3KsTMwmFwvlWlf7!<(9{l^-|16bv<7D_5$J2d z17$`IYRZ>2!Yqn*+VB=I{Y<2PVC$Bv@owB&PWGW@*Dxf*< z+V=DG^^1AM3whPiylSlRyzKxVxoZ}3tD?D8bI0d%w@#U38>-$ezgd3k_}vZlGflJE z*LL5@z7xFTn6k%;$`*>YMvJz_vWsSpV!r3kmE0(tJNtIu&AwY9bjRwzNb#?&lOPsb2bo-e|+2j9cHLP3z+Xu;% z_O~AjMsyk+reU@qZ9(yM$2A8meDb&6=ddAC+V!*S;|$e)zc2kiP2IhLq%L z%(B$#4+_^qlW+9K=zL)gelY7kX@3G=JZrSMBYL0I) z(sf7jsU7COH8f)qTJg+~_a#bgM9g5THa`3|uFRGJdwJqdRxyHb$8>p zsM4)ewyqFLu(28?JtCK$0!2pR2!XJ-gke&qr);2@gC#)_24+LzPc_$qh}WX07AL6z z>BjZvC6)(=4pLCquDZhx+ethv*w2IgfqqJUM2q$6XwYk!uA2yU{<_>|nW-_JB%}zA zfz&|SI0%+-l5S}_YGiUt##2_vQ?k7E;S^PI0uK9(p|x@v)yV|0W>y)-9XRA6xxYw` zSMMmpAv0jYNt#|v0z1a(-HPlA)2xXTTTCXwdCs7O%a4?Ef|Hre5wkfs?CT-rW5GSh z*mO#MvRNYvSjPaDhjY#|n99scH_y#1-B_+F_ny5(5G&=${AT7r8_a3WTsjvjC5pw>W0#`>R;w7Vg8^!1#V z#dAvUB(#pJI;-}Ga_R%#jva~?SfgdxUcmjt0&CJ;9xpP0Nf)V^-=Mt;I@$Bm3oidd_(G|Df1K=^YKbU$wqf zVmlZMa%`xDR{LSL+6e}cqks2a0I^CYI9#%RwDDUJ54kJ>Qzm%_XWI`s9Lvu=8nBh` zA0vU5X3}#$=c==?4`!koVh74BJq9rLkw`%0i;mT?;!y&z2itijmQe9dBYlW-JrxB6 zhTe@8@+pZ!6VOVMK0#oIquL?+2Z&@WQDQV!W^zuRmp*-#E-%tWpo@<#3Oi3E_KwJS zcq+5++Z3j-%;IUPw`FP~XQ2_ZuhPlcUw?%3U}Uqtg2zp^XgKfi52>WTrY{n+OZ+~) z68nnVFgc};;{N2w8dVFzIQxm}BD*h;JLXN|b$V=&0 zXioV=3pp*IgS}dCkjwpol7)h*XhGGKjXbB2b3fZ%$C}w4_np}b&f=)Em_3w6ouv<~ z<}L8%Yc5N9;523&FoG^hO$Xlslsk8Z@C!%gqBDz3pRRPoT)D4?;TR!EhsES>S;Bqd zpPzL`T~)E%!%Lz#V~WvQ?4Qrrl|Zh?vQ}MvZ2GZCR!ziNgKKPc+4b&g z-3zO0qpNG@S8pZCP+}NmOf|ezAIsdNwQycc&3N_X?7xK!ZdF6AqTejP_ z`Mk&GQy-r&{hhsZ(UtM)$mGa^Yi-oEcHXrPY^A({t0U7RQhE!>`Mj->Z3k}k{%P>e zwm%t-?l=(1YnyP!KyjT~$f=3u)WFK?)O=3kgy~8OiknDgqLn356^s`rM95d)Cm=+0 z?P`GFQaK5~ej;)bellYB7N!XOfL0mD{y~8hO+&-nOp9c=TyyC-#IIUoD5waKLDNNl z@Eiec=rJ(KFEOZ-35Dd{FDe$7i{2&u3k<>^u8>@~r;=hH26EYm; zMuaVGw)hwye-YiG@y#kyplmcqDqSDZ(pry1SX$}I%92-7_Vv7LdDn}s6@6{ZysIK& zui!(i6?zhN$Y{?0jt302@iLhaNdti(qdyqD_>X2x2>4|W6sP#{d6V~LP>y|@I$B$?WrE^qnUC^-rH!lGF?<9Iyzt!@{tkp zSwViipr9dXiKr8j@U62$mq^Dz)k4`Osbm0c;R+eFTalS9R4d^B3Wow=x}C!tVO0Y| z7lElTxrkDSo}nR8fLc?CE0-v`C30wWa1;|g0OUf+LOKu7R1p2xtuWuYnX!9o&9<7& zT#3Ye5q8L4C^?NmA5cDcNK=4>N}(~F)abz(u4p#v0y2GMxhwQq!CFws+pIyZ{_oKc z5Sb{PX7o6=XfxabF#@B(P0#39*F|D(e@|Ngy7BmyiVO7cM$n6T7vdl0`Tk zduDRSRMU)cy5*(EVwv^Y{UVl{K9w& z=UrPO_AMMDDC-tAQMgcd@S=5ouJUtK6$bUJRjhakuE_UOfK9UNR*f4TIN}_`nv_?b zCWel8(ZuwcV0NOcX_Yeqo`JF7fyyQP$gL~*F1B992@q{0-qXM9s+P{%V*7+-oQ{1* zvqYFeDP|O%l?A*Ll3-eDRFI^OLS zKneh;fHDbs2T5g-k(xRj0Dqt!E0-MxrmdV(a3sw*6;f*plLf?SA_ zhv29&ZuXuH#tU!~vh4Q~4eUOPGnBho-^@X`GPHz zX|U>SoH9){egHiaaklZ=#jox8Zr0qfTctOje5)w3YR81@1AEErrh9grLX+|8#mS2^ zrkTcB(`;iTuUxx_YF7-+L%bUwV!~s^FjMoB2v7zFT%lfnAF&Y_!NLcRnS_(+HNZa9 zp~+@jay9BraPF>@!!t6CHh^J%j@T$cWJRGFLVk2G{|uv5Il+PrMk$2+CUWC;-z9Hg zm|!~LPULEnwA!?270qgip+)l!d?}?A=3E`|s@gBqV&VUS8pKvXNV8ztNQ0B+HK`eJ zjkf^Wjr~t)F;`wx7-W)~I5hM?!I09ZrU7Tp0JtKIC04gcc-P>z_A(O3kwunFQY-fk zaF?9W`PI}eK}}GiLGfYLJ-{bWR#SQg-@;KEJ?LXJn|6FYYS1Zwz6-e$7zGgs%|SNw z(2du2I3*fXxg@^cUTnMxRi$kiz(=Yko`|gU(?AC3TvP6=BrpVelYN*}pO^SF=@}74 zB!srQHWQ%P-@}04)ma@W89MZ zYQ0hbmU#tp(O2c>9{IpJlb61vnZ@^7PAg{v4lMDn5w{8=JQ&EZfxXlbY@q!OyKRl^ zT%bq0lofRNGF!?Jv5@T=xm7~>i9Z=7#)kASq=1+kCwcpnz9hSNPb3WBMD@}z21rIV zk}d_HuCynxlrQMK(!$2vytP>)=9-*!v{WCgODRbhnSnleHR`sMji4^Aq#F}es z=8|sZ%@^#NchyJi^~3W6g&rGZ{bDUR!Zi8Dt zkvv)DEKdQ4Ikr#N2pCC1D zV}NfQe#(AGlrv{o5~x(S0BC`pfxBgF07?m7MY$aNER_ZJGfodBc+9LBh6H%kR+zN> zdpKxxNElgiKC1-Acp3F>p3Z&VC&Icwg-04r=b)AetbU-Tjj2M*zK$5{uhJ;?V+O@- zy!5es{H~f5srrd5H~)BzR0raLd&%V$n$Ps8;ppfOP#i0h@e<;8LP^OFD?8IPp4{8f0ygj>InVF&R0iWh+{gSB>2TY45;%&KE^dYQQZUwEL>lP;0+FSn zb}(`$p3IJiWr>YF@Sqe3E<1vNWs$wU@HU?yXhek5Wy3#$jZvx)FCRFvrdsYf3g6Eu zeC?@;7CNl>!px<6u8LUZF`{+~XPRCEx6S=Q_L`Xsv(GM+H%7}F=d+t8lIctk97X=> z-pRc)4R;-@Zxl$B)y#?Or>~uchEmSxeVy45gWwqriG?q|-Ok;W5XJ0?3H7?1^JK~sk- z%$Vn0Wf6PXKm9rh5v(VEysyEqKi9H^-$pwS1D{=Z(2`twZs@S62+vIT$;(hrAkO${ zA1F&hC#xLm4#_mkb7CJSS8r;mg>i4wj4{WG!0xd0^8yXbfH zsGE={Wk3n4D+5Y|$R}c;N)Qprm7m_pv8rPWM%%U`o6`6u??4ZjROEV(#_=o>VuXql zUrIua2Zsi$N%kf2u>f0{y`@qF8!ipLDSHts`2(jqLu?mXzH@xMO{;%c2otYU8@Ncj^9$^0@Wfyn{<(Z*OMEvQBGKB%aSOD|BJmh zfsX6E&ID`2Uf6dKBntou0w4hr1ouS}NdR2LO(eBjCW|P51Q&pM1#WObqHHHFNOB9X z<)eZnhhVHZ0wd*^N_38?6VI4RyhurRriuj_Pz5<*Pis2u>7H)N(sXQjPI|t3|K+_Z zJdm`KnR9X`PvXO?_ul`%f4%>`_rLeMYBG}Nqou3CPO?Ueq;Wy;F>c@qK~&lJdkku8 z03qX-xS=>onml;-D>Qd}cpJ>MFG&>*Df*>nho6lM#`Bw^nN73VM`93}{#7B{FFIWq z`)jW~b+l6$YxdG*vX=qvc>{LJE!inppCb+okfup_9dy2!rLIHn9v9f2La;r_jHp&X zg`6kb(R|K}P)$K`ZcDlCFyXD!T(U@Rut*;Nr)VJErzRnn+>ema<$iez)z+zKObc5Q zh{l*I*pU=eKoILC5G^6yrDzC}$T=m`*@@xggVXU@j6WhY4e;z-MtkoBba(XB+3rU1 zJ?Vfb)ZKnKVTi@SE;l9-i1(oh7Z+HSQ*J|A2CouJ{TGy#%pPfrl4>C%oGN)alaDOW zo0zX;G|?TP3h+C2bH>MDoXQsA6ws`b{x97G|hum&P=qp3Z`)j<}O> z9yeY?UI{nc=Yup6QGOL2Sc9XPOMmmLEXT5g&LHhTzn7l9HPiE6VHVCw-h6rq zzQ;XG=X3KgKfk~-Y@dpk=l|WhJgeDCW1Cnm=wPJEO3OIBq6EpSm>K({C!qb&6V1Y= z@hDM)L=4B2RJ7rN1sdoJz_(4ZykYI3P^Yr@5_Hy>wfNW54{xmVa0jN%9;_k){*g*6 z-?m6soQRfHF`1#h?C-NoN2^ASeCLxYWGR6xrXWtBdVgNLf&dLr4=K^Mncu zG51{bto6X7o0usW1<-Z+y&EP zi<-^kgSP1QX+G6^661x3rb*na%!6?YR6{Zj2@ltRW|g8T!+g=bGx4#xy>fYau5P#g&@B(I= zOyW6}eWsOsFb%MZdO8bUgW24|GPK1ggo&Ndx`?sZ%;TF!59onXtKPt#~v>T8)U%?k*f#I8g|HovF$- zvC1`5mFw_Ox)`^u0ld2@76@Vbr&Lr@3mKo$=@x#nY<)y*$k9y|HrOoH|3XFBM@7IK zFR{*Xt)ywanNvMeToJE$^e2mx^f0&+FMc%YeN;08HL?7fcz#_pvu-vCz=wn^;YC4! z4D5zF8WB=}3+oDGVD}F^J0`97c{lL|;pZRm(dM( zg3#jVuCj+Q8D0U^}+lB>(zOIm&So~TG7=v;s{s?H6$zU_Lk z079sH2sy#Y?2W~VAtc@CxHoh&oV=TJr{J>&*_W2?E^ z!QLXBL}JqhMCtW|S?bv_fEI?*H{mUH$8LyQZ985(5Xw+#UVO}hbmXhT@TE4x-Iyc9 zD!f~q;;Srn+oY6x53pJrazeCr?KO6zpBgg|n{WUsrK5>7pgfVgK5=`-Z}5z@=7vF6 z{AxC$42n(Hg!3f3?Hd%)3Tk)kga@$4nn)8@&(Pf*z7~cI#^-d0#4>5vkc|eyy2yt_ zlQ2ABOa>RuJtmpEo2EfIjnts4(+_O_dER?@Qx6=9J#c99fk!46JsNx95rAztueV-# zY{LKjC$H69`EvAuN5UPkMUT#u&x>sT_E31oNBQM{Gk@_&$4B$(#yj5Fd1YsOUdu@P zN44Z&TDx-OL5O0Jv!g>Z3mYdEU-MjD`p&@Q!cEglS6nN(x^bd8(lNeh?7`^@L<|_q zk1c=oJgew>(-<_nS{^9E%@wvPgQlcw2V*;A$cx#4nPq0&RMO?l3gJg1E9!r9d~u zmxLH~5z*gHpCPpgI@crm@h$ukSPFE7yZ?i39K#!YcW@p$+!tcX_#`fu0jBBVQ@BAI zGl<-@y=7dbB!5JwY@8C=#7W~_@aBnhga|Qu&+xa9IVsQ*9;3g1fV-Xhl@UCAKIyZc zNXJM(Db=2c`1S9oYiW`C%_YaD1d)V_)0leQYSBzD} z3u>?IoCth>Uo?MJG;@_bIRlY(e(D9oG#4=g;;AIW7RNIOK{|+|uNJGH`eFHNx9S=c zliBi)y2ScR`|;|h<*ym$$bOBrGY~b`c0$>|^uNuywmXdW0h*?K*y-#LshDsoQV#o) z$kpD?bx^xN1~LN9Dow&QVRrV7Si>&`G8NG^zK(B|qV4%;!PBaXt-#AQ4<0MSDnCtB2%`8SYlnp#3H?Kav5TGdl5 zdmNQijTZaX|J`fJOR4Rg1H?~fm3{>8iMM!w}%-%BSdt0JsKsE4sP%8xs`*3kL}sL0b3+3{y_iH z?iM1p^9Oo+dN%AcdZCDeKTdyN!{*x1eT@xIu4rEWR3qCHH&z;6qV66lOCsa2Fxe6m z-wi5lOwiK|qW#CaFBru4C(?pIksIJ0cOw@|cp?))Lyyt75Vcrc9LC}VXG@BQ%zwR< z^I^*8aL*ZIG3R=?zo!SVlS2F=N|Eqv1sqHw$5LeDAL!NeV7K4sIxf(@-4Nc-iTV>_c*q^j?ms&0=}x8FDvuio{3>-#IC z)qCS5`xxM1Gz(koMU{~fSOOF_OfPPHG=X-8H=HrG3Nu zB0DF&_4ppvTbL3|>Azm+J(zQV?$F5*TwLE$$G-p85|yrW>(H# zdPzgYOYe)gm}}{MuFQV2+v&H0&Wo_ovVZ?Dx?CK1jxmsWDA~jb4TiA|FGEW~lf=kJ zF^z?Ex`i}W5zBiRfzN4x^DrwCEUookIS6Htggr7w<2czEY2%09c;d>|H)V#yqZ`x=8N$TRZiZGjU3_2XtL)QsU<)P{^1e+;Xkx?7-VaJNt5%Lhh z=RcW*fq*Zj9(E~7W@3qKlSP*Dn9PM*$b#53>~YeYklPlK+!nG8APxIAJH|s>YK78z z^tL8o?&={^x$MIESlXZ{wH{z2Y*-7m%uosOP^Cc13#J+Cn z_GwPoup-u41{{!B-R%JFerleSn==tu#$o5*Z^w-2(E+Rhn1E&@H`}xbwv+kX5CF(+ ztp3cJQ*e{#P9V@sjjBBWBVAxUC9^yT1Pr`m`-KyADvkNq8u(+5RCbJxeJS;3weHQ_ zfhFo&c5F~6SHGDvuvEPXj08E$Ry&6B0%?KtQ)Q>ihw`0{XT88F(K_-_UMT+r&GnQ+ zjd}wClb|)oJ51Ark5Ha%a2AVF4sWbgZ<~KrAF{s)S~&FxX<&T>@!|he8Jq<6z5w$i zgBi){)RdSFcDLuy^d|Ipi4%uR@DzAiNEf#Kg6uu0AiC%AbqxnknRPEXr{-3`ty!WI0`7`A;<1Ozjo-AKCUB4>2c+JS(zggTi z!U%1I<5n_N(-x~~yS67@v-QTFsPDjsB?qA&sb9q?e8ZvFc3j>)wtK3&Iab{q&u@V! z52UL0S9Xl5b1@J<>iSk;B^Km5uPuDJ&g1`f^3&z~2@$-=gf7zLO0WF_J%3u{u_< z8gNdnMbH`5uNdDwvK6%j_ed3g=;a5e3yNNW?ZL}g(*@O21$D84y78@(1xx;+*ilq9 zT5)^6!?)=6N`QfZ!Jsxl#7uGwkCaV%5eai%G;`iR%;Psd4-&=r*`_U(JMK?=|NgX{ zSy@RsY7An*XY9qr7d2V3<24{qIS0+nXH!w%9fEgy?eX%am6y#B)hGg_)PRw~I6_Ez0u@PKn)t z4I6yxTUuLInD3ZdI$M;*J$8)Y%m77^WLv!&Q>k3%_F7g_OCq@aMRgOQ<88#$euD zVcj8skY%B*UPi`#YQs|xK9F)qmfQB3oo3a}e$w2RL>Tb&#ti>nbcOEWb|@8e1YGEN z%19d*x^Z<(lZjczDG+nTDf0_&lE!IFOCc+wJg}wX8kSFB@j61)t*7~Vh zcx{-ma^;suKVsPdwM(d1u)lR#O_znea3g`^ctPMN2lLMYae1X zn}l-(D-i_AC(YK1rNpdHg7WYj+U1BzE8r_6-JL+AEv-~|(yeL+@XsWn5R@^+%6)#>H z^{$-GFPW|J&?^Mha_-4-5?ucsriYWJN5B(EJLNi!y;1f>({c!EBo9jnJFFObYS^qe z0`DT(=WIYL&DDxwEF94CxapGy86Mmx@8EhM$){nB@dPpmdoGYUh?0Dh4Vnxv4+RL(*QBAXjC)WnFj(~=srfAHz%&R}4MiMwmgsvt2&A94gqN#&8A@kfQmu(ac($6_)dY zSow;ucP6KFUG;_o`vU+-P(?~|d8QC(HHtrnD0z@@p6wF_R z^|84nynST%cx$X=(fHG`l7^VKak_lP2%y1NAjfNEKPtU`{?8V~%Xfr5FM6lvFMt9M zYCF;lgY^a-8R?687tiJoF(<^*NK4V(`9u3rYsVd$wtMEL&ztBKI*9M~=i-MRPgV}j zVlwBWuw?=Wj{NQ!yTMA(1t)jmqF~}o*9|a60R6%;5cD-%fX_Vw)Ew+iGK<4nVDIdq zi)5}AhiC?nUyR_qU^0g}Nz+0Pd&FEL|Gwr^{)@D<(kwM+9mbs1^j69Ts25xDTUH?H zea!Z0KcE3j`UYj)>AG++$t#3ju((ul`Nn9R)*}(dX@%ywv?~jCNi3%66F5Vke5MwXuyv^yvcA zF;KG$-9bC<`Ox`(ZBYx))L!fYb%}UzV1>XYpd)c6hM`Y-Z0U~?x!{Hcy*<@WZdd5^ z$C}~pK<3jTP~PMGli(EyXq2$#PC*=`lyrbsFg<;8A;+0zH;BKMtaZY9A>q83%vL`L znmAZ2NK#V53F_rF=pgiRG7c46?=OnwFN){a4|~GSa4Rv>TV6Q-nkVwms~JEjk7h0u zGyuJ<58dnSDA7Iiy3<&L_0c+RWLBz|dG)th-R$TDA;sFQglbh~nNFbbZq~DIXR=j@Xd}V_LWrNE=)WrBVz*u>Y*lWs*OpPc1&gTOqdy8u`b7By$Ge zV%#?Js5uIk=VWu`Wj+M=gKS~Cee2Tuh#@h9#H>SV~&#TxtOUt?GK(L=Mm6^bG_0J3gQoAMaups zMo+hf95V>&sXu@P5KS!wB2idP)nJ28`7_IiuPEv!#u`1-xrlcdH}kk(GKfKPO=kEI zbgu4d;e!HWux^fEX8~Y4iq((8KgthUnvCT`vz^4pxV0<|qP@z3CzC_Aj9HElQk zGYE@dU&$!@s)Q!J@ryJEVLk)cEg1?6zj-cM zX3-ZXT>9%`dj1m#7d)a7QdZCmJ+6s#=}!Q67`|O!gmmdF4x#cE^7gxsE}e%WVIcPZ zVo4VVGZQNq28xW*$^Zdsbf__-tIc%G*oP5kC14;@Vr-d2%-D~2l4;f<+))l?^8F8q zVtrLmEYqRPhGMZ>*&2xjQrs5xw%O1tdg*thR^;v;&-X<$eS%gIH>(aU-5vouX7z5c z+L9J^oAg zdR%NDVF{dx@@rFEU5Yvw%x0cSKaKbu;Pun(EL;GycXN7~h z6Vw^mxzL7Q%3-OW8zpw%wGC|Sd``?y$rL}~>j7W|yYeX87}%Lnul)}BsotcNjXC~5 zz?9I0W5c}OhE#%pEkQeV2L4lU!zTxIu^}s*Q83g+WNQI8!7Nm_2u{0=_ifSA$%to3 zQlK6l=p@;eXU|~I4xP##_%v=rJC^@6dEVZyYTk#{AZo-MJPLjglt7AhH_az z-Pz9(&hapz29XZC`v~R582WyOGuHLS8&JGRwq8aAmU=}wTUGHi=#qsFNZFW>iw}y) zBw8DNYt;!g$eFcF#H=T?0iIx%Zd9lWgiF2!zzqt9N|9Ier6R);q#d+`2@PwIOqm%P zP#)vTQ5+plzN~l)OM{gs}fSOut(va(9cJ~SQ~HBy|2+vR>pA5 zmX-9g4G$7&JQil5UmFim(!bVuQciH~;8|k>eEk?6D_bni5D`Ef!5(}7*mX}J$Zy$5 z*K4aM;S0!NK&Q(dwnj9$1#q4A>7ugmHo}P|lQhIIY=Ed-DZYedN%1&Df)~FW80noIMCR zvgPV|_#Z}#*T%eS!`sNAqHN^oYju-33;x!-=vL{%snUj6X~RU32tOPzT|3-4lUp8f zz1A_ATRZK|dkLm`FYcs$BZ?8T_44+y?SvBqLxc6B>&Me>7B8MC`a${C^60v~vBtf( zlsO?gv{tqt7%8GnK0NyHaObVk@^B{rCZ{s1W0}>HnFvU1(PT-RK)6;$>c{I4&hq?~ z^B;Pb(}pG43d;K*dh72X*!^2{O_E?|5t;_HCea5#1~To<$sSnL^tf zxsaG>3V_yJ^tOU&kPvX6Y`}o?S_DgNQVpSRmBnyQ-e8fMOw3Swo}+~wr<0BXWedS4;l(ncI+Z7dG) z>6SLo<<{bB`Ux9D3n}1cvw)j^!bTvJ;x4sWMkoViwGCfFZ^^PchB8rBhizH4Ir>oM zfEHOpnI`-$J4DzCkXdlZmtzw`R1Sh1Hsj}#oqf%WY`z5Y6ZRgD5%fPIxDZkel{g|g}EZ~$YB^;d$R5H+i zrcnl6yr{SYUUqe%1X811fU(Aj4>eG>6o3W$x{ayJmi)4y&`IC6epLv6kU)6pHP?E} zmjxRkJ_-{tR1jLcJqb1|EK zf46}$VwVD+B-^(QbXFX03RZlt90#hzC_jMz$;`lH00tKv6y;Y7wO<;HO3rSuuH9@} z5gv_2EU}p=Uotjeq_ZdHVAHJZG-4M+2 zmPU&?&E~y`pY{_f5F4SA9YiV{KrzlZw1x3|^z`dEA%+F9?k1yc(83L~A~p^prXb;= zL1sKoq>EPnM1dRu990HEGcF`DNz#dOh1YZ#dsZ~}{7FM0j!c;J+vczmnq zzN9>W`nT$Zi;*qQKQo>DWJcy*NRe-nBBhaOZgu3`go|7V5Yzo;&hqK9is9|I$|_zt zHhL_&pe0_mJWLUw^GinBUpOhak@53y3|$$D&0lpbaJ}{IV>dDgEhDyOZ?t+}EN@@f zO}XZe)JIlbUO%=zRF3`v(0;$3cf>$u_<2 zp0Qs<7%p|a#dc7qV0#!hj=2RJJ6N{%djwNkZ`iaXh05YRP}2 z^$B*L>S-bE-R8};J8Rh>iFJ91=*gxCQURjuFyso7tq2$Xa=9T=Z_y=G`nOam-6!$! z2mC-JG^4IjDX_+)mP#xZ)&;7PO#9SxYlTTl+uNJQ#WMdi#@7w_yO%_uCzNP9;s;9PJBOvm^4L;BtUDIb{rN2~=F z-aH#NBxQ}!}`SMWDjrIr7sKXAbO{j-$5q2q{vh9N!(r1 z$~ov$1DZZ4v*8M$i1?Dp`j|$V&{NrCTW~|p2DgCDfh{?{g?Z2B91QczSA$F0<;x7& z$6DpF&fP&^Q~k|^YlS-Tq=2pUJm-x9mRYKq^|2RY~ib0qovTo@t~ zS192AzCkas7tX&$LaDzA{%`mYa!z{ULa^AAZoMu1*le8Z>^zHkj-dc(cvF*jphITV7zSQmBI0v z(O{(YJLkp+V`VF0L;dL6kN)tfx1WlYZ6(g4GQ3?yq9qT9TSfO}l1(qSXh@esRfrZ~`?9Xyo@^1g?H)hm>{~ErTWYq#{5XL3 zv@;^4@j0+3Pt=$x)D=o%)AFYLPr1RVQEP2XSC$?Z92|E7UC3dVgRQnfGjjx3VcY67 z?($%yVB6{;_gCQ%gAss{Esn>5vpM8`#tm2eT5)w=J6odET6=<$7Q+Z)j^3nvZBoxw zX9OS^(A(639Ms<~fRR&eP7gUBcf9z4b^-PJp?Ebno3{i4ki02qEUQh3F~b7S!7ijx zzEm^tIwQ6b=oS8{m!m*GcH6LDEjD?u7Fu$Un-xj>r?tDch-Hs=)68Y*5OVJ8J}(4y zEpe-@IJs1|Vja_8mPddufgWW7Smj06j#R^C=~HxH{S*Ndv5R4^&_oLIg1 z71nm3qO{Y1XhUWdj4NnfV=FBjvKZvqgPt^1HM! z8sDG{NQPh+ANVnRldiu*CwfQAS?DWD9fMGJz8!J z-X0*ee|4(UUq+7xAGVs}G4SfKTxDtjI};OeE*_S6&wC z_YGP*hmi(rC&BA#<+fb2qSY&6IV)~^@^YJJ%4^40y|Mnv`gnQsHFvDMZNziim04J$ zob~sO?i+8PENO%t|AJbD1~B4zIs0}t!9bClkrx<9)5Rsj?YD|c!tJy`cfa=VWKP|! z{1O5&8n24wFP$!HO5PbLBt)ebcf;S0-iaK%nePK^Mbl{7?ez5Aazbe0 z*a5y+0Rr!gpPejd#)k{bDI`?JaK=md!}*c4%b8=D?wJJ*6UDFgUu%t4teRfnBhTJ%ZU61< zTqOT3!v2(0{|e@)&DIJ`v_=b-{q}YmZvXbPCP!)A>$?DXK(DoZT!9!=B0>-VGb>hp zD~(=j`#g969Xejoai8PedF^$M_e$pB@-G%vcg}bGq%OZ>qx&Z-@9S9O{^^Qz-2dsC zG~D^=MmJsGm(^M2{#iy|XQ}&VrD=3MzkYkV`{!v+oVz^8Rvp@u?8~_GMfm|c2MCHs zh@ApSi`kIIWmXe0QRpI?&Twv0 zZAY|}Ljs$TiIzd_1pNn8f*^d>4K>MiNvf!{W6HQkYV3SKDq&TFImtUwI_>S$E1Xf) zTcq3J7$a)LahZ$wpx^?iK_c8c}fbdX#T8$ z(jZxPbBE3^zc<_bDhZ%Q_pV$zl}Em>LpWl|9v5bPf~n^*qkDw4cNm&97Emqr@+W;0 zD^g`p8XEH~$;d!9B824D?FTltu2wdK8+TJMN#w?d#iPHMmJ4!Z*$Xr^cETs&K|pDY zfdUAZ|5tH^y}du78z<@XH99ee{}Z|*zS=lSC(eSr`x*JwVAh{_edX-Wix9ug`H<#| z)1XXSKJy;b8x-ui(E0Kitqs$u4{ zhICB8A&cfOnXYPzESsuoid8kivtiTKP1j3)T>Wl!ysC3F<5pE0J!^|qwOw!j@$Pqb zPgd<5$(Z)ljAVQ#_v2!qxB~#7xM`-m8cMdWjCiKY>PJpZmDR_}>RD%1wi;2Q=L6S_ z>}q23n@0~_YlCxt_H;R%`{CnX-#GE;mAx-4If29m6{mq=&i>T&be}U#;{uOmk zJ&Xd7Wyy(JpP6JA&nc&rBk8$~9)vf*UbZYuE_+RgTBM9;EU+G0+rcisPoo5OUl3bN zRkrCotStfzNFa@rO;~=?Das(67}BbsZ9|SWTV0m~RHp5-6E<6L7X6kkF*Xe4lFnOv zbC(->oM#a&rOz4iaCvM1KyBR*AUmip!0kBG{~~__5(t46;j_XL!CacyY!xyHG)8BX8e<5&`A+Cq z0s#hgP^x_Cy zqiS3MB3F`qUl4KFz!-EQBlcj1t7dm!5K96t!oW~8ml?A6=6KfjM!swqhFPUpPF5p1_-nM%iS0podEu4C zv?Td`dY_keMWt7O3D+ZuE!PEqa{E4-%UL~|>h`8|U zX>Iu{JcYcof)qKMpWiHDuA!8H%)?&2uz?T|Pmy^s@1hx4hOCyBAq6XD3W`TMzMUQE zi4`oud+^I8OU!oYab^}RnMnKou4^@axDP=;{NK&IUObXUF+q+-o{nVUG8GQ0+9$v( zTVvI&?<~Ha_NU8kc;eL^;XTtWD}T^?wfFj}n=SW`JT=}CD`~p%RJel{HwKa*xR7zz zc!w1%#JV;RHN$V`r~ioaKZjUGdSy^%Y{*}_2%79c{wYTwgDE*hp4C>C<||37kQPGB z=XQ}KR2qU+4rFrfu0R%>KiK79XQY9YiUtq4Abt@Z9Up=0uRBa(%iNWi9f%I;iY)sp zdi@CGa3DMnm5BCW0^XsFK<+VTAdihMG6%GXWP;t1W09Qm$E}?^uGR^ zM!QT^kkTPOW`wd}rj==K%I|dCp|%tryvUOZcf+-qz?7}7b_=>ZrpSfm zkats9x+2L-td1mN3DC9I=!zCgl9luUYAu2=()y)CFoK?vyK2BOh>T?D#2kc9bW-R< zx$y2aXnb9DnV}MsAgTTUUm2|5NxmH|6jSkxY6mmG+ood(l6&Edao;6cBFQ}MKT$ZX zXjA9A8?N~$TCX|(c+I;TL`cN1<`+79X@y~7MmUgAC}!gfN;v4+xLeeopxzowY$ZzO z0C;(4R8vBdOJp5Im-r3Cf6e#~7@r7$gywk-C$Jg8h z6n6Fek&fw_#lj+lF}8Q#SQf9@H=6fxO;fC?^GB<16#r;Lys0x@(>a<))~pNSxxVqX zo4NJVC8c0S=GBCE->R4w&YiBTint?PV_D%`*qSbEn8^Iag4W@^;Vt2>OnWOMU!E?Q z7wIMl>XX+xV)g5<lfMo_N*D zaK5x_dEqMn7B8(JA^VnztvBth7+;P|Yu5t{yCR!pZvnuJEwZW1s#s=KWYa|Tbx*8u z)AhiQPrZ9;>b?W9`wqnKJ2aX3utX4#Yy(6=*h3p@w5gUm9-7QtWySBSzA-de{xIcz zE2lDY=z`VaP2=8_H2kelrfnLnrp8K(`H^~vnhccyt2W3W&SX}p?)C*P-Ce)nq1Htm zY`)Orfes*j@KVQxGmxIennnJH*iD04Q@FX3dOUE#--VS-Lfh$ug(YROk5pPuY}`S? z>j$0-=|fYTrY%pf_YO^}xw;t#Q8;!b5JY=D{Ui+wB0d%z7HBJ`e zymb%Uq=DlJPgi&Esm3f}zR&kF%7ZX|XE4ZgGF9u0= z(4NXyC=xI($woh#|iaqJrmi&_dG>@;s-s*d9*wo#z76Akk zvbwE4?`GHc5Wo^%B_9anRz)#cX_%J1G4s&IbBIIQK zK`mCeJLJjlke(et06=T)@8VpTHpFI<(Ds9z>sFn0h}Ltaa}W>Z_DrMYeJ#B8q|`9$=ET^iBG zv(ogyeib!Xu1aVA#oZO=FLibI(WzQS2CsGvWgv9*eE$wChS`dF5bhUbaR9~ys0RV; za|51__h_LsNVOeMN&>toRNV%GyhDaWI!4;WemU!pX$yri75=Q)QDAvB$pxh0d~aaj z_%h$|Zi<#**^!msP>fQt1<-7!&0|6R;jKHj@!pH=r*?1IyX}d6 z2alL6Dheen5QKIr)klSmLWpTbH=H`}2b>|5JE|6 z`Q{p7Nle!(S1B_HQadT19l`7(7i-$P6e0zu|98&{?aFP-0O}hw+7+C+&I~k5R^HOC za`b_PP9As)IR+z&Aqy4gEd&c|ZK%3Q{y-+Y41^M9>MfB4&~%58Kp1vtD{C16gbf!F z?j&iNV48LfK+AUuVL^~u9T*C>kTRt1gMFYXkpQnTQ|hS}INL?~nPaTAgm)S!03dTt z_YSf%J7F_1c_1l@^@yY)vwolKWT2P?Avl9A(M~dyBtUVIt(k-}QWitV9&qQX0{AN+ zU1&JaKBo;(7w6Y)=_@2U$e1<^Ufw%M#S^)p)z6+n*cFpp2qVf3$T0blTK45}? zs=+E8{^3CqJ;}`EBGj;|8q_+_#&WsMCPW!#y&^?WLYwh5AVXm|N{vG^2=0uedF>7~ zS_=UhDeYM?PL44^Gws8o5M&(5!vq0=Vc+u79 z$p`jidtNEgmq9`R~)U(zE@o~ zzQo7gK@X9;&*wedcd`#rd@QX?;BC}i4WGLjTRxYOIS$NPf^42hV*h!iP()kOs1?U1 zktB1Um&{JI?=hSA<>JIzjn7@a23B+=oQueUDCryd?Z7oU8*u*zB+2RwA42xPwIejNSCk z9y&clr+sufK&QQQ+D|8fx)D}aq*pP1O7~d*O}cJII>2leJLs&Md4U8e+WcfkMtT9n zsarT;XkSLSLjEni!ddC5MgMX+2ijT=r^FPQCAle z+2UIa&X6vi2T4ekV@UoHFbv3bfhd3#1o&`IKt@!;;M3#;sViJP1G>$e- z71hUz>c`K;i(10lK5Aa^^59f?n@jtaM4Vaa**c zeTKl8QhpLPQ?#igTGBcD=__9z{c?2i#%Rf=lxLshW-KiFG%dS4?-LKMMmiC{vZN|f zGrE3cY2?6o`uNjVvLauZsJU6N?6wOp+)i`kmfUvW{o7@va(Y-mF^oStad6`3_?P1I zRz|DZuC2PBal`d)&b6UvaYxMCVYP|7l~W$gshjX#3*Kzlkb+gAaIQ4G0|2jp4snR} z>oRne=Vngzc=1F!VuDw`O{%J!H5(+t)VDWAy$h5BD1n(Hd?&gFs<7}5bvqB*@riZs z3{I`x8C$#a=F*+hh?-eFT0MT~+M3vc4MJHSThI|N>_i~V!s1sdM=K+%#w#Y;;)Tm` zr?`}2c1BoV7B6mydK*YL&vqHIW|{Bonp)KvTh)29p>w9ZN~re64^9+bd1P$ggaFx^ zx8{0vY+gsayz^%HgYVabcii)f)A{9*n&(523llZp4Ivch)cobK`OB|)-U<9@!;K5^ zHT$Cn9*)m{WF&jKs&;%ww6b|59lF5^-?-3>5v1;fZJFjO)s^gX0Zf7_OOA%4NtTIwK`bgx&MB&)!Sn1M<3$c>5*ys4C+=RNY zylBLYjSy*@BK&O^j4hb(OdP-Nj#qAq=WmW?ZvM@$PC7Bl*edfU1*Ln|d%7?i^`VVO zCP597fV?b-z^1Tk0rK*|amEP|7b*oPaR|4T@=7^ai31DvfJ>@oTz7g?t7h(CT*B%H zJ4Krt>J>6f(Pj{4Q7A52z|D#io0Lh46F02z?Tkz;hJFxq?c;ab0$9C?cBO;MtxZ$J zJvzTBFWHyE#;g%FvNJ}!OBv0tHm3V)K$SJKWQxqDs4U$uvHa7j5&$bC==^McQ3`F$ zYqFHBl7demzs&%UDFe*;F!QOhF_}E#@C5Hf>@Me{9gGO&2VXyXX0}y=$cStbl9daR*6|1gd}{T(2vY)BavY;Ih2?3?F@AzEYC(cx{(`v`VtvH+ z{2vgz!TbFtJK_=S$p1u-h!bHRBgI>Z(wQ6s4Zr&_`Gdp|VVkEm1+S^BI?@v@T^#PT zS>bNw6plOsw1RQ>__=GIA7;Is6 z(T5@#ASu}4WumzdZ(7N^eAgu0cEs5v63E8`@_8`i4pt&3n_UXrwIQASZ31<-`8M)Q zHP)~w=i0uZZ4{l37uUdQQ!m_h7zzV5s+&Vz zm9zS5Nm;AjGXDCffs^g|*M@n1~N3&BfRn2n?`$-*L^)uh0o>PyXzG-M(hlZ()*P&OAy zab5<$rHn{~w67{Ge9?4Uq0R1P*TL67o)~>F;=|Sn{$c~QFq_DUZcP7G+L>V{p#k(S#Cizbe%og+Xehn z`hYbbn=h@punJs}nLY0rNJTV%s#iEk@*n}0M-ns1I|>p}%d%S`wkhnZulFXbGh|u4Ty^Lc-gOBqB^>KXp_P=GENib9D9>hk854wE5Dx2Utt{%Xjdz(e=wG@TWJA z#Dc5f5lmeBUy^A1_nZW$S;`8mw9ZdS!%B8gUn0I4@SQ_xL+L}r`(Y27JuRS|puePk zfK4Nv0gcH|GAvKnijP9v8VS6@#?>%)+fBvUL#OXi={~1NkI>bBpwrjr!~iz;WtFzv6k<@ygv%GrXfFFB@bmO#H5ehBfWTSxqn!pIij&A^&%b)+@& z^w{dr%?LV;P=kJe%Xd%suhm@bzH<7SKUTjM0P|7rT49|{46(71P7mYM=uBkkjt6=j zSLqXa%Jt$as@z}>VGuvbTY^s+zrqWj7qb{GZpjc8Pc@dYaypU4#m6Y@Hr7&R576oN z==60u-A^Z~lh8na4NaKHF#LgDSnC^vqnB`Z^#>DfxGWk5ei~n=Mkf2iL>h_!cXqZw zr1mp9D4R~4U|LQ}?L-={hX$*)rzlCfn5D8%nA+XOAJZ3|=Z*hL&$DT^2wXqWk(6)3 zb>Tw7b@8Iv$%$OuC*1)kzLS1lOt|{a0lI3Vf`zt7t_U@(Sj`Z`cdlQD<~3F z--zs6SQbee%?+o0k_m*Lu|{A6MV!wMO3=P~$k+snsS#=Z43v+f{90^MBo%DT~Y zkq#gk7S)b#jeD2az6rH`QFb`}(;`>aIy926aXJ^llZPJICYysXpS`@W&(9Zu)s~1cWt?bKcg?>lJ$(6z zBX9+)Lzx3j>NzZcvj>{hFZC`ESRLj&p-kEmpg@x++SHroUzKJ68U}I9m1ij3s2EtI z-nw&c{KXvD_vu{k<$cUaFKoJx+@&Yht1_5>&7SZ=lY$Km;vG_sK(;wLjPila>hX#D z)Rp-cdYl~9GeG@px$E0r%iHAxTU1U1TlJOhacUdT8#&sBoLS`a37=SOKzWp&37VQT zhK=8@(wl!(j{(~)>tYr>Ftzp&c$yw3d?`m0d+HLDC?Q5B+Sls^(OMz#HA~MXXzbF7xEhQ7>Ak;pV*=DF#nqU=5&0O zyh(SdXZVhr>he`x6Z5Ju*Z+GUvz&gw2i6Wq^4^g!j|kLZ&1m zAlUo>$iZUoqJw*j?FIP)gh$d2AY&bt3NR5y|7jL2RJOVx67HeD59pqR!5s|t0<+z+ z|MOt?#q;o5l`+r+K(_La!M9}Sc8y^{2$;YMGR`vIyD6~aRg%5fE7o8+AHa6xB5NRG zV|S2ZHeyGm|5zU@XH>{F6e_vO)G7lMA>>#e;(#FZ-63S^KZhWT0&1QEwZUW&Mr-g* z>@s?fVm}L74SZWyc|)MTYr_#C63a%z9Z0kQohNZtzqqNTWjQRU0!IN(zntGEgTL-( zktlfI5r*F&ICoVq6MDlMfzVI3JdnkYo`CTkHxEL;k(x?85Zw$l6AuTnNir2V6eN$a zwUiO&neMLM9ys8l+M*bu39KKW_jMh5;k?vMRpTT_jv%1rN!pM)as)eWr|630^CL&N zFDy>KLKP>WOwix`XW+NWO^E<~e&eFV+z!Y;clt5JsdnG7XGdZS>=e*eJn-M!Fv z$cBLEYbo|D5nNQyq7;yQMd3*dh{|GSXqAVxhcV0K%l9@Lpxt256ADnEW+?tbwUXR* z=V6qL$)&^hCHEmsL(B9;2CPS<;Bd+|PxhjmKjz0|>+$=+4M5O`NMxo4p%Al2j9EE{ zbV*IU0PQxKx4SQpjVkG99`OUctiv$+4X87PN=+(;WHTip+M0Aj=S2-_B_TdZn#k14 z9Ey@gP-%nxr#MI?Vq5A=Hkbw4cQCm$JPwiyL6tIfL1|M8XjTVM zs6-l&dyv&nD3=M8z<7>M7wP8>I{l1J1T22*I0T3>y#7 zj|`$3hkMQ#@6mU>)SNVM4pZsfI0-e*UsH*^+z&);VL_V6kX<^5kGHWAxetmUiY=7z z7bNKu#y=!|e7UABoH<=o9?qD_DH>V%;>H<)$~#rQBv!uUE!PjSu4Y}UeKR*+z9zh5 zx~yt=`*d#p%WY&2g(yO|U2a&tl~%m+#OM=KrS-AW`Vkkx9Trr)wtal-MEYd)@^`jh z-}>Y2?{1%5)&8+v&Oco8_L4YU56d@(caS7(0Z1;cWUH$a6N}@;D^N&ycY7u?E2djk z(BG<$GxJ}}O3HI0GhW_$ttM8!YO0(th2!O$!rqxBt=E?QByDm@XZX}qUQH~oW-_nt z{oP^rzt1n7&M$hcF_vF9Q&949I=N3b&s5fqw~Z|rNheI@qL(%eZ+hXr*GpnKi)XwA zFLr*EQ#>=TZoKo2-B)&he{XDF+wks>=Pevhf5Usl`~AGwyyb8|r>6WUr)Z|C`tp*o zC6`;qS|%#sHXbco34pfzQifP=81Ihw!{z6%Yp)dayF>ugY9>UE!qb$~0WlDAosYqWI_hls4gnr2_k>7b*5D z(RvHuu}UZyP_=vK2MY%ltWPICa-?HlC({eq&FDp-MTDF7Cx4z8SHWv=raF&Py+;jV zJN#!6aSm)61=T^=I#snEt`Jawbpq6yH-YAG24L>T@;a79*nMNm3d_g_|Gf?Y$78+r$9NRJnX`~`|VTDWq95s1Hc{X4<36lN-L#7PO|PrVsKMqi9bXj_lvLTSPlL zcpQ*=@WwcgIM=iV2Am!kw^@Ud>-=ah)h;!;{gAr^{6+dXNF#B)yj!ij6OMLMYy)ij zTE-T!N`gm3-K5tDR!52y<%2UF#z;R;B3g)B0L?=~-VX;47PFKUV6QoG_wU`VqzrRn z?d$VB+}C?S%z6Daj42Y@SV#~)G&IVZnl1#6HPh{;re*jA?+oe_{Ln4X)O75$c-Y;4 ztf`4y0g&n(uFeAK9AHDsP)cOL7`xzQ&mZrFyhYpO63DfOtQIYefbyO8ckMfvQb1WY z4dNhhZ+-iX?sL5qXo6yDb+P=HoY$l9Dd|5CL5S+3tDBk|W^P}=4>6gVOx99Wz>=Sw z{J>BmeDi%OtT_LsPJ(d3GNt*g^Za?ZadBXIQ$DAuOb6y=8Yib2ns%5*9k7aMdKxpB z4OV!fgomE$d5P=&G%v~03zmKjj;y?JAhP%unLaTM!D8uyG{`&+KgI>tp*vc|u_3K> z63cAtbd&+%F-}osZM4)%Z`9*F=rFNUO@t7nvax5wUAwQ_80@P2m1gTrS!Y1qE`g zOTz5GSS0!+YO%;du*^j6VEV$rSNMJ~Io_NFD%!7ob*0e>jXDi1CQ8%*CCf50`R(pA zrz~M%!~IDY32P@Y41L|8H2p+RDL+at++*ihfsb_$$bc$GbWV~o%bCsV5DI**yRVlt z7|0Q}4n!6$A2+36iIl3OKce8GS9JCQgC$d#$uca~H!wDZ-_K9!su_JQLX#C?2pP9< z51c1fHnFbJO%+9q`=N&>(1UmZ3tKf9ec?Yb4G)jC!)ssKJiHlkNpt2?uoJMD-+pl9 zzNoimCcot6gD_U5D4*?bY`?PojXhWPe1BiO)M~Jr#05feC}v+Z%5wMFXX-C)Lwou- z9@HIXn;o*Gx!c6p4>l(Lm~}QbqbCYc_LRfS>rHA~9E{3GA}1fvqm~bmn}QRF7cQWL zxGghY$KMXQp!IbRxt?*ET3>L!BzNlm*0yJIN?C`7Ut#*Hs6L7@Vjwd)1LZG2OSy-@f^Hp!v^1~7Wh@_uMSon(rX?0 zg@Ywj->pqJYxlxLgAL7pg6=ZjLW3Lskxu7n$}o`mLi)+`>lUtL&sA>G}S`*BBolIo@x{h=-6vPgacwxce-l9<>s;GSC>y!Ess?#zm^fN zS~rrx_+X6MCQQUBTu*ttvNfK+GMc&4gbZt*u2^|(?X|}1tFz&IPs4Q=s+x50g6YAnR{$c|=oKN9GP{7|KCY3a#5R8a$)|;BD=7~kORMUH|(VOK-eG)Z`DWE;;-`$uT-Z#ce@Z50bl+Gnw4Pe+QB!`#h!Q+C_)*@5(M zcGv+MX6M(vLmupKc@%#@xJ{Rw7s;MI9g=rO$o<^=fXhOwB>G#(O?FS}J4w$4 zmRZts)4>aSrC!DgP{8p^;I?YNzE)(GstQyUHkR##-1?S3omO&WpTSG1L~_3zLxZg#F4-YD_;&P3qr<*mbB4k(NEAc6nYVIhf4V{ zq`WR*0T7BQI5UU|M*kV37r)J->hiER6^e5PhPmAaE5NZkMf-G&;!5A)A|t{v%Z|9A z)7}BNAYk}=297APRa6)H;Ir7|qAXcU4Yf10#yYnKAumX&20MD#f?@WFKx4t7p@66= zF^jTD7Gh#G{3JP2#%`unM0Wubr!K%D1ZV3>OmQ0 zW@R&T^j{E{MvH%__?^tdiJjI(hRBE7*qUG~>*jyypfq|*4-%JDP_Smpw$d7&#o9s* zv{7gKx@sd#(OxiJ7(S8{@~v!H-Lk?0>VSrZ3h|x+U)Ze>BFDcB3=}Y&*7mwP?IFe3 zuKgX`#muy9>TxrH{6f}annF_7zhbETD~5_Rxz`vfD}nOSfVqavS%R0LnU{jfVjYlB z^1)yNNG@0wj&{?SlISrIXioe4kO?8TSZ1p!`y}mwcPVa!{*oBY#_P9n@g3JUoZoPL z!wu6)#E*lEonzQTu5!=2o_7zshSN?^ij?Ezmmt;@47>3ZZ>Apn)OpcipVmGNxokb} z#P{5EHSFX(O2K+M@D(eu)&2~ z{gHTE`}=j1^Y%vfKNK%N5G^<`TX(959huX8$7OBnVSqLayQuTXqffP`^oBqXv44ja zZgeM{eTj5YFZLb~do7nP3Cs7)O{e^)j|Tkr4L#TB!Q+23&B#EZGa&~L1!yR2o3FFpk~_Cv|MVLEf@)YJYIv>ny7N!gO!%WM2YwX1vF80P=)(^>-n%b; z{{h_M3M10m|3SrJcMTeGpO0Pd*6^@Kee^gFQDG!x_r=-$VZFkAdX>nUd=& zarXiK-slHN1DqX*(PUkHkVI790}ni)dbQMcm=22lrIvdg)*n!HNyYiwOO8)n&fJ4e z>~NRV47UR`{^{xb0t6%8HM;BhXUAJ7JU_^}nsc+R4c-j50ILGqhw(*kEWNTcR@xly zq*q&q&qmUpfA*si-+1BpBUh>>TlY?u>>F`Hxl&R(;vZQRe(;kFM=2sZmqyY@cTFxj z0I>MdBD{c4$``m%_X?E&iIiw8h9$U+R>C#Azmy607ql*RrO?E_5aVyb(&VSquB@Ro zsltaed>EjqgsuqwNGP5%>F3ud1qU?9!B5~Q@V*GY$!;w4UE?#H5_zhkaXcWVVwUcg!TglD_+9FW7!v&kTP=v&Ub*14uGbg6 z(R8J0A`oBD7Oz+p&i(J6{H%&kY8_R}>%!T$@`}RlX@(pk^roiK zCPW{2IS51_=h)iuFU97y#>-c}v+cU)`a|z#+*lS{w>Q3OU$l&zPKxuw+t3LG#o=eC z0fbXC+B4!-C_>pcb7~2PVczJx$P*J4*Mjd?kIah~J`&z~tE}Rc?$PdW`-|JBE9>xQ z*R+gw4Tv53d8?u_?D=M{pbXTTNf-;Luh7yof#S2y8aGl8j*90GdG2gI&H4=jma)-U z2cQEEIPV3K*Iug)?TDLD_Yu!VYKiQ=f^Vl59luR_ZPDqt2DHvYE!RdVEXlPt#morS z)6g-6(%$mCDRncTm|BNJvHEll#mK=%lm4d6jFA^y1dDSiH;@6leXQ)_2xX{Je${D- zuVh;vlqX$Tb3^xJ`;LqdwG>Zn@ShDr!LYe+=lP(@9?CRzMo3+yN^btWOKQCr0mNgn z#^b{d1%TJ3l_58<36@&oLuH<*QK`(ohzaGeIY1(4_5kAo zs35j^A~djb5XsT&V$`Lirj(7@egi`#TTzxnD$q`{8AH-OquTiMo11<>*#V#;G%GqI zQ@4 z4$x0lBT`&OUBkQP@zBFt+L0LHb5H>wXa)?}$z%IeKxyhav34*?BVbpRJsk&k=*&!0 zCy5Q4l)Gv6kI+#t3qi$UFu|O5pLOFH`apz=hQTg4^M2YigNBtpJ%?gZH|q|lGGQia zDjJ~_W8?Y_mcWrTg*YRaQ$+oi+xMs}4)^CAJtmD1Hlu$ike6-%Nfj&= z5CetIR4m_SZ1OJi;s4eZ;*^BYt6vs1mdznXlg?9WpeZ}$2EbWMx;vnjgCydXnp*0U ztrkY|7Hd*Ouo~_{X=pKvCf-GP`u|J(5#7q@$UC5=e-ZqVd)6`&rD4-g%e=svX4%UU z>)E}M5J@)4xDDCZt&X(X1Dk}sqky-E4Ig1n*gMeTvtX;Un--kdu%TnYCzqp{N-YsE z^qvRZ!?xWi5H2EK;xpYzI2hIj*8`u{6J}Kq$6SMz=r>I@;O~mWoQk;zF`nc?50%sS zAK=>d4i>ZL0|=8O5HvAGn87rXE{lY?xf|~a>|sI@W-JPJ(MXiqENwC5jJoCWi&80vhf#96)yBNs?^)7nG=rPAujA78PM+27x-vb{Ql38cK*&MCVr|#1dKrHt5d*O1R*q^~38Uvw&!CAuOJE)H~jOtv)t? z{q;pZZhW^fHorYy(D8SLRSZH~Hc>Kh;d;sSi}Avpe^*#BS}x3?;H7^%!;_o$nHRRe zBR!J~+9q>WO&3>A71zaz>&DwB7G1A+-xDpaix=;SdiQ(`=Z-az^^-Y^Z_TT@eBao8 z@p(&!cf%FG9nx)h({#}iD_rl#!1yg;5Zw0h#(3_su#3#Jr~+=nEcCqL{X;KFxR7qA zDw|@JP4UWQ;jNH*1y=GaEu$^*qS~_q^PQLpua3wtq6I(gl9ttxjU2t zhvuA67JU!!WYCoiA&5#Sn}28W@4P#g0irBi90=wvlo!hGNk=LEEU6SySf5o2QSNju z_a7#uAcc3z!R7uc*VKs=`M7chGH_LZs|>DvA+8XT8TX1p`7CCmesD(?wJIjZWUfyM z1jZs608rGsn89uelJ1r8y+V0UKI2xAY56*fg+!5Fq{v3z!c;`Gp~~BOPvtG{6_`D) z(sJI}sd@KgqHS~GK3!^2VwAp#Nlpg>Nu`+z4Lbur%TpU85zAB3E2kViZaD7$x1=wW zq`ZQkmON}!3znxgz>4?+P;o5p*yJC`wmi4_LLkTT+~ykrZ?Ai(EL0Za@P&cgP#TB$ za#KqWmG&XL7vCv>A!Df}CmUnQKq116Y4wqv(M_Nz=?$AU4HN@@5h{+C$}NG&%0uO1 zJfLK`xONdWz;%fZL{>3W9x4r#2FmP$a)l~D3(AuMkyYScxyVHZBAaXcxa{B?mGXy8 z#ploNbIWs=ohm0#iGD4xw3SV3atL$Z?7ZzDFQEEzov?W~RXGSh69jj2;@?m?f+1Dy zwF~lSY{Ex>N%V$84;zPYH8@}Slxj}K%EBAprZxIyI*rijJ2(v%Hj;}2fjUDnX2#0+ zCO!N&bb5(SqjdV#|HIsyfJb#@=b}}rI;v4s8cMSSrFlRIBrt=(7=ajsnUN<95ke(l zVIkoo$w0Me;~{Cub_XeTLJ`wJPCKz^JAv->P2-!+XS(gAo!m}Gg>Y1^sB_itx$k}X z?t9-STXe3QbZ*|i);?2}N?>=!W3y}PoIS3+_u6Z(y#@+?i-HRjgebU3!EaOW8Um0e zOhRm>CT*i&I|W2H2%)Xb zq)57NL>{dO?HetGu_NOj)0vAzS-5ENWrfV4`p{Ej#bZY&GODx^Yr@$zH&bfjt0FU1 zH&e>M-A~UNIXd#xNDf(3!fi{)Jd(R$G&6e`J^@COB57phESu6Pk(tzVxC$6)9L)@+ zkLHEsaB9(le}@_`W{wt)rH?hfo*7OnA5RabEg46Sx@()lsjEN_EtoUDS$|ou}8RICdCVj+?lCl?vPKUE9$M=&@i;1;6 zCYC%H&U$dvGLy67+V*P=*Y{6kZ5**A_HwbHTZ>O@R&rfoBi9v(-Q9Hs5IA=ki@U zeZ%*mee2IZEki5#_VNRF=8o0Y7#RbQrs59hX+-X=w*c-xR$%;tw+Tqjgts*FtX6@a zZf^Ty;0o=4$jls4>QmU)m7U#PCrSKXG3toZ<=W+tIwOr2$e+L+Rh7=MQ;xIZ_y_eZ zVrv>@@wCEgx9)7-+q!eh)|S@&&D*xaPn_0(dHiN-j7Z*PsN5>nxv*j=EC#GyFAdIq{W!ByJL6!kXRWsDLaGJVu8Ug^wAp#6Qq z>`O4IV$=pAMw9X4xHrCPGPi!xyJEt=LL9eHn)dvsn90H8+AP`+W@zsT$invF-Ws-K z#0?7ZMl|iQdDE6WW3|D+ZG#`0u^b~Ite66HW#DsZ}qW3qkQFdA-6i6d?_YQwp;(U(G+LjBtPF+7GUP~xHRUb8=`D|>*U=7I7-|PAW5Nx4 zmy3r^O?elGy^F`Jlisokd)a>uXqOtGy|?Q$U0^K$ZaEd*m(vg!K`N)yTLz;8Fv0Rb z5wZ_2g;bHs=E}kw4P~h5{`~U-&riVfhrRwW-=w#E!d}k6yCMWx3RshqWpe z-obR(j5yX8lh8TT&QFn&ldD-tpheBJH3LL`@Ry;_wY9Z}539g%u(jOAo->Eh^=_(j zQ7iz>@=?4+({52)xoJP7nBHfylv8Dv&D0pHu)f2|co6uboq4Bss?{dZFZ-WG!w%qf zs#ossYn0`-GtH#j563ti@_$>XHp3(cX7eP#bnfVGY;PwgkqUg=f^*Dc#YTa1ME}_; zaE+fJpd^+52(1sMG~sq1Mx{h{!7V;aE%-J;gr%XlH#`~KhPQk$tD%(dYblA>d`EbU zQwyX@dcowv#&=7!O50($?GYSUKK9pjYO8;zLORI@yaEXeu)X)UI9 z1~>7VFm%@t<;6oK#HZmAI;@p#l|PB?JVRQn+hCn2Fn&EPIQCK|O zNI;!yy(6$0<(`*WCb2m&=|7>4+j+?ZD;Q8{r$CyqtyU_cG3T`zY*14hdc|E+0~-I> zZ|aON^o19Lg2(8hiw(sq4HEt@i7$R9;YEo?)Dd79|$3jrqVG+uMtN@R5ct!Z7s`yhSdp68*CxKVm>6+)2ilR(UHm(xt)< zb%=3LKtS9)nFR9y0=i=hHqY;l_C|}K6kcudbO747TkE_0w^TNbw>+)IbnqvO`szeK z+PXVn^+yN+UjM%xR5~_(rfA6@}F2^-9S^hohQ6`E-NwLilYfCOyn=3lzk-tsQ z;IY#?MrQJZPEiVsh<3~Wg%a`7{$q;q&P6u!@06=85tZ>@8VVANJ+6&*HoA8w??Au2 zN8Uu_7TMQCbDQ@(&LeS{4e|+Gd6Q~$6Rh>=WR;`zRwoyDT42MYw;F~ulCi-w(K?=h zqIJN?{}<8+9io$Hsi=XMk}}$VNCoOZVWI0<4SZay$1pF5NC~dc);0BrxXRiKW%1&@ zN{nsm=x?ICcwUY^ZR*pOgH#MRuAaNfx8WQkz{|_DhH#TTVlpnJw?rZe1jlp}v(UK; zuT}+*(_zs$y>x9?7r?U$hWKg?{0g4&Q29Fe`K_|$iktU+{bG6V>(}TA1_j>l6Q`o8 zBXSWHTTDR-1-B_+ON`#uR=zzD!eyu1ga1LXzo+2;rQn~bfZG&v(xg~SK@kP(DR_W_E%bFW z#kNs!mHvE?V*iU`Efjl{g2yQ!HmKZ9K@SDTDajvDaE|_bi2_ztV5g0Y19wpi-lY#@ z+frUivA?4ror3?H0^ItW6lH`!=u%(f==-k$!9h26=NLkf{H7n$tv{pqbYbLB^b5@5`ffUJ}Pm`=t z&YT4?*x8VB;8Hi){*}j`eeBaDvy?^ey|Wa1pRQo*OGRw;kZoh$7y&#kgZd2>!`i^p_-qj}bnCFMkXi^T7;wc>ZzUjChN zxaTB%pIh#foO3yL1U?S}zY7h`lccqC9!aW1LDYDsl%X_=VmV3DF7uq-Ar;=vS|Ryw zA2;Vn&e;Z2Vezc3L@J)~teKVYi^gZ?@f#A^$e4A|JEzI%nR6jFx5Hd4`R2Bp9a73{ zo~gheS+XqRFOB3EUtV`{9h5R=Q@&)8vSvIvvl2y6T3XetjiYc@vS`-9QKuGplnKqlU&n%_Spji?{sPz0<8%I&PZ`Q$4 zl)h-z#Zi==Eix&k)7!aD%$F+6hE(6V?YFHt(u&!YKB+2_UOa1|-zwPZ#P5tFcTU3Z zY)!V5!UICTaAos;l;yWT3Tqk$}&TV@~Mw7A=-aB0j(Pt>4MNGY(wN z;63?}5sC67s5v1K{Zbx9mF=G&B9gmr%iW&EcS&1Tmx@Wt2*2ZzW z$(t{}E0cuZf}q-Kei)5dCHY~#R{So8qig#60n~%v8Ar;Tgx}dsNtj2o84c)evNgp& zYol1Y$(t+Q`Dj*T;@#Y7^L?1x{bo~6ek2FAW=czEJdeyu_(hviGiPlS!$ip9Z%Tvc z-AYqV;jFDn^38Z2n3eF0^yx@XF+0s|2gM#XR}xT*W-atvy^DXjnfM!DO?%AHJF`5B zMI6aNDvqppP(&DP^k%j{$tOX}sc;sP$BBwEP&LKuCeN~22gR_QO6FV?t2beGuUQX# zHS0QVmNv|IR?SKjQSxyV8CT6ZIEs6_5|I*!3vfx{x4&XB)!jF1E0R{tq?XM}_(gV4 zEx)1udFLGTZl~Ggubx_57hYT!DJ+gGt&7wwkF4J~>y^!Du-7*$QADYkqktvg%u%N) zZON>Qqi&P0dNzfl9+R&@Ph3bxczD}V~SXgnx*VWI>wzNt2Qc;0}qP`!&gVMRPT2(yF;~pR{7G#v!G_7@5}QvdURUi&@H>@f6KU6j7SWQ9D6~KP%(T zZ!rcY zRjD9{N~sK;A|XIAv~E$AMfmsvC=v@O5~nHIF(qY(rEH=kQV56Vd_pmin=-Z|x%OxS zNAfM7XW$%gHe>uR;XwX^z|^(SKpyLWwnaaz8K9dzeZ+tGf@7)WQ^!;3h1M%TCDC|d zFj(G(IiGw&A)bC84Lr>`LG2M~s5rojKQ`5B75|jrPFG^M8TH^UP8n?D5nVq4#a$fm zSta2Fkk_IkasvfSpvH|lK~<*Uzf92 zg_tro5EFBQN^aLchzLz(w8cDk5D}y5{aZ?^L?Qib*oxP@ldj4MYbC>iPO93Yf#JX6l@Sckas(|{11n|n{3fSIWFCpy}nq+9F`cuSDmp&AE{JSz(Iwe`Ssu#x~NS=Era7k%Pl zJjT=$3^prP8{uSB@OwzIqw-W&p#O;){}be4w_o60U95rl3hbm-Rt%mS+-z_og9Qhm zE+*W!kZv2Zr%3jJ+rg59!IHQneF_tms)w_LW8mo2%QQm5GezMe)FSSoXp~m^hWq`? zcVqu~pVIyxno@s8u?mX)8e-reFv|E5;>PVD>S|>uwi1NoM$EBa&>RaO8Rl3j3E~GX zwY+g(XxA-Qb;MIMWSRElgfd?0ov;^9+nhrypFcCw_}rHxo)yL~5u0nM@!3-&Y0rIW zBoL|_JvL_kjVB|XrN%UnV#+QSQx&yp4`C$yZJv7(-4+HVAnWM{{i-~eFq+FWxIokL z>SjeD29R`aslJM}wXO*OsAWOASewL&w)jB^2N189p0|`1KuO!Ea;!<7s_En$sH9uF z?I#>(!Eu3OuS}8O7(xNqq^5^p0xeH|)RvMvxq!s->0gVfO_NXV*Cdhk#VUWLKVK~= zko*Fm&}33eR9i0(^b`KzM=ztF%&YSguywL@a6buF@}mn&Xf2ldi?pwjTCz|L@AD-5 z=HR}p24tLoOxoFGGuf_5K3=SrqyMTc9<;Wmt8WLb$4k|?{+kf8T6^F=&YDO}%rN5R zdRc0WMjSm>W|i7Eh=91-#xN0_w8;ugPlTPW2dyexD~1GxRy8yhX;~?XldAX_jIjz; zWljX_MYJE$fTY)?mB=DVkgkf7&%!+GT7pp_YxKlpb-PZo3CN8pov+bQ|&DQL*!UW7M$6Bt>TJGRTHHoC!kN;Wk}(# zBt^!UlEA`bBhchC`Vlfw-%h(URl9%NCThm^0}m@U&1%?)HEBe$HZlzggG6lNh{v!Vl8U(Kr9j9~~OY4upO~C1s@`ly8lISBu z_WzK{p$TvOl`UgWz3L3rU2307Exxkl=SakO zRp@vh%qkDoXo46vRoii%&NQ#o^ zJQQ{E3y5vOkrL%&Vw&&+9zln5ODOPCM~TS{TD#I@cTaeihHXoy?P(*Wp`=^({Ew~P z5$i2$=8VmK?(D~2-%F>?4-OArYP!7r;`XtY@s*PW%O|~c6ZX1~ZD}KAmojeI3V#O2 zLPayFc~hw+;nb3`El8BQ98Q59o|m%EZNlMg#PXsG0@5P`m-^p$D0Bjzb*A0kFu@ph zk8io_KQ6C+`#$)?ZNHXt<$>>Rxl#5fJ15JVhn&+c&rtBC2SRN(U5npXF&6y#1J~Ma zmaP7%yL=|MJ_O~s`Y;3~b62u*9GvICf{<`|Jno$Itr*%8aix&;bNC!yJGwU1GPZI& zb24Muq-*(vb-CE?tpJ4j(AI}-**y1u5Q(8oHA*vPlQ(S0WR*9Ov>z-`;jTq~7+({T z@BDS!p!ICBz7@do35JOtP_UKAonugkN*2m>y1I$F9Awyy5#PvnYrw)eZFpzp7&dvl zmyT;TT|^BOvIP*$+6u@730sWR_B^ID;~Ra8QRUuL!A@wO!Y=+9;VXdAxKKVP*-yXl zE~e}^&9I{ipD=yw0V_ zvIox7D^+bdsLl>G#7QRllw@$~NS-ZYP$qdwVebZH;h$?GcW30^l8nFNf8BphK;#GZ zhs|rowSAC6MKaDNw#7%_D~?b)nj!o5oa*tD{0JpbC*n(~4efB)s6b{R3%8;& zs5#T_D8NeRwHn6IFw)%xi@S`qm7NnC9yvZ>Pjna`V+xkVB{2;&4Bk6rNHCI)G`c1l zZm@Cz^K*QE+q?%7)@;T?*k7R?h`2$*Kg^dk_cFEQe1sjt(2bn{U;jchhS+3iECoUF zc`1n&ZG#dN3?VgzP!Prm8d=srnQ=yHLvA}IKu23N?Q_B~3^zgPdmFqSLCBtGMk^V- zSM2F4ujoXF&I`IisT7kFju9IJ0Sq+``xbWxcCu5f$yxH)1>q%e{5;nU&W6(2jYQjTFNzfS z;TI05dvMZKFlN5#DthDiwSwzy-(38D*{$;JGx-(c=8F#u?VNFChwi)S@{b+5w*O|? z>PY@#yt6ycyNBH)Eur<}1-I<0fWgl-&qvjCQesq1Qj(toRqL*%g-O61{hR}>T5-zI z5VQfMD&KGhQc>!!BfUVW5}p16=1vQ~s%2=x+c+nlF`#Xnpwv=%tI$qu=!f#?=C%@P zTLMX&(FU9&-cn9zZ=vV(kZxfhSvk`{XSmyO!l|8UKu5(t&=ZzEuVJi!U9ClJ{h(xU z3J#52-6=S28@gj~adsh{MYX-yR2*$#G~P+;SKCxn1KY}0!rsgvx2^jtB#-@R-iz`D>j1}ojfSmy3ez!Pbkh&$8 z)%OHt6VO>_*t!UZkxMj)PQV)%JZsdj1CK|Q-$wk>PFcKp*JBSB|2ytAw8#CsZ8+G+ zl&;Ypp}He8pks_L{PZX|xft6)v5M>A8H>E10%HqjvKUD2% zs|0LzTLxj3qfiVzLz=Rk*t~h9#ZKEf&`*Z)<&N$S*bJs3be|i_OPs;_1~9PjNZls$ ziMdN`>;alyU483lo!6BLb(yFeR4a@_KAGeJV2%92ONA^Ex zTlX{Jh&Jo3Qfy5t&T{>gJm=u>psT;4kL4 zPYqdTY#Ad1H*E#5`P75`TGz>M-8#9ifU18VaY3Mh%gjP+a6_c)W#)a(B z>`T7OJHe5vAarB6LNuAsJo6kenT_<_Tlkxv=M;XAIhuieQ?p*z5n$i0^Sq^z zL|?EvaqDXnwC~$A30$b>oatjv(WIwj!d}7v+$~q2U67G4!pC@7$Cdabga>&Elu?p$ z3U<*43a(PQ#2BZm#w1)Y+Z7?TQWg)QtL0Lzhf~K~tP{zL5^#M8;4Eat7K~<)q{J_W zr!u4#&!Fb145Vt(afN_XztS(+u2o4q5R~R~1rFSef#8$^mON7sDNt@QmD`zgHrZk7 zcTz5T2KntFwCSw*tfL2HD!lrb15OaY$bHt`h}H zIqld{3Yp2XHrULy8+bt)1O{#FW6t(vo9<(-#ME!hy$EKOl6fRx_6TIY6A*O_x?VGV z&HDMvtjcb4pio}W3lZr|GGS>es~!AP=%EqCPQ(bWbx?rHTIYgbq)+{wP{dT8U}ST4Snd?BVCoZ!uD~ljCzTIm>9FTyE$$0@`zkB%tMT7grCK`d zI)QJ^d{IC}bGs_rlx+~~k|RgZejp;yaK!Z{Is=Z3dIyAmRdEzJa-_dkoEKD^k(3-) z>d>3z77*FDFsaD93fDlir9xRXi=xSG1QBG=x!4P~4&BOvjw8MjNYTA8^#-y`5cwee zsDW+Wr^tmc)HYy2@g&@wa05UNatZzbT{y$-XG~V%0+R?`f8Elf;QH{H3O!t7{EG`( zQO~dXx{kr|G>;$Mj;QIWpGu0j+Y*sN>6=nH(~1NqFI ziUX;z_lZ6z1UO6GKpq_fJnwM0m(K-z8+jxZew{cb2+t$9IR}gt{h1iT8*>w89he0t zgs~E>D}^B?h;+@KA^k~E#+)Nxy*;2iS(;v*@$hy|77sBfAo)Aw6Xa=}k3q_sV#x&@ zJB}Qo3!)<`r&2lk@*#)jBl7c!2{kE$%j=&BbC%*)>lH_B)u*$PN2!baFhVi~aMm+p zg;9(3>ERcLv;}a(U9f}SuS@_Us4FY$U=9_u_=@Gr)%ihr6JZHKINy(BwJ{|bkmWg0 z$;MTys>r17Nxp9ZAZyW zG$%^Hc@*b3fx4Ado0zy?#X}^&hz&1lBknO64!h+sBDdGzojimfSg=``g~Bkx3^K+L zgU2&~CQ)$F-M%*X*+3KoMZQYKksOjdO2I`6&QtIj1#2mw+qPh4OD{aa6GK1Hg<}+X z4FxwfXz_3G%YRI%$n2Y7n3B#0nJo}p?_gbp(t!$0t)~XSJclo0p}DLe_)7MCs%EIH z;-d^qS+Xw3uW{j^apXUz*xym%>8;wX(n_5rt$r49!EL6ZGqN8Pm`rDiDo@k`h>IJ% zUndAMRIM<{a6;aP1W_9mL2hT>rQ9SL!p{CIa2sdYB5804;!dn@(RYp?NhNXxjWhC>(LXOX*rVU9Xo73^!U?jC{ zEC7p>E5--Lk6qh0;aP1I&Vdcjkoh+p!*x_SO#Wn!KXoN%!c~W++B_4sylL3pToH2I zaur9?GcPO|UGmD(;my-2J{ZlazLio&FKb3?Ua1}4Jd?h~XtjwPwgy5?Vw`99^`|Rih$@(5*h|8nA&l zctWqhBvX+8d4acxfVU{@S`?BeUBwetAr=RbJwp6J%iz&E#0g;sEp_YGDDUrB1_$Up z<8TV}^j-9x(0b6)tfdcH)(_Mx@8#bxrr)5yf5rHIeV3X(C^fIETXjIIVT1l9nZ9h& zKdm2Fsa9@nUbliu5WU!-e?Vy~>Nja$)^}-H_={fH2K@`_K_30n`cBG3J62HIiced$ z;x_1ClIhDP{nPqRf}Wab)k^)#2K@^%ty)Q$sw~R7LM3ARZN;dffZw7Q6vUJqk!AW$QMPtl!zd!`c8ieA3pJIbhB)q7D z&p@Yj^>nRsDEJ%mE!1yho)-SyVK!JVkKQrYARoL5^2iSEMC@0*O9l_YAjYVR41$MX z)>Csi<+?QSaqa3(Z9TXmN-cUWQNGUoP+LpJIM09sx!XX35RnvAteMcowZAf$r<|v% z{Lp#r=m_*d4)+93WjF=~muqLOc2!o5u8&WUHz=ZX{71p2^f&D};BV{iCs8*rp_ZZw z;i0aIVplM7@;4}0j6X4DSXd}ooX`@W)*n$)3N{jUcpZ7*UCx$0VOt!rd&o$2+DH=& zPi}ju^-|wh-B@6}?)77@Jrho;J-2nnmNH_#PQnJ@tIba7sig;nw}T zCf4spwms%mlzG+1?$V#xtPUp%u`8$?vrT(6zL?JnAKZ?wIKSc&MyOe~CKq0?(LwR( zV!7anz(xy*jTdk>4X-s{Snnnsn(c=jsBy ziA>{yXJ=Dkbk-EGzv%4A)66lbOWI`yNrpdzyr_gE;z4r!Si}D2?paTo4j%*y@mNj54dc$ zbDQDeN#lVIKvP=(>o^?%;vTi$7ajfgsh`w$a-m*}&V?LubeaS17wm&c^984kEs-6= z&Ouu%@s#-)v>h-FJLObBg|>jWN3GLr8g{|=R5p5J?_Z}TI=)_w>A!;-2NJ@TxmGgT zY?UE~&;x89#OlEOd_YZYoS)!LR;up}tEgIir~h^)f%91f$vTBAYBC+K(Z8y(#G|bC zM;mLNWsjLg%rCo7nNC|CGo3P5dE35*CGDgm(jG91=vD#@t^kQhb&^*p;#!IuL~%Bz zD{SRt%$NN*(n4XPEqF%v9E59FI_c`72eGA53C#82N~wIl7MF2I1nEr0fH8(fFu%0D ze}E3~#HbWUXB15Q72<*DY#FVP0W`atWxZJEi#)vdwvz=fO2J3(O5CIpi;~`O1MZ^7 zM`BwlYm#th&^jy;(^WplcyaS0d+-M zKrNQ_a#V3}nVguaYPa?5^U8m?t$QG@JUHnAR~XP!kPGG(D~y57+lGNW zz`~)B`aGf)Pv$}Ch>r}+vc=%gf;&n4V4jqEe_Fu1(wmP&VlwKrshni2Ms4aU+7qI% zs96p=j$*Ph?>hLP+8&xXalB>)c?yJC>)#~SDkDBd59*929tBomZE&$Vt<=wY8(8~o zE1N%!Cdo%zn0NU1>_Al6?0Ng4qX8}f&2t4{0kUgh3pP)jbBPEdgDUZlx-HRnU2_2* zCY(C)r=~H3$kEdbvO*$X;z@IduZHpRV}%(RIKQk)WMckO|ArI&@c5f2Ec@w9X^rqsm*oZ43wr$^RkLMn|lHsA}*NE$w1Wu?fp>+ z_fEJET!NyaDVuPkxJAWLZ1$)MYV%a~Mg-AhoFpNT7PTqsLB2$9Z7>?z4im1;{|qjn-7qLK)Ckt_1>30Y6$hf;)JxXkv(s=boIIP9nvykLTt4>H z>lLG5SckGAg(ac9o4NPB{`7d~*S|cHJe^S(>U^X9Rt8K&lur4UgndiKw|?kb@lj?z z92s2LHo7g;`09?2a{X`;@aSZ2?FfwOFC9O6_1KkTw|uK2`GvpH{Ml?i8MUc~QJK$f zdrg`CH}c+o?7PYDy5Dh6WNZOHIAyo_#~GD+`Hd6HH-~FBzu*2r(R-cYnw__NyZ-sJ z=?p&@!zo!GWh|zOw~uarbw`A3N8sHZRxtWTv*LnaVdWk=|S4N4y=w zp*s~5h?teW=$~)i<-D1!%0t@`^+!f2hEBaR7#8*l#mj)$gk1hV+ER`US$Vw zRR&*S6N=#yic#6I%;PPTwq;?Tf?|rjwJLwqDtDZe#pMhyx_tx@`vGOoll#zm zT^EZNm|Q^b)=&$+PwU}53f`ySuPInY0bxOz&VZt&Y$oe3@MqNbP>)6i?ZKrDtCGn3 zsjyng_-)EV*1-fGsHRvs1v>x6ha~FaeV&pN9K^K{K}!IL*cZYinoU`b^3(K6rho=G zc5!apxKS{Lx%Cu0L?in%ly?W$La-=gcMtVF_oYZ`?xoUD|7+Euf(cK#@g`>4kukFA zQqpDDMb|Ay>8#b9vRvcrGdt=j^&966)AN~5SNjTcD|HS5< zPRTrfc=&K=%~;E1N;Mp&W#mCsX`GNwZd~R1kp%0sKVZ1W0Cj zJgMg&8GdAB|4Wab+xoH9^+NMZap{EBH*3v@2_SdotOdU_>9FsBU$P^UHEW}o-2}@_ z4vN9PL+L-b5c{OT~Qvc&%#4JMHqm zyy~O0eDXSyngfSw)2W%0v}O=YrnbyEq;${FrcXR3yEBqsF$9&noQOAV$ng_f1~uJ2 zY=7DLw;3fvHia`ba_mDpOo^F%r8CZ|cXF;gdP5F7cbwZi?evdjOghV88||~(XUwLQ z{7ajr3RZ**R!q270$WK1(<$Eb2Zs-ak}lgW+Fo-^rod$!;P#RmmsnE4oj%%(->XX7 zCYgR9ZP;$Je2{EL7$bB>>@Q3t^Bm3D&*3)1d^c){Sv4pv{?TcoL`rg?P&E2R&zaaz zzDob7J3Mp_%)y^Cx!Tx$@`*MGDnO8^uM6`1T_@`Oy%6m{q)s{PE5|In5XZF6E}4&; z*yn2fyXff2+Eq-V;xfNcp@YTg4&{kl&K!L|mTpYlhdn+BD^>4Erj_Gp=S`$-0*Dovd$WP5RbMy4Fru*NS^Ljy#(;^uxK}Wx~@E_VYBet$=+_E-F>v9|5OJUKK-Y9@kR3#3Lz~0 z7)vvg4_qYXg^6mEeIa3v`^9{!^H=*T>uQ(#mx^Rn{w3l=Jw9;87#X63Gg-{1&pT&We0HRkg4S3zA9_VxGrP!w?OHD@P5kW+0cx?S-t1HMQnYg+be{2@vRJ_*Fi;Ce>*jfMOe5R4d>UrI%A-ZGC$ z&<^PdFl~TaptD$k@|P(fbJ7as=NGiVIeJaO|1d1~(z`5o(yEw}u8Y7}!KCK^?&A z>f+%NFdvmQv;eLbt)O-htB-!Q-9+%CnN)e)z)$x@FpM7v7Ib;n5ZdpqruGDio=ZkDukrUg8 zd5*3S7TP*+Uo38sF*)erner2LrZmExyUOraIfAfA@f?>@gM|$esI2#@Hbsb^296$=frS9) zO=9izfTeEG!V;2&U=74+gmDiAsbkp9VrU_?rF;XRa9$PGK48%HB&|XM3T+A`WURva zUxEagbqC)JM80Ca(sY!6h#6ocZlYF#nfz<`=D~GqAFjWMy2*p}vh(YP*Nyat8b?n} zx)x7Z7mN9avb0CLXa294PDYg!{chB7pR8Gopj+rZIP)DeK_dc=gcp`gAX80wCNLJ^ z>5_4wcK58c!N}6m*jRkeodR8pg`^%V3C&5Fg+523Z`@|{%Uhs}ut1qsFa*(3oFKTR zSlRK9&K`Ri7xP$`tS53@V;$=0_51DPbRvm+22IDn?|>6o`13mkXQziTaLjh4BXZm` zn)Gt2l^mj4f7kp6$-k~a=z!`d)e1+c_BJx=&9i@3hm4J)O}*?8W`207syhZ|D5TYy zx?>AJYyyZ^K4+Ob-d{0~QZ=k1(-@O|aN_yNPX!zmWvNsfySgLd(zF7wr`PlC>E%R|hjs$-P+i z(BL?V6^|P$u9d}Qb_Y`!YVc`~JFNC6cqs={cz;sgK@#^H7;RzWfW>T|r$2w60^*m( zA9M)k3;IVAQnz2Bls}??-OIohurMx4KvHNS&O^Z>LJq{rfeK)b$?h9znzZF!Ixv>` z+QFN)it!cKO0TSoc*=~d5wQ41+D49oacNb2xnFXPHBIJJ-E_e$b&*l*RQ2^Ph1xFK zFQ;5gnS|fg*d((lFflvl0XqW4!SAJG*zr{tcmQcxGcHKw46iwV|M2}#8_c_yH`X+f z+xSk|M9J`MR*0?b}@f8)0xpI#jlSA;(IYTdB72;-JYcXr~5ZR_)Q2|Xr7QOw+?lbCo zlRJ*XI)I9OK(8^uiawHFv|!ze`p6P4-zPBhk}nWw2tn;P)674KL6x6E5JT-pQ)C6i z%!HR;M1uQiuGb7= z!`JU8pqjuHE1Y(r{gOxoBbHrF$|VYSzLm-#!T%$4|H*}^THPSJ49yG#!Oh}*oveK%2LCA){8tq4CyTNc06rBdj{^AZ2H^WlIg9?yf&Ytz zfUmAtI&5)|74ao3HyoD)Zxl2GmLb_$jP8!B2%T!SO!uFy4=N}z@^reG0tvPpDAiGi1y*6}x`vyB*lX^u)<%!48!5=I% zejTU#g+A7Q#KO@k=Y3cEi%4+Q_zRBM0v)S3%OZBqGw7-OLvdte#O2Vk#|%!oHaOaM z`L{4SU#8I^*-N0WR8wjBn`>TQ^Yw-onuog1_YU_?dKTZb`sWXl#uigp8FZ9FK{#vy zcZvrR7Y571bgUs-Dfpwf0T2Yg)+VU`#_oWzRMNlAYS3#Z+(lQlMBeLf?>Y`<2BSi@ zM4fsr`8R2S;GapQ&!ZXh2cb{Ch$O=_3S_$zas;WSEdP*W+MXAx51skYUiFCuFT@Zi zpyeMr*(0ZF`$7l2I_Dves-6D%8cFb^b!Wi3{R*&8v=bTOEv8!ao`Brz#?c4F1H&H} zPVEP#ryyTI3Tl#C?*XZmX%t#5y~d2 zyyE4}$0wdp_=7f+-~rPNB{_c{xVU?e}#C=GEY^Z+^SS5 ze+}^Z9RPTaSR7d7K2ug9P;kq0yZ_a}tJn6_1h4XH9(cF(uvNq_1l}(h z!299C;8m)W#{k~90ABfb5D^g7P#|&>qIA(JU4@82+YurykeN?PWN~%S)M@U*>EjLa zubW9L2Ywov$xvmEI(Y6JfUY_4&9_jZ{JT^uxi-TK<`}YX33?lYdE_4>2?yWRG0l&y z`7_q^bIo7b{p{|M`@+`J(6&jdFy0b##MZ7n$x)nVCLL}#OWU5PJX7~I@u0{D1r zx3OY4_{VMjUEuF@bRUJq4d!&U)3rApWoWet9yVhX)s&jD=!pFyjsc`GjaxBbD`v@n z3KbefxLKf+kz(ds<7vg2_!c{^QmCj%6f5FH@o|fk(pD~I0Uy1z)40$(gMX)?6@R7< zW?r!$s1ngnL2@3x6&n2eL_~a?@695u112!q`&*$qu0R3<&SG}Sq7_k_QdI1?zd`eZ zfG-@s#uH^Tt;YaNv3kD!Z}srrPrj% zoK=&q)f3j$iSZ4O)4_kmae7O^XzDLh6Wy_+RDa*9)A$GKsR#bu$#F}di;norZD7mx zv`%nS)epUr{@#=H*U{eo{@xR@qbK;#%`9a=@rA(Z6&1Cr70JJg4);+*6<#QL9gr!Q z0X*mY_<))3j)7-QIHzX3WiqFJ(zRm3y5c_)nkN!Nlb{F&oZ896(4-YXH+8t>gO8kF z5}cx@g~9oU1WpS69^jPUroV``ixK(MHi~rYHgt4*Hfhk*<0ZD9c#h+J{Bsr;p8Zz! zZ6f(8sIny)QY4V2LJEr^1&K7qJ)KFNB=H_FnOHI%s*_}o793#n%P!iANIEo;9J#v1 zorTTZvr+)|4Gvc-Wh6t5&U!q-b&ziU90IO6gEp8Wvj$B1C6WH!Wy-@<(96|UlAzB} zn+%Jy%7Pn|Sc%x~AY#E1qsZ2&$fFbIi62ON=Y!;@8$o`K({Up18BAjJ-z2qsv*|I@ z%P*<2-;i!MmR1T$^?R3Q8+1SwRWr{-%%yf)$*(CyQ8Vl9ND?&k=DkY&D(bG z+OoSPnx?$jv~$nq2U`y`AKViA>Hv%@J}L;HB%n_~!qjELd_jB|-Rm-$QXzXwLMy}| z#dTLOsli{B!lJKHTSw2+UAVRpE}>GO69l#d>_d_ARn$X&9_{XJf0F(682;|VK6{!^ z)$&>lg}AeMkz#ytqe;0|IinWT5Va#{rQ=l8{&btnM!4nsutcI3{27%7;6AA@YJ=Qf zKZ&nfzygZeC?Q(Q=2H4-#u8N^9&upuwGxZ>Oe>X*#9d@CwNHK*#r^~B5SeJsITPHS zj`R-qyl#_#xlcM(E%xSmp{I20$p+`eI#-5zWgIk3aAGzTX5}*DNn440W z9ks?(N5|8~EfaY)Q|_f<_tJlywcz`mKH^DyKgYAFKI!`v_RYCT->)y)oF%=NX{IpO z(UdH`SDe>mmfkl@h_@Tp2!KnEdG0R}>INkrf&kA!*seZk4Olv)fR#>~0qI~e{@DUK z@D5}>XbJBV|dam_gN+3V57)r9z zK@Vt(6uj{UiUP#}58k8(N&;TINka{(_)QO#2Ga1G5hx3!JcEywR`}4(p8RHw3J$3GxQ^^+~*xE`mrW zv)8}n(dMnng#jrk>5_fCw`2L@V*-13npG;2%C9W$INjA*d$LEjY(_6wERgOE=noh$ zf;B3QKY@!ARfCHU)>z@(VsT1tHuyMDZlq#500u)1Y}S(OI%q|flLhY|v@_~580KP? zzDlb7@%q&(4|5CZ7(}>vR^OtP^~yWCKzOpo|1@#3>3c1zIMG*GrBVBUCsuW3aZB4V z2reOMG3&A+{xlbk_kPqQ+?#2|qFs7*qJu5CwiiQSw2XDM;|$5>Hg9dhfg;hBOzjqG z72U*ibq0=bs}+$vKi#~j7E2c%M9Pmws?xj$i(vXVwjMj#7h|Q4KoK{V3c!$(T7r)Z zE~R0WYAvm(qh0q_QEgScG7sR1t>9v>EW9d2R>eKCmE6t%!+-|3W^)UzDDo0HstgC-5Tu z1w11j#d|6&?@F!I`>4D1iLL;2&Bb35&5b^}8fD=NDf@N=z#YW>$PDru$@#y--@z2> zGpyah6IXw0>lV;neHD0*ZLq9j$ojG~Qd2u*y=BjhEU)K3H*e#gYP|i>o;&|kOU>ji z_aJhCh%l{-x}^d3+l3ftmH+p)+%lM%Ob_e3Bsk$1&NA9rMa{!gUlW7VPZVq< z1ATZ5EKPM0R9O{sL#03f;BQLDz|%PiNh#L(WPLQ|a-Kk2qL~`wyb0D1S>?0!>H4Vk z3Ft@*;iszUA0mNFg~?8uA~ZrYMHG%fIT{g67jr||r+9We zMze$FJk1W5V>zZsO4|8t!`sg99Nrnqy5;u&%x+4lp2=7<^1xKansCON>%Mn$-^u-; z>{iBJ*iLt+o^Kv*9tm7HHhS!qdlAg4D>`CLzbJ%P@yyk_lMMCEc}4pa~=(RN|wLv@goU4Up;l z3??hjo;DOH|47ZJ&KMZ}r+GpXFzC_e4gK9kbB3-Gus0PJT|V^Nhej*LPr;m|%S(c~ zp^}@f!bnC=X!Ym=V~>P0YTh2Ww(qUe;f&S8O*0tGlsB=P=Aav96BIo zN)){$44!y|c)v5B;qN*Lka*1QcI(dQLlc-o-O6*%JPBAl_sCY!WExW`bM)(50?$0fs`3GH8*S~c?s3-qC6 zen|_IUphaf+B%*oiP}WuUEGtn9ePQ)F-zV(N1df5iFHe-bzbzsv>op?KKakE807CG zfG2rld#-8q)_ z${xIO{M24Hli4uRI+fWF&TP28^4+!XtewoddywEz@ddps>H1@oA*c-Bvp6`ctzrb7otoBeG|IBl51GKnDrPZN*#Eih(_~#xN z!<2~Ce9t^z7&9^XCY?xT_tn6+t;8hfXE5p6EVNv+jiOeGB3V1(nRFjx4OiL(NS&O5%bts#$(+iermr^7;4dun%kGQrv3;+3fp3~43!xD~ zFHN`>Me-J1uD)13l~)tat3j3rBd)Ze4Ux=T6_*TcHK3T6J%&F<9=>IVRRu#Sj$MDiPn@CxfrJ&M_)twyazV6rb>9ucTtJeSI=Ac`3t zWfIa$#&vLy8Z^9M>b4OK{1*vl43Y0j@7UO(k32*WX{H4MTaJ!>kxG@M>K*7A1c)tW0c zQ`PIj_`huZcb|B-`+BG9j`sZpTCQEQ z>Ujqxt#9ypeUG{m>~VaCd+i?i66|t=$!PO4F>Q9Ltx9-mNKgi^TJ0)X>uJki@^O+h zj(gNGg0Z-Skoe+#P$4&%{KfO~`cEc%xfFv9o{~JO;V)3t#n9dJ ztQhK@@~jAZR$RB<^4vdUQTE}>HN!iGHjiZDE_gaM=Yo6GJ(XGn#;EoO8P=YaEZLq< zOqNs+P)&BxSmxW-TUkqq7@)2H0F(9wp^;bTywEzDz7$-|9#8A3rDjpFKvgdwET+M0#oYZF<;nQHg37< zy5hRFb+U3@*t>4RzHUAaqrF?;FxTC#&jhE85$m)6ocK#3 z)-UcXR%7;B<)0!CIAih8=PyZJOGGoE4S&kKyZGYp_n?{Ai?!$Nd-gm5wz|hYy%26~ zK|ekxUxj&H3HUAg>Q(U+>4T%E+ZTYG1v#+5=uu#@;+`-mz9&o)aBl7alLUB|_L~ul z{J-vzGXeb3SJ9=I5aLl)_>ur;fAJdBdBmrym|DaiU%W)xWd?<(Nbs!hkv{>nXte=a zb>um++jGKuRzlk#s6{pm0up~U%ayvdcYL#IBTqX-GV>B`U1Wj0MC}rU*|c-w@pAR8 z{u@Xhw4n}Lp5{YBvG<|ODF~RohneNLM=AC}2wnvoBpw#9@!sSRCPR(y^g0gVTyqva z70Uq|zQ}i|C!a)zk*-U zThsCT)VThui{xqTPPmd3?3mP3h;kBOp+KsdU-$?eNs{efa9*YJ+`Y@Z0tI~KbIhy^ z%eEF&<0{WHX)lOSRz()U0`sK#e(Hutu%bjIqBktj?w<#xniX z41SJpP-FTpVIUzzahBF+>>5qi*Qmgm=vD3)?3D(QFVri|=rn4~qZ$Lg!8FVwJI)7h zTM1*_W!3kT;AAxy2h2%%Zd7mQrfidPCCF87bFykJ3be3M08oNi11iLzDAhT>4%oy}R zj%1@1G}>9J8$kHjt6=i_?b~;*?33$If$;R0w0>uB?OtKX>J0RQWO)D{4Oo+Ktz)pNT~#dZ#PkDd6&){`3%!J5#0(Q`F+Q~N zEm|tQ`|ki()S=1W$#jSn!WRrp;(5rwhvv&qQo`hco|Eti74@(b7`SIJZ%3AN{+yEi z8U>ovwKx-#u!liTgc;-{LLZg3?%dPZ5_LklJJ8YD26cND7^=z?hh;t(^AUNPQriJX zmPHd|ycUg&+98xC?aLsnp z<;Ow%)h8}=k9JRGRfMxDZh9+l(RZO?v>}{PH6FNn{L1mGy;pi~q)pat!VzAu(Z^e^ z9=vk!YU`EO$-MhVHb=7aMxTjPFU38a^P+QX#cSS3n(tE1<${X^Q@PdQ+!zkvL{4Kk ztr6FS;?q=aZ8*1fyzg4mcea0X`}G5Vv}-bV(@1h8BR8B;rdRmzwF8rRYwuCj(s1t5 zw@+UkyfQeoY)g3AmWiCLH`BIGXXIa4Ke}FAiH< zM%s;i-^=`<_M1T`#?1ovhjNx??OW zQnBn>^7Zs@x~_NL=zr(L2S>vj_D)pnd)+!yv1EM9c+1$A#;hMNE*@L?+L`gDn~RrE z`zzl}c|Bz|$y~NJviAP#$rBs)Pghirul)L%u_v!BzL9;y0U7+V2hF!F)}mr)3KUiS zq@)6U`$^rJkNo#d`d44~T^~SK>KBEY$Bx}BsGVJBD&A|pz0qu1vTVG6YS{zfWe?nN zOfK62AQ|RXZsFyei#cQEletyn2Pbn^NA3ySsec)8P5z4U^2x=^Kb{XWf9adH*KKdQ zUw4l`e9ONQB3@-sioAO2$|;(L*Bjq@X4aCl)m%L0#26HnX^Ho};r+Pbfg9Ez*uH1` zfg2;ce{$pA$%cJn&hd3&|LPe-xkwt>()@!*zW2xv4t?*?#Qp>CwT?L_mNbU_n~cf! z-|{byELnDS^_A6E*I!wG-Tc-AWA;e(15?$zF} z**-}&H8h$(DqTBSy6*a;H)t>#l+O)iXi7uaziM8)G1l*9zmxrL!8-*v+Wus*l5A$_ zifacaYBv6^W46&u!#KMM!?;o%w%;Zh()`5=`grtO-(=o8Ud5zdc8MjVVuDw~g7NssOzT9=O>(Z0AC2NM~ zCyS~^w~p)!nIjp#OOIYYbn(zsVO_Ye?%Qj=v;Ldwr&ctFS2Rx)00Hcnl}u^rBXy(J z$f7F5Q&K-MAwQ;RYQ~WBv)lWUOrOaMX@}NO({@33DW11$HKZ5m12R8bp=o z@{nC6DC`c9Wp=eZ{Z||@$x^Tt1$&B?wo3SU21YZ17 zq-yDS`<2`gt6&k2m4s8vfww~$qs^b#OuqXCs}-%#9_;Oc)p`<bW%2{~B^V?1aHd}USp<#4?oCKcNdDglV!&i;ZH1-f)>dVER{q*Z zz#%%2wrB78hT(<@SJ6y%{)OPH!4V5?)kY4y;(#T*oMQ0AQ!^k{j6M3LXW;kuE?^iz zd9k)cWmOj6W>S;B%;0$?8ztcYM! zrdQMor{I0@fP-~s1K{|t?F2aDw_sLb-Y9Sp)(8a@Ns<;OcLgrGDB5h)z=POSvI+-VW{c+j^Q06eZzY&$uBrZouL&YUI?O| z4-N-ICBym*H+F>LXsUVcR}fiPBK2u*tpO>? zFjeQRXm=|d{;(ySJ^)Ba#~5F=5QK%ZyUKi2Z*!PgI7>z^oFce8At z3aN>W`zGxB#kxi>wTI%|>ywBqI61Le6Hh2iz?8&a2>CB0T`i`VvMpe7Rs&893{^-` zzcQru;W(nIPPAf$$4wgT%_9U7;?c%V8ga4!*=?K)dALv{!NidjFM8)+uW3`E=WakL zxC>A`3j+nh%n2t30ZajjELj&=GdMlRbzggP$S@-`Y(LgMzx$)!8Ff{RDxFWb;f-+T z4SGlko2?>~e^*Q|{{r*EuzU#9N3DR2EdLXtF(}>+B`tiwD$;be_|KyRuP=z?Ge(+T z3Qj2cTXHt4g0MbaZObIN!S0hdhPQu#k9RyIdh<9~A~i6Rdgic_fCe{;^l&;&2Y;E> zxmh8kMlB_n8Jkn}zmz137)O<;gJpRsF5b?GGFd+O6si}cYh}v(T`9qhM!U`BfRb^pYSAb?Z5+6`QA#eoE<;m;Da{zK zHW*JQKpw8jlZ&X0#T1lKaGL@aL#(G-eS}QFu7xoo`oP-{b7+`7#KI0Fn#f{@@-*cj zDFne2`i%a(L%}~&V5S~hC`hKjPJxSpQYx7)*92#TMX@MYObn5Wc>k-WPm&f(b~>@- zEjqV#Xvd_rFyhHLw~d22t0XO(^CU}|bEy_-qj}bCTE24D;*pj^eO>$(*YNL*W6_+1 z_j7)Sxr`JUW10HZRGvx3uMB&nw)&rm?48O#?R z!$ipQy0*6VFf8K3pBPdB4gB50UV^&2D^VowK>@%s>%?ACN>Q=30^DL&8TMN`8r_jJN5MoMJ4SU6w zth_}xe~$8k>o*gx4OSB#7m(fC3)r=g=M1u>2>5ZUV&7uPcS01uU%?uGNHe-vfQ}6J z=;J2VwV5q_SJ@2!<78C?(k&D$qkzYS$8#~2<&ICDM~N7(_$ihM=2{VV$sJt8&gamF z0|O^XBfqavmfOxWlZrD;K6l)`U==&IP!o1h@H~x*nYyjlE+%Kt!?4@eU%QVZoZwD| zKFnGSgHcb#)KP(4j0Z!Cw+tulIKNeJPY06i20R&^E>{~7bnm3yq^qLt4AAip{H>Ok)QR7$*0g$9dcZMnK=y zzqCQnT?(@QK_DDaL#+Mg!)$LmSgMz-7Id_?w;SaWzKH=X4_dOJX)hB%bW}9&`v^6C znO*_65DRgk9_)sH0A(r8D~rr)-mR_>eV4VtQzjULe*kYm2e1i6ZtY(Y_;bl%wE-|1 zs)}uap6kQJxfC=Mn~RO}@l;?7eH#83c*Jg44!=k3E~Vi2DbTlP%8gd*3+D=bkDH$J zwgb*(mA`|u3VnlN6nn?~v3xt~Y;ElvAm7uit>lH#B(FsX*Q#WpqhI)rWapE%?%rc$ z5mbJjCiNOZ691b5y3CRPjNYxHKk3p2t~-0XyXl4t9>Qwdj<(Cd04ABv&oZ&TWMWCc zvkA;6$i&!+N;D9CGI1TE$%s=mPD<#afI&z1sWM$$3MZD|q8MLMrBf_}0v`o*yCT!Y zV${|uoTAHo@kBR=tmcUh2jE+?1J?FCD z34zLgL}?v3PVWRDKmr%h%j@*gv!6WNpXhj`O(qZE@?!cziv4mG#g@9xt4+t zDEI*dKcavX*kv4dmHEy3Xy2ee@1w7f?8D|l!A=TxQ?Q4Ey%g-DU_S-V(I`AZvBMO! zA&A;wQ*8itgrdnJ!u0!zs14^icwLvpl3-$S1?B0aJa*i5wrttIr77y({?OK~yBc@5 z?%BQbv8ZML&MmlYYkm}8tS4YzKAH*W)Pft-(NVjlyMv4@wfz5;o!gHSRUF69ubq2m zdfRr|?Y7-Z7w9ffSSg6Ris0@F6+za;c!xw$yl`Czmmp-kM7v%>i4WE%F(zt!!o&w3 ziT(k$%qkF2de#|TBbxa8&8Si1i!a~br@wRNv~xK#%{g;^KjfMH)Jn3p%g=*e zIq>vj6+Ga_kDs1-ioWA%5*qiId6wh=$w3r6V}G3cL*zP4a)jh4$uW}SBqvBtlAIzr zO+xP)&748GrqVs^@XS7(-IVuE?wqJ?**Wt%6^J|TnV6iOsnPZN9#wyz{Fo+!|adn`SE5ZSg0uV=rKb#i4Y7 zpEfWkeap0YX3VqLJX7acbe=_gKt?APp+9z=ZL`_71(sc4`K6Eyp(RF={fpuZhT5#W z!1}MVp^j0sS&@grkXaCx;7yLWSo#T&ym+svh2(0X7%! zGITX$4|lE0Get0n(RfJ-;*E^Q&|vsoG3Ezc9e0H2RUy+BGR-a@&9-1R!~cyuBBesO z6JAPyO#Ob3q4DA&NYwXx42`D=VAfBP-^8V(nsL5owx{txTP<3WW0+0#;^>DbE}gur z*m}*Hn2+Pqtgn?AB`kYKeOtX){b2On(Jz$>t_MwEMpX$wi$BiFqNmAgumQSo^)O z>q}wRbz!?LY{#s!R>-Q^EQvo=Gn{Z`>Z;bQqpVtBT6DQwBEBtia%WLgbb zBEN|lHLz4y(qNUFQ&F-y47o)GD)c&d!qQ!77}D-Tkc9-tNzAQK10FV^>}W<{3w?nt zuMBK;+_xRE;)+<0SO5PuOQS2`Zdhcbd^ZR%1&($n4-<66tSb_DW*91sr#yycNk6q5 zRxC2orE@z#0b`M&ESUxoidzZee(7;2@>Oj81}=}lh`$SHJK8cXqQ!YP{U*NzyN(ob zRq`DH)?MW4N{IT^(RQ?ME~3Tik@Z|AQdpPi*P+;PF&-hGPE8m@`+_FMV9ajlkoTGL(2KYlg5XG1Yj4%ft%t zLtG`sAmZeY5MyUgH6G;#F}UgEyM-%mUc_)El?nljVW`7+|=#8JM2xQyJ&mOEmkA=ghgL-jo^A>Vw) z`Pb*gHCVaDlJ15iXuQI51zh;R~l#C3T}>MAPmcR zN{6l34RCbEhZ1h=!#(!~&=ECPBoFo8jjky{)y11_)yw6fvbc#sdXAY6i&@euu@_=A z|JZjW-Z#hk@zEe8oOrQ$?BaOyR6AaNzSfBst(qro6(Lu@0`*? zLc15Y(^D^VgKrDGG0>byzJ6P<9PjOiTSNESg=sso+nV@B*6JfKp13M!+j6$my=G2c zi)TPJ>&kg!)^PM4j-Kfqxd1B>Mp0%U$RCl{RUR= z$L<{^Q&1bXFq#@In&io8fuep2q!_4^7HIO&0(~sd7YRfWgHJ_^KIEkkz~m)Q{bu)$ zI{jHzr2vI`1b6mscjxwIW@l$-=C8YU#S~nB_-te%_L!pllWzR0K~~gSNL7?uimvFY zrR3Ess;cNAy}=6Q8?H2vXoumx}z;4Z*cz}99(f3#Uy`O^>TZ8suU+SYB|jn>`3u?INz0Ja0R13m=!5a3?G zy?_q`KCC~ccK~**dJEGNc%IM?>4)`wz}Q*tOg{cO5hSTr<65C$yP9j-1?O|nhMq-+ z^V)=w2}zoXGJ+B`RBPu^xuv+&Q(SKbdwI`vbw+tJ?A-*wjC#l8!(}BInttth)3TVx zGC9n_u-KI8=5RY58j7h^v#bOLsn!Dwqk!I;)Ii0aI$4QU<@Y};9DKS@B zj){&{btKuqX~NZpf-zMMJLa^J3{@j0eN{CwsaYk%p=mSrRi-y*=Z)S%AJ@x9?|C~@ z${PjO>CJ!~y~VPdvkRk6h8qSzPUA)|<~G@Dnd4sLQ>p%Ay^iS`Jw+{Z75JTAOsZE* zYA9zHom8=0Z6a*0R&e<)yfuNp^9YLT$`>t4%bs@zZw|hD`TZw;bM%)-ZyS|(_k6g! zhGr#GCo*nmzJdXVQMsjnz`<5Lqw9_Y3dpNYn?rW7yhPpPcXp$=t}KdgPv1=c?DTv% z!CUcg*$0#Sh!1vA+315+A_#h~yw;Y(Hyc;>TO!>ZkF0`(mJq1n!lc1nrWKfwAlBsx zY%;~tX(^l}pmxb+XV^>UUS~bB<0j=c8LoycThpuIQ4-sbnXkq(5TQ|1yr1vEq=Tf5 zde1xYJV|X-fUfOIB=+`&A6>XHaxcF79T50k<5upy+-Ds}7dnnsI=U>0UVIRpNWzId${YyOX!d@0CAG^eiNLX0vzAIkS>DS&0wMhX;3(RQ&O4lL}qqSMM(r zW?|cfLh1tfYEIk7GBJpH4TsS1+@_?Udm+(1``X<%=H93zp031C&WBI#Bq{ivkb;-J zjG*BxE88WOFIlcxv|vy9R)A-%LY7RO zja#t(r2g*~f`WYrBbe#PrW6~_iWw}!wG72n4pw9kg)}yRp;XWyj2YL^*Ah6nH?X7L z?!$V?1ljTyv`a{w|JAGIt*PGhO-NcMAZ?u+?mMZ4L~3^OZh5X;Neouv>G^Pa2T9xX zhwF%%u;L6|^2u3S=GHYRySf5~Wq%Uv4n8=Rlx*L+=^=L+dE!~k^{Cfy6#OQ$+_yDg za&BO2?C@RYt#x=#C(gB5%}NdoO`$6;+gX>5kfq5qYr^I@2IsfDfaR9q0QIP_5LYuZ z7HI4NGk=VK%`+ZbH)QC}-ZG}Q#LyQsu76Dog%3hsm!W~ielYVF`12GM;&8n)&U!Oj zS!tJWkhkDh+P-Bbk7~BWyLyc^`Yp%7hF{_DYs`%o*t(}Pa*X&FIWmNk>OeGx2G7!U9M$_<#qFZQxfGdI3=)cyF_`OL1C|Lw?s*k z-6=@|@TW;gmJ3i*z3~hhKiQNNEg9{fKJn*{O5%k|e0V-Qypy(;x1ouai4C34$g7*N z%wlo5LV7^G@dO>lwyrFsF^A@fr$|7}xz9#}{We3bpf{1_hJXDab?^Wk$lXaQ>!kQlKi z5N@*Axr^tQJa_f2z;o(63lER)_>-+aQ|UpP>{c7$}U+tLIGD1 zRsLKq-G@gTrKHR# zGwMvpKZS~@@y%x~!`FduvI}>dpQr&HtrZ*!Cl@khHf4}=E|5S`SKrxEArnlZ7$=mQ z&z}g%bd`u0j^vfVfl#xGInAN(_RoR*B5p*{PDG`25@eFJQYMKA?!G^HyA+J^Zzs)u zGQZyp=K^-f<%jA81B{DbyVPF30)7(s6PnZKLuwy5+ES3p409QW=$6f zuJ&u(_yJ91Pf?bS7sM3WolPNnWiVZHH5fDqKvD40b9%syLPml}u@XY8o0OQ8F%Zi< zPXng7Rzy|=w@X+W)YZ`8!4{^_*jQO&8G~5@r?&5EFu=p_-}lqTd*S9avU_gX@7cE}W~VA0!5Drr zDqi_je3$|eGD(idX%Y=)!L3GR77Tw4PcUbiov8EI{TdJmT|_;EhiYYeXaX&`7SD1L z)nshV{&WznMzY9ma>b|dH}D|vmZmjFU7}78)bnNPDdxB|bM<1fDey@Y5a-{e;#CyW zF?>IpVHfR!5tzrmYHV~gTS97(F*?dg2UHcInnmKC$YA50goBc8_#rBeP(d+JPC+qF zffP>8cTOH(;jQE3Y~jyPF+>GfzrrLE8>7_bLOl`Z=cKbL741hWyE8q}sKn@Aaz;6bk zfPgZsQYFyZj;PoPp|xD5H`+24Ix%yuHg+YZ)@`_>*21~H^6Ps8{szT8{yukH^XgVw^eV0f0Mo$ z?iPJ3+->@HxI6TnFDPO4KdQq`T;E-&Z?093jU0AA!rDWH#~(9mYQL>^HS2wPzy81r z-r*Kb^B~eZ6l%4;w}tADAGXt(KHa774sAGo#Qbf)$2{2>x0V0tAJrd5X5bu3>KZN&wym#Y$0PlzK?#BBO zyg!0>hd!)7iuWEnC*jkd(t8lzseepAi1*%U*E%IsQ?D57hF4<_1;*D*tQ}sfDuCj( z#~-oVX!=5{FQ~#lT=67k`S9weR-aKn{hIKdR8K0;x}Q`|s!dN{r)W)TGB+5BMB~AD zI2wudHo20%?nt~VGBv@TedEESh?8Z6^r_KMlQ-$^h)gGaJ>huB2#zQ72B#(`qeeWo zZ#)`|Cv(l8$Rg=I6hW5PsW!;f+dUCH8cODlj64%EV)!sJf_$^}(4-L>4aP(G5inB^ zgn~L%Y$S{{;mFa^iCD6L(|1n9`iP3mwDE8}J|04Jt-G^R>x_;^4eeksf?7_5 zB5`eSIu;L2a88}k$!Q~e^jKVL>}=AuY}&M?1 z#-<{pJb{|EU`#t18Xu=OfHP{ej2;V(a!JTXn-GP@rcglqSTL@kV>v78+h>A+J3SZ= zY8astp~*Np@@NPZGFnAPJbnz2uZ83EeKH!0g^%DTI(rnkh#o@A?8>00sjB1C%}CP_ z(=g4oV}RrFX;~zi2w2xcy3GGEF*UUV7@?>!-7ZQch}+z{sdbY!86Kw}c=|@;7}3pJ zwSLTgszMJB|e(Xg67&4I*ZC3HZ;fEY(Y7~~bRiiIbp#tFEaxf@r` z?&PsBpgkO0F{j{Ye2S;j6ip>GOSZIa(g2R)ijL8Q(`1pDB`fCDNR@BUQFl%kor+IR z#m#m$X)OS+SX7IJLOebl{oSqcX9eh*UF3X+Bb0iSFkx(xFlEbbZ7N2f-(V1!pngYz z*?}D!=o1geidD;)4JW|}-;$T8`CVkTGT?OR0AvA&`+7R|4{9+%n_5@QRixm^Pt^_f z?HlSJ=B29@oY|0|{}hn9q@^@VMSjkT_%nBQZps&>EvOZ%>9} zVr01C=D@TOEsCr>4kx2i<2ty(#0g5+i3LR~l{Z0)P}S9%CZBTTQ}g_Z+5j z>lT2<Dv6HOckKXrv*ojfdjebaV>vhYsX?SIiAm1bsb$ z2BQu}5M54GVF-zsG0+-g@u|r$CT@6)vkb;gteDqCs8-UwrP&^nOkEMYD@T+48$HGPo z6MyOm2&YM>o3*{6(N=9s+R#24iJnA%MO*YJ*a)OK8IB**MyJ3>0r^PY4A47f4u{1z z3B<>A7*wXoK^!8{2q^VTwnZdHB@4=oD2bsE)YKb)3C~$&7Gmg$Mny4-<5nyPA#PLT zQI)t9!W3nYVta0h?M;gf;Z{5xJBwqNIP&)CZryK+LC8JJj<09O{pPRFD|*hX0yp;y z-cxEk*9@OkFUWd6uQmmGlev4l20I73`-i&wdS@z~6Rg$o<$3_=lfK8g1_mi!X<9rP zn)EX2nJG^Dm@y0(C^qAltWU#CX#=d_qwV-S+FA*sH+!JR$van{$#cdZiyrC}S zw4d(0no~Jnaye)9f@k#&6sU}nV?J`|)f+VkIje+}VO3Y4H&LN8aSeNP_pn#@3};Py zo3fHwf;Jk|Z3d11b@E*Y>?^%ZK4UfB$()f9F^cH>z{tqQ!3oHb$m#DI= z07z=Kf%&c&O>iIw_VyndN@n#P8ltzCNv_dK-|d=jqMzh^3V*R8IH-9b?{rrpFaPvD z_&(VsVpE*7D!UPYN4@cfa5GmK@;gQhu6Ni6H*44r*EgIE*FT)2XAkGXmoprIn>(Bb zH!z$JH*dHAZvJo~+=AgExP`;TaEpdZ;1&;;!YvstgIhXWu9pp0=;gzedc|;+UOBu< zuYx9P)o_ho4Jp26cui<6^hc{-@Lb^9LeHg5uW8bN5O|_*m$F(TPl?F}45xhXK zjv8ToG75SXv$>e|$)FLO&?4)3kCe=s`RaG>eXvv)Y1KoT3`?`CF24@O+>{{)R zzd^hhVUN?w&3vV>?4_9(XXbR&l_e#_$Omc@eB1%E3;b8nN!=%!NKs356a;!{S1 z%WbM%K8<`MBLEE`%l(wV*W1_G(RrXNnbX_X2g-D?d$=o^*L$d^XK0|KcW__dz(G{9 z=U-uJ-`jhzw zy7wO#=o;)F=<4j~=}hMJ^gZtQS$b%&Yh>4+?x8`DpvSs9yL!5NA59kSKh!liC;~cr zItB-md5?B=^^Xj8ee_UQZzt-FDs}>u0ih);$Q|kL8yp%z;;xQ??qN}%a`9oHYgu?M z4a$DTmxIZi&c6O9M>=}?4|F6;d;9iw?dv#%Ug#R^JA@MOGnqGH56;Nu^q*VOe{M_v zxht8UmUc(_@2y+XfA83qEJ%yLWmhslTyuDI0#bccH$H;FTaNn(&Uny&2cFowa9&Wp z<$35@Zs7FZM1JY%{Rz+7L{SB>INqhJP9IEoH2J$GQBrlfCjr#HdfkF&RbrL4;HgM> zY7%ADr+X8g%`$r1wd&dhPi4ZhE>QtOP@3>OAiwOC8Pz7%)Gv6d6Q1odC(pJ-apmbp z6P||?Mb%XF1BvSO$m3dRH7c;oDO-)wY^Qwf>Aq{;qVKt~ylpq!N>=fEAA&qEPD3C~yK35xOvMe+Cc4e{hK zcF<4E5QupUyT(q6)KAVXat@L65ILl0H+I8GmNV${1aZy{;{l2>NX|#exu2W?a@ye} z^H9QI*T7?4oY3f`4gS!m_U;c%@=D|6w%zyM;=_^m1uY0GanR|Q`q1J;k=}~VGt#%MgudYJ%?54#X z-3{foNB8Rmfe+!{N^Mo1snN@98-em8Mr{W&-`|&K(XTPOz zP&ca{&$dHNpGhxIVclTXbv)M$x8J(UWY<*)566jjSoXwA%z)#>*DQN%b{{_3N>!Qm z#H-DSv#RbjzZhHZSVpOt&VHk974|RFXSU6(zxn3Uoqb9Jz|V0aE6X0MX2qFnX19;> z)w51{;%m(;W<6$^&#UW{II*z&VD;f~2u>tg@Pi((#I^0pDR<_Q9Q~ZB58U_G2fBy; znXOZmCsF%#%4W=hlP>zD;va>H)eUQv!#DGKjw#7YUI3~XlF{3>E=a!M9D>kfkY)>F zGu9$vq?o{uAY}4!Rz)^j8Bj(d9HR3HXp32Q!R$yd91*Ex?i%#m!L)?q(UUDu@rIzN zl^RWv+~!r1-jm@7h=?~B8x4n(F5^gV(qmvPWTvt^@=S0%EHo^v5s-?8rov=S7#cd# zosU9lLrdUH$C7^NPUEDAN@j&3q(?|*=^=g>V_Akg&<((4sW0h?LU)n$jKo6mq-PW= zr(}_=IfV~WC<$$#y4J!>GTYL;Ks4~gLgQmepG=i3Hj{If zBa^}Sv7|a?XvjK7dIBCQ!Bjy;MW4n;M$md%IHNV`XWGOgctqPSu`I)1y#;)Y9 zyIN5E((H?~^C#aa*pOJ?{N-Q!(yv`!zkQ*wF6HtTRVPX}ES0t_mbRQfdZlznDo4pH zda3)x?$7B<eSMw_7eXo^%dF_|hUdh`mqnWi)x~>=8M^{WWQFwRJUufZr2+{e^vgU%fD86xo*#u%FZ9S zl~pa@DP8pguXw+o@*(;Au_iS7&x$(hmAC54x;*Z;?%%q1hxeP!e)zw+!`r1~fAax1 z{C}-@;P#FJJ6jLoH2hX?5CH|TQD+q*P2!n#;g^MLbYRdC3)Ay2E2nAYb(I*_7m+aO zH|Gk&2UZH>tY5Hyg(G9pCbuz%$ehA>3BDL*h7srSHa>|TGo`l-H9!(}21-oBXXpYd z*35Z69Y|Dac;zK(@Ver!;`h6LA;zXrRw{uT`v^Qv(v(>OIc||AM3;|=5nxWMPTC|k2$yPCtVzgHL{+saW3e@0Jy~M# z6e}!UDpHU$8tL!OHtNB4>_G360;SBrcJOm&>?C*ZRP zbpKdA;FJ6y5EIpR<&hV!@%6CGo?W zkaVQx`tdN9Ck1?GSg#_HoJv1@SgZ!M64rRCAv`)dBEh-gX=pmQ;NDRucSzmN)BJY< zuCR1cPi4=#XFX%Cy~@*#igGGvHfJ{b88xPU+V9{_b4cwBuEL9dS+9DIBZuYBY|aJb zNRO>R{`5wVGMjaJTbu|MKbiPg@OZ=*FMGhVW(q}JXT7uj3z8oO*0u7EJnSeZ0~p;? zIa#+U-G}mJ-JIpmx}PNq0dZ>)~(KNZ^|_0hp3l{Q0!f1p4*1BE=<+1ZhF!)*!(rMMd!W`P~^c?HLs3WA1Z$IZ37WJ!h< z9`ISTI!fBxP%@kS2g#c&U{!?Yh#&kRUw)9F+my@5H|gc1$t>~J_zKmZbd||0D1E?t zCcQ`y9b?iN9Rmv_0%;8rMlfRPf}JljGB%H*<)VbcHA6;)vi?y^QQ^B5Hw_ z#Ddh-gzUk<6qK+6uA=(0%LIE)9anxn`gU)x(0{Qs_^j}6Eh^5OWF|(HX%y9Fr5o0Lk*F9at-Vs%1EGM~W#2zvyg_h@KFyA}1O#~{>W zK~COFJ73&+1~TY|#qtgBc2YUS&d7gk;IZ%fp!U#i`< zSi5bh_QA#42QSy|o^!qAd(n3$Z_&RdQBX9O&5+YnX#5e?o;lw?wtP&4X6PqTB7=Q@ zLcaCn{3)FG%gxsGOXbC^#;o|CS<(KSe5B8XEI?iKel8~w+#s{*#@iI-w>&U4k=kulm zQ(7fPNc{!nJ(t((2N7JQEmdt?tlF4pY)-6QzqIy&#kCJ4Dr(NoygZXC+38(>tzb>c zi+3tZDbi9t^7)mr%2YP_a+LC_R4(}fN>N2Bk9=76*^nwAU!hX5I#oozVk`ySpxka4 zs_I>HGt28OyP2QmEf$re`lU&-gw6qP>J4bSKp5iqDV|I-8%k7~+v+qkxZ|z~_bC+$ zJO`tO8Edg>W=>#oC6+L>xP{a+q3yV(R-IK$2H92#o^nO%?mqpqY79++N)_#*$9#iC zxlW@6wi?mKO_McBe7)>?91+$RZ&)-lXjdVUoj?MoKZHmtYB;ew#)vre&ed z_J2||vBmDghY9))V}(!{gGvUDOa#e*@&p;s2qDCnLVbIA%@pRyeg@&k!(tH})acjo z)tH5oRE)nP|1|mC2ljRfHna-lXhc@VlyF8^1!z1<(P@@8xszFJfEp56kQ^UN!#gDz zaxoSt8bS6LJiPGe&;8BWPtKk>`Hm0xpyZ!DtG??iI>KYr?sk6+&0ak+TUoG;{Lag{SZ!Lz za65|PtVa$g_MadqT~vmU>Q3hLld(2yAZI?($c9BtS{ECak!3J1){2g1NfrIiQYtA_ z$lf(X*0pRj#e+?Gk+j-MTB&rS1A#7ar^C33^DgJSy-t&-FSu4JDO+)rrN%8}Vb(vE zo5@59hEsN{U3W-ju^M1NEOY~XB=M$Z*E!yhk=?UdU&%71rSWd~%Z1hop_?j1C`W zIZ{$%ASo(YqbxdiLJz< z9X^a=v^y5TS)dg393ucNItsiFW8EoU!yy(cjQu2pK%|+s#NRQoj&l!1nEgo=6>Xuu z3DOP(>{bxQ#ptvn(`i~OtM_3w~#TOX+o-Tt8ND_;R(|sC><;sgc&;9 zVq=`;?iaIRR#mY#z!^o@d=pl+LBlct=jsWy1RJjdcF-Niq9^H>AXNlmEzz--qrnNw zo?ODBS+wj^r}h!aMRC-hv@=51iMtynKc;OeU@9KvS^)5{|ZtWIW|Cvfkd)b&O z&*O%rl~z$|t8Gh4U(M$sZIjk0Eu!pUr?1P?XS6@n9?~{jmCKaMHcvH6q&KYUZksBj zAuCdCwVOx=@dQSUN-^h!1+u{M1Tea=kJo_om-i^qSY0~_gkn_!Inh=%!CI!l5n&}v zC<)0}(Ga*^z@#}x1!QVsD%D{o*Vz^Vbu>@w>BUBeb`m7)YEe5FwzWD*ClO!3 zA{B4d^5CJtA#-0(3?|v4Dwt@T0qLT7azrPvjS*Bx>{g41#;2JITiM9(0wLMOSd^P` zY@V&1KlKVj?FKNk?{BeSQy>qUI)eR_$jjVNxrt}f*7qB@ zBkmmYb=4rf5SCzA;YI?mkZnouN@kB7?0AB=BnXWZD`i+)LwcK}uTKbv#&1%xzlMWF zl&{g3fRhR(^U{bwvS3+zjIVNLa*c?Uii@-|m2u$lo*PzM7AX z2A_&T?@y6JuMS?xtvz3Re(K7`j<09KNfhqF1t&EoUM3zV9h2>Vu{feQM%d(SpD3M=3W#-j9(P*`>CQ4W0KX zZ&ehLdtd3^Libw_2lnQ=znSZWe^jaj5K~bs%{2*oXK~Pgz0hF`Wh{nusVm&3(NB!U8 zu(Okh*g~Zpnr%xWltpq_WW?KGzb3ChI0-D@#d3Dw@N$ryRRF-4GC+h<8qX*h0>BIV( zH$$F9$kS`(nQc!&hjz(hhkjmxc4>u@(kHvEk#cC49Lj35hNqk;LcK#O3kjrc<|BJI z=-tTP;wxTLlf+2IT6&7-i~az*p+VtCA{n2f-z=@%tPe;g>y+;~p99JGf-bCxr6HL; zv`g5+G8Pg@)9o;Gmr1t+LeH6*^0S0In8Rp?fMQ5NFg;|-1|)TH2xn)PM8QI@#Cb78 z_p{d#t*pEeSW>b#k_WYFe|Op;ZWtrQaD>=t;6k80?lt+-)N$Rl9!Cr!axeZfNAqOk$5P1}Q^;p@ZJ3+-goIKkq1nl^;27XfBcyrRwp8KbJp?ncQBXCe}7 z7&!t8lre&Xy#qntL z#MC6V9-0QN1fNznJD4P}IWhE&;D0O-PovJz6(cn%c~JGBsWCK9D&hL05@`jH8kzNS zXfV|hzoIxFC4?H`?3okhxDx0%`?SoQ&P1T4M`~;^A`WmNSP>m#ofv_yU^$tC5@FbJ5aFq7a*US9juDoiac}Hf zx>i8WnKULYO^;`RiDc`{1akKSLAtDxm>oY>okUXZTguQZ!^v6xn3WQUEMpIus7ee0 zK?mlW5ydesI2gmMgHVx1KWT0<6d$?NiWD{9$#CgTb?Y2#gT{wJK?*R$Ck!d3?vOZ1JFUWIi|x^ULy zH@-!ml5ogYmgYm!C$X>b_wN!bcyw>2?+7q!d?n&JS;9-G$zTc4u6w?a12GsJz)& z+L`Bm^T9x;-~E=~3;!tfg89%QzME`_63a!%OyVAikhZwDT!i#HL?Qo$Od_Oj1rgGB zk0Rs>CH;&=NLw^^-9hklnl(TM6wfRPp2Ex@CK@p5kmGXKqGz_Fzq8H$p3R2n={=SG zT((2>%nJT{NU%&kO#RkRNAwiT3044!!NTILJRyyFH*BP&qqCT6Gno^vQuGLpGKzqy z0-GopDv-?Rn56m;Rnn}oAjwfAW;wt=@bPBMM{pvO#;$0>z$KC%iOyIdGlshr+fXjJ z(@X{iri^Mboi=;Jh22XD4qozCLPq^*!i$uDGs(WT-3bHDfVt!6T_4)U|4dv=9L zib_F0H0k3m)uf-`2HnC%iD5Q2fyRT?54jp9g2n4JWv+O)RI zH5%hn6ZsUyklrQ@D@lAK`5rP59jZr?tlYdUg#X*%AmmJP8J(Q@@u~3W3EC@;bxDZ0 zVUk~?BxzB>-1_v|lAitelun1&3M&=>!+x`|QtT(`)0Rv#WP%PNB^5S7M-3@F;Q+3d z*whj9BCX89sDSM=fY?wk9u)JGO3qH8QtD_r+!VS7)P|2XC7anu3vrI`ZK@zK|kkk&*LAumCc}oc&>I`IGTRroWXfA%rIs;}5TXyqE;+#(t`$5%dQZL(xh``9AQBpwv z&`yeuBp}N(;JLf8lj5FU#zNhrBFKWPOf!x1Z`m!W>4&2@_*1cV`-M{p^&0;KIT?Fq zY#k4sG-Jty#&_}A_-ArR)srmE1c%ENK&0-VNiQCu0=ht1kVEI1#J&R$R6xgEKLr&~ z@x7>kGFkVKT8J%qiW6kBQ_VjSScGlRq#(*B1ySkUD~RekJ<402(#|ILTa|&%diPuP zUie4d=mYcdz=PlFjdSpjNzSYbJ1o?Uo20FcTD-%;J?q8}3pL{z3RcWhZsdq~*kM5> z@nhQyjJbGUg~wsYW1UAe>tRD4&vPD!qQe!ugiSJxPE18dhqa3`Sbq69j*9BagVV!0M~C)msu7&4pySJd4%mAnp?pQW(i(B!ci7tXX}s z?PQ4!tA{#{J{9s3i{@gbmu_0Iv!$q}1Ok|40xT99g)#0l3I;zQta0JN4JcS9hm4JD zBtl`T3c3$wwo;@H3hP!HFR|7uY*Fa|^LW~XKo^+XfK0^+t%gP;ko(L{9AR->{E7ff z?1}SZIt0^dE!BgX4m}gDlp*2#q>#-~7FJJ3vEU3n0L7w3VY{8UL?MKA)-hZr0}*is z;7wz}_koDjV`R=FNz!i!9BsUbTY=pt@`ivTA*|7dkq97&w#v@9vvDuyD%C6KWwQYg zv$3C*hK`K_xwb1dU7|BnpcETI?!x?8C=DzW2oz!NiZQFfwIkvwO~VPr*_iRx9Z(ir zO9MQyMa2rW4eMdIH)QhXX|@4eqS+FGPK8Z5>CyVxjG<^pF@CpfLh8QwBkkBiz#WG^g$ zFiWj=InFR6P+|2NbYuh`E1uUxlnj?f5H?~%+Ai9>D{awXjcFNuFSo|@ih}}vAH0Hb zm7KT8;q^VTAEqXW#XWicf(2K`|H0=g#N^TGcCg8OO!ax!eJdBt)Q@BRT>iP4h1|Lo zZJ#Sq#`9$@$}2@J${!ST@n&#W8# znD3PPIk(M^t-C!}XSXVytMi>o=j!~y0dx{iF_Ww7BDbNlThU!FdtpU`iD3>>R z-BSsfnIF?qoF}K8f_IxaX2>h5H*ox*+hm8orOgO zME?qeP57u&T&9A4V+JQ38i^(dh!hrP<~HIqnrQ)BJMPz#ASTbbC)R}O2v(VljOe&~ ziwQTu1>D~LdaI5l53|?!ep{Cl2xTOS#$^@%d3vKM9fDhkKQgTr%70Vcx@(R707Fp^-vH?Bu#Z0sj!cKmi}&y-HPWi@vsN`Q2}Ce7k1h z&|?dM$5U=4I{;G?>?ac2ldj=tkVEhIR;65??53-gtLMX)D;wv!Q#rh?p=7C`cCn!L z+{W|a%LR1q+7EB$Dn+YaZC@zZ@I9EVG$l%Ry;1c>?l&G-DDJZkF*^70g+SwvQeJ%j z(anI8cL##nj4HpHyIVP5*3qE+WkE;1`%+$U$6EKLwO;Z!6zuW2FYO5Iak<}gdEpfi=5GDPM|0Ewfb zw4okl6T?Gwk$r^4YC3NlX6tgrjX#Pb5+IP6>ztgAndBs-yQqD~r$9cm(RPs5j7edD zOn{)NG+qgUVu4I}gka^^?n>N0*&q;)&wK;PL-KG8&J}jn0y6BCJF#fj)jf2eYhdMp zZPxneD^36=c0=?Hw}GgwHR1@D9b*9zeYX#G>M(PVEiic(V%``oc|@0WJ$lE{`IKSW z07&w*vUFqoSIpR?nsa>(-ZO4o($|aKu)GnLO&wpP&t4Mo$CH5x*oEVYS|TDwvP3px z1P1J*Mwo@Cq#L$O24!WWn@5VhYvMR=;|KKphvcxJM2Lwh&KmF}?Op2^w51pG&-f9( z?skJp`~f_m5*wko{w_#C!)p&;DcE|oeEqqjm&;q{_Tyx;qRO)cFBdEou3s!%Kj+0+ z+-E=W@+X!mwk}p|oeO-YuE|%_mr}UvWwtS;>v7~Du(Dki?>Mwb} zvhIB7!p4in@3$q&t8uvco-+?F1lD4E>Y0jp_k7R%?(@Y91*wzgqHD8Mf(N^T&9HH8AJ{${!Y11lGgpU zd)#aSAkn@zUWP3AnYE5*oApBSbDi=&=d~rjCU@{{NZLFl?~L`Gc*5jnf4<1yrZ%@D z0mQ;O5H>Y~km6ks7n%Q^NPx3rteq!L^e#{HF-vB49heygHLz1M(K1v#d|4z8w}Fb( znOyMNbW%@P2xx@*CBDZuAUcxve(A8bNysvGpG78Ynt4Z*J>$vC$;-iU)yvSd@voQ* z#DUAJvy-0V5WiN&#^OBtWUdo``$l29g`32aKHT?AhZZLN(i0QNns`@2))~-sHxXDj zu+}j`*RLQVq3b-c&X@sR13yP!jxLqozgT|%TyCPc>TKJ~ZA-=XEf(L06a1QYzEQDw zU&rN=gK*FJ-hBMG_b=SnG3Q?>IhZJ@dg&7{eq#RF%LR?++ZPMAM{!1>?LsrNL3Wu?s6>~l<5WybEypJi;PlP369_!P$5%v`7Ighg7~>CMv5wi} zWw_C9#LopmrWOAS&U1d?*ozrXI&s@kl@w z!sJR~r{M)ENIM^;+(sA&9U`rfjfk(`3(ja>ENp(KaLYy4MSZcLeZk*;S2)A)p`2eK z^zi7)=z;VKztnhv8}M`CB3LIw65fZHz<~)^w{-WIpum9%Xef=xkenw!7FGTbsfLwa+5LYcunAd6Pi z%&ggn&sq?eHuSPmw1=AZU=-=(PoZXw;y5bP z+L!0z@@!xkK?j(N1GSK^j>WVIWCN=bDuCAX;?t9CpJH43idl?4beO5|F4Z9K++^ET zvzokz(X{EK1w&!uYT4a{W8K`ILDND-93X{Fli@K~49T6%;!v=#5sUwP5hB%X(GHYu*r>5lWYS6&*uRX>$1v<6Aue0UF3r4UqQ zuQ13KkZaJDX#Yk8r5|`5DyrSy%)0VKK{@HWmkQbz&GS0%teA?iVrtV?QTj3l;~LKXkyQY37L=pm2lIJ!`Vv4o!Bty@z|5y@w|l zKm!?pnG1iN$3mkgV9$lsc=HYuffs=hE&D2oEHdhDB!*$rK*D2W9tiA2IE_wvkA+Q3 z2r@V(jC+{wA;Db(4pR}a)WumiLQP9UyZ3{t(#1^pZ;nWgDc-@jD zaMAs+Y6*@0d`OJEXoDf`9(TGr$uKvLup@!8>{Oda_>kg!fD}iJm^JC_L6g_Zkll{} zJaZD00V<}6V=`L9#i#*LzU=6sWdqjRe`ttqy1@M!m=83>79X`2_-d4lqFTEtR{Fgg zeTRl9B`(&uT|yBnJ!StuU*A5yT;p~rIaZUjy0Z3?Y&M%O@F$K+kyT7LNp99!%$P6% z2eJUty0e@}HYV5q4NnI0UJ{N;x;|o&f)y#eyi?wwn<$gnRvk0hG!@;#tQuvY{Tm<$ z#hylT(EffkCo}QKb#H-^mmYrc;icTx#oX5O&s?0olG~9eDZN%wc31MGU<7tPpnR>W zW4-%QX`n-MU(&qrk2-0yb=>`LBh-0*w+^#TT%IVI23*rfOK<$xyJRyNo!ZOOnRa{J z?p9viQ-%EPbFRl=6x!sSS;s(c(sA=9MGy_%i6%yVrUIv4iaR}Ff7xn&Y-|#@bMK+^ zdt1k_T>~a;*5}5$aa>XY3_cOtQb%X%PFtUvHA*ltA~PBpY2p(DaoQhU`)X8^^E{kn zk(GrRm+x0h`ee$aHwN34xIvb!%P#v&`ps$@s{j>G5mf9(H0=D&QM~yH+^y@+N%(ti z`aIq&1O-YzH?&lC-(uN)Um5)BQ?Ea@)UtcAW%uQlN4` zu00S}ruLAJI5Kg^smJ&q@Xr)W0gA+_w3|);7GH58>(?m3+vI!;PO@yowrlOgF}z^J zap*1|duUXn_Ts3+^%S4(wJ_$%p`B4l&kiz z#M{8AP_Y-RhWf*9rYb-u%XkklW>)uLg9Hwjda42Y4jP)Z2H5@6i!A>eo;JQmxzK(o zk-=H`OoYR==4`3;w}w7Sp?rB2`hnCIF+UBQmeK=)1qs6Ci zTJ%$}XT@BI8xktm&(70LUCEr0k+CV7MI$2yp@yU%S0iA5LDUd%?+IadfdNp4sW*Mj zW|j;P5Hm>RNM=Dh0756=kyK5hv1D9s(5Zw%pGVg&@{~b&*cu2jfQ?o>^^(33nL{DP zp$lJmA_~}eg?|19In)73T=hE%jRtS(OS(eOCcPt5@$k4&LNWe|oK+l`oH}wCez~6r zn3C?OF(Quttf8+2p2;Gnp#8MLh~KJb=^NH1%I#P{G(F)ZKdWPl|An& zd;UeyzD+-CQ=VM4_S>HI*J^;ea_2razkV@KJ6HeZwlB3UY~8!y-}|21wK{9TQX!EuI5(eAKdP$5^WLS(w#CY}n+pBH2_eO5{mpG2 zHTz5zbzC+oi>sm6v@Nb_ORTOZRfx?f#)&0BiI zi+8Hsu7|8aUcZWXDA-M&YbA{-FL_Xdyuy@^y?!OXD3#4#+*e(b%4ILz0hHp@7`m*A z8wDH+q-wQvUDMLKhZom9jK(gNtY0iypDMzgvZ65ZaAD*@VJO$fUO$za&E6a;H)?Jwt%AFYomKF) zvr~_{^{QKtM_ygZP4DI{;{EUeeqZyJ-0&j&=5aL#0QAGuiCV>9@;$|?)_x!JWBs+< znz@ITa%&cIYvuOdqGfZ^eAtYqC22`n4_m>r5?j)isyJL>5@c(^MBYUz-eS6ECGENSqkbS4}dNs z%RyI=m7oujRiLX$!+8_>SwkKIY9tSXHj!pfKkF?(T2O8!ZJ+bdvXZM*a--y7yh@a+s3mxM@vX+U2H#qI>+qd} zZ#}+q@tue7e0&$+yAa<+FL*v~I_yMgu}pO@c?9cuz`WXL5`-IcX*Za3x0p_6vSK!o zNo%`-ok=yU@CMG#E4;wU{YWJ`5<;i6F{rru40pjHy| zkSPmU{>ht)_0O2{!f{)XKm9CjIYUCWqR2f?`@8Lv$L4j>%$Y;xyjhK8-9?eSIqNBw zi!v%?_6k{Vk)JmgEg75RwiM4mNAZX?t0xY#m+maWk6Z016swwI^URx|pKZy;# zFzi!<+4^D)?5TWNKJ*dNH8 zK@7iW$+WKN(mk}^G43CU);oN2Z>{&?wfft<_5w}1lAcuMkj*5Rg}g1hq&WBY808)D zK;~1g&D!qHaWHSs+U`!TvUV4Z_r*{}*}PPcxoq#?vw4qs%vTt@>ugedhrNr`efW97 zUHrTde)bO8nV;>mj{Ar8^F91EYk&8cpa0{2UUZwEm9l8K&$T~mi#t3zYl}O4Icp17 zala`(73}3?arS}IYAo$Y9~C}!&wQz2iD*W0wz^ zT5$shVLuya#=<1`|n$<_iLk)N~-lKf9VZ~t64B?gK(suyJ z-*^W-^x%unp>;;#jkSYo<65%R=h3FMN6DJRs`q)|Jh4!78r& zO#iyU4RP&AtpC{mMn6-n^&6@OBhW9F^p#us{mRr|3v%h+bmnBb7%RnTZud3R=$53M z)?L%#sN0g6ld`HiSWKkEKHbtIXLVOXOQf}|n3iPS#ukEJ0X}Tf%_>+aF)PJ&OCp`s zZ9Qrx*Jmiu1~io>_qt6(JfS!6Qql4H>G$x7iF=w z8f&aMpnTblwc%~~QWKinruy*Qg`&5v*IXlBQ>jdV9?>KjlOqDMv+p`eL~?lZ#M za|MTcIQZ;fVdLxed6QKS4O^~P%^$5hml<~~ne@~=xAW}IbGy!Le$!R^T;tisLT;2y zxR#&Uc+Kv*?yfILF9g5peqge0?(mN5a~6)ap5Hm_yzZ?nM9-Zbt9jkKY}~PI+`DXY z;qnhU3iW5blivB`j`?p_2oBf#Prdh4!8=y}Rr@O1AUIkx5*Zao9vQ2h@UD1Sy0G$+ z>6O)&I$vpg)jaXwyFb78a{c8Kug$-*{n9vr z&#b>@cTisjo)3?NM+4{E&prLJWo-Q?w!XOa!upqXyyX2%-KEaY9r)CNS35s__|r?r zz3avu>)v#@xRMQ*H%~ZrFePy0hw2KQ&mR~$Fxq+k@cE@Sjwk;*a4)#~MA($(sQ3C|ij3-`;ttIfNv=8U{qJ$Oe{3> zAF`liC6W!5feSX;8eh$cK$5p zy-eCMu{n!_E+;+ohste- z-A-x)>~_&7J+tQR#9b^C59N@`L0CQHhA*nv$;itzS@Z6^MZsNH-i`0fx{ACRbtc*x zb&zSO7Hya?mR9W*Q?gIgSh`1(!1nIbc&#**y;k_Uv)iX2xlCoWEC`XcCf_!^e3AS$ z`VtD$)ZI-hy1Qvgwr%hJM!dsWwu%G|IVjCe`)MZ0vQ;X;VI$316ADtmQfsCS*ONvP zfO^r_Cnn`=R`w<6t>pJt-J^;Fngn^?K@(GVk4zYPf8ZpT>H85U!aP%^9%wHm`Kqkt zl3D65mZ8&1)^%CdOoy7pBqSSstINtPac-cFojt8qX;!S#U{&dA*sWVIHKlx!B{`X{ zxYnIz!4F~eCS-K6TK9^DkvO>y0%>85_&SsI~6%`GNY^r>RY5OfE$ zvouX@2RwtXhNC&nfP6yj{88KaC1aN1dhA_x*Kq5zrwV~*h9;})3hPHIhHaBoHHBq` zz;Ms7B+~=d zpnbXGS0aj{d&G1$aUv(5j3c|GY*CJpux=Gk%J&3YMB&<6nk;qv?Sx||} zqF;AONU*c2oYRU!fhA5Uo+NoYextV05UuMT}R0M;eSPOj5DpWDeXI6r15hgaz87t?&w1TJJz!xv^P9s2OAamh1`{cg7DG?bj;LQoEEpXc4#)piz+Z_+7b{a) za$hVY1#~y#m6i((_hY$Ka_;ncY4OKeL@XoDFGXx5EXnXy6=&0RWON=5ME+hoGAP(+sX8l$F<-l!I566+6JY_V1O-qIE!0c?1N zKEAscQ6CNjBSBb}AnCG*3q%9aFuaz+y%TPE#1!>Xkj5tEY1sia!!|AYo|FT+BbAXP z5f@o3*5$TXP7=w>UQQ9aELWc8+2rq~9N}80H)&#W4vK+w#IvL;C zQ=-`1qY*A!?m$t2w9NVC?!z0(kImTCC-#X0A_m(>hoZ;|!D{c5@n01Ba*D!uM2tms zYoDy<03{L$wkm+dJzerkF~DSwdYTZ?PYASTPGVmvMY~Lcw4xL})IacHB{pyw-Y@Y( zq1INcA4}04)YrHG%xD9}1cbi7@CE~KKrAk%wm>L~nRIK|Y?62-@KhxdYYPV8@##e_ zM*LxHA)1&bC4EYp*cS5Zj$)DZV`af#nF+GLF9nId)8)ixj)T%Fi_x z2@cWC4Cj&0QR#(_Q44 zd}ykMfm#mg7?>m2Du)wO^$g7AHS-vlFWBk}iKzt)Eaa*eF|e4cUc$h;c$=jR__%Ek zFtCh+>=a07!kZ zk;6@Z)W@4S++x739Bu=o7H{Wp2d}-klfw=`I&-@?+zm)geT>7$4cN)y9s};>@CgI% z<8VJ9HRAw>2LY+u4sm!GkPhJpherXaRmV7d(tuqYb^}sXB8M?R8fy}V1dytdIaCbT z!(kkdYEE!?+-Td&VGBg*1JYQ{aM))EpWsk6YBdh=KhKzOj>CRH8qFs;JOxOt z8sKmckPiPT4)cK2sv!}spg#=b^x;Z<#0Ezz4;i2j{{OacXGJLXuFrgCjb|XZlBu6;eJE-0EY(+;X@oA zHsBEsj~eh8hfe}h=X7z{4M=SkIg9~PBP9+AAPsMsL&bnS9L5cp;P5yg)!fTr5|B=4 zio-M@^+txnK0rA3<_QjQU&bay<1ha z;_x&e9m3NbuCoZXxrKqL^%g$Afb&NeOl{tm zyExnpNMqwM4j%`k>ZE4g~&Kf z)gI&UNu#!l!)`z}zZ}L4VTnUx)XE$x2JGQ54oLl+;PAN7wwJ>sAe&zf(+13N*k`~K z9O7-tRB0UIcMCd%n>h~q0jZHEIXngE8pitNa1f9V|0xdh1{~t>G$3{C(;Tj|8td1} z=NFI;VIzl|0O_P`=5UJvw=($FHrn=VVrn~wI}Es!!w$fzvjbDRINS|bJ+ffxF%BO$ zU?+!r47iuWCji}Nv3@z+4_G@Aed_>+2dzTwqHFFs*F5#tyz{SB&AV2!kkZPz^dG8F Yu3LO7!=%qRuDY7PBOElF%q+k7AOC(>r2qf` literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bc5d2f10bcecf8950f2dbb418da2dad4a1672ac GIT binary patch literal 44209 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw2.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageDraw2.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..052799c1716aa1e62913e2dd2ef2342e309c3983 GIT binary patch literal 9804 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageGrab.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageGrab.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2100fe8ef6b2bb1b3dd9f2e0f8d1b5e7850f198d GIT binary patch literal 7016 zcmc&(TWlLicJ1c-(R@=Pt%ucm*b@Da{9JoH+MU&7Y;#5{du(TIYds(+c1voSWOJ&U zdT^VV$zp*e2L?oC1Biw*u(Cg^iSwcTS$L9<3>FA7z!&P?nKAraH)UPY1T4?78Ua$ah7$>142v9}5GJ3KwMu<39-d_*I^3uJVS_+* z^2OiivD%V0Pku5ls;xv+(_kA6L*5-A2(&4JMD2?jRIW)G%_BT3e0N}sj4q=W&9&bI z5mnr%{;E+)r}hVjX=lldK_XC>MBD*wGscW5W6oG41EZ6S4+ustnUvBj8PhP9!doO$ zjsMIzt4Z5H${<2n`=WN0Yf>1^AnBnmR5j-oU22c0TjiQm(yKi)R>>M|X||}`qdG$p zyXP-VO9GzX>)#wx=u*e>%=~* zX;fBI5}oQ8(KeN9(r9OsS2>B4G>_`>aR*{3W6Rhxj$QscsP=49#w6J#2L!A|vNKj} zFhivwj-bT6Ee$cl*dG~d65wM39hYoM1UWOV*P_81?QV{&a*|PU;y92@l1riH`fp3^ z_e>+s@Ct&5v>CUV*vI-Fb@V0`Y>Xr05f7;~l1GhMgYQ%fZ2fc*Yr|Qy2pnrmhbbnIXCvH6RB>Fospvpy$s9cjWUezk} zSO0gX#hZ6I<7HZ4mupo`U|;_K?C?YTu7!8s9qo;1ZWDM{*XYlP1!7Tqn^+(Nt&_5W z38Mur@lrRKOw7tQA%a*o5eX;76k^kwCw_uY5T;oo=ZzN=g;#xKwdVS%1baWRoz;KVsTCDOOXMrk3HO!7#Sbs&E0 zIlfd7E&>{aw=cqHQ`$M3;N$G^nl8c|FMVg{au83B-?jMEuK6n z8-%%($i={Kb6jLD&?4)mr};(M$0Z`M6vKvM;UyNa44#4E7X-L^W3f=(V%fCFa01x5 zBx`2oWD~YA85ZYcT^P-R4l#B{l(ix#qDS29oG2Tnc~Ru!vWAPx7A_vD*#idhGcy7U z&aRoqgvGF|Sv(C29P?eJ8N4wak(d0jqIIJME?>!ADU7d; zuMZS^PnSAQZ&GKfuGZDImA1m=vg=TGv;wnU%3Zn_#M1|J!Tj7N)rIHn?0R_n{_S=B zhVFA}W9G5&n^>`btlT-Cw^W?&Rnv;;&n*>SchT8h@w8-vRhx79PVP?O<`Y|Awfpd| z+y1g`t9!WAJzR12ueZO@YI^J?>R|R_e!S54t$}d+R=ZZZD$W)#2>xzkrlsO)$%j{b zg_A4og^yOc)<#QCFxdUVWp>-Mqu+Q5=zE}R#gNzJM_+SGi*NPj%FP0^cI`d~jzORM zH_kpj^_vTi=fBc?@zY}G`{kC2yhhP%W%$;)n%D)j}Ugxawr!n{0TUZrIpt3EKr`^!#nvBQ-$|HrpO1m*cR!mW32Q~n}FSDl_! zYK1EHohv!dRh_NMkItb@=ZR-;4vzY&7CVPFyc>(fjvsDPBY*sw-n@Tv?Z$%-UtPr~ z$|`;u+@@SRhd{%Z0)|C@|NRm3rD5V9hR0gpZ`1zXtHGroml0@feE57)Q1vJvGiKE2N=r0_!@G4kn6}$AV)>teq9Q3iN<`_ ziKX3n-SB_!%N$U3Lt3USV@tH{io(76x9{rT0sY~bAY&8pg{geeAJ&;&gz0R^m?ax? zaGpT=S%T^M6`8Roj_xB%zaraRm+etxZA>p@aAWFJl0)qaIZZQ{9#`9&6ta-Mzdod{ zU&bjpqZga4Dp%j(*P!*XTGyl*7jqcSArqWKZpkgV<_UqkXClGlIzr8IAk**vOp|d) zF4PBk_khc@4<)|8`hc!U|2d5S7%?=!{@*={#KL&Y$xAc8 z``ZAXuRe9!$R-#X#z=b=n6A!VZ_$$%Dp0Q9BixG3v6{6Hq_ z7qJhZ!&Rk&0o}lwT8;~BjE&$YHQC&761s-l%!=R;s13&Q>2Y-u8dgOajOGLyu^**4 z$P|>dQgl~9G6u+v;RXUUpP(nWL~8K{wz8hTg&^rlro@0jz{%?*FV1m^Sv+QhPjZ0q zDW#TfC@A0;i%A}GG)@dp<2YGLvNS&f{SzW!d{quVi_!2sTJSwfZKnDg8zAO>G(GkAP zkq;N}c1j?8i6ML~qjo4Dv4Pi0*(iu1oZ%=L9>Uiv!f6A-Pf3V|LiW7ku6kN$5JZ%U zh_W@6z?n!0XL*nhvk{(w)r9U1TFz{B_hyL%LFwXFB?a3QW(5~@WF)M z!!uE8;NgviCX}jiZdzG5TqPT3S@7jN!gnIVE|NX4GQoH<#^OARWor4P7Nruh1+kEa zClrN1TLxSNiixm2WY^dn7h|s065N^y?g1+v@Sx*(>_I%XDZgo${JV5w{a5Nx%z#)7i$z)R2VudIH1QKEhcpeEJ zXu?OsYajXn7O}mu3}^xBIQS?0qmtiMjh0_Xe=6k{pBTHUzOF4_f63RsZYcYPa#U86 zy<9a}mQ6WR-hGeSrY=0)#n{V4b@Qq$$3+xyOo4Z1dSE!Z>)wAO;c`aGfj+^it z%y(uDPkmk4OBKqU7YjG@e2F@gySSqz{PZ)Ed)bk56bzfDu5FtutEpOT%ja_E^5@Ie zjxB3n$=bJ0KCuS=r@R1EGUv?sflX7plATn|)N)6zqu?u>>8kg@>U%5iZFx_Xyr;_E zGdXiso4rx7+Vh7${r*$xz_zn>%h^+M_N<*=*Oi^e*TW^}iR?(l;mMEY77Hgo%~bpy zg%1kX3Z{pS`;K)>*?)S=|5nNW*5kgi|D6^6_AAYXvVUmHf41a5yTO$GZ|C(DkH2`} zNa5_mx9`8bh910A^c*cxN2}JBJo6XtZd!Y)o|e@MD;Ek(+0&aHuQ=R!_EYI!oX56( zhqipDO1@JYXUe|wMd$g7%UjU@S;wAD4$m|2*ju@`iYDbdHA1n<7WzS%4ylV3(DR2L#t!GWz$dvlWWzW^z z__q5N&Lj`5Mau3YMe4{i$igRclZ7)Ix=reAmaJGQWx$h9tQ{4%XLVp@AUpO#W9zo( zshtkOORt@N;yL_vd)H1E)a}qjYg?gvt2c`^h3WzH#>(!2A~o>L;lf#Nq5I*${eiNhH><1K+{;tBse-O- z>&$8@5DUhf@t#=;gclIkL_jxr@#18_f-tmA(_#uX`A@inc#M9f_>h+9Ngj?v{2B@m zMLZuv80w-WTwtJ^w!p5h_rlLr_*6(+l|yAvDdF0|Sz7wwt~%%+;{@?1Agay~pkzxZ zG?T)wd!Z15Y?DA?TquXDawI8-t8)G-N3U|S;mlNdjZwDj=LEw4T~*uCrr|ixq+;w3 zPzLHSz!u_A>}W}n{P!M$?EM2_ev1Fvo)WI7gykvW_*cTSVLzp5hNKrU>D$l_kecy zKmt0*u%e0pSq{O-Ho%yQjwO`^hOUT;6U&aB*jAJ{%A*P-=osFD6Q=Ac$5r_O8BEzl zSEcgx?Css&@s46Buw2fP=$@UKo$2YB>F(+2`=^o;FNf#rKYVEDEA1Tj6M8Wpw~^pi z{|AX#PU0j!!bSOBo~N`eV(Ya5+ava<&?~S!A>xQSd!12NuM6)E$r*7+J-wc&x7W+w zT@hc@-|Oc&8+Sh^xnJNU&pDgXOK*u(EqPxMdP{+QzyYa7@&lIvmjIUomjYJ+2Y@T3 zTB!`UN-mWHa+zE%SICuel~jJ()mt6r26+!>{U_B)6)!k?YYLRqOO+_8El{#fszOQK zm@U}wb0Ray>%LGd7S}>rI380E;@!PJF3FFLjmSZpZofA+hKx`o66%l0Kj-NSo9^g| zhK6L_-xmfB$A+RI?Fc^fNb-mx4}>&%z~F!Z?FQmkcjNO}PUd=fi36kgUc0nKvSGl2 zv{kYLJ7{>)HtQgbw6tAvfNZA}l$@yNl3FAeup8J7>;d)wd!-$W;XYtuxF47pUII)E zF9jxs2Y`v;Wx&Mna^P~{3g8OhO5jT1D&Q*MYT#<%8uU{GT#NTw;5y(s;CkSC;B~<3 zfE$1tfE$4uf!71C2i^d@0eBYv( zsT~7YKpi7v+L3syPaRNX8R$qzkvm4^*l0&2+@CJo)!unqhZ@%8wvo`lQ4B!sc(muC z4z{Qs#!_k@!J6yq3&+A*U*CASIqY^bYXi~Z0hr{LDypW0&%0Lf!sQImfebc45k${& z8m(ORBzY~v2y>?@&nEd{!K{(R!_I8lOiBDGr!*9)PekQClI>i&??Yho4fkS4FaE;y z4{?%ExTFxhU*=x5P1rP_NmepL&+~i^SNvuTt<+2n+At;t!j?O-J z^10N&Vr|PpS<6y+)ojhln%Rbv4Jq%1@|JX!nUc$OE%UqHy7TOvZ{2nFuKBiwn%y(@ zCsWR?acR{5BZ)bE-+(gwLmVT>5sH}lbpieN)D<} zxCNukoXrny$$6cYSee<e|aVWvLX9>Tm|Z-=F=g<6Yi`QOS;V&OS+!N*<-@> zoa-2Wj5}_Bf;+~qO)Ek7L7nd#ujvn^t-+WiYB2A`!MGxB)A?;ogDGScDI{p2|5%zp zuuKn_Iwq}jn66Stt|;pWhyc24NX7|5Qxvj*^wN8g4EHCrw5IdWX~Ix?LLwF)(H*EB zjw-Z}q29tVT^LX(yFZLlragl`Lj&6IPD%~hGI|^9P#40{K4`^wLeqI!*+hkubsM8Z zB|`^_(tHes=?IOCM8?KT&7rij_g$!}1~JS@Zl#nft2&XKPR{LL42V<0lCN~?uAf%a z&IV5g=ejR8wxzn?>^ajjue~*PcI+F?ixnT6+P`8GN?Mnz8&5wq-#`D@`SSC(zq9A< zJ?D2U?AW(h{jnL_6*pH>|3m-!3;y+U{i)4w2G0av-+>m!&yJr z-nYG9^M6D7&hR&fzZJRUe{eZao95@QuH4O4ZTbagD`{P-YoAxUj=b@;v;1bfR#envM2?CR$G?k$f&tW zwjhpqpl^J7d~QpsYB8{N!M*ib(rD0(G&-{pX=x^%E!gEqJikkpa|GY2Bm-HOQ@(4v zxmgaxD9al^%Q;HbKSqFQ;*N(_a z`edIuU4$elk0O>6M{ld76?0}Jl~@e4Ex6lmo=jRW=_QX@yB{4Gyy`(Jhcql_#h}gV z6)>`tLc~?i3m=uZobxB+p_=F~LLU}03iDXUauPJChX~yCWae_|cd0G5q6%`!AR~uM zEbBOZ_Q*$~<64G96OkgMfFUT%V+hN6mS|W@hJ5P!3^B;aVF=55?p82F3Xc|Hh_A0t zQxY;NfGJfOd&H9a*|lcO)5RI%$9~F^Q*9w9oBhJAU=X|_MHoaYCY~>SSk8-U&6t7W zj3Gf|kdeD$h_aV%1w%&S$BHuqg?U?u<$Qjv84|ueLku!<7{anrh;9vR^F#$R#MY3Cm|UESn4CuiWqj>cP!TD%fWV6gX$~tdDC6t5go^9%B9hMw%J}B3 zpknAcyco*o1!a8umQZmWUJT{)f-=67Lq*!zan;AJiQ5?r3d}cnHRC!ElOnrM)18W} zC6tU}mgV9=|O>qfV$@KH8V!+%1c6X0sCX+xM_10RfI8IyZ++>0;FjMwNJy6XWk zl-33Eq@-Vr0zr9zDzVnH)wj}pb}SUdsB}m$Se6NzZA4J?J(CDU(j}1hQhWg7mM%<{ zZ3LLhgj_|+J_7du5T(=z0gb>YfpG#8 z1lZBz_bK%U1el@Aj7(VE>f!2L+rw<_?C z>Q!f%W6w$}x4jkK!xi5S$NJ0uz={KS#mSX!SaDIx&6RFh@leXk1?pL?6+h>#SS>-` z>QlVU(YEU59otr&yrYW1HhOKR)Xe~V+micj8@)1+ZLgE^I;o>xVzA%_TL(g%T zWh@q26**xD+_2TMK`A}MR6p;Lc=L+D#LTJ2?w-%u4VDM+4fCd7<6bIZ5h4_z1EX0} zNIkxXzg1e>liaeea;AIs{*(95K63Jr)c(b)?TfzPf{-?odDJnVTR0GMK`QeE@-6*9 zmU!cuoYdw&P|ZIjK?C_>uV4RwSNl*Ta0>Ac6hu~7M!n>3QA>`6Mzxk}oT z!d~RPyi-7|XA*RpB@_#SXbqaZyyp;y8(dQ6?7=;-1JpYQY)?Ssn0LHEA@m-I_0omq zCz#Qqig3w`imWCgniwCUzS4SdY?XVa{X&hI}N`@*TG^c)4R)*xm;xz*ZDWRw+A4k-vs$yVW;=P$V=scu> z3j=a^R7R|$D23VJL&{itx+C^=e1rwAc8M&q3cQPpxFH}!Tr_*!rdq!jyUjpV$!N>G zEjIBJ@q{=);gtyJl5uTL%z#CRF(L{~k;S9(*s(Z*D?`eV5&M`!QcKIxWB(_5jPV#I zYnS*K=+5#ay$~>EN5ZOz{|OaZ2NRr){_G!?2eeiZ_w7V9Ys?&o7>cNIv0rAjW12i9 zE3M!q)20+AIueIfAdXT{S}Tn%B#wlS%Mnpaj6~$t+@=uSE5}%HX*|Z5nIwPyKa12;X2oF6c)P|^>NQXq9QyXj+jtqVnjl4vFuiK6yx(+j@>ikiiA60gtF1zeYGt0RB@>wWX z-ba=HqH3oACbs58^H7amzEtD5zm^nS@dEllxKoy&;L3!Scht>IL|4}4peYc|Y1^UBew?wRtJ z?q6|mr>1%f9+wa6HR-$-81l>Z(d2=G`*ieU03^ zjlTO@?C%D7z#M5#rV*3o&qLU}=z7upqGxSn`b#b?Bhe9+dL7ApF0K76^=&s&e;lMk zs^dH~VMpXEB4gF^tX$7Zbx354jULGGItej=h_`Vf-bS#<^Gw9q^Sr=KyM`&AGVif! zqarmd+6XnsSjc+{Xd^qc5jhmu18r1eriU{rGY4^8*^x9^qsvSlPP>wJQyXcdy4jQD zB$wniwem}D$v@?qa!+{%?Ff(ezvQuT)1K)}#1XW1iTUMlqnXNLwC0t38W|4k3G-oo z+GVz$)_P*P(1MuO+hk@G(RwAJzlNpG1k3>vKiJonfcEV6P0Kw9U{!pSg_c87qbjOAkWj+fn5cx+qbg}z2@(L*Bntb?$0X6y0X%bNuXJWu-!EX|X0!Vzo2mb6U^qddNKC-Lhh3fD!t6oH?% zbl|7mqWUt&2U0|1%mYCJo$)~VXQYCH?iq;pkucF<0a3)J?nVYV3sr^WH4GgXM)-Mw zgH_T6Dq;bV%HN|{FM-4w2}fiJji8pG!aB?tJd=}?hR^O_QFXlDGCA#gBk=*)jr-c^ zgKlVTmHdgnf^Va`e)iK}`1I6)uzm4y)uG?N5YpAc?68 zu>&67i$Dr-J?(NO*KDwY8HdVuDEqqrx)2Ggnl4~nsk-Y(NTpy@-JNNR*rj}rz`F!; zO-K5924j>$ejL`X#hUage@nUV5%@a--zPx&O<}GmG9wwk74m8*#7>ng*R)l6&pr2~ z4ND7)m48Ep8saR0tFSD07PKr&EtchSN%_pS+18V-ue2|gG`-P1U-4G$+1hjUuRn6B zWY-iAztc?T^q$kMH{A10Kd5V6s)C6*b7-z)pjzb6d}{qAp?29@aiVRyZO)r|>imIk?>fJC zq4}QgHZOYbzhSHPy=GtcPVT*(zV3bY_wMEabFA8okK#`7)9PNm#y)9rj$@%kmv0Z!5y~>n$Vi_cGm5;xiT7spU>}`` zi<~nHC>~M7sg?~hb2wxPI_Ju;T;Ls`W3Kg}&5ncx&b1TR z>gp0Zced|p-^t3xOS1=A;dxlho64hKumyM zEzK=61S;)fqeDssjRuWwnAH6bDrchiIyEm-rJ^XTD=UZ?&1>oiRU6f)Vorl*Q5cmH2rIJSaU$$wXhoX faqBm(IM(qyS#{vczIyhau8tg5{fY-E#+3gB_=7(25q@uXx#aR!zqTYt7A^Tlv@O!4WVMC`wUUxZN+`iFlhkHgEGWK}#Dsr+ zyEH(80#rB!oKscgAOVd5T?)AH#l7@g^x6wu7byGS00n{`d}AW_;!|gKmy*>6=z=>l z-^{$(H}igme+h;B1fDIHrD}bMPAeMx%{>Pz`vd=8SJB4wP?Jej=#o?DmU^u%gDR&Z03HA9;E^9 z6N6+aBU$NV$RsN>3FaWrfrTj`d29)F>apZKmVCApz!_&fb$=`~yla?wUZ`3X z-WdJ~&sD1ik8W0Yv;?-OY4JjN%Zv*dB%z?L5wUREKLy40XgnVOx$tb{%FGnLjhtzq zha*|_sv*2c!84CZb{~`>EqXKp!aiw|PrH`4cm`?+W#a+RLBSN$C~lfKGWupCv0W({ ziSiB3>PF(-O1@Sy%9fePL!}edy0u*?>yVRS0Nc)SBk{l}KS&e{8?JFWo=hdof@Mrq zbNSD5TZWmqvzkt*TxW=s`6T`$9W>$>pkI#j4uL^-JIzo_Mkt_42GDtS;xbp5TJqwBmM zg8ZKF0bsljiPj}UAea|{{EGZTnfRwa^l-Hu7*%dbVmGnEhBQ;4=dO&!rNmvYc&~nc|flbD)K6Nvq;MF9LU!aG zWyiClTHbD+5XIA!n@UrC>Wl)GLjohpy1ziQ-34lT>%n15Epi4H|1av2+@GF42!)$pR z&GOylMKHqZyGB{iyMitYy2xz@1sv|3@=$mTy{{s3U6;fAt$J2~6%Ak8=|-B1ywUAXALMHj9+a6N+~r&Bm&I<@Gqw8Jv! z0!o*sGqBfXvu+A)qiz`$&J51+z}lB#%xAX=p&DgY$d!c$yAZlUL&E#ka7AoJ9CH*t z6!C@^p%Sz_=yA56Y5Kq#bszh-72Ykw!WjGxnDD5Wf2MftzgEfM(Ei$Q)(-Febztg? z%(Lm;_dCi^NbRUZ3${X+J6;4n7ib9l03PM{rVrG^*~7^v+L=}s?#KB7fhJ-0gj2nJj*h~SJ1&LS8hT2HI@2c2OA@3;X*5uA6y7=m$k z%mjjqMC)z!&2}y!xa@)}2qs++LvWR7p;q`>=Nf|RByznSp875UVE4UFiui($YQNlR z2O_QhsjGXLoXs9 zw0s{x?Rw9&onPNs6o3wl?EUZ{wKv)xJh!)Uu(&tX?iqA_9EZNM-;VVRs=I5DLeJ>I zN6#bUyDKjP!v_}+)hF_k%(KZCf!i(Rw%rfm7~vlbyHWE&l(0d@0@$cGYtX}?QFCaI zgs%V*+GeeswwpAa3@>S-ZlIjMmTQZ!Z+vq37F>}g8_CE zF=v5vWJ>A3&l5WF4e@_X#=a(_{~{M&tA0AXmwioubw-F3_)eOob4M~r-=bv4{SSN# Bt|R~e literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageMorph.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageMorph.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c084ae8dcc2a9f3ddf5cefa4d82c5ffacce4d354 GIT binary patch literal 11334 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 N11#(Lh(Sn+{XesqC87WT literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageOps.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageOps.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e02d4d4d91b83cbf2b533e5b9d089ddb6d48ce98 GIT binary patch literal 29364 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 C1{r<; literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePalette.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePalette.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bedb3edda794b0bebfe21cbba76be89b1f5beefe GIT binary patch literal 12174 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePath.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImagePath.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a182ef84766989f174e593a7d1a14afcc6ca3c28 GIT binary patch literal 357 zcmYLDyH3ME5Zv>FL?NM}qe7x`L5@d@s3?dOq10|H$6jIw`_8&MM{=6TRX%}l$Pe%n zd;pRwBt(%8DWaj`E)Zplo!K4j&b;<|9nkgiHk?QT@L`5sS$~9V?lpOa7-Et^PJBWj zwqiT8a@)5FpgnExPWCw6{@u@p`3IHbxobl`(j112aTThRGr88@X6Fv_aDoqBtLX&6 zW2s7kK_F}`HXvLBPQ(Q^P7$i4aYnkYV59f&Go}g8k+KUBS4i)8ROZN(q>+A4i%KP& z1u_zd8j?^TogtgiEFJ%g*Zs>YDpQ5$MHoHl6q1exL%I!QeELPzv~O}Aml@uQBW-Ci g%M;zcY(mKQDUh>IIDT(+m-BkQT-1x&5nV0+0;$VeJpcdz literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageQt.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageQt.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..08ac1996047a1928afc9bd66c7b20ae092d21512 GIT binary patch literal 8457 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 QWPjr{_SWlvQ^!F1e{juY-2eap literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageSequence.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageSequence.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c2f8f3cef7436636a60527e8865a4065ddd7941 GIT binary patch literal 3388 zcmb7GT}&L;6~1?Vc4vQJ@j`(nI7|a>vNB;w)5Hqu-^MtOC7U#bmta}TuycXI^RvD) zYgjZJA=k>^Me7F0n~KUk{rkT+~xwV^LP_s-6;Q1Z}O z?U^(8o^$TG=Y03v^F>Qb62bH5uP)E5D+v9AeMFBGGI;-2z^ox1>DWXTp1_##f+<+y zgb2K-OQvMW6Ea2ux`=f7Hqv8{giw1TmOy$Ufuf(D)Ro)vM7$c$rM_VzIUJ-k+jcz7 zGaTE6PvyL3n%a~}zQN(Ve96*gNGUWJ(zS$|a9b&2y;s1}u_P;TfMbT(x9suB#eW*(4URJy+Fi)u@ZA z&eR+!d8#+7d1?tJrifZ`iLQE%YC2AtTXAj@%9WVQs!MKEh+QIsNj~|pQ{jrB1y+bU zIeGQkS2TrJ4cOz?1HEEui_TjZ9esb)n^4wp6ff*1^|1=u{_N4WDrE?cU{ zo+m;EDk6mUeVzx8WsE;Q)^UUZw?!9ff(LT-IpI-V?iTj3kBSY8Uc4cL=IZ#1M%bHS z?NQwh=rts&C?}5wl1s?-#csn=t%~cZv)WCT0difnh&Su#L9%EWc9HLuvL$nJ5TDgt z>r`S^#QHRXoBY7YK$G#AgVg5+;?h;~ET}Igu@5PSaLU4@AqIahW%Oo`dQ9tYeY9 zJw){?$&Wat3I|ZW1fb5BtKfiLbW4;Fc+F~*XUB`zWJj(tU}%>Yo+S| z9ykBXOPBK;`ePA{%GE$A77g3*ip9lK5rzk&p?>hiJqKh7J;`*g()D+CGOzAt2bRx2 z$*LRe+u1W)=`*|8j%Dd?{7HB3hV+N{@8h5Ke12oQ``u;fUdukHq9gfb5$5?_1!fIS zv5)4M(6MK(k=w%wA4gfn-=Q^z`jFSiVLzhnH8{aFu?YoYWWyJ32|B6?p9u4K9xaF; zqj{VYMh`N?)>UV^anf=U&kbc|El@6e_Dq3_Zl7521MSy|`???mWW>6s+U;;6rbLn9GjX657qQFQ@4DfIqSj3j|;2 zOJM%be4lt?qx>-pEZ`H*G+u0Bs5`6zCu5AGh3%g|94(mFl|(e=H|mOyIa=^1xCt%d zC}rh}b^*!BhcKaSY_uCl&@$#ZzpZrag?PjPxw zzlNHw9^^GHl*Sb#`e+8%&&`v{mlB~ED%4O3a(9)QOO1C1 z&`I!%5t<+Suzzu&mr+e<6j+Jnt$-Ug0prlU)aBtWQ$ut?E2J^=k%CKDE8&rbCU@h6 z{$fD=&V}mI%-3OPfne2UuVF`FV*~DkhpeaKUeBc{nQ8b~FlT;&%^E*4(=5_1BMkL7}<72VE3yi}nSTB<-Xtgy{+S-oPh zkFJ&^w6^sr%4)bLznsovezw&n3<;b}6xbpG$1-OI_{Y|mQ$ zetsKnk@!<3^(W;oFYOGCY-cV!9va#BU{zUbx!>|>W@~8VF$^gemc^$^b|rHsvmXDO zqVAb-0f7~19v@pXJj>d?}K&sajI`i`tj%OK)!t*M{V!pZ=c6dy5D6O z{cG2Ig0eZ7c`q)}SKzz8{l#8hQ^Lxk`aGsrn})8@H$iyuY}CeIJu*30~nu6{;`VU}H! z?$3eji5TO5zKU?)*XZT1QTxAQXYjx?1Y~afk#7$@)m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageShow.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageShow.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..160e5c754b90f17c9945b008bc86e459b3462a2f GIT binary patch literal 13678 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 P;p5#rrF*64IN$#Op1*k( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageStat.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageStat.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3515cd2e0affa7d6eca10e7c1bedd889e1c47ae1 GIT binary patch literal 7380 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 Y{m1bWifa1;;WGOygWRP*a}Y)U1$t(XSpWb4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTk.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTk.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4afee67b47fbb659d1bdcefc4741dfa8193262af GIT binary patch literal 10852 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTransform.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageTransform.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3fa2f385b21ed4186981a4e5147b3768e16ee5ee GIT binary patch literal 5360 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 JF?33W{{iTwV@Lo1 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageWin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImageWin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4c7a3a76fcba8c9c03c0bb68555dc9d250cd909e GIT binary patch literal 11870 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/ImtImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/ImtImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2b056fea21619414180b28be61892ffe3afeb021 GIT binary patch literal 2569 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 TS@W)S7M`p8p=UfiDc=1LXGcnT literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/Jpeg2KImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/Jpeg2KImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90ad4578b56ee36cca013bfd7c275b46561370f6 GIT binary patch literal 18169 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 T)hb#AoTyBDCqAd1B-8(Yvhy^s literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/JpegImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/JpegImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6a75f240e2df1b330215f869d9867822c0f39e89 GIT binary patch literal 33085 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 ARsaA1 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/JpegPresets.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/JpegPresets.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..99bd7a21188fe814647afef984c850ba26585741 GIT binary patch literal 8136 zcmd5>OLH5?5e7h7q?V#AiGC&VV?-qmp-{UdC?zRWVk?$pmt1m+spya>2XMJN0M^rYbH+bh+8n{Y`gI&o{Fx z?%&tfjT-&@^`8%VzuT$R{>6jo&xKs6fAtSi{#bKsk7{n+ZTR(|@u*R+xl6s8yZq-m z$yZ1=+;d+vU|WH0wXiYbJZ#3CZ4I^ybGCKZE*3V<@hWVW=4_W?yHeOV#|CV#&DruC zuNSsAzBvDAY4~RIt?ccUTFv-$|K2C+NoMLxcI%d}()|4bscC3|s zWP84S=xcR2RIcvYnV+_egM(vz*dh4A!M4f=fp)ztka6GZ^<{LV<6&ps6xdI_05d3D z5o$J!;0vs2d=^nv(+Zt@aklHy>LyKS4~A{mPVM%=1a+WX&q0%9t`{; zx|YMXRWi_y*B!RohM}h2{`qF^?SyuqH)keB;bb;#OPG4Uw^J_)Rmz>31c07=eSjo8 zOzdFbbLS^}n@5;&l%w2x$}=XJyuhSA)mxihVD~gCH9sHpHn(LFyj$GO&8A`eTJjk; z$6 z1d|r^Y0uc_XY(G@*ot-6Y^#2n4wANI>Cim(9(w~KmTg9H&*G7F2O&E%&7n2zM@ix_ zNoUN8&PJwl7Vm7UU1f)^YSFUnR5?*hl@21Z5NmF>>A!9I)oQmGWw5qGH2H0mDW+IY z(-EU1G8>&bV&{kG*h~BDHrm}RblL~zrvu%)&wH`&XFV@8X?kb6#RrN(+#rg7Kg=UI zQNT3gBg)L31`h1_v5t8!aC*HkNww|rUQkWmq|C9;142C%SlLk_9-fV8b-8&D})?F`gVx4O0V&a8brLi3*yunRwW~_tg zNE_F)Fw_pM$&QED=LpaxN+1|`q_#M&Py07i13ON6b!?fogc{X6xxz|j%r3A)Y>U08 z*G}4~rfuVNit*JrHVoejX=18r;(<-aE9J=yH(W2)PD*!>ouAYv`E^74*30-r&fWDnQ78BOY&rRb z#mABQMY~j7tdzz^1ym}rn}|Ot=V70o4U-9p!A}S;Om*zgsqSgM{V2-=@9=Xv0<=In z&PA{34l->5dPh1x&HB)4?d-O8_F6yPZQZ(cbI;;!p@V;Xd`uUZ?m2Yl#&%*77c4)I zIsJWO54<*vF+csA_0gIghEa+uCK)%_c6L4 zlg0aNdzH0YEPla5e#waGQCy2Jvh6+A7!q^%_%aJXAXW?SLI`l@3tUwciO26gm5Brb zZH;lIT1t=?8Bzyd=ZL)Qv0@EP`7vvyIDov(xVNUb7;{TF-jSG_9Aj^O#4|qPVF`!6 zK_DL5Q-WZK91y(2W{fV(p1tPnoOswZ?j43XzrM#qF!Ej2&{B0R{w7__WPHfa4YALAe$rDno$7Vj#GdN(keKpkTXV&=!jg7AP2naHGaMY*Vbk zi_QQnI8+0s!2t++$8YdlghDlP5D^Ms=5P!gAgeqCU$GM8kVFD$G7b<3hyn-*Rt13#i55nYX;rm|_y4ZZ zJqY^Ei}4coQpg0l%tP{Nx6X)@P}m31suZsZg8f2{Qlb(ifkS{&lornS(eb5F0$iD+53A$GFGwNPrhl2nal&;JwH*QM zSqK3RwNxdNl+f^kQkAHL`^kK{C9e!oy$ly=)ImJ)u@bzO;lU0Y1mZvdf(JLsM57=| zu@U8T2xcJB!YC3HWmF{+2sGeIwyNP7JCna1R|S~2Q3qkb!wmvMWZB@&!aE0s@Z$QH zXMkb|S}S1%Cr`o>M8NVEh-~5z4aut#2?QDfEKDR|tVo6nwKH~_I*4Z-Rss!2w2FiB z*aRU&lxmP?=Ryc(Akpa%;9hLf8ne z2-H%QNFdM`*8GgCI%~yu z!O(3h>)|dbNQKMGB_H4CgT3;@&sN3}~FR^^KaoJSQm#(~X_1XIsuJ_obPIp;5rGOR( ie76XA6}d=quCoL@S>gXO>v^*5H`W?|Sc&gZSN;ommhY$l literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/McIdasImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/McIdasImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9afe27a01e2954d6af0aa726510f637e662e8d3 GIT binary patch literal 2241 zcmZ`)O-vhC5PomHyEeuKY_Kb$P`N;qI#F;#{;HIwA|W7G1k#YSlB>$vc%O-hy>{NN z6KsKmsvJy|3e!X5v^~%pD3Q`rm1B;Tda*?-tW^$3IaIzOK`%XZX8jX_=t%o!-hA)P z%$u3__7At)Nq~Oanw2lo%0H zQbYp1LzNzi5m_J;M3o;B)y||j%R|#>ojx4((WOqL# zWQGK7Q#A)5It~pIH_(@y;Vhn**U?zu-?`A8bc%(vkGPs+p|Nx`P!B6*yv2Ys}2O<97-U5Fr%0$E2AHS zGtB5*)A>HWBz#W3rH5m4Sd#;!(r1mTEmEV=lY}g^w7kQB&aKm1txE4+AcVVBVNo#J zTDZ`(1rb0D(Uv{cHcJh6bDh!Iln(1nRRlkcbT;kfVZ%IHZ24NWE!b2Ei=@ifQCw2( z^K?;Ml(ge5#L+<77Dd$w$dMM(z7KH$;#S@NdlC`+wr&|%=s>T)JCVl)K-)pE2((=d z)Po%3UX(#=&GzlJBF{s9KjuxpfM+$l z=w|1ErKS{3rBwz@PvjYwF$5`k6K|i08dEet4mx1Ql5vyjrY)tY zSe{s!T%Ig-Z@T&l^mV7dc<*uk=b1InPhYO-KYmm7o-AB>?d>bYHog62SO50FU_t!T z5vUFxTRZc-=Xv}^Y9sY>{MG2@(D-I>qB1a1c1+-kqosR0GI6;JH&nKL8HHB+2QYYg62 zM>MJ_DHe^I&L~zqn?%_ajo!;D$p#|Vd(-sRd8?t|@5ax9U5@=~d9Vt~v1zU00}yol zpFJd1w{K~@+IzAr`uD^E$yr~HD}y4(rZ=VAIfLo^9LnPDbUGPyVodQY#0xQTe2n=Z zqVRa3j6G>}zU9kwb2bZ|&A8P!{34?724*@&>LV#^<__=9@{COZ*IXwQYM literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/MicImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/MicImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4e2a9ce009fba5e547b0ae23a5b17cbcb2e5a47 GIT binary patch literal 3806 zcmc&%TWnLw8J;;8`}mfN6V}cJaDb3F3m8c0Zg;C?Ljr78+$#2=HLXs~Imd~OZ=G{O zE|?WUNKICt1ho}Gsze@xcSHO7eTkQ>Y#s4HwUsKKnkB4?wky&9ALrOfl zxSX++@Ud^zy^hs*tgbu~sy!%~7NXu4Scy{Gm&oPvR>DfT0 zR5HoU3z>hg6iL8;c%$Nq-jTNS?@qA7- zHD(x4j3<~8yK3aF#xkkP8_vN)M~=qKlw}+&B(y7VC^L3p^i1q*O51dvqG>3_*5-RD7)qdlrt&zW3YEgPr$xmVEnHr2XsQA{u5++PG1=egRs333wPJ zPIUqtp>a_c;*u`LW#ET|{LsCeCvM#bERo`h?wKV?s=IIb;~w45Z3S%aESaKlAK(?R z{mzb0Az0$s(czgeG_kyyPg)UvmdJ2ETgaORJGJGWT(BX2Pe2&hmxoxjTWoYgMUs}B zL)FVi8)J$@-8d$;3QVP5p}Ru``eMe(k1dzS>`VJuPI&N8r*1}ZZHy8F6d`D(oc=M*=ouE2PtAWv4C zV>O=183$u{yujYjvw=c&;mQd5)cUFo@q`}!O>1^JcD>X^XI0QE*-Nb2Zub$^cAe_9 z@!5*>CSZD$IoiF(e>^nl(YiChFY6hY~|A4%n|CNe2Ka{kOo z-olUp4CVXcyEkv%%t(iZhDR9�GLs&1Brs=^YIX&6_c5|){yO<{tpIc7_Rgf(vBu_BNdVsFc8zF_2Lf}5u} z#M`3aHva+H4YH<4o`GkfUFA@JDb&B*{=3k_(9_V7*^%2Ht+kVmoez}zN;%wL3iq#u z2i9dNn_de(=Hl50-~YT?c2SRVDnqJ$&!<-P7RnR22WbXU?54!4uQeIkzkAsPdoXvxnQ!hJ?k10gp5gbUC*7Xmcf}{YO~ZrYlR+75ZF5XV zIC*3VLUh0vAYF?r;Mqt;>hRd4(-3{2*XB8Dy-?@Z1@P8*?#w_)x~8UjTd}5Q&{8c9 zS+zKjZmIWmtaMH1P77+)*&iiEx>?~|b$CXexaveuon+PHj^vCjid=Q#r(#`o@XE~u zKpp0UHXh;Zjrwe#iu_cyaYMVpQ1-TWG^ZOIB2Z4AKgH$1@bR&|NKn&aMk34bp=Wqb zJ5YO-QCVz1I`F}Y%50Bg+X^Z>2LfVyv27n@CJGqoU*$jRf$B`_7WU)bMzL!VGI;x% z+se(mOU=8Nx1{uzmA6aE+sh-X%8}2VhY~dcfn#mfDEpa z+wY+*v3IbCD}Om{Xq!9v@gx`(RMqyXYBsM=WYG4j>Mte|nGKICnP>36+QDk6>IQsa zrwaHN!R`UJ0FwX?Ei+-Jt{U*>s)?j!Fg24;=&9UTH6USdVTUn8CNadt4s1|O18o76 zw2B`p_`@pcFk~~#c(_93U*95?K=8(?O2^=e^j4++;EL3{F71+ctba%Ya@YDUDtCV4 z66Nqey`tRpHGzzS#%F==mTXD`H1PSb<;&BSVRDpg>2f}wiTV+PPHLV zpE^9)@_z&D0J?Brc7PdU@SOsu#n8--V_UG+W=vTSuK}iqq`C|KouT}&it`8TW9W{@ zHGc}(nn)@AW*?z@zamY4C;Qg@l=i)9IZnG4j+fgGm)Z`$B2ZcTSRl0hhFm6XCDOKV orrh3FYVTX_{(N$k9Dh#2=n0odc(J?OaiG+3U^)3EImTE2Hwf<=t^fc4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/MpegImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/MpegImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ab3f7c6f647d14f32e3d189e68b1866d7f4f15d GIT binary patch literal 3690 zcmb6cU1(d^`JDTse_66EJF%O%s^iVk=2%VIrlpL6vpA_s76Kb=e#=nCU{CwLbERwfC+&7X z-}(8z@7(YIeEM@Z93U|Mxbj$G)a^5QbA71 z1tq13y^>c8o|H$d)x5XhOZg~~$a$i9ZW7IVUvh3s`L&4VyQ!oC0_O)@fGG>`?Y-l^ z+~x>Mgvkqs_u>g*!G+<2PFbMCixL3uk%OoX;?;s$C?|DfZF7(O&)nf1&T>y8x{Ztp zY6mlhQM59aUNp>Yuq8=IwmMVDXoQfKJk10T{ZxR4Ns@WnN+#E!+L=wh3wL zML4Y!Mp9HGDM|Bc6bveBK23sI(fpbWv#JF&1!fQIRhYeHPa7>6U5x0nRPW&od6XDkjU% z^AOOONEna*=SuQQvA~kX^IR*l>?P_OkSLMGkKxJa>Ae&^GiA1m@JiTUplQDx|L2>`drN? zJ7*X@<{<#fq}dl+QEqvgu>qL;&7t8H<-?v9ph(u$95$E}!cK3%qE0LqS0xLsO#sy% z3+){0>~YrU{We!;zAS9004^bOFHFK#wgO(#5|l^a#6*@jj{>w6gI%{OJv-{){#hg% z0f>wU^@+8K^{aQ1n~~8C-ze_`>@KHcf(d1g!0mMcD!{?sQKgHZ82>3? zk$%s(-`?Mls*>hV`b2=Zbhjpe6Ls4&G^qmjRiz4?LwLEytCH*VAUS|OjPmb<<+sX9 zZ=u8oeD`Tw6)1!iKe$J(Qj|=S#R*sj+@m-lzKvyyw;cu25I%sQ2LN~u{lxLqrdbnh z6_0m3R$^?i+he#N1q$<*03i5!`fls1`ufE% zU;CTU!_AS=-x|L$9?-_f$p>#Wj-FmQduz5Cir$`ie`dXRb@s!V$6*rbckbHk8F}18 zqOsfWuD*MB?Bm2oiF;aO^i(7A!h@?1&wf(=V(OD(BQm|=o8BK89uNyOpe?B9-xV3Z z0E@cb1HSgqgcU6}0e}i`-7^-z;(LcCbrPd9w_^lkamG_)g#Mo~g0gom?V2G1AR4+$ zAe1?ImSd@K+^-5p3(xOlERO*`A?*Z0yWF+Y)?Cy}-9do+3E(g@0QLkym!to1>7nwu z_cQP3q0d5Jy!EHZ=1Z?Pj=sL%^Xe|od&t00eP(UuuF{B&K`ry|cQS^kaPmc1i1c?2 z305A*&`07ke z``{-lv>7|xr504`NOZ*~bel~mqHb3DyC2Y>&6O=?{@nI(W-W2UR%VL^1Ih4Fw`JY1 zfJ+D{QYPFd_ibnAoA*BrQo+pJ@fCdaUK~spn`brl{Y05|Y(khY@*pJx8t!v9_ZN zu}K?-_H6OEs9W;vwu09qfOP(pqeY>|@RT^4*ROZKD&BM^n`I@711EU}ekO_x)(`g9 zMr$WmUfmd)XapxVlnE!20O^i)`qLJw(bbqxXi6wFB#LNE)UupV?XdeuW7lIV7cNep z-=!1ED#G#~;(OZ zPzjF+awmMyLw4|T*|0L#r#UZjTg8}UFqwLVwUf@KrY#rD+^(bpl46M&mHu7sm=uT8 zaIKjI0N#h!H~U66LZgocppCi}Xbue4-(Gur{mh-z-QJG}KN`Fz{cd<;;D=C_0`1gw5|WD~ z^YG{3+Z^9Vehh%^nJ@A}#}s zehDfHWIx9!vkEYD9P zd%t@IjU6*g{NK<;SkMb>kIJ_1M@}tzjib&GL&W?QfX6bW^j{-{9{W2P`Gy?&hCKK0 z&=K1EPXeIz8l@+m^o8j}ZDuPr-iVDqA+UM;eL`c)>K5s5kp9|*t=REK?D)MC4-b7s rrXG)TSzU{4xI8^3;CJq4+Swofd4i|5Hb1lH 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/MspImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/MspImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55027c129413c7cb6c543abfd39e50289cfc1d42 GIT binary patch literal 5965 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 WgnWgzmFC`3bMMmRm*`b`>;D7a^$-yN literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PSDraw.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PSDraw.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bcda9f5e5eead42f48ce6e9b9ad7ffe3e8f763bd GIT binary patch literal 7952 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PaletteFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PaletteFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82766e5d45967ec0b8f123381063d1a76d490072 GIT binary patch literal 1917 zcmZ7$OKcleaNd4xCutn#pAzbjl6LzuNhu$xLJBEVm8!J#gH+RKwefBoJL|RkcAdo0 zTB=YbLP@DZi{iq8R8*oU95`{|1U+&I$^o;=p$PSmTa*+*dx3fWG^QiHdGqG;X6DVj z`K75T00=+)b~^r}0PrU})Bw*6$o6r>OQ3^JOh}O^A&llsF2zTAqFI*IZ+7Zr3#=dTG-QI~ZAcPS?-KCj`dW*UxTyqhqMxx);HCpAkq4H}+E)9?j@ zYVovn*miO#$y9X16R2h%@%VEm-;PzCmLrf5^DO%Bp zyPTIWcKI@PMV`z1^8S24mtD+%mYeFq7)0Gy-W7`@U=7s0g|Bu~9nW9m&7r$GexRQ3 z@-D}EZ{Z8wpKPfHR=2r)P1^x+W@?l)1O4Fas+sNu+DKR~SZ|h#>zgGk zpG&ZioPk;X63h@KFuDO)=M7d<$_lp4s@}h$Bc2P6Yx@5>h_cq%_?M~S0wv&yRI}m+ zWo_j7sG;d*!ZJMGG%T;-e9m&T*>@;SQ%|%rX2S9KgyndF_cb$XRQN(Nov=K)+NMf_ zC)kEL;c*igk0fX}yO!7Nz8FA|1=7 z49l@2G5my)OwO51TdEzShJo9pMvcg{VNFNO#CTPB^vK{)#7;QI;fxlW(&C04IeY4K zr0%mF$>cnrswS+2qpEXl^^zKQHwI<12fYgG0|)Pq+)J*72Ja@9TW${(v|GoDgSXyX zPR`4#p}~i{LZx76sbR6&20xiD^4Hx` z$NmDp-qE+*zt%CZ8XS1o_tH0=cRTNOuLTd@?Jf@AZY{j`dB<}1{P1e<;3g+D^_2F6 z7aI#Lh2g@LV&7%}f=Djpi>){E>%DuH$(I-Jox4xIzIbQsyK~=@m5aaj4i)4gSqyCM zgXY%F1JJd5X?AgTSzhbhKQG*9e6kgR)}bd`J($g5?NLCbWBz0KD>s$ z%n%Mo_!i3k%ehb=<1*BN%Wgw-4SpA1f4Hml>d9@POH>}eO2h*d1Ew~LzR}}E7UM*Z zl>K*4a&no36{i9_$m)2)(rB*ymn-*2kiX;8^Bu1Q{1!cm0`{;rd*V%=5c1cHK>8m+ R`y=T5TMCl{TY#u+`yZ_J$KC({ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PalmImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PalmImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d824d7297a6d96aae59724c7cd46ba50a658e01 GIT binary patch literal 9706 zcmc&)Yit`=cAg=J4~e2ElAi~YO(L53>V0rYQ8M(85`u&7bz% zL*C&LDJ<%FI37>vVLg(FYj9~9I=?Ei7K>pUiiO7& zqYh7}B2k4kC-#H2B?jKQs=O>fV6S!czaU&?I-}{e;%W7tYJtycfw5ZP^%_8B#nYr^ z78jru7M1yEIM7fFxNCvNS^!ySQmlm~;z^N(0?0xEWT61EPyksf0Oq5LnPu>5O~!Qq zvao(IFpNMJ3Q)zWEX?Cw5TyVc6PFMhsbUCF#Soy1AwU&F01d4cStvji!)U4)0#q^V zP8CA{!z$&Q1Y9u$sA33E#Soy1A%H9_Gbn}tvQWT8c?4Aq8>wOlP{k0SikbP4k0(Wx z84ggzu#qZ;09DMaoawPupL2vEfkpo$?t6+^)62elvp8rF{k zSPKP^g#ySz0c4?oIT)T4Sy&hckc9%sLIGr<0P}GP^BiV{96%O^asXK z1(=W14oNW|RSW?%mGaT2ikXeLf$<#3Lc1Uf1*l?GmWm!#77Ac36hIaVAPWVkVpWz( z`BfGQAPWVMg#ygyilG!#F$6GkrCJ22Vy4d(LjYN57i6ITRSdfzOQl)_%tSB^=wmH3 z0$C`4EEJ%MRaq+KS6L{4EEGT%3NW85hS5|p1gK&NnB#|95HJk~kcFWfKo$y6#jrb7 z3;|@Rl#c)!3Lpywkc9$Nu_{ZY{3;6t5TyXJP=NVdF>IuYAwU&FfGUOnvM>VzAz-2$ zKo%N76~kz%7y?u=Gaui!5HQU;7KUQYjw+WT606%p_PR5LFC)su%)PF$Ab$ z2vEfkK&pyB2$*3|3;I+s1gK&NP{qvdTrmX9f_PFBwOlP{k0SikbN;imiIt z^73#4@0DH5Z{h}k6U@gjW&n7f0X}X3m}b788vxSGZ{`MozhQoW8vuU8{1$Ei_=@>K zZUFdq=C^VK!0(vf#ti^-%*TS50fE|0fO%Xo6I}-|^igHz%pB?#mf`=&i~_fL)PZLe z1o8P!c-vnPboOxoj|n!|nnM<4i*DnfZs*?PO0O{s{|GTFq=X5UyXMf@D#Al&tEKFH zM@F8x_RK!c%!<_!oDhEM5QJGvN=#XjkaBr+;!rzm|xHv{6-2;B+mlD*e}$`1Ss1 zN{^Ak|l3AeZ4k?IxHx;aP+C-cV*JJGyx6fwtUzu(2gA#q`-@u-6oUtgzC+8>;ZpaGxp)59_G;Q)a{9Bg1!qsjwPqFC2Ua9c_CU`1 ztI_4%$BH`#3mt<6|M7x!eC{1c_f%>wNX^+R%Ti~_)iihZISfIF2uGQjW2S@sLcjHl zPHB1~wwEiIbVoF}h)t@BrYUmLb1kgx)nOvENl+-RSKe?8DV~TchEDZ*zimgta-7xV;Ib;vaGOVZatS15GND?+?u7}*jw#3;wsHk3NcUL@Q zFXnRr+OUZt1{q_sy1ekmkk zcWpcT%G>2FuorBw`!aRp#*{TxCtJs?kEL?oaq+RW?7@22%k#m5=u7<3SY>OWpSM)c zd=CAcpEOmrYZ=z7laugv0rM=Zvd4l|#yTp3;Rhp!4PSiD_U*s4 zEC?C6wPh?xcot{3_hI3Ycuw60ZSaUG-Z1R3@Qv%?sA1EtMaFcE_3oIPQ<)Hk^KdjA zyDEo|B!eL>d|l}~98HXdquLR0$_;-3VH$gt{Es;ycWNp8#hZ^NzU(=m?g8jKMkQ88 zC9>_kJSufRbSaO^q8?!WK`Ffw=9qb7=X}NI75C@XhfkQ+1lDCTQq;En(wT~G#i4hA3ZP*iIW16C`GL_V~ zm|+{dVZC^I(2&3!gXhHXbg!lQu4vfCqEp(n-d00mw1!KGkHT4v#K#hbbzFgG|H(uo zt{V~}j`PDORW+d+wh)F((L`7_BrTGJM^F~#3mrfI?uCmdhlhvGp9@|3$%T`{@G?<; zXE5xcQ)iEz1_1Kn>q0#^ywQfm8xs4|u8OOQZB{CK(gQX&y>Pk&e+4!i@FX18byYnH zZN1HgB@#0%W0Qt+3|iyi7(_soY<%h)theL3qH6HxWy2cN#tjJ`ur)(c6VsaE1bcNx zhZi0%d9n^g;<9qXXyOmw&^5%~C74#>am{GpkLXyod4+;Fd7FBaQHv2=Ch8%$(Aa{9 zx1pNj=uuqEDtkRaGsR;62vhiqLxBy;4cYiq%^bx|q0dY0-6t^w91u+TT(mkShpyVA!?Ey2at=da~D z=YN(yRca0_TIWxvPnNv?h1U7j<@N(b@4?Jq$?ds!Idl2mmCTjJK+(NDcc9?jQ_i$& ze%IoT`M%mj<^IJ=|CQ#QIrZ1m52tgHr5kzQ{`B!@zP82gPxs^-wyoKP=3v@#*I8-ld&|;6Pq#UTJW{`(Skj^6jrIsee2DXu8n;R>|YNm&_#d zo*jAT4zQ)Bzyo`J`>Tc4fkM+j+Exm7r5j4YwuR(;a^dFuO}K!mI5>as)5A~wy9@r^ zMgN|Rb0yfCZdh@6vac=do8MP(w3mGCig73hSaKZb-jD5xH zOWRi@`|UHg&fL9}?YT4Zpl4D4e0Ra!^DBMn%wPY!;C}PB(v$ap<0`n1FH0v%mC%b> z>z&KXQlNV6xC3vaZT$LDcITZBmZf%neKFtES#)%pWmJfEZM*C{X_8Y zf`ym&Kk0lj{<|Cb_b%ptFkJLr$~V3Ljn!hae**$}(rR|!vSUj{qF>a*M+4_ecoQ-t z+~RG0unoqN_4u`-pZVwDe}J*8iaw>rzjfh9jy|-#PIZLs6j5fbfJxR3oxg&c*iY3D z*tJX3)s9pLLh6Tr7}7cTL;xFQeJC_G1sRo4NM*MO!w%b8BtEXPo3tU|*P-%;>j+(q z#KY=Lc_U_@$YBp=-^4 zRNQh#%nQNiZ(E$A_fIWCTVJuYKQ9E<8ij2=UySA7yIiRI@tl2STi4PXPc9V#gL%RC zyg4F@{l&9Yei^fNNYi8U2Mq(mxbOH!B1k&{G literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PcdImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PcdImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d5f2fb6ac5116b0cea794926d396a9a061fc94c GIT binary patch literal 2050 zcmZ`)O-vg{6rR~1+u(IT#t@)D4J9P5C~n%MRnjU_8yA`sAxh~XzO1&M!7SLj?(CAp z7LibugOL&eC&;NeRa9KsOLMDwtkeq*M7BmbSn8qT7K!xIOZsN*1tO7={N9`Q-n{qr z&G*KCMIx;T)^F9x?6m+we~XR3)P{f$e+OX`5kznf<#8HgL?j~Tq`aJ#^GaI5NJ0~c zDEARjsj?9A103@mxgn=j2~l}LJGS@|RTs|q@-e6Cj?~zR9B{Jz*yc;8pCp0flf_^n zbRgUln1>C^vR%V9ZOb{pLML(cM&8I$-r})wGe#2-L?JsCNf(GHkyP(}f z%V@#3oZu_cP4ojk-L}wd?+JIftes{K{Dz1N%?m#L)IGcm-$|riMC8Sf5n>Ud+>_j( z@4YPf@u4bA)E+R9KnZf*lL=(hl_O7?1Q#zrgb)dx)LYuJOah)INLo%>NGt4)sv}|8 zi5_{&ZS$qmz(6z-fgVMDpJQGEk(?oDr&(7PdZ~Nh7d}OlXqz$-K=(k{9YNsM^wJqX zOWcTq9G?SZm=Y9nAll7@%Rw55`O~Xcuedxj@p(cr#YLI|Gh8lYNJ3%)J{~c}B`3mM znk#U{p>&Zej2eW8zbRU-arXN_2;apT2hxK1JIdA7_(t4kfB2A|3%u*hloMZ-uAz3K8 z^R}fs8Ad6vd4tj9ZED?4=FIP!#t+9Xevoubm%djpGK(-XPICIjWYP!wbZ#kYT4RMG zRA?8dRf_r+F;ruoZUAa=o&Z@v^|p?+JF9ng+lF>SLqO{xZ7sMOT+>#y_1XPUZ%u1o zn^>J#n_QjTitT9wWn2$y<(aZkzPvv1H2hXAI#j;?JlemN*^3VCYD4v|vs=nW_A%aA zEQf3H;j*$H>aT^nwg!ds@JKoJOdG64y0<=i8tJbMpD(BOwZVF4Z&`WJTI=i=?0M(F zroN#+{&su(m)R$`e!W#0z4k}TpO^MJr*~stmz9Sthfq3tZF&V5;D-;lL3q>jvT;CV z^Cb}x{B_z4o<8ILv;k_5-i|lKJen0h3wmuHivsO3o{Xd?4boR%-M}6hg!<#RHNE>8vI6Vaqa)42HiCJ8kvMmbFX-L;C zBTsdmx9VaXmS9G7uIc*sOGd6~3C!6nZ@4_#;5wmzWV0X!fV~ZI*)Wiwk(a~!ASV8& zJmP(+`1Jdz7KyHm*Lp7ODqV+4Or60mM-_FXaY*==lrb3VsYHvYWNrzngi4rz07p!` zSl)zsQF(;Xtm(LvdBA7y3a99ij^1^t<%sG=#j&^`jXrG Vg1Wc*sy(BXp3&{OXXvt*^M6{uxlRB8 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PcfFontFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PcfFontFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7b26bd12590af382651f59a3ee3624cd6c91ae09 GIT binary patch literal 9919 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PdfImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PdfImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60b0550ca3ee8d43396850b9b1c7ef5fa117a58b GIT binary patch literal 9778 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PdfParser.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PdfParser.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..09829bab855cacaf4b90b62968d1a325044ac65e GIT binary patch literal 52814 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%0D<`iNOm+qS+9L2a8j_ozE7 z&t^; zzA+vJieTnjsFJ}E24><0zjtILZoI$)<%yfUqY&DHvFuH3A?L@=GuAgxl$OUT5--{z zmOpMyw5y+>P}~gG8SkfWjT_GM-dE$sVZyu^<{r1v#y)&{d~DpuQZsH&yug2E*w-(W zB7PmQw;lA=ARGHfhDTop1v&ycmEq!qrb&;;%f5+r1#AjHWZyA|K;OrJ_Oxl`zdIPJ zi552s#f{P8R-w2xQoKG=u;GVC?>eK~4h!23N4GsAYArek${aJ9uVh}zoHj3*ia*cE zdr(n5)wx(+KWF&f*i6>6aoPu>V|wRo`&{L%t#iKb?}?R^&vZVhYn9R72<@Ei{M=deFk4g6^3blSuAjEW3X7%Cgf{g?JnADnHSuN11ixzHM03& zxbjKC`Q(E2(BGANQBrL%^pyG_76Nb?h6XXB!?G3Kfa*X|HpJ7UG1_g=X7=-EPZ}ktY!P%^>@a?t|rjx`2|!_%+(kxX_+@f+d73d6d<%62^T+wy}#&b z?SIwlk+Dou-u$aFjm`1!39ZIn6gIhj{bjbMv<{>fmDqY8rRm}Q%9n?M`wN?~Yq#z% zc3Zlw#=o>^;esWXV6^p)je3FJ5HZLYZTwsCeP#2Le#DEAk6h@^5D1Iqx06-jW6U|5j^Cj$&CVqj$= zoETUpubImu78dm#J$+d^jn{%dE2%_Da9D!eoTXE9MRP@aMK@?T1CicI?2ZsKlb!{8 z6w%!~y300$X3#LHo77H%5=6;4P@}SxG1VJE}JyL7=JnR%I`&%+!Z6X=})B0sRQZB_C$BcY_|wP6HJgrOa3(X-u?wk zP0Uq#(|p}L)%oq7#q7e6;XUs{HU(0^1H@UbTV@YNT&?uJ5;aG6id{;)mDSj9kCJGK zpQ#f+Za)fI!A-O<;qicvWOME66Bhm3)*!Li_dUL;Ny*56#I0FM`Pm0wmC<362pZ zdD8z*iQ3^1wqGzk{@&?`weG%k@7$)3x8K=**ZGs8Pm6@6y}#1y?CuBIAe^ra&kPIM z6%UO%vwMxPT!$i4dPJ3(BQ0m?8+80D$R`eBI;}$TjpX?#%3=Nf;So4kV!6ek_Nx_B8L`~_YenxCO?5yOiFl250{+_|2`IRh zJ(C?8_zch@;XgB%dwt|Hd(%U+Ca>hnER8*X`q{T9!=_R;j-+ow8&V)YQLj7bW+)JT zF;NuUi;3d+*N{}ip$z;_$j|mMhKjMh?Nx+%?CBWOi&DQj z+3FiP5oi6UyFP2|`E=L(z(*VBUirh#cXve^djx0C#lv43GL2>b^rcbLbWqDC$DibN z6lbwLeh_ubPXeN?DZe$L_d94hsV^Xrk4r*9HLa7?GzDo_g-th@HpZkGpuJU%tCtO17FTYSL7Jm|2VF!>Q9pw-g zRNl%8zoOC!fDxwQoc3Rvn3)i$j);3lq;Q8|+i}+`*!G1@`@}WEvuT~Kn8k`u$MXM{ z+Ck1gQ5_~Yq8PeU%Zg%A>a(K;X%!S6XA(q3tc-*lI#ZNGL$A!lkmSzcLI0p0d89{% zwlv_x^yiqy2w#=7&!}v!YFtv%HUS(>l&*ygl%!Sa@RpOgTukka)U`y&Fob46ENvMa z8-X00sm8}m$D#O5EssOq2kL9UPx@M-=F=3?r^3THLKvnfYM5 zXe|^4Fj4C|!Mbkl*!;%3#?P#~A2hX1bxu3370(oh4n}h8?^_$#IHb@Nw2R(Pf+Klv1X4ARG_`eP6&SLSUKb$OC z z^(^|(z-0pm*#1puCI-M}m^30JhtP5Kjghm7VM+B7LX-9=)au#Nv?#nPctp@hD@tk& z>ej6gkLN-HO6!k33ZM+?-@rFb>c0WCX_<>?@8xM}#0{O`%LR0u+m~on#{s_V-P4TvZ2d&d_n)r(HB;3Cet zsV=~VD?2ak3}q}>Dgfsb)TCj-RvUAbg$6>WLgs1XgOc*8Ly(0{Z+bfr+WXcwV-+>C z&s?9Fwk{TxhK|o}m^~Fb5h-e%dqyZ~oz7TvfJVEzeOC9*o|v;3JjL2M-Q0%Rb&+y3 zq;ZJMts?n_19lEYwRvkerR6IgA_WFS39>pY+d)?Nb{ljD@Ino;p}v1e&#TD zHtT;@YVB;$|E$3Xe+ni*K#YOH1L*HHQ1;}F2U+Nm7)LW?&p||Wh;~Tql?l|Uj@Hf_NDkT|r!ZuU0>3)?b|7pLS(v>NyLTLIV(eZ%gM5sFpc#aZy+i>l zoLNF-JY3jI3>2oOdqmM^mfH_`XdvH(WwbWIt)EgrZ?S=+Qh zvHD5b4Ciduq$bo-ksksTjJT+SM&$5)+KP9YFFV)e3Q$5%W^+|3rOTsc<(^6G>5k{mFIRB~*6I z`+qd?M-!3Cj!035VCx8*Iz);B)11l=uSZ&*El-*_z!XHPy zBj7^%XgBT#?&s}f=ldAs>O8be9e>C>dfI;m$M7;S*1q9@H;@Bh4n8CuK|@}5!08?z zeR*{3!f5OGsBirIc_!nA>OGqfgw?WH5jO;I#2B*&HJk(6)8`WPtI zA)QqAa>-hPz&}|%ahoKMCmks?iNA`RX`AVO1Ti*nVzP;61v_Y}eSjzt4=s)57hUV0 z>7RW;$ZwtM1}n*$H~rFmOEr{JvvTb8*YMrkYsf+%vNW2aUGg+6rNH zMPyUYg5zM=3cbFn58CH4-rqUf5^n1Z=XH^8U+wH*B(E`SZT$6@`3c0X6r$&ATW7Yu zb%b!b(*Filp0gAfpHi1csM`4sw678L6+1uqhOMJfbIrEbsQGDQ{$8E_&$U`|jjp|J z{hwE8;nIH0I+*Q@wCs{NdbA&}1%#-Z(sx)b6+zBU>Mbi$& zQIfvgW9vP}pbjuvZ#QEf58)KFmxYavkBl%T0V5I`I=2V1lZpR6Mn-s;dx8Pk6DQb9 z10yp|G>BmyPhOHpk}dGR#m6%gL0sj}<27y^8W|fvD=3P#9RB~JPz#{5glaQRz!2jA z7--jy8whI=NfjEjcqW*>BLjmlAHgr+JsDwQ^b9#q6Fg{!0|Y74G}Za~1n{JoIcv&$ zsW@gUBwrCi7R`?7j`uP@DEz45hdtrK-3#VDL_$3M_G?o%F;4&9@#)}#xrS)=^>4p= zW%ANw2xlA{!lnk6;9Y;TuwE#vUobbsZ29jQZf0N4o*kQiCF0r^bv+@tp14;WaUBwD zhkouCY)8YUqlsJ#=2F!3?sK81ucA12*yK))cs?|6^~H#-GHj|8BYX>HkT-?zS!O#R zD6rLsP4!~L_=36Y0W^JjF7-@%L(fI5wNqNs{GoR))E%)_tGwe7+rXvQLN%92c=}7} zlSM2B-6uZ=(WhPR1+I}qh~U7u8A@{EKklgHOa0}Jfs1U!vEJheWsqkR${^1rltG>o zl|i`Y*l8v+e$60jvhbUQUkmpT1JfJxN+BA0_2Y^n7k{sd=3 zO8biNlbjvlxhN?Yzj&74*5d!oDKT)mQ8- z;)-a+^_9R^%zUL>NnaUP+E?x^^OjSHw~U2XK%vEbcCXxu@v4CO2>(LDwvgfF~9q4r(B@yksw1~^{RE3q|{xVRL5h~jqh2j)*AF*4f?N^`x;k^ z-@4UXA;IOo`qk5Lb*yzRa=ChP(YgsQUSagAIXD3{!q?Q5jmn38hS8Y$aZOV|qKHl^g+yhg6gDJi$Ck#Y+wzm!}q*}s*A ztBvf|-=ef_tCqHHjncNSnrr)Nxwst(Xta~%6`{^9^2_70W3{}P&%0An?p!0~o>kkn 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 SkpzqF&7StK@UDVTSoL36tR4^m literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PixarImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PixarImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef425fafd6fc786830139bb97f8ea82d9065d579 GIT binary patch literal 1974 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PpmImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PpmImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b393d525877b5605ec820ef3a5e0d4916451a7f1 GIT binary patch literal 14124 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 E3urjkwEzGB literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/PsdImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/PsdImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75b2daeb755aa9d9f9458f2177a2b44813804b56 GIT binary patch literal 10843 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/QoiImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/QoiImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..428ce1737952150624023ccf83574356e07d3689 GIT binary patch literal 6058 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/SpiderImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/SpiderImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72f23ac65e47a5273f3396e86a6a727e9340c778 GIT binary patch literal 12244 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 Vvcir3qqXb6aXa&&ojbn8@PDgH5>5aB literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/SunImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/SunImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..904defd06abc71cb28717959ad51d0f2c805c9c0 GIT binary patch literal 3428 zcma(TTTENYb*}IA+hAk!Fc>xlQdn+Er{-}gR`qQtTx#rq<3)+r! zXU?2+=Dg?3{c}^31;O~^ZeZ?TEeQRCZM31U0^DI4fOUis<`O8$1vw639p)3dBp>9H zLQqKRgL)MwBn(Mo&;+mr>+cIevkpxnY`BlGkqB{_&A!h9?ht#uOb*cuPd={IY>8czY%9wrD3fuTN#TpjHlpL00DN(9$496?_sbqML zC}wq;h$V<(Q^D)u1d(L|r}VLr3$rA`__e`&f{#1=2!M4Y*JwHP>dINHo1 z`6vbm9i!{+zKzf=Fk!kPfRxy8;=ljGr&IU@5fvU(f@VXSl4xv2Vj{i&ne)%5lEg2* zM{$Pu$5WBTBoSrF9|3Rt>5M#|5<^mi5(3M7m=gaI5tsal*z6H;Wcd6AzZ8?nyXkP` zE;uduuTKU1w-&{!!->VYm^hryD8^7Y5+P}s+CeW%jdTX4duY$voL~CoUm`y z{T;tC@r`veTk?)>3!{g?f+B3vhL(cEZosS~f`S}IK^^9TJk|vTtj9bQkUk^$42n&& zLd^hw>&|r64k+)HrBd62&zv3{r%FE^&g~Pm7f(=+f!$x&E6sqZH;L&S5t3m_b zP{ZpR@WvY6(15R9f>mQqz-Cr%)QT-LkQdNx&}>~bi3ys8T&SJ#IRZ(|m%QOW1w__FXv7{m*&F37l@+assvqJ5S3>&PaceGh)}>aqztf zx1P#pfcX4KA@eYlnzG55h&?K*#z^)S-Ep~Upft-+qYQ&w)L)?{x8o?fhSv5mWyO$6h zmOYx>IJ?l_8Mp_(b+UXWF~{djIdfF^jCDE~bF7AHQOqFF;ZeOB`W`K3zE8_(8nE}Y zy!v{lD_*cE+YWDoH!OOg`FLry??j>RQ1*OQ*vnS2v5BRm!s1wAVW7+-XxrTREPwv; z6oUd;K5+Smlu;|J%dny&lq z3QI$U)p3PweR>tEx^;Sld!z-Uqnxd2iR?&x~SeC$&1cxc>vUHH)jp^!BtO$&t7%537!V#hf zjGeMR24`-wms^lw_E~^J5>bVd6h0}#qZHebK$H5_8Nvp|+cAXxX%ffqSiA1yyv-nRE` zoBCirFrcQEN0SdG9|ax+iq0Kdcb?m`w-**3X3NfZ@>lnqJ;lh5vv1qhx8LH*8(z1$ zi!H^mCttv$JGQa#jd{DxmlqydUOQZcu>yT!$?IRYb`-hdg(uhY=Dm)t;`!q2lWg9$ z*V$dXv7!6AE8o0tbriR?>6YdHB8uk2^aJzi#XxvTfL{-^%U{!MA8YouU=OtiY!M<0(CZ#@2R z;|C?z;AUURHMHd{IY+h@N-dZ2hJ&|}t*vM;SqEP`I@j%w?Hl@yr7huw`MJ3?IQs4T zFDL)>)9tIbcN}*PcwJ|6e*9NcAho%p*t_E-f{<0o}y z6LMW_hze!*aT*$jff9L);-jVs@`h&znqPU zVVa?=sj7EhZ3(IwN)sh>G4|7^ULrcqBsgn0vLX{vVxCN}vn)*2duaNw8jX+WG~n0| zvlNEufaf^w-)9lm|4%ejLPLK;y@v*l`{0dZp5yupqr0wwl55}%V!MMcdBnBe)9)fz s3AqY^-PXZU>)>Yh*79G_$NR|5DDDz+7rS>mhf1A8o6*0bi>e9#1=5fYn*aa+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/TarIO.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/TarIO.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e5e8c6ffcd17938b44444a006c2e4a5bbeb887d GIT binary patch literal 1913 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 B=7azM literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/TiffTags.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/TiffTags.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..455720c27affe44d4eb5341b21cd178985107958 GIT binary patch literal 18818 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 P(1QOL_FYZ=Kbijz+tCw6 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/WalImageFile.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/WalImageFile.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc0614b453dbde98ec4376dafdcc031c08683d59 GIT binary patch literal 4098 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/WmfImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/WmfImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a55d98ae9ef430896a100ad2e6219f75d77b9060 GIT binary patch literal 6180 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 b(;_|1#LKyNX&LBBz literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/XbmImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/XbmImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d30779d5ab9de30a03eed93673ca1012d3562ae9 GIT binary patch literal 4105 zcmbVPYit|G5#D?8O+Bbb{KiFoQj$ga5i@rEj$>PeOQ~@J+mzG;#XC_)lSg*%WQilq56yGTSL6+>|9~TY{FjHE5*}jU+nSWIC%-(Xt5sNDJCUw`l#84LWFa0g1Lxk!Y8! z(T37&ZNJErMnR|8AUeRp1>P;uEwwr&UUEja)sspN(}%G$OLRv)t-7|ZMY^P0w&dT` zQgm*x?093#nl)3jxA7S<^isMrq$mk3q{#_I4ZxW0>wiWL(@X1IUpy3%bh|;$%P~p) zH%ttvojXNoR92)xen=bc>gg0FWKkO{jrN@yIBpD24)*RpI^5+Q9Ku7&a972|Zdi;- za%4;!_Dc+>gkbIy5*OE=LtPDn#N1e$;voFn3V~MQdk?2DHTzF(P{lMD+E22wg^A zCh*J(Gb-uIdxN94#8eH-Nx~&Doam%VJo5jI_{I`($*1&UF(vuVCBoxzNzqha7_P{d zOle~YMNq?7l7Nhbu;jZTDK~sEd89mfsOP{zpDJt8{$wb89j;LI4fI{|T^)%VH#ra+ zkH|_-GNoIEP&h0lHSC6UVW&tX;Xj2|oz1f+W=?!|YX0E-nY?pHwzJ^u&a>U?FpI*Z zGn*O4>*R&pMG^{9B7#Ru1sRbJ!t)gwcv@VF^;&e7xd9SNI&<~xPtuO72M+LOWi1{` zzI4_W@MfI#`>=p<*5-mWbc+5lx=m^2Eg%#vqf3nnxux1+nU9it*w94E#1NC-q%xH1 z7U`R`W;c~Hv^fhaJ1bHuN=|S?6B$$2q&Jz@+OVdsNpG^5`rbKH1D|=V*9tzGHm|j? znwlmZrQs~=;HbzQhwm0`86?=u1IRELmgozWbJN<)xoEq|RjFtf9pHUaRbp~!VBq_= zn&T?1zO+TQB#lt8Vr7RZRddeg~xOjlY#ScO3^}-A7Y%qIwLEZ z&P8xyJgKv?GMdmiA)XLnX+f3K5+?Bn{KsTBERpDpq=-7JfxydwNQ#Z>R9t7`YDDKI z4Gk_uh)RN-Ck?wwP7+B;NqcJFR*yhrhhbX%4mxYyUL$&&H-zPsj8JPdwY_!$nU=-qrE6sb%iW-3wn_n7>eL z-BoPbJF z*N z_z%~9cdgKU@-g*S?$6v`tbc1QwgvL7{nPBP?3i4301}l2OWHVAbT*JsBtROQASj`@ zBnY}gAm=_FBfLuxem)+Gm1iuY2@LnAdrDLgC4f{pN%9~j2>%cn?u}E%q~l~qiu%&(y; z`jP?ssCdp)(B(GZR6XnyS@1=WbVC!l%^(4fmM@uT<%L$2#8=)vMc!Z?bS1C8?h5v| zSOG=JNo{C#an)gB5?~{X13$1gX9m*GTkNC$m%6~)+k91hZ*KDoD5N!-pIoo9&A`dm zXn0KBDuwE`vHmR(?1Ti2s`yx~SAXElnyUK({A>rWMEX!$6jYbJ_c}#){lbrC9y;0TiFNuu0jW_BNl~k!= zJ`5!fS&YWf@IFvJ>CQJx;JW}Y;(&4oXUy^)f+Wp~#y+x?Vv-|4^AKX-PX{>`=f!aX7P$>nnxB z=N^XuxVH!L+xnN;fwJB7m2cTL12ofY4mM| O>gaF%7QJVD&Hn(R#%!Me literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/XpmImagePlugin.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/XpmImagePlugin.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2da84f469681d6f27598efb7d9f517499364f47 GIT binary patch literal 4255 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 R8oi60U(?w9IT}@y{a;EamKXp4 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa9bd0f7de6f1f0499750401ec88352cade83414 GIT binary patch literal 2036 zcmZuyzi%5i6y`~?Ez9=FseyDWh;)gH`mRoq7FL1+{v}tb2MTcxo-7K9-o@DfB_;~#8_qDYeP|t6#I-}Q1 z0Q{+q>t|s$v93%F3b1Gp64+Y%WRanPDwWr;25W1jTup~xE zZ(a36F_^b!zM`TZY&L3dbjusobOpz8BC%9C;*Dy&_EoQ|G@Plu8>YJB)C)7!c4bF~ zy|J4GyeG4v5ww?a!`}CwnKluIeUKViMJyYI`?M$sop9KcX`UxF+#R&T(G6L+=p-J-8B>lnZcl~h|6+dWy zrcbj`UlR3LSLYTJe%RQSV*1D(7)KPLX$_$$Az7&Bs|fv=;c&jPgb+!5gnj{6`c(eK?l_648-K>h zgu45QpGE2{gsZe(%(WZ|rJgiKVvIR;FKB$>hHN-r{M^~P=L#n2W{UlD)qdfsvvCn( zF_Q>6N{;UmRBWTm=!_Dzx$MCN4TuD8;!;h?n=;)4SwI?hek~&!8W{qTuG2 zaB)&NaFF8AP3Y!iV%vAf^LwAXd6K*~n+;^@<)b&eH9E1)vb;IqS>M1N;)vr2#dv_R zWhZh54tKd1xv@9!Fme!hyaLYEf8sJ^t~q|HKH^0lDx6krYMT}=SC|koWoamd?oaKA zF>6T}g(8qQ^>$l9B2{Y4b)6*^fzv>$n5DW^EgO^uS(+)JRJrDG>FPq4^#GVPwW?Up zV``X>(abRVWn?5{AYxbX0?3*4vlv9GiEkc2k|G^RLA9>{jEtB9l7q-e6kaYi4?27M zM29J~6XsvDA!u@O-XoO8EEJS>lA^31$C76eoTxQ(qy3ZKGRu#PG5$o`6V&)dn_sAQ Uzw>bV+#Pq{HV)s>ky literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/_binary.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/_binary.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb8ebaea692ddef188f6da5a6358f1b391fb4cd9 GIT binary patch literal 3444 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/_tkinter_finder.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/_tkinter_finder.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee95de0f15344d2f9fcf67cfbbd380549bff5ac7 GIT binary patch literal 774 zcmZuu&rcIU6rS1LcFVR@tE4rA!%DeSk@eTnm|(<&K!`DohP_Od-D$hsU(L)ESWoH+ z6Ay6W;9p?4d*^IoB$%M%MZ?Kkk(d}xzEYZy=sUdm-h1<2^B1^^#_1h9=fWFrrIN{A!HR&XDyp=ztAr)Fykq8X}r+79US&CZS>$mvw|GQ%9J z&}{qSpnl%BFP)DD*f!z<-2QI`bPH5#kN?Zs!DsAZs#X!rPa&3pSykIuMsFt8(7L*e z)^IKR{I2=Pk3G{(qK+R@&x{hU8&Wg$Tw;X;N7$SfXh}&rR&8#qnMt;h3=)^Hc6TcB*Flgiw^!E*1j3N-G2 z5a-}}D#rLo!C3p9MYwv1jBlv;BU9LTw%Oj#Tz#SRv>dK{)r%Ya)7Z7o`t>j6E8Edl zbWon&D^I`9e}^#G3O4db1yn3;Rt`#&d!@3~mo V3HrXBo*hTKN8lYSm0tlJ#lm4ztsLjodkyUlLDle#Um;x+~ZbPn0+C1iJy7#ZNW+v2wF zF!&oJN9<1fKv{}B3{{Zb^))tz8^SOmo#a4S7(rCT=sdc9{R+A&o<~%(y?~tAL1qs=;zwmMOIV)ghgMkiyX}S=aIgBP{FDNb%$`P ztUwc7m29b$Gxc(r&>bnCNAMQo$a8gz+9eR|e%tlKTL(aN6A@%!8^IikHeQkpu_0t7 zng&&A8yFeF_#y}fZ?#26VI<^a8m(fUwp8?eCo3?qOY+{! z)NYXcS-(_wi5CX>5)>?7YlL&YX9guo2rP3JCHZ;c&F7tJaa;LX?v+>b0eF0=W|b~k z6%yp9#wPM+*r-*#O0L#mY11q@RuGsK67rKxbD?iH_uT)KBM?`h0$D`AW%`yATfm}8 z$T|ZnHbnx5qn(`0eebbT9|0esRlFV`)nrJ;P-RuS#x zuDUtlrHsfhFwwC~=!t;!{uYL-nQYFOC4YwZtmMyIv}$?bzMetp`G>a-0^Qd$3A!dn zU6WaIx?ZdKGz>l_mc6fi+&F3RLE=IX9 ziGt&W^j=(!i}K(n;I0?Z-Qg%N7>OKI^ccvPSoK2M2OJ#)0@8lYAL3+ylNUJQq3o#| zFBat_2fsiDvV=CI6DKRch(`L=%VMWVu|vEnbI0V%0rB1 zhw{my8YeLhP`$caBs8G>R?;jNB|%hc+is?^8R7Iuq3aat+}{ipod%p9ND*({dar$Nm;E?VZ*Yc$dBhF#bRUF`!KmW4wWe z9-`Qu~Dd=BQl4X5E8`|vZzBzki_EzV5*U@Y7riLW-zSy}gb}nD} zQ5^VPI-C?s-lC-&z^Haq0;I7DDLAEC(y2Yr`kj-W*@c zjIXCB7TX>xC^3V-RR3;%h>_mCGO(67{up6d|3yneqO$%^a|9(bkC7zz|0M~r{w)Ng mDZ}<@z{m7XS3yGGX-XlD?n!E)O}wXLPSfp$Ve#G&2Kq0|*9@Kj literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/_util.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/_util.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bf30b505a8f780dd1f58325f2737aab972ff5e5 GIT binary patch literal 1553 zcmZ8h&2Jk;6rb4-dt=9Gn>K|YDkexpG6EYKP7y+)w5pJzP&GXn!Fsbhwl~=?X2wl6 zL?}Wz6d?q+aNvSe2}QZ{PjHFU184-|&;#nN)JRC2`rfW>~tLXp9?BSR%gy2w@6SuB7t)XUXVJq+-TMwqu8Xn?j=d8JQb#i+-Mrwd_T#xvytB6 zYABM&6s-)su&KmH;(D&QyzQxhp1Yf8{MOJDfsYmws(@e;LPzT$91}I&J0NQ8oe(vS z4kWZMXxo`c|F1oBf_Rgh(2b_8YoQDisl3GJ+TKDi+LTIYBbC}gTwDaT6 z+48lA_0=ZkI77`t`fFBc1Iy4|qT|1yqJu|2T2CNphgKA(NS*L|H)Uc9U zO-DCw@E#X}2RDUCg+EO(SfN~$0-+s~1A0K*@nJ%8BCz>Rs5bZ>l-H6x>WLRYCGi|% z;sPw%aosQpmFwQv*QAHmuLnm$U#R zUVx3JA(mm$CXdt%oVx4wIkc)0fN1%7MAI#VF6+Pm)WYJo{jd7>8zro1JHjR=zJP^M z&$jC6*lrW%WB=9=4Gy9{LBnx1J=u>@#~ zER`Kz*2zrx?*4_@gn;T2*vfOj4#_|Bs!m&Ky=G17^J_xNcncB)>U9+_c2Y z=%N8kS48m$2pfK212ZKUvK3?&ux1sTB=KVIy1M4NaT*LGl;>Udv!NH2I|55Dt^m{X zFup4EV-B+yh*v;$LJB-ZBxQIQBl?#N*bx~S)Lt4@sD1fKg;W-w8n(SMGC}$qrSdQy z0fgsaDR31C_m`)y)W@^$*C)+7qU{agjRUj-n?YbR>q?pZ@)C?&SKYCyibnWO71Lfq zeGPxH<;Mf_Zkd4h#Ot8LHY#FxVp2-~Ag?|mbAJ-{7imE>^qqg523>hdfE71911Se( AfdBvi literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/_version.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/_version.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6152243d96352fda5eff3394d6878c3108fc4ded GIT binary patch literal 273 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/__pycache__/report.cpython-312.pyc b/venv/lib/python3.12/site-packages/PIL/__pycache__/report.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efaa1461691ff578a0896e1128afcaa962520a11 GIT binary patch literal 335 zcmXv~Jxc>Y5S`5?UWld;Ye58yE4=li6)O>hAl7M?^>!|Ic(;4(?gj3b=wA@6^C#>T z4lG10(h2FT+{HM>%zHBr-eX?I;}Q5;yiI1(&(A>qi~a$!N<6p+36hjhktrb{dy!ICd43z*@aG<3YD`g^=7PYU9J_k zsX_E37Y5lJ)tr^Z?fQ6{9G@^-I6SOHdM9RR+0E6284QV%y6uK%m6lD3=Vr_Mh4^;I Xw{J=ad58Tk*!_U$;oueaO!(t3GtXT- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_binary.py b/venv/lib/python3.12/site-packages/PIL/_binary.py new file mode 100644 index 0000000..4594ccc --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_binary.py @@ -0,0 +1,112 @@ +# +# The Python Imaging Library. +# $Id$ +# +# Binary input/output support routines. +# +# Copyright (c) 1997-2003 by Secret Labs AB +# Copyright (c) 1995-2003 by Fredrik Lundh +# Copyright (c) 2012 by Brian Crowell +# +# See the README file for information on usage and redistribution. +# + + +"""Binary input/output support routines.""" +from __future__ import annotations + +from struct import pack, unpack_from + + +def i8(c: bytes) -> int: + return c[0] + + +def o8(i: int) -> bytes: + return bytes((i & 255,)) + + +# Input, le = little endian, be = big endian +def i16le(c: bytes, o: int = 0) -> int: + """ + Converts a 2-bytes (16 bits) string to an unsigned integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 2-bytes (16 bits) string to a signed integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 2-bytes (16 bits) string to a signed integer, big endian. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(">h", c, o)[0] + + +def i32le(c: bytes, o: int = 0) -> int: + """ + Converts a 4-bytes (32 bits) string to an unsigned integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 4-bytes (32 bits) string to a signed integer. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(" int: + """ + Converts a 4-bytes (32 bits) string to a signed integer, big endian. + + :param c: string containing bytes to convert + :param o: offset of bytes to convert in string + """ + return unpack_from(">i", c, o)[0] + + +def i16be(c: bytes, o: int = 0) -> int: + return unpack_from(">H", c, o)[0] + + +def i32be(c: bytes, o: int = 0) -> int: + return unpack_from(">I", c, o)[0] + + +# Output, le = little endian, be = big endian +def o16le(i: int) -> bytes: + return pack(" bytes: + return pack(" bytes: + return pack(">H", i) + + +def o32be(i: int) -> bytes: + return pack(">I", i) diff --git a/venv/lib/python3.12/site-packages/PIL/_deprecate.py b/venv/lib/python3.12/site-packages/PIL/_deprecate.py new file mode 100644 index 0000000..83952b3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_deprecate.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +import warnings + +from . import __version__ + + +def deprecate( + deprecated: str, + when: int | None, + replacement: str | None = None, + *, + action: str | None = None, + plural: bool = False, +) -> None: + """ + Deprecations helper. + + :param deprecated: Name of thing to be deprecated. + :param when: Pillow major version to be removed in. + :param replacement: Name of replacement. + :param action: Instead of "replacement", give a custom call to action + e.g. "Upgrade to new thing". + :param plural: if the deprecated thing is plural, needing "are" instead of "is". + + Usually of the form: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd). + Use [replacement] instead." + + You can leave out the replacement sentence: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd)" + + Or with another call to action: + + "[deprecated] is deprecated and will be removed in Pillow [when] (yyyy-mm-dd). + [action]." + """ + + is_ = "are" if plural else "is" + + if when is None: + removed = "a future version" + elif when <= int(__version__.split(".")[0]): + msg = f"{deprecated} {is_} deprecated and should be removed." + raise RuntimeError(msg) + elif when == 12: + removed = "Pillow 12 (2025-10-15)" + else: + msg = f"Unknown removal version: {when}. Update {__name__}?" + raise ValueError(msg) + + if replacement and action: + msg = "Use only one of 'replacement' and 'action'" + raise ValueError(msg) + + if replacement: + action = f". Use {replacement} instead." + elif action: + action = f". {action.rstrip('.')}." + else: + action = "" + + warnings.warn( + f"{deprecated} {is_} deprecated and will be removed in {removed}{action}", + DeprecationWarning, + stacklevel=3, + ) diff --git a/venv/lib/python3.12/site-packages/PIL/_imaging.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imaging.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..c7fbd5864970be8c38d87f977eac5b8f7d9afbf8 GIT binary patch literal 3115489 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

    |FsBS30>wgcV*=%zd%ce*U_ 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

    XwNI;h)&vQ*@l}ew8q+6aWpTwHi$6fsRQB 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�Ia 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

    vOok$Iyjnssg$1OQ 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
    ms|fLuvh;oH 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 z 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

  1. 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

    ssKRr$rz%J_|S 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imaging.pyi b/venv/lib/python3.12/site-packages/PIL/_imaging.pyi new file mode 100644 index 0000000..998bc52 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imaging.pyi @@ -0,0 +1,31 @@ +from typing import Any + +class ImagingCore: + def __getitem__(self, index: int) -> float: ... + def __getattr__(self, name: str) -> Any: ... + +class ImagingFont: + def __getattr__(self, name: str) -> Any: ... + +class ImagingDraw: + def __getattr__(self, name: str) -> Any: ... + +class PixelAccess: + def __getitem__(self, xy: tuple[int, int]) -> float | tuple[int, ...]: ... + def __setitem__( + self, xy: tuple[int, int], color: float | tuple[int, ...] + ) -> None: ... + +class ImagingDecoder: + def __getattr__(self, name: str) -> Any: ... + +class ImagingEncoder: + def __getattr__(self, name: str) -> Any: ... + +class _Outline: + def close(self) -> None: ... + def __getattr__(self, name: str) -> Any: ... + +def font(image: ImagingCore, glyphdata: bytes) -> ImagingFont: ... +def outline() -> _Outline: ... +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingcms.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imagingcms.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..914f5d1962cb07b5eb7bca5658d64ae6e728b411 GIT binary patch literal 145465 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 MJJ|rY`b+$O0iYm1#{d8T literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingcms.pyi b/venv/lib/python3.12/site-packages/PIL/_imagingcms.pyi new file mode 100644 index 0000000..ddcf93a --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imagingcms.pyi @@ -0,0 +1,143 @@ +import datetime +import sys +from typing import Literal, SupportsFloat, TypedDict + +from ._typing import CapsuleType + +littlecms_version: str | None + +_Tuple3f = tuple[float, float, float] +_Tuple2x3f = tuple[_Tuple3f, _Tuple3f] +_Tuple3x3f = tuple[_Tuple3f, _Tuple3f, _Tuple3f] + +class _IccMeasurementCondition(TypedDict): + observer: int + backing: _Tuple3f + geo: str + flare: float + illuminant_type: str + +class _IccViewingCondition(TypedDict): + illuminant: _Tuple3f + surround: _Tuple3f + illuminant_type: str + +class CmsProfile: + @property + def rendering_intent(self) -> int: ... + @property + def creation_date(self) -> datetime.datetime | None: ... + @property + def copyright(self) -> str | None: ... + @property + def target(self) -> str | None: ... + @property + def manufacturer(self) -> str | None: ... + @property + def model(self) -> str | None: ... + @property + def profile_description(self) -> str | None: ... + @property + def screening_description(self) -> str | None: ... + @property + def viewing_condition(self) -> str | None: ... + @property + def version(self) -> float: ... + @property + def icc_version(self) -> int: ... + @property + def attributes(self) -> int: ... + @property + def header_flags(self) -> int: ... + @property + def header_manufacturer(self) -> str: ... + @property + def header_model(self) -> str: ... + @property + def device_class(self) -> str: ... + @property + def connection_space(self) -> str: ... + @property + def xcolor_space(self) -> str: ... + @property + def profile_id(self) -> bytes: ... + @property + def is_matrix_shaper(self) -> bool: ... + @property + def technology(self) -> str | None: ... + @property + def colorimetric_intent(self) -> str | None: ... + @property + def perceptual_rendering_intent_gamut(self) -> str | None: ... + @property + def saturation_rendering_intent_gamut(self) -> str | None: ... + @property + def red_colorant(self) -> _Tuple2x3f | None: ... + @property + def green_colorant(self) -> _Tuple2x3f | None: ... + @property + def blue_colorant(self) -> _Tuple2x3f | None: ... + @property + def red_primary(self) -> _Tuple2x3f | None: ... + @property + def green_primary(self) -> _Tuple2x3f | None: ... + @property + def blue_primary(self) -> _Tuple2x3f | None: ... + @property + def media_white_point_temperature(self) -> float | None: ... + @property + def media_white_point(self) -> _Tuple2x3f | None: ... + @property + def media_black_point(self) -> _Tuple2x3f | None: ... + @property + def luminance(self) -> _Tuple2x3f | None: ... + @property + def chromatic_adaptation(self) -> tuple[_Tuple3x3f, _Tuple3x3f] | None: ... + @property + def chromaticity(self) -> _Tuple3x3f | None: ... + @property + def colorant_table(self) -> list[str] | None: ... + @property + def colorant_table_out(self) -> list[str] | None: ... + @property + def intent_supported(self) -> dict[int, tuple[bool, bool, bool]] | None: ... + @property + def clut(self) -> dict[int, tuple[bool, bool, bool]] | None: ... + @property + def icc_measurement_condition(self) -> _IccMeasurementCondition | None: ... + @property + def icc_viewing_condition(self) -> _IccViewingCondition | None: ... + def is_intent_supported(self, intent: int, direction: int, /) -> int: ... + +class CmsTransform: + def apply(self, id_in: CapsuleType, id_out: CapsuleType) -> int: ... + +def profile_open(profile: str, /) -> CmsProfile: ... +def profile_frombytes(profile: bytes, /) -> CmsProfile: ... +def profile_tobytes(profile: CmsProfile, /) -> bytes: ... +def buildTransform( + input_profile: CmsProfile, + output_profile: CmsProfile, + in_mode: str, + out_mode: str, + rendering_intent: int = 0, + cms_flags: int = 0, + /, +) -> CmsTransform: ... +def buildProofTransform( + input_profile: CmsProfile, + output_profile: CmsProfile, + proof_profile: CmsProfile, + in_mode: str, + out_mode: str, + rendering_intent: int = 0, + proof_intent: int = 0, + cms_flags: int = 0, + /, +) -> CmsTransform: ... +def createProfile( + color_space: Literal["LAB", "XYZ", "sRGB"], color_temp: SupportsFloat = 0.0, / +) -> CmsProfile: ... + +if sys.platform == "win32": + def get_display_profile_win32(handle: int = 0, is_dc: int = 0, /) -> str | None: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingft.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imagingft.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..185e47e51852608bde322169d256abcee95b9074 GIT binary patch literal 298281 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�n^uZhyKJgK(!|!`JEb!M4R4mA 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingft.pyi b/venv/lib/python3.12/site-packages/PIL/_imagingft.pyi new file mode 100644 index 0000000..9cc9822 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imagingft.pyi @@ -0,0 +1,69 @@ +from typing import Any, Callable + +from . import ImageFont, _imaging + +class Font: + @property + def family(self) -> str | None: ... + @property + def style(self) -> str | None: ... + @property + def ascent(self) -> int: ... + @property + def descent(self) -> int: ... + @property + def height(self) -> int: ... + @property + def x_ppem(self) -> int: ... + @property + def y_ppem(self) -> int: ... + @property + def glyphs(self) -> int: ... + def render( + self, + string: str | bytes, + fill: Callable[[int, int], _imaging.ImagingCore], + mode: str, + dir: str | None, + features: list[str] | None, + lang: str | None, + stroke_width: float, + anchor: str | None, + foreground_ink_long: int, + x_start: float, + y_start: float, + /, + ) -> tuple[_imaging.ImagingCore, tuple[int, int]]: ... + def getsize( + self, + string: str | bytes | bytearray, + mode: str, + dir: str | None, + features: list[str] | None, + lang: str | None, + anchor: str | None, + /, + ) -> tuple[tuple[int, int], tuple[int, int]]: ... + def getlength( + self, + string: str | bytes, + mode: str, + dir: str | None, + features: list[str] | None, + lang: str | None, + /, + ) -> float: ... + def getvarnames(self) -> list[bytes]: ... + def getvaraxes(self) -> list[ImageFont.Axis]: ... + def setvarname(self, instance_index: int, /) -> None: ... + def setvaraxes(self, axes: list[float], /) -> None: ... + +def getfont( + filename: str | bytes, + size: float, + index: int, + encoding: str, + font_bytes: bytes, + layout_engine: int, +) -> Font: ... +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingmath.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imagingmath.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..f64ac145b1b6f62fceaf03884480804954cb4983 GIT binary patch literal 156856 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 Ck7ye}r^m#Mfbi~?T5_P7Y?I<6|& z8k4Q_O&B7i+l<*+n!daG9vA+bDD=C@HU-bO^gV3b4t|$Tg+RruFUohG4G1-fK_8y8sfTp*#Ddp#J zFeHBa_hcjbuB@#ucjB-%@UeogyJ)e$nVgt5vjeEm!f1o@cX)jt_#!E#U6%=z63=mB zYS?LM;a?lYT3<~st%$^Yj=vWBDYn>Qh)B%m8c~|mor<$`h)B%mIpJ=CK9Ovkm@lyH zN$6`J*Jn_V>qDj^_HO9gA)JISaS~#iat^-4IcQm)#wqxcOu=ECbk9qmx~57-(iPj{ zaA(VxbXMdVO`n`}2~fH~wD!?50wrB08h~{p>GX7XV4>r{axZcYAUNfQY3-9_J4!Zs z`HeO@B^%uuriJWlq@9xO7L$FG$-Y3^DXI3E;@oGlmzw;aG}-C)olLeKYWx6Eo6YH}f)!ZdF_c7F(? z7p4dA#CHK9K%Y(MpVHMug%ADA0Sf(7jQ+_ST!lgedSUws`dMKEdSUB%7iJI$p?`|e zuZ4CWS%6+xRxLn2LOd}F{Zov7ORlE90AcjPbZj9my&#NUn0{V_mxv%hznZfDNnKrS z@~@44XQ{U9Q9gzXvVYaoRFNk$*E1UG}o0`$Ui5tic+ zPYEVm&YUM1eWQEurXz&W3saYTybS_j^ujcBDcgAfY7{cg<>5coamqUQQUp1hATrcTF8oq0ggf>mjc-J z)zL!~`qhkn)uY(=AOgLxeGC1Bupzdvb$JYD=nz7`n$fR-wuCG|FD&to2s)i*~C2%`sbd&xBjrMp5UC3@%7bvhN_M7Fc0fpG=38z zh9zvF&tUR^z=n>5Z9Mc*5E|CQdII9T4ee#JU|7PE`z$WTA)ZWiD1MlSGGZOxyMXXe zgemeloP0ufhY+TdP!B^ooaiagzAuLIlLJF}NLSDKIO*V^uU;}t4do#o%9GFIr~nZ| z5w@S8pA|L?Mc8`2fTIG0hVl>(Wev3Z$bz8=%S0r?5Qt}ujX>h8;vpVNw-<2{4dI~( zll3J$Gh!3>KwD)OOm9K3A!bLcfa9Yp>$@1ni7nnBIfw-w@sq!t}sv zm}((FUlIiL59;cr3m^KR8x{Ho8U4_Wc)<%I&Z+&G5-{XBf=D|Gdm)=1-+HhhHQeg&id4gTjL0==;H zeFv;U2F^o5N60&Hi=lh6y(toLw224VEVR0g#a0`xm9fO@Z9*n%{iH}NN-Z#i0_zn9V9 z{5~G}Km>YWdkgwTVFP+$3;6&SIS@jBFQXp~Z5UaAURX9jdmiGUA64f4>|RE1-HTgV z!(2%{IK-=Us|Q05T&Wjftfr6rv|34N)7ei@_B{t(Fv5$J_&C-g1C2K2&K zXCHp*3qt6ZG5VXKWsn8vh2?E%Z$Lb26#8Y1-u)5I9w3Zfm!0DADg%bLSOq3uB#zHzdZy{m+G0(q?x&&kgm`# zW%T#KeI9fjh zfelfG?FZEp0TH-`?PciCK?rvqpYV+!M)&MPI#ioZ|a# zKiopA_c^i>B5(`aH0YBcg!^vB{VudO$pYNM68Z&BgCU*`3isWNdjf1DA&gs?zJ&S- zo3KTNX>2` zl`Oz5EFVJK4e{hC+>04^U{fw|7wy-6CgL~8vLcfsFKL~9(S%6+xPC@$$;)zt~7c%-TrMR$xFnVEn z6Y48$;vNWnr&G9p2m$)HssMeiUf7g0Gxzf|6#867{|fwHfC%)$rhSXACJP&43)=wL zQXzysm(j0<_83`!URW+bD}#8-z#Vg+%ji>1<316D(F@ZKsPC|edm!{ZzQe;P2+%)- z(d!HJ1c|;M8L{ZAT@zKtFYwEFp>0O%O%TF})@bn?wDV*EMq%l51`!~hB871QW4s5p z1rWw4OjXa~7C%e?)QyrMN2gbWXt`Oe0BENHD8~Iu#DXEHZ zwCJnPPf}@cC*$t^10GI7L>dU&v(TRqHf$te`vv+r2%*1|(f9cgtssP6SRRG;Af#v8 zWYOIou>wZyj(74%%1~cQt!N~|H0>PDav(esVfq&8afo-zR87l~(R8CUS;j?xR>$Bm z_9smn18KD%%2E{WfwcY_%9|*>4(af)4Dw4D6#AkAE%d9XSdvbLfSUPwg51i5Y$di{ zL{H*?Jl}6C3+-nF{sAJkvaqF`M?yo0CqzV~$Dyqx3wRQiIu~%F2k|7RtvsK(nF-qj z2y-J$y?(|MWe9U4O!Y6~wj%_%e{}%l9r}hQq~Vf6tbjXXio$(|A8w(YLhG*}0=KYr z#-7*_Lb&f>+{>ZeO%~u5mf&CUxC7#$9OG?z2jiXq+Ykuj7N+>$ur(lzTbP`e(27J$ zdLN*cL$;y)ad?;TPp0 zoH@dDH`F^JK>s8iAhPuYiM}6fwBTV0c6PC+X8UEl(6lPLc8P)lBU+=y^{~W42&1sv z3oRewi9t1E%w~*xVcS8TG-C-1wb@&2|%~{0TS9a zv@U`Wpj#P`)vjy5lLdf;Wgsj!Ks*$a0o}@g?t|?f2m=x(mqXX8Lhz%mxipuJ;*dK1 zx^X;u7*#C+Rq=>CDwIm}2FmD=F67^PtPR(M^{nAm`ilgoRAr)Sq^imkReiQ$-?rRk2@OT`KFi2$fl##6NbES4@1qETHJ*C< zzAH!5@IygOoi&23&U(&JJ*=v`HvDR7R_ArWorB|pQ)<9JN(&C|1`oVtCW{DdbHPg0 zRhntEs!BR8glp(lXK=7+t;6o9ZVDC$k80Ple=zKJ)d|@{s>4o&>Kwx63*qz&0nS`C zbaNN(ntJm(DK)6KP#XsiBMa#@YWsPHn0L)S&KT8+@GE&8r4hi(%?kLV!4vwD4< zE_HC{Fi7tfOd|(An5mPx(eR>Qu&u|1>bTehK+^yk$S_Q(2-C2pMwsz}7I%$7MVg%~ z5jZDqqhDV~Z3uGi!b56|Dy@l82Mo;tjBrG?(aa49ZBu^}#lRCqZY;_71#a#iGo=RQ zLqf!Z-8pzP;87E%!czN*|gXivWX{H zAB>i*JNQg({2K*}Ms5AA2!*@&hK->4I*83%pd*iC!9lxw7GMsGSl%6I+AA}W(*cSm zd^)y4j*6ks=pz|qC!1+}c*o2Sk^(ZP!b-Ii$2D`1xVXi4`f5batn0fYT#E$^G3Uh?68^i}Serws*35c(S*i z!T+bdZvm6DDAWBXo#_lW3E^S{kr6>r$s`21sDMZaB!PtP$qbu>!A@tU=K^!1rzd0( z3>Vo0D93oon)O1nuGs|z&8nOQ6hSc>z$}p?mlZig0cAmskzH06WjS9}y>I>hRMp?z zBsuHzoZ~>c>i??h{cdl4^>Q3= z9(S1#e&n4}h@yGw2x|I+6a;w#pemvAuW78@9nBsYt;{aS*FToZ!^Oeb-J=tg{*mEX z$F|8gd7dzPV7Pm5yr(qVNR`kmDEH6q>+YUa85tRrZ}6LS%-q@Kk&(*m@v-vk!GTq3 zZ1$QHk1rhmo>}EmPk*s8Yj9wAe9df`2gFFvCH$&^%GhMd*n|jPr)e}k62Fug3x|q* z1H*ljfaR8Zz=(&6mHxJF6$kkev{HAatv`|&ja7PjO1;w0$lt?HjF!fvD+d6(Qf*|0 zL~EA(8#ZGQjK`AEiP4cV04oDSC7CA+C58eh=n7L*4UP1S50;Y3he{Iro}{FwG}c{C z3T$7_y3q;wF1OxN*}#oXl*;9iGQdYCx{IS@f^P;93b_ytisG^H(b&YEf$oaMRfb7q zx{HH@@LgbsM`WcOU6I_4>@kJ64Viy8WSTN{T1zF8NByu!^_sG(nVMav9v@K;Qd^P_ z*-CcNqHJ&WKE=j*09Q_4tDy*RiU4HQglSpVh)I^n7mrMxdP4vxiPn}K{}aO9QrEgZ zWnGK%cCYNy>QO~}FXfuNi%lL(*jse)Gde1ntU{IBTK@qNlo35MYaZ21xo@2GU}j#K zee0iA{ozXei(=X|^Qg0~lRPQYcgl>ZEv@QN=hk_E+b3oF1x|svw3)=+TGTsP+4KJf z^%~q54F-Qp-PqsyI#O95?Q5?CO}S8;7gz08w2!_XlGHP<&1}I&IrnEcm27PI-5xt# zj#`$r+@LnkwCt4mGgPaJ@if$<8?sxTR_R}qT_z99p3dHKi(D>iX;qI~)QJ42hnFpq zUdu_^Tzw3LNS}QqyId{$FV?xj=$!Jl8EwYVlO0E`x9hZL^taN|nw@gQjFuU)zNzH~ z6$$HbW!WO*F??=OkSRqw`$$WhzE2Rx|7?Vb#1;vxL=1NUDgovOpjY+Osn()$mC35J zFr#l3!nXimrp(GJ@@2E?hQdAm6E%F~(+Cn-_O4PXlR z@6kb7Kea{q<<)9UhZ~I%*(qH!T6&v=O1;@-hG0;3%MCBSXm(%Il()}lFqV0jw zTg=L3Ei%d+wuJ>ELj z?31`DvQu`8p5Cl6$qi3f&x_h7MEg!Gt?Nz84JoeJ3?y9nvkIOMiJWJaD~4oS)RQWC z%JZUXboHF3o@?>s(YLKxeOH(HP*ZcW+DQ91Pgjk6+0@>uZCPi;+54LJFmm;{%uG7D zxkX*gYHrS+C*Q6tOR_DioA*_nU*FQ)l$qHiN1C#ul3lhad&9EIN!iRHD!17dWyW6F zDW~ZAq|UOvv_wDX%474R3^_j~0<4YSrg-F#FwGizCM^ZxR4!2arLqN#b$Li16XiFM6;UfbN# z(kl`A%jP{LFfA=@iT+8=dkRw1Rn4$_;&L?SIE`L%?D(g zmIr#x%`2J@=#d$x%$Yi+`N+)2iNP0RLaen&R5+_)qj$;Bn&(TAGfk-0=X8Wb;1 z5>$FLxvxDsiykRo_Ex^!*SvR{2k(nLxU~Tf?p7Ws2P(bBfz`@^1GQ-67TAACHuF*C z`u+zT+$??ZagWSiZO!{rUft*0|*)Zq>uxm}c)H-`*RHy+72r z7bS6hdv^l&M;do@x8rWnxFfqA_dbm~yxVc_*SJHw9rpo^JGk3%f2?tn+akc;&$E8n;k84ypS%eP3+TxP7&8cf#JEXx!f2j{A_tE$w#P|EY0%c02A*HE#EA z$9+WO7I!=DqZ)VRZpVF0HewcBx@(75^9 zxI0lF{+Gth?RMNJHSV(7xI2-z?Hczlb~~=zcFO(Exw{?rmm0Tox8pvgaXWT9?$a7~ z>2Ak;M&q{ccHCcS+&cSWCwTU2jaz45>;&$=Xxt^cJr2)l+{L>c_j!$b_HM`hjmAA| zx8uH`aTnFYT@-#klzt!ezcuc{oy1Lfp4F7O?y{!VMT^vPv`uTTl&8z`yy}2VRXwFS zAbX26GVsKQS^}O$vMJz@PKsQS|@cSfzTNI2+{9x27Qe!orON5@9=oVGR45L}8!e;C zXraG2)*sK9S1uJRrMdF)mczyJMDO@;cQiV3ac|Ts@70rc9F_;3x!BVACl2xmU zV{TZ9l;ll+Bi%_oYeveEdcS1pSh1}*+%u-;6~_ug#nDmq)=Keouv9FoCGxJp z^1zzH(D-0wV02J*%d6l_gjsJtei`;!^R#!2wx4d$c@qfxHDY>N8Q&^M?j? zO!dTKrMth>6G;*(<#BnlWH~An^xGl}60c%qU}QLwNQu!2)REp^3A$K4&%6<{aC*FY zsL)$3N#HLk2pxvhDrk-dD}u6GY#Ax5w_s{Zgf?U1c``4>9&Jr`SyUKn#|I_tBdd_n ziwfd)pM1)yiiKjFc&}19tO6h!6iehWCRDjJR2&%Yk(t88o{?cm;9yCn3=EG|#Eya? zW;8f5+}Elf#)roS`i4tAt@5^4rKP(lA<{e`0b;L41ZJQjLGD&Fg+4_^f=D9VJ6P-+ zi_~7wUclPn(i*c_E|%>Q$y=d2s-K|lOjk|Dc;n0x0OSm{FtW%2Ajx4Lb);Clhi7u8% z2}Q;R2f9m9=^~jV5#T;Aj1S8nqbQ`)v2A5=YqY{a7tx8UJS<f6hj45ttaN4At#hBdn#vAn#5#P$#ftkr}BTX+^3@@ z(UtIxMXOX?#?%&7GzYbXs-U+dUaV7(3q_4C-vTX0mbke^g}6D;t#t^xK0VZ)lV6x81X=sl%QeO=Kc^b410(h7*Fd{VFzG1CD{B+qi+ zxTbh1qvg_Ask~Z_BSBGTgsP)DFA7y1E5kkViPnN#F7bQ3zJ#Lzo&IpU+b)Mj%}UQJ3KN=-70lgW{n6hB=HxE zFt>1?l>gDP&WhwqQ_kj0>f4&`f~u5K=VY(wDw$xfA&``|37saL8%etm6UTv;^pw`f zUCU}AuzJ)LP~AAmm^lq3a7#-Ujh7_YtUl_`LN1YgC_@EQGPOY!`LXqMaZ!;TDy|Xa z+{BV`Rc;6{IYFiCFIW#(!6FK=>kOEadnnmWsrfd-aQ zQ+H`%Xndnlz)hiwTxn2XcyD-SsgfJfhp%D{6PPT239-G!7MNan!Z4_gFL6W1pl4)! zm26o#KL_m1+qjCkXj`oBj1;GAbtsID4$3{2ps$j@{=m>8RP z0fIRk2bJ9(8^LoK!GmqM&Skh_#pn8p&t)LkGB#9uGt}-GW%yTO)t?=2WpAQt@vrDeUfG3Ywy&u0r{0iRc+8!!k{Mg{k^sV&$vZ zszwq&s$i{$l?l^)Z#|_MyKaN^(wiikRsRtB-!N5p#7|F1ZSF4CzWi@FiAL@g6KWbBy zW0$EAqWG$pQuWVcBC^X|$U@&5j{%CC4?7u_l}|W{P2;BeZW{HIu(koE8T~ytYTZ-T zanCa5g3t@(kF?c~aEzaEQoR$FGeXI+@52R#Dmg|@mSS#NOrs@!tYJrKrI{A8!;S^) zuwwx`>{x7p>805r6m!EMB3G-3TxE5*xi8}VPPB6G!7fwL6m|KkyQuodF*n&|E@Yu^ zO_%Gj;^t;2!?JR#lh`zF&V}I#Ya39SiMZ}~>$qnbb3y3!m?|9Orw3KP0?Qepx!l7O=yP1?;e6joKj;bHgAaSF4CzWp%jOg?O*F zDax_SR0vUg)m>EmotT^KG8eMYx5i_D;^u8mhGpelPGZxzxfX^etZhJPCgQrQtmB?# z$qnbxk>0tV{UGGn@L>t z5?Ia%3IFWam*B!T&?d*o$@%X$K*_N*P6X`u$jWp(>{!4KI~K6Rjx}nBP|OX3h+M5A za+THL<~+pve4C;iyG(@;#aG=$)wjglWS6;+g}yZ&0~9x}b}}q0Z*>xz#?4+Bp0Kt7 zrJ0E9F0hV!mXVu;z7JD{NBnHl>IJZz5lW7I3NA2I$+3;^Gnu~)ZE`G)69GFuy3$Mz z*IzuS2qni3 zf3KN87j1HkoZK99(_*G^B4EdLE6wDP9d;~WhaC&pVaFP^Ln!8kK}4=r5xL6haPtYI z=Jz&5Id+)}A&RfMi>i-C;N@n3UFJd-`qp?1P~0pz8J3l^oW!PaGXh}});6G2K70=A zrlJ*tk-(b+5yYbt}!}kR5g`V22$G z*kQ*SwL>W8hCxKGRuQ?%>TvU2i1+C>MLBkv3dx$Ux{Ipc9CMRh=0X{!4KI~K6Rjx}nBP|Q^?B3G-3TxE5*c`@SsNt>b^yG(@;#aG=$ z)qBU>WS6;+g}yZ&0~9ysI~kUh`#6bB@pX!(6`28fa2zHPKIUWt4?CmxcO@s zp0Kt7rJ0E9p0|#BmXVu;UZg)p-TYqYNRzng!LXbW68`avQ>v$7d$prYj**kk#N4#& z(l`;YV^&)b$ipW(~hnxE$-tR^$6l0gE5Tf|1yQuo? zxNfq`T*yM-8jk^rn@2hsmX(X0#HMlcJup0BZ39X(5!an)9rr9FHwpb&OcjppAUF4f z<&02rY%W}2sFGvkPl~z8E^{FZeQP`hC~h9;WLQ?7>?Aggn^(Z_gtZMQ%|u*x zwRPOHjNByj)0iq8;}?2WUpdZXkP%9bt%3_>w8=4YvN?Wz(_*G^B4Ec?$<2Trb}V3r z9ShiD#~QUmDCVjck*ifiuChAZ{3_zT*`_GRE>j^y@l|(G^Dj<&cxuG;aPA3{P0wfYMCFbq`s`Jf&vM8J-JSeb5z9ShiD#{zcPu}19>in(DBk*ifiuChAZd>N^kfw;?= z&Ms3SMDbO3QFT|$O?H_JS?F8iF+g$iB`3qO@_Z+;Y1}*nh9|6TKxro8y2GsFo@L}F zp+6FHlV3bp{TVE0goI;uY!z;q%V?8hWw>`W+T>UoCjxfdNp1%0uwwx`>{!4KJJzTj zLNQmph+M5Aa+THL=6uAvU{jQ1m#Gk<_^P|8dN6)2#4d9o3w>)m1}JVm<78M?4mpWU z<7Ph$PgvW4(oDp4gVu4+GIEp94`8bBh+m;wy&sk{LdmgqxWG^)$F`zwJ`tbk7Bh_# z0Xyy`Hv@Lqv49LKgbgcnnb7eAvmbtUTXIY#KLjgW(Bl8&H~wxb6UJ$Z9r)z;<_x>i^@0)rpH_mx)gJhU;AGD3M^-YgnxEyE?i)!l4I9{lV6OvY1h3D zJGQPglS6jcv49UKWxmrc!DyzfIquY!HXP}k)O?H_I$(paai>gnG zxydebAq#zLJO(Ik-sWUjR-Wu6HjSI-!0?2%4Jge-T({IZ?pa1|68amMDjZw)PH^IL zu$&P}j!l6JGtef-$jMt{Zd%MVP6X_DXl1$`b}V3r9ShiD#~QUmDCUMiM6Om5xytHr za{}@Hv`tZtU8X{a;;ZhW>b+xbvddh^Lf;yX0g9U&oeay$eVoLmaq|l>JYj7EN;47H z-Dn;6EF(7w{TikU$99mL*THf|C^_~b-mbz>CCA9gyJBuy%rs5}?0A&i4A^1E0(RK3 zfE{+MQ9FcUu6hxi-~>n6L*g)H=~@fe`Ed9{;aSvku|Y#KL@hv5lp8&H~wxbA({anCYxlhA*S zslu^MP6&g6_Kl~4mVdK-j~=E<=AB^gebo1E~$qpx6eNexzrs}E*mS%sTwMXn8KLCZm*B!T&?d*o$@wuiEoK@g z0(ShG+zi-Z#{zcPv49_^_dN3?!gpy<5hYJs(O^%V1rT6)mX`Bey5f#nkkR5g`V22$G*kQ*SwL>W8 zhCxKGRuQ?%>TvTH2=X6nigN5S6+#qWbr)6tIOZn1%!MrUt??M3xOt?LVOhD=No*Q7 zr-CpEYa39SiMXx>>qTW+E(qNhb92*NaAHqb&Ik$r?ASNp0z;J?BPYjWZrXLP!;UPu z8L-2S1?;e60Xytiqjm_zT=gPywTj49R)?Eyi1z}Uq8z(Sg=EcF-9^>kiMh!xb0G_T zYdi)hZXW1lSXSQUBsPtkc^ICswgIJ?i0eA7YvBlWS6;+g}yZ&0~9x3axyF{ zpKubJ#?9wxcx-J0N;47H{g&&~&-5lhFNwLi9dCxN{tT8gLc%dSwhF)6Dx*z~k(14F z-L&h{I1#X8Cb=1~!;S^)uwwx`>{z3A2*q6WB678g$W>N{n+GD^vu$c~>@pQX6kl~0 zRS(9$vt*aKkcGZAL2f?dWLQ=XIf+f<=7|n*8dI8yxb7tDxMvybCIj(#OcjnzKhq?x zdOs{@gpy-U-VYq2$^&)b$ipW(~hnrtVyzjFq%CXB-2vL01T~vK`%uRNg3t8w}<1s*S zbF-6SS-IFrY#KKog5e2k8&H~wxb6|_xMvx;N$BJ7qNZ?c6OQ8QS713KlpLE27Z|GK z*wx_V`k0#*GmR4gJKjld2JEn70Xytizz#dss2xHvSG|Z_ts-)j)#2tJk(z@LcX{od zU8X{a;;ZhW>XTw_vddh^Lf;yX0g9WqIT@CfCp(EvWzF*ohHG)@HUXd^cRcG$6i9d;~WhaGFw z4xyN^X3gp-PUClefj(w3um} z2-tBfxf!s-js@(nV*xwtSfh3b#a#6waUaot_kanCYxlh89^rEqM=so>_t zkTF8ZF@8G-kC@~bIk`FJro~L-M8J*{$<2Trb}V3r9ShiD#~QUmDCVjck*ifiuChAZ zdj^y@l|(G_0hIS=GbK}WT9`3#{k96tDOwX%2~iASQyla@>8eBdi7M3QgZ9r)z;<_cVm#$^%dOJQK<{7l|z9)7Mdxu#tHTu`4&T43Jy!?OL zZ(bTC*jd_#`c^f>x3#}@L>~Djt zIjTf+kF4_Yrw~umV%ZZEJRJ{QI`>E!_$>s#pA5vyKg9C|U*=P=&*3H%qQL-BP{M$+ z@<615feaP$jNmlkUldIjF{mN<3gxQ*baM10V*7+zkav#YhDTkE(5sqJMzb zB!oNb1Xaw!LKI+@$&h2zBykgcr_j{ zKooSgntUlMn~@3zGE_Fh=ZhOrwUQzIsx?&?`TKCW)mntpf`Zs*oEAGU^WWSR6wnuY zzEE%&oWrs3I4++=EA!3KM!|FOfH_|%*b|Wf5CcT+h5{AwWHF}<&X>P|4cDq$o*gNMDjypR`{XG`=MFEkg(O~i(7h9&zI;>*;w*(30k2cyKlhWGUp4g_JuU{ zeDM)GLWmtzA2H>8@e%VO#C!m;f%9cOJpUqEReadr1R2g3UVaN=d%jTcgLuFk3lBo@ z=wu*XJ|53E=L-cd!~+J1g86ST`BGNCggyfqDx2Z+#f_+1$&h~DnySy2J8*fIwFpI? zg4k!AFWWKmX?Fz$^u?Yp6zmI!a4bB4%Lmcg^M!(+#RKMiq2QItKnxJM8w!+!HSql9 zlkkCrkm}1W$-o-VYjPnz6)0h(xWXj|A}4~<#jho;>R%?gHutuCT|Xc|0U+>#>I z*AI=U@qTD{D)^x>EBw$HxgQ!L`Jpi@{Ltk6&@5+2*y^L#Ej_8{%Z`Ihy}IBK(+UmQ z{m(ZWkvU&@^%|t9=ZlZn5kl;!`iLp#i;tKOA?5>!4V*7m!}IIWs^Y``jgaAd;pLYh zw&x24---v!v2Zs8Kbj20%Ln55=6s>xiFm*OQE(i>udI9qeFidAHpAzO8&S2AA^n&& zRi7_6`1nsz@lrpEiB;i=$<#;ou|W8{8lh~$UHtnfqA?uTXtL&8>{ zFMenmJYU?BBGuOqjj8c|Xm~34p)o7`&=|QN8Y20jF)RGgS;(*&lexDBZSyd^$}Cf7auVnLd*vc8#rG|@O%iZDn9IA z2^r28Uj8M-_I#n>ui^o7Ec^`wU!M%b%WuZ>&G|yX=6JvWQE({2udKWueFidAHpAzO z8&S2AA-&L=s?V2?;qnvKBAhQ2#6IJExg9gV1yP-gZ&zB-BA|a&uvP&|s#`Bt7h))Gd7%8rB$w9fxju^?M2UjqF zWQUk}4MM;m%6?^+tv+9Vh`1nsz@lrpEiB;i=$<#;ou|W8{8lh~$UHtnfqA z?uTXtL&8>{FMenmJYPy4Yw~_*OpW(L!&AWzjalJ`#>oB95XldXS>cB!?}uhNL&8>{ zFK+2cJzq8*WX_d$z0sa8?B0u`$DA*``T?Y==ZlZn5kl;!`iLp#i;tKOA?5>!4V*9Y z;rU{;s`#+K3NoB8yzGV8o-Y)vjt9)Ka0LXPm<+_rPsj7k`9i_Qc)$Qr@G1tBm0v+B z7|2lB44*GcDq$ooj4}|#5 zUatFU75)D-&{0S?;qqH(ZAGRaHWP;d&D=T}Xc(53(OMu1E{g|DX{X?e7=T4|m9z=D zY)dU><#{Rf_Q@ zE8mrN-xX5`eOFjIeOJs1-<5XXl@)Y>tuCFuE9s>ZZ;EnvituA%GD|JhqyIZ8B_^z13<-5XC=euH7_^#xA zSC-QSwz|~0n<}-`jqYa(%gtyd&Fr25#+g#bt1}@@EpT^%`Km5v{7n@&^7>aCsV4Yq1zfL2P8j)Tg^J z^Ly?J3bw=pW(5Uw531=Aa~bkXBF^`%$UCQ_s2SJ{xl|5z8E#dd*2vq+dCh36iY9V- z?=&TJjVrziaC+DjEn}B$CR#JKx|I%ETIbv>1uB|Y&-ck|SN8B+Y4=?zr?{f!L08NQ z-<9*|0^3aV;i=W1c&@bjuC%MjJ3oA1yLQFh6tdZTS1w9%MazS(m=(S&E9e4SU5UxA zX*Mf)-xY6f8@J{hY1+%tN}*!+afnPsF9M6L+Jfxgjk+;u}UmnP!M}DW_BvQIK+CPfp~eC^#VW?#9jc10urd!mNzx%Z($@e(i9cgWj3W;S9ZO6Ukz1U44$A!O(l&xvz=CswC8q2)m*%nIKL zBln#klJA6B5paTc4>ClH*)~NVVmHpjM^c>7@}LuDh3|xs`%Vzacfza)I3c2K(~W%E zex{Ym#qNa=nG(mV!FXbA#3nnjgI!`M#EvSjV#JgZ=i8VM*_aO?=3N_k-(X7ITVNww zwe8q{KgOEnu3JhRFFydW`criMC(RTrjt5L-ItPNkm<+_r^Wymihyun%G&EM?-1sOj z7@*Uw@^Mw-c)7qTS7Iq~6vSSPn-WJaR!#=uWseI)LF@&9C}6tlm$(Cf&5Sff?d&oe z*{CdeINZxli;>I5a?`^V^o!}BoY%}oj6?|?;R=^xa-Aq~Gd(Ak`A)1!aYD<3PM8(G z6GrYkK_uS^vm)R`qQuc+w(|6d-8d5$r8uGGK_|=#-w7l4ogk9$gjo@ALPXQ|HS&dM zrNps&FRGs@alHBgq^WmtL_EtPcCbqfQ{s3PBc_x%B3@w;^Xw8sAtnM8cj zi#^xFOom)uRAHCl=1VucX0+oMdnlo6TrmfR)5E4{IlFB2tD@&%9@8X7xLIo8#hy=k zuC)8En3ryRSNLL&?}}OByK){~V5?v3S?amc?z>X=#U6K4NHz0aF)!WtuJFYk-xagM zcVz`#V5?v3A-m$N0e-ZXeTLi&hF1yBVa(R5W`9X=+6y;>Rpv2fG$S-?Z5) ziKJl8-jw>1^bd4)E0h}I6MPrw(u4oTp9@8X7 zxLInTqV4Co((b!r>XYvZE1K_$S>d~K9$jFoE873`Txs`Rsaw(9O(C1jcg55v-xXFg z-xagMcVz`#V5=({*%fCc@4MpdZBrfQ>}lE}S}9cQehekaR5V_F+!m@%v(kMe;)NEm zgI!{nipHxL(W_`ufB5u1BR^A{qC0^4L$qq^u>T}vs6xDa3SwJ@DEM7GV5-nw@a-V$ zP%i2V&urDlgc|%uF?p8U1KOJDoKwt0F0HDqsL_Nw~=Vz1Brt!=A%S%VHCtJ@_8ltRCy5^hB9SRE!btc zSd)0oY{gZK5<15fe)@8L`bMV)(l^=?NZ;t*)x`(~(^tE=O_3k*(WR)=1m8!q!+jrF z6MP@d3g5@P@8d-wA1?~|c+uV-Ma5iqOPlL$Ev9YS18vmF?z@pzQ!03MG^D9FKSbQi zB6hG#3{xt26(crKDwYGa7p-C_`)eUXso>>R5Zh8g!6)MZQ!2g+!T&(p6rIoRR)}<| z;Kh@%a7vXIY;~#l9cHv3YM~9~mI?;&Y^+sl*zbl6`}G=JejKgc_!Pu0qEyhjr`#13 zJR1*~Qb7S-foeBPDSvlW*LO6VL{`02~}>6237r%y@+ z1H(2GNvU`NHZgq-l?s=lviE!+&BphAWU26dG%I``^S+N#DtsTMRM0oJ^4Z6GSDDw? z$COeric)bsOGebm?t@m;&MsM;S|@zC4j0bU2_Mm`6Q*|gi1`p=zUm`-E}JJwRrs|L zts*)5w_Bfc?A{HLaHpwiY>FS%HkUUSVhRmYi0soWxlw1AQLMGQJ_|@1))aNHOT*OO znR|r#xL8VP>Yf~tUy@L^6@W6fRueBLA;j_=Tq7|C6 zyDvf_zdvV}Sx?;zK3sS~=o%@T!L_i~W_Z*wQZ|EYW4sw$QsA>E3dT~a`1Zyt&EVRo5M3i>Gq@Jk+6)&vM#^SzZHzaAYie>c(EM8g z*vQH7VNZEySh?B^VdaMKVdb?qgPR`N3}NMJGlZ2J!iSaD+6+7N>tFJRKk#2@&h9x@ z)Xpxmp1K))xDFT2Yz7}OWi$AQ`4D2h>LaFXhQr|3k!Tes*+0?xoMZO`5Y^ZWu8j)O zHBvT%YhkU;@J7c-*$l3Y@n&#MO>PF7zZigxY=%QT<(*;WYBPkD8^VW`*WL_ndSo+% zm8;DVR&EF%R$gl}tixuw6|K;m-QQYKJG;z!>SplaI$Suj8GOW)&EO;ELx}mRkC?I< z?uK8R(JD@||CseT$L^C5)z}QKjSA5+5I(HD_GWO?Bby-jr6@I@TtpuIjYalZ0<<+(E z#N-q4xbGw8Lx}mRkC?*V98{i*R*{JPQEN_)-HRcr!Cu!!h3FdD6s>SAti|31j*${b z*T$H=uBl1(()_Cd*a&;i_LMIRD^~;xD>ozwD^Deme)%WoDPJB|K9Q)jSA5!wEzt*~;%-mr4R(6I7a>^&8JpNCe0&hAEt410O?ck#rSvB{o~m=7W5t3F~1dq<&i zHCja?_OG|*zbNmFU|iF02^WNpr?FU zSh-?vSh-6~$y!v?_tpuIj;}8ZHhbOl2z$fI6??IR@Bb!{Z^Fn#w;JM!-X@O!ADHl3_fB$gqW}Th$)+)3MV$ARh(r18`i-byLUiT zV>7rmDn!>v$*F5$tu8r|#a7|5a2AcmP05-B2KJO{-3@cYp0>jG96TPtV z+D`)A^vILIuyVB%!^+KW3oB3EiBg59!|z#W<+ToW2dt=_-3zQJWi$A29WI>N3_fDY zX7Ca7A;f&uM@-oaAAl3{(JD@|-)Xd{}wy&ETd-HbYps+6-akhVWtKwKl^h^A3?{ zD_YqM?Cyb($Zt{E-P4LvHiHk>;li2C;3KAN1|KmWLd;iv#FWkOBwT$4t>Ps6FWNBV z*!>TPYHSAAMuq4aDVxEyu-0aH)G<;vgKJ~F8C+A7n}Oy}dmWqMaZhqE*>te}je0 zv0H^Gl~%4f3Xk^OYVnr2#>lmP`{PE%GDFKuyXTcEUdiN6E*pp zjklSE455_+ncbt0FhlY|VC)_bk)m{Gl~*U&i7CglucU)Yh+#GfuVTcMW7&*5yeq8y(p2R#lB(Q{1(fSe;-*Lb zY$2>%eIQrZa~VlhZpK{YO%Zk60pF+T7|QHMr;1nZRCWC$;5~r0DJrttVwv^H8`p-` zM$t+fI#-~TTFLHjAu{`kS3IR;Vxx%p5Tg869QZL}%6?KG0JQ;=Z$PW4&HgtblN$wg z?}R85m7A(taq(C@kKHGe^IU&2THr=VX?7iIiq3PrskQgaea+X+t&+pL6MrOAFKh2Kk6*oZYj`tDsA;f&uN35~qTVTu^(5el^{@Wmv9nbE& zAksVjWLzwW=dpWEa-NAq{AhN(>yOgxIwU*Z^``!ge+?n08?xisr5o}7q=b$o_a|j1 z!kOg$bbXHz-4G-Z85TN~M2zEOdx;%C6*kZlxmjnIE*KNk{-lHs7!%AMq-?TNW-RQK zLJT`)R)w81W7d_pli2Yso>R-iPO1GFcFOF*uv2C%?36+bJ7rddoibywFUj60Xm`Ec z@ty46Z$<6wK43*Dx8OcphYM#4h>w_Z%itsCLx}mRkC;+Gs&HZ>TD3RX|E6^?$L^gF z)p(xj+Ncm+BjxFqYhkUT@L9)5DX^}M@$*#I)a3J2n!g2rjXY2Nyr;Y~tX#cP7FKRv z4GSx;{Ysge9w~%j<@(kKmQs=N+}z$!HraDCmfQkye>%`+p;f;_L3hB4+S$Fpic&U% z57*(sna$uMrfdcuF&{#d-=V;^*v6F2@BvJmk5+M#{dVhMj@{)D)z}QKjSA5y9J~JkQH{;u+Ncm+Bh~Lv91Cl0hDRMEWiz-o#+$)4HMtpR z{xm9Y;BS;4_mp>rm8;DVR&EF%R$hBExapD25LT`>Ls+>Xd{}w^WY$I(j2+5H+s zhP$}1jYL*%9IwLlwP;m#+1~(}d>jJ1d}S<^Rx7cFHYhyyZ?$;ozeB+knxKA%0ufCx z1k%4l!3d2q1j6r7Fh-rGn%4Opil@9ItX%&NC8!*~LkTKRef=G?BYw-Id@p9lfe^C3 z)XE`VK#SgqH7e%pp8}cWklpzZrREUh)*OXLdzM^A-;MVBXkSgtNp@$VY95C6aJ1*6P0m&QHIT1GdnMZMrp$i=^6hA!M*A$< ze?i-ZXQQX0U5eJ#KLq(G+6vk=XeZEq7wtB*PoZ`3UWWXS9M6~;i_yCC`yd}dTSoi0 zDf4fK{BE@0NBe5Z{FzgY#>3Daj`n=Cu03lYUyJriw0EVlH|9S@@q=n^#|d!<#$Q{ z0oVM}U4GFsztP!U|3iFB@`d=4^=r^>K+A76=l7L=Vx~d(0a_RDSCD_~O=jdKw6~+( zjP}NZ&G^^RK8@DJ%N}ARH>14=?KZSep#Aon&Aj{3zJ}JtJLpg&xdZJswA<0XfcAm6 zn0Y@#yDx859Kg3jejnQHXm_A}7474#X5n*a4|}Tvgv;Y0|7Wy2IPY*XVIQ>5qkRSK z?6-ySRvcmEkD%o@`0z`i+*PL>WhC>_=Fl!hdoJ3-d(6C1vN^kkeP}O0do$YY$D6e~&^`-&FQcWtbt(GRJ9y7HcrWZCUOoNvL*OZ|g4N z)zeSC>tV+x=%-(|LqGj$fgdwd{8>Bmti z{`?p?#M|iLUB8QX_4HHk?018IXq*pY*N z`ZW{!>DM*zV?&BRi-AMDP6zMMUBs)WpL#dJj#HtZezib9{h}YtyUVxF0f%_=9lU*Z z5wD(p>U|Y<%z=LT_40|vV){j%J(iN6Ujv7D$2oYf?jl}2{nWeYXk&LP^wX~ei03l2 z^yAqSf8GNe;vMPWE#5`EditsNv#?`2^wTfa0s2KhUQY4n3g8g$KnL$+__MQk_4HHk z)376ge)`o9{cF(DkCv44=bwN>yk-Y)XczJ7>8IXfW*NTiI1W1;c93WEYX|&Ddwy~V zaESMkgLgjs*;%}L`l0q|L%e4kydmPSeVusZNt%A@ zeE@cBgMRw840`F;Hsoh}3g2!64)Gp#@Xp^wyn6bncV?Rj@jcK_zZO70{h}YtyG;x_ zQ-DLf%?{q;UBs)WpL$EMV-xh#uM?r4eyu}ZZcNF~Ilv*_Z4TbayNFj$KlOeCcH9X4 z^s5E>XQHJan^OGw0&s}8(ZSni7xC)pr{33K$2#bzUoYc+n10cZds6)Q7vK;~c!pb`h_he(F8=7{j+# z=%-&>p#L$n^rJt;pQ*qh-jNR8)?LJ_r=NQJV8?Xmr(d^2KmDQ~Yf}8l1BZAAI(T>O zB3?cH)cY;i5kWuwdKUU$MoT}gN%7|f;1I9b!FypB@#^WP-ln;RZ#(e&8Tv(@(XVH5 zfB$mI^M&W(5Aj}d@ScD_JBwFOKlLtwKii?7e)Z%2gs=P3kCv4DoCqA^J>%dF?IK=1 z{nYz;*s%@z>DMyor(au;m&a1_b2V^?_ppO^{x0Ix(@(w6!j5~OpMEWXe)>f}n0Ld{ z`0*j&5O1@Cw|E!v>glK6HQ&A~f)7xC)pr`{`J z$BocWzar?Lj+TDhl;Y1IaEQ0j!E4?{yn6bn_d(dP4*KcW4!q7ozv##9DgN969OA8a z@Lt+Qyn6bncP8{+j+TBMg?N&8^kYkkKU1)tcvm}kvvv`$o_^|e-ycA~$TPlQpdZiU zMpK^8odx@eH;!xK5r^&T#j7_zu1uj`lL)6qzkAIc+gk)vqP?P4zIy``-T-;dk*iBJ zf1M*&$!dz;7+rpa0cbK!G*8R-i#A;f0h$Y>RXE!moYi{%^ynsM{(6yz?Ef-w?m1IB z^25L1_^R|3KHsjoFAVwzkvByLMK@k99r@`uP4r!9mAn=9uY_DJ3+cU2&)+w?W)Kq- zO=$k3GCn2RJKBDJVxn}Pkbh0`-rCz8f1lIx{iAyv`M>JrZ-{Ox>W+QLilNGW#-9T- zwEVy*x||Zz9wqWA(H>FMI$7Q(@);^Gco)uv7(Pzq(tD960M7 zJGVo=33nr3F!0f@AU_p$E`j_vkn4>pGRFUR#CQDqJ>;!t7=Ram^Qy>0cJ3kh3CRx; zxr)zp?9*F-^H!0!qMvN$VE(!zjg)ad9`YPc!$-vq^`riLSK}`-*IV~DZC>OddsY$W z?PebF`yt=q#96(YJA`v-iu`)utb2#SCx1Q-`L>gcobm65e23%j2FT~&)hO~uedK}W z8%}-l|I5S&Z&w;M(an&LI`Xd(2Y)s|d(;OfDEv)$x86G7+(9|s?a+nz-wk;V^UuTl z%_0xQ?LN#u75o|jloPVy!4^IN4e-Y+SpKk>GTe7ITTp6p3 z_x84RM?Ix-sc&GcQYsfJLxt|ak>S!=f7IG7X(@Vuc zL5qe((5(~AL3$??_KKitz zbg^71Z_gMh3#}4EXO=3tk%3`hy^f7q1rKCI<=G@Jn7Z;<|3I%!jKovS<7J`Hy{4!* zD1p4BG>Hi+stcp2ZERwwQd}i%rEJ=M_J&6)rMAA|@wQdt1A{%YBoq3ozc|((we?I4 z%SzK$%4S3y9}~h&x+ut4xinZ*3(y-KtVC^^#%-0-8tLmj(pDbnDOQS6Td5zLvcE^x z^2)3*yVI;-U#(Iq1VEcp92)2r6GjAB9@?}vgS={NENYXAF(ie+7^yvLD^_IZtQxOK zm1*lKts3tW=;Cl+d^s@OtFX<`s#WFEYF-Tv442rKxUs8t3+4kUPzqm{=n$DbP5w#w z*FPts!xm*3qw1c2@{juEpJ~L=snV(?)W2a5Gr)Ek2aH%_psSk&^7vZ9{vFB~`C-ea8ML2pY&&J{eIPV$Qe#Bk>R;)*R7w!j*)W7HWsI#8W zBiZi5g=k&-ufuxAKU#^2Xm4u5H5%GY>8GTlrf@xY*t$@!) z8t0GKUy;rmb_Auisv0y)4l` z56YwB9@q1E{XJN}4e?{#XgBlln5<3eU#AEqKkL-Ske^W}{#?)2yv`8ok1p5CWT9!- z;gSv4vHg_{B=z5TxtVz*)^9hL_OaFWOy@V!C@lKV*C{T)$c$5uxiY%gSMBfQpVB`^ zT_k?EUe)L155vLs6&Y0ZpFh|9jp=QI{#H)J1m=PB)rYJ&Q}ocbvYFx9<<3=qwd~6D zN>y0oXZ4V2`RLAlcgp(J+s%r*u;Rn3)GT z1&Hg}=A^@ZQq$iZVx%ACCvsrWoqJx&`ga{^D$=Gp_A5NruB86$ON{hokmGO}RA&bH k$n!&$CvrEr{;_k-`iq@G*Z%!d)}OP&tRHX|IG54?0eopHl>h($ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingmath.pyi b/venv/lib/python3.12/site-packages/PIL/_imagingmath.pyi new file mode 100644 index 0000000..e27843e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imagingmath.pyi @@ -0,0 +1,3 @@ +from typing import Any + +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingmorph.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imagingmorph.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..9992d4ab5737e81da46b17a073b5f873a2a6e308 GIT binary patch literal 36112 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 E0qHrs@c;k- literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingmorph.pyi b/venv/lib/python3.12/site-packages/PIL/_imagingmorph.pyi new file mode 100644 index 0000000..e27843e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imagingmorph.pyi @@ -0,0 +1,3 @@ +from typing import Any + +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingtk.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_imagingtk.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..2f17f6e4b6618e9178225f4a59b7b3151405a104 GIT binary patch literal 46352 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 Skx0ca(y`%aPOFdx8vhgKtiW;r literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_imagingtk.pyi b/venv/lib/python3.12/site-packages/PIL/_imagingtk.pyi new file mode 100644 index 0000000..e27843e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_imagingtk.pyi @@ -0,0 +1,3 @@ +from typing import Any + +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/_tkinter_finder.py b/venv/lib/python3.12/site-packages/PIL/_tkinter_finder.py new file mode 100644 index 0000000..beddfb0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_tkinter_finder.py @@ -0,0 +1,21 @@ +""" Find compiled module linking to Tcl / Tk libraries +""" + +from __future__ import annotations + +import sys +import tkinter + +tk = getattr(tkinter, "_tkinter") + +try: + if hasattr(sys, "pypy_find_executable"): + TKINTER_LIB = tk.tklib_cffi.__file__ + else: + TKINTER_LIB = tk.__file__ +except AttributeError: + # _tkinter may be compiled directly into Python, in which case __file__ is + # not available. load_tkinter_funcs will check the binary first in any case. + TKINTER_LIB = None + +tk_version = str(tkinter.TkVersion) diff --git a/venv/lib/python3.12/site-packages/PIL/_typing.py b/venv/lib/python3.12/site-packages/PIL/_typing.py new file mode 100644 index 0000000..0a7d87c --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_typing.py @@ -0,0 +1,53 @@ +from __future__ import annotations + +import os +import sys +from collections.abc import Sequence +from typing import TYPE_CHECKING, Any, Protocol, TypeVar, Union + +if TYPE_CHECKING: + from numbers import _IntegralLike as IntegralLike + + try: + import numpy.typing as npt + + NumpyArray = npt.NDArray[Any] # requires numpy>=1.21 + except (ImportError, AttributeError): + pass + +if sys.version_info >= (3, 13): + from types import CapsuleType +else: + CapsuleType = object + +if sys.version_info >= (3, 12): + from collections.abc import Buffer +else: + Buffer = Any + +if sys.version_info >= (3, 10): + from typing import TypeGuard +else: + try: + from typing_extensions import TypeGuard + except ImportError: + + class TypeGuard: # type: ignore[no-redef] + def __class_getitem__(cls, item: Any) -> type[bool]: + return bool + + +Coords = Union[Sequence[float], Sequence[Sequence[float]]] + + +_T_co = TypeVar("_T_co", covariant=True) + + +class SupportsRead(Protocol[_T_co]): + def read(self, __length: int = ...) -> _T_co: ... + + +StrOrBytesPath = Union[str, bytes, "os.PathLike[str]", "os.PathLike[bytes]"] + + +__all__ = ["Buffer", "IntegralLike", "StrOrBytesPath", "SupportsRead", "TypeGuard"] diff --git a/venv/lib/python3.12/site-packages/PIL/_util.py b/venv/lib/python3.12/site-packages/PIL/_util.py new file mode 100644 index 0000000..8ef0d36 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_util.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import os +from typing import Any, NoReturn + +from ._typing import StrOrBytesPath, TypeGuard + + +def is_path(f: Any) -> TypeGuard[StrOrBytesPath]: + return isinstance(f, (bytes, str, os.PathLike)) + + +class DeferredError: + def __init__(self, ex: BaseException): + self.ex = ex + + def __getattr__(self, elt: str) -> NoReturn: + raise self.ex + + @staticmethod + def new(ex: BaseException) -> Any: + """ + Creates an object that raises the wrapped exception ``ex`` when used, + and casts it to :py:obj:`~typing.Any` type. + """ + return DeferredError(ex) diff --git a/venv/lib/python3.12/site-packages/PIL/_version.py b/venv/lib/python3.12/site-packages/PIL/_version.py new file mode 100644 index 0000000..963d8c9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_version.py @@ -0,0 +1,4 @@ +# Master version for Pillow +from __future__ import annotations + +__version__ = "11.0.0" diff --git a/venv/lib/python3.12/site-packages/PIL/_webp.cpython-312-x86_64-linux-gnu.so b/venv/lib/python3.12/site-packages/PIL/_webp.cpython-312-x86_64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..11cb511ec1a0c8c4693512d734e04019ac1d0164 GIT binary patch literal 84193 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Η%9P zALFY3k+9c|dKBeJAl}0z51fo*kl|%^V*KX6Onb--bjb%!ny?u05kh%B$7Qp+E2^2n z2Tppi2_HDQ2kduq4J&QXVk4i=8No5G(FEfp`@@Gmcd;>t_zW5z!c{`be2#NI2RWZ3 zoG&Beh~{%7^Er&to3yCzx%~TbtrYS^Slg1D>qpTAQ`j}Yf35L+^z#+L&xAR-GuT;U zl-XJ&)4+$PTaE3j@$wOgYl802D#E&7BosNHTfm1di*aEVnu+EBe{!7V&+;dlNznm> zq$k^miz@>P5tU|G{tM$q$Bl}c#F?TgK7?uln27UUfDgzJI3uO-ndYQq6L3slz=a68 zSTf?Sgv(QWvT6C_;*>ygIrxr5xBL>Y;Ro(TiLC*)?YxSf1fC`ERGh0oU? z4eoZLM&w0$$CH6W$jIRmQBYux&2;TUT}#D=h23aKI*l$WFwW*ixSq+Y1Pp;}V`w)8 zTIV1*sQIvNq!!KKF3g{x zCu@$9ICB;lM-4lTy6`_5As=<)*ym|crR~?5m~F+-Zp;nWnT980XC?G6bJ0|LEC56C zlo!Au%0o0wP}Hfww=DPWg-$x#s!FTs$UY2Xa-xn?%E;C*Y zPCGGD)|@l>m0d51)E28|fpVpm8H7XTMv5|w%Oa&H8J9@8F$3B5ZJt# zq3|mHjlx3w;l4ur>A}{9mCHd}*u1uN$%^IqLksYe*dx1H6_!ZVVC9m+#S0hax2{;R z6u(-UUp%C6<%$)ps*k1xq!q3y88L6fu>6$`icj8eF?X@UE9EY+WEEWm9hPDfX*DOh4)x2OJa zp{fHpPx@D&`kRGry}O0_6NW&;4=t^W7Bw`Y9)&w!YK|&WzgzVR2P~hDYq_GSzjiop z!lat-YL=7_GD)fbp*&QhO3!nIloRNCr?;|c* zu_zL=sG()y%1A_a9s7vpwJojqD~^yR0G_33Y*?veQ>PWEV&}hLZEHizna$*nWoj+7 znZb*#_#*s)(Qa0#xN3P5{~%^03R>$wRodMXoTa*gk?^-TRoyivoOPxK5Zkazwx?ok)QaYgw(*@h6p+=0yJ>s)=nWk+gcfV5Xp**RY8L9^PnlG!6WjJICGM>LLiGPD_BeY;y5Up0u1*ZL6Z1RyFABC@2MY@6O5 zB(3vR+cBGMd$Vs2Sn$&mc8u3bx{LMYuh}tHQh~S4T6rDd7wwp#-ZqT3A9RE6Io?3f zw#%v^)AUZZ?LPJhul4T@uYrhKq8&5Y9?@dQw3XT;MicPW*#kJTYP%nc;~3aBJ52^S z*-nL_VprQqCBW8*CCP7luebYxBkMuCFKsr)jy3Ic6S$pr&&jqwWcRmXOB<>3Ri-@% zoPkmRlkE}?@-C^;gnhilkCXnO>U z$@XLxv+ZfB!B7^}_COY+?LI6nw9{CWA)rvqk06XCPB-1tv>w*}j^{u-w&>eb|tCR{bt*F_m zMyWL#?P?@S=PSkLC{?QM>Fjm1vPY>>L|dm!nWa?OqfT*FtC5V+Bk4HzNZ>5$jo%!x z$FTBOI7!7GBkz8RLKE}Cdfjsu!z=}Lza2l-cfdBSm^you_a2G9QQm+Zn_~wG?NQd6 z0>s7?@{aOaYcW~J0l5}ab-L|?5bspZ8#{Kgjo%H3#Uy%Gg%WUxF+`?$H4umFI3VnI zZS24iX_p|VlXutyyjGvX(%}GfXxFG{XYgAOZ}g$xQeK)IW!wF%Ovq1_H1sJ{!K`R7?IgHA-glXuv;zDU%qW~!W89QN zMZMNT>rFIBv0n1X`~fn@`U!`W0;*YEprpMGZQVpMABtPS0&rShYtMQZG84Zl6EQsE zlTEva=y$i>6J>x&Z8EBf_+c_?|Dc`VHCrJZiRkwpGsCAV8^z3AY(Vr` zZyMBMD{KMNOtxdMv{S8h7z|9*1HMl|{CO8^KTOu~vPJb?XD3;6=oBjts{r+R0Kiml z9rC;%Aim3J`#Bv7FOhgLw_!!7YlY`?Rn}cpr#@kC{}2#+hI?& zoS;3Wz%H~}S`}b>L-rJJ3NZ!t6w9f$@!xkLl(^MS_nHUjr@4A$+q{Pv$lg}(gGdTi zyonI9njhfgh_BPwR6=WZXehIl2EM#irbi3{$?+y1fW&PgF~-{lzIQ1r1+q%K)@xjK zy8{@AHM9xSD(bL&tmTy2B~(7miecuQjGW3q!-l7y4q=&R|BRStVzpRni=J6uuWy7I zy?`N)Aw|z@LmI-mhD-)gb+S%EXpDC!l_3oqmssmp8|Z)}>o=HbG2Z8-O^g>Y$i}Gj z16Q8)i|z!$$%64e4~KJ=hfPJfk0O-2`^+TZ-JzQ7hH|RO4Z7SVrK2;djh{?rhz!JxLrlccL}TJ;q7w8Y$Owpz8G{&RKpmNXz4m$B zbFd}OH($PRzN)+TS!eIH*Is+=wbx#IpMCny=87nlI09y%)&!jIiw)(c)KXb$Fn!Gg1qDHBrzvvAJ2vqK)D-wiGkiB5gK3yMU9 zXMGpLW#78}cz$rb>a)95on3WMdwur!8^PySUfFljRon?ad_C!=ld_K-wX^T|1AQl5 z2?MW7@^!H9m|rH&X>T}4;S~U`g^JV;(shxO*Pp_j<+kg?yf`NN-J_(d-FE%wFBN$N zO_C&(UqE9*;Y$764lD7wTck!Hrj_y769o3tp9hwjk_1N)flP5U1gRo^Bt`4^c1 z!t;^+=j~Vnhdypb`s#K9(e$EVaJuA76JTDt==2GkrvsblUr`V=l2_26a!p8kwF# zaC-J(Z_PQVAozYdS%7Euy|Rt!qQgON_r1RFm$&xyU2^~0qwhlx#$dZPdpb>k*1wXX zH2!5@K7d}=y`N**g`HXGY%;$x*)p)MM-^E`9&@m7(|^GOwgnL0O)RHYzx(I~3{dOQ ztvL0`7~uX541k|Kz>(}{vbWJ-m@PdBo(E`1J>c1!U_fB(TbunKH|!*H6rc}eSS@E) zF2$4A;XzMH7`?Kwp>!Tu*Ja<6$qWd(r*F8QAZxR?WC+bM*{5$9*tup698|egztbv~ zD)U_&_u_XO-FBtC8Pj&ZRVj5_?P{}uSiM+nV7l-5^HqF;q3P8t?RIgY;^Bt#5Ra!;9XIf%MCWF^^poW6fbR9w@3Es&Z?;y47}T6Yt>#OO4wY4Gx1~IzdbGh*PgYhu^3VC= z?C^+B#04U+u~Y-ofMlss>`(=Wy!I-12qHjatGdsxcWa&MQf<|%`{M3thqIQNjS{k2 znaU}@0LKyGtG4|GG)Q|9?j?G43TT&_D`4QY^=iW_*1>_wz974jJhepZX-mc1-V*3* zHA`qMq8m-?gQIg^sfqS27du4{Z}fJ$tqRelRjD=G?HV%p^QagewLSb-%iUtlXXg$j z4UvwP9n*vp>c8~Z=Y&M%inr{ytJg_=(4ZV=0l0EzcFX3CD1Kk1#!$#the#Fq7@wFd z__>MU!p!ujM{T>}*O9dBEfrgxDpk?1RqNG`msIH^A0r-jpk~PSIZ~)+(J&h5U{_oSe+gl@{c&<@qc- zrD9_lt-V;OE-ZGu+1w@m=;W|JIz2r#?dJxk3loKjsmYE0)a>Z=*!HO_z-=&QU&mht z1~_U-%$wY6m=il@cKTCqjiH&G*}k1{4el5%j80Q+OvEeuNdaZIiRQ7Xl``m>N4^e zsujo|`eD0P1>Z#%njnzEtTyJG=r*W0DQr+dy&uI_>T{JAbro*aB_RM^(L*sL6%pk; zF+4Tt;jMP<_Fx<{hg*4Wp*83=D#aFhgs2M-bhM4N`b4QLHMooOp~Ho8_t1T!5BqkE1M-5G>HtJl5uDL?~eh>14A}$#+^^ zNQn_Dss?o~)xZfTC*;IP5$np^2lEBxL%G^nmBs?Pk~SobK+>2Z?9QmH7!b4Pk zCZ8Lf92p%Ets@q}AS@mzfo>b4X06$3FTu#7O0so{O8P@2!1Gcok}UN7IV^yZrL$aZ zA|EsbHs7=jm8}~;B3mCovTZbkMZ49xE4%^wNbfvY7o??0rRiTw?e+8NbtJAPP zMQgGIw2R9X(W~^>I%bIsOux~s3jr(%Hr>fxxovdPpB&v;Kx0)KWR~!#%90Wcpo{`F z#JtH-B333XNc)AUDSv2U8;q?bX|?mgWHw`*T{$#3B6Y3oD`Mb+0Xo-2_lZdl_yyfl zW#f=W9kdwEvVojq%C!jfCex{lwjgR!K+M|*J*NtbZ3loFl?6=CmMh*~9=Ucvcwlk1 zxj=1BmbK{YjkrIr+@~oDDLn2%q<3uAh`0#r80M*D7kKSjlW1e{18GoNZL-d|9v5u( zR;3$JU1j(HCj*0?%Ypu1@>jddVXZVXnV-q!U^kDB_+z86r7;1iQ+EaPc<3Zsl!i|k zo1shDAjx6sBK5>DC-xl=jL^P3wUBO(`QIX@GS;ymVf7je@Zv(7v)ay}AKTk#!#f^rAVgPGbpX%yuSL`^piE3Q@n z1BJI>3A!0`hU!&6R+AhY}phrxQ z;VjQob?)QpR(&#rISQoU2S%u2n%{<)NhWCEGg-t00o!rFvL@zDGAZS`e800lpl;O2 zT&Og_rB<6Yu(yJ}IzFreJcjg>Vdh`6R9TSXi8$7X#D?K!W4^k;T?%6@Cc0ogMnLIy z7*oW)8pPxe6vJ3xy~8R5oC;_S{5z)bM9q-;xMF&uFeo-RpmXQXHfo_MLLii91~58UiD zCxE%WsXy3`8fS#1)kJ?L z4J2cr_LJ*;Y{4hZ?UjnK@Wgm)uqO7^zQD&@c>=Fa3sQe{FQy9d4YbB4k~9iBbG1#9 zj?Rt_PBUWiBKh9DOuxF$MxowZFShogQdOVqQ0_6v2`2;QY20AQIjEJGB|nDLK}2(U z6#913O-l#K?ldd?hae0U|(PckyD6j2R^{}L3OV- zuI*MaN#_oYGBF@7G+;&e^UZFnvq;mGMg!Ui3Y*NUb^{YOo5WGIiLBBxTnIJM!gEju zA-SKK^>+;79kE)ovCv;`cIU`&(wP9J$LQ)9Z`G^>r7$F&`p!c&Vu*$>QO34QkaUnd zjb>`VwFN64$_N=(D#g7uvf`zF@Ze&isdFXdBj2o_hbIWiT%-#?p0J#u+JI zNflm^J?HkJF5hgx%ZcKNHP+*}Z(#%(mT4h1O-^Jg;uU};$iv9C$(jD)O&9lL%j4#O zP5qlUZr;3U)8k8kvwhH!8>N{4owvDh3V139e&K? zLHWhj=@iAsKz&~oJO%+C%~h{6Ygq-7U&_Y}zkDHystoh2U*M<3XzI}>TEE2J1<{$X zCNK%6`5a9nYy^P4F|%WIvVfZF%!tPdn4Qw*st957iDN9Lng(I?+MHDuAIPP@Qp9}Q z4JV6bIIzgt(sdAyyHU^If(zIiWv(0HcebaH%aacHV{_x&jA6qH?GNLS%}&#?mS(Ws z#zW{QSUfNx$V)}W3>2mK|9zkLYE~O0MA)j#YY{Yc3>!l|hSSD72K+{nk*HwTe5VI;YrjD?`Fz63tS&vQ4 zOpcJsFiy5)@xWwWyCiXlG!o1;_|3#K$4+Go3lOS#_7|}48s3W*%0auR87|IPv6IE4 z)snH42h@m3?PJixa9r!w8{R5+nFuOpN}xHbpr)d>#0o9+vA$#zz?S!D z*{r`1i6MdIDa5o$AGaZlCGqOcEwEG4gN-jb-c2{r_|#*UnpplJ|3|bDZOFia%GkuV zndw1VAPk8w^>;KLMq6d z@l`8Z-lX+}YR6|!8@!)tcK{{XDd<#rFdkDsU89u-S0lhPg)BpXC>idun6;3PT*fEq zq9KJwLL>^6v^`q3B;GI6Jn%N5MP=?zEk#U)y64f`^OrkCjFkxz72g9u*`NZP358P8 z->W5-*^neUHrhas%9{$AXtUCSo&=|PU4rU_wOer1>s*I5@&;5&dj%6@EcTF(o3))y zG+g%x)!vQvdn*;|Oi`Jj-p1oxWUYrh3Kf1=Bl`266XpJW8fLtlMW1${*&k{2Rd`>D zu8cQp(bF9$XVDD~G;7g~4wSR#hy%@zX>=w4S@cQ=nvtS|UwTuEUe@{fs&J}9IBWEt z6MzEjp%}{eBW1v+98Yo<4cN5H*c6nptGA3@A`;~HkX8H>I~a~|dWFf((gH!DFb`zKxYf<;fo z8`E?Fqea6Q3n>_Jl7MEcI|Mn4{@8(bUG+#mf7q>2At ztcczmlwr|tJ5ZiZV5RGj<3Nw-g&#j1B(rK-dt|(xoOs91RrMcSnY)cq3$6;gsf_T2 zuIY0A#O0i|oQGV_9-*avXzUHxw##xF)hW%2*Zj4Hzv^n5d%Ko)iz_wv2O9me02C&l z;#B#+QqqkO(j{?92o}#v)qk;h1(!83oz+4YB+Q~l3>qv>OF|n`=Et>`-wA4KQR64X z_4C(J+VGWeIW5^y9=>*vP+cqGh0|qRw{EyT+#__<$3CNv|3X6)`{j2Wvb%>|<{s%G z>i3Wc;ab!Xy2qlc3QE>y)Z#BXGZ*Q7nOYv#!y2M&i~iJs@)o7fr_hy5jyyArkGbpx zi$3K*GZqbFOjE93*K9`EKaR$ewGOXv+|CK%@!wHRK;N373leS7yaUZz)GC5hl05o* zSnKfVfCUz%FIUl(%v5UQ7oC|f$1`WW?rDeOWv`{t^32nEIttO{c?Yz*^u0&A&;S-a z>_B;oendg(_4&nOq)Hx$QFxTseZV_pME;JWs0}DrA@)O`m!r#a{5<(H-upE73zw5U z!gNH(J&N(;8iL~%U5hv9=}Km=JhSY7;<6Vk`c(&-v1k}$Zyz)h;>VhCBMu0l>sT*) z)>e*rhYYqwpJlwuEsE1J_=36j4vl^x0Lio97w_+rc;T`t&{;cl(Wqr{oE5?s`kF-- z9Vl|1#iBteJ?fr%GtQ(`R(hHjqs61| zIAnLfpi{pQo!Tc4Ib1?Vi}k6-RT8ok0j9=&q%fAOEQLfQ=zWCM14nz`N<0rbp(kr z-Vcrh(-9;R8rR|c3c60y5W2&nn;j@;(U0mJ=!MjYVf+=BytaGN*vSZ)d9%LGd@yIi$4`4 zqwgux)#uopd$~r>(~xpn{MUkHHH`+X(PQ_CvX9pR1ECT3h$CdyN_~YZp=az+Gto1I z);9127{YHkgjZW-Cmh17dj+Ux0I-3nw~XCZ#^bJx-B!k1T^YN3%Sh0i-;DKDVzIPC z@SE}CsS*aYjQ5nH$~vlgyeHWsNtE$^bR?LLAQ4INZpBs75CioNt~QRmKLADG^%e~Pt?MTa6^lc85kK;_SnR*3p#su%{P8NHVvk-Dv`FNM{)0?sA zy$+PO=zmsFvdJo=?k^H!n0accL!r!A)IPG1Oinm64zJbQj90Meqyx=ZG>oygr}O9m zy&GVDOrvB}S^QatHfPaS1*|+Z_*8Weq~Se%!uca+xRK`A*aQHL>S(MKKVN<%lH25iQC`@o3hr3;+!8$(A@W%wR(_;&W<+vyO6 zB2$_p$XV#knYfg7bx+Qj-kd!P1uXo1Y%sUs8J^g?e41%W5J?fT6;$eqmsVMOIOJu z$QkQz4nW4_j|QNJHTt~(B$%SV^Z|Fe&U9n_j785;kTkd?i~p|EG^YjGE&3V<%3JjG zBfv-{Y*ZtBSVKswMc?B#f7>O@S@icEC~qZvDF6xH=DKoJEZwjDMf#8Q3&Ako|w* zHjQsa`p;MCtjl+Yt8&jkm&sV=zn`AyY}KQ0(9i}l8+x8nxT*Ch-=&PnxiyAoneiOwBdk#PKyzepmBrm7+TCebD7!Evh0$5b|8kA4?4=DVA z!cR~*zC^~?VTGTi@WTq0j>A=V#+rQu=YEUxSYY{N$o&>Pg0Pg10Be z=eIHZwccGZco}fo39)N9if4t>pXl1%o*ra4dg~s8Nccg(*LWBe`=jtffS-i+%54&O z{U`~^6Q+GWlHqflJ_6#Khf?5wp906(hhBd#8t-(#lghmSaH8|@2FYZf?IXh^Dg7=@ zf6suVw=cT48Qxp)!4y32NrB&)f``6Lo7Q@HKD@qa2M z{oeqd#Q!H0kA2j_e31V;CH+z82TAo^p8|h<3j8vLgP-RK;eW35(`LRTI_FdH+>ny~ zX2AOuXE-23JBj|gQ{bOXfqy9l{!PG>=zl6D{aUD=Bzn#OJPFSmQ{dw%c=o2i4>BA} z4cag8^)$Y2OG*EGn*Me zOH<%irNCPZf0-Bme)PLj(til>BsxEqlKwL(>1p96sb2pxCH)#SVN$s#1KzJ~6b?23 zPUA(tw)^Y!;cyBbT8(;b7=gx@8Bgy6S~Da3ORD#7(j<4Lr2mg8@J}nA2VO4-j<%vo zExde(vyE`x72bcXEa0_IyusO_V_ooOCLOF=Zu$$g<{VDkD&rg=9Dj?K;^=52I!~}X zurWCW&bet+aehdvxQa7fIyiAd&haaE>-AM+3ElBoZIPsQ02jSW7kYm2Pb~=^5KRB>SKhs1>Y!4(gB5xve;BY{bXWp;TXDMZ1Xu z73h2;&mXyRa&QL@qVRnjdf|_bYliWWX@CklaF(oO-L`#dXmC5ucpRg{k_&@FIQ7eu z6YQv7vG=|cPxqi#yGq3 z=5o(TYq8^-(vKO8@{NuG;PVEkPI3?hpZ&ux-rL!*@&c$ksDhG4kNS~gaU$nt3P>>O zDKoLxNC^#}+8{~!1%F8yZE!i@B6{){Q`>XaSFCDaBc%&*7Vp5j7q6p*(0i8r@;l{- z9DWx9Ftst1`U-C3)!A4Qym)FHkoSXeN=L=s!Nmz!cp;eDyoLQl$-rbk@7Ck*hN_!F7wRyDb*bCv5nz~QWw00yQ$iq9~dIYeZ-spsaR9*1i zG>WsM7h?Euuu|F)A9m`fJJX&OVxl^Xwv>@>3NU_^LxN{FE9U4M=Am4=!O(W@wHM$(p;0?4_>v&-uVF$;OP`GHZMiZYGTxfI$=yaFz z1{@g1cYIRMKzX%+oF0deEq-FJ-G^^{Ji}=lMM|i#C7fF|fH4ribPBpRzysnytI20= z3{)0%$j4zfp1YGAGWJUji&HKt0tlF#V!c`dJvi5peg?QS!90iK zPLHY1(R=bhfb&HbfV$YAV=DEQm9RaUo5R7f_JocJ6)x%#6aKEfWksI2hS z#!WbXf4@An@Bz%b!bG}D;`INP<~RO( zTQ#YMyJGYk|1_2NuMr{oEx-BiEWE=KY8Ws7FyP_*&kjpM3%AEI#LNFZBqv|8k!gP2 z+z!DLPjB}Y{vnc)@89y9A9?2y=KrtAOY~cQ^LOsi{Ns2QzWT#Ah(Cn?aQ?e|NpRPc zgz*hIMz@838_VzQk$m><lKpV98G6|$-UkG01+yGqX9Iu{OZPnwRG3wZ%TAY%kQ^@nj$7n-a0&w zCE=8}D&ymH#nb*uO8y5l|Jkv1@Ob_=q~w3{KM28RJH;gT@%(R0$$!GVlK#G!^C6yp zRP)E{`RUI}{>xq~q5WEZ3v-&^o?G}+5-eQbHHU=U_V8NP1N31ic=9+Y;c!g;tXxY< z_ojOcM&Y}4J7VrwfxZR-{hQpMCScxiWU{Lu4jy{7l=QW*aN$Y3d>XEj^50DhFSx3) z46$2}#uqBW)nSQp;o2xE&yqX$8<$_|AO9;f{+^@x&(Zuf&3T4~R)0fy2_m$%Y~|ms z`ES?!_h|jkL>i*V@*DrY1Q>~^F4||G6(d@xBlLtMS^Oo zep1uDb9+Br_Afv7#>{!^7yH-ovvI(;(O`Ib4T-$10OtV)7m}feq_^s z`qbC9HirM(^aT(8;I{|%zwxmT{N#i}W9{E>tTZ3F<(6k|x&OGw-qAVt;0eF;x`|tW zBK3L_{npwzoTv`%~cG zg}5fsPwz7%;aN?AuTO!$6Z9wHCpD9V|G5-C{4wZH!t;6XFA2T~{7LY~QqsRQCH<)> z<^B+OlIZ_~6#02919rO@-&DfJys zX~#keemaUIsob+t`2U3z_?J@T>KNcp;@e6}xgSlTe>SDu52dsVt=lD)OUtqS_>W)r z0)JBaF(iC#JTdNRqhb=@ewb3P^(pBObG>@k@Bbz96YF#5Na41=PW}bn4{?^jZ9RKP z@x<3Vt6c8Oy!g82UQHigC(CI1_`VQ2zJ$t+@2j9Urjpjfu3|Yyxv}*vI(~@h-yrnc zevX5hKED6p14>VPAHaa(iLbA3Q9SW=*$a)IzbfUvLIQ8+OV>*rc!>iqao{Bmyu^Wj z8XVA(>z{X^`_sMq)E|Q3ov&T7dpqL5p1&{l{0*^tJ9ywYV{gAij@NrzN3i{5=3lpU z5%b5qQq!CN{MCAI&!73}^GyPoe+p&}U*_*ovOM!YsoTyo{}1`7=rX?(%pSS+NC5MW zFI(@iebnl{^349Rbs>Y>I+M|9>rKZfJ}ZybxCmtHTC`?H_r~X^^xoFZp40n&O7#EY zifvYSpFtuFXSa>*L$USq7zvT>CSkhe3z32}yxS+bDo=~&ys}FhG5w;#}x=oX~d&JSDu@BPfG%bK`9B1%fI?IW}cLU%1hHV1^c7TG1Fq$~TP*h!R( z&iFP3qB3cphA`Up=1{5~vd2dD<-|9I#3d(G4PfVeI{IBH{ou3gPeCcM%_q@RvY|m! zfghnSeo7Thn&|72!A=l6K|g?ii16N!l)Z5Ydv2&A+RbRYoUkSQWysL>6yj1SJ<3el zX0~7_?OXCd>Udub3D}5!EIqc_&c0p>D#9Ohim@WR(=J4g+i}E=*|Vojp>FS#-p6x= zHlqkzqF&=a yUREx7!~Eupwrrj&aY360HV$mM&^v2tdSctew=Py<9ZON4Z6h!+c`1-$z>{g-x literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/PIL/_webp.pyi b/venv/lib/python3.12/site-packages/PIL/_webp.pyi new file mode 100644 index 0000000..e27843e --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/_webp.pyi @@ -0,0 +1,3 @@ +from typing import Any + +def __getattr__(name: str) -> Any: ... diff --git a/venv/lib/python3.12/site-packages/PIL/features.py b/venv/lib/python3.12/site-packages/PIL/features.py new file mode 100644 index 0000000..75d59e0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/features.py @@ -0,0 +1,352 @@ +from __future__ import annotations + +import collections +import os +import sys +import warnings +from typing import IO + +import PIL + +from . import Image +from ._deprecate import deprecate + +modules = { + "pil": ("PIL._imaging", "PILLOW_VERSION"), + "tkinter": ("PIL._tkinter_finder", "tk_version"), + "freetype2": ("PIL._imagingft", "freetype2_version"), + "littlecms2": ("PIL._imagingcms", "littlecms_version"), + "webp": ("PIL._webp", "webpdecoder_version"), +} + + +def check_module(feature: str) -> bool: + """ + Checks if a module is available. + + :param feature: The module to check for. + :returns: ``True`` if available, ``False`` otherwise. + :raises ValueError: If the module is not defined in this version of Pillow. + """ + if feature not in modules: + msg = f"Unknown module {feature}" + raise ValueError(msg) + + module, ver = modules[feature] + + try: + __import__(module) + return True + except ModuleNotFoundError: + return False + except ImportError as ex: + warnings.warn(str(ex)) + return False + + +def version_module(feature: str) -> str | None: + """ + :param feature: The module to check for. + :returns: + The loaded version number as a string, or ``None`` if unknown or not available. + :raises ValueError: If the module is not defined in this version of Pillow. + """ + if not check_module(feature): + return None + + module, ver = modules[feature] + + return getattr(__import__(module, fromlist=[ver]), ver) + + +def get_supported_modules() -> list[str]: + """ + :returns: A list of all supported modules. + """ + return [f for f in modules if check_module(f)] + + +codecs = { + "jpg": ("jpeg", "jpeglib"), + "jpg_2000": ("jpeg2k", "jp2klib"), + "zlib": ("zip", "zlib"), + "libtiff": ("libtiff", "libtiff"), +} + + +def check_codec(feature: str) -> bool: + """ + Checks if a codec is available. + + :param feature: The codec to check for. + :returns: ``True`` if available, ``False`` otherwise. + :raises ValueError: If the codec is not defined in this version of Pillow. + """ + if feature not in codecs: + msg = f"Unknown codec {feature}" + raise ValueError(msg) + + codec, lib = codecs[feature] + + return f"{codec}_encoder" in dir(Image.core) + + +def version_codec(feature: str) -> str | None: + """ + :param feature: The codec to check for. + :returns: + The version number as a string, or ``None`` if not available. + Checked at compile time for ``jpg``, run-time otherwise. + :raises ValueError: If the codec is not defined in this version of Pillow. + """ + if not check_codec(feature): + return None + + codec, lib = codecs[feature] + + version = getattr(Image.core, f"{lib}_version") + + if feature == "libtiff": + return version.split("\n")[0].split("Version ")[1] + + return version + + +def get_supported_codecs() -> list[str]: + """ + :returns: A list of all supported codecs. + """ + return [f for f in codecs if check_codec(f)] + + +features: dict[str, tuple[str, str | bool, str | None]] = { + "webp_anim": ("PIL._webp", True, None), + "webp_mux": ("PIL._webp", True, None), + "transp_webp": ("PIL._webp", True, None), + "raqm": ("PIL._imagingft", "HAVE_RAQM", "raqm_version"), + "fribidi": ("PIL._imagingft", "HAVE_FRIBIDI", "fribidi_version"), + "harfbuzz": ("PIL._imagingft", "HAVE_HARFBUZZ", "harfbuzz_version"), + "libjpeg_turbo": ("PIL._imaging", "HAVE_LIBJPEGTURBO", "libjpeg_turbo_version"), + "libimagequant": ("PIL._imaging", "HAVE_LIBIMAGEQUANT", "imagequant_version"), + "xcb": ("PIL._imaging", "HAVE_XCB", None), +} + + +def check_feature(feature: str) -> bool | None: + """ + Checks if a feature is available. + + :param feature: The feature to check for. + :returns: ``True`` if available, ``False`` if unavailable, ``None`` if unknown. + :raises ValueError: If the feature is not defined in this version of Pillow. + """ + if feature not in features: + msg = f"Unknown feature {feature}" + raise ValueError(msg) + + module, flag, ver = features[feature] + + if isinstance(flag, bool): + deprecate(f'check_feature("{feature}")', 12) + try: + imported_module = __import__(module, fromlist=["PIL"]) + if isinstance(flag, bool): + return flag + return getattr(imported_module, flag) + except ModuleNotFoundError: + return None + except ImportError as ex: + warnings.warn(str(ex)) + return None + + +def version_feature(feature: str) -> str | None: + """ + :param feature: The feature to check for. + :returns: The version number as a string, or ``None`` if not available. + :raises ValueError: If the feature is not defined in this version of Pillow. + """ + if not check_feature(feature): + return None + + module, flag, ver = features[feature] + + if ver is None: + return None + + return getattr(__import__(module, fromlist=[ver]), ver) + + +def get_supported_features() -> list[str]: + """ + :returns: A list of all supported features. + """ + supported_features = [] + for f, (module, flag, _) in features.items(): + if flag is True: + for feature, (feature_module, _) in modules.items(): + if feature_module == module: + if check_module(feature): + supported_features.append(f) + break + elif check_feature(f): + supported_features.append(f) + return supported_features + + +def check(feature: str) -> bool | None: + """ + :param feature: A module, codec, or feature name. + :returns: + ``True`` if the module, codec, or feature is available, + ``False`` or ``None`` otherwise. + """ + + if feature in modules: + return check_module(feature) + if feature in codecs: + return check_codec(feature) + if feature in features: + return check_feature(feature) + warnings.warn(f"Unknown feature '{feature}'.", stacklevel=2) + return False + + +def version(feature: str) -> str | None: + """ + :param feature: + The module, codec, or feature to check for. + :returns: + The version number as a string, or ``None`` if unknown or not available. + """ + if feature in modules: + return version_module(feature) + if feature in codecs: + return version_codec(feature) + if feature in features: + return version_feature(feature) + return None + + +def get_supported() -> list[str]: + """ + :returns: A list of all supported modules, features, and codecs. + """ + + ret = get_supported_modules() + ret.extend(get_supported_features()) + ret.extend(get_supported_codecs()) + return ret + + +def pilinfo(out: IO[str] | None = None, supported_formats: bool = True) -> None: + """ + Prints information about this installation of Pillow. + This function can be called with ``python3 -m PIL``. + It can also be called with ``python3 -m PIL.report`` or ``python3 -m PIL --report`` + to have "supported_formats" set to ``False``, omitting the list of all supported + image file formats. + + :param out: + The output stream to print to. Defaults to ``sys.stdout`` if ``None``. + :param supported_formats: + If ``True``, a list of all supported image file formats will be printed. + """ + + if out is None: + out = sys.stdout + + Image.init() + + print("-" * 68, file=out) + print(f"Pillow {PIL.__version__}", file=out) + py_version_lines = sys.version.splitlines() + print(f"Python {py_version_lines[0].strip()}", file=out) + for py_version in py_version_lines[1:]: + print(f" {py_version.strip()}", file=out) + print("-" * 68, file=out) + print(f"Python executable is {sys.executable or 'unknown'}", file=out) + if sys.prefix != sys.base_prefix: + print(f"Environment Python files loaded from {sys.prefix}", file=out) + print(f"System Python files loaded from {sys.base_prefix}", file=out) + print("-" * 68, file=out) + print( + f"Python Pillow modules loaded from {os.path.dirname(Image.__file__)}", + file=out, + ) + print( + f"Binary Pillow modules loaded from {os.path.dirname(Image.core.__file__)}", + file=out, + ) + print("-" * 68, file=out) + + for name, feature in [ + ("pil", "PIL CORE"), + ("tkinter", "TKINTER"), + ("freetype2", "FREETYPE2"), + ("littlecms2", "LITTLECMS2"), + ("webp", "WEBP"), + ("jpg", "JPEG"), + ("jpg_2000", "OPENJPEG (JPEG2000)"), + ("zlib", "ZLIB (PNG/ZIP)"), + ("libtiff", "LIBTIFF"), + ("raqm", "RAQM (Bidirectional Text)"), + ("libimagequant", "LIBIMAGEQUANT (Quantization method)"), + ("xcb", "XCB (X protocol)"), + ]: + if check(name): + v: str | None = None + if name == "jpg": + libjpeg_turbo_version = version_feature("libjpeg_turbo") + if libjpeg_turbo_version is not None: + v = "libjpeg-turbo " + libjpeg_turbo_version + if v is None: + v = version(name) + if v is not None: + version_static = name in ("pil", "jpg") + if name == "littlecms2": + # this check is also in src/_imagingcms.c:setup_module() + version_static = tuple(int(x) for x in v.split(".")) < (2, 7) + t = "compiled for" if version_static else "loaded" + if name == "raqm": + for f in ("fribidi", "harfbuzz"): + v2 = version_feature(f) + if v2 is not None: + v += f", {f} {v2}" + print("---", feature, "support ok,", t, v, file=out) + else: + print("---", feature, "support ok", file=out) + else: + print("***", feature, "support not installed", file=out) + print("-" * 68, file=out) + + if supported_formats: + extensions = collections.defaultdict(list) + for ext, i in Image.EXTENSION.items(): + extensions[i].append(ext) + + for i in sorted(Image.ID): + line = f"{i}" + if i in Image.MIME: + line = f"{line} {Image.MIME[i]}" + print(line, file=out) + + if i in extensions: + print( + "Extensions: {}".format(", ".join(sorted(extensions[i]))), file=out + ) + + features = [] + if i in Image.OPEN: + features.append("open") + if i in Image.SAVE: + features.append("save") + if i in Image.SAVE_ALL: + features.append("save_all") + if i in Image.DECODERS: + features.append("decode") + if i in Image.ENCODERS: + features.append("encode") + + print("Features: {}".format(", ".join(features)), file=out) + print("-" * 68, file=out) diff --git a/venv/lib/python3.12/site-packages/PIL/py.typed b/venv/lib/python3.12/site-packages/PIL/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/PIL/report.py b/venv/lib/python3.12/site-packages/PIL/report.py new file mode 100644 index 0000000..d2815e8 --- /dev/null +++ b/venv/lib/python3.12/site-packages/PIL/report.py @@ -0,0 +1,5 @@ +from __future__ import annotations + +from .features import pilinfo + +pilinfo(supported_formats=False) diff --git a/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..79c9825 --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright 2010 Jason Kirtland + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA new file mode 100644 index 0000000..6d343f5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.3 +Name: blinker +Version: 1.9.0 +Summary: Fast, simple object-to-object and broadcast signaling +Author: Jason Kirtland +Maintainer-email: Pallets Ecosystem +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://blinker.readthedocs.io +Project-URL: Source, https://github.com/pallets-eco/blinker/ + +# Blinker + +Blinker provides a fast dispatching system that allows any number of +interested parties to subscribe to events, or "signals". + + +## Pallets Community Ecosystem + +> [!IMPORTANT]\ +> This project is part of the Pallets Community Ecosystem. Pallets is the open +> source organization that maintains Flask; Pallets-Eco enables community +> maintenance of related projects. If you are interested in helping maintain +> this project, please reach out on [the Pallets Discord server][discord]. +> +> [discord]: https://discord.gg/pallets + + +## Example + +Signal receivers can subscribe to specific senders or receive signals +sent by any sender. + +```pycon +>>> from blinker import signal +>>> started = signal('round-started') +>>> def each(round): +... print(f"Round {round}") +... +>>> started.connect(each) + +>>> def round_two(round): +... print("This is round two.") +... +>>> started.connect(round_two, sender=2) + +>>> for round in range(1, 4): +... started.send(round) +... +Round 1! +Round 2! +This is round two. +Round 3! +``` + diff --git a/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD new file mode 100644 index 0000000..7cfb714 --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/RECORD @@ -0,0 +1,12 @@ +blinker-1.9.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +blinker-1.9.0.dist-info/LICENSE.txt,sha256=nrc6HzhZekqhcCXSrhvjg5Ykx5XphdTw6Xac4p-spGc,1054 +blinker-1.9.0.dist-info/METADATA,sha256=uIRiM8wjjbHkCtbCyTvctU37IAZk0kEe5kxAld1dvzA,1633 +blinker-1.9.0.dist-info/RECORD,, +blinker-1.9.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +blinker/__init__.py,sha256=I2EdZqpy4LyjX17Hn1yzJGWCjeLaVaPzsMgHkLfj_cQ,317 +blinker/__pycache__/__init__.cpython-312.pyc,, +blinker/__pycache__/_utilities.cpython-312.pyc,, +blinker/__pycache__/base.cpython-312.pyc,, +blinker/_utilities.py,sha256=0J7eeXXTUx0Ivf8asfpx0ycVkp0Eqfqnj117x2mYX9E,1675 +blinker/base.py,sha256=QpDuvXXcwJF49lUBcH5BiST46Rz9wSG7VW_p7N_027M,19132 +blinker/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker-1.9.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/blinker/__init__.py b/venv/lib/python3.12/site-packages/blinker/__init__.py new file mode 100644 index 0000000..1772fa4 --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker/__init__.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from .base import ANY +from .base import default_namespace +from .base import NamedSignal +from .base import Namespace +from .base import Signal +from .base import signal + +__all__ = [ + "ANY", + "default_namespace", + "NamedSignal", + "Namespace", + "Signal", + "signal", +] diff --git a/venv/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/blinker/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4dfd08908b476a56a644af7432452f3a4c7701b GIT binary patch literal 510 zcmaKoy-p)B5XZ;a&F&@Y^cac)^6!h2e z0=xtdfV9$9h=L9s-BpY?gp!f<_wPR*f6e3CS|2DLo-U_98NjnQtLQ9&z5gM&0|km{ z$XUu5sE!JBClAt~<&Zc`!#42%Q11B#w{nrNt!U2g6jQcX>ZXV4qp9r zLsk!@F-0lMtT67C-sE$^`RF%I8w#&vrAuLCj&3d|=<7#h)URx6q$b<*cC{9Lr6ad2 zh-{aRw2_zCOX8*H#dl&f?ALuEuBx)KD1;3tSBGQi@cVsrEQHirhQO*h@+{7Z%G?Nzj4VoLSv+?KR$-&VvcUg)1^v!EIMaRcF zGuLRj5ShtJAr9t?Iyub?RcSo48+5Dhmis~S7BI#d*nNS`2KE}*X<)m7EgJvAc+k0x I?K)L`05Y+INdN!< literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc b/venv/lib/python3.12/site-packages/blinker/__pycache__/_utilities.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..066d792b91dd707fa266ab89d72236109de4c5fb GIT binary patch literal 2737 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 Symbol('foo') is Symbol('foo') + True + >>> Symbol('foo') + foo + """ + + symbols: t.ClassVar[dict[str, Symbol]] = {} + + def __new__(cls, name: str) -> Symbol: + if name in cls.symbols: + return cls.symbols[name] + + obj = super().__new__(cls) + cls.symbols[name] = obj + return obj + + def __init__(self, name: str) -> None: + self.name = name + + def __repr__(self) -> str: + return self.name + + def __getnewargs__(self) -> tuple[t.Any, ...]: + return (self.name,) + + +def make_id(obj: object) -> c.Hashable: + """Get a stable identifier for a receiver or sender, to be used as a dict + key or in a set. + """ + if inspect.ismethod(obj): + # The id of a bound method is not stable, but the id of the unbound + # function and instance are. + return id(obj.__func__), id(obj.__self__) + + if isinstance(obj, (str, int)): + # Instances with the same value always compare equal and have the same + # hash, even if the id may change. + return obj + + # Assume other types are not hashable but will always be the same instance. + return id(obj) + + +def make_ref(obj: T, callback: c.Callable[[ref[T]], None] | None = None) -> ref[T]: + if inspect.ismethod(obj): + return WeakMethod(obj, callback) # type: ignore[arg-type, return-value] + + return ref(obj, callback) diff --git a/venv/lib/python3.12/site-packages/blinker/base.py b/venv/lib/python3.12/site-packages/blinker/base.py new file mode 100644 index 0000000..d051b94 --- /dev/null +++ b/venv/lib/python3.12/site-packages/blinker/base.py @@ -0,0 +1,512 @@ +from __future__ import annotations + +import collections.abc as c +import sys +import typing as t +import weakref +from collections import defaultdict +from contextlib import contextmanager +from functools import cached_property +from inspect import iscoroutinefunction + +from ._utilities import make_id +from ._utilities import make_ref +from ._utilities import Symbol + +F = t.TypeVar("F", bound=c.Callable[..., t.Any]) + +ANY = Symbol("ANY") +"""Symbol for "any sender".""" + +ANY_ID = 0 + + +class Signal: + """A notification emitter. + + :param doc: The docstring for the signal. + """ + + ANY = ANY + """An alias for the :data:`~blinker.ANY` sender symbol.""" + + set_class: type[set[t.Any]] = set + """The set class to use for tracking connected receivers and senders. + Python's ``set`` is unordered. If receivers must be dispatched in the order + they were connected, an ordered set implementation can be used. + + .. versionadded:: 1.7 + """ + + @cached_property + def receiver_connected(self) -> Signal: + """Emitted at the end of each :meth:`connect` call. + + The signal sender is the signal instance, and the :meth:`connect` + arguments are passed through: ``receiver``, ``sender``, and ``weak``. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver connects.") + + @cached_property + def receiver_disconnected(self) -> Signal: + """Emitted at the end of each :meth:`disconnect` call. + + The sender is the signal instance, and the :meth:`disconnect` arguments + are passed through: ``receiver`` and ``sender``. + + This signal is emitted **only** when :meth:`disconnect` is called + explicitly. This signal cannot be emitted by an automatic disconnect + when a weakly referenced receiver or sender goes out of scope, as the + instance is no longer be available to be used as the sender for this + signal. + + An alternative approach is available by subscribing to + :attr:`receiver_connected` and setting up a custom weakref cleanup + callback on weak receivers and senders. + + .. versionadded:: 1.2 + """ + return Signal(doc="Emitted after a receiver disconnects.") + + def __init__(self, doc: str | None = None) -> None: + if doc: + self.__doc__ = doc + + self.receivers: dict[ + t.Any, weakref.ref[c.Callable[..., t.Any]] | c.Callable[..., t.Any] + ] = {} + """The map of connected receivers. Useful to quickly check if any + receivers are connected to the signal: ``if s.receivers:``. The + structure and data is not part of the public API, but checking its + boolean value is. + """ + + self.is_muted: bool = False + self._by_receiver: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._by_sender: dict[t.Any, set[t.Any]] = defaultdict(self.set_class) + self._weak_senders: dict[t.Any, weakref.ref[t.Any]] = {} + + def connect(self, receiver: F, sender: t.Any = ANY, weak: bool = True) -> F: + """Connect ``receiver`` to be called when the signal is sent by + ``sender``. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends. + """ + receiver_id = make_id(receiver) + sender_id = ANY_ID if sender is ANY else make_id(sender) + + if weak: + self.receivers[receiver_id] = make_ref( + receiver, self._make_cleanup_receiver(receiver_id) + ) + else: + self.receivers[receiver_id] = receiver + + self._by_sender[sender_id].add(receiver_id) + self._by_receiver[receiver_id].add(sender_id) + + if sender is not ANY and sender_id not in self._weak_senders: + # store a cleanup for weakref-able senders + try: + self._weak_senders[sender_id] = make_ref( + sender, self._make_cleanup_sender(sender_id) + ) + except TypeError: + pass + + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: + try: + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) + except TypeError: + # TODO no explanation or test for this + self.disconnect(receiver, sender) + raise + + return receiver + + def connect_via(self, sender: t.Any, weak: bool = False) -> c.Callable[[F], F]: + """Connect the decorated function to be called when the signal is sent + by ``sender``. + + The decorated function will be called when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument along + with any extra keyword arguments. + + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. A receiver may be connected + to multiple senders by calling :meth:`connect` multiple times. + :param weak: Track the receiver with a :mod:`weakref`. The receiver will + be automatically disconnected when it is garbage collected. When + connecting a receiver defined within a function, set to ``False``, + otherwise it will be disconnected when the function scope ends.= + + .. versionadded:: 1.1 + """ + + def decorator(fn: F) -> F: + self.connect(fn, sender, weak) + return fn + + return decorator + + @contextmanager + def connected_to( + self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY + ) -> c.Generator[None, None, None]: + """A context manager that temporarily connects ``receiver`` to the + signal while a ``with`` block executes. When the block exits, the + receiver is disconnected. Useful for tests. + + :param receiver: The callable to call when :meth:`send` is called with + the given ``sender``, passing ``sender`` as a positional argument + along with any extra keyword arguments. + :param sender: Any object or :data:`ANY`. ``receiver`` will only be + called when :meth:`send` is called with this sender. If ``ANY``, the + receiver will be called for any sender. + + .. versionadded:: 1.1 + """ + self.connect(receiver, sender=sender, weak=False) + + try: + yield None + finally: + self.disconnect(receiver) + + @contextmanager + def muted(self) -> c.Generator[None, None, None]: + """A context manager that temporarily disables the signal. No receivers + will be called if the signal is sent, until the ``with`` block exits. + Useful for tests. + """ + self.is_muted = True + + try: + yield None + finally: + self.is_muted = False + + def send( + self, + sender: t.Any | None = None, + /, + *, + _async_wrapper: c.Callable[ + [c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]]], c.Callable[..., t.Any] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Call all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _async_wrapper: Will be called on any receivers that are async + coroutines to turn them into sync callables. For example, could run + the receiver with an event loop. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionchanged:: 1.7 + Added the ``_async_wrapper`` argument. + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if iscoroutinefunction(receiver): + if _async_wrapper is None: + raise RuntimeError("Cannot send to a coroutine function.") + + result = _async_wrapper(receiver)(sender, **kwargs) + else: + result = receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + async def send_async( + self, + sender: t.Any | None = None, + /, + *, + _sync_wrapper: c.Callable[ + [c.Callable[..., t.Any]], c.Callable[..., c.Coroutine[t.Any, t.Any, t.Any]] + ] + | None = None, + **kwargs: t.Any, + ) -> list[tuple[c.Callable[..., t.Any], t.Any]]: + """Await all receivers that are connected to the given ``sender`` + or :data:`ANY`. Each receiver is called with ``sender`` as a positional + argument along with any extra keyword arguments. Return a list of + ``(receiver, return value)`` tuples. + + The order receivers are called is undefined, but can be influenced by + setting :attr:`set_class`. + + If a receiver raises an exception, that exception will propagate up. + This makes debugging straightforward, with an assumption that correctly + implemented receivers will not raise. + + :param sender: Call receivers connected to this sender, in addition to + those connected to :data:`ANY`. + :param _sync_wrapper: Will be called on any receivers that are sync + callables to turn them into async coroutines. For example, + could call the receiver in a thread. + :param kwargs: Extra keyword arguments to pass to each receiver. + + .. versionadded:: 1.7 + """ + if self.is_muted: + return [] + + results = [] + + for receiver in self.receivers_for(sender): + if not iscoroutinefunction(receiver): + if _sync_wrapper is None: + raise RuntimeError("Cannot send to a non-coroutine function.") + + result = await _sync_wrapper(receiver)(sender, **kwargs) + else: + result = await receiver(sender, **kwargs) + + results.append((receiver, result)) + + return results + + def has_receivers_for(self, sender: t.Any) -> bool: + """Check if there is at least one receiver that will be called with the + given ``sender``. A receiver connected to :data:`ANY` will always be + called, regardless of sender. Does not check if weakly referenced + receivers are still live. See :meth:`receivers_for` for a stronger + search. + + :param sender: Check for receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + if not self.receivers: + return False + + if self._by_sender[ANY_ID]: + return True + + if sender is ANY: + return False + + return make_id(sender) in self._by_sender + + def receivers_for( + self, sender: t.Any + ) -> c.Generator[c.Callable[..., t.Any], None, None]: + """Yield each receiver to be called for ``sender``, in addition to those + to be called for :data:`ANY`. Weakly referenced receivers that are not + live will be disconnected and skipped. + + :param sender: Yield receivers connected to this sender, in addition + to those connected to :data:`ANY`. + """ + # TODO: test receivers_for(ANY) + if not self.receivers: + return + + sender_id = make_id(sender) + + if sender_id in self._by_sender: + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] + else: + ids = self._by_sender[ANY_ID].copy() + + for receiver_id in ids: + receiver = self.receivers.get(receiver_id) + + if receiver is None: + continue + + if isinstance(receiver, weakref.ref): + strong = receiver() + + if strong is None: + self._disconnect(receiver_id, ANY_ID) + continue + + yield strong + else: + yield receiver + + def disconnect(self, receiver: c.Callable[..., t.Any], sender: t.Any = ANY) -> None: + """Disconnect ``receiver`` from being called when the signal is sent by + ``sender``. + + :param receiver: A connected receiver callable. + :param sender: Disconnect from only this sender. By default, disconnect + from all senders. + """ + sender_id: c.Hashable + + if sender is ANY: + sender_id = ANY_ID + else: + sender_id = make_id(sender) + + receiver_id = make_id(receiver) + self._disconnect(receiver_id, sender_id) + + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) + + def _disconnect(self, receiver_id: c.Hashable, sender_id: c.Hashable) -> None: + if sender_id == ANY_ID: + if self._by_receiver.pop(receiver_id, None) is not None: + for bucket in self._by_sender.values(): + bucket.discard(receiver_id) + + self.receivers.pop(receiver_id, None) + else: + self._by_sender[sender_id].discard(receiver_id) + self._by_receiver[receiver_id].discard(sender_id) + + def _make_cleanup_receiver( + self, receiver_id: c.Hashable + ) -> c.Callable[[weakref.ref[c.Callable[..., t.Any]]], None]: + """Create a callback function to disconnect a weakly referenced + receiver when it is garbage collected. + """ + + def cleanup(ref: weakref.ref[c.Callable[..., t.Any]]) -> None: + # If the interpreter is shutting down, disconnecting can result in a + # weird ignored exception. Don't call it in that case. + if not sys.is_finalizing(): + self._disconnect(receiver_id, ANY_ID) + + return cleanup + + def _make_cleanup_sender( + self, sender_id: c.Hashable + ) -> c.Callable[[weakref.ref[t.Any]], None]: + """Create a callback function to disconnect all receivers for a weakly + referenced sender when it is garbage collected. + """ + assert sender_id != ANY_ID + + def cleanup(ref: weakref.ref[t.Any]) -> None: + self._weak_senders.pop(sender_id, None) + + for receiver_id in self._by_sender.pop(sender_id, ()): + self._by_receiver[receiver_id].discard(sender_id) + + return cleanup + + def _cleanup_bookkeeping(self) -> None: + """Prune unused sender/receiver bookkeeping. Not threadsafe. + + Connecting & disconnecting leaves behind a small amount of bookkeeping + data. Typical workloads using Blinker, for example in most web apps, + Flask, CLI scripts, etc., are not adversely affected by this + bookkeeping. + + With a long-running process performing dynamic signal routing with high + volume, e.g. connecting to function closures, senders are all unique + object instances. Doing all of this over and over may cause memory usage + to grow due to extraneous bookkeeping. (An empty ``set`` for each stale + sender/receiver pair.) + + This method will prune that bookkeeping away, with the caveat that such + pruning is not threadsafe. The risk is that cleanup of a fully + disconnected receiver/sender pair occurs while another thread is + connecting that same pair. If you are in the highly dynamic, unique + receiver/sender situation that has lead you to this method, that failure + mode is perhaps not a big deal for you. + """ + for mapping in (self._by_sender, self._by_receiver): + for ident, bucket in list(mapping.items()): + if not bucket: + mapping.pop(ident, None) + + def _clear_state(self) -> None: + """Disconnect all receivers and senders. Useful for tests.""" + self._weak_senders.clear() + self.receivers.clear() + self._by_sender.clear() + self._by_receiver.clear() + + +class NamedSignal(Signal): + """A named generic notification emitter. The name is not used by the signal + itself, but matches the key in the :class:`Namespace` that it belongs to. + + :param name: The name of the signal within the namespace. + :param doc: The docstring for the signal. + """ + + def __init__(self, name: str, doc: str | None = None) -> None: + super().__init__(doc) + + #: The name of this signal. + self.name: str = name + + def __repr__(self) -> str: + base = super().__repr__() + return f"{base[:-1]}; {self.name!r}>" # noqa: E702 + + +class Namespace(dict[str, NamedSignal]): + """A dict mapping names to signals.""" + + def signal(self, name: str, doc: str | None = None) -> NamedSignal: + """Return the :class:`NamedSignal` for the given ``name``, creating it + if required. Repeated calls with the same name return the same signal. + + :param name: The name of the signal. + :param doc: The docstring of the signal. + """ + if name not in self: + self[name] = NamedSignal(name, doc) + + return self[name] + + +class _PNamespaceSignal(t.Protocol): + def __call__(self, name: str, doc: str | None = None) -> NamedSignal: ... + + +default_namespace: Namespace = Namespace() +"""A default :class:`Namespace` for creating named signals. :func:`signal` +creates a :class:`NamedSignal` in this namespace. +""" + +signal: _PNamespaceSignal = default_namespace.signal +"""Return a :class:`NamedSignal` in :data:`default_namespace` with the given +``name``, creating it if required. Repeated calls with the same name return the +same signal. +""" diff --git a/venv/lib/python3.12/site-packages/blinker/py.typed b/venv/lib/python3.12/site-packages/blinker/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst new file mode 100644 index 0000000..d12a849 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/LICENSE.rst @@ -0,0 +1,28 @@ +Copyright 2014 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA new file mode 100644 index 0000000..7a6bbb2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/METADATA @@ -0,0 +1,103 @@ +Metadata-Version: 2.1 +Name: click +Version: 8.1.7 +Summary: Composable command line interface toolkit +Home-page: https://palletsprojects.com/p/click/ +Maintainer: Pallets +Maintainer-email: contact@palletsprojects.com +License: BSD-3-Clause +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Documentation, https://click.palletsprojects.com/ +Project-URL: Changes, https://click.palletsprojects.com/changes/ +Project-URL: Source Code, https://github.com/pallets/click/ +Project-URL: Issue Tracker, https://github.com/pallets/click/issues/ +Project-URL: Chat, https://discord.gg/pallets +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Requires-Python: >=3.7 +Description-Content-Type: text/x-rst +License-File: LICENSE.rst +Requires-Dist: colorama ; platform_system == "Windows" +Requires-Dist: importlib-metadata ; python_version < "3.8" + +\$ click\_ +========== + +Click is a Python package for creating beautiful command line interfaces +in a composable way with as little code as necessary. It's the "Command +Line Interface Creation Kit". It's highly configurable but comes with +sensible defaults out of the box. + +It aims to make the process of writing command line tools quick and fun +while also preventing any frustration caused by the inability to +implement an intended CLI API. + +Click in three points: + +- Arbitrary nesting of commands +- Automatic help page generation +- Supports lazy loading of subcommands at runtime + + +Installing +---------- + +Install and update using `pip`_: + +.. code-block:: text + + $ pip install -U click + +.. _pip: https://pip.pypa.io/en/stable/getting-started/ + + +A Simple Example +---------------- + +.. code-block:: python + + import click + + @click.command() + @click.option("--count", default=1, help="Number of greetings.") + @click.option("--name", prompt="Your name", help="The person to greet.") + def hello(count, name): + """Simple program that greets NAME for a total of COUNT times.""" + for _ in range(count): + click.echo(f"Hello, {name}!") + + if __name__ == '__main__': + hello() + +.. code-block:: text + + $ python hello.py --count=3 + Your name: Click + Hello, Click! + Hello, Click! + Hello, Click! + + +Donate +------ + +The Pallets organization develops and supports Click and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, `please +donate today`_. + +.. _please donate today: https://palletsprojects.com/donate + + +Links +----- + +- Documentation: https://click.palletsprojects.com/ +- Changes: https://click.palletsprojects.com/changes/ +- PyPI Releases: https://pypi.org/project/click/ +- Source Code: https://github.com/pallets/click +- Issue Tracker: https://github.com/pallets/click/issues +- Chat: https://discord.gg/pallets diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD new file mode 100644 index 0000000..497ee45 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/RECORD @@ -0,0 +1,39 @@ +click-8.1.7.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +click-8.1.7.dist-info/LICENSE.rst,sha256=morRBqOU6FO_4h9C9OctWSgZoigF2ZG18ydQKSkrZY0,1475 +click-8.1.7.dist-info/METADATA,sha256=qIMevCxGA9yEmJOM_4WHuUJCwWpsIEVbCPOhs45YPN4,3014 +click-8.1.7.dist-info/RECORD,, +click-8.1.7.dist-info/WHEEL,sha256=5sUXSg9e4bi7lTLOHcm6QEYwO5TIF1TNbTSVFVjcJcc,92 +click-8.1.7.dist-info/top_level.txt,sha256=J1ZQogalYS4pphY_lPECoNMfw0HzTSrZglC4Yfwo4xA,6 +click/__init__.py,sha256=YDDbjm406dTOA0V8bTtdGnhN7zj5j-_dFRewZF_pLvw,3138 +click/__pycache__/__init__.cpython-312.pyc,, +click/__pycache__/_compat.cpython-312.pyc,, +click/__pycache__/_termui_impl.cpython-312.pyc,, +click/__pycache__/_textwrap.cpython-312.pyc,, +click/__pycache__/_winconsole.cpython-312.pyc,, +click/__pycache__/core.cpython-312.pyc,, +click/__pycache__/decorators.cpython-312.pyc,, +click/__pycache__/exceptions.cpython-312.pyc,, +click/__pycache__/formatting.cpython-312.pyc,, +click/__pycache__/globals.cpython-312.pyc,, +click/__pycache__/parser.cpython-312.pyc,, +click/__pycache__/shell_completion.cpython-312.pyc,, +click/__pycache__/termui.cpython-312.pyc,, +click/__pycache__/testing.cpython-312.pyc,, +click/__pycache__/types.cpython-312.pyc,, +click/__pycache__/utils.cpython-312.pyc,, +click/_compat.py,sha256=5318agQpbt4kroKsbqDOYpTSWzL_YCZVUQiTT04yXmc,18744 +click/_termui_impl.py,sha256=3dFYv4445Nw-rFvZOTBMBPYwB1bxnmNk9Du6Dm_oBSU,24069 +click/_textwrap.py,sha256=10fQ64OcBUMuK7mFvh8363_uoOxPlRItZBmKzRJDgoY,1353 +click/_winconsole.py,sha256=5ju3jQkcZD0W27WEMGqmEP4y_crUVzPCqsX_FYb7BO0,7860 +click/core.py,sha256=j6oEWtGgGna8JarD6WxhXmNnxLnfRjwXglbBc-8jr7U,114086 +click/decorators.py,sha256=-ZlbGYgV-oI8jr_oH4RpuL1PFS-5QmeuEAsLDAYgxtw,18719 +click/exceptions.py,sha256=fyROO-47HWFDjt2qupo7A3J32VlpM-ovJnfowu92K3s,9273 +click/formatting.py,sha256=Frf0-5W33-loyY_i9qrwXR8-STnW3m5gvyxLVUdyxyk,9706 +click/globals.py,sha256=TP-qM88STzc7f127h35TD_v920FgfOD2EwzqA0oE8XU,1961 +click/parser.py,sha256=LKyYQE9ZLj5KgIDXkrcTHQRXIggfoivX14_UVIn56YA,19067 +click/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +click/shell_completion.py,sha256=Ty3VM_ts0sQhj6u7eFTiLwHPoTgcXTGEAUg2OpLqYKw,18460 +click/termui.py,sha256=H7Q8FpmPelhJ2ovOhfCRhjMtCpNyjFXryAMLZODqsdc,28324 +click/testing.py,sha256=1Qd4kS5bucn1hsNIRryd0WtTMuCpkA93grkWxT8POsU,16084 +click/types.py,sha256=TZvz3hKvBztf-Hpa2enOmP4eznSPLzijjig5b_0XMxE,36391 +click/utils.py,sha256=1476UduUNY6UePGU4m18uzVHLt1sKM2PP3yWsQhbItM,20298 diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL new file mode 100644 index 0000000..2c08da0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/WHEEL @@ -0,0 +1,5 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.41.1) +Root-Is-Purelib: true +Tag: py3-none-any + diff --git a/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt new file mode 100644 index 0000000..dca9a90 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click-8.1.7.dist-info/top_level.txt @@ -0,0 +1 @@ +click diff --git a/venv/lib/python3.12/site-packages/click/__init__.py b/venv/lib/python3.12/site-packages/click/__init__.py new file mode 100644 index 0000000..9a1dab0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/__init__.py @@ -0,0 +1,73 @@ +""" +Click is a simple Python module inspired by the stdlib optparse to make +writing command line scripts fun. Unlike other modules, it's based +around a simple API that does not come with too much magic and is +composable. +""" +from .core import Argument as Argument +from .core import BaseCommand as BaseCommand +from .core import Command as Command +from .core import CommandCollection as CommandCollection +from .core import Context as Context +from .core import Group as Group +from .core import MultiCommand as MultiCommand +from .core import Option as Option +from .core import Parameter as Parameter +from .decorators import argument as argument +from .decorators import command as command +from .decorators import confirmation_option as confirmation_option +from .decorators import group as group +from .decorators import help_option as help_option +from .decorators import make_pass_decorator as make_pass_decorator +from .decorators import option as option +from .decorators import pass_context as pass_context +from .decorators import pass_obj as pass_obj +from .decorators import password_option as password_option +from .decorators import version_option as version_option +from .exceptions import Abort as Abort +from .exceptions import BadArgumentUsage as BadArgumentUsage +from .exceptions import BadOptionUsage as BadOptionUsage +from .exceptions import BadParameter as BadParameter +from .exceptions import ClickException as ClickException +from .exceptions import FileError as FileError +from .exceptions import MissingParameter as MissingParameter +from .exceptions import NoSuchOption as NoSuchOption +from .exceptions import UsageError as UsageError +from .formatting import HelpFormatter as HelpFormatter +from .formatting import wrap_text as wrap_text +from .globals import get_current_context as get_current_context +from .parser import OptionParser as OptionParser +from .termui import clear as clear +from .termui import confirm as confirm +from .termui import echo_via_pager as echo_via_pager +from .termui import edit as edit +from .termui import getchar as getchar +from .termui import launch as launch +from .termui import pause as pause +from .termui import progressbar as progressbar +from .termui import prompt as prompt +from .termui import secho as secho +from .termui import style as style +from .termui import unstyle as unstyle +from .types import BOOL as BOOL +from .types import Choice as Choice +from .types import DateTime as DateTime +from .types import File as File +from .types import FLOAT as FLOAT +from .types import FloatRange as FloatRange +from .types import INT as INT +from .types import IntRange as IntRange +from .types import ParamType as ParamType +from .types import Path as Path +from .types import STRING as STRING +from .types import Tuple as Tuple +from .types import UNPROCESSED as UNPROCESSED +from .types import UUID as UUID +from .utils import echo as echo +from .utils import format_filename as format_filename +from .utils import get_app_dir as get_app_dir +from .utils import get_binary_stream as get_binary_stream +from .utils import get_text_stream as get_text_stream +from .utils import open_file as open_file + +__version__ = "8.1.7" diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5662af1bc996e9d005c6c0d715ad107ff3fe2648 GIT binary patch literal 2715 zcmY+_$x<8F8VB$eXhIT`F*Y7BZLp2SATgQA7>oqiBo0tEY|f^u)jF0s?y1gc*&)08 z6!#hO0(psSQ5#`V8GiJ^VB{m^1MA<1g6P^(>?8n{{|EYM&p7x&kvtpJ#<30C_ zqR4&%&xtwqQ+Qs?v!B5WVu3viFN#I>bGRf*>>^wiW%eArB$n9o@UmEDFTg8eg}n%` zidA+AUK4BVviHJY7whaLctdQkm*GvZ$zFlC#1?xM-WJ>JHTb1?$$kOvh#mGi{7SrH zZ@{}^m%Rz^i9Plf{93$bZ^QdypZyZ9hzffLu8J!Am3QDDibM7;d?b$8d+;0ahW#3T zE8epA;bU>kuE1Z3ui&cq`tqQ7_1xw9wd+ToG|w*MW*C@$SZ|@_20C(; ztedqW13u=U);EfWwCC{ zX=3q)>zK5nt8+LWh1#xpvXuKhfppgI0E8CZ`ROptqZ&uAX*DH=WVervazD;8+ zY+`qzRHHY0zA3%vranenYelx!R$V%wvg42@PhSr#@G(r4jl1HXLkcJ12mEl?+m_?GuSN{M#ReROv_svE9QdN_$m(6*SVP8^(^3jQr*(7H zh3;fnMf2vT98cP`QP_FjZn_rfG(+pNYhybb+$$;TE?s#BlR8cApZ4rl;51Q8MRrTm z9^@kxHk8!5*6o3&AMqWbX-4X*<4cdaW?I1&la1qf6wfGTDV|dl zDds5VDHbReDM}P&L^~DZ*VJl>3d&DK;oJDYhuKDPB_SP`pC4Q?1y= zneI|ykK#4OK1GG1ifHF8>+1QpelY$($@t4DH}Os_2TQ7cDa!|;!>>wR#)G5F5q}9R zyu~GcY>j6`mOsnja~WTN-oe$<@=95|v0RL7=M$bR45cqh*|OZgjV-GbUAD73-H*wx zdXF{fy{vym{I5TeNc_Jql}P?sFcPyJW1(X_=@^@wX2&RXjOmW?oa=KPqtY>+b&M4T zifdfo=KiSfFi^yB3`7%N>KNibgE;_bPSvf@VH~lcZ^AH b7P*2$C@!+m;RSn(QT%mi{6Behh70=}2Ic`% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_compat.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..04e3081e359b4a2aa04325a9dcfbd0c973d6e0d7 GIT binary patch literal 27460 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 Qcl0`!?k<>uj>)0_2Om2h=l}o! literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_termui_impl.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4ff5e327a6a23d21168c4c53fcc28c57d6fe69c GIT binary patch literal 30538 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_textwrap.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2897c94d7e4eef372e2ba0bff64f0c8544544f77 GIT binary patch literal 2456 zcmaJ@Z)jUp6u<9pUz7A-`e#eqbXmK`#?5A1w~50V$+g;a%gUu?z@<0m(Y=qJDLtAaG$YT}zhK|i=}!A=+==(#U1UDnMV$T{cU^Y7ks ze>uqyO-(KY^j+z~^q7RuZ){N`SlhJo28cC;5#|zTvMRYr9@cz9m=h;O4)N%9goR~< zMS|jXMkm%0>q1qTlrmgMy3ZElAN)c+cP%=-bPOuuCNo%vZr9{(IO~f=}HP{-_ENLNz zjTuX(#7I+ZJX&ivD~$^p(H#{wE1u%cF{483?Dll)?)^F0V>V{SRphKi_V5shTjEv z_Tf~n5dyPmtyZ-mM78NbE>FrjW;2B@a)dS&3~&$2I| zMd3ZPz?_%Fve5R}sa=Gxt1g+x;hUqjx?P_7Vuk~C=xE*5qmdJqq7*5#uu!q!- zpsb;3l;!IN6&Gi=J+yZ$jG_--MCg5Z|E!P|0ZpuBdk6-cfVtUGcmNN0usN`Yz=Myo z@B1Dyr5nf;Z=lclM`P&ImqhrLh`aZ=!qVLJdYcU@%0Ovxu8?ds5)H-$jTnSYoJ7oE zgIuS*;6VM1wK7*Ro{VWBxeAqoY=@`wmJq{>FqsOZ)0U zQD+E3kRAng1(lmxa{TYU{=$i`UitEsI|CSRHYTQc3jP@Wb)omvKvY- zWdMZVGeuRk$Q)5s%cZJwNt}kUrdl3Vy_Ak59190y_d<+~UEQE?Rn4ILA)2z6x0Er1 z^(;wgfbBgG>=v@K+usMu;A1n^68$4!%c#P)N+a98?k~EocNK)|JrxPo6&ba6tOc(H z^X=CTR~p!kg1nuTMy9z?YkS4bG!Jq$?=&&(5RyA8yh}P$7^xr-H;;XD`qt@haq;k( zKiPUms5w;jyCr`?s2~tGg$GPjPsk1jFRw7rv*~WhMkW>0rs*&kESK}Y1%4mwyH@Wq z0;Wgzvy`*duDwhF;xI+wk^x{9f#bM)sO28={)z@4$cH)q>QKoWEP8`~Az0WM{sZ$P BHtzrc literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/_winconsole.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18367f2936825f12dbafd1a44d2fcce8357d95e0 GIT binary patch literal 11995 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

    6$evVIVkVKrlbv<=_GBF5gUc#sI@FEjX2X!%!O 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�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 XFHn5{G3THtJ|f0n{#0NmYzq5tm$A%M literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/decorators.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c64971c930b574d523b432e4a19eea82bcfa2177 GIT binary patch literal 23988 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/formatting.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3382ff1909fc761e7fd5486597a9e303e62076b0 GIT binary patch literal 14070 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 KdO~H49sV5xkhFsU literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/globals.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..343ae7b29e1703853030b3563f7ffb9bc2d8cf97 GIT binary patch literal 3135 zcmbVOO>7&-6`ox#C5og(NtPT}O`LJ_2j+*g6%;9iwy7)IjS`nmY+cNvpoTj`a^>YN zJ3AyrL1`t!fE)CX-rPeE2~adv9iYjjbx%ca0eX?(22M8);G((sCWk!~>7jjZmXs+$ zL4ppz`P(;d-hA)9@A0prqe%ko54X=&H-`!NCocL8*1C1i7=&CSoN&V>MFU3DHS4ir z%pk&8PV~hej54WZOvz7sz8o?S{D0$$|$e=Ho;jdEHneL0X}e zy7AbJ-rZ})W%DB8*6YSkjgA$KZKF+AVi!r<$i~@axZu2YaX?i~&>oUh<4k*a<|tjP zIRUkqN6UgX1HmZ^D5GuGp~_EEXw0@nuun(i4eFPdg{^2s`gO{@PP-fn zRUNNN9Tk8?jkO%mS!Rd|T)YRx2!UKut6B7EqZ!l=l6aQR)rG3fE%ov*7ubG7EDa*w zQ`G|JpL>QrbT6vDT(D4U=REsN5bwwT)l$OF1m z@ICkhvYy{}w>B1iI?&KhE#|na>_)y5fPIBET?DBI0m#5*k~x8(>>wp`Vg)>SzUe8a zE>277%cY!_)AVxhztC2XEn;|}XGQH6#GFvTd{m*~^587xA#PIiu3@mGvHnejJUZ?t~t z{O0gG55N8J_44+y6Sp$6TZ!3!-$~E>`sJ(TGunw|`qTmsA|4dk6*TK@&E;C9j^_ zICtARx@{f(Rr|Vm%X;RvHM?!izW4lx)(a8yg5+*P2Wp_c2b2E?sD7CT7>umB`owur z_gjDiCXDhM)DOu^us_XCLfCS8OkdHz)n7H9I z@U!o>1mFz_mU=IdPlDVFDEka_kjhDt7~L8^@=<2$=jl(AkG!?`x8&37^LK}n>p%M_ zGx=ucjm}o$$lX*%yCZ9yfdI$aygH#o?kxNfk<9(k8TjWRek?JeG;d{%9EhPsdZ|AY zz)%z@=sy+NiEv1D8c;LjA=nH@R80!TagDAGM;9-?db%|K(&_nE779NICnDJr{F4zL zGJO!5N&w+OnT)Q8k`7{2x<2C?p3o}$z8faaHL(0KS7(*PsM8?qkIlrl>ppL~;=A%V zh#(CF??bl}GYsQnGWiMl`rVjy^~K9Cer$c?6YG(GjEw!_q4gnPF*9~`W@Dyn8b$($ z%}np$Y$ws%zmKc8tQ`Ww^`HEHb#wJ*b~}ISGh9Cqzn_>k#!(7}_a^>0^Zv}uh3yk( zy14EhH;r#~lcw>|{p2V}O}sPn_RRHDz_vRC);C}KbMa5b53KF){P176){gog$Vla3+YJ<-<|rn}vUfy5M;>C!&`zu(y z1o6uLDxNb?i;v`6Qe&d?eO`(8*Pu-8`?-w%O`;1m9#hNZ-%@=IKE%=o8>1}ZUR7R%o<^*4!b zsa|~0sOzQrTxpY7fzr*abR}BX8HrfMMp1@3X0aNjTf~}N+YcU#NvuW5tp@HWCvJL+ z6YJgwl+n}gW@+_E+pMLPva~Ho^Jr-^KB&1P$`6kXte&0BnLZQIu zSWp_3LQ!gK)DsAKx`P4#IZrr*0SyPv4ok8pD4myrp0=T|Yzu@i`jB7pL?_22&#*6q z(S^=#_Y6zHF%Jri`l3-Jc#whmL3BSFmL+e84J#md#)7_(2MZAm=LXAiSz#)s%o;sP z9!x~`L<6HzuBI&cA{bJXmJxqGj~EylLP3l>x2n`5O;=l|4NGXFeraVePjukJzuJZ$ zi-(Et>bSs$vYXy#Xm@A>Bv}s2o>3_h@tu_-wzE=5l6|y&)S=cHs#9TQw>((ei07;n zjY=1yv?>^w=WIAEV%9Vb8&w^}+D1LfK8(|(BI8m7vsIR#wSfJOMm*u6d^Zzv0F8z` zXC^&IW$A2Kp7cE5;rY5xR)#a`3xuNhmqZ&%(14zwj1FVnPKAe}6Ex-C@OVh{MFZhb zhljx=RwWo14bX(JEB>$ukO%oxWeF!T&{ngD0UzY+gyr;+-$Wr2(4@IJ@IIF$xW7pC%B zDu0%n29j+m(F^-q*~Vh_WwrnqH@7lpSR)5aJt-!O17ytS51G1Clx zu{dTD&F9)UPOgp_MvBz>`8TVjjZ&@6bD?jtn!u~_(^0!xK4wx&^l+C1zu_$BH@phU zJ}s2zO z+yH+7G}(y&;v~GhK9d2ihX6M)6!0_L5ZP|?;0Z)=mxr~R# zeExHU3iItNNOLG4N1{L^qI7|^#JVLEArXpV1R`IB@G?-RcQRK_eyGGS+0mS=&hX$n~3QLGHG>QEpU#4@nO8SD#(q`?kWvMV0@XI;BWAKUSq~G7RHtiMKeZ3GPdKiTM7;|$ZoWpF-5R6 z5yCc}nLqe;4u?mjouNl$aZ=jZ6ZR_*wUZWl=NKb10};P0NuhzrFcxJe;PCuT@GiN` z-5s5~c4DEW9RxH)OLzK-)7Yuenv8j1NQ(N0r|Je2$QmG&+VNyC?DqvD2RfA8!x&Cv zAA;Y_a9M-7s5k$#zbNW7-sC%tGT}^_COTEq?F$hbG3+}J7?}VIMT77>>3PKKkZH*? zd^BTKNP#aX6Z*-RePd%%NX!Vb5A-Nwk-;y4er5!AW->*m!7H(a%@~7HC}Yj#iy2ce z5Q%!NGL1|lM=jA$z2&~@>Kak-s$RvtHtOyAF@EnpiQ5i?!I?3CR)JX+90XbNl zFRM96>74t!Pt5e(FRh%LS}tvzIg#$^ojIJY^UU;QO%|bgZbz2G>nB~;Ph30k!E4u^ z{b&08yo|F~{L)2rT#a#I)$WQvm3FxCp6hyNf7(%U>Gyoi}*OF^b*2=luOU^B6SLs60e9?RMRi%mdq(s-{ z;d_oPxhAlaD0RPb%aZ4b<;o|QTu=VGymC&y{Aj!<*Xf*i@wqQ{V076%oYk>psk&cY zop4`%B5sK9nYE^!rE$~!nucU!^7LZYwU?6p$&TfkPRg8Xn0+k1KVI@{%%SYNkH04- z_FNuWvU`?Hp5LRv(!CJ^flnTF_OzHX#_(A5D~FU3?;#Xgz~K`a`kv-v{KJl^Y!VGI zj?gq}KuE0x$zWvG##*3n4g{U6Rm$+JRPM`b>SIuu;eJDKNvud9;tK-vc@6S*q+|q! zWR>ITQ2?SSG8PO(2QYkj7mAGHKXMwu43~B|=L~bD@uM?G(iX?t({D__^(`#d-0t{9 zyd-V0#XI9CXD-a`y<@?7Dx2Fi*A<^g7!zHI!wC!aWXZZEjg@Pf^Ua-^YmFaRGS#f1 zT`ptvM=!`Eo3CSb2=%b_BBX}(;@@y!r4Zlv%wT;^aZwGGvR5<%8pcJ$5Q1!tW?}~zid;Y`*Oz{PtWwmyVE7^ z_)BVu#mI8y?xl)7OZL4>roHlRw2?7KqB3ZQK6L$elz?i3)EeA_V2dE;1CuIZf-N-0 z3GW<14#fDpoA4+zK> zusiy-4I@lxqn1_P@8?EDWQST)36Iz8yNaw+1g6A?sEh*yCt4N~hZzywPkXk1FftsJ zE_5)U9^CFZ1BpxwhgzeIwhs9MK~G>v;T@FPpyh#(KTHxWXs+k@S?neRF&|_tg<|`I zAob|xwec`G0En}MO!HMdQpE3rSQ{Z~O+qfQEld(428E=tfDfDxffq))BcL(_9UV+? z+HnSy>fHYQ9)%hz%mVeGoJ!1fK$&J+qjbSXqx7_nP7?DVHG0`lsPHRlX5)5GqniEd zpVHXq41wz;8XPkh_5%{$Yb-n3<=`>v@v zT~RgD{Z?Pv=9uXwD!2Jp71i-0z<`%d%$}GVzvrm`+{jhdWL=!YIdkH7UlwzY$}c#R zuo-l!$Z^RwYn$7>@c8`W_pJ4+_L7+s*<$4VAwu-|Ms=5o`^41TwcYs1HXflLiP}?= zi>>`HL>4%S>*t}TG!)@T6>*|Vk=`WZh<32Fnw%sst(AaWRnwWzRCCP_&9z7t(fWWA z#t~vMHatu|bcjW73H?QqO|(h&A%kdt%cOFV{SMKA_H=5B#bSwQ6M1OZoY0#UPx9VU znWVQq?CP133?zS9Qh20{35Yb3F^N(n3P#CKjJDi{q8WiW$Ed#$BM}WIe7u$gl30M~ z6ypZ)sXXjU!*o#s8uqBeMOmuL9)|P&3P59tYT|6nqGBaRTddPXF>Az`7h6R>X88dp z8h&I{%e@JTJVImI@aPGuF{{Ybo@!mbP>j=rP0_^Ye|v$5SESa+<<+6j4gJyQh$gz` zGxIY7=DvV>8s^WJ`D69|H8WI4irzjnaWT`3K@^CpVCD0xY{HjD5n=+q?CNM@W_)Sj z9mDDlXd?e45KP}x^YPGm5N#3o3E0--hadrvfv87HGyoDwX>A$a%P^F}9|@5tX&6f~ zcE}xJnQ=c*#|#9+p|ivZMKZ>S1eRSP_fmv$0x}WwjL|2Gax-EKY01YZcANr&Px%A| zM-X^zkc6b*5c`miQnFrAV#?%45o83+0m?jD1%}pGpfDKLfdR0=l$l^KR<#<@jsPU#k=prDtcKU2)W>9QBEzgPg|%zm$RJ8w2o*9AwS)`P7+$X+YcCtf;=Ju0uePuvKdm<>;Ub%4fg zee7^%>;MW<7s4`hbqeA(GMpgOIhJ2SuwK}+jLBh`ej-yPIoy!@{?Akr zc4FX#wB32>iP1J>I2xB3mq-t7rG^C45FTFDRO5)i&#olyt8|hFAOWetq zICiJFIqfK=+AEHRl%pZpeBFD^yZE(b$0I9_M^lbRZwvPv2h;}p?i9EGk>aMmwf)R? z&(W<`IeMqK2_vL2T<^QqcXQ82kKcOywr{!l(8ryr=AI4X`gK{|(w3b!O&{5B*%zm8 zcP-T)SS~xbY=bc$Qr8qcOdA68hC7i4D($wr!qTy=Gm6nv# zvqsHl5A&S4Bx~S>U5V4sDhj*SjA}yGTr9LCPF{WC$_rTz(ZvJobzA(BzLa?o3h?7! zdsNnU?Qf8jmls3_sQ^SHcyFs#R*U2$1(Re3_bq^Thdn``OMh5>!YL6yHsRTfo8=xB^?+=i#p>a$_Gm6F6bl|9ig4w@aT_9 zof8jBiPx$iyLE~>f`Deifn*jrI-xqFLns4ZpxcJhGe6#$OpHcrdF> zOp!-X1@7 zV%Lr1Kjg3N{XMf2ylE+gxww>9Y#OaxaKCyX1@9z|a1xM9ecr~s3H ze)E6uD8qIr0=p3gHAP$^Ad|faGG@i+LpgGE_%ddgea`!2MNaZj!7T{9x$~)=qKq&c z4ubfuKcQz(bjqa;w_RsE5@b4T*msc;9H!nGw5#D!KrD!FV ztM)Cs_d(s`bpOzpIPwGA9cN>@x^7-bmsTbkzE^v{a_fC}#Zu+LW%r>K_tBL5Xu7`P z>dRMNUKBqZxiOM8auvt;HO^2`xn?v~m1Q|oX&ER(uG6wR_DxCCb?Y_jb>}rF%oHCB zpO*dH4uVrr6F;)*X^9I=f3%16M=5Ll!^kPm0K;pSMa)c=C>WxE=q4kS@-W2$6fi<5 zybvPg$yrLEg<_jiKq46mrr;j_BS8djai1HELRF$K%i(pi;iL9j?YB?e+Q~jYZCaz$ ztgT9DSp~hEn4Oq=ZDDGDD%mvutwsJr+YQ^z&X4xr+JD=B>tL#_d#S2BV^&0-L7OtcF@#Q%Fj+$3@m0u5 zMWKACk(U3B3K3#@Kw8?`nQYwHTqqQGJOZKE#@5bj(SwAH=^5Av6;L23*tqG87*X)g z)D^)F_#%Tz=uG&o4qX{ap1N`lFf4Q~f)l|@*(EB!ZkJRqinTGUW#KOM8$}N|5tE*h zUo_RA9Z?Vs*ef$Q5pzz{*&s3w0kw2+zhq^#Z2E2Ha_tYzbx1{G@dHYj^k{%K&JwW% z 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/shell_completion.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b617f7c5db84944a8ba1630e21cd43210ad9bb72 GIT binary patch literal 22772 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 ays5JEZo68ZQ}A=4o4-ELzo1{NY5ZR$V6YJY literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/testing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..45cf5ac7c3f1d18fb3e552d0e1ca09ed05e5af47 GIT binary patch literal 24577 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 E4Pbte{r~^~ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/types.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a59d12208999699fe6e01cdea303fff5bff24d02 GIT binary patch literal 49457 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

  2. x_Hj|=&>Ie7wBWz){{W{0U9bRv^D6rb7LCF0@NlXZsqo6Arjm!yA;qAko8!i-mIUgSD=G@FaTB06u7^ z{7^h&N{pylf}r3MSSM7*L#iu~&o$&Om6U7(~ci9RCq zI9eh4C|{NGr_@ge@bLX&Rm#piZ zUCL1__Jn-!OS9D2h7-q7%>PooZ<(HK$5TPR8Yu&C9x#a^0F8>T+!?`|NQP{_`TQ$b zZT}3}mA^z#Fnm`mA0O8a&tD_U>i+^#)IhiWWG z#c3B!Zu(PQ3g#_X!$HuxUiAY9VagxiWuA{qs!Girb&0CNkSa0q7gSfm#h0XaJr$GN ziL&|9=aP;_K^insNldZcL+e56cCIhkwSU1x$5VgYI>T|i-twG`owOcfmh(IC?ai2Y zwBU=boHmUP!p24p`aUkBv$NQFlUb85UN&7Oqii+5EagttnlMk8KnPf0aOC_e7*BiD zR9y^97XT2rt$nohIS9KLMve<)4EYr7wG5`NrY9#JQ^F)c(U9K z=c@K&Iw}JQRGzG>t6(oiX+ee4RJ#$B{sEujh5ZtVE2C4RUwd%EamP=7X&#wy-gWt> z9q(XgnRbXx^}PSFdH>_{{sx?PUtWRp?tL{=YiHKqh)u3dS3CqCv=BmNJyL1qqU0zo zTl7obz-|Ade|+$k<&Bc>mArZA_V!28{zucEN0W|6d6h16-thry_M;T+rbd0AV$7HU z<>hl{%*Cyuw38GNG*b>!K)^yUb1PiDhJ6nS+(olVq2S+8U;GqL+2fT9%v!As zYigjT-mAT{<*!v;ufmbul{YJI$!}P{XT90*rZc(aXe#tbs_{`excIo7eC!mRltmWU z_cZU8Y-L%KY~4HAjg24Hy$fb70SuFPv|=(&k5=f9R%C7E)?>2nX_tQ#c*o$B0{0k{ zqWZ`9wUvHwUvpa--DK=4U2aT%wE;p9N+pu&(z!AD`JQ}8m)o3{vl8gh&9aq)W3qA# zKB<@$8aL;?Y5s^eYjbuBIT)GKyx>3%)Qc_+Ym7?+RXL3vo?|TOLb@w2UAG4q2U}J^ zL`u0DX=THYmP?dE22)yzutiYIrqtXyhWcCRDbjZ&bcS&lI32xbOX$oZKiBmuu!OKB zblnO+(^*7*R;|^7pXnyk{H#9jnF;0OeS?gy6J!R@mtkE!iIv)O^487Xxb?pKJiPrR z2;lOS-vdP(>PqP>P2-%pR>d}YRX<>W88)zc@UgCtZv>rZVi!oKh+)y~k{O$*j7bRq zFS8k{O)@wN2wIb{-xtu&p&%>TNL{`1vE5b zp)sgp07YO{fTh2t*t-;DDQKg>g#t1qv3Pv=44jI@fU4jnmIejZRwNdC=cD9eL&SciUz@b=$Y~PEF%W@mIFb z`oH+1i%2;N`C7xofxA_86Yh8I<&&$v9=&a^zXPYdC%!a-jouhC+Aiir}6pML&1ygT8h_^Ibd?|6I@u3y-F zYF=;FWOtU|@zhMOdMS3>v;IzH(|qO8w^zOGfBQtz|JZ`rR8@gf>7fcSOWqKCL}IUD zMcP%LwA8=9=!7*Ejt+5_-*tQ6byaH*vQ8v@7^n65!^RbDPU%NZXWI(%j~Zo!;-J_E zgfi?2>edAEWo(#hS-r+46-4KmXv*EUSKQ zY52Ki#m_C9e{DNpk}KYmC|rERVwIbw;SdzJMQ=b3O&(p8a9iB$lpCgZElRj8R#(Z@ zld(k!x5e$}WO@6d^)h^0mam-Iw$7uB58r zwzxGQS57;rnw5*2+qvnF{5WuyC| zV%;Pkli^x$QKHCu5qX!~F!}hEj;W3r`Bm#RYbvldD&9EN&o-= literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc b/venv/lib/python3.12/site-packages/click/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a85b872ecb392353bf19259ddfa6b84cbe7a256c GIT binary patch literal 26307 zcmc(IdvqMvdEd;wUwAGaBnXm25+JZ3u#iMbqF{;&2ofYH3Zw*34^S$w+!+uHE_RWb z1xdgQ1$2}Mu;dbmlmM*d3QAO)s+^imn?yNH8p}yj`=mVq1UiJqU=Mxb_8kAyEDh$^ zRsLvy-@P-lyWmoE;?vU+F?096AK(4n_v){UihKf|Ke~D1-0_ow@OSjXd`gYLy6O;w zc|jIrF)sA+uh=KD-?ly*``Y^)_}b#m5m%o}q&)Vxd&JY{VPOZt-aaqFPT3XrjrjZg zEbK-&&=+7~55h%#MJ((^xVW#Fg?$K@^p&u%AK}uzQWg#%T-H~{!bJ#|_m#77F~Y&V zAPbiuT+vs-!lm)bk*dBbQBWMiVRMMtuUf^%v8ivfO;9!u@5`o`A-U{Bk%#-XAdh2s zznPN#%H>v`t#VM=CRZri1|4$cYmUC{a)(@nuOwHa?4fKKGi2o5ggiUt!}4a7u2FWe zSeLxzHD_O)O*ksZwXX^C)(>sGR9`)d+lIL9R@`o{VE!i`k$0fAZnKT-w{RaeBZIv2 zz9mj&%bTJ5*Td@CrG(@<{MFy5&JfF0A&Y|nc{j$`BnRaNjM*{#yxBtbi@?Hp z+v3i?6HC(Yzw zvHTEv)QX-Qlbhv-OYFZV-?7UFQD(@T!|Ye#EAbTi^(**mXZ>>w4`*|j zA)a&4Cm(vv)%V!A7<&3Al++y(_2RKnIg(QPFRGEzQAI_J@0p}L7FT-5M-}`k>Qy6A zL_9ER|$U_YWr3{zyWLA#<^jO-rdtWJE)ZKRK!-&dClu|>HloU%z+Qmp5v#CkSrKmDWsajZfMAUQIgzHq8zPjuD zMfTfsD$GM_B^rtv&9M)y;dcD36D|8~aUMw1Cd}B=AYe*`d`5s$CRb z62^s#!X^7l!bR}|k)Y9g#Oy@Ku2OxfgqQB1j%zewk~F1mp(wYpJtsD6kwGPjF@z7q zllW=}!$wja@@Xx2{d`Ku*zDf2PlMG96-&X!#j53C<5HmU=W8XKekzFGveiK8YDqBT zMDQ~$fD*s%_6u)#tL?udR@*}kT}N~Ep~qVOkbR=QBbm6Ms3`(eHeM-~NG17? zm@E-8OPmXT<{V26w(Qs4sxle}9uB#6UrdW7v{WP!Rdnas@st9Hm6d2xR&={IuIZKM zl+<7>t{|LJfD@2{n)JZwM2s>WQPrf1oGHR5A&h|I6JseyBIgxCt17J^v2xlAcufgE zc9+f8zf*a`y`4a7-)eBv{DHXx@7r%mPb^DMtVmy22_9Gq9JuQe0wvR9Z?r8rDt~_0 zDU{X{z?s<>-Pbm+1owUt*qgB<_A{*vb^q4Rc0u@9*wVhu{_$23Z{0DZ#7A}CNaRv~ zTuGcu4MnXLMt%#IR3UbrX5NAYq#BPbnyWQwOWS1I`Nsjc&NMjZw5>*%d;qGRw5RQw zIPOT>WhbM`uJeFwl()-n*^csvpLC=w_)6Q&)@1htAY;;*g|lqhVc`|)nH{0*qY;A!_$T%}$A~y>E)YanNoa~J zVY_KW4w8csftb0+CTu?6PyP>{ZXMH%8g$X4y4W|Yi_(NW91e$^z{=oYR2qqH2VCl2 zB>|GFf_G9kAu{AqAH_#~j4~9BM%2hTkfEV|B_Zq1i%C`1^gt?^io^||)_w7amg+~H z$|YTl=?<2Mu##jvd`nidEopLFV0_e6KlNViL{<`$w5PEF2-gago9Dacx)ugkD(a`6 zx$Ul4uzljL0j8hro_%GhWY@FHRGNZr}wRTD&Da#9R8|z z@!4x-@10)Wv}f6~XF71(U%k-uiNEgCK-q17$*c`rg7)R7R)baZ`{(vA99e8wY`-SH zcVwY^CAjC4z#hupw&Jh9w&U8whpi}-sT3;eGMj|b;FU`=mlm9F{MwRd8#?JMd%I)7 z`PT7e$F`{x`0Wo&N4{LoJ8@)j$JJwBExJ~A?b#11mp8R8ds=x%+CK5uuc9L!@AR`X zu4yq-#LB%u0>QOvk;k^(Jys{5< z`H{QAtRee_C>MYz=SRA0&?Xll9AJ5|#Wp^LYak#;$zqf&mN&^I_?F;Xif^gBSuVr3 zOfJ7qUme4B8(R?sB}jGBA4K=UGr)2%0j|*eRIsvs*#;4kME*)PqUHiE6;weOBO)ci zrg2-SM)#bEOpJGeOiui-b}5dqL^M;vCOof6@z{9PdPir_(wUZXi_4X z0&^LUk4q$%_-MbThLn5rL7swGGXnl|M3K%$v{+P%4k=NzphQ%Z2EEr5MT!klaaIj= zf}{|M5XguE+#<0S2?-!C&{$ZKdWT|~gnwh2f?h~yLLwH-=njazRh7mPN!%i4f<<@h z9c65pMu?B_SX_e(VqH=NhY?97M`F<^p+)ndupNKvyV780fKmwk4(pc#zp^wI)VtqmJuMK=#rQ5OzgZ3-CNk<+ zn<_Em(jr>2ryU;}xrqv+K8puL*rKE3(6yy)7X-B?MSMSdsJzL^4TCyud`!*}+OWKO zL7(z!4mrA2Dz1xaZz!PKl9<^+Z4^tuL_763($uHvb%I{c(2E#!-PS*-2Mnn<8c%A9 z?jX?9o$N=*r8_hwKB#t4fdZ9iG;^G+7>r&&C{HZa-#<}iZiKKI^{dFMy^hzEaJN*b zseO0z)y<3hS2j0KJKprJR%~LQO%gsut5vo5_>Iq}o&f#Nt{-ARA?UM3YdFG3EJwjRK?28MjmD0MKrA^DFO*cxL zSF36$->OtMefS4~tqdXa`C)>X1wH5@ttW#)BD?u=!RHC%fJUR19zorSq9L2^2HzY> zf%Wah?+;=A#=T$##l6JdB`GJbz()Y${@&$4J>kF8CUEoA2XDuKFC zNEAYf{cBFJQjYG4(gR}&0yc0^3`aIh*cv2VJQ#AS&!JA;0og>=O9<0NQqc2o43-7x z4@5SXd2&X7KNZ>lemv?5>eQaZi}Va7S00~ve96CU4YI7`UH4V@TTd*N5G!;!P&mE^ z5`Nwa5a4Zi3eR=n`9-X6Lvj2>EbaCU&o^x!8fcIS4FZV1#f5{pY0W2qrVlL#|Kq&BEz+6FoSKTJj)K(THR z+M!57j)Q!m4bVJBk5CddjjGU7MnR|(Jl3j;>3TXynI!>bUeq|@qei*`iwvpKrXU53 z)f#>{h9H550t~1b*3E+OMx5M(;=21}4;Q9=SzVGUQ;G+)lyx-ZV4$zt)C;<(utbgK zp8CQNF+(;JMHU{RefBmo82C5i69T2i7FZ2d&p$r*_;h#1=Jr0dR@b^(S~2gP^DgXr z_lc`dEXv;)d2i%;?;oG}_L=Wh{LPl{Z@Fu?)fX=Zc1$0db=)Z3ktr5}l|a^RF#Xfs zpWpQhrPV(b?B1tt1zLVozGdO?yIohiuC;&b_y@;tlt2E_vrB=4|Cn(j{WFckn}5~r zYi|)gZt)(H>>oc?e`t&SyIY(H=V@sOr!s6zc;UXNYzqJo=^LNV!`GrPE<$T76?8?!ZqgS4pdFCr8Gj<`c{a)N+4g4Sq-*4b*83t})abz@}Ec0Lta)vQ@ zmi9840B6Vgw{f3I7b6xWLnyMqdo7g@|C=iT! z0}zR!EXvt0m_mZ}f>WpmS*O5Aq?C9(b`I+2`1nL^{*>mY(oi*0XhL4~0JLxVYd`VV z(hNf={mKcNT~6-vz=|jv11s9KG`j}T{@|Wfh0YoRHy{9%rQGU>754`yzfQOlq@^S{ z?Pm)KZue5OKLz6kM0$jnGETRp&PHjcnvb=@b%@g0v4f8c9~I-8F!AayAx?gAzB;b{_R-l$T^NEPy9)#XIAD)4v7<#o_s*b4TBp zT=LYi0Re5oU@mm)E+EoaG}Q@qj5sRV(ezc1;T76UO_8wF->>`n`ysi&YK3s1zyDXq zB5@{{CX@KVjg%jJ(`oQQ@J zq@+CKrjSPnR?IieH7)eawPw5&;}got=Y4a&g}rkn89&7Yz-X^ib(zORXVaoRBj9sQ z{Fd_r=Q;&5F1zy?abefGK;Mk7)LA|onV09}g@@mL^y;H?=hp>9t=HL|wd+2obMtz! z=&Z=NT+Ut8KWhBhcb~ud{NgjqTOV02-KY$6$ zRm>>%LQE}U3oud9sY7+<41JGeA(6ScJi##sm@yNxp8(**NLB0Yi7{nG}rj!7+ z#oF`UryR=x$tSWIx(3MnBz9)R4NTg!Ngn=Ee%3E|PFIJXDjR94a5Thf4Io z(~2@m%p9>qr0k3myOjx1Zy-mm5XH9JL}hM+ zmhkx(l$T_2V2GW&ryXDM@wKN(&g+Q-5e(0fm12YBN4?ze6p;ATmyk#O3cdR9%IhJa zfr(8UdT5Dwe?{4Yc$p&J#M}f-SS5{19&W<=g~%7j2?JCY(Gr6pBpfqQwV`E$rhOl2 zDv9TOPV&h~9=SpuK07o`^DsOzDVMi+0a5w1hheUJ7KD?Y|4O+z&19s9HJvv;S_QTe z&8)4g9tiACftA=uQEVz%h50%RAe1{9goy9y7Z($6AZeWpNVEn-L12nrDcQc{DZrln z(mfnUJB52l$o-xka$&p}ls*@D|D!qPzp z1QU#0slP#?-=vpCaTv8yU#GZfdKDr!)Tm0Y@8VDUHeRp6Ml3oTfV6wB_Ac)DM*VyB zSI-blXt>r(^q?W*5}hGVCPG;<5n4wyL;FSdMf*kfqWz+K(SDJI_KPy5qEjNugAX+; z-9rKp$3dRP(5t&g6itK6f=ZZ0wa_jwR4i(M&oMP`gYz z(>8TS+IdOTV40I`uo_xDPdl?Mn02YJ*2#8eX>%r=2s?NTlH^|lp}dV3Y(aBJ z651FXuaFZ?IFt#)9K}dYGXohj$fhz9(_pO~jGaSn3@#y^h$Y4@adDLD>ET1rB*T{h z^T4Wm0ajG<=^@{zB<79vIIn=Q5)U#(<5v(I6}{QwgML_*JlKXu42}+{w%` z1?p#*2i9gRsFoUs^9A+Z=vFrSbIM5a0@B*Md%DnBAggQ%{HDd?wjgtYENfFdnLKZG zhnuGoF%y#si*0~4SeTgC z2|*y602(-7s<3nt>!wP{v%^Z1d{$HrjWj!$b#i3ku)%9ERBlES1k1dB3Q?uZ0T6+( zbeOvl0ydJ;zyQ<_Xm4PEkHRPp)ZQk&KrVw;CPWPk5)9#mKXUFC<_4B%34-0b%J-Ruf}X zD{-wPQ@f}P7z{A@oMmU$NNeq(>@2+OEJrwOIypq4Ha(}vZEezH;fJi!#s;$XkFgH{ ztF$XOZX=_&CJzML_&%QAr;`adwhRtgPT*3*0Hh){0K%HI3bz#;4Y<+JnpNKOsr zyc%dAyZ327v&hIugs>b_zr_J-9KgEOCqRpI(YH>7&KD|HiPKhzKC3PCVu}iqaC9&2 z$cU;&#&sv#(<(_xa4n%(R*6EX!~&>fJXc9or26m*xz)EROpKEH+w}S!dd=gd+p+q( z-|)4ioypjI+R=Epnb4s`;c&8u+&{!0(^EhL)h7y`z*PEEfALzdVI>%vIs9YxojwdU zFHkytU^P$<9?(;=apkoAM{e(G zaoLw+v(HW2*Zh^U(RcRV@NZuYl+5m%d3vVfHUf{%oS5$Tk-wPqMZOu|n}JnN@!f#n zDWBc-j`N-IrRvZPchg!`=vv)MRqM3>w!do0zthktzIkFbP<=D7bvdwgA$lW#Xyez7 z02(R33oXg+MP;S5dD{77f9*o=;-feGp|$ebg`T%sXF6^bm9CY*oYb;bO|@6I&N)7< ztXZp)7K3jkXYIEgp4X3GK0d9zc5;;me}h|{CK^&o_yny=Bz~rWX;d4UB?@4|jS#@B z;gvioig-W9sd5+NEQeZ1hRS*)PKw}AOS0UZ3|^JYdSA1A(!M0Z=p&lEAWVApiR)SK zDDEXlh##)ij4vQKBjzCr9vkQ_pIVSot&MFq=A{7sgEpQ~ny3X72+%Y?ABn?bWE2wE&5WvxZvD_EFi=rZ21%A6W7n_|#wa#{Q|3Tts;q z#hLj&O3P_J*76P@CRbhYfaQfN;xDkg_FM-ATH?rm$4EYJl^H*iv&x27$(RPsDa;Mr z2cC045yOOF&3Qyk!uA3t)nKKJ<>zI9iwD)@2wP=?QM_la!KZR>8u%|Kr6_1xiut#Y zb6a!_>;>_s@I3~L%SmW7sjA>R$PSX_4|%g-HF#T`o%#O+peCzgc-yu~;PX_KvEQ^o zWO(vKi9<5^0F(30<1qnFUKRTRZswxWAT2pLTtSIiknxC5hwM=eEf6 z4nZKTEp{W3@MdOI$Ki&QitVWkMJ~j!m4KL;6`fe5h8DuIh=I%$i^6-A?ViX+#M;cA z;s|w;D8sl6E*x@CFdh?@dSW9n@{vm=Sv>^oR#1FXOa3KC2%lh|(dE0zE$$t6B9j;y$~6R65K@-apElGSWXK{?#^}(O8dS^~r)pM6mPPI>^ zf8?*GDmrI6-+p+0-`u`;#CM%nopWD!KXC2Y-z!-OJTxud_6MepG1@ipL@Lbe#N-p( z%vB-SEgO7g^JAF4#3KFW6Z6t=A32_*k zjWnfj?S{`bxICgzfB)xyMp`VEx$D98bA=E`7=||+a4IMu(Op0j;gblfj5EEQIt&bO zj`7KzG$YZ}PD5eLY6EEnc_&_ehz|CmDk3OZjLyeFZO}N_Swf(4jrpp>(+=~?)Qo5& z(SP(%_;hb)%YJJ}&qOe9S`-vXjU_dy3F^Qm=7UZhWxPUm5=rfw96LAEEXiYx_?$X& zN_uqfe$ooDPO#tm9%{xcN8@9pQp-^tzkms#&Y)h_cZ`?_KPNb##u}o{S)fD88hDK% zV^wyVibPTc6Lm0z-625Hz`%+2?xRn3m;-A@Ob6A>7>rXVd%9jkY3UR@NXzJO7JGAM z#8BOmm}<_g*%1qXIQ-=GqdN&@KR6@afz}fp{Y@nGs_31PvKj=#gu_Mmc9WA-8jsO4 zTCr4wXjszLYQTnL*g^;s&>LN8MIsjc*Sh+Yrl zrMozD1f>QewckQqu0}&8Hw^ZAn@A{`mq9`wgA#5nSV?}PH-o#DgS!@wtprR< z6LU{2ytoqFJ?){xosI7tx#8Zq8r(Af)ZA0=@4dO}!1AsGE4vPU$GZ|dKJ9_&KTt7s zGUF90YAMI!<4es?t^^O>3?5ky9$5_pXI}yluJ9ozRDj6I2&wJ?>R~QgIKY~Wz(8?M z_X8lJ3O`yNwWFKnL%ad~UjJK=6lh4yctIUZiz-M&0>^15?b+kLg`~h?(w}a4vPUrK zIOWv#oEoUj4bQM8{bdtCz6|*bhDd|p2?hP;3z0V*xwPaqkVu<)?4Mr814-ycUTcCcmBy500cZ0=AxfKpzS*5uZO-g?epCy18@qOSKF>V&hW? zN@Vu~S}D|9k2!}XdsAr6%{0jC-pFsFJEmTaP!88;0VT#kNEl|MSZo`(uSe*50_HqV z8YHd-GKFg&Aw-}upd7AuV?NK!lNYfgNeyh%DD-=<3lk%QO~)`CxNSHm5<%s(&|pz| zlT6~4#*_~3+^#VW8KF)V6YfQ?a+ zT^6@>fD<#i3Ih!1jGl=^rIS65d`Fz{;YiP%|)Qsb@d*(osXzO6>%hEmupEj2Q7 z9m=gGJeW+joQ;52VBG>YeK>XsBouGRka;jn@yjPAR`xHwurAGr5bM-w|)r2snr)OXW z$N@bx){20K{Ohs!qcP|;ViQVM2)4*E1&B=`RvVL=g3L?+PIM&gQfA} zj0*P9K(9ImtrUtfbr-R>45&<&5eaNAH#SYbjqWr41u(9`_ZNG`5EDgohmV?=f>nr#fe{3D=!Ps;y0L4yD{NX;c~|+w=rLQXPLpuRo?z_Vda( zPE9g|sgYTQ4V-He{G`*y!29Kxs{RGi{u41n{~LiR;U5kP9{;CXcFx4E6~o$C7M!n{ ztC`<6w{6kBQdT$ZTJ@JrA6%=fo_}HPg`1TP%ask+>?@Vc)17N2WmhiFT)dK=NiTGQ zfhuWP^0a*FF3*X7=g_-HuO7Ww8(yvrUl0C=mp;0*^60UpeO*hf$5(2fUSTKF*4)0= z)0fk;mp*ZC&ndbVD5m2jHv`+21KXCiA6yAM^_@*Q3Ju(-QA{UMt{j*-u;%fR4fIO! zOz~26<2QGHtKox&n@tCnn+|+*W~HfX#dCbk16FRuvt`|B54bXL<#sVfEQ%Sh9+M!h zlc!*=*L0s9KE#C&u{#PKOxuj|bc+wXqMh(ScFSJFJKC*y*>U)Q)ut6dUJvs6#vLJ_ zUVbVPg(pELxv0Fr@1Kf%h!tb{SL56YZBjr8Q>lR>Le0pe5_kf^qeznusmb$7;#ADA z`Dq|A8m^@>_ZOL>K(@lnV$OUK&MHLx41xyCa+XyfjiLq!s7$dyL`)kRgA8;r(TZCi zBJq}^9c;TA+tHN0$o~f2z&lJw)!;-zUJ*Hsq3;pyhGR9z>VYVm<2u1cWJO^!kmT6| ziJy^o=-%$teif3~x@`d0uB z(^Z_pd1B2Ah?v-NFPvBo<3FbzPL>@wj8|`i!+3y0yuq*|A?K9v@8Snt)&xBjOUQpc z;Bc0Jdw!Gm&LgL~P91^SkGa>=P}J|^Wn39$IFeJTiA@D&j_rki zq-i^ZEb!;Bxx7{6F>zw%1V=+Z2uQdrs_LhL!&~*kz^2>K!2$s;)W5su>Yh(Z>TyfR zUAs`a8|MR&;WMoQ)qJUDtMD~%d$IlN+uFVMkG)O=ajzC2r?4iJMBH36cwt}h`+Du? z!pvWzsyvt>pXrHh1xB88cH05bB+rFEJ(phWT`6f=@-#63Qq!m<^FHu>-o7Y)!||R2M_x|9cltd)d0}tA?jU#Q?dvYL zvno?AI`?o_>^ydY@Ntb25!qc<|YSSg9^Q-D;+ZYFmQ zxh@wv6qI#TE<6jS z^f+mIKrgmzm>B$gK#2mX`fR_64%1_-GyG7DYqZ>H8|KHGwnLWy)F=CZ=IDUKhDY|A zHIU8$vadhV2GBT6)DqN;Q>18e1g2ORzYGGej&XG~NDOXI8sRc15{a9pOOF_dA}e56 zg1y+Z6O!RDrH;c;3w8ZkMfny?9^0tgXJxV8P&E6Qb zpdDybakh};5s+WHERlOLDNGIUu^Nui#6{3eHyAf*JGqgcvnqUc$Z?ieL#zbrLcTGY3UZsT z!8MT@7!yETn7K@r+8a*c)P2lCj@6ephbtK`oO$S#tnwe3*h1aMX_p~G-tfQxPKN?D z_V=Twe0ce;^=t;PCZkZh=Loq5JIMTP!34tC3SU*rBko>_dw-5cC>;-FF6<_V)0L8j z9}wL^W{8I`DC+qMW$YY)CZ3Ey1!PVhG%FFnN9+Q$H(Yapi+jvr@LS4o6^Q|j{rv}l z-vz^))P~JKZlx2BFeX?fZ=MOC1>;hvgo{{iW1-pYmlyb9IMPdV*P$f}F|y*qIWR4y zssEm0cGK&d^deG+iw@|1QtU_F6=w=_cpgz9^}kW7cXZr1mCNef;D1C{#gbQ4zp>ew zo>*N)K@ZVpJMa&9lQ6C)o0?oJ4bJ=L{0qmIOB<%0Kk}EXm6Wsl!Ni#_PCLjQ6t@n} zj(~u>o30HnyZ4i%)}!) zg47WpvF8_7uUjfx)L?sH4aBN%c(U$IlPdoBBeDH&_^7~iHtKb zQMm-k69O)*c@VlK7p)L=pLr z^Hg>O@omx(rX!+pfcB9x4XPbrjifrBml+$w%A0e130JE^0S+3Ke<>T8(nuF&+WV;yqMKlNa6=AB&g5iGUZ9}Sa2ZOC zXMqOofKDn|CoC8i6U>E(=p=&7w0utoOrIU1JRC^wr5jw7#Pv4RAG-6#8d1or-ojR4 z`Z@b#(z;cR}jEegYBoe7#c%xaYk=cp+Ag7N1{B9ZHeOx?A*Vb-ct=jbEqjXj6=FhZpbnD|X-yw(XyN=33wa)Ku z5%C7Ot3$#>X)4?SbqN95nN!WubFVOM$V6>^bSiA#s(j|TS6&H;KOtjp$l2Z9+liYk zy45eTpZw|z_M@{iBzA^uz4+_y4n58n>Naw53hp8wkHk6dq2*;RiMY%{Q|-v1JIS|F zqyN1GKP#-eapyU-N2#16CWMRGF%jlJ&;7Z`jK>d=5VmCsTwIL?(1B^59W%j=@GqS@ z(%*6HNXOG%-ADB@-V3ZIz=9AUpeBX8R8G+ihCQQ7RHeDo-M#3~^EkjlQU^cRQcEG2 z7L7yC`zV_o+?Lu&amVOI-evsc^J^6P61^7j(mjXRRr0u_gZ%b&S1+2!j}IsVIg)XE z_+Lo3v1#4o6GNFAw^%jX zK7VBHNJc<#A-YbVI~A>B!{V-tfY0^4?DHM_I{o^YES?s{t#<@^|7_G&B}#V$yfXWQ zoxACBk&+;EIIG)s-to(#Shk8AIr?V$7MM@ma?!SoonmkM{8yT0nr5G!@15(#iR}8T z^>b&IeLFHvN(C$9Ey}oA(1ZIsGF}$MeN{zQ+Gg5jWpF|nRy$k=T)y=pmfUUkiWN(> z7zV!I+wnI|-)~x{V5U~sQNOxv_Z@e+ShwoK{m}T{E-tw;JTtryoJnS!_>Crwt3$Mz zlNrhhUjvu>^%pO{xbCH2VWF%7mjQO1t%ZC_Ewi7#q_I?Jrr zO)=J$Bvh}LVtj%h*QQV?fE#l&R8OXu+UmXBJH6vd{Y?GkGwUT3J17d3HFum1V#R84 zSH_O-Z4{v2XvpPVcO!JCR}71;1*{Z4*BtEgojUee>Un;hVt;m4tP=OoBJIH(5_)e!AoGnY%@ZVSMNR1yq@ob^rhX literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/click/_compat.py b/venv/lib/python3.12/site-packages/click/_compat.py new file mode 100644 index 0000000..23f8866 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/_compat.py @@ -0,0 +1,623 @@ +import codecs +import io +import os +import re +import sys +import typing as t +from weakref import WeakKeyDictionary + +CYGWIN = sys.platform.startswith("cygwin") +WIN = sys.platform.startswith("win") +auto_wrap_for_ansi: t.Optional[t.Callable[[t.TextIO], t.TextIO]] = None +_ansi_re = re.compile(r"\033\[[;?0-9]*[a-zA-Z]") + + +def _make_text_stream( + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if encoding is None: + encoding = get_best_encoding(stream) + if errors is None: + errors = "replace" + return _NonClosingTextIOWrapper( + stream, + encoding, + errors, + line_buffering=True, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def is_ascii_encoding(encoding: str) -> bool: + """Checks if a given encoding is ascii.""" + try: + return codecs.lookup(encoding).name == "ascii" + except LookupError: + return False + + +def get_best_encoding(stream: t.IO[t.Any]) -> str: + """Returns the default stream encoding if not found.""" + rv = getattr(stream, "encoding", None) or sys.getdefaultencoding() + if is_ascii_encoding(rv): + return "utf-8" + return rv + + +class _NonClosingTextIOWrapper(io.TextIOWrapper): + def __init__( + self, + stream: t.BinaryIO, + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, + force_writable: bool = False, + **extra: t.Any, + ) -> None: + self._stream = stream = t.cast( + t.BinaryIO, _FixupStream(stream, force_readable, force_writable) + ) + super().__init__(stream, encoding, errors, **extra) + + def __del__(self) -> None: + try: + self.detach() + except Exception: + pass + + def isatty(self) -> bool: + # https://bitbucket.org/pypy/pypy/issue/1803 + return self._stream.isatty() + + +class _FixupStream: + """The new io interface needs more from streams than streams + traditionally implement. As such, this fix-up code is necessary in + some circumstances. + + The forcing of readable and writable flags are there because some tools + put badly patched objects on sys (one such offender are certain version + of jupyter notebook). + """ + + def __init__( + self, + stream: t.BinaryIO, + force_readable: bool = False, + force_writable: bool = False, + ): + self._stream = stream + self._force_readable = force_readable + self._force_writable = force_writable + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._stream, name) + + def read1(self, size: int) -> bytes: + f = getattr(self._stream, "read1", None) + + if f is not None: + return t.cast(bytes, f(size)) + + return self._stream.read(size) + + def readable(self) -> bool: + if self._force_readable: + return True + x = getattr(self._stream, "readable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.read(0) + except Exception: + return False + return True + + def writable(self) -> bool: + if self._force_writable: + return True + x = getattr(self._stream, "writable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.write("") # type: ignore + except Exception: + try: + self._stream.write(b"") + except Exception: + return False + return True + + def seekable(self) -> bool: + x = getattr(self._stream, "seekable", None) + if x is not None: + return t.cast(bool, x()) + try: + self._stream.seek(self._stream.tell()) + except Exception: + return False + return True + + +def _is_binary_reader(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + return isinstance(stream.read(0), bytes) + except Exception: + return default + # This happens in some cases where the stream was already + # closed. In this case, we assume the default. + + +def _is_binary_writer(stream: t.IO[t.Any], default: bool = False) -> bool: + try: + stream.write(b"") + except Exception: + try: + stream.write("") + return False + except Exception: + pass + return default + return True + + +def _find_binary_reader(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_reader(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_reader(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _find_binary_writer(stream: t.IO[t.Any]) -> t.Optional[t.BinaryIO]: + # We need to figure out if the given stream is already binary. + # This can happen because the official docs recommend detaching + # the streams to get binary streams. Some code might do this, so + # we need to deal with this case explicitly. + if _is_binary_writer(stream, False): + return t.cast(t.BinaryIO, stream) + + buf = getattr(stream, "buffer", None) + + # Same situation here; this time we assume that the buffer is + # actually binary in case it's closed. + if buf is not None and _is_binary_writer(buf, True): + return t.cast(t.BinaryIO, buf) + + return None + + +def _stream_is_misconfigured(stream: t.TextIO) -> bool: + """A stream is misconfigured if its encoding is ASCII.""" + # If the stream does not have an encoding set, we assume it's set + # to ASCII. This appears to happen in certain unittest + # environments. It's not quite clear what the correct behavior is + # but this at least will force Click to recover somehow. + return is_ascii_encoding(getattr(stream, "encoding", None) or "ascii") + + +def _is_compat_stream_attr(stream: t.TextIO, attr: str, value: t.Optional[str]) -> bool: + """A stream attribute is compatible if it is equal to the + desired value or the desired value is unset and the attribute + has a value. + """ + stream_value = getattr(stream, attr, None) + return stream_value == value or (value is None and stream_value is not None) + + +def _is_compatible_text_stream( + stream: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> bool: + """Check if a stream's encoding and errors attributes are + compatible with the desired values. + """ + return _is_compat_stream_attr( + stream, "encoding", encoding + ) and _is_compat_stream_attr(stream, "errors", errors) + + +def _force_correct_text_stream( + text_stream: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + is_binary: t.Callable[[t.IO[t.Any], bool], bool], + find_binary: t.Callable[[t.IO[t.Any]], t.Optional[t.BinaryIO]], + force_readable: bool = False, + force_writable: bool = False, +) -> t.TextIO: + if is_binary(text_stream, False): + binary_reader = t.cast(t.BinaryIO, text_stream) + else: + text_stream = t.cast(t.TextIO, text_stream) + # If the stream looks compatible, and won't default to a + # misconfigured ascii encoding, return it as-is. + if _is_compatible_text_stream(text_stream, encoding, errors) and not ( + encoding is None and _stream_is_misconfigured(text_stream) + ): + return text_stream + + # Otherwise, get the underlying binary reader. + possible_binary_reader = find_binary(text_stream) + + # If that's not possible, silently use the original reader + # and get mojibake instead of exceptions. + if possible_binary_reader is None: + return text_stream + + binary_reader = possible_binary_reader + + # Default errors to replace instead of strict in order to get + # something that works. + if errors is None: + errors = "replace" + + # Wrap the binary stream in a text stream with the correct + # encoding parameters. + return _make_text_stream( + binary_reader, + encoding, + errors, + force_readable=force_readable, + force_writable=force_writable, + ) + + +def _force_correct_text_reader( + text_reader: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_readable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_reader, + encoding, + errors, + _is_binary_reader, + _find_binary_reader, + force_readable=force_readable, + ) + + +def _force_correct_text_writer( + text_writer: t.IO[t.Any], + encoding: t.Optional[str], + errors: t.Optional[str], + force_writable: bool = False, +) -> t.TextIO: + return _force_correct_text_stream( + text_writer, + encoding, + errors, + _is_binary_writer, + _find_binary_writer, + force_writable=force_writable, + ) + + +def get_binary_stdin() -> t.BinaryIO: + reader = _find_binary_reader(sys.stdin) + if reader is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdin.") + return reader + + +def get_binary_stdout() -> t.BinaryIO: + writer = _find_binary_writer(sys.stdout) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stdout.") + return writer + + +def get_binary_stderr() -> t.BinaryIO: + writer = _find_binary_writer(sys.stderr) + if writer is None: + raise RuntimeError("Was not able to determine binary stream for sys.stderr.") + return writer + + +def get_text_stdin( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdin, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_reader(sys.stdin, encoding, errors, force_readable=True) + + +def get_text_stdout( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stdout, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stdout, encoding, errors, force_writable=True) + + +def get_text_stderr( + encoding: t.Optional[str] = None, errors: t.Optional[str] = None +) -> t.TextIO: + rv = _get_windows_console_stream(sys.stderr, encoding, errors) + if rv is not None: + return rv + return _force_correct_text_writer(sys.stderr, encoding, errors, force_writable=True) + + +def _wrap_io_open( + file: t.Union[str, "os.PathLike[str]", int], + mode: str, + encoding: t.Optional[str], + errors: t.Optional[str], +) -> t.IO[t.Any]: + """Handles not passing ``encoding`` and ``errors`` in binary mode.""" + if "b" in mode: + return open(file, mode) + + return open(file, mode, encoding=encoding, errors=errors) + + +def open_stream( + filename: "t.Union[str, os.PathLike[str]]", + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, +) -> t.Tuple[t.IO[t.Any], bool]: + binary = "b" in mode + filename = os.fspath(filename) + + # Standard streams first. These are simple because they ignore the + # atomic flag. Use fsdecode to handle Path("-"). + if os.fsdecode(filename) == "-": + if any(m in mode for m in ["w", "a", "x"]): + if binary: + return get_binary_stdout(), False + return get_text_stdout(encoding=encoding, errors=errors), False + if binary: + return get_binary_stdin(), False + return get_text_stdin(encoding=encoding, errors=errors), False + + # Non-atomic writes directly go out through the regular open functions. + if not atomic: + return _wrap_io_open(filename, mode, encoding, errors), True + + # Some usability stuff for atomic writes + if "a" in mode: + raise ValueError( + "Appending to an existing file is not supported, because that" + " would involve an expensive `copy`-operation to a temporary" + " file. Open the file in normal `w`-mode and copy explicitly" + " if that's what you're after." + ) + if "x" in mode: + raise ValueError("Use the `overwrite`-parameter instead.") + if "w" not in mode: + raise ValueError("Atomic writes only make sense with `w`-mode.") + + # Atomic writes are more complicated. They work by opening a file + # as a proxy in the same folder and then using the fdopen + # functionality to wrap it in a Python file. Then we wrap it in an + # atomic file that moves the file over on close. + import errno + import random + + try: + perm: t.Optional[int] = os.stat(filename).st_mode + except OSError: + perm = None + + flags = os.O_RDWR | os.O_CREAT | os.O_EXCL + + if binary: + flags |= getattr(os, "O_BINARY", 0) + + while True: + tmp_filename = os.path.join( + os.path.dirname(filename), + f".__atomic-write{random.randrange(1 << 32):08x}", + ) + try: + fd = os.open(tmp_filename, flags, 0o666 if perm is None else perm) + break + except OSError as e: + if e.errno == errno.EEXIST or ( + os.name == "nt" + and e.errno == errno.EACCES + and os.path.isdir(e.filename) + and os.access(e.filename, os.W_OK) + ): + continue + raise + + if perm is not None: + os.chmod(tmp_filename, perm) # in case perm includes bits in umask + + f = _wrap_io_open(fd, mode, encoding, errors) + af = _AtomicFile(f, tmp_filename, os.path.realpath(filename)) + return t.cast(t.IO[t.Any], af), True + + +class _AtomicFile: + def __init__(self, f: t.IO[t.Any], tmp_filename: str, real_filename: str) -> None: + self._f = f + self._tmp_filename = tmp_filename + self._real_filename = real_filename + self.closed = False + + @property + def name(self) -> str: + return self._real_filename + + def close(self, delete: bool = False) -> None: + if self.closed: + return + self._f.close() + os.replace(self._tmp_filename, self._real_filename) + self.closed = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._f, name) + + def __enter__(self) -> "_AtomicFile": + return self + + def __exit__(self, exc_type: t.Optional[t.Type[BaseException]], *_: t.Any) -> None: + self.close(delete=exc_type is not None) + + def __repr__(self) -> str: + return repr(self._f) + + +def strip_ansi(value: str) -> str: + return _ansi_re.sub("", value) + + +def _is_jupyter_kernel_output(stream: t.IO[t.Any]) -> bool: + while isinstance(stream, (_FixupStream, _NonClosingTextIOWrapper)): + stream = stream._stream + + return stream.__class__.__module__.startswith("ipykernel.") + + +def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None +) -> bool: + if color is None: + if stream is None: + stream = sys.stdin + return not isatty(stream) and not _is_jupyter_kernel_output(stream) + return not color + + +# On Windows, wrap the output streams with colorama to support ANSI +# color codes. +# NOTE: double check is needed so mypy does not analyze this on Linux +if sys.platform.startswith("win") and WIN: + from ._winconsole import _get_windows_console_stream + + def _get_argv_encoding() -> str: + import locale + + return locale.getpreferredencoding() + + _ansi_stream_wrappers: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def auto_wrap_for_ansi( # noqa: F811 + stream: t.TextIO, color: t.Optional[bool] = None + ) -> t.TextIO: + """Support ANSI color and style codes on Windows by wrapping a + stream with colorama. + """ + try: + cached = _ansi_stream_wrappers.get(stream) + except Exception: + cached = None + + if cached is not None: + return cached + + import colorama + + strip = should_strip_ansi(stream, color) + ansi_wrapper = colorama.AnsiToWin32(stream, strip=strip) + rv = t.cast(t.TextIO, ansi_wrapper.stream) + _write = rv.write + + def _safe_write(s): + try: + return _write(s) + except BaseException: + ansi_wrapper.reset_all() + raise + + rv.write = _safe_write + + try: + _ansi_stream_wrappers[stream] = rv + except Exception: + pass + + return rv + +else: + + def _get_argv_encoding() -> str: + return getattr(sys.stdin, "encoding", None) or sys.getfilesystemencoding() + + def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] + ) -> t.Optional[t.TextIO]: + return None + + +def term_len(x: str) -> int: + return len(strip_ansi(x)) + + +def isatty(stream: t.IO[t.Any]) -> bool: + try: + return stream.isatty() + except Exception: + return False + + +def _make_cached_stream_func( + src_func: t.Callable[[], t.Optional[t.TextIO]], + wrapper_func: t.Callable[[], t.TextIO], +) -> t.Callable[[], t.Optional[t.TextIO]]: + cache: t.MutableMapping[t.TextIO, t.TextIO] = WeakKeyDictionary() + + def func() -> t.Optional[t.TextIO]: + stream = src_func() + + if stream is None: + return None + + try: + rv = cache.get(stream) + except Exception: + rv = None + if rv is not None: + return rv + rv = wrapper_func() + try: + cache[stream] = rv + except Exception: + pass + return rv + + return func + + +_default_text_stdin = _make_cached_stream_func(lambda: sys.stdin, get_text_stdin) +_default_text_stdout = _make_cached_stream_func(lambda: sys.stdout, get_text_stdout) +_default_text_stderr = _make_cached_stream_func(lambda: sys.stderr, get_text_stderr) + + +binary_streams: t.Mapping[str, t.Callable[[], t.BinaryIO]] = { + "stdin": get_binary_stdin, + "stdout": get_binary_stdout, + "stderr": get_binary_stderr, +} + +text_streams: t.Mapping[ + str, t.Callable[[t.Optional[str], t.Optional[str]], t.TextIO] +] = { + "stdin": get_text_stdin, + "stdout": get_text_stdout, + "stderr": get_text_stderr, +} diff --git a/venv/lib/python3.12/site-packages/click/_termui_impl.py b/venv/lib/python3.12/site-packages/click/_termui_impl.py new file mode 100644 index 0000000..f744657 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/_termui_impl.py @@ -0,0 +1,739 @@ +""" +This module contains implementations for the termui module. To keep the +import time of Click down, some infrequently used functionality is +placed in this module and only imported as needed. +""" +import contextlib +import math +import os +import sys +import time +import typing as t +from gettext import gettext as _ +from io import StringIO +from types import TracebackType + +from ._compat import _default_text_stdout +from ._compat import CYGWIN +from ._compat import get_best_encoding +from ._compat import isatty +from ._compat import open_stream +from ._compat import strip_ansi +from ._compat import term_len +from ._compat import WIN +from .exceptions import ClickException +from .utils import echo + +V = t.TypeVar("V") + +if os.name == "nt": + BEFORE_BAR = "\r" + AFTER_BAR = "\n" +else: + BEFORE_BAR = "\r\033[?25l" + AFTER_BAR = "\033[?25h\n" + + +class ProgressBar(t.Generic[V]): + def __init__( + self, + iterable: t.Optional[t.Iterable[V]], + length: t.Optional[int] = None, + fill_char: str = "#", + empty_char: str = " ", + bar_template: str = "%(bar)s", + info_sep: str = " ", + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + label: t.Optional[str] = None, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, + width: int = 30, + ) -> None: + self.fill_char = fill_char + self.empty_char = empty_char + self.bar_template = bar_template + self.info_sep = info_sep + self.show_eta = show_eta + self.show_percent = show_percent + self.show_pos = show_pos + self.item_show_func = item_show_func + self.label: str = label or "" + + if file is None: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + file = StringIO() + + self.file = file + self.color = color + self.update_min_steps = update_min_steps + self._completed_intervals = 0 + self.width: int = width + self.autowidth: bool = width == 0 + + if length is None: + from operator import length_hint + + length = length_hint(iterable, -1) + + if length == -1: + length = None + if iterable is None: + if length is None: + raise TypeError("iterable or length is required") + iterable = t.cast(t.Iterable[V], range(length)) + self.iter: t.Iterable[V] = iter(iterable) + self.length = length + self.pos = 0 + self.avg: t.List[float] = [] + self.last_eta: float + self.start: float + self.start = self.last_eta = time.time() + self.eta_known: bool = False + self.finished: bool = False + self.max_width: t.Optional[int] = None + self.entered: bool = False + self.current_item: t.Optional[V] = None + self.is_hidden: bool = not isatty(self.file) + self._last_line: t.Optional[str] = None + + def __enter__(self) -> "ProgressBar[V]": + self.entered = True + self.render_progress() + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.render_finish() + + def __iter__(self) -> t.Iterator[V]: + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + self.render_progress() + return self.generator() + + def __next__(self) -> V: + # Iteration is defined in terms of a generator function, + # returned by iter(self); use that to define next(). This works + # because `self.iter` is an iterable consumed by that generator, + # so it is re-entry safe. Calling `next(self.generator())` + # twice works and does "what you want". + return next(iter(self)) + + def render_finish(self) -> None: + if self.is_hidden: + return + self.file.write(AFTER_BAR) + self.file.flush() + + @property + def pct(self) -> float: + if self.finished: + return 1.0 + return min(self.pos / (float(self.length or 1) or 1), 1.0) + + @property + def time_per_iteration(self) -> float: + if not self.avg: + return 0.0 + return sum(self.avg) / float(len(self.avg)) + + @property + def eta(self) -> float: + if self.length is not None and not self.finished: + return self.time_per_iteration * (self.length - self.pos) + return 0.0 + + def format_eta(self) -> str: + if self.eta_known: + t = int(self.eta) + seconds = t % 60 + t //= 60 + minutes = t % 60 + t //= 60 + hours = t % 24 + t //= 24 + if t > 0: + return f"{t}d {hours:02}:{minutes:02}:{seconds:02}" + else: + return f"{hours:02}:{minutes:02}:{seconds:02}" + return "" + + def format_pos(self) -> str: + pos = str(self.pos) + if self.length is not None: + pos += f"/{self.length}" + return pos + + def format_pct(self) -> str: + return f"{int(self.pct * 100): 4}%"[1:] + + def format_bar(self) -> str: + if self.length is not None: + bar_length = int(self.pct * self.width) + bar = self.fill_char * bar_length + bar += self.empty_char * (self.width - bar_length) + elif self.finished: + bar = self.fill_char * self.width + else: + chars = list(self.empty_char * (self.width or 1)) + if self.time_per_iteration != 0: + chars[ + int( + (math.cos(self.pos * self.time_per_iteration) / 2.0 + 0.5) + * self.width + ) + ] = self.fill_char + bar = "".join(chars) + return bar + + def format_progress_line(self) -> str: + show_percent = self.show_percent + + info_bits = [] + if self.length is not None and show_percent is None: + show_percent = not self.show_pos + + if self.show_pos: + info_bits.append(self.format_pos()) + if show_percent: + info_bits.append(self.format_pct()) + if self.show_eta and self.eta_known and not self.finished: + info_bits.append(self.format_eta()) + if self.item_show_func is not None: + item_info = self.item_show_func(self.current_item) + if item_info is not None: + info_bits.append(item_info) + + return ( + self.bar_template + % { + "label": self.label, + "bar": self.format_bar(), + "info": self.info_sep.join(info_bits), + } + ).rstrip() + + def render_progress(self) -> None: + import shutil + + if self.is_hidden: + # Only output the label as it changes if the output is not a + # TTY. Use file=stderr if you expect to be piping stdout. + if self._last_line != self.label: + self._last_line = self.label + echo(self.label, file=self.file, color=self.color) + + return + + buf = [] + # Update width in case the terminal has been resized + if self.autowidth: + old_width = self.width + self.width = 0 + clutter_length = term_len(self.format_progress_line()) + new_width = max(0, shutil.get_terminal_size().columns - clutter_length) + if new_width < old_width: + buf.append(BEFORE_BAR) + buf.append(" " * self.max_width) # type: ignore + self.max_width = new_width + self.width = new_width + + clear_width = self.width + if self.max_width is not None: + clear_width = self.max_width + + buf.append(BEFORE_BAR) + line = self.format_progress_line() + line_len = term_len(line) + if self.max_width is None or self.max_width < line_len: + self.max_width = line_len + + buf.append(line) + buf.append(" " * (clear_width - line_len)) + line = "".join(buf) + # Render the line only if it changed. + + if line != self._last_line: + self._last_line = line + echo(line, file=self.file, color=self.color, nl=False) + self.file.flush() + + def make_step(self, n_steps: int) -> None: + self.pos += n_steps + if self.length is not None and self.pos >= self.length: + self.finished = True + + if (time.time() - self.last_eta) < 1.0: + return + + self.last_eta = time.time() + + # self.avg is a rolling list of length <= 7 of steps where steps are + # defined as time elapsed divided by the total progress through + # self.length. + if self.pos: + step = (time.time() - self.start) / self.pos + else: + step = time.time() - self.start + + self.avg = self.avg[-6:] + [step] + + self.eta_known = self.length is not None + + def update(self, n_steps: int, current_item: t.Optional[V] = None) -> None: + """Update the progress bar by advancing a specified number of + steps, and optionally set the ``current_item`` for this new + position. + + :param n_steps: Number of steps to advance. + :param current_item: Optional item to set as ``current_item`` + for the updated position. + + .. versionchanged:: 8.0 + Added the ``current_item`` optional parameter. + + .. versionchanged:: 8.0 + Only render when the number of steps meets the + ``update_min_steps`` threshold. + """ + if current_item is not None: + self.current_item = current_item + + self._completed_intervals += n_steps + + if self._completed_intervals >= self.update_min_steps: + self.make_step(self._completed_intervals) + self.render_progress() + self._completed_intervals = 0 + + def finish(self) -> None: + self.eta_known = False + self.current_item = None + self.finished = True + + def generator(self) -> t.Iterator[V]: + """Return a generator which yields the items added to the bar + during construction, and updates the progress bar *after* the + yielded block returns. + """ + # WARNING: the iterator interface for `ProgressBar` relies on + # this and only works because this is a simple generator which + # doesn't create or manage additional state. If this function + # changes, the impact should be evaluated both against + # `iter(bar)` and `next(bar)`. `next()` in particular may call + # `self.generator()` repeatedly, and this must remain safe in + # order for that interface to work. + if not self.entered: + raise RuntimeError("You need to use progress bars in a with block.") + + if self.is_hidden: + yield from self.iter + else: + for rv in self.iter: + self.current_item = rv + + # This allows show_item_func to be updated before the + # item is processed. Only trigger at the beginning of + # the update interval. + if self._completed_intervals == 0: + self.render_progress() + + yield rv + self.update(1) + + self.finish() + self.render_progress() + + +def pager(generator: t.Iterable[str], color: t.Optional[bool] = None) -> None: + """Decide what method to use for paging through text.""" + stdout = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if stdout is None: + stdout = StringIO() + + if not isatty(sys.stdin) or not isatty(stdout): + return _nullpager(stdout, generator, color) + pager_cmd = (os.environ.get("PAGER", None) or "").strip() + if pager_cmd: + if WIN: + return _tempfilepager(generator, pager_cmd, color) + return _pipepager(generator, pager_cmd, color) + if os.environ.get("TERM") in ("dumb", "emacs"): + return _nullpager(stdout, generator, color) + if WIN or sys.platform.startswith("os2"): + return _tempfilepager(generator, "more <", color) + if hasattr(os, "system") and os.system("(less) 2>/dev/null") == 0: + return _pipepager(generator, "less", color) + + import tempfile + + fd, filename = tempfile.mkstemp() + os.close(fd) + try: + if hasattr(os, "system") and os.system(f'more "{filename}"') == 0: + return _pipepager(generator, "more", color) + return _nullpager(stdout, generator, color) + finally: + os.unlink(filename) + + +def _pipepager(generator: t.Iterable[str], cmd: str, color: t.Optional[bool]) -> None: + """Page through text by feeding it to another program. Invoking a + pager through this might support colors. + """ + import subprocess + + env = dict(os.environ) + + # If we're piping to less we might support colors under the + # condition that + cmd_detail = cmd.rsplit("/", 1)[-1].split() + if color is None and cmd_detail[0] == "less": + less_flags = f"{os.environ.get('LESS', '')}{' '.join(cmd_detail[1:])}" + if not less_flags: + env["LESS"] = "-R" + color = True + elif "r" in less_flags or "R" in less_flags: + color = True + + c = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, env=env) + stdin = t.cast(t.BinaryIO, c.stdin) + encoding = get_best_encoding(stdin) + try: + for text in generator: + if not color: + text = strip_ansi(text) + + stdin.write(text.encode(encoding, "replace")) + except (OSError, KeyboardInterrupt): + pass + else: + stdin.close() + + # Less doesn't respect ^C, but catches it for its own UI purposes (aborting + # search or other commands inside less). + # + # That means when the user hits ^C, the parent process (click) terminates, + # but less is still alive, paging the output and messing up the terminal. + # + # If the user wants to make the pager exit on ^C, they should set + # `LESS='-K'`. It's not our decision to make. + while True: + try: + c.wait() + except KeyboardInterrupt: + pass + else: + break + + +def _tempfilepager( + generator: t.Iterable[str], cmd: str, color: t.Optional[bool] +) -> None: + """Page through text by invoking a program on a temporary file.""" + import tempfile + + fd, filename = tempfile.mkstemp() + # TODO: This never terminates if the passed generator never terminates. + text = "".join(generator) + if not color: + text = strip_ansi(text) + encoding = get_best_encoding(sys.stdout) + with open_stream(filename, "wb")[0] as f: + f.write(text.encode(encoding)) + try: + os.system(f'{cmd} "{filename}"') + finally: + os.close(fd) + os.unlink(filename) + + +def _nullpager( + stream: t.TextIO, generator: t.Iterable[str], color: t.Optional[bool] +) -> None: + """Simply print unformatted text. This is the ultimate fallback.""" + for text in generator: + if not color: + text = strip_ansi(text) + stream.write(text) + + +class Editor: + def __init__( + self, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + ) -> None: + self.editor = editor + self.env = env + self.require_save = require_save + self.extension = extension + + def get_editor(self) -> str: + if self.editor is not None: + return self.editor + for key in "VISUAL", "EDITOR": + rv = os.environ.get(key) + if rv: + return rv + if WIN: + return "notepad" + for editor in "sensible-editor", "vim", "nano": + if os.system(f"which {editor} >/dev/null 2>&1") == 0: + return editor + return "vi" + + def edit_file(self, filename: str) -> None: + import subprocess + + editor = self.get_editor() + environ: t.Optional[t.Dict[str, str]] = None + + if self.env: + environ = os.environ.copy() + environ.update(self.env) + + try: + c = subprocess.Popen(f'{editor} "{filename}"', env=environ, shell=True) + exit_code = c.wait() + if exit_code != 0: + raise ClickException( + _("{editor}: Editing failed").format(editor=editor) + ) + except OSError as e: + raise ClickException( + _("{editor}: Editing failed: {e}").format(editor=editor, e=e) + ) from e + + def edit(self, text: t.Optional[t.AnyStr]) -> t.Optional[t.AnyStr]: + import tempfile + + if not text: + data = b"" + elif isinstance(text, (bytes, bytearray)): + data = text + else: + if text and not text.endswith("\n"): + text += "\n" + + if WIN: + data = text.replace("\n", "\r\n").encode("utf-8-sig") + else: + data = text.encode("utf-8") + + fd, name = tempfile.mkstemp(prefix="editor-", suffix=self.extension) + f: t.BinaryIO + + try: + with os.fdopen(fd, "wb") as f: + f.write(data) + + # If the filesystem resolution is 1 second, like Mac OS + # 10.12 Extended, or 2 seconds, like FAT32, and the editor + # closes very fast, require_save can fail. Set the modified + # time to be 2 seconds in the past to work around this. + os.utime(name, (os.path.getatime(name), os.path.getmtime(name) - 2)) + # Depending on the resolution, the exact value might not be + # recorded, so get the new recorded value. + timestamp = os.path.getmtime(name) + + self.edit_file(name) + + if self.require_save and os.path.getmtime(name) == timestamp: + return None + + with open(name, "rb") as f: + rv = f.read() + + if isinstance(text, (bytes, bytearray)): + return rv + + return rv.decode("utf-8-sig").replace("\r\n", "\n") # type: ignore + finally: + os.unlink(name) + + +def open_url(url: str, wait: bool = False, locate: bool = False) -> int: + import subprocess + + def _unquote_file(url: str) -> str: + from urllib.parse import unquote + + if url.startswith("file://"): + url = unquote(url[7:]) + + return url + + if sys.platform == "darwin": + args = ["open"] + if wait: + args.append("-W") + if locate: + args.append("-R") + args.append(_unquote_file(url)) + null = open("/dev/null", "w") + try: + return subprocess.Popen(args, stderr=null).wait() + finally: + null.close() + elif WIN: + if locate: + url = _unquote_file(url.replace('"', "")) + args = f'explorer /select,"{url}"' + else: + url = url.replace('"', "") + wait_str = "/WAIT" if wait else "" + args = f'start {wait_str} "" "{url}"' + return os.system(args) + elif CYGWIN: + if locate: + url = os.path.dirname(_unquote_file(url).replace('"', "")) + args = f'cygstart "{url}"' + else: + url = url.replace('"', "") + wait_str = "-w" if wait else "" + args = f'cygstart {wait_str} "{url}"' + return os.system(args) + + try: + if locate: + url = os.path.dirname(_unquote_file(url)) or "." + else: + url = _unquote_file(url) + c = subprocess.Popen(["xdg-open", url]) + if wait: + return c.wait() + return 0 + except OSError: + if url.startswith(("http://", "https://")) and not locate and not wait: + import webbrowser + + webbrowser.open(url) + return 0 + return 1 + + +def _translate_ch_to_exc(ch: str) -> t.Optional[BaseException]: + if ch == "\x03": + raise KeyboardInterrupt() + + if ch == "\x04" and not WIN: # Unix-like, Ctrl+D + raise EOFError() + + if ch == "\x1a" and WIN: # Windows, Ctrl+Z + raise EOFError() + + return None + + +if WIN: + import msvcrt + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + yield -1 + + def getchar(echo: bool) -> str: + # The function `getch` will return a bytes object corresponding to + # the pressed character. Since Windows 10 build 1803, it will also + # return \x00 when called a second time after pressing a regular key. + # + # `getwch` does not share this probably-bugged behavior. Moreover, it + # returns a Unicode object by default, which is what we want. + # + # Either of these functions will return \x00 or \xe0 to indicate + # a special key, and you need to call the same function again to get + # the "rest" of the code. The fun part is that \u00e0 is + # "latin small letter a with grave", so if you type that on a French + # keyboard, you _also_ get a \xe0. + # E.g., consider the Up arrow. This returns \xe0 and then \x48. The + # resulting Unicode string reads as "a with grave" + "capital H". + # This is indistinguishable from when the user actually types + # "a with grave" and then "capital H". + # + # When \xe0 is returned, we assume it's part of a special-key sequence + # and call `getwch` again, but that means that when the user types + # the \u00e0 character, `getchar` doesn't return until a second + # character is typed. + # The alternative is returning immediately, but that would mess up + # cross-platform handling of arrow keys and others that start with + # \xe0. Another option is using `getch`, but then we can't reliably + # read non-ASCII characters, because return values of `getch` are + # limited to the current 8-bit codepage. + # + # Anyway, Click doesn't claim to do this Right(tm), and using `getwch` + # is doing the right thing in more situations than with `getch`. + func: t.Callable[[], str] + + if echo: + func = msvcrt.getwche # type: ignore + else: + func = msvcrt.getwch # type: ignore + + rv = func() + + if rv in ("\x00", "\xe0"): + # \x00 and \xe0 are control characters that indicate special key, + # see above. + rv += func() + + _translate_ch_to_exc(rv) + return rv + +else: + import tty + import termios + + @contextlib.contextmanager + def raw_terminal() -> t.Iterator[int]: + f: t.Optional[t.TextIO] + fd: int + + if not isatty(sys.stdin): + f = open("/dev/tty") + fd = f.fileno() + else: + fd = sys.stdin.fileno() + f = None + + try: + old_settings = termios.tcgetattr(fd) + + try: + tty.setraw(fd) + yield fd + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + sys.stdout.flush() + + if f is not None: + f.close() + except termios.error: + pass + + def getchar(echo: bool) -> str: + with raw_terminal() as fd: + ch = os.read(fd, 32).decode(get_best_encoding(sys.stdin), "replace") + + if echo and isatty(sys.stdout): + sys.stdout.write(ch) + + _translate_ch_to_exc(ch) + return ch diff --git a/venv/lib/python3.12/site-packages/click/_textwrap.py b/venv/lib/python3.12/site-packages/click/_textwrap.py new file mode 100644 index 0000000..b47dcbd --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/_textwrap.py @@ -0,0 +1,49 @@ +import textwrap +import typing as t +from contextlib import contextmanager + + +class TextWrapper(textwrap.TextWrapper): + def _handle_long_word( + self, + reversed_chunks: t.List[str], + cur_line: t.List[str], + cur_len: int, + width: int, + ) -> None: + space_left = max(width - cur_len, 1) + + if self.break_long_words: + last = reversed_chunks[-1] + cut = last[:space_left] + res = last[space_left:] + cur_line.append(cut) + reversed_chunks[-1] = res + elif not cur_line: + cur_line.append(reversed_chunks.pop()) + + @contextmanager + def extra_indent(self, indent: str) -> t.Iterator[None]: + old_initial_indent = self.initial_indent + old_subsequent_indent = self.subsequent_indent + self.initial_indent += indent + self.subsequent_indent += indent + + try: + yield + finally: + self.initial_indent = old_initial_indent + self.subsequent_indent = old_subsequent_indent + + def indent_only(self, text: str) -> str: + rv = [] + + for idx, line in enumerate(text.splitlines()): + indent = self.initial_indent + + if idx > 0: + indent = self.subsequent_indent + + rv.append(f"{indent}{line}") + + return "\n".join(rv) diff --git a/venv/lib/python3.12/site-packages/click/_winconsole.py b/venv/lib/python3.12/site-packages/click/_winconsole.py new file mode 100644 index 0000000..6b20df3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/_winconsole.py @@ -0,0 +1,279 @@ +# This module is based on the excellent work by Adam Bartoš who +# provided a lot of what went into the implementation here in +# the discussion to issue1602 in the Python bug tracker. +# +# There are some general differences in regards to how this works +# compared to the original patches as we do not need to patch +# the entire interpreter but just work in our little world of +# echo and prompt. +import io +import sys +import time +import typing as t +from ctypes import byref +from ctypes import c_char +from ctypes import c_char_p +from ctypes import c_int +from ctypes import c_ssize_t +from ctypes import c_ulong +from ctypes import c_void_p +from ctypes import POINTER +from ctypes import py_object +from ctypes import Structure +from ctypes.wintypes import DWORD +from ctypes.wintypes import HANDLE +from ctypes.wintypes import LPCWSTR +from ctypes.wintypes import LPWSTR + +from ._compat import _NonClosingTextIOWrapper + +assert sys.platform == "win32" +import msvcrt # noqa: E402 +from ctypes import windll # noqa: E402 +from ctypes import WINFUNCTYPE # noqa: E402 + +c_ssize_p = POINTER(c_ssize_t) + +kernel32 = windll.kernel32 +GetStdHandle = kernel32.GetStdHandle +ReadConsoleW = kernel32.ReadConsoleW +WriteConsoleW = kernel32.WriteConsoleW +GetConsoleMode = kernel32.GetConsoleMode +GetLastError = kernel32.GetLastError +GetCommandLineW = WINFUNCTYPE(LPWSTR)(("GetCommandLineW", windll.kernel32)) +CommandLineToArgvW = WINFUNCTYPE(POINTER(LPWSTR), LPCWSTR, POINTER(c_int))( + ("CommandLineToArgvW", windll.shell32) +) +LocalFree = WINFUNCTYPE(c_void_p, c_void_p)(("LocalFree", windll.kernel32)) + +STDIN_HANDLE = GetStdHandle(-10) +STDOUT_HANDLE = GetStdHandle(-11) +STDERR_HANDLE = GetStdHandle(-12) + +PyBUF_SIMPLE = 0 +PyBUF_WRITABLE = 1 + +ERROR_SUCCESS = 0 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_OPERATION_ABORTED = 995 + +STDIN_FILENO = 0 +STDOUT_FILENO = 1 +STDERR_FILENO = 2 + +EOF = b"\x1a" +MAX_BYTES_WRITTEN = 32767 + +try: + from ctypes import pythonapi +except ImportError: + # On PyPy we cannot get buffers so our ability to operate here is + # severely limited. + get_buffer = None +else: + + class Py_buffer(Structure): + _fields_ = [ + ("buf", c_void_p), + ("obj", py_object), + ("len", c_ssize_t), + ("itemsize", c_ssize_t), + ("readonly", c_int), + ("ndim", c_int), + ("format", c_char_p), + ("shape", c_ssize_p), + ("strides", c_ssize_p), + ("suboffsets", c_ssize_p), + ("internal", c_void_p), + ] + + PyObject_GetBuffer = pythonapi.PyObject_GetBuffer + PyBuffer_Release = pythonapi.PyBuffer_Release + + def get_buffer(obj, writable=False): + buf = Py_buffer() + flags = PyBUF_WRITABLE if writable else PyBUF_SIMPLE + PyObject_GetBuffer(py_object(obj), byref(buf), flags) + + try: + buffer_type = c_char * buf.len + return buffer_type.from_address(buf.buf) + finally: + PyBuffer_Release(byref(buf)) + + +class _WindowsConsoleRawIOBase(io.RawIOBase): + def __init__(self, handle): + self.handle = handle + + def isatty(self): + super().isatty() + return True + + +class _WindowsConsoleReader(_WindowsConsoleRawIOBase): + def readable(self): + return True + + def readinto(self, b): + bytes_to_be_read = len(b) + if not bytes_to_be_read: + return 0 + elif bytes_to_be_read % 2: + raise ValueError( + "cannot read odd number of bytes from UTF-16-LE encoded console" + ) + + buffer = get_buffer(b, writable=True) + code_units_to_be_read = bytes_to_be_read // 2 + code_units_read = c_ulong() + + rv = ReadConsoleW( + HANDLE(self.handle), + buffer, + code_units_to_be_read, + byref(code_units_read), + None, + ) + if GetLastError() == ERROR_OPERATION_ABORTED: + # wait for KeyboardInterrupt + time.sleep(0.1) + if not rv: + raise OSError(f"Windows error: {GetLastError()}") + + if buffer[0] == EOF: + return 0 + return 2 * code_units_read.value + + +class _WindowsConsoleWriter(_WindowsConsoleRawIOBase): + def writable(self): + return True + + @staticmethod + def _get_error_message(errno): + if errno == ERROR_SUCCESS: + return "ERROR_SUCCESS" + elif errno == ERROR_NOT_ENOUGH_MEMORY: + return "ERROR_NOT_ENOUGH_MEMORY" + return f"Windows error {errno}" + + def write(self, b): + bytes_to_be_written = len(b) + buf = get_buffer(b) + code_units_to_be_written = min(bytes_to_be_written, MAX_BYTES_WRITTEN) // 2 + code_units_written = c_ulong() + + WriteConsoleW( + HANDLE(self.handle), + buf, + code_units_to_be_written, + byref(code_units_written), + None, + ) + bytes_written = 2 * code_units_written.value + + if bytes_written == 0 and bytes_to_be_written > 0: + raise OSError(self._get_error_message(GetLastError())) + return bytes_written + + +class ConsoleStream: + def __init__(self, text_stream: t.TextIO, byte_stream: t.BinaryIO) -> None: + self._text_stream = text_stream + self.buffer = byte_stream + + @property + def name(self) -> str: + return self.buffer.name + + def write(self, x: t.AnyStr) -> int: + if isinstance(x, str): + return self._text_stream.write(x) + try: + self.flush() + except Exception: + pass + return self.buffer.write(x) + + def writelines(self, lines: t.Iterable[t.AnyStr]) -> None: + for line in lines: + self.write(line) + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._text_stream, name) + + def isatty(self) -> bool: + return self.buffer.isatty() + + def __repr__(self): + return f"" + + +def _get_text_stdin(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedReader(_WindowsConsoleReader(STDIN_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stdout(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDOUT_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +def _get_text_stderr(buffer_stream: t.BinaryIO) -> t.TextIO: + text_stream = _NonClosingTextIOWrapper( + io.BufferedWriter(_WindowsConsoleWriter(STDERR_HANDLE)), + "utf-16-le", + "strict", + line_buffering=True, + ) + return t.cast(t.TextIO, ConsoleStream(text_stream, buffer_stream)) + + +_stream_factories: t.Mapping[int, t.Callable[[t.BinaryIO], t.TextIO]] = { + 0: _get_text_stdin, + 1: _get_text_stdout, + 2: _get_text_stderr, +} + + +def _is_console(f: t.TextIO) -> bool: + if not hasattr(f, "fileno"): + return False + + try: + fileno = f.fileno() + except (OSError, io.UnsupportedOperation): + return False + + handle = msvcrt.get_osfhandle(fileno) + return bool(GetConsoleMode(handle, byref(DWORD()))) + + +def _get_windows_console_stream( + f: t.TextIO, encoding: t.Optional[str], errors: t.Optional[str] +) -> t.Optional[t.TextIO]: + if ( + get_buffer is not None + and encoding in {"utf-16-le", None} + and errors in {"strict", None} + and _is_console(f) + ): + func = _stream_factories.get(f.fileno()) + if func is not None: + b = getattr(f, "buffer", None) + + if b is None: + return None + + return func(b) diff --git a/venv/lib/python3.12/site-packages/click/core.py b/venv/lib/python3.12/site-packages/click/core.py new file mode 100644 index 0000000..cc65e89 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/core.py @@ -0,0 +1,3042 @@ +import enum +import errno +import inspect +import os +import sys +import typing as t +from collections import abc +from contextlib import contextmanager +from contextlib import ExitStack +from functools import update_wrapper +from gettext import gettext as _ +from gettext import ngettext +from itertools import repeat +from types import TracebackType + +from . import types +from .exceptions import Abort +from .exceptions import BadParameter +from .exceptions import ClickException +from .exceptions import Exit +from .exceptions import MissingParameter +from .exceptions import UsageError +from .formatting import HelpFormatter +from .formatting import join_options +from .globals import pop_context +from .globals import push_context +from .parser import _flag_needs_value +from .parser import OptionParser +from .parser import split_opt +from .termui import confirm +from .termui import prompt +from .termui import style +from .utils import _detect_program_name +from .utils import _expand_args +from .utils import echo +from .utils import make_default_short_help +from .utils import make_str +from .utils import PacifyFlushWrapper + +if t.TYPE_CHECKING: + import typing_extensions as te + from .shell_completion import CompletionItem + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +V = t.TypeVar("V") + + +def _complete_visible_commands( + ctx: "Context", incomplete: str +) -> t.Iterator[t.Tuple[str, "Command"]]: + """List all the subcommands of a group that start with the + incomplete value and aren't hidden. + + :param ctx: Invocation context for the group. + :param incomplete: Value being completed. May be empty. + """ + multi = t.cast(MultiCommand, ctx.command) + + for name in multi.list_commands(ctx): + if name.startswith(incomplete): + command = multi.get_command(ctx, name) + + if command is not None and not command.hidden: + yield name, command + + +def _check_multicommand( + base_command: "MultiCommand", cmd_name: str, cmd: "Command", register: bool = False +) -> None: + if not base_command.chain or not isinstance(cmd, MultiCommand): + return + if register: + hint = ( + "It is not possible to add multi commands as children to" + " another multi command that is in chain mode." + ) + else: + hint = ( + "Found a multi command as subcommand to a multi command" + " that is in chain mode. This is not supported." + ) + raise RuntimeError( + f"{hint}. Command {base_command.name!r} is set to chain and" + f" {cmd_name!r} was added as a subcommand but it in itself is a" + f" multi command. ({cmd_name!r} is a {type(cmd).__name__}" + f" within a chained {type(base_command).__name__} named" + f" {base_command.name!r})." + ) + + +def batch(iterable: t.Iterable[V], batch_size: int) -> t.List[t.Tuple[V, ...]]: + return list(zip(*repeat(iter(iterable), batch_size))) + + +@contextmanager +def augment_usage_errors( + ctx: "Context", param: t.Optional["Parameter"] = None +) -> t.Iterator[None]: + """Context manager that attaches extra information to exceptions.""" + try: + yield + except BadParameter as e: + if e.ctx is None: + e.ctx = ctx + if param is not None and e.param is None: + e.param = param + raise + except UsageError as e: + if e.ctx is None: + e.ctx = ctx + raise + + +def iter_params_for_processing( + invocation_order: t.Sequence["Parameter"], + declaration_order: t.Sequence["Parameter"], +) -> t.List["Parameter"]: + """Given a sequence of parameters in the order as should be considered + for processing and an iterable of parameters that exist, this returns + a list in the correct order as they should be processed. + """ + + def sort_key(item: "Parameter") -> t.Tuple[bool, float]: + try: + idx: float = invocation_order.index(item) + except ValueError: + idx = float("inf") + + return not item.is_eager, idx + + return sorted(declaration_order, key=sort_key) + + +class ParameterSource(enum.Enum): + """This is an :class:`~enum.Enum` that indicates the source of a + parameter's value. + + Use :meth:`click.Context.get_parameter_source` to get the + source for a parameter by name. + + .. versionchanged:: 8.0 + Use :class:`~enum.Enum` and drop the ``validate`` method. + + .. versionchanged:: 8.0 + Added the ``PROMPT`` value. + """ + + COMMANDLINE = enum.auto() + """The value was provided by the command line args.""" + ENVIRONMENT = enum.auto() + """The value was provided with an environment variable.""" + DEFAULT = enum.auto() + """Used the default specified by the parameter.""" + DEFAULT_MAP = enum.auto() + """Used a default provided by :attr:`Context.default_map`.""" + PROMPT = enum.auto() + """Used a prompt to confirm a default or provide a value.""" + + +class Context: + """The context is a special internal object that holds state relevant + for the script execution at every single level. It's normally invisible + to commands unless they opt-in to getting access to it. + + The context is useful as it can pass internal objects around and can + control special execution features such as reading data from + environment variables. + + A context can be used as context manager in which case it will call + :meth:`close` on teardown. + + :param command: the command class for this context. + :param parent: the parent context. + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it is usually + the name of the script, for commands below it it's + the name of the script. + :param obj: an arbitrary object of user data. + :param auto_envvar_prefix: the prefix to use for automatic environment + variables. If this is `None` then reading + from environment variables is disabled. This + does not affect manually set environment + variables which are always read. + :param default_map: a dictionary (like object) with default values + for parameters. + :param terminal_width: the width of the terminal. The default is + inherit from parent context. If no context + defines the terminal width then auto + detection will be applied. + :param max_content_width: the maximum width for content rendered by + Click (this currently only affects help + pages). This defaults to 80 characters if + not overridden. In other words: even if the + terminal is larger than that, Click will not + format things wider than 80 characters by + default. In addition to that, formatters might + add some safety mapping on the right. + :param resilient_parsing: if this flag is enabled then Click will + parse without any interactivity or callback + invocation. Default values will also be + ignored. This is useful for implementing + things such as completion support. + :param allow_extra_args: if this is set to `True` then extra arguments + at the end will not raise an error and will be + kept on the context. The default is to inherit + from the command. + :param allow_interspersed_args: if this is set to `False` then options + and arguments cannot be mixed. The + default is to inherit from the command. + :param ignore_unknown_options: instructs click to ignore options it does + not know and keeps them for later + processing. + :param help_option_names: optionally a list of strings that define how + the default help parameter is named. The + default is ``['--help']``. + :param token_normalize_func: an optional function that is used to + normalize tokens (options, choices, + etc.). This for instance can be used to + implement case insensitive behavior. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are used in texts that Click prints which is by + default not the case. This for instance would affect + help output. + :param show_default: Show the default value for commands. If this + value is not set, it defaults to the value from the parent + context. ``Command.show_default`` overrides this default for the + specific command. + + .. versionchanged:: 8.1 + The ``show_default`` parameter is overridden by + ``Command.show_default``, instead of the other way around. + + .. versionchanged:: 8.0 + The ``show_default`` parameter defaults to the value from the + parent context. + + .. versionchanged:: 7.1 + Added the ``show_default`` parameter. + + .. versionchanged:: 4.0 + Added the ``color``, ``ignore_unknown_options``, and + ``max_content_width`` parameters. + + .. versionchanged:: 3.0 + Added the ``allow_extra_args`` and ``allow_interspersed_args`` + parameters. + + .. versionchanged:: 2.0 + Added the ``resilient_parsing``, ``help_option_names``, and + ``token_normalize_func`` parameters. + """ + + #: The formatter class to create with :meth:`make_formatter`. + #: + #: .. versionadded:: 8.0 + formatter_class: t.Type["HelpFormatter"] = HelpFormatter + + def __init__( + self, + command: "Command", + parent: t.Optional["Context"] = None, + info_name: t.Optional[str] = None, + obj: t.Optional[t.Any] = None, + auto_envvar_prefix: t.Optional[str] = None, + default_map: t.Optional[t.MutableMapping[str, t.Any]] = None, + terminal_width: t.Optional[int] = None, + max_content_width: t.Optional[int] = None, + resilient_parsing: bool = False, + allow_extra_args: t.Optional[bool] = None, + allow_interspersed_args: t.Optional[bool] = None, + ignore_unknown_options: t.Optional[bool] = None, + help_option_names: t.Optional[t.List[str]] = None, + token_normalize_func: t.Optional[t.Callable[[str], str]] = None, + color: t.Optional[bool] = None, + show_default: t.Optional[bool] = None, + ) -> None: + #: the parent context or `None` if none exists. + self.parent = parent + #: the :class:`Command` for this context. + self.command = command + #: the descriptive information name + self.info_name = info_name + #: Map of parameter names to their parsed values. Parameters + #: with ``expose_value=False`` are not stored. + self.params: t.Dict[str, t.Any] = {} + #: the leftover arguments. + self.args: t.List[str] = [] + #: protected arguments. These are arguments that are prepended + #: to `args` when certain parsing scenarios are encountered but + #: must be never propagated to another arguments. This is used + #: to implement nested parsing. + self.protected_args: t.List[str] = [] + #: the collected prefixes of the command's options. + self._opt_prefixes: t.Set[str] = set(parent._opt_prefixes) if parent else set() + + if obj is None and parent is not None: + obj = parent.obj + + #: the user object stored. + self.obj: t.Any = obj + self._meta: t.Dict[str, t.Any] = getattr(parent, "meta", {}) + + #: A dictionary (-like object) with defaults for parameters. + if ( + default_map is None + and info_name is not None + and parent is not None + and parent.default_map is not None + ): + default_map = parent.default_map.get(info_name) + + self.default_map: t.Optional[t.MutableMapping[str, t.Any]] = default_map + + #: This flag indicates if a subcommand is going to be executed. A + #: group callback can use this information to figure out if it's + #: being executed directly or because the execution flow passes + #: onwards to a subcommand. By default it's None, but it can be + #: the name of the subcommand to execute. + #: + #: If chaining is enabled this will be set to ``'*'`` in case + #: any commands are executed. It is however not possible to + #: figure out which ones. If you require this knowledge you + #: should use a :func:`result_callback`. + self.invoked_subcommand: t.Optional[str] = None + + if terminal_width is None and parent is not None: + terminal_width = parent.terminal_width + + #: The width of the terminal (None is autodetection). + self.terminal_width: t.Optional[int] = terminal_width + + if max_content_width is None and parent is not None: + max_content_width = parent.max_content_width + + #: The maximum width of formatted content (None implies a sensible + #: default which is 80 for most things). + self.max_content_width: t.Optional[int] = max_content_width + + if allow_extra_args is None: + allow_extra_args = command.allow_extra_args + + #: Indicates if the context allows extra args or if it should + #: fail on parsing. + #: + #: .. versionadded:: 3.0 + self.allow_extra_args = allow_extra_args + + if allow_interspersed_args is None: + allow_interspersed_args = command.allow_interspersed_args + + #: Indicates if the context allows mixing of arguments and + #: options or not. + #: + #: .. versionadded:: 3.0 + self.allow_interspersed_args: bool = allow_interspersed_args + + if ignore_unknown_options is None: + ignore_unknown_options = command.ignore_unknown_options + + #: Instructs click to ignore options that a command does not + #: understand and will store it on the context for later + #: processing. This is primarily useful for situations where you + #: want to call into external programs. Generally this pattern is + #: strongly discouraged because it's not possibly to losslessly + #: forward all arguments. + #: + #: .. versionadded:: 4.0 + self.ignore_unknown_options: bool = ignore_unknown_options + + if help_option_names is None: + if parent is not None: + help_option_names = parent.help_option_names + else: + help_option_names = ["--help"] + + #: The names for the help options. + self.help_option_names: t.List[str] = help_option_names + + if token_normalize_func is None and parent is not None: + token_normalize_func = parent.token_normalize_func + + #: An optional normalization function for tokens. This is + #: options, choices, commands etc. + self.token_normalize_func: t.Optional[ + t.Callable[[str], str] + ] = token_normalize_func + + #: Indicates if resilient parsing is enabled. In that case Click + #: will do its best to not cause any failures and default values + #: will be ignored. Useful for completion. + self.resilient_parsing: bool = resilient_parsing + + # If there is no envvar prefix yet, but the parent has one and + # the command on this level has a name, we can expand the envvar + # prefix automatically. + if auto_envvar_prefix is None: + if ( + parent is not None + and parent.auto_envvar_prefix is not None + and self.info_name is not None + ): + auto_envvar_prefix = ( + f"{parent.auto_envvar_prefix}_{self.info_name.upper()}" + ) + else: + auto_envvar_prefix = auto_envvar_prefix.upper() + + if auto_envvar_prefix is not None: + auto_envvar_prefix = auto_envvar_prefix.replace("-", "_") + + self.auto_envvar_prefix: t.Optional[str] = auto_envvar_prefix + + if color is None and parent is not None: + color = parent.color + + #: Controls if styling output is wanted or not. + self.color: t.Optional[bool] = color + + if show_default is None and parent is not None: + show_default = parent.show_default + + #: Show option default values when formatting help text. + self.show_default: t.Optional[bool] = show_default + + self._close_callbacks: t.List[t.Callable[[], t.Any]] = [] + self._depth = 0 + self._parameter_source: t.Dict[str, ParameterSource] = {} + self._exit_stack = ExitStack() + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire CLI + structure. + + .. code-block:: python + + with Context(cli) as ctx: + info = ctx.to_info_dict() + + .. versionadded:: 8.0 + """ + return { + "command": self.command.to_info_dict(self), + "info_name": self.info_name, + "allow_extra_args": self.allow_extra_args, + "allow_interspersed_args": self.allow_interspersed_args, + "ignore_unknown_options": self.ignore_unknown_options, + "auto_envvar_prefix": self.auto_envvar_prefix, + } + + def __enter__(self) -> "Context": + self._depth += 1 + push_context(self) + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self._depth -= 1 + if self._depth == 0: + self.close() + pop_context() + + @contextmanager + def scope(self, cleanup: bool = True) -> t.Iterator["Context"]: + """This helper method can be used with the context object to promote + it to the current thread local (see :func:`get_current_context`). + The default behavior of this is to invoke the cleanup functions which + can be disabled by setting `cleanup` to `False`. The cleanup + functions are typically used for things such as closing file handles. + + If the cleanup is intended the context object can also be directly + used as a context manager. + + Example usage:: + + with ctx.scope(): + assert get_current_context() is ctx + + This is equivalent:: + + with ctx: + assert get_current_context() is ctx + + .. versionadded:: 5.0 + + :param cleanup: controls if the cleanup functions should be run or + not. The default is to run these functions. In + some situations the context only wants to be + temporarily pushed in which case this can be disabled. + Nested pushes automatically defer the cleanup. + """ + if not cleanup: + self._depth += 1 + try: + with self as rv: + yield rv + finally: + if not cleanup: + self._depth -= 1 + + @property + def meta(self) -> t.Dict[str, t.Any]: + """This is a dictionary which is shared with all the contexts + that are nested. It exists so that click utilities can store some + state here if they need to. It is however the responsibility of + that code to manage this dictionary well. + + The keys are supposed to be unique dotted strings. For instance + module paths are a good choice for it. What is stored in there is + irrelevant for the operation of click. However what is important is + that code that places data here adheres to the general semantics of + the system. + + Example usage:: + + LANG_KEY = f'{__name__}.lang' + + def set_language(value): + ctx = get_current_context() + ctx.meta[LANG_KEY] = value + + def get_language(): + return get_current_context().meta.get(LANG_KEY, 'en_US') + + .. versionadded:: 5.0 + """ + return self._meta + + def make_formatter(self) -> HelpFormatter: + """Creates the :class:`~click.HelpFormatter` for the help and + usage output. + + To quickly customize the formatter class used without overriding + this method, set the :attr:`formatter_class` attribute. + + .. versionchanged:: 8.0 + Added the :attr:`formatter_class` attribute. + """ + return self.formatter_class( + width=self.terminal_width, max_width=self.max_content_width + ) + + def with_resource(self, context_manager: t.ContextManager[V]) -> V: + """Register a resource as if it were used in a ``with`` + statement. The resource will be cleaned up when the context is + popped. + + Uses :meth:`contextlib.ExitStack.enter_context`. It calls the + resource's ``__enter__()`` method and returns the result. When + the context is popped, it closes the stack, which calls the + resource's ``__exit__()`` method. + + To register a cleanup function for something that isn't a + context manager, use :meth:`call_on_close`. Or use something + from :mod:`contextlib` to turn it into a context manager first. + + .. code-block:: python + + @click.group() + @click.option("--name") + @click.pass_context + def cli(ctx): + ctx.obj = ctx.with_resource(connect_db(name)) + + :param context_manager: The context manager to enter. + :return: Whatever ``context_manager.__enter__()`` returns. + + .. versionadded:: 8.0 + """ + return self._exit_stack.enter_context(context_manager) + + def call_on_close(self, f: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Register a function to be called when the context tears down. + + This can be used to close resources opened during the script + execution. Resources that support Python's context manager + protocol which would be used in a ``with`` statement should be + registered with :meth:`with_resource` instead. + + :param f: The function to execute on teardown. + """ + return self._exit_stack.callback(f) + + def close(self) -> None: + """Invoke all close callbacks registered with + :meth:`call_on_close`, and exit all context managers entered + with :meth:`with_resource`. + """ + self._exit_stack.close() + # In case the context is reused, create a new exit stack. + self._exit_stack = ExitStack() + + @property + def command_path(self) -> str: + """The computed command path. This is used for the ``usage`` + information on the help page. It's automatically created by + combining the info names of the chain of contexts to the root. + """ + rv = "" + if self.info_name is not None: + rv = self.info_name + if self.parent is not None: + parent_command_path = [self.parent.command_path] + + if isinstance(self.parent.command, Command): + for param in self.parent.command.get_params(self): + parent_command_path.extend(param.get_usage_pieces(self)) + + rv = f"{' '.join(parent_command_path)} {rv}" + return rv.lstrip() + + def find_root(self) -> "Context": + """Finds the outermost context.""" + node = self + while node.parent is not None: + node = node.parent + return node + + def find_object(self, object_type: t.Type[V]) -> t.Optional[V]: + """Finds the closest object of a given type.""" + node: t.Optional["Context"] = self + + while node is not None: + if isinstance(node.obj, object_type): + return node.obj + + node = node.parent + + return None + + def ensure_object(self, object_type: t.Type[V]) -> V: + """Like :meth:`find_object` but sets the innermost object to a + new instance of `object_type` if it does not exist. + """ + rv = self.find_object(object_type) + if rv is None: + self.obj = rv = object_type() + return rv + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def lookup_default( + self, name: str, call: "te.Literal[False]" = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def lookup_default(self, name: str, call: bool = True) -> t.Optional[t.Any]: + """Get the default for a parameter from :attr:`default_map`. + + :param name: Name of the parameter. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + if self.default_map is not None: + value = self.default_map.get(name) + + if call and callable(value): + return value() + + return value + + return None + + def fail(self, message: str) -> "te.NoReturn": + """Aborts the execution of the program with a specific error + message. + + :param message: the error message to fail with. + """ + raise UsageError(message, self) + + def abort(self) -> "te.NoReturn": + """Aborts the script.""" + raise Abort() + + def exit(self, code: int = 0) -> "te.NoReturn": + """Exits the application with a given exit code.""" + raise Exit(code) + + def get_usage(self) -> str: + """Helper method to get formatted usage string for the current + context and command. + """ + return self.command.get_usage(self) + + def get_help(self) -> str: + """Helper method to get formatted help page for the current + context and command. + """ + return self.command.get_help(self) + + def _make_sub_context(self, command: "Command") -> "Context": + """Create a new context of the same type as this context, but + for a new command. + + :meta private: + """ + return type(self)(command, info_name=command.name, parent=self) + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "t.Callable[..., V]", + *args: t.Any, + **kwargs: t.Any, + ) -> V: + ... + + @t.overload + def invoke( + __self, # noqa: B902 + __callback: "Command", + *args: t.Any, + **kwargs: t.Any, + ) -> t.Any: + ... + + def invoke( + __self, # noqa: B902 + __callback: t.Union["Command", "t.Callable[..., V]"], + *args: t.Any, + **kwargs: t.Any, + ) -> t.Union[t.Any, V]: + """Invokes a command callback in exactly the way it expects. There + are two ways to invoke this method: + + 1. the first argument can be a callback and all other arguments and + keyword arguments are forwarded directly to the function. + 2. the first argument is a click command object. In that case all + arguments are forwarded as well but proper click parameters + (options and click arguments) must be keyword arguments and Click + will fill in defaults. + + Note that before Click 3.2 keyword arguments were not properly filled + in against the intention of this code and no context was created. For + more information about this change and why it was done in a bugfix + release see :ref:`upgrade-to-3.2`. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if :meth:`forward` is called at multiple levels. + """ + if isinstance(__callback, Command): + other_cmd = __callback + + if other_cmd.callback is None: + raise TypeError( + "The given command does not have a callback that can be invoked." + ) + else: + __callback = t.cast("t.Callable[..., V]", other_cmd.callback) + + ctx = __self._make_sub_context(other_cmd) + + for param in other_cmd.params: + if param.name not in kwargs and param.expose_value: + kwargs[param.name] = param.type_cast_value( # type: ignore + ctx, param.get_default(ctx) + ) + + # Track all kwargs as params, so that forward() will pass + # them on in subsequent calls. + ctx.params.update(kwargs) + else: + ctx = __self + + with augment_usage_errors(__self): + with ctx: + return __callback(*args, **kwargs) + + def forward( + __self, __cmd: "Command", *args: t.Any, **kwargs: t.Any # noqa: B902 + ) -> t.Any: + """Similar to :meth:`invoke` but fills in default keyword + arguments from the current context if the other command expects + it. This cannot invoke callbacks directly, only other commands. + + .. versionchanged:: 8.0 + All ``kwargs`` are tracked in :attr:`params` so they will be + passed if ``forward`` is called at multiple levels. + """ + # Can only forward to other commands, not direct callbacks. + if not isinstance(__cmd, Command): + raise TypeError("Callback is not a command.") + + for param in __self.params: + if param not in kwargs: + kwargs[param] = __self.params[param] + + return __self.invoke(__cmd, *args, **kwargs) + + def set_parameter_source(self, name: str, source: ParameterSource) -> None: + """Set the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + :param name: The name of the parameter. + :param source: A member of :class:`~click.core.ParameterSource`. + """ + self._parameter_source[name] = source + + def get_parameter_source(self, name: str) -> t.Optional[ParameterSource]: + """Get the source of a parameter. This indicates the location + from which the value of the parameter was obtained. + + This can be useful for determining when a user specified a value + on the command line that is the same as the default value. It + will be :attr:`~click.core.ParameterSource.DEFAULT` only if the + value was actually taken from the default. + + :param name: The name of the parameter. + :rtype: ParameterSource + + .. versionchanged:: 8.0 + Returns ``None`` if the parameter was not provided from any + source. + """ + return self._parameter_source.get(name) + + +class BaseCommand: + """The base command implements the minimal API contract of commands. + Most code will never use this as it does not implement a lot of useful + functionality but it can act as the direct subclass of alternative + parsing methods that do not depend on the Click parser. + + For instance, this can be used to bridge Click and other systems like + argparse or docopt. + + Because base commands do not implement a lot of the API that other + parts of Click take for granted, they are not supported for all + operations. For instance, they cannot be used with the decorators + usually and they have no built-in callback system. + + .. versionchanged:: 2.0 + Added the `context_settings` parameter. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + """ + + #: The context class to create with :meth:`make_context`. + #: + #: .. versionadded:: 8.0 + context_class: t.Type[Context] = Context + #: the default for the :attr:`Context.allow_extra_args` flag. + allow_extra_args = False + #: the default for the :attr:`Context.allow_interspersed_args` flag. + allow_interspersed_args = True + #: the default for the :attr:`Context.ignore_unknown_options` flag. + ignore_unknown_options = False + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + ) -> None: + #: the name the command thinks it has. Upon registering a command + #: on a :class:`Group` the group will default the command name + #: with this information. You should instead use the + #: :class:`Context`\'s :attr:`~Context.info_name` attribute. + self.name = name + + if context_settings is None: + context_settings = {} + + #: an optional dictionary with defaults passed to the context. + self.context_settings: t.MutableMapping[str, t.Any] = context_settings + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. This traverses the entire structure + below this command. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + :param ctx: A :class:`Context` representing this command. + + .. versionadded:: 8.0 + """ + return {"name": self.name} + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def get_usage(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get usage") + + def get_help(self, ctx: Context) -> str: + raise NotImplementedError("Base commands cannot get help") + + def make_context( + self, + info_name: t.Optional[str], + args: t.List[str], + parent: t.Optional[Context] = None, + **extra: t.Any, + ) -> Context: + """This function when given an info name and arguments will kick + off the parsing and create a new :class:`Context`. It does not + invoke the actual command callback though. + + To quickly customize the context class used without overriding + this method, set the :attr:`context_class` attribute. + + :param info_name: the info name for this invocation. Generally this + is the most descriptive name for the script or + command. For the toplevel script it's usually + the name of the script, for commands below it's + the name of the command. + :param args: the arguments to parse as list of strings. + :param parent: the parent context if available. + :param extra: extra keyword arguments forwarded to the context + constructor. + + .. versionchanged:: 8.0 + Added the :attr:`context_class` attribute. + """ + for key, value in self.context_settings.items(): + if key not in extra: + extra[key] = value + + ctx = self.context_class( + self, info_name=info_name, parent=parent, **extra # type: ignore + ) + + with ctx.scope(cleanup=False): + self.parse_args(ctx, args) + return ctx + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + """Given a context and a list of arguments this creates the parser + and parses the arguments, then modifies the context as necessary. + This is automatically invoked by :meth:`make_context`. + """ + raise NotImplementedError("Base commands do not know how to parse arguments.") + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the command. The default + implementation is raising a not implemented error. + """ + raise NotImplementedError("Base commands are not invocable by default") + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of chained multi-commands. + + Any command could be part of a chained multi-command, so sibling + commands are valid at any point during command completion. Other + command classes will return more completions. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + while ctx.parent is not None: + ctx = ctx.parent + + if isinstance(ctx.command, MultiCommand) and ctx.command.chain: + results.extend( + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + if name not in ctx.protected_args + ) + + return results + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: "te.Literal[True]" = True, + **extra: t.Any, + ) -> "te.NoReturn": + ... + + @t.overload + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = ..., + **extra: t.Any, + ) -> t.Any: + ... + + def main( + self, + args: t.Optional[t.Sequence[str]] = None, + prog_name: t.Optional[str] = None, + complete_var: t.Optional[str] = None, + standalone_mode: bool = True, + windows_expand_args: bool = True, + **extra: t.Any, + ) -> t.Any: + """This is the way to invoke a script with all the bells and + whistles as a command line application. This will always terminate + the application after a call. If this is not wanted, ``SystemExit`` + needs to be caught. + + This method is also available by directly calling the instance of + a :class:`Command`. + + :param args: the arguments that should be used for parsing. If not + provided, ``sys.argv[1:]`` is used. + :param prog_name: the program name that should be used. By default + the program name is constructed by taking the file + name from ``sys.argv[0]``. + :param complete_var: the environment variable that controls the + bash completion support. The default is + ``"__COMPLETE"`` with prog_name in + uppercase. + :param standalone_mode: the default behavior is to invoke the script + in standalone mode. Click will then + handle exceptions and convert them into + error messages and the function will never + return but shut down the interpreter. If + this is set to `False` they will be + propagated to the caller and the return + value of this function is the return value + of :meth:`invoke`. + :param windows_expand_args: Expand glob patterns, user dir, and + env vars in command line args on Windows. + :param extra: extra keyword arguments are forwarded to the context + constructor. See :class:`Context` for more information. + + .. versionchanged:: 8.0.1 + Added the ``windows_expand_args`` parameter to allow + disabling command line arg expansion on Windows. + + .. versionchanged:: 8.0 + When taking arguments from ``sys.argv`` on Windows, glob + patterns, user dir, and env vars are expanded. + + .. versionchanged:: 3.0 + Added the ``standalone_mode`` parameter. + """ + if args is None: + args = sys.argv[1:] + + if os.name == "nt" and windows_expand_args: + args = _expand_args(args) + else: + args = list(args) + + if prog_name is None: + prog_name = _detect_program_name() + + # Process shell completion requests and exit early. + self._main_shell_completion(extra, prog_name, complete_var) + + try: + try: + with self.make_context(prog_name, args, **extra) as ctx: + rv = self.invoke(ctx) + if not standalone_mode: + return rv + # it's not safe to `ctx.exit(rv)` here! + # note that `rv` may actually contain data like "1" which + # has obvious effects + # more subtle case: `rv=[None, None]` can come out of + # chained commands which all returned `None` -- so it's not + # even always obvious that `rv` indicates success/failure + # by its truthiness/falsiness + ctx.exit() + except (EOFError, KeyboardInterrupt) as e: + echo(file=sys.stderr) + raise Abort() from e + except ClickException as e: + if not standalone_mode: + raise + e.show() + sys.exit(e.exit_code) + except OSError as e: + if e.errno == errno.EPIPE: + sys.stdout = t.cast(t.TextIO, PacifyFlushWrapper(sys.stdout)) + sys.stderr = t.cast(t.TextIO, PacifyFlushWrapper(sys.stderr)) + sys.exit(1) + else: + raise + except Exit as e: + if standalone_mode: + sys.exit(e.exit_code) + else: + # in non-standalone mode, return the exit code + # note that this is only reached if `self.invoke` above raises + # an Exit explicitly -- thus bypassing the check there which + # would return its result + # the results of non-standalone execution may therefore be + # somewhat ambiguous: if there are codepaths which lead to + # `ctx.exit(1)` and to `return 1`, the caller won't be able to + # tell the difference between the two + return e.exit_code + except Abort: + if not standalone_mode: + raise + echo(_("Aborted!"), file=sys.stderr) + sys.exit(1) + + def _main_shell_completion( + self, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: t.Optional[str] = None, + ) -> None: + """Check if the shell is asking for tab completion, process + that, then exit early. Called from :meth:`main` before the + program is invoked. + + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. Defaults to + ``_{PROG_NAME}_COMPLETE``. + + .. versionchanged:: 8.2.0 + Dots (``.``) in ``prog_name`` are replaced with underscores (``_``). + """ + if complete_var is None: + complete_name = prog_name.replace("-", "_").replace(".", "_") + complete_var = f"_{complete_name}_COMPLETE".upper() + + instruction = os.environ.get(complete_var) + + if not instruction: + return + + from .shell_completion import shell_complete + + rv = shell_complete(self, ctx_args, prog_name, complete_var, instruction) + sys.exit(rv) + + def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any: + """Alias for :meth:`main`.""" + return self.main(*args, **kwargs) + + +class Command(BaseCommand): + """Commands are the basic building block of command line interfaces in + Click. A basic command handles command line parsing and might dispatch + more parsing to commands nested below it. + + :param name: the name of the command to use unless a group overrides it. + :param context_settings: an optional dictionary with defaults that are + passed to the context object. + :param callback: the callback to invoke. This is optional. + :param params: the parameters to register with this command. This can + be either :class:`Option` or :class:`Argument` objects. + :param help: the help string to use for this command. + :param epilog: like the help string but it's printed at the end of the + help page after everything else. + :param short_help: the short help to use for this command. This is + shown on the command listing of the parent command. + :param add_help_option: by default each command registers a ``--help`` + option. This can be disabled by this parameter. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is disabled by default. + If enabled this will add ``--help`` as argument + if no arguments are passed + :param hidden: hide this command from help outputs. + + :param deprecated: issues a message indicating that + the command is deprecated. + + .. versionchanged:: 8.1 + ``help``, ``epilog``, and ``short_help`` are stored unprocessed, + all formatting is done when outputting help text, not at init, + and is done even if not using the ``@command`` decorator. + + .. versionchanged:: 8.0 + Added a ``repr`` showing the command name. + + .. versionchanged:: 7.1 + Added the ``no_args_is_help`` parameter. + + .. versionchanged:: 2.0 + Added the ``context_settings`` parameter. + """ + + def __init__( + self, + name: t.Optional[str], + context_settings: t.Optional[t.MutableMapping[str, t.Any]] = None, + callback: t.Optional[t.Callable[..., t.Any]] = None, + params: t.Optional[t.List["Parameter"]] = None, + help: t.Optional[str] = None, + epilog: t.Optional[str] = None, + short_help: t.Optional[str] = None, + options_metavar: t.Optional[str] = "[OPTIONS]", + add_help_option: bool = True, + no_args_is_help: bool = False, + hidden: bool = False, + deprecated: bool = False, + ) -> None: + super().__init__(name, context_settings) + #: the callback to execute when the command fires. This might be + #: `None` in which case nothing happens. + self.callback = callback + #: the list of parameters for this command in the order they + #: should show up in the help page and execute. Eager parameters + #: will automatically be handled before non eager ones. + self.params: t.List["Parameter"] = params or [] + self.help = help + self.epilog = epilog + self.options_metavar = options_metavar + self.short_help = short_help + self.add_help_option = add_help_option + self.no_args_is_help = no_args_is_help + self.hidden = hidden + self.deprecated = deprecated + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + info_dict.update( + params=[param.to_info_dict() for param in self.get_params(ctx)], + help=self.help, + epilog=self.epilog, + short_help=self.short_help, + hidden=self.hidden, + deprecated=self.deprecated, + ) + return info_dict + + def get_usage(self, ctx: Context) -> str: + """Formats the usage line into a string and returns it. + + Calls :meth:`format_usage` internally. + """ + formatter = ctx.make_formatter() + self.format_usage(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_params(self, ctx: Context) -> t.List["Parameter"]: + rv = self.params + help_option = self.get_help_option(ctx) + + if help_option is not None: + rv = [*rv, help_option] + + return rv + + def format_usage(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the usage line into the formatter. + + This is a low-level method called by :meth:`get_usage`. + """ + pieces = self.collect_usage_pieces(ctx) + formatter.write_usage(ctx.command_path, " ".join(pieces)) + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + """Returns all the pieces that go into the usage line and returns + it as a list of strings. + """ + rv = [self.options_metavar] if self.options_metavar else [] + + for param in self.get_params(ctx): + rv.extend(param.get_usage_pieces(ctx)) + + return rv + + def get_help_option_names(self, ctx: Context) -> t.List[str]: + """Returns the names for the help option.""" + all_names = set(ctx.help_option_names) + for param in self.params: + all_names.difference_update(param.opts) + all_names.difference_update(param.secondary_opts) + return list(all_names) + + def get_help_option(self, ctx: Context) -> t.Optional["Option"]: + """Returns the help option object.""" + help_options = self.get_help_option_names(ctx) + + if not help_options or not self.add_help_option: + return None + + def show_help(ctx: Context, param: "Parameter", value: str) -> None: + if value and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + return Option( + help_options, + is_flag=True, + is_eager=True, + expose_value=False, + callback=show_help, + help=_("Show this message and exit."), + ) + + def make_parser(self, ctx: Context) -> OptionParser: + """Creates the underlying option parser for this command.""" + parser = OptionParser(ctx) + for param in self.get_params(ctx): + param.add_to_parser(parser, ctx) + return parser + + def get_help(self, ctx: Context) -> str: + """Formats the help into a string and returns it. + + Calls :meth:`format_help` internally. + """ + formatter = ctx.make_formatter() + self.format_help(ctx, formatter) + return formatter.getvalue().rstrip("\n") + + def get_short_help_str(self, limit: int = 45) -> str: + """Gets short help for the command or makes it by shortening the + long help string. + """ + if self.short_help: + text = inspect.cleandoc(self.short_help) + elif self.help: + text = make_default_short_help(self.help, limit) + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + return text.strip() + + def format_help(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help into the formatter if it exists. + + This is a low-level method called by :meth:`get_help`. + + This calls the following methods: + + - :meth:`format_usage` + - :meth:`format_help_text` + - :meth:`format_options` + - :meth:`format_epilog` + """ + self.format_usage(ctx, formatter) + self.format_help_text(ctx, formatter) + self.format_options(ctx, formatter) + self.format_epilog(ctx, formatter) + + def format_help_text(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the help text to the formatter if it exists.""" + if self.help is not None: + # truncate the help text to the first form feed + text = inspect.cleandoc(self.help).partition("\f")[0] + else: + text = "" + + if self.deprecated: + text = _("(Deprecated) {text}").format(text=text) + + if text: + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(text) + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes all the options into the formatter if they exist.""" + opts = [] + for param in self.get_params(ctx): + rv = param.get_help_record(ctx) + if rv is not None: + opts.append(rv) + + if opts: + with formatter.section(_("Options")): + formatter.write_dl(opts) + + def format_epilog(self, ctx: Context, formatter: HelpFormatter) -> None: + """Writes the epilog into the formatter if it exists.""" + if self.epilog: + epilog = inspect.cleandoc(self.epilog) + formatter.write_paragraph() + + with formatter.indentation(): + formatter.write_text(epilog) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + parser = self.make_parser(ctx) + opts, args, param_order = parser.parse_args(args=args) + + for param in iter_params_for_processing(param_order, self.get_params(ctx)): + value, args = param.handle_parse_result(ctx, opts, args) + + if args and not ctx.allow_extra_args and not ctx.resilient_parsing: + ctx.fail( + ngettext( + "Got unexpected extra argument ({args})", + "Got unexpected extra arguments ({args})", + len(args), + ).format(args=" ".join(map(str, args))) + ) + + ctx.args = args + ctx._opt_prefixes.update(parser._opt_prefixes) + return args + + def invoke(self, ctx: Context) -> t.Any: + """Given a context, this invokes the attached callback (if it exists) + in the right way. + """ + if self.deprecated: + message = _( + "DeprecationWarning: The command {name!r} is deprecated." + ).format(name=self.name) + echo(style(message, fg="red"), err=True) + + if self.callback is not None: + return ctx.invoke(self.callback, **ctx.params) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options and chained multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results: t.List["CompletionItem"] = [] + + if incomplete and not incomplete[0].isalnum(): + for param in self.get_params(ctx): + if ( + not isinstance(param, Option) + or param.hidden + or ( + not param.multiple + and ctx.get_parameter_source(param.name) # type: ignore + is ParameterSource.COMMANDLINE + ) + ): + continue + + results.extend( + CompletionItem(name, help=param.help) + for name in [*param.opts, *param.secondary_opts] + if name.startswith(incomplete) + ) + + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class MultiCommand(Command): + """A multi command is the basic implementation of a command that + dispatches to subcommands. The most common version is the + :class:`Group`. + + :param invoke_without_command: this controls how the multi command itself + is invoked. By default it's only invoked + if a subcommand is provided. + :param no_args_is_help: this controls what happens if no arguments are + provided. This option is enabled by default if + `invoke_without_command` is disabled or disabled + if it's enabled. If enabled this will add + ``--help`` as argument if no arguments are + passed. + :param subcommand_metavar: the string that is used in the documentation + to indicate the subcommand place. + :param chain: if this is set to `True` chaining of multiple subcommands + is enabled. This restricts the form of commands in that + they cannot have optional arguments but it allows + multiple commands to be chained together. + :param result_callback: The result callback to attach to this multi + command. This can be set or changed later with the + :meth:`result_callback` decorator. + :param attrs: Other command arguments described in :class:`Command`. + """ + + allow_extra_args = True + allow_interspersed_args = False + + def __init__( + self, + name: t.Optional[str] = None, + invoke_without_command: bool = False, + no_args_is_help: t.Optional[bool] = None, + subcommand_metavar: t.Optional[str] = None, + chain: bool = False, + result_callback: t.Optional[t.Callable[..., t.Any]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if no_args_is_help is None: + no_args_is_help = not invoke_without_command + + self.no_args_is_help = no_args_is_help + self.invoke_without_command = invoke_without_command + + if subcommand_metavar is None: + if chain: + subcommand_metavar = "COMMAND1 [ARGS]... [COMMAND2 [ARGS]...]..." + else: + subcommand_metavar = "COMMAND [ARGS]..." + + self.subcommand_metavar = subcommand_metavar + self.chain = chain + # The result callback that is stored. This can be set or + # overridden with the :func:`result_callback` decorator. + self._result_callback = result_callback + + if self.chain: + for param in self.params: + if isinstance(param, Argument) and not param.required: + raise RuntimeError( + "Multi commands in chain mode cannot have" + " optional arguments." + ) + + def to_info_dict(self, ctx: Context) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict(ctx) + commands = {} + + for name in self.list_commands(ctx): + command = self.get_command(ctx, name) + + if command is None: + continue + + sub_ctx = ctx._make_sub_context(command) + + with sub_ctx.scope(cleanup=False): + commands[name] = command.to_info_dict(sub_ctx) + + info_dict.update(commands=commands, chain=self.chain) + return info_dict + + def collect_usage_pieces(self, ctx: Context) -> t.List[str]: + rv = super().collect_usage_pieces(ctx) + rv.append(self.subcommand_metavar) + return rv + + def format_options(self, ctx: Context, formatter: HelpFormatter) -> None: + super().format_options(ctx, formatter) + self.format_commands(ctx, formatter) + + def result_callback(self, replace: bool = False) -> t.Callable[[F], F]: + """Adds a result callback to the command. By default if a + result callback is already registered this will chain them but + this can be disabled with the `replace` parameter. The result + callback is invoked with the return value of the subcommand + (or the list of return values from all subcommands if chaining + is enabled) as well as the parameters as they would be passed + to the main callback. + + Example:: + + @click.group() + @click.option('-i', '--input', default=23) + def cli(input): + return 42 + + @cli.result_callback() + def process_result(result, input): + return result + input + + :param replace: if set to `True` an already existing result + callback will be removed. + + .. versionchanged:: 8.0 + Renamed from ``resultcallback``. + + .. versionadded:: 3.0 + """ + + def decorator(f: F) -> F: + old_callback = self._result_callback + + if old_callback is None or replace: + self._result_callback = f + return f + + def function(__value, *args, **kwargs): # type: ignore + inner = old_callback(__value, *args, **kwargs) + return f(inner, *args, **kwargs) + + self._result_callback = rv = update_wrapper(t.cast(F, function), f) + return rv + + return decorator + + def format_commands(self, ctx: Context, formatter: HelpFormatter) -> None: + """Extra format methods for multi methods that adds all the commands + after the options. + """ + commands = [] + for subcommand in self.list_commands(ctx): + cmd = self.get_command(ctx, subcommand) + # What is this, the tool lied about a command. Ignore it + if cmd is None: + continue + if cmd.hidden: + continue + + commands.append((subcommand, cmd)) + + # allow for 3 times the default spacing + if len(commands): + limit = formatter.width - 6 - max(len(cmd[0]) for cmd in commands) + + rows = [] + for subcommand, cmd in commands: + help = cmd.get_short_help_str(limit) + rows.append((subcommand, help)) + + if rows: + with formatter.section(_("Commands")): + formatter.write_dl(rows) + + def parse_args(self, ctx: Context, args: t.List[str]) -> t.List[str]: + if not args and self.no_args_is_help and not ctx.resilient_parsing: + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + rest = super().parse_args(ctx, args) + + if self.chain: + ctx.protected_args = rest + ctx.args = [] + elif rest: + ctx.protected_args, ctx.args = rest[:1], rest[1:] + + return ctx.args + + def invoke(self, ctx: Context) -> t.Any: + def _process_result(value: t.Any) -> t.Any: + if self._result_callback is not None: + value = ctx.invoke(self._result_callback, value, **ctx.params) + return value + + if not ctx.protected_args: + if self.invoke_without_command: + # No subcommand was invoked, so the result callback is + # invoked with the group return value for regular + # groups, or an empty list for chained groups. + with ctx: + rv = super().invoke(ctx) + return _process_result([] if self.chain else rv) + ctx.fail(_("Missing command.")) + + # Fetch args back out + args = [*ctx.protected_args, *ctx.args] + ctx.args = [] + ctx.protected_args = [] + + # If we're not in chain mode, we only allow the invocation of a + # single command but we also inform the current context about the + # name of the command to invoke. + if not self.chain: + # Make sure the context is entered so we do not clean up + # resources until the result processor has worked. + with ctx: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + ctx.invoked_subcommand = cmd_name + super().invoke(ctx) + sub_ctx = cmd.make_context(cmd_name, args, parent=ctx) + with sub_ctx: + return _process_result(sub_ctx.command.invoke(sub_ctx)) + + # In chain mode we create the contexts step by step, but after the + # base command has been invoked. Because at that point we do not + # know the subcommands yet, the invoked subcommand attribute is + # set to ``*`` to inform the command that subcommands are executed + # but nothing else. + with ctx: + ctx.invoked_subcommand = "*" if args else None + super().invoke(ctx) + + # Otherwise we make every single context and invoke them in a + # chain. In that case the return value to the result processor + # is the list of all invoked subcommand's results. + contexts = [] + while args: + cmd_name, cmd, args = self.resolve_command(ctx, args) + assert cmd is not None + sub_ctx = cmd.make_context( + cmd_name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + ) + contexts.append(sub_ctx) + args, sub_ctx.args = sub_ctx.args, [] + + rv = [] + for sub_ctx in contexts: + with sub_ctx: + rv.append(sub_ctx.command.invoke(sub_ctx)) + return _process_result(rv) + + def resolve_command( + self, ctx: Context, args: t.List[str] + ) -> t.Tuple[t.Optional[str], t.Optional[Command], t.List[str]]: + cmd_name = make_str(args[0]) + original_cmd_name = cmd_name + + # Get the command + cmd = self.get_command(ctx, cmd_name) + + # If we can't find the command but there is a normalization + # function available, we try with that one. + if cmd is None and ctx.token_normalize_func is not None: + cmd_name = ctx.token_normalize_func(cmd_name) + cmd = self.get_command(ctx, cmd_name) + + # If we don't find the command we want to show an error message + # to the user that it was not provided. However, there is + # something else we should do: if the first argument looks like + # an option we want to kick off parsing again for arguments to + # resolve things like --help which now should go to the main + # place. + if cmd is None and not ctx.resilient_parsing: + if split_opt(cmd_name)[0]: + self.parse_args(ctx, ctx.args) + ctx.fail(_("No such command {name!r}.").format(name=original_cmd_name)) + return cmd_name if cmd else None, cmd, args[1:] + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + """Given a context and a command name, this returns a + :class:`Command` object if it exists or returns `None`. + """ + raise NotImplementedError + + def list_commands(self, ctx: Context) -> t.List[str]: + """Returns a list of subcommand names in the order they should + appear. + """ + return [] + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. Looks + at the names of options, subcommands, and chained + multi-commands. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + results = [ + CompletionItem(name, help=command.get_short_help_str()) + for name, command in _complete_visible_commands(ctx, incomplete) + ] + results.extend(super().shell_complete(ctx, incomplete)) + return results + + +class Group(MultiCommand): + """A group allows a command to have subcommands attached. This is + the most common way to implement nesting in Click. + + :param name: The name of the group command. + :param commands: A dict mapping names to :class:`Command` objects. + Can also be a list of :class:`Command`, which will use + :attr:`Command.name` to create the dict. + :param attrs: Other command arguments described in + :class:`MultiCommand`, :class:`Command`, and + :class:`BaseCommand`. + + .. versionchanged:: 8.0 + The ``commands`` argument can be a list of command objects. + """ + + #: If set, this is used by the group's :meth:`command` decorator + #: as the default :class:`Command` class. This is useful to make all + #: subcommands use a custom command class. + #: + #: .. versionadded:: 8.0 + command_class: t.Optional[t.Type[Command]] = None + + #: If set, this is used by the group's :meth:`group` decorator + #: as the default :class:`Group` class. This is useful to make all + #: subgroups use a custom group class. + #: + #: If set to the special value :class:`type` (literally + #: ``group_class = type``), this group's class will be used as the + #: default class. This makes a custom group class continue to make + #: custom groups. + #: + #: .. versionadded:: 8.0 + group_class: t.Optional[t.Union[t.Type["Group"], t.Type[type]]] = None + # Literal[type] isn't valid, so use Type[type] + + def __init__( + self, + name: t.Optional[str] = None, + commands: t.Optional[ + t.Union[t.MutableMapping[str, Command], t.Sequence[Command]] + ] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + + if commands is None: + commands = {} + elif isinstance(commands, abc.Sequence): + commands = {c.name: c for c in commands if c.name is not None} + + #: The registered subcommands by their exported names. + self.commands: t.MutableMapping[str, Command] = commands + + def add_command(self, cmd: Command, name: t.Optional[str] = None) -> None: + """Registers another :class:`Command` with this group. If the name + is not provided, the name of the command is used. + """ + name = name or cmd.name + if name is None: + raise TypeError("Command has no name.") + _check_multicommand(self, name, cmd, register=True) + self.commands[name] = cmd + + @t.overload + def command(self, __func: t.Callable[..., t.Any]) -> Command: + ... + + @t.overload + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], Command]: + ... + + def command( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], Command], Command]: + """A shortcut decorator for declaring and attaching a command to + the group. This takes the same arguments as :func:`command` and + immediately registers the created command with this group by + calling :meth:`add_command`. + + To customize the command class used, set the + :attr:`command_class` attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`command_class` attribute. + """ + from .decorators import command + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'command(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.command_class and kwargs.get("cls") is None: + kwargs["cls"] = self.command_class + + def decorator(f: t.Callable[..., t.Any]) -> Command: + cmd: Command = command(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + @t.overload + def group(self, __func: t.Callable[..., t.Any]) -> "Group": + ... + + @t.overload + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], "Group"]: + ... + + def group( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Union[t.Callable[[t.Callable[..., t.Any]], "Group"], "Group"]: + """A shortcut decorator for declaring and attaching a group to + the group. This takes the same arguments as :func:`group` and + immediately registers the created group with this group by + calling :meth:`add_command`. + + To customize the group class used, set the :attr:`group_class` + attribute. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.0 + Added the :attr:`group_class` attribute. + """ + from .decorators import group + + func: t.Optional[t.Callable[..., t.Any]] = None + + if args and callable(args[0]): + assert ( + len(args) == 1 and not kwargs + ), "Use 'group(**kwargs)(callable)' to provide arguments." + (func,) = args + args = () + + if self.group_class is not None and kwargs.get("cls") is None: + if self.group_class is type: + kwargs["cls"] = type(self) + else: + kwargs["cls"] = self.group_class + + def decorator(f: t.Callable[..., t.Any]) -> "Group": + cmd: Group = group(*args, **kwargs)(f) + self.add_command(cmd) + return cmd + + if func is not None: + return decorator(func) + + return decorator + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + return self.commands.get(cmd_name) + + def list_commands(self, ctx: Context) -> t.List[str]: + return sorted(self.commands) + + +class CommandCollection(MultiCommand): + """A command collection is a multi command that merges multiple multi + commands together into one. This is a straightforward implementation + that accepts a list of different multi commands as sources and + provides all the commands for each of them. + + See :class:`MultiCommand` and :class:`Command` for the description of + ``name`` and ``attrs``. + """ + + def __init__( + self, + name: t.Optional[str] = None, + sources: t.Optional[t.List[MultiCommand]] = None, + **attrs: t.Any, + ) -> None: + super().__init__(name, **attrs) + #: The list of registered multi commands. + self.sources: t.List[MultiCommand] = sources or [] + + def add_source(self, multi_cmd: MultiCommand) -> None: + """Adds a new multi command to the chain dispatcher.""" + self.sources.append(multi_cmd) + + def get_command(self, ctx: Context, cmd_name: str) -> t.Optional[Command]: + for source in self.sources: + rv = source.get_command(ctx, cmd_name) + + if rv is not None: + if self.chain: + _check_multicommand(self, cmd_name, rv) + + return rv + + return None + + def list_commands(self, ctx: Context) -> t.List[str]: + rv: t.Set[str] = set() + + for source in self.sources: + rv.update(source.list_commands(ctx)) + + return sorted(rv) + + +def _check_iter(value: t.Any) -> t.Iterator[t.Any]: + """Check if the value is iterable but not a string. Raises a type + error, or return an iterator over the value. + """ + if isinstance(value, str): + raise TypeError + + return iter(value) + + +class Parameter: + r"""A parameter to a command comes in two versions: they are either + :class:`Option`\s or :class:`Argument`\s. Other subclasses are currently + not supported by design as some of the internals for parsing are + intentionally not finalized. + + Some settings are supported by both options and arguments. + + :param param_decls: the parameter declarations for this option or + argument. This is a list of flags or argument + names. + :param type: the type that should be used. Either a :class:`ParamType` + or a Python type. The latter is converted into the former + automatically if supported. + :param required: controls if this is optional or not. + :param default: the default value if omitted. This can also be a callable, + in which case it's invoked when the default is needed + without any arguments. + :param callback: A function to further process or validate the value + after type conversion. It is called as ``f(ctx, param, value)`` + and must return the value. It is called for all sources, + including prompts. + :param nargs: the number of arguments to match. If not ``1`` the return + value is a tuple instead of single value. The default for + nargs is ``1`` (except if the type is a tuple, then it's + the arity of the tuple). If ``nargs=-1``, all remaining + parameters are collected. + :param metavar: how the value is represented in the help page. + :param expose_value: if this is `True` then the value is passed onwards + to the command callback and stored on the context, + otherwise it's skipped. + :param is_eager: eager values are processed before non eager ones. This + should not be set for arguments or it will inverse the + order of processing. + :param envvar: a string or list of strings that are environment variables + that should be checked. + :param shell_complete: A function that returns custom shell + completions. Used instead of the param's type completion if + given. Takes ``ctx, param, incomplete`` and must return a list + of :class:`~click.shell_completion.CompletionItem` or a list of + strings. + + .. versionchanged:: 8.0 + ``process_value`` validates required parameters and bounded + ``nargs``, and invokes the parameter callback before returning + the value. This allows the callback to validate prompts. + ``full_process_value`` is removed. + + .. versionchanged:: 8.0 + ``autocompletion`` is renamed to ``shell_complete`` and has new + semantics described above. The old name is deprecated and will + be removed in 8.1, until then it will be wrapped to match the + new requirements. + + .. versionchanged:: 8.0 + For ``multiple=True, nargs>1``, the default must be a list of + tuples. + + .. versionchanged:: 8.0 + Setting a default is no longer required for ``nargs>1``, it will + default to ``None``. ``multiple=True`` or ``nargs=-1`` will + default to ``()``. + + .. versionchanged:: 7.1 + Empty environment variables are ignored rather than taking the + empty string value. This makes it possible for scripts to clear + variables if they can't unset them. + + .. versionchanged:: 2.0 + Changed signature for parameter callback to also be passed the + parameter. The old callback format will still work, but it will + raise a warning to give you a chance to migrate the code easier. + """ + + param_type_name = "parameter" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + required: bool = False, + default: t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]] = None, + callback: t.Optional[t.Callable[[Context, "Parameter", t.Any], t.Any]] = None, + nargs: t.Optional[int] = None, + multiple: bool = False, + metavar: t.Optional[str] = None, + expose_value: bool = True, + is_eager: bool = False, + envvar: t.Optional[t.Union[str, t.Sequence[str]]] = None, + shell_complete: t.Optional[ + t.Callable[ + [Context, "Parameter", str], + t.Union[t.List["CompletionItem"], t.List[str]], + ] + ] = None, + ) -> None: + self.name: t.Optional[str] + self.opts: t.List[str] + self.secondary_opts: t.List[str] + self.name, self.opts, self.secondary_opts = self._parse_decls( + param_decls or (), expose_value + ) + self.type: types.ParamType = types.convert_type(type, default) + + # Default nargs to what the type tells us if we have that + # information available. + if nargs is None: + if self.type.is_composite: + nargs = self.type.arity + else: + nargs = 1 + + self.required = required + self.callback = callback + self.nargs = nargs + self.multiple = multiple + self.expose_value = expose_value + self.default = default + self.is_eager = is_eager + self.metavar = metavar + self.envvar = envvar + self._custom_shell_complete = shell_complete + + if __debug__: + if self.type.is_composite and nargs != self.type.arity: + raise ValueError( + f"'nargs' must be {self.type.arity} (or None) for" + f" type {self.type!r}, but it was {nargs}." + ) + + # Skip no default or callable default. + check_default = default if not callable(default) else None + + if check_default is not None: + if multiple: + try: + # Only check the first value against nargs. + check_default = next(_check_iter(check_default), None) + except TypeError: + raise ValueError( + "'default' must be a list when 'multiple' is true." + ) from None + + # Can be None for multiple with empty default. + if nargs != 1 and check_default is not None: + try: + _check_iter(check_default) + except TypeError: + if multiple: + message = ( + "'default' must be a list of lists when 'multiple' is" + " true and 'nargs' != 1." + ) + else: + message = "'default' must be a list when 'nargs' != 1." + + raise ValueError(message) from None + + if nargs > 1 and len(check_default) != nargs: + subject = "item length" if multiple else "length" + raise ValueError( + f"'default' {subject} must match nargs={nargs}." + ) + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + return { + "name": self.name, + "param_type_name": self.param_type_name, + "opts": self.opts, + "secondary_opts": self.secondary_opts, + "type": self.type.to_info_dict(), + "required": self.required, + "nargs": self.nargs, + "multiple": self.multiple, + "default": self.default, + "envvar": self.envvar, + } + + def __repr__(self) -> str: + return f"<{self.__class__.__name__} {self.name}>" + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + raise NotImplementedError() + + @property + def human_readable_name(self) -> str: + """Returns the human readable name of this parameter. This is the + same as the name for options, but the metavar for arguments. + """ + return self.name # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + + metavar = self.type.get_metavar(self) + + if metavar is None: + metavar = self.type.name.upper() + + if self.nargs != 1: + metavar += "..." + + return metavar + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + """Get the default for the parameter. Tries + :meth:`Context.lookup_default` first, then the local default. + + :param ctx: Current context. + :param call: If the default is a callable, call it. Disable to + return the callable instead. + + .. versionchanged:: 8.0.2 + Type casting is no longer performed when getting a default. + + .. versionchanged:: 8.0.1 + Type casting can fail in resilient parsing mode. Invalid + defaults will not prevent showing help text. + + .. versionchanged:: 8.0 + Looks at ``ctx.default_map`` first. + + .. versionchanged:: 8.0 + Added the ``call`` parameter. + """ + value = ctx.lookup_default(self.name, call=False) # type: ignore + + if value is None: + value = self.default + + if call and callable(value): + value = value() + + return value + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + raise NotImplementedError() + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, t.Any] + ) -> t.Tuple[t.Any, ParameterSource]: + value = opts.get(self.name) # type: ignore + source = ParameterSource.COMMANDLINE + + if value is None: + value = self.value_from_envvar(ctx) + source = ParameterSource.ENVIRONMENT + + if value is None: + value = ctx.lookup_default(self.name) # type: ignore + source = ParameterSource.DEFAULT_MAP + + if value is None: + value = self.get_default(ctx) + source = ParameterSource.DEFAULT + + return value, source + + def type_cast_value(self, ctx: Context, value: t.Any) -> t.Any: + """Convert and validate a value against the option's + :attr:`type`, :attr:`multiple`, and :attr:`nargs`. + """ + if value is None: + return () if self.multiple or self.nargs == -1 else None + + def check_iter(value: t.Any) -> t.Iterator[t.Any]: + try: + return _check_iter(value) + except TypeError: + # This should only happen when passing in args manually, + # the parser should construct an iterable when parsing + # the command line. + raise BadParameter( + _("Value must be an iterable."), ctx=ctx, param=self + ) from None + + if self.nargs == 1 or self.type.is_composite: + + def convert(value: t.Any) -> t.Any: + return self.type(value, param=self, ctx=ctx) + + elif self.nargs == -1: + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + return tuple(self.type(x, self, ctx) for x in check_iter(value)) + + else: # nargs > 1 + + def convert(value: t.Any) -> t.Any: # t.Tuple[t.Any, ...] + value = tuple(check_iter(value)) + + if len(value) != self.nargs: + raise BadParameter( + ngettext( + "Takes {nargs} values but 1 was given.", + "Takes {nargs} values but {len} were given.", + len(value), + ).format(nargs=self.nargs, len=len(value)), + ctx=ctx, + param=self, + ) + + return tuple(self.type(x, self, ctx) for x in value) + + if self.multiple: + return tuple(convert(x) for x in check_iter(value)) + + return convert(value) + + def value_is_missing(self, value: t.Any) -> bool: + if value is None: + return True + + if (self.nargs != 1 or self.multiple) and value == (): + return True + + return False + + def process_value(self, ctx: Context, value: t.Any) -> t.Any: + value = self.type_cast_value(ctx, value) + + if self.required and self.value_is_missing(value): + raise MissingParameter(ctx=ctx, param=self) + + if self.callback is not None: + value = self.callback(ctx, self, value) + + return value + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + if self.envvar is None: + return None + + if isinstance(self.envvar, str): + rv = os.environ.get(self.envvar) + + if rv: + return rv + else: + for envvar in self.envvar: + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is not None and self.nargs != 1: + rv = self.type.split_envvar_value(rv) + + return rv + + def handle_parse_result( + self, ctx: Context, opts: t.Mapping[str, t.Any], args: t.List[str] + ) -> t.Tuple[t.Any, t.List[str]]: + with augment_usage_errors(ctx, param=self): + value, source = self.consume_value(ctx, opts) + ctx.set_parameter_source(self.name, source) # type: ignore + + try: + value = self.process_value(ctx, value) + except Exception: + if not ctx.resilient_parsing: + raise + + value = None + + if self.expose_value: + ctx.params[self.name] = value # type: ignore + + return value, args + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + pass + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [] + + def get_error_hint(self, ctx: Context) -> str: + """Get a stringified version of the param for use in error messages to + indicate which param caused the error. + """ + hint_list = self.opts or [self.human_readable_name] + return " / ".join(f"'{x}'" for x in hint_list) + + def shell_complete(self, ctx: Context, incomplete: str) -> t.List["CompletionItem"]: + """Return a list of completions for the incomplete value. If a + ``shell_complete`` function was given during init, it is used. + Otherwise, the :attr:`type` + :meth:`~click.types.ParamType.shell_complete` function is used. + + :param ctx: Invocation context for this command. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + if self._custom_shell_complete is not None: + results = self._custom_shell_complete(ctx, self, incomplete) + + if results and isinstance(results[0], str): + from click.shell_completion import CompletionItem + + results = [CompletionItem(c) for c in results] + + return t.cast(t.List["CompletionItem"], results) + + return self.type.shell_complete(ctx, self, incomplete) + + +class Option(Parameter): + """Options are usually optional values on the command line and + have some extra features that arguments don't have. + + All other parameters are passed onwards to the parameter constructor. + + :param show_default: Show the default value for this option in its + help text. Values are not shown by default, unless + :attr:`Context.show_default` is ``True``. If this value is a + string, it shows that string in parentheses instead of the + actual value. This is particularly useful for dynamic options. + For single option boolean flags, the default remains hidden if + its value is ``False``. + :param show_envvar: Controls if an environment variable should be + shown on the help page. Normally, environment variables are not + shown. + :param prompt: If set to ``True`` or a non empty string then the + user will be prompted for input. If set to ``True`` the prompt + will be the option name capitalized. + :param confirmation_prompt: Prompt a second time to confirm the + value if it was prompted for. Can be set to a string instead of + ``True`` to customize the message. + :param prompt_required: If set to ``False``, the user will be + prompted for input only when the option was specified as a flag + without a value. + :param hide_input: If this is ``True`` then the input on the prompt + will be hidden from the user. This is useful for password input. + :param is_flag: forces this option to act as a flag. The default is + auto detection. + :param flag_value: which value should be used for this flag if it's + enabled. This is set to a boolean automatically if + the option string contains a slash to mark two options. + :param multiple: if this is set to `True` then the argument is accepted + multiple times and recorded. This is similar to ``nargs`` + in how it works but supports arbitrary number of + arguments. + :param count: this flag makes an option increment an integer. + :param allow_from_autoenv: if this is enabled then the value of this + parameter will be pulled from an environment + variable in case a prefix is defined on the + context. + :param help: the help string. + :param hidden: hide this option from help outputs. + :param attrs: Other command arguments described in :class:`Parameter`. + + .. versionchanged:: 8.1.0 + Help text indentation is cleaned here instead of only in the + ``@option`` decorator. + + .. versionchanged:: 8.1.0 + The ``show_default`` parameter overrides + ``Context.show_default``. + + .. versionchanged:: 8.1.0 + The default of a single option boolean flag is not shown if the + default value is ``False``. + + .. versionchanged:: 8.0.1 + ``type`` is detected from ``flag_value`` if given. + """ + + param_type_name = "option" + + def __init__( + self, + param_decls: t.Optional[t.Sequence[str]] = None, + show_default: t.Union[bool, str, None] = None, + prompt: t.Union[bool, str] = False, + confirmation_prompt: t.Union[bool, str] = False, + prompt_required: bool = True, + hide_input: bool = False, + is_flag: t.Optional[bool] = None, + flag_value: t.Optional[t.Any] = None, + multiple: bool = False, + count: bool = False, + allow_from_autoenv: bool = True, + type: t.Optional[t.Union[types.ParamType, t.Any]] = None, + help: t.Optional[str] = None, + hidden: bool = False, + show_choices: bool = True, + show_envvar: bool = False, + **attrs: t.Any, + ) -> None: + if help: + help = inspect.cleandoc(help) + + default_is_missing = "default" not in attrs + super().__init__(param_decls, type=type, multiple=multiple, **attrs) + + if prompt is True: + if self.name is None: + raise TypeError("'name' is required with 'prompt=True'.") + + prompt_text: t.Optional[str] = self.name.replace("_", " ").capitalize() + elif prompt is False: + prompt_text = None + else: + prompt_text = prompt + + self.prompt = prompt_text + self.confirmation_prompt = confirmation_prompt + self.prompt_required = prompt_required + self.hide_input = hide_input + self.hidden = hidden + + # If prompt is enabled but not required, then the option can be + # used as a flag to indicate using prompt or flag_value. + self._flag_needs_value = self.prompt is not None and not self.prompt_required + + if is_flag is None: + if flag_value is not None: + # Implicitly a flag because flag_value was set. + is_flag = True + elif self._flag_needs_value: + # Not a flag, but when used as a flag it shows a prompt. + is_flag = False + else: + # Implicitly a flag because flag options were given. + is_flag = bool(self.secondary_opts) + elif is_flag is False and not self._flag_needs_value: + # Not a flag, and prompt is not enabled, can be used as a + # flag if flag_value is set. + self._flag_needs_value = flag_value is not None + + self.default: t.Union[t.Any, t.Callable[[], t.Any]] + + if is_flag and default_is_missing and not self.required: + if multiple: + self.default = () + else: + self.default = False + + if flag_value is None: + flag_value = not self.default + + self.type: types.ParamType + if is_flag and type is None: + # Re-guess the type from the flag value instead of the + # default. + self.type = types.convert_type(None, flag_value) + + self.is_flag: bool = is_flag + self.is_bool_flag: bool = is_flag and isinstance(self.type, types.BoolParamType) + self.flag_value: t.Any = flag_value + + # Counting + self.count = count + if count: + if type is None: + self.type = types.IntRange(min=0) + if default_is_missing: + self.default = 0 + + self.allow_from_autoenv = allow_from_autoenv + self.help = help + self.show_default = show_default + self.show_choices = show_choices + self.show_envvar = show_envvar + + if __debug__: + if self.nargs == -1: + raise TypeError("nargs=-1 is not supported for options.") + + if self.prompt and self.is_flag and not self.is_bool_flag: + raise TypeError("'prompt' is not valid for non-boolean flag.") + + if not self.is_bool_flag and self.secondary_opts: + raise TypeError("Secondary flag is not valid for non-boolean flag.") + + if self.is_bool_flag and self.hide_input and self.prompt is not None: + raise TypeError( + "'prompt' with 'hide_input' is not valid for boolean flag." + ) + + if self.count: + if self.multiple: + raise TypeError("'count' is not valid with 'multiple'.") + + if self.is_flag: + raise TypeError("'count' is not valid with 'is_flag'.") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + help=self.help, + prompt=self.prompt, + is_flag=self.is_flag, + flag_value=self.flag_value, + count=self.count, + hidden=self.hidden, + ) + return info_dict + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + opts = [] + secondary_opts = [] + name = None + possible_names = [] + + for decl in decls: + if decl.isidentifier(): + if name is not None: + raise TypeError(f"Name '{name}' defined twice") + name = decl + else: + split_char = ";" if decl[:1] == "/" else "/" + if split_char in decl: + first, second = decl.split(split_char, 1) + first = first.rstrip() + if first: + possible_names.append(split_opt(first)) + opts.append(first) + second = second.lstrip() + if second: + secondary_opts.append(second.lstrip()) + if first == second: + raise ValueError( + f"Boolean option {decl!r} cannot use the" + " same flag for true/false." + ) + else: + possible_names.append(split_opt(decl)) + opts.append(decl) + + if name is None and possible_names: + possible_names.sort(key=lambda x: -len(x[0])) # group long options first + name = possible_names[0][1].replace("-", "_").lower() + if not name.isidentifier(): + name = None + + if name is None: + if not expose_value: + return None, opts, secondary_opts + raise TypeError("Could not determine name for option") + + if not opts and not secondary_opts: + raise TypeError( + f"No options defined but a name was passed ({name})." + " Did you mean to declare an argument instead? Did" + f" you mean to pass '--{name}'?" + ) + + return name, opts, secondary_opts + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + if self.multiple: + action = "append" + elif self.count: + action = "count" + else: + action = "store" + + if self.is_flag: + action = f"{action}_const" + + if self.is_bool_flag and self.secondary_opts: + parser.add_option( + obj=self, opts=self.opts, dest=self.name, action=action, const=True + ) + parser.add_option( + obj=self, + opts=self.secondary_opts, + dest=self.name, + action=action, + const=False, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + const=self.flag_value, + ) + else: + parser.add_option( + obj=self, + opts=self.opts, + dest=self.name, + action=action, + nargs=self.nargs, + ) + + def get_help_record(self, ctx: Context) -> t.Optional[t.Tuple[str, str]]: + if self.hidden: + return None + + any_prefix_is_slash = False + + def _write_opts(opts: t.Sequence[str]) -> str: + nonlocal any_prefix_is_slash + + rv, any_slashes = join_options(opts) + + if any_slashes: + any_prefix_is_slash = True + + if not self.is_flag and not self.count: + rv += f" {self.make_metavar()}" + + return rv + + rv = [_write_opts(self.opts)] + + if self.secondary_opts: + rv.append(_write_opts(self.secondary_opts)) + + help = self.help or "" + extra = [] + + if self.show_envvar: + envvar = self.envvar + + if envvar is None: + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + + if envvar is not None: + var_str = ( + envvar + if isinstance(envvar, str) + else ", ".join(str(d) for d in envvar) + ) + extra.append(_("env var: {var}").format(var=var_str)) + + # Temporarily enable resilient parsing to avoid type casting + # failing for the default. Might be possible to extend this to + # help formatting in general. + resilient = ctx.resilient_parsing + ctx.resilient_parsing = True + + try: + default_value = self.get_default(ctx, call=False) + finally: + ctx.resilient_parsing = resilient + + show_default = False + show_default_is_str = False + + if self.show_default is not None: + if isinstance(self.show_default, str): + show_default_is_str = show_default = True + else: + show_default = self.show_default + elif ctx.show_default is not None: + show_default = ctx.show_default + + if show_default_is_str or (show_default and (default_value is not None)): + if show_default_is_str: + default_string = f"({self.show_default})" + elif isinstance(default_value, (list, tuple)): + default_string = ", ".join(str(d) for d in default_value) + elif inspect.isfunction(default_value): + default_string = _("(dynamic)") + elif self.is_bool_flag and self.secondary_opts: + # For boolean flags that have distinct True/False opts, + # use the opt without prefix instead of the value. + default_string = split_opt( + (self.opts if self.default else self.secondary_opts)[0] + )[1] + elif self.is_bool_flag and not self.secondary_opts and not default_value: + default_string = "" + else: + default_string = str(default_value) + + if default_string: + extra.append(_("default: {default}").format(default=default_string)) + + if ( + isinstance(self.type, types._NumberRangeBase) + # skip count with default range type + and not (self.count and self.type.min == 0 and self.type.max is None) + ): + range_str = self.type._describe_range() + + if range_str: + extra.append(range_str) + + if self.required: + extra.append(_("required")) + + if extra: + extra_str = "; ".join(extra) + help = f"{help} [{extra_str}]" if help else f"[{extra_str}]" + + return ("; " if any_prefix_is_slash else " / ").join(rv), help + + @t.overload + def get_default( + self, ctx: Context, call: "te.Literal[True]" = True + ) -> t.Optional[t.Any]: + ... + + @t.overload + def get_default( + self, ctx: Context, call: bool = ... + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + ... + + def get_default( + self, ctx: Context, call: bool = True + ) -> t.Optional[t.Union[t.Any, t.Callable[[], t.Any]]]: + # If we're a non boolean flag our default is more complex because + # we need to look at all flags in the same group to figure out + # if we're the default one in which case we return the flag + # value as default. + if self.is_flag and not self.is_bool_flag: + for param in ctx.command.params: + if param.name == self.name and param.default: + return t.cast(Option, param).flag_value + + return None + + return super().get_default(ctx, call=call) + + def prompt_for_value(self, ctx: Context) -> t.Any: + """This is an alternative flow that can be activated in the full + value processing if a value does not exist. It will prompt the + user until a valid value exists and then returns the processed + value as result. + """ + assert self.prompt is not None + + # Calculate the default before prompting anything to be stable. + default = self.get_default(ctx) + + # If this is a prompt for a flag we need to handle this + # differently. + if self.is_bool_flag: + return confirm(self.prompt, default) + + return prompt( + self.prompt, + default=default, + type=self.type, + hide_input=self.hide_input, + show_choices=self.show_choices, + confirmation_prompt=self.confirmation_prompt, + value_proc=lambda x: self.process_value(ctx, x), + ) + + def resolve_envvar_value(self, ctx: Context) -> t.Optional[str]: + rv = super().resolve_envvar_value(ctx) + + if rv is not None: + return rv + + if ( + self.allow_from_autoenv + and ctx.auto_envvar_prefix is not None + and self.name is not None + ): + envvar = f"{ctx.auto_envvar_prefix}_{self.name.upper()}" + rv = os.environ.get(envvar) + + if rv: + return rv + + return None + + def value_from_envvar(self, ctx: Context) -> t.Optional[t.Any]: + rv: t.Optional[t.Any] = self.resolve_envvar_value(ctx) + + if rv is None: + return None + + value_depth = (self.nargs != 1) + bool(self.multiple) + + if value_depth > 0: + rv = self.type.split_envvar_value(rv) + + if self.multiple and self.nargs != 1: + rv = batch(rv, self.nargs) + + return rv + + def consume_value( + self, ctx: Context, opts: t.Mapping[str, "Parameter"] + ) -> t.Tuple[t.Any, ParameterSource]: + value, source = super().consume_value(ctx, opts) + + # The parser will emit a sentinel value if the option can be + # given as a flag without a value. This is different from None + # to distinguish from the flag not being given at all. + if value is _flag_needs_value: + if self.prompt is not None and not ctx.resilient_parsing: + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + else: + value = self.flag_value + source = ParameterSource.COMMANDLINE + + elif ( + self.multiple + and value is not None + and any(v is _flag_needs_value for v in value) + ): + value = [self.flag_value if v is _flag_needs_value else v for v in value] + source = ParameterSource.COMMANDLINE + + # The value wasn't set, or used the param's default, prompt if + # prompting is enabled. + elif ( + source in {None, ParameterSource.DEFAULT} + and self.prompt is not None + and (self.required or self.prompt_required) + and not ctx.resilient_parsing + ): + value = self.prompt_for_value(ctx) + source = ParameterSource.PROMPT + + return value, source + + +class Argument(Parameter): + """Arguments are positional parameters to a command. They generally + provide fewer features than options but can have infinite ``nargs`` + and are required by default. + + All parameters are passed onwards to the constructor of :class:`Parameter`. + """ + + param_type_name = "argument" + + def __init__( + self, + param_decls: t.Sequence[str], + required: t.Optional[bool] = None, + **attrs: t.Any, + ) -> None: + if required is None: + if attrs.get("default") is not None: + required = False + else: + required = attrs.get("nargs", 1) > 0 + + if "multiple" in attrs: + raise TypeError("__init__() got an unexpected keyword argument 'multiple'.") + + super().__init__(param_decls, required=required, **attrs) + + if __debug__: + if self.default is not None and self.nargs == -1: + raise TypeError("'default' is not supported for nargs=-1.") + + @property + def human_readable_name(self) -> str: + if self.metavar is not None: + return self.metavar + return self.name.upper() # type: ignore + + def make_metavar(self) -> str: + if self.metavar is not None: + return self.metavar + var = self.type.get_metavar(self) + if not var: + var = self.name.upper() # type: ignore + if not self.required: + var = f"[{var}]" + if self.nargs != 1: + var += "..." + return var + + def _parse_decls( + self, decls: t.Sequence[str], expose_value: bool + ) -> t.Tuple[t.Optional[str], t.List[str], t.List[str]]: + if not decls: + if not expose_value: + return None, [], [] + raise TypeError("Could not determine name for argument") + if len(decls) == 1: + name = arg = decls[0] + name = name.replace("-", "_").lower() + else: + raise TypeError( + "Arguments take exactly one parameter declaration, got" + f" {len(decls)}." + ) + return name, [arg], [] + + def get_usage_pieces(self, ctx: Context) -> t.List[str]: + return [self.make_metavar()] + + def get_error_hint(self, ctx: Context) -> str: + return f"'{self.make_metavar()}'" + + def add_to_parser(self, parser: OptionParser, ctx: Context) -> None: + parser.add_argument(dest=self.name, nargs=self.nargs, obj=self) diff --git a/venv/lib/python3.12/site-packages/click/decorators.py b/venv/lib/python3.12/site-packages/click/decorators.py new file mode 100644 index 0000000..d9bba95 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/decorators.py @@ -0,0 +1,561 @@ +import inspect +import types +import typing as t +from functools import update_wrapper +from gettext import gettext as _ + +from .core import Argument +from .core import Command +from .core import Context +from .core import Group +from .core import Option +from .core import Parameter +from .globals import get_current_context +from .utils import echo + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") +T = t.TypeVar("T") +_AnyCallable = t.Callable[..., t.Any] +FC = t.TypeVar("FC", bound=t.Union[_AnyCallable, Command]) + + +def pass_context(f: "t.Callable[te.Concatenate[Context, P], R]") -> "t.Callable[P, R]": + """Marks a callback as wanting to receive the current context + object as first argument. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context(), *args, **kwargs) + + return update_wrapper(new_func, f) + + +def pass_obj(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + """Similar to :func:`pass_context`, but only pass the object on the + context onwards (:attr:`Context.obj`). This is useful if that object + represents the state of a nested system. + """ + + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + return f(get_current_context().obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + +def make_pass_decorator( + object_type: t.Type[T], ensure: bool = False +) -> t.Callable[["t.Callable[te.Concatenate[T, P], R]"], "t.Callable[P, R]"]: + """Given an object type this creates a decorator that will work + similar to :func:`pass_obj` but instead of passing the object of the + current context, it will find the innermost context of type + :func:`object_type`. + + This generates a decorator that works roughly like this:: + + from functools import update_wrapper + + def decorator(f): + @pass_context + def new_func(ctx, *args, **kwargs): + obj = ctx.find_object(object_type) + return ctx.invoke(f, obj, *args, **kwargs) + return update_wrapper(new_func, f) + return decorator + + :param object_type: the type of the object to pass. + :param ensure: if set to `True`, a new object will be created and + remembered on the context if it's not there yet. + """ + + def decorator(f: "t.Callable[te.Concatenate[T, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> "R": + ctx = get_current_context() + + obj: t.Optional[T] + if ensure: + obj = ctx.ensure_object(object_type) + else: + obj = ctx.find_object(object_type) + + if obj is None: + raise RuntimeError( + "Managed to invoke callback without a context" + f" object of type {object_type.__name__!r}" + " existing." + ) + + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + return decorator # type: ignore[return-value] + + +def pass_meta_key( + key: str, *, doc_description: t.Optional[str] = None +) -> "t.Callable[[t.Callable[te.Concatenate[t.Any, P], R]], t.Callable[P, R]]": + """Create a decorator that passes a key from + :attr:`click.Context.meta` as the first argument to the decorated + function. + + :param key: Key in ``Context.meta`` to pass. + :param doc_description: Description of the object being passed, + inserted into the decorator's docstring. Defaults to "the 'key' + key from Context.meta". + + .. versionadded:: 8.0 + """ + + def decorator(f: "t.Callable[te.Concatenate[t.Any, P], R]") -> "t.Callable[P, R]": + def new_func(*args: "P.args", **kwargs: "P.kwargs") -> R: + ctx = get_current_context() + obj = ctx.meta[key] + return ctx.invoke(f, obj, *args, **kwargs) + + return update_wrapper(new_func, f) + + if doc_description is None: + doc_description = f"the {key!r} key from :attr:`click.Context.meta`" + + decorator.__doc__ = ( + f"Decorator that passes {doc_description} as the first argument" + " to the decorated function." + ) + return decorator # type: ignore[return-value] + + +CmdType = t.TypeVar("CmdType", bound=Command) + + +# variant: no call, directly as decorator for a function. +@t.overload +def command(name: _AnyCallable) -> Command: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @command(namearg, CommandCls, ...) or @command(namearg, cls=CommandCls, ...) +@t.overload +def command( + name: t.Optional[str], + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @command(cls=CommandCls, ...) +@t.overload +def command( + name: None = None, + *, + cls: t.Type[CmdType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], CmdType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def command( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Command]: + ... + + +def command( + name: t.Union[t.Optional[str], _AnyCallable] = None, + cls: t.Optional[t.Type[CmdType]] = None, + **attrs: t.Any, +) -> t.Union[Command, t.Callable[[_AnyCallable], t.Union[Command, CmdType]]]: + r"""Creates a new :class:`Command` and uses the decorated function as + callback. This will also automatically attach all decorated + :func:`option`\s and :func:`argument`\s as parameters to the command. + + The name of the command defaults to the name of the function with + underscores replaced by dashes. If you want to change that, you can + pass the intended name as the first argument. + + All keyword arguments are forwarded to the underlying command class. + For the ``params`` argument, any decorated params are appended to + the end of the list. + + Once decorated the function turns into a :class:`Command` instance + that can be invoked as a command line utility or be attached to a + command :class:`Group`. + + :param name: the name of the command. This defaults to the function + name with underscores replaced by dashes. + :param cls: the command class to instantiate. This defaults to + :class:`Command`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + + .. versionchanged:: 8.1 + The ``params`` argument can be used. Decorated params are + appended to the end of the list. + """ + + func: t.Optional[t.Callable[[_AnyCallable], t.Any]] = None + + if callable(name): + func = name + name = None + assert cls is None, "Use 'command(cls=cls)(callable)' to specify a class." + assert not attrs, "Use 'command(**kwargs)(callable)' to provide arguments." + + if cls is None: + cls = t.cast(t.Type[CmdType], Command) + + def decorator(f: _AnyCallable) -> CmdType: + if isinstance(f, Command): + raise TypeError("Attempted to convert a callback into a command twice.") + + attr_params = attrs.pop("params", None) + params = attr_params if attr_params is not None else [] + + try: + decorator_params = f.__click_params__ # type: ignore + except AttributeError: + pass + else: + del f.__click_params__ # type: ignore + params.extend(reversed(decorator_params)) + + if attrs.get("help") is None: + attrs["help"] = f.__doc__ + + if t.TYPE_CHECKING: + assert cls is not None + assert not callable(name) + + cmd = cls( + name=name or f.__name__.lower().replace("_", "-"), + callback=f, + params=params, + **attrs, + ) + cmd.__doc__ = f.__doc__ + return cmd + + if func is not None: + return decorator(func) + + return decorator + + +GrpType = t.TypeVar("GrpType", bound=Group) + + +# variant: no call, directly as decorator for a function. +@t.overload +def group(name: _AnyCallable) -> Group: + ... + + +# variant: with positional name and with positional or keyword cls argument: +# @group(namearg, GroupCls, ...) or @group(namearg, cls=GroupCls, ...) +@t.overload +def group( + name: t.Optional[str], + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: name omitted, cls _must_ be a keyword argument, @group(cmd=GroupCls, ...) +@t.overload +def group( + name: None = None, + *, + cls: t.Type[GrpType], + **attrs: t.Any, +) -> t.Callable[[_AnyCallable], GrpType]: + ... + + +# variant: with optional string name, no cls argument provided. +@t.overload +def group( + name: t.Optional[str] = ..., cls: None = None, **attrs: t.Any +) -> t.Callable[[_AnyCallable], Group]: + ... + + +def group( + name: t.Union[str, _AnyCallable, None] = None, + cls: t.Optional[t.Type[GrpType]] = None, + **attrs: t.Any, +) -> t.Union[Group, t.Callable[[_AnyCallable], t.Union[Group, GrpType]]]: + """Creates a new :class:`Group` with a function as callback. This + works otherwise the same as :func:`command` just that the `cls` + parameter is set to :class:`Group`. + + .. versionchanged:: 8.1 + This decorator can be applied without parentheses. + """ + if cls is None: + cls = t.cast(t.Type[GrpType], Group) + + if callable(name): + return command(cls=cls, **attrs)(name) + + return command(name, cls, **attrs) + + +def _param_memo(f: t.Callable[..., t.Any], param: Parameter) -> None: + if isinstance(f, Command): + f.params.append(param) + else: + if not hasattr(f, "__click_params__"): + f.__click_params__ = [] # type: ignore + + f.__click_params__.append(param) # type: ignore + + +def argument( + *param_decls: str, cls: t.Optional[t.Type[Argument]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an argument to the command. All positional arguments are + passed as parameter declarations to :class:`Argument`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Argument` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default argument class, refer to :class:`Argument` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the argument class to instantiate. This defaults to + :class:`Argument`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Argument + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def option( + *param_decls: str, cls: t.Optional[t.Type[Option]] = None, **attrs: t.Any +) -> t.Callable[[FC], FC]: + """Attaches an option to the command. All positional arguments are + passed as parameter declarations to :class:`Option`; all keyword + arguments are forwarded unchanged (except ``cls``). + This is equivalent to creating an :class:`Option` instance manually + and attaching it to the :attr:`Command.params` list. + + For the default option class, refer to :class:`Option` and + :class:`Parameter` for descriptions of parameters. + + :param cls: the option class to instantiate. This defaults to + :class:`Option`. + :param param_decls: Passed as positional arguments to the constructor of + ``cls``. + :param attrs: Passed as keyword arguments to the constructor of ``cls``. + """ + if cls is None: + cls = Option + + def decorator(f: FC) -> FC: + _param_memo(f, cls(param_decls, **attrs)) + return f + + return decorator + + +def confirmation_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--yes`` option which shows a prompt before continuing if + not passed. If the prompt is declined, the program will exit. + + :param param_decls: One or more option names. Defaults to the single + value ``"--yes"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value: + ctx.abort() + + if not param_decls: + param_decls = ("--yes",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("callback", callback) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("prompt", "Do you want to continue?") + kwargs.setdefault("help", "Confirm the action without prompting.") + return option(*param_decls, **kwargs) + + +def password_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--password`` option which prompts for a password, hiding + input and asking to enter the value again for confirmation. + + :param param_decls: One or more option names. Defaults to the single + value ``"--password"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + if not param_decls: + param_decls = ("--password",) + + kwargs.setdefault("prompt", True) + kwargs.setdefault("confirmation_prompt", True) + kwargs.setdefault("hide_input", True) + return option(*param_decls, **kwargs) + + +def version_option( + version: t.Optional[str] = None, + *param_decls: str, + package_name: t.Optional[str] = None, + prog_name: t.Optional[str] = None, + message: t.Optional[str] = None, + **kwargs: t.Any, +) -> t.Callable[[FC], FC]: + """Add a ``--version`` option which immediately prints the version + number and exits the program. + + If ``version`` is not provided, Click will try to detect it using + :func:`importlib.metadata.version` to get the version for the + ``package_name``. On Python < 3.8, the ``importlib_metadata`` + backport must be installed. + + If ``package_name`` is not provided, Click will try to detect it by + inspecting the stack frames. This will be used to detect the + version, so it must match the name of the installed package. + + :param version: The version number to show. If not provided, Click + will try to detect it. + :param param_decls: One or more option names. Defaults to the single + value ``"--version"``. + :param package_name: The package name to detect the version from. If + not provided, Click will try to detect it. + :param prog_name: The name of the CLI to show in the message. If not + provided, it will be detected from the command. + :param message: The message to show. The values ``%(prog)s``, + ``%(package)s``, and ``%(version)s`` are available. Defaults to + ``"%(prog)s, version %(version)s"``. + :param kwargs: Extra arguments are passed to :func:`option`. + :raise RuntimeError: ``version`` could not be detected. + + .. versionchanged:: 8.0 + Add the ``package_name`` parameter, and the ``%(package)s`` + value for messages. + + .. versionchanged:: 8.0 + Use :mod:`importlib.metadata` instead of ``pkg_resources``. The + version is detected based on the package name, not the entry + point name. The Python package name must match the installed + package name, or be passed with ``package_name=``. + """ + if message is None: + message = _("%(prog)s, version %(version)s") + + if version is None and package_name is None: + frame = inspect.currentframe() + f_back = frame.f_back if frame is not None else None + f_globals = f_back.f_globals if f_back is not None else None + # break reference cycle + # https://docs.python.org/3/library/inspect.html#the-interpreter-stack + del frame + + if f_globals is not None: + package_name = f_globals.get("__name__") + + if package_name == "__main__": + package_name = f_globals.get("__package__") + + if package_name: + package_name = package_name.partition(".")[0] + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + nonlocal prog_name + nonlocal version + + if prog_name is None: + prog_name = ctx.find_root().info_name + + if version is None and package_name is not None: + metadata: t.Optional[types.ModuleType] + + try: + from importlib import metadata # type: ignore + except ImportError: + # Python < 3.8 + import importlib_metadata as metadata # type: ignore + + try: + version = metadata.version(package_name) # type: ignore + except metadata.PackageNotFoundError: # type: ignore + raise RuntimeError( + f"{package_name!r} is not installed. Try passing" + " 'package_name' instead." + ) from None + + if version is None: + raise RuntimeError( + f"Could not determine the version for {package_name!r} automatically." + ) + + echo( + message % {"prog": prog_name, "package": package_name, "version": version}, + color=ctx.color, + ) + ctx.exit() + + if not param_decls: + param_decls = ("--version",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show the version and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) + + +def help_option(*param_decls: str, **kwargs: t.Any) -> t.Callable[[FC], FC]: + """Add a ``--help`` option which immediately prints the help page + and exits the program. + + This is usually unnecessary, as the ``--help`` option is added to + each command automatically unless ``add_help_option=False`` is + passed. + + :param param_decls: One or more option names. Defaults to the single + value ``"--help"``. + :param kwargs: Extra arguments are passed to :func:`option`. + """ + + def callback(ctx: Context, param: Parameter, value: bool) -> None: + if not value or ctx.resilient_parsing: + return + + echo(ctx.get_help(), color=ctx.color) + ctx.exit() + + if not param_decls: + param_decls = ("--help",) + + kwargs.setdefault("is_flag", True) + kwargs.setdefault("expose_value", False) + kwargs.setdefault("is_eager", True) + kwargs.setdefault("help", _("Show this message and exit.")) + kwargs["callback"] = callback + return option(*param_decls, **kwargs) diff --git a/venv/lib/python3.12/site-packages/click/exceptions.py b/venv/lib/python3.12/site-packages/click/exceptions.py new file mode 100644 index 0000000..fe68a36 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/exceptions.py @@ -0,0 +1,288 @@ +import typing as t +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import get_text_stderr +from .utils import echo +from .utils import format_filename + +if t.TYPE_CHECKING: + from .core import Command + from .core import Context + from .core import Parameter + + +def _join_param_hints( + param_hint: t.Optional[t.Union[t.Sequence[str], str]] +) -> t.Optional[str]: + if param_hint is not None and not isinstance(param_hint, str): + return " / ".join(repr(x) for x in param_hint) + + return param_hint + + +class ClickException(Exception): + """An exception that Click can handle and show to the user.""" + + #: The exit code for this exception. + exit_code = 1 + + def __init__(self, message: str) -> None: + super().__init__(message) + self.message = message + + def format_message(self) -> str: + return self.message + + def __str__(self) -> str: + return self.message + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + + echo(_("Error: {message}").format(message=self.format_message()), file=file) + + +class UsageError(ClickException): + """An internal exception that signals a usage error. This typically + aborts any further handling. + + :param message: the error message to display. + :param ctx: optionally the context that caused this error. Click will + fill in the context automatically in some situations. + """ + + exit_code = 2 + + def __init__(self, message: str, ctx: t.Optional["Context"] = None) -> None: + super().__init__(message) + self.ctx = ctx + self.cmd: t.Optional["Command"] = self.ctx.command if self.ctx else None + + def show(self, file: t.Optional[t.IO[t.Any]] = None) -> None: + if file is None: + file = get_text_stderr() + color = None + hint = "" + if ( + self.ctx is not None + and self.ctx.command.get_help_option(self.ctx) is not None + ): + hint = _("Try '{command} {option}' for help.").format( + command=self.ctx.command_path, option=self.ctx.help_option_names[0] + ) + hint = f"{hint}\n" + if self.ctx is not None: + color = self.ctx.color + echo(f"{self.ctx.get_usage()}\n{hint}", file=file, color=color) + echo( + _("Error: {message}").format(message=self.format_message()), + file=file, + color=color, + ) + + +class BadParameter(UsageError): + """An exception that formats out a standardized error message for a + bad parameter. This is useful when thrown from a callback or type as + Click will attach contextual information to it (for instance, which + parameter it is). + + .. versionadded:: 2.0 + + :param param: the parameter object that caused this error. This can + be left out, and Click will attach this info itself + if possible. + :param param_hint: a string that shows up as parameter name. This + can be used as alternative to `param` in cases + where custom validation should happen. If it is + a string it's used as such, if it's a list then + each item is quoted and separated. + """ + + def __init__( + self, + message: str, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + ) -> None: + super().__init__(message, ctx) + self.param = param + self.param_hint = param_hint + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + return _("Invalid value: {message}").format(message=self.message) + + return _("Invalid value for {param_hint}: {message}").format( + param_hint=_join_param_hints(param_hint), message=self.message + ) + + +class MissingParameter(BadParameter): + """Raised if click required an option or argument but it was not + provided when invoking the script. + + .. versionadded:: 4.0 + + :param param_type: a string that indicates the type of the parameter. + The default is to inherit the parameter type from + the given `param`. Valid values are ``'parameter'``, + ``'option'`` or ``'argument'``. + """ + + def __init__( + self, + message: t.Optional[str] = None, + ctx: t.Optional["Context"] = None, + param: t.Optional["Parameter"] = None, + param_hint: t.Optional[str] = None, + param_type: t.Optional[str] = None, + ) -> None: + super().__init__(message or "", ctx, param, param_hint) + self.param_type = param_type + + def format_message(self) -> str: + if self.param_hint is not None: + param_hint: t.Optional[str] = self.param_hint + elif self.param is not None: + param_hint = self.param.get_error_hint(self.ctx) # type: ignore + else: + param_hint = None + + param_hint = _join_param_hints(param_hint) + param_hint = f" {param_hint}" if param_hint else "" + + param_type = self.param_type + if param_type is None and self.param is not None: + param_type = self.param.param_type_name + + msg = self.message + if self.param is not None: + msg_extra = self.param.type.get_missing_message(self.param) + if msg_extra: + if msg: + msg += f". {msg_extra}" + else: + msg = msg_extra + + msg = f" {msg}" if msg else "" + + # Translate param_type for known types. + if param_type == "argument": + missing = _("Missing argument") + elif param_type == "option": + missing = _("Missing option") + elif param_type == "parameter": + missing = _("Missing parameter") + else: + missing = _("Missing {param_type}").format(param_type=param_type) + + return f"{missing}{param_hint}.{msg}" + + def __str__(self) -> str: + if not self.message: + param_name = self.param.name if self.param else None + return _("Missing parameter: {param_name}").format(param_name=param_name) + else: + return self.message + + +class NoSuchOption(UsageError): + """Raised if click attempted to handle an option that does not + exist. + + .. versionadded:: 4.0 + """ + + def __init__( + self, + option_name: str, + message: t.Optional[str] = None, + possibilities: t.Optional[t.Sequence[str]] = None, + ctx: t.Optional["Context"] = None, + ) -> None: + if message is None: + message = _("No such option: {name}").format(name=option_name) + + super().__init__(message, ctx) + self.option_name = option_name + self.possibilities = possibilities + + def format_message(self) -> str: + if not self.possibilities: + return self.message + + possibility_str = ", ".join(sorted(self.possibilities)) + suggest = ngettext( + "Did you mean {possibility}?", + "(Possible options: {possibilities})", + len(self.possibilities), + ).format(possibility=possibility_str, possibilities=possibility_str) + return f"{self.message} {suggest}" + + +class BadOptionUsage(UsageError): + """Raised if an option is generally supplied but the use of the option + was incorrect. This is for instance raised if the number of arguments + for an option is not correct. + + .. versionadded:: 4.0 + + :param option_name: the name of the option being used incorrectly. + """ + + def __init__( + self, option_name: str, message: str, ctx: t.Optional["Context"] = None + ) -> None: + super().__init__(message, ctx) + self.option_name = option_name + + +class BadArgumentUsage(UsageError): + """Raised if an argument is generally supplied but the use of the argument + was incorrect. This is for instance raised if the number of values + for an argument is not correct. + + .. versionadded:: 6.0 + """ + + +class FileError(ClickException): + """Raised if a file cannot be opened.""" + + def __init__(self, filename: str, hint: t.Optional[str] = None) -> None: + if hint is None: + hint = _("unknown error") + + super().__init__(hint) + self.ui_filename: str = format_filename(filename) + self.filename = filename + + def format_message(self) -> str: + return _("Could not open file {filename!r}: {message}").format( + filename=self.ui_filename, message=self.message + ) + + +class Abort(RuntimeError): + """An internal signalling exception that signals Click to abort.""" + + +class Exit(RuntimeError): + """An exception that indicates that the application should exit with some + status code. + + :param code: the status code to exit with. + """ + + __slots__ = ("exit_code",) + + def __init__(self, code: int = 0) -> None: + self.exit_code: int = code diff --git a/venv/lib/python3.12/site-packages/click/formatting.py b/venv/lib/python3.12/site-packages/click/formatting.py new file mode 100644 index 0000000..ddd2a2f --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/formatting.py @@ -0,0 +1,301 @@ +import typing as t +from contextlib import contextmanager +from gettext import gettext as _ + +from ._compat import term_len +from .parser import split_opt + +# Can force a width. This is used by the test system +FORCED_WIDTH: t.Optional[int] = None + + +def measure_table(rows: t.Iterable[t.Tuple[str, str]]) -> t.Tuple[int, ...]: + widths: t.Dict[int, int] = {} + + for row in rows: + for idx, col in enumerate(row): + widths[idx] = max(widths.get(idx, 0), term_len(col)) + + return tuple(y for x, y in sorted(widths.items())) + + +def iter_rows( + rows: t.Iterable[t.Tuple[str, str]], col_count: int +) -> t.Iterator[t.Tuple[str, ...]]: + for row in rows: + yield row + ("",) * (col_count - len(row)) + + +def wrap_text( + text: str, + width: int = 78, + initial_indent: str = "", + subsequent_indent: str = "", + preserve_paragraphs: bool = False, +) -> str: + """A helper function that intelligently wraps text. By default, it + assumes that it operates on a single paragraph of text but if the + `preserve_paragraphs` parameter is provided it will intelligently + handle paragraphs (defined by two empty lines). + + If paragraphs are handled, a paragraph can be prefixed with an empty + line containing the ``\\b`` character (``\\x08``) to indicate that + no rewrapping should happen in that block. + + :param text: the text that should be rewrapped. + :param width: the maximum width for the text. + :param initial_indent: the initial indent that should be placed on the + first line as a string. + :param subsequent_indent: the indent string that should be placed on + each consecutive line. + :param preserve_paragraphs: if this flag is set then the wrapping will + intelligently handle paragraphs. + """ + from ._textwrap import TextWrapper + + text = text.expandtabs() + wrapper = TextWrapper( + width, + initial_indent=initial_indent, + subsequent_indent=subsequent_indent, + replace_whitespace=False, + ) + if not preserve_paragraphs: + return wrapper.fill(text) + + p: t.List[t.Tuple[int, bool, str]] = [] + buf: t.List[str] = [] + indent = None + + def _flush_par() -> None: + if not buf: + return + if buf[0].strip() == "\b": + p.append((indent or 0, True, "\n".join(buf[1:]))) + else: + p.append((indent or 0, False, " ".join(buf))) + del buf[:] + + for line in text.splitlines(): + if not line: + _flush_par() + indent = None + else: + if indent is None: + orig_len = term_len(line) + line = line.lstrip() + indent = orig_len - term_len(line) + buf.append(line) + _flush_par() + + rv = [] + for indent, raw, text in p: + with wrapper.extra_indent(" " * indent): + if raw: + rv.append(wrapper.indent_only(text)) + else: + rv.append(wrapper.fill(text)) + + return "\n\n".join(rv) + + +class HelpFormatter: + """This class helps with formatting text-based help pages. It's + usually just needed for very special internal cases, but it's also + exposed so that developers can write their own fancy outputs. + + At present, it always writes into memory. + + :param indent_increment: the additional increment for each level. + :param width: the width for the text. This defaults to the terminal + width clamped to a maximum of 78. + """ + + def __init__( + self, + indent_increment: int = 2, + width: t.Optional[int] = None, + max_width: t.Optional[int] = None, + ) -> None: + import shutil + + self.indent_increment = indent_increment + if max_width is None: + max_width = 80 + if width is None: + width = FORCED_WIDTH + if width is None: + width = max(min(shutil.get_terminal_size().columns, max_width) - 2, 50) + self.width = width + self.current_indent = 0 + self.buffer: t.List[str] = [] + + def write(self, string: str) -> None: + """Writes a unicode string into the internal buffer.""" + self.buffer.append(string) + + def indent(self) -> None: + """Increases the indentation.""" + self.current_indent += self.indent_increment + + def dedent(self) -> None: + """Decreases the indentation.""" + self.current_indent -= self.indent_increment + + def write_usage( + self, prog: str, args: str = "", prefix: t.Optional[str] = None + ) -> None: + """Writes a usage line into the buffer. + + :param prog: the program name. + :param args: whitespace separated list of arguments. + :param prefix: The prefix for the first line. Defaults to + ``"Usage: "``. + """ + if prefix is None: + prefix = f"{_('Usage:')} " + + usage_prefix = f"{prefix:>{self.current_indent}}{prog} " + text_width = self.width - self.current_indent + + if text_width >= (term_len(usage_prefix) + 20): + # The arguments will fit to the right of the prefix. + indent = " " * term_len(usage_prefix) + self.write( + wrap_text( + args, + text_width, + initial_indent=usage_prefix, + subsequent_indent=indent, + ) + ) + else: + # The prefix is too long, put the arguments on the next line. + self.write(usage_prefix) + self.write("\n") + indent = " " * (max(self.current_indent, term_len(prefix)) + 4) + self.write( + wrap_text( + args, text_width, initial_indent=indent, subsequent_indent=indent + ) + ) + + self.write("\n") + + def write_heading(self, heading: str) -> None: + """Writes a heading into the buffer.""" + self.write(f"{'':>{self.current_indent}}{heading}:\n") + + def write_paragraph(self) -> None: + """Writes a paragraph into the buffer.""" + if self.buffer: + self.write("\n") + + def write_text(self, text: str) -> None: + """Writes re-indented text into the buffer. This rewraps and + preserves paragraphs. + """ + indent = " " * self.current_indent + self.write( + wrap_text( + text, + self.width, + initial_indent=indent, + subsequent_indent=indent, + preserve_paragraphs=True, + ) + ) + self.write("\n") + + def write_dl( + self, + rows: t.Sequence[t.Tuple[str, str]], + col_max: int = 30, + col_spacing: int = 2, + ) -> None: + """Writes a definition list into the buffer. This is how options + and commands are usually formatted. + + :param rows: a list of two item tuples for the terms and values. + :param col_max: the maximum width of the first column. + :param col_spacing: the number of spaces between the first and + second column. + """ + rows = list(rows) + widths = measure_table(rows) + if len(widths) != 2: + raise TypeError("Expected two columns for definition list") + + first_col = min(widths[0], col_max) + col_spacing + + for first, second in iter_rows(rows, len(widths)): + self.write(f"{'':>{self.current_indent}}{first}") + if not second: + self.write("\n") + continue + if term_len(first) <= first_col - col_spacing: + self.write(" " * (first_col - term_len(first))) + else: + self.write("\n") + self.write(" " * (first_col + self.current_indent)) + + text_width = max(self.width - first_col - 2, 10) + wrapped_text = wrap_text(second, text_width, preserve_paragraphs=True) + lines = wrapped_text.splitlines() + + if lines: + self.write(f"{lines[0]}\n") + + for line in lines[1:]: + self.write(f"{'':>{first_col + self.current_indent}}{line}\n") + else: + self.write("\n") + + @contextmanager + def section(self, name: str) -> t.Iterator[None]: + """Helpful context manager that writes a paragraph, a heading, + and the indents. + + :param name: the section name that is written as heading. + """ + self.write_paragraph() + self.write_heading(name) + self.indent() + try: + yield + finally: + self.dedent() + + @contextmanager + def indentation(self) -> t.Iterator[None]: + """A context manager that increases the indentation.""" + self.indent() + try: + yield + finally: + self.dedent() + + def getvalue(self) -> str: + """Returns the buffer contents.""" + return "".join(self.buffer) + + +def join_options(options: t.Sequence[str]) -> t.Tuple[str, bool]: + """Given a list of option strings this joins them in the most appropriate + way and returns them in the form ``(formatted_string, + any_prefix_is_slash)`` where the second item in the tuple is a flag that + indicates if any of the option prefixes was a slash. + """ + rv = [] + any_prefix_is_slash = False + + for opt in options: + prefix = split_opt(opt)[0] + + if prefix == "/": + any_prefix_is_slash = True + + rv.append((len(prefix), opt)) + + rv.sort(key=lambda x: x[0]) + return ", ".join(x[1] for x in rv), any_prefix_is_slash diff --git a/venv/lib/python3.12/site-packages/click/globals.py b/venv/lib/python3.12/site-packages/click/globals.py new file mode 100644 index 0000000..480058f --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/globals.py @@ -0,0 +1,68 @@ +import typing as t +from threading import local + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + +_local = local() + + +@t.overload +def get_current_context(silent: "te.Literal[False]" = False) -> "Context": + ... + + +@t.overload +def get_current_context(silent: bool = ...) -> t.Optional["Context"]: + ... + + +def get_current_context(silent: bool = False) -> t.Optional["Context"]: + """Returns the current click context. This can be used as a way to + access the current context object from anywhere. This is a more implicit + alternative to the :func:`pass_context` decorator. This function is + primarily useful for helpers such as :func:`echo` which might be + interested in changing its behavior based on the current context. + + To push the current context, :meth:`Context.scope` can be used. + + .. versionadded:: 5.0 + + :param silent: if set to `True` the return value is `None` if no context + is available. The default behavior is to raise a + :exc:`RuntimeError`. + """ + try: + return t.cast("Context", _local.stack[-1]) + except (AttributeError, IndexError) as e: + if not silent: + raise RuntimeError("There is no active click context.") from e + + return None + + +def push_context(ctx: "Context") -> None: + """Pushes a new context to the current stack.""" + _local.__dict__.setdefault("stack", []).append(ctx) + + +def pop_context() -> None: + """Removes the top level from the stack.""" + _local.stack.pop() + + +def resolve_color_default(color: t.Optional[bool] = None) -> t.Optional[bool]: + """Internal helper to get the default value of the color flag. If a + value is passed it's returned unchanged, otherwise it's looked up from + the current context. + """ + if color is not None: + return color + + ctx = get_current_context(silent=True) + + if ctx is not None: + return ctx.color + + return None diff --git a/venv/lib/python3.12/site-packages/click/parser.py b/venv/lib/python3.12/site-packages/click/parser.py new file mode 100644 index 0000000..5fa7adf --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/parser.py @@ -0,0 +1,529 @@ +""" +This module started out as largely a copy paste from the stdlib's +optparse module with the features removed that we do not need from +optparse because we implement them in Click on a higher level (for +instance type handling, help formatting and a lot more). + +The plan is to remove more and more from here over time. + +The reason this is a different module and not optparse from the stdlib +is that there are differences in 2.x and 3.x about the error messages +generated and optparse in the stdlib uses gettext for no good reason +and might cause us issues. + +Click uses parts of optparse written by Gregory P. Ward and maintained +by the Python Software Foundation. This is limited to code in parser.py. + +Copyright 2001-2006 Gregory P. Ward. All rights reserved. +Copyright 2002-2006 Python Software Foundation. All rights reserved. +""" +# This code uses parts of optparse written by Gregory P. Ward and +# maintained by the Python Software Foundation. +# Copyright 2001-2006 Gregory P. Ward +# Copyright 2002-2006 Python Software Foundation +import typing as t +from collections import deque +from gettext import gettext as _ +from gettext import ngettext + +from .exceptions import BadArgumentUsage +from .exceptions import BadOptionUsage +from .exceptions import NoSuchOption +from .exceptions import UsageError + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Argument as CoreArgument + from .core import Context + from .core import Option as CoreOption + from .core import Parameter as CoreParameter + +V = t.TypeVar("V") + +# Sentinel value that indicates an option was passed as a flag without a +# value but is not a flag option. Option.consume_value uses this to +# prompt or use the flag_value. +_flag_needs_value = object() + + +def _unpack_args( + args: t.Sequence[str], nargs_spec: t.Sequence[int] +) -> t.Tuple[t.Sequence[t.Union[str, t.Sequence[t.Optional[str]], None]], t.List[str]]: + """Given an iterable of arguments and an iterable of nargs specifications, + it returns a tuple with all the unpacked arguments at the first index + and all remaining arguments as the second. + + The nargs specification is the number of arguments that should be consumed + or `-1` to indicate that this position should eat up all the remainders. + + Missing items are filled with `None`. + """ + args = deque(args) + nargs_spec = deque(nargs_spec) + rv: t.List[t.Union[str, t.Tuple[t.Optional[str], ...], None]] = [] + spos: t.Optional[int] = None + + def _fetch(c: "te.Deque[V]") -> t.Optional[V]: + try: + if spos is None: + return c.popleft() + else: + return c.pop() + except IndexError: + return None + + while nargs_spec: + nargs = _fetch(nargs_spec) + + if nargs is None: + continue + + if nargs == 1: + rv.append(_fetch(args)) + elif nargs > 1: + x = [_fetch(args) for _ in range(nargs)] + + # If we're reversed, we're pulling in the arguments in reverse, + # so we need to turn them around. + if spos is not None: + x.reverse() + + rv.append(tuple(x)) + elif nargs < 0: + if spos is not None: + raise TypeError("Cannot have two nargs < 0") + + spos = len(rv) + rv.append(None) + + # spos is the position of the wildcard (star). If it's not `None`, + # we fill it with the remainder. + if spos is not None: + rv[spos] = tuple(args) + args = [] + rv[spos + 1 :] = reversed(rv[spos + 1 :]) + + return tuple(rv), list(args) + + +def split_opt(opt: str) -> t.Tuple[str, str]: + first = opt[:1] + if first.isalnum(): + return "", opt + if opt[1:2] == first: + return opt[:2], opt[2:] + return first, opt[1:] + + +def normalize_opt(opt: str, ctx: t.Optional["Context"]) -> str: + if ctx is None or ctx.token_normalize_func is None: + return opt + prefix, opt = split_opt(opt) + return f"{prefix}{ctx.token_normalize_func(opt)}" + + +def split_arg_string(string: str) -> t.List[str]: + """Split an argument string as with :func:`shlex.split`, but don't + fail if the string is incomplete. Ignores a missing closing quote or + incomplete escape sequence and uses the partial token as-is. + + .. code-block:: python + + split_arg_string("example 'my file") + ["example", "my file"] + + split_arg_string("example my\\") + ["example", "my"] + + :param string: String to split. + """ + import shlex + + lex = shlex.shlex(string, posix=True) + lex.whitespace_split = True + lex.commenters = "" + out = [] + + try: + for token in lex: + out.append(token) + except ValueError: + # Raised when end-of-string is reached in an invalid state. Use + # the partial token as-is. The quote or escape character is in + # lex.state, not lex.token. + out.append(lex.token) + + return out + + +class Option: + def __init__( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ): + self._short_opts = [] + self._long_opts = [] + self.prefixes: t.Set[str] = set() + + for opt in opts: + prefix, value = split_opt(opt) + if not prefix: + raise ValueError(f"Invalid start character for option ({opt})") + self.prefixes.add(prefix[0]) + if len(prefix) == 1 and len(value) == 1: + self._short_opts.append(opt) + else: + self._long_opts.append(opt) + self.prefixes.add(prefix) + + if action is None: + action = "store" + + self.dest = dest + self.action = action + self.nargs = nargs + self.const = const + self.obj = obj + + @property + def takes_value(self) -> bool: + return self.action in ("store", "append") + + def process(self, value: t.Any, state: "ParsingState") -> None: + if self.action == "store": + state.opts[self.dest] = value # type: ignore + elif self.action == "store_const": + state.opts[self.dest] = self.const # type: ignore + elif self.action == "append": + state.opts.setdefault(self.dest, []).append(value) # type: ignore + elif self.action == "append_const": + state.opts.setdefault(self.dest, []).append(self.const) # type: ignore + elif self.action == "count": + state.opts[self.dest] = state.opts.get(self.dest, 0) + 1 # type: ignore + else: + raise ValueError(f"unknown action '{self.action}'") + state.order.append(self.obj) + + +class Argument: + def __init__(self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1): + self.dest = dest + self.nargs = nargs + self.obj = obj + + def process( + self, + value: t.Union[t.Optional[str], t.Sequence[t.Optional[str]]], + state: "ParsingState", + ) -> None: + if self.nargs > 1: + assert value is not None + holes = sum(1 for x in value if x is None) + if holes == len(value): + value = None + elif holes != 0: + raise BadArgumentUsage( + _("Argument {name!r} takes {nargs} values.").format( + name=self.dest, nargs=self.nargs + ) + ) + + if self.nargs == -1 and self.obj.envvar is not None and value == (): + # Replace empty tuple with None so that a value from the + # environment may be tried. + value = None + + state.opts[self.dest] = value # type: ignore + state.order.append(self.obj) + + +class ParsingState: + def __init__(self, rargs: t.List[str]) -> None: + self.opts: t.Dict[str, t.Any] = {} + self.largs: t.List[str] = [] + self.rargs = rargs + self.order: t.List["CoreParameter"] = [] + + +class OptionParser: + """The option parser is an internal class that is ultimately used to + parse options and arguments. It's modelled after optparse and brings + a similar but vastly simplified API. It should generally not be used + directly as the high level Click classes wrap it for you. + + It's not nearly as extensible as optparse or argparse as it does not + implement features that are implemented on a higher level (such as + types or defaults). + + :param ctx: optionally the :class:`~click.Context` where this parser + should go with. + """ + + def __init__(self, ctx: t.Optional["Context"] = None) -> None: + #: The :class:`~click.Context` for this parser. This might be + #: `None` for some advanced use cases. + self.ctx = ctx + #: This controls how the parser deals with interspersed arguments. + #: If this is set to `False`, the parser will stop on the first + #: non-option. Click uses this to implement nested subcommands + #: safely. + self.allow_interspersed_args: bool = True + #: This tells the parser how to deal with unknown options. By + #: default it will error out (which is sensible), but there is a + #: second mode where it will ignore it and continue processing + #: after shifting all the unknown options into the resulting args. + self.ignore_unknown_options: bool = False + + if ctx is not None: + self.allow_interspersed_args = ctx.allow_interspersed_args + self.ignore_unknown_options = ctx.ignore_unknown_options + + self._short_opt: t.Dict[str, Option] = {} + self._long_opt: t.Dict[str, Option] = {} + self._opt_prefixes = {"-", "--"} + self._args: t.List[Argument] = [] + + def add_option( + self, + obj: "CoreOption", + opts: t.Sequence[str], + dest: t.Optional[str], + action: t.Optional[str] = None, + nargs: int = 1, + const: t.Optional[t.Any] = None, + ) -> None: + """Adds a new option named `dest` to the parser. The destination + is not inferred (unlike with optparse) and needs to be explicitly + provided. Action can be any of ``store``, ``store_const``, + ``append``, ``append_const`` or ``count``. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + opts = [normalize_opt(opt, self.ctx) for opt in opts] + option = Option(obj, opts, dest, action=action, nargs=nargs, const=const) + self._opt_prefixes.update(option.prefixes) + for opt in option._short_opts: + self._short_opt[opt] = option + for opt in option._long_opts: + self._long_opt[opt] = option + + def add_argument( + self, obj: "CoreArgument", dest: t.Optional[str], nargs: int = 1 + ) -> None: + """Adds a positional argument named `dest` to the parser. + + The `obj` can be used to identify the option in the order list + that is returned from the parser. + """ + self._args.append(Argument(obj, dest=dest, nargs=nargs)) + + def parse_args( + self, args: t.List[str] + ) -> t.Tuple[t.Dict[str, t.Any], t.List[str], t.List["CoreParameter"]]: + """Parses positional arguments and returns ``(values, args, order)`` + for the parsed options and arguments as well as the leftover + arguments if there are any. The order is a list of objects as they + appear on the command line. If arguments appear multiple times they + will be memorized multiple times as well. + """ + state = ParsingState(args) + try: + self._process_args_for_options(state) + self._process_args_for_args(state) + except UsageError: + if self.ctx is None or not self.ctx.resilient_parsing: + raise + return state.opts, state.largs, state.order + + def _process_args_for_args(self, state: ParsingState) -> None: + pargs, args = _unpack_args( + state.largs + state.rargs, [x.nargs for x in self._args] + ) + + for idx, arg in enumerate(self._args): + arg.process(pargs[idx], state) + + state.largs = args + state.rargs = [] + + def _process_args_for_options(self, state: ParsingState) -> None: + while state.rargs: + arg = state.rargs.pop(0) + arglen = len(arg) + # Double dashes always handled explicitly regardless of what + # prefixes are valid. + if arg == "--": + return + elif arg[:1] in self._opt_prefixes and arglen > 1: + self._process_opts(arg, state) + elif self.allow_interspersed_args: + state.largs.append(arg) + else: + state.rargs.insert(0, arg) + return + + # Say this is the original argument list: + # [arg0, arg1, ..., arg(i-1), arg(i), arg(i+1), ..., arg(N-1)] + # ^ + # (we are about to process arg(i)). + # + # Then rargs is [arg(i), ..., arg(N-1)] and largs is a *subset* of + # [arg0, ..., arg(i-1)] (any options and their arguments will have + # been removed from largs). + # + # The while loop will usually consume 1 or more arguments per pass. + # If it consumes 1 (eg. arg is an option that takes no arguments), + # then after _process_arg() is done the situation is: + # + # largs = subset of [arg0, ..., arg(i)] + # rargs = [arg(i+1), ..., arg(N-1)] + # + # If allow_interspersed_args is false, largs will always be + # *empty* -- still a subset of [arg0, ..., arg(i-1)], but + # not a very interesting subset! + + def _match_long_opt( + self, opt: str, explicit_value: t.Optional[str], state: ParsingState + ) -> None: + if opt not in self._long_opt: + from difflib import get_close_matches + + possibilities = get_close_matches(opt, self._long_opt) + raise NoSuchOption(opt, possibilities=possibilities, ctx=self.ctx) + + option = self._long_opt[opt] + if option.takes_value: + # At this point it's safe to modify rargs by injecting the + # explicit value, because no exception is raised in this + # branch. This means that the inserted value will be fully + # consumed. + if explicit_value is not None: + state.rargs.insert(0, explicit_value) + + value = self._get_value_from_state(opt, option, state) + + elif explicit_value is not None: + raise BadOptionUsage( + opt, _("Option {name!r} does not take a value.").format(name=opt) + ) + + else: + value = None + + option.process(value, state) + + def _match_short_opt(self, arg: str, state: ParsingState) -> None: + stop = False + i = 1 + prefix = arg[0] + unknown_options = [] + + for ch in arg[1:]: + opt = normalize_opt(f"{prefix}{ch}", self.ctx) + option = self._short_opt.get(opt) + i += 1 + + if not option: + if self.ignore_unknown_options: + unknown_options.append(ch) + continue + raise NoSuchOption(opt, ctx=self.ctx) + if option.takes_value: + # Any characters left in arg? Pretend they're the + # next arg, and stop consuming characters of arg. + if i < len(arg): + state.rargs.insert(0, arg[i:]) + stop = True + + value = self._get_value_from_state(opt, option, state) + + else: + value = None + + option.process(value, state) + + if stop: + break + + # If we got any unknown options we recombine the string of the + # remaining options and re-attach the prefix, then report that + # to the state as new larg. This way there is basic combinatorics + # that can be achieved while still ignoring unknown arguments. + if self.ignore_unknown_options and unknown_options: + state.largs.append(f"{prefix}{''.join(unknown_options)}") + + def _get_value_from_state( + self, option_name: str, option: Option, state: ParsingState + ) -> t.Any: + nargs = option.nargs + + if len(state.rargs) < nargs: + if option.obj._flag_needs_value: + # Option allows omitting the value. + value = _flag_needs_value + else: + raise BadOptionUsage( + option_name, + ngettext( + "Option {name!r} requires an argument.", + "Option {name!r} requires {nargs} arguments.", + nargs, + ).format(name=option_name, nargs=nargs), + ) + elif nargs == 1: + next_rarg = state.rargs[0] + + if ( + option.obj._flag_needs_value + and isinstance(next_rarg, str) + and next_rarg[:1] in self._opt_prefixes + and len(next_rarg) > 1 + ): + # The next arg looks like the start of an option, don't + # use it as the value if omitting the value is allowed. + value = _flag_needs_value + else: + value = state.rargs.pop(0) + else: + value = tuple(state.rargs[:nargs]) + del state.rargs[:nargs] + + return value + + def _process_opts(self, arg: str, state: ParsingState) -> None: + explicit_value = None + # Long option handling happens in two parts. The first part is + # supporting explicitly attached values. In any case, we will try + # to long match the option first. + if "=" in arg: + long_opt, explicit_value = arg.split("=", 1) + else: + long_opt = arg + norm_long_opt = normalize_opt(long_opt, self.ctx) + + # At this point we will match the (assumed) long option through + # the long option matching code. Note that this allows options + # like "-foo" to be matched as long options. + try: + self._match_long_opt(norm_long_opt, explicit_value, state) + except NoSuchOption: + # At this point the long option matching failed, and we need + # to try with short options. However there is a special rule + # which says, that if we have a two character options prefix + # (applies to "--foo" for instance), we do not dispatch to the + # short option code and will instead raise the no option + # error. + if arg[:2] not in self._opt_prefixes: + self._match_short_opt(arg, state) + return + + if not self.ignore_unknown_options: + raise + + state.largs.append(arg) diff --git a/venv/lib/python3.12/site-packages/click/py.typed b/venv/lib/python3.12/site-packages/click/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/click/shell_completion.py b/venv/lib/python3.12/site-packages/click/shell_completion.py new file mode 100644 index 0000000..dc9e00b --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/shell_completion.py @@ -0,0 +1,596 @@ +import os +import re +import typing as t +from gettext import gettext as _ + +from .core import Argument +from .core import BaseCommand +from .core import Context +from .core import MultiCommand +from .core import Option +from .core import Parameter +from .core import ParameterSource +from .parser import split_arg_string +from .utils import echo + + +def shell_complete( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + instruction: str, +) -> int: + """Perform shell completion for the given CLI program. + + :param cli: Command being called. + :param ctx_args: Extra arguments to pass to + ``cli.make_context``. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + :param instruction: Value of ``complete_var`` with the completion + instruction and shell, in the form ``instruction_shell``. + :return: Status code to exit with. + """ + shell, _, instruction = instruction.partition("_") + comp_cls = get_completion_class(shell) + + if comp_cls is None: + return 1 + + comp = comp_cls(cli, ctx_args, prog_name, complete_var) + + if instruction == "source": + echo(comp.source()) + return 0 + + if instruction == "complete": + echo(comp.complete()) + return 0 + + return 1 + + +class CompletionItem: + """Represents a completion value and metadata about the value. The + default metadata is ``type`` to indicate special shell handling, + and ``help`` if a shell supports showing a help string next to the + value. + + Arbitrary parameters can be passed when creating the object, and + accessed using ``item.attr``. If an attribute wasn't passed, + accessing it returns ``None``. + + :param value: The completion suggestion. + :param type: Tells the shell script to provide special completion + support for the type. Click uses ``"dir"`` and ``"file"``. + :param help: String shown next to the value if supported. + :param kwargs: Arbitrary metadata. The built-in implementations + don't use this, but custom type completions paired with custom + shell support could use it. + """ + + __slots__ = ("value", "type", "help", "_info") + + def __init__( + self, + value: t.Any, + type: str = "plain", + help: t.Optional[str] = None, + **kwargs: t.Any, + ) -> None: + self.value: t.Any = value + self.type: str = type + self.help: t.Optional[str] = help + self._info = kwargs + + def __getattr__(self, name: str) -> t.Any: + return self._info.get(name) + + +# Only Bash >= 4.4 has the nosort option. +_SOURCE_BASH = """\ +%(complete_func)s() { + local IFS=$'\\n' + local response + + response=$(env COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ +%(complete_var)s=bash_complete $1) + + for completion in $response; do + IFS=',' read type value <<< "$completion" + + if [[ $type == 'dir' ]]; then + COMPREPLY=() + compopt -o dirnames + elif [[ $type == 'file' ]]; then + COMPREPLY=() + compopt -o default + elif [[ $type == 'plain' ]]; then + COMPREPLY+=($value) + fi + done + + return 0 +} + +%(complete_func)s_setup() { + complete -o nosort -F %(complete_func)s %(prog_name)s +} + +%(complete_func)s_setup; +""" + +_SOURCE_ZSH = """\ +#compdef %(prog_name)s + +%(complete_func)s() { + local -a completions + local -a completions_with_descriptions + local -a response + (( ! $+commands[%(prog_name)s] )) && return 1 + + response=("${(@f)$(env COMP_WORDS="${words[*]}" COMP_CWORD=$((CURRENT-1)) \ +%(complete_var)s=zsh_complete %(prog_name)s)}") + + for type key descr in ${response}; do + if [[ "$type" == "plain" ]]; then + if [[ "$descr" == "_" ]]; then + completions+=("$key") + else + completions_with_descriptions+=("$key":"$descr") + fi + elif [[ "$type" == "dir" ]]; then + _path_files -/ + elif [[ "$type" == "file" ]]; then + _path_files -f + fi + done + + if [ -n "$completions_with_descriptions" ]; then + _describe -V unsorted completions_with_descriptions -U + fi + + if [ -n "$completions" ]; then + compadd -U -V unsorted -a completions + fi +} + +if [[ $zsh_eval_context[-1] == loadautofunc ]]; then + # autoload from fpath, call function directly + %(complete_func)s "$@" +else + # eval/source/. command, register function for later + compdef %(complete_func)s %(prog_name)s +fi +""" + +_SOURCE_FISH = """\ +function %(complete_func)s; + set -l response (env %(complete_var)s=fish_complete COMP_WORDS=(commandline -cp) \ +COMP_CWORD=(commandline -t) %(prog_name)s); + + for completion in $response; + set -l metadata (string split "," $completion); + + if test $metadata[1] = "dir"; + __fish_complete_directories $metadata[2]; + else if test $metadata[1] = "file"; + __fish_complete_path $metadata[2]; + else if test $metadata[1] = "plain"; + echo $metadata[2]; + end; + end; +end; + +complete --no-files --command %(prog_name)s --arguments \ +"(%(complete_func)s)"; +""" + + +class ShellComplete: + """Base class for providing shell completion support. A subclass for + a given shell will override attributes and methods to implement the + completion instructions (``source`` and ``complete``). + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param complete_var: Name of the environment variable that holds + the completion instruction. + + .. versionadded:: 8.0 + """ + + name: t.ClassVar[str] + """Name to register the shell as with :func:`add_completion_class`. + This is used in completion instructions (``{name}_source`` and + ``{name}_complete``). + """ + + source_template: t.ClassVar[str] + """Completion script template formatted by :meth:`source`. This must + be provided by subclasses. + """ + + def __init__( + self, + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + complete_var: str, + ) -> None: + self.cli = cli + self.ctx_args = ctx_args + self.prog_name = prog_name + self.complete_var = complete_var + + @property + def func_name(self) -> str: + """The name of the shell function defined by the completion + script. + """ + safe_name = re.sub(r"\W*", "", self.prog_name.replace("-", "_"), flags=re.ASCII) + return f"_{safe_name}_completion" + + def source_vars(self) -> t.Dict[str, t.Any]: + """Vars for formatting :attr:`source_template`. + + By default this provides ``complete_func``, ``complete_var``, + and ``prog_name``. + """ + return { + "complete_func": self.func_name, + "complete_var": self.complete_var, + "prog_name": self.prog_name, + } + + def source(self) -> str: + """Produce the shell script that defines the completion + function. By default this ``%``-style formats + :attr:`source_template` with the dict returned by + :meth:`source_vars`. + """ + return self.source_template % self.source_vars() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + """Use the env vars defined by the shell script to return a + tuple of ``args, incomplete``. This must be implemented by + subclasses. + """ + raise NotImplementedError + + def get_completions( + self, args: t.List[str], incomplete: str + ) -> t.List[CompletionItem]: + """Determine the context and last complete command or parameter + from the complete args. Call that object's ``shell_complete`` + method to get the completions for the incomplete value. + + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + ctx = _resolve_context(self.cli, self.ctx_args, self.prog_name, args) + obj, incomplete = _resolve_incomplete(ctx, args, incomplete) + return obj.shell_complete(ctx, incomplete) + + def format_completion(self, item: CompletionItem) -> str: + """Format a completion item into the form recognized by the + shell script. This must be implemented by subclasses. + + :param item: Completion item to format. + """ + raise NotImplementedError + + def complete(self) -> str: + """Produce the completion data to send back to the shell. + + By default this calls :meth:`get_completion_args`, gets the + completions, then calls :meth:`format_completion` for each + completion. + """ + args, incomplete = self.get_completion_args() + completions = self.get_completions(args, incomplete) + out = [self.format_completion(item) for item in completions] + return "\n".join(out) + + +class BashComplete(ShellComplete): + """Shell completion for Bash.""" + + name = "bash" + source_template = _SOURCE_BASH + + @staticmethod + def _check_version() -> None: + import subprocess + + output = subprocess.run( + ["bash", "-c", 'echo "${BASH_VERSION}"'], stdout=subprocess.PIPE + ) + match = re.search(r"^(\d+)\.(\d+)\.\d+", output.stdout.decode()) + + if match is not None: + major, minor = match.groups() + + if major < "4" or major == "4" and minor < "4": + echo( + _( + "Shell completion is not supported for Bash" + " versions older than 4.4." + ), + err=True, + ) + else: + echo( + _("Couldn't detect Bash version, shell completion is not supported."), + err=True, + ) + + def source(self) -> str: + self._check_version() + return super().source() + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type},{item.value}" + + +class ZshComplete(ShellComplete): + """Shell completion for Zsh.""" + + name = "zsh" + source_template = _SOURCE_ZSH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + cword = int(os.environ["COMP_CWORD"]) + args = cwords[1:cword] + + try: + incomplete = cwords[cword] + except IndexError: + incomplete = "" + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + return f"{item.type}\n{item.value}\n{item.help if item.help else '_'}" + + +class FishComplete(ShellComplete): + """Shell completion for Fish.""" + + name = "fish" + source_template = _SOURCE_FISH + + def get_completion_args(self) -> t.Tuple[t.List[str], str]: + cwords = split_arg_string(os.environ["COMP_WORDS"]) + incomplete = os.environ["COMP_CWORD"] + args = cwords[1:] + + # Fish stores the partial word in both COMP_WORDS and + # COMP_CWORD, remove it from complete args. + if incomplete and args and args[-1] == incomplete: + args.pop() + + return args, incomplete + + def format_completion(self, item: CompletionItem) -> str: + if item.help: + return f"{item.type},{item.value}\t{item.help}" + + return f"{item.type},{item.value}" + + +ShellCompleteType = t.TypeVar("ShellCompleteType", bound=t.Type[ShellComplete]) + + +_available_shells: t.Dict[str, t.Type[ShellComplete]] = { + "bash": BashComplete, + "fish": FishComplete, + "zsh": ZshComplete, +} + + +def add_completion_class( + cls: ShellCompleteType, name: t.Optional[str] = None +) -> ShellCompleteType: + """Register a :class:`ShellComplete` subclass under the given name. + The name will be provided by the completion instruction environment + variable during completion. + + :param cls: The completion class that will handle completion for the + shell. + :param name: Name to register the class under. Defaults to the + class's ``name`` attribute. + """ + if name is None: + name = cls.name + + _available_shells[name] = cls + + return cls + + +def get_completion_class(shell: str) -> t.Optional[t.Type[ShellComplete]]: + """Look up a registered :class:`ShellComplete` subclass by the name + provided by the completion instruction environment variable. If the + name isn't registered, returns ``None``. + + :param shell: Name the class is registered under. + """ + return _available_shells.get(shell) + + +def _is_incomplete_argument(ctx: Context, param: Parameter) -> bool: + """Determine if the given parameter is an argument that can still + accept values. + + :param ctx: Invocation context for the command represented by the + parsed complete args. + :param param: Argument object being checked. + """ + if not isinstance(param, Argument): + return False + + assert param.name is not None + # Will be None if expose_value is False. + value = ctx.params.get(param.name) + return ( + param.nargs == -1 + or ctx.get_parameter_source(param.name) is not ParameterSource.COMMANDLINE + or ( + param.nargs > 1 + and isinstance(value, (tuple, list)) + and len(value) < param.nargs + ) + ) + + +def _start_of_option(ctx: Context, value: str) -> bool: + """Check if the value looks like the start of an option.""" + if not value: + return False + + c = value[0] + return c in ctx._opt_prefixes + + +def _is_incomplete_option(ctx: Context, args: t.List[str], param: Parameter) -> bool: + """Determine if the given parameter is an option that needs a value. + + :param args: List of complete args before the incomplete value. + :param param: Option object being checked. + """ + if not isinstance(param, Option): + return False + + if param.is_flag or param.count: + return False + + last_option = None + + for index, arg in enumerate(reversed(args)): + if index + 1 > param.nargs: + break + + if _start_of_option(ctx, arg): + last_option = arg + + return last_option is not None and last_option in param.opts + + +def _resolve_context( + cli: BaseCommand, + ctx_args: t.MutableMapping[str, t.Any], + prog_name: str, + args: t.List[str], +) -> Context: + """Produce the context hierarchy starting with the command and + traversing the complete arguments. This only follows the commands, + it doesn't trigger input prompts or callbacks. + + :param cli: Command being called. + :param prog_name: Name of the executable in the shell. + :param args: List of complete args before the incomplete value. + """ + ctx_args["resilient_parsing"] = True + ctx = cli.make_context(prog_name, args.copy(), **ctx_args) + args = ctx.protected_args + ctx.args + + while args: + command = ctx.command + + if isinstance(command, MultiCommand): + if not command.chain: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + ctx = cmd.make_context(name, args, parent=ctx, resilient_parsing=True) + args = ctx.protected_args + ctx.args + else: + sub_ctx = ctx + + while args: + name, cmd, args = command.resolve_command(ctx, args) + + if cmd is None: + return ctx + + sub_ctx = cmd.make_context( + name, + args, + parent=ctx, + allow_extra_args=True, + allow_interspersed_args=False, + resilient_parsing=True, + ) + args = sub_ctx.args + + ctx = sub_ctx + args = [*sub_ctx.protected_args, *sub_ctx.args] + else: + break + + return ctx + + +def _resolve_incomplete( + ctx: Context, args: t.List[str], incomplete: str +) -> t.Tuple[t.Union[BaseCommand, Parameter], str]: + """Find the Click object that will handle the completion of the + incomplete value. Return the object and the incomplete value. + + :param ctx: Invocation context for the command represented by + the parsed complete args. + :param args: List of complete args before the incomplete value. + :param incomplete: Value being completed. May be empty. + """ + # Different shells treat an "=" between a long option name and + # value differently. Might keep the value joined, return the "=" + # as a separate item, or return the split name and value. Always + # split and discard the "=" to make completion easier. + if incomplete == "=": + incomplete = "" + elif "=" in incomplete and _start_of_option(ctx, incomplete): + name, _, incomplete = incomplete.partition("=") + args.append(name) + + # The "--" marker tells Click to stop treating values as options + # even if they start with the option character. If it hasn't been + # given and the incomplete arg looks like an option, the current + # command will provide option name completions. + if "--" not in args and _start_of_option(ctx, incomplete): + return ctx.command, incomplete + + params = ctx.command.get_params(ctx) + + # If the last complete arg is an option name with an incomplete + # value, the option will provide value completions. + for param in params: + if _is_incomplete_option(ctx, args, param): + return param, incomplete + + # It's not an option name or value. The first argument without a + # parsed value will provide value completions. + for param in params: + if _is_incomplete_argument(ctx, param): + return param, incomplete + + # There were no unparsed arguments, the command may be a group that + # will provide command name completions. + return ctx.command, incomplete diff --git a/venv/lib/python3.12/site-packages/click/termui.py b/venv/lib/python3.12/site-packages/click/termui.py new file mode 100644 index 0000000..db7a4b2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/termui.py @@ -0,0 +1,784 @@ +import inspect +import io +import itertools +import sys +import typing as t +from gettext import gettext as _ + +from ._compat import isatty +from ._compat import strip_ansi +from .exceptions import Abort +from .exceptions import UsageError +from .globals import resolve_color_default +from .types import Choice +from .types import convert_type +from .types import ParamType +from .utils import echo +from .utils import LazyFile + +if t.TYPE_CHECKING: + from ._termui_impl import ProgressBar + +V = t.TypeVar("V") + +# The prompt functions to use. The doc tools currently override these +# functions to customize how they work. +visible_prompt_func: t.Callable[[str], str] = input + +_ansi_colors = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, + "reset": 39, + "bright_black": 90, + "bright_red": 91, + "bright_green": 92, + "bright_yellow": 93, + "bright_blue": 94, + "bright_magenta": 95, + "bright_cyan": 96, + "bright_white": 97, +} +_ansi_reset_all = "\033[0m" + + +def hidden_prompt_func(prompt: str) -> str: + import getpass + + return getpass.getpass(prompt) + + +def _build_prompt( + text: str, + suffix: str, + show_default: bool = False, + default: t.Optional[t.Any] = None, + show_choices: bool = True, + type: t.Optional[ParamType] = None, +) -> str: + prompt = text + if type is not None and show_choices and isinstance(type, Choice): + prompt += f" ({', '.join(map(str, type.choices))})" + if default is not None and show_default: + prompt = f"{prompt} [{_format_default(default)}]" + return f"{prompt}{suffix}" + + +def _format_default(default: t.Any) -> t.Any: + if isinstance(default, (io.IOBase, LazyFile)) and hasattr(default, "name"): + return default.name + + return default + + +def prompt( + text: str, + default: t.Optional[t.Any] = None, + hide_input: bool = False, + confirmation_prompt: t.Union[bool, str] = False, + type: t.Optional[t.Union[ParamType, t.Any]] = None, + value_proc: t.Optional[t.Callable[[str], t.Any]] = None, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, + show_choices: bool = True, +) -> t.Any: + """Prompts a user for input. This is a convenience function that can + be used to prompt a user for input later. + + If the user aborts the input by sending an interrupt signal, this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the text to show for the prompt. + :param default: the default value to use if no input happens. If this + is not given it will prompt until it's aborted. + :param hide_input: if this is set to true then the input value will + be hidden. + :param confirmation_prompt: Prompt a second time to confirm the + value. Can be set to a string instead of ``True`` to customize + the message. + :param type: the type to use to check the value against. + :param value_proc: if this parameter is provided it's a function that + is invoked instead of the type conversion to + convert a value. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + :param show_choices: Show or hide choices if the passed type is a Choice. + For example if type is a Choice of either day or week, + show_choices is true and text is "Group by" then the + prompt will be "Group by (day, week): ". + + .. versionadded:: 8.0 + ``confirmation_prompt`` can be a custom string. + + .. versionadded:: 7.0 + Added the ``show_choices`` parameter. + + .. versionadded:: 6.0 + Added unicode support for cmd.exe on Windows. + + .. versionadded:: 4.0 + Added the `err` parameter. + + """ + + def prompt_func(text: str) -> str: + f = hidden_prompt_func if hide_input else visible_prompt_func + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(text.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + return f(" ") + except (KeyboardInterrupt, EOFError): + # getpass doesn't print a newline if the user aborts input with ^C. + # Allegedly this behavior is inherited from getpass(3). + # A doc bug has been filed at https://bugs.python.org/issue24711 + if hide_input: + echo(None, err=err) + raise Abort() from None + + if value_proc is None: + value_proc = convert_type(type, default) + + prompt = _build_prompt( + text, prompt_suffix, show_default, default, show_choices, type + ) + + if confirmation_prompt: + if confirmation_prompt is True: + confirmation_prompt = _("Repeat for confirmation") + + confirmation_prompt = _build_prompt(confirmation_prompt, prompt_suffix) + + while True: + while True: + value = prompt_func(prompt) + if value: + break + elif default is not None: + value = default + break + try: + result = value_proc(value) + except UsageError as e: + if hide_input: + echo(_("Error: The value you entered was invalid."), err=err) + else: + echo(_("Error: {e.message}").format(e=e), err=err) # noqa: B306 + continue + if not confirmation_prompt: + return result + while True: + value2 = prompt_func(confirmation_prompt) + is_empty = not value and not value2 + if value2 or is_empty: + break + if value == value2: + return result + echo(_("Error: The two entered values do not match."), err=err) + + +def confirm( + text: str, + default: t.Optional[bool] = False, + abort: bool = False, + prompt_suffix: str = ": ", + show_default: bool = True, + err: bool = False, +) -> bool: + """Prompts for confirmation (yes/no question). + + If the user aborts the input by sending a interrupt signal this + function will catch it and raise a :exc:`Abort` exception. + + :param text: the question to ask. + :param default: The default value to use when no input is given. If + ``None``, repeat until input is given. + :param abort: if this is set to `True` a negative answer aborts the + exception by raising :exc:`Abort`. + :param prompt_suffix: a suffix that should be added to the prompt. + :param show_default: shows or hides the default value in the prompt. + :param err: if set to true the file defaults to ``stderr`` instead of + ``stdout``, the same as with echo. + + .. versionchanged:: 8.0 + Repeat until input is given if ``default`` is ``None``. + + .. versionadded:: 4.0 + Added the ``err`` parameter. + """ + prompt = _build_prompt( + text, + prompt_suffix, + show_default, + "y/n" if default is None else ("Y/n" if default else "y/N"), + ) + + while True: + try: + # Write the prompt separately so that we get nice + # coloring through colorama on Windows + echo(prompt.rstrip(" "), nl=False, err=err) + # Echo a space to stdout to work around an issue where + # readline causes backspace to clear the whole line. + value = visible_prompt_func(" ").lower().strip() + except (KeyboardInterrupt, EOFError): + raise Abort() from None + if value in ("y", "yes"): + rv = True + elif value in ("n", "no"): + rv = False + elif default is not None and value == "": + rv = default + else: + echo(_("Error: invalid input"), err=err) + continue + break + if abort and not rv: + raise Abort() + return rv + + +def echo_via_pager( + text_or_generator: t.Union[t.Iterable[str], t.Callable[[], t.Iterable[str]], str], + color: t.Optional[bool] = None, +) -> None: + """This function takes a text and shows it via an environment specific + pager on stdout. + + .. versionchanged:: 3.0 + Added the `color` flag. + + :param text_or_generator: the text to page, or alternatively, a + generator emitting the text to page. + :param color: controls if the pager supports ANSI colors or not. The + default is autodetection. + """ + color = resolve_color_default(color) + + if inspect.isgeneratorfunction(text_or_generator): + i = t.cast(t.Callable[[], t.Iterable[str]], text_or_generator)() + elif isinstance(text_or_generator, str): + i = [text_or_generator] + else: + i = iter(t.cast(t.Iterable[str], text_or_generator)) + + # convert every element of i to a text type if necessary + text_generator = (el if isinstance(el, str) else str(el) for el in i) + + from ._termui_impl import pager + + return pager(itertools.chain(text_generator, "\n"), color) + + +def progressbar( + iterable: t.Optional[t.Iterable[V]] = None, + length: t.Optional[int] = None, + label: t.Optional[str] = None, + show_eta: bool = True, + show_percent: t.Optional[bool] = None, + show_pos: bool = False, + item_show_func: t.Optional[t.Callable[[t.Optional[V]], t.Optional[str]]] = None, + fill_char: str = "#", + empty_char: str = "-", + bar_template: str = "%(label)s [%(bar)s] %(info)s", + info_sep: str = " ", + width: int = 36, + file: t.Optional[t.TextIO] = None, + color: t.Optional[bool] = None, + update_min_steps: int = 1, +) -> "ProgressBar[V]": + """This function creates an iterable context manager that can be used + to iterate over something while showing a progress bar. It will + either iterate over the `iterable` or `length` items (that are counted + up). While iteration happens, this function will print a rendered + progress bar to the given `file` (defaults to stdout) and will attempt + to calculate remaining time and more. By default, this progress bar + will not be rendered if the file is not a terminal. + + The context manager creates the progress bar. When the context + manager is entered the progress bar is already created. With every + iteration over the progress bar, the iterable passed to the bar is + advanced and the bar is updated. When the context manager exits, + a newline is printed and the progress bar is finalized on screen. + + Note: The progress bar is currently designed for use cases where the + total progress can be expected to take at least several seconds. + Because of this, the ProgressBar class object won't display + progress that is considered too fast, and progress where the time + between steps is less than a second. + + No printing must happen or the progress bar will be unintentionally + destroyed. + + Example usage:: + + with progressbar(items) as bar: + for item in bar: + do_something_with(item) + + Alternatively, if no iterable is specified, one can manually update the + progress bar through the `update()` method instead of directly + iterating over the progress bar. The update method accepts the number + of steps to increment the bar with:: + + with progressbar(length=chunks.total_bytes) as bar: + for chunk in chunks: + process_chunk(chunk) + bar.update(chunks.bytes) + + The ``update()`` method also takes an optional value specifying the + ``current_item`` at the new position. This is useful when used + together with ``item_show_func`` to customize the output for each + manual step:: + + with click.progressbar( + length=total_size, + label='Unzipping archive', + item_show_func=lambda a: a.filename + ) as bar: + for archive in zip_file: + archive.extract() + bar.update(archive.size, archive) + + :param iterable: an iterable to iterate over. If not provided the length + is required. + :param length: the number of items to iterate over. By default the + progressbar will attempt to ask the iterator about its + length, which might or might not work. If an iterable is + also provided this parameter can be used to override the + length. If an iterable is not provided the progress bar + will iterate over a range of that length. + :param label: the label to show next to the progress bar. + :param show_eta: enables or disables the estimated time display. This is + automatically disabled if the length cannot be + determined. + :param show_percent: enables or disables the percentage display. The + default is `True` if the iterable has a length or + `False` if not. + :param show_pos: enables or disables the absolute position display. The + default is `False`. + :param item_show_func: A function called with the current item which + can return a string to show next to the progress bar. If the + function returns ``None`` nothing is shown. The current item can + be ``None``, such as when entering and exiting the bar. + :param fill_char: the character to use to show the filled part of the + progress bar. + :param empty_char: the character to use to show the non-filled part of + the progress bar. + :param bar_template: the format string to use as template for the bar. + The parameters in it are ``label`` for the label, + ``bar`` for the progress bar and ``info`` for the + info section. + :param info_sep: the separator between multiple info items (eta etc.) + :param width: the width of the progress bar in characters, 0 means full + terminal width + :param file: The file to write to. If this is not a terminal then + only the label is printed. + :param color: controls if the terminal supports ANSI colors or not. The + default is autodetection. This is only needed if ANSI + codes are included anywhere in the progress bar output + which is not the case by default. + :param update_min_steps: Render only when this many updates have + completed. This allows tuning for very fast iterators. + + .. versionchanged:: 8.0 + Output is shown even if execution time is less than 0.5 seconds. + + .. versionchanged:: 8.0 + ``item_show_func`` shows the current item, not the previous one. + + .. versionchanged:: 8.0 + Labels are echoed if the output is not a TTY. Reverts a change + in 7.0 that removed all output. + + .. versionadded:: 8.0 + Added the ``update_min_steps`` parameter. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. Added the ``update`` method to + the object. + + .. versionadded:: 2.0 + """ + from ._termui_impl import ProgressBar + + color = resolve_color_default(color) + return ProgressBar( + iterable=iterable, + length=length, + show_eta=show_eta, + show_percent=show_percent, + show_pos=show_pos, + item_show_func=item_show_func, + fill_char=fill_char, + empty_char=empty_char, + bar_template=bar_template, + info_sep=info_sep, + file=file, + label=label, + width=width, + color=color, + update_min_steps=update_min_steps, + ) + + +def clear() -> None: + """Clears the terminal screen. This will have the effect of clearing + the whole visible space of the terminal and moving the cursor to the + top left. This does not do anything if not connected to a terminal. + + .. versionadded:: 2.0 + """ + if not isatty(sys.stdout): + return + + # ANSI escape \033[2J clears the screen, \033[1;1H moves the cursor + echo("\033[2J\033[1;1H", nl=False) + + +def _interpret_color( + color: t.Union[int, t.Tuple[int, int, int], str], offset: int = 0 +) -> str: + if isinstance(color, int): + return f"{38 + offset};5;{color:d}" + + if isinstance(color, (tuple, list)): + r, g, b = color + return f"{38 + offset};2;{r:d};{g:d};{b:d}" + + return str(_ansi_colors[color] + offset) + + +def style( + text: t.Any, + fg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bg: t.Optional[t.Union[int, t.Tuple[int, int, int], str]] = None, + bold: t.Optional[bool] = None, + dim: t.Optional[bool] = None, + underline: t.Optional[bool] = None, + overline: t.Optional[bool] = None, + italic: t.Optional[bool] = None, + blink: t.Optional[bool] = None, + reverse: t.Optional[bool] = None, + strikethrough: t.Optional[bool] = None, + reset: bool = True, +) -> str: + """Styles a text with ANSI styles and returns the new string. By + default the styling is self contained which means that at the end + of the string a reset code is issued. This can be prevented by + passing ``reset=False``. + + Examples:: + + click.echo(click.style('Hello World!', fg='green')) + click.echo(click.style('ATTENTION!', blink=True)) + click.echo(click.style('Some things', reverse=True, fg='cyan')) + click.echo(click.style('More colors', fg=(255, 12, 128), bg=117)) + + Supported color names: + + * ``black`` (might be a gray) + * ``red`` + * ``green`` + * ``yellow`` (might be an orange) + * ``blue`` + * ``magenta`` + * ``cyan`` + * ``white`` (might be light gray) + * ``bright_black`` + * ``bright_red`` + * ``bright_green`` + * ``bright_yellow`` + * ``bright_blue`` + * ``bright_magenta`` + * ``bright_cyan`` + * ``bright_white`` + * ``reset`` (reset the color code only) + + If the terminal supports it, color may also be specified as: + + - An integer in the interval [0, 255]. The terminal must support + 8-bit/256-color mode. + - An RGB tuple of three integers in [0, 255]. The terminal must + support 24-bit/true-color mode. + + See https://en.wikipedia.org/wiki/ANSI_color and + https://gist.github.com/XVilka/8346728 for more information. + + :param text: the string to style with ansi codes. + :param fg: if provided this will become the foreground color. + :param bg: if provided this will become the background color. + :param bold: if provided this will enable or disable bold mode. + :param dim: if provided this will enable or disable dim mode. This is + badly supported. + :param underline: if provided this will enable or disable underline. + :param overline: if provided this will enable or disable overline. + :param italic: if provided this will enable or disable italic. + :param blink: if provided this will enable or disable blinking. + :param reverse: if provided this will enable or disable inverse + rendering (foreground becomes background and the + other way round). + :param strikethrough: if provided this will enable or disable + striking through text. + :param reset: by default a reset-all code is added at the end of the + string which means that styles do not carry over. This + can be disabled to compose styles. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. + + .. versionchanged:: 8.0 + Added support for 256 and RGB color codes. + + .. versionchanged:: 8.0 + Added the ``strikethrough``, ``italic``, and ``overline`` + parameters. + + .. versionchanged:: 7.0 + Added support for bright colors. + + .. versionadded:: 2.0 + """ + if not isinstance(text, str): + text = str(text) + + bits = [] + + if fg: + try: + bits.append(f"\033[{_interpret_color(fg)}m") + except KeyError: + raise TypeError(f"Unknown color {fg!r}") from None + + if bg: + try: + bits.append(f"\033[{_interpret_color(bg, 10)}m") + except KeyError: + raise TypeError(f"Unknown color {bg!r}") from None + + if bold is not None: + bits.append(f"\033[{1 if bold else 22}m") + if dim is not None: + bits.append(f"\033[{2 if dim else 22}m") + if underline is not None: + bits.append(f"\033[{4 if underline else 24}m") + if overline is not None: + bits.append(f"\033[{53 if overline else 55}m") + if italic is not None: + bits.append(f"\033[{3 if italic else 23}m") + if blink is not None: + bits.append(f"\033[{5 if blink else 25}m") + if reverse is not None: + bits.append(f"\033[{7 if reverse else 27}m") + if strikethrough is not None: + bits.append(f"\033[{9 if strikethrough else 29}m") + bits.append(text) + if reset: + bits.append(_ansi_reset_all) + return "".join(bits) + + +def unstyle(text: str) -> str: + """Removes ANSI styling information from a string. Usually it's not + necessary to use this function as Click's echo function will + automatically remove styling if necessary. + + .. versionadded:: 2.0 + + :param text: the text to remove style information from. + """ + return strip_ansi(text) + + +def secho( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.AnyStr]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, + **styles: t.Any, +) -> None: + """This function combines :func:`echo` and :func:`style` into one + call. As such the following two calls are the same:: + + click.secho('Hello World!', fg='green') + click.echo(click.style('Hello World!', fg='green')) + + All keyword arguments are forwarded to the underlying functions + depending on which one they go with. + + Non-string types will be converted to :class:`str`. However, + :class:`bytes` are passed directly to :meth:`echo` without applying + style. If you want to style bytes that represent text, call + :meth:`bytes.decode` first. + + .. versionchanged:: 8.0 + A non-string ``message`` is converted to a string. Bytes are + passed through without style applied. + + .. versionadded:: 2.0 + """ + if message is not None and not isinstance(message, (bytes, bytearray)): + message = style(message, **styles) + + return echo(message, file=file, nl=nl, err=err, color=color) + + +def edit( + text: t.Optional[t.AnyStr] = None, + editor: t.Optional[str] = None, + env: t.Optional[t.Mapping[str, str]] = None, + require_save: bool = True, + extension: str = ".txt", + filename: t.Optional[str] = None, +) -> t.Optional[t.AnyStr]: + r"""Edits the given text in the defined editor. If an editor is given + (should be the full path to the executable but the regular operating + system search path is used for finding the executable) it overrides + the detected editor. Optionally, some environment variables can be + used. If the editor is closed without changes, `None` is returned. In + case a file is edited directly the return value is always `None` and + `require_save` and `extension` are ignored. + + If the editor cannot be opened a :exc:`UsageError` is raised. + + Note for Windows: to simplify cross-platform usage, the newlines are + automatically converted from POSIX to Windows and vice versa. As such, + the message here will have ``\n`` as newline markers. + + :param text: the text to edit. + :param editor: optionally the editor to use. Defaults to automatic + detection. + :param env: environment variables to forward to the editor. + :param require_save: if this is true, then not saving in the editor + will make the return value become `None`. + :param extension: the extension to tell the editor about. This defaults + to `.txt` but changing this might change syntax + highlighting. + :param filename: if provided it will edit this file instead of the + provided text contents. It will not use a temporary + file as an indirection in that case. + """ + from ._termui_impl import Editor + + ed = Editor(editor=editor, env=env, require_save=require_save, extension=extension) + + if filename is None: + return ed.edit(text) + + ed.edit_file(filename) + return None + + +def launch(url: str, wait: bool = False, locate: bool = False) -> int: + """This function launches the given URL (or filename) in the default + viewer application for this file type. If this is an executable, it + might launch the executable in a new session. The return value is + the exit code of the launched application. Usually, ``0`` indicates + success. + + Examples:: + + click.launch('https://click.palletsprojects.com/') + click.launch('/my/downloaded/file', locate=True) + + .. versionadded:: 2.0 + + :param url: URL or filename of the thing to launch. + :param wait: Wait for the program to exit before returning. This + only works if the launched program blocks. In particular, + ``xdg-open`` on Linux does not block. + :param locate: if this is set to `True` then instead of launching the + application associated with the URL it will attempt to + launch a file manager with the file located. This + might have weird effects if the URL does not point to + the filesystem. + """ + from ._termui_impl import open_url + + return open_url(url, wait=wait, locate=locate) + + +# If this is provided, getchar() calls into this instead. This is used +# for unittesting purposes. +_getchar: t.Optional[t.Callable[[bool], str]] = None + + +def getchar(echo: bool = False) -> str: + """Fetches a single character from the terminal and returns it. This + will always return a unicode character and under certain rare + circumstances this might return more than one character. The + situations which more than one character is returned is when for + whatever reason multiple characters end up in the terminal buffer or + standard input was not actually a terminal. + + Note that this will always read from the terminal, even if something + is piped into the standard input. + + Note for Windows: in rare cases when typing non-ASCII characters, this + function might wait for a second character and then return both at once. + This is because certain Unicode characters look like special-key markers. + + .. versionadded:: 2.0 + + :param echo: if set to `True`, the character read will also show up on + the terminal. The default is to not show it. + """ + global _getchar + + if _getchar is None: + from ._termui_impl import getchar as f + + _getchar = f + + return _getchar(echo) + + +def raw_terminal() -> t.ContextManager[int]: + from ._termui_impl import raw_terminal as f + + return f() + + +def pause(info: t.Optional[str] = None, err: bool = False) -> None: + """This command stops execution and waits for the user to press any + key to continue. This is similar to the Windows batch "pause" + command. If the program is not run through a terminal, this command + will instead do nothing. + + .. versionadded:: 2.0 + + .. versionadded:: 4.0 + Added the `err` parameter. + + :param info: The message to print before pausing. Defaults to + ``"Press any key to continue..."``. + :param err: if set to message goes to ``stderr`` instead of + ``stdout``, the same as with echo. + """ + if not isatty(sys.stdin) or not isatty(sys.stdout): + return + + if info is None: + info = _("Press any key to continue...") + + try: + if info: + echo(info, nl=False, err=err) + try: + getchar() + except (KeyboardInterrupt, EOFError): + pass + finally: + if info: + echo(err=err) diff --git a/venv/lib/python3.12/site-packages/click/testing.py b/venv/lib/python3.12/site-packages/click/testing.py new file mode 100644 index 0000000..e0df0d2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/testing.py @@ -0,0 +1,479 @@ +import contextlib +import io +import os +import shlex +import shutil +import sys +import tempfile +import typing as t +from types import TracebackType + +from . import formatting +from . import termui +from . import utils +from ._compat import _find_binary_reader + +if t.TYPE_CHECKING: + from .core import BaseCommand + + +class EchoingStdin: + def __init__(self, input: t.BinaryIO, output: t.BinaryIO) -> None: + self._input = input + self._output = output + self._paused = False + + def __getattr__(self, x: str) -> t.Any: + return getattr(self._input, x) + + def _echo(self, rv: bytes) -> bytes: + if not self._paused: + self._output.write(rv) + + return rv + + def read(self, n: int = -1) -> bytes: + return self._echo(self._input.read(n)) + + def read1(self, n: int = -1) -> bytes: + return self._echo(self._input.read1(n)) # type: ignore + + def readline(self, n: int = -1) -> bytes: + return self._echo(self._input.readline(n)) + + def readlines(self) -> t.List[bytes]: + return [self._echo(x) for x in self._input.readlines()] + + def __iter__(self) -> t.Iterator[bytes]: + return iter(self._echo(x) for x in self._input) + + def __repr__(self) -> str: + return repr(self._input) + + +@contextlib.contextmanager +def _pause_echo(stream: t.Optional[EchoingStdin]) -> t.Iterator[None]: + if stream is None: + yield + else: + stream._paused = True + yield + stream._paused = False + + +class _NamedTextIOWrapper(io.TextIOWrapper): + def __init__( + self, buffer: t.BinaryIO, name: str, mode: str, **kwargs: t.Any + ) -> None: + super().__init__(buffer, **kwargs) + self._name = name + self._mode = mode + + @property + def name(self) -> str: + return self._name + + @property + def mode(self) -> str: + return self._mode + + +def make_input_stream( + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]], charset: str +) -> t.BinaryIO: + # Is already an input stream. + if hasattr(input, "read"): + rv = _find_binary_reader(t.cast(t.IO[t.Any], input)) + + if rv is not None: + return rv + + raise TypeError("Could not find binary reader for input stream.") + + if input is None: + input = b"" + elif isinstance(input, str): + input = input.encode(charset) + + return io.BytesIO(input) + + +class Result: + """Holds the captured result of an invoked CLI script.""" + + def __init__( + self, + runner: "CliRunner", + stdout_bytes: bytes, + stderr_bytes: t.Optional[bytes], + return_value: t.Any, + exit_code: int, + exception: t.Optional[BaseException], + exc_info: t.Optional[ + t.Tuple[t.Type[BaseException], BaseException, TracebackType] + ] = None, + ): + #: The runner that created the result + self.runner = runner + #: The standard output as bytes. + self.stdout_bytes = stdout_bytes + #: The standard error as bytes, or None if not available + self.stderr_bytes = stderr_bytes + #: The value returned from the invoked command. + #: + #: .. versionadded:: 8.0 + self.return_value = return_value + #: The exit code as integer. + self.exit_code = exit_code + #: The exception that happened if one did. + self.exception = exception + #: The traceback + self.exc_info = exc_info + + @property + def output(self) -> str: + """The (standard) output as unicode string.""" + return self.stdout + + @property + def stdout(self) -> str: + """The standard output as unicode string.""" + return self.stdout_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + @property + def stderr(self) -> str: + """The standard error as unicode string.""" + if self.stderr_bytes is None: + raise ValueError("stderr not separately captured") + return self.stderr_bytes.decode(self.runner.charset, "replace").replace( + "\r\n", "\n" + ) + + def __repr__(self) -> str: + exc_str = repr(self.exception) if self.exception else "okay" + return f"<{type(self).__name__} {exc_str}>" + + +class CliRunner: + """The CLI runner provides functionality to invoke a Click command line + script for unittesting purposes in a isolated environment. This only + works in single-threaded systems without any concurrency as it changes the + global interpreter state. + + :param charset: the character set for the input and output data. + :param env: a dictionary with environment variables for overriding. + :param echo_stdin: if this is set to `True`, then reading from stdin writes + to stdout. This is useful for showing examples in + some circumstances. Note that regular prompts + will automatically echo the input. + :param mix_stderr: if this is set to `False`, then stdout and stderr are + preserved as independent streams. This is useful for + Unix-philosophy apps that have predictable stdout and + noisy stderr, such that each may be measured + independently + """ + + def __init__( + self, + charset: str = "utf-8", + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + echo_stdin: bool = False, + mix_stderr: bool = True, + ) -> None: + self.charset = charset + self.env: t.Mapping[str, t.Optional[str]] = env or {} + self.echo_stdin = echo_stdin + self.mix_stderr = mix_stderr + + def get_default_prog_name(self, cli: "BaseCommand") -> str: + """Given a command object it will return the default program name + for it. The default is the `name` attribute or ``"root"`` if not + set. + """ + return cli.name or "root" + + def make_env( + self, overrides: t.Optional[t.Mapping[str, t.Optional[str]]] = None + ) -> t.Mapping[str, t.Optional[str]]: + """Returns the environment overrides for invoking a script.""" + rv = dict(self.env) + if overrides: + rv.update(overrides) + return rv + + @contextlib.contextmanager + def isolation( + self, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + color: bool = False, + ) -> t.Iterator[t.Tuple[io.BytesIO, t.Optional[io.BytesIO]]]: + """A context manager that sets up the isolation for invoking of a + command line tool. This sets up stdin with the given input data + and `os.environ` with the overrides from the given dictionary. + This also rebinds some internals in Click to be mocked (like the + prompt functionality). + + This is automatically done in the :meth:`invoke` method. + + :param input: the input stream to put into sys.stdin. + :param env: the environment overrides as dictionary. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + ``stderr`` is opened with ``errors="backslashreplace"`` + instead of the default ``"strict"``. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + """ + bytes_input = make_input_stream(input, self.charset) + echo_input = None + + old_stdin = sys.stdin + old_stdout = sys.stdout + old_stderr = sys.stderr + old_forced_width = formatting.FORCED_WIDTH + formatting.FORCED_WIDTH = 80 + + env = self.make_env(env) + + bytes_output = io.BytesIO() + + if self.echo_stdin: + bytes_input = echo_input = t.cast( + t.BinaryIO, EchoingStdin(bytes_input, bytes_output) + ) + + sys.stdin = text_input = _NamedTextIOWrapper( + bytes_input, encoding=self.charset, name="", mode="r" + ) + + if self.echo_stdin: + # Force unbuffered reads, otherwise TextIOWrapper reads a + # large chunk which is echoed early. + text_input._CHUNK_SIZE = 1 # type: ignore + + sys.stdout = _NamedTextIOWrapper( + bytes_output, encoding=self.charset, name="", mode="w" + ) + + bytes_error = None + if self.mix_stderr: + sys.stderr = sys.stdout + else: + bytes_error = io.BytesIO() + sys.stderr = _NamedTextIOWrapper( + bytes_error, + encoding=self.charset, + name="", + mode="w", + errors="backslashreplace", + ) + + @_pause_echo(echo_input) # type: ignore + def visible_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(prompt or "") + val = text_input.readline().rstrip("\r\n") + sys.stdout.write(f"{val}\n") + sys.stdout.flush() + return val + + @_pause_echo(echo_input) # type: ignore + def hidden_input(prompt: t.Optional[str] = None) -> str: + sys.stdout.write(f"{prompt or ''}\n") + sys.stdout.flush() + return text_input.readline().rstrip("\r\n") + + @_pause_echo(echo_input) # type: ignore + def _getchar(echo: bool) -> str: + char = sys.stdin.read(1) + + if echo: + sys.stdout.write(char) + + sys.stdout.flush() + return char + + default_color = color + + def should_strip_ansi( + stream: t.Optional[t.IO[t.Any]] = None, color: t.Optional[bool] = None + ) -> bool: + if color is None: + return not default_color + return not color + + old_visible_prompt_func = termui.visible_prompt_func + old_hidden_prompt_func = termui.hidden_prompt_func + old__getchar_func = termui._getchar + old_should_strip_ansi = utils.should_strip_ansi # type: ignore + termui.visible_prompt_func = visible_input + termui.hidden_prompt_func = hidden_input + termui._getchar = _getchar + utils.should_strip_ansi = should_strip_ansi # type: ignore + + old_env = {} + try: + for key, value in env.items(): + old_env[key] = os.environ.get(key) + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + yield (bytes_output, bytes_error) + finally: + for key, value in old_env.items(): + if value is None: + try: + del os.environ[key] + except Exception: + pass + else: + os.environ[key] = value + sys.stdout = old_stdout + sys.stderr = old_stderr + sys.stdin = old_stdin + termui.visible_prompt_func = old_visible_prompt_func + termui.hidden_prompt_func = old_hidden_prompt_func + termui._getchar = old__getchar_func + utils.should_strip_ansi = old_should_strip_ansi # type: ignore + formatting.FORCED_WIDTH = old_forced_width + + def invoke( + self, + cli: "BaseCommand", + args: t.Optional[t.Union[str, t.Sequence[str]]] = None, + input: t.Optional[t.Union[str, bytes, t.IO[t.Any]]] = None, + env: t.Optional[t.Mapping[str, t.Optional[str]]] = None, + catch_exceptions: bool = True, + color: bool = False, + **extra: t.Any, + ) -> Result: + """Invokes a command in an isolated environment. The arguments are + forwarded directly to the command line script, the `extra` keyword + arguments are passed to the :meth:`~clickpkg.Command.main` function of + the command. + + This returns a :class:`Result` object. + + :param cli: the command to invoke + :param args: the arguments to invoke. It may be given as an iterable + or a string. When given as string it will be interpreted + as a Unix shell command. More details at + :func:`shlex.split`. + :param input: the input data for `sys.stdin`. + :param env: the environment overrides. + :param catch_exceptions: Whether to catch any other exceptions than + ``SystemExit``. + :param extra: the keyword arguments to pass to :meth:`main`. + :param color: whether the output should contain color codes. The + application can still override this explicitly. + + .. versionchanged:: 8.0 + The result object has the ``return_value`` attribute with + the value returned from the invoked command. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionchanged:: 3.0 + Added the ``catch_exceptions`` parameter. + + .. versionchanged:: 3.0 + The result object has the ``exc_info`` attribute with the + traceback if available. + """ + exc_info = None + with self.isolation(input=input, env=env, color=color) as outstreams: + return_value = None + exception: t.Optional[BaseException] = None + exit_code = 0 + + if isinstance(args, str): + args = shlex.split(args) + + try: + prog_name = extra.pop("prog_name") + except KeyError: + prog_name = self.get_default_prog_name(cli) + + try: + return_value = cli.main(args=args or (), prog_name=prog_name, **extra) + except SystemExit as e: + exc_info = sys.exc_info() + e_code = t.cast(t.Optional[t.Union[int, t.Any]], e.code) + + if e_code is None: + e_code = 0 + + if e_code != 0: + exception = e + + if not isinstance(e_code, int): + sys.stdout.write(str(e_code)) + sys.stdout.write("\n") + e_code = 1 + + exit_code = e_code + + except Exception as e: + if not catch_exceptions: + raise + exception = e + exit_code = 1 + exc_info = sys.exc_info() + finally: + sys.stdout.flush() + stdout = outstreams[0].getvalue() + if self.mix_stderr: + stderr = None + else: + stderr = outstreams[1].getvalue() # type: ignore + + return Result( + runner=self, + stdout_bytes=stdout, + stderr_bytes=stderr, + return_value=return_value, + exit_code=exit_code, + exception=exception, + exc_info=exc_info, # type: ignore + ) + + @contextlib.contextmanager + def isolated_filesystem( + self, temp_dir: t.Optional[t.Union[str, "os.PathLike[str]"]] = None + ) -> t.Iterator[str]: + """A context manager that creates a temporary directory and + changes the current working directory to it. This isolates tests + that affect the contents of the CWD to prevent them from + interfering with each other. + + :param temp_dir: Create the temporary directory under this + directory. If given, the created directory is not removed + when exiting. + + .. versionchanged:: 8.0 + Added the ``temp_dir`` parameter. + """ + cwd = os.getcwd() + dt = tempfile.mkdtemp(dir=temp_dir) + os.chdir(dt) + + try: + yield dt + finally: + os.chdir(cwd) + + if temp_dir is None: + try: + shutil.rmtree(dt) + except OSError: # noqa: B014 + pass diff --git a/venv/lib/python3.12/site-packages/click/types.py b/venv/lib/python3.12/site-packages/click/types.py new file mode 100644 index 0000000..2b1d179 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/types.py @@ -0,0 +1,1089 @@ +import os +import stat +import sys +import typing as t +from datetime import datetime +from gettext import gettext as _ +from gettext import ngettext + +from ._compat import _get_argv_encoding +from ._compat import open_stream +from .exceptions import BadParameter +from .utils import format_filename +from .utils import LazyFile +from .utils import safecall + +if t.TYPE_CHECKING: + import typing_extensions as te + from .core import Context + from .core import Parameter + from .shell_completion import CompletionItem + + +class ParamType: + """Represents the type of a parameter. Validates and converts values + from the command line or Python into the correct type. + + To implement a custom type, subclass and implement at least the + following: + + - The :attr:`name` class attribute must be set. + - Calling an instance of the type with ``None`` must return + ``None``. This is already implemented by default. + - :meth:`convert` must convert string values to the correct type. + - :meth:`convert` must accept values that are already the correct + type. + - It must be able to convert a value if the ``ctx`` and ``param`` + arguments are ``None``. This can occur when converting prompt + input. + """ + + is_composite: t.ClassVar[bool] = False + arity: t.ClassVar[int] = 1 + + #: the descriptive name of this type + name: str + + #: if a list of this type is expected and the value is pulled from a + #: string environment variable, this is what splits it up. `None` + #: means any whitespace. For all parameters the general rule is that + #: whitespace splits them up. The exception are paths and files which + #: are split by ``os.path.pathsep`` by default (":" on Unix and ";" on + #: Windows). + envvar_list_splitter: t.ClassVar[t.Optional[str]] = None + + def to_info_dict(self) -> t.Dict[str, t.Any]: + """Gather information that could be useful for a tool generating + user-facing documentation. + + Use :meth:`click.Context.to_info_dict` to traverse the entire + CLI structure. + + .. versionadded:: 8.0 + """ + # The class name without the "ParamType" suffix. + param_type = type(self).__name__.partition("ParamType")[0] + param_type = param_type.partition("ParameterType")[0] + + # Custom subclasses might not remember to set a name. + if hasattr(self, "name"): + name = self.name + else: + name = param_type + + return {"param_type": param_type, "name": name} + + def __call__( + self, + value: t.Any, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> t.Any: + if value is not None: + return self.convert(value, param, ctx) + + def get_metavar(self, param: "Parameter") -> t.Optional[str]: + """Returns the metavar default for this param if it provides one.""" + + def get_missing_message(self, param: "Parameter") -> t.Optional[str]: + """Optionally might return extra information about a missing + parameter. + + .. versionadded:: 2.0 + """ + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + """Convert the value to the correct type. This is not called if + the value is ``None`` (the missing value). + + This must accept string values from the command line, as well as + values that are already the correct type. It may also convert + other compatible types. + + The ``param`` and ``ctx`` arguments may be ``None`` in certain + situations, such as when converting prompt input. + + If the value cannot be converted, call :meth:`fail` with a + descriptive message. + + :param value: The value to convert. + :param param: The parameter that is using this type to convert + its value. May be ``None``. + :param ctx: The current context that arrived at this value. May + be ``None``. + """ + return value + + def split_envvar_value(self, rv: str) -> t.Sequence[str]: + """Given a value from an environment variable this splits it up + into small chunks depending on the defined envvar list splitter. + + If the splitter is set to `None`, which means that whitespace splits, + then leading and trailing whitespace is ignored. Otherwise, leading + and trailing splitters usually lead to empty items being included. + """ + return (rv or "").split(self.envvar_list_splitter) + + def fail( + self, + message: str, + param: t.Optional["Parameter"] = None, + ctx: t.Optional["Context"] = None, + ) -> "t.NoReturn": + """Helper method to fail with an invalid value message.""" + raise BadParameter(message, ctx=ctx, param=param) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a list of + :class:`~click.shell_completion.CompletionItem` objects for the + incomplete value. Most types do not provide completions, but + some do, and this allows custom types to provide custom + completions as well. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + return [] + + +class CompositeParamType(ParamType): + is_composite = True + + @property + def arity(self) -> int: # type: ignore + raise NotImplementedError() + + +class FuncParamType(ParamType): + def __init__(self, func: t.Callable[[t.Any], t.Any]) -> None: + self.name: str = func.__name__ + self.func = func + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["func"] = self.func + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self.func(value) + except ValueError: + try: + value = str(value) + except UnicodeError: + value = value.decode("utf-8", "replace") + + self.fail(value, param, ctx) + + +class UnprocessedParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + return value + + def __repr__(self) -> str: + return "UNPROCESSED" + + +class StringParamType(ParamType): + name = "text" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, bytes): + enc = _get_argv_encoding() + try: + value = value.decode(enc) + except UnicodeError: + fs_enc = sys.getfilesystemencoding() + if fs_enc != enc: + try: + value = value.decode(fs_enc) + except UnicodeError: + value = value.decode("utf-8", "replace") + else: + value = value.decode("utf-8", "replace") + return value + return str(value) + + def __repr__(self) -> str: + return "STRING" + + +class Choice(ParamType): + """The choice type allows a value to be checked against a fixed set + of supported values. All of these values have to be strings. + + You should only pass a list or tuple of choices. Other iterables + (like generators) may lead to surprising results. + + The resulting value will always be one of the originally passed choices + regardless of ``case_sensitive`` or any ``ctx.token_normalize_func`` + being specified. + + See :ref:`choice-opts` for an example. + + :param case_sensitive: Set to false to make choices case + insensitive. Defaults to true. + """ + + name = "choice" + + def __init__(self, choices: t.Sequence[str], case_sensitive: bool = True) -> None: + self.choices = choices + self.case_sensitive = case_sensitive + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["choices"] = self.choices + info_dict["case_sensitive"] = self.case_sensitive + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + choices_str = "|".join(self.choices) + + # Use curly braces to indicate a required argument. + if param.required and param.param_type_name == "argument": + return f"{{{choices_str}}}" + + # Use square braces to indicate an option or optional argument. + return f"[{choices_str}]" + + def get_missing_message(self, param: "Parameter") -> str: + return _("Choose from:\n\t{choices}").format(choices=",\n\t".join(self.choices)) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + # Match through normalization and case sensitivity + # first do token_normalize_func, then lowercase + # preserve original `value` to produce an accurate message in + # `self.fail` + normed_value = value + normed_choices = {choice: choice for choice in self.choices} + + if ctx is not None and ctx.token_normalize_func is not None: + normed_value = ctx.token_normalize_func(value) + normed_choices = { + ctx.token_normalize_func(normed_choice): original + for normed_choice, original in normed_choices.items() + } + + if not self.case_sensitive: + normed_value = normed_value.casefold() + normed_choices = { + normed_choice.casefold(): original + for normed_choice, original in normed_choices.items() + } + + if normed_value in normed_choices: + return normed_choices[normed_value] + + choices_str = ", ".join(map(repr, self.choices)) + self.fail( + ngettext( + "{value!r} is not {choice}.", + "{value!r} is not one of {choices}.", + len(self.choices), + ).format(value=value, choice=choices_str, choices=choices_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return f"Choice({list(self.choices)})" + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Complete choices that start with the incomplete value. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + str_choices = map(str, self.choices) + + if self.case_sensitive: + matched = (c for c in str_choices if c.startswith(incomplete)) + else: + incomplete = incomplete.lower() + matched = (c for c in str_choices if c.lower().startswith(incomplete)) + + return [CompletionItem(c) for c in matched] + + +class DateTime(ParamType): + """The DateTime type converts date strings into `datetime` objects. + + The format strings which are checked are configurable, but default to some + common (non-timezone aware) ISO 8601 formats. + + When specifying *DateTime* formats, you should only pass a list or a tuple. + Other iterables, like generators, may lead to surprising results. + + The format strings are processed using ``datetime.strptime``, and this + consequently defines the format strings which are allowed. + + Parsing is tried using each format, in order, and the first format which + parses successfully is used. + + :param formats: A list or tuple of date format strings, in the order in + which they should be tried. Defaults to + ``'%Y-%m-%d'``, ``'%Y-%m-%dT%H:%M:%S'``, + ``'%Y-%m-%d %H:%M:%S'``. + """ + + name = "datetime" + + def __init__(self, formats: t.Optional[t.Sequence[str]] = None): + self.formats: t.Sequence[str] = formats or [ + "%Y-%m-%d", + "%Y-%m-%dT%H:%M:%S", + "%Y-%m-%d %H:%M:%S", + ] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["formats"] = self.formats + return info_dict + + def get_metavar(self, param: "Parameter") -> str: + return f"[{'|'.join(self.formats)}]" + + def _try_to_convert_date(self, value: t.Any, format: str) -> t.Optional[datetime]: + try: + return datetime.strptime(value, format) + except ValueError: + return None + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if isinstance(value, datetime): + return value + + for format in self.formats: + converted = self._try_to_convert_date(value, format) + + if converted is not None: + return converted + + formats_str = ", ".join(map(repr, self.formats)) + self.fail( + ngettext( + "{value!r} does not match the format {format}.", + "{value!r} does not match the formats {formats}.", + len(self.formats), + ).format(value=value, format=formats_str, formats=formats_str), + param, + ctx, + ) + + def __repr__(self) -> str: + return "DateTime" + + +class _NumberParamTypeBase(ParamType): + _number_class: t.ClassVar[t.Type[t.Any]] + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + try: + return self._number_class(value) + except ValueError: + self.fail( + _("{value!r} is not a valid {number_type}.").format( + value=value, number_type=self.name + ), + param, + ctx, + ) + + +class _NumberRangeBase(_NumberParamTypeBase): + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + self.min = min + self.max = max + self.min_open = min_open + self.max_open = max_open + self.clamp = clamp + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + min=self.min, + max=self.max, + min_open=self.min_open, + max_open=self.max_open, + clamp=self.clamp, + ) + return info_dict + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import operator + + rv = super().convert(value, param, ctx) + lt_min: bool = self.min is not None and ( + operator.le if self.min_open else operator.lt + )(rv, self.min) + gt_max: bool = self.max is not None and ( + operator.ge if self.max_open else operator.gt + )(rv, self.max) + + if self.clamp: + if lt_min: + return self._clamp(self.min, 1, self.min_open) # type: ignore + + if gt_max: + return self._clamp(self.max, -1, self.max_open) # type: ignore + + if lt_min or gt_max: + self.fail( + _("{value} is not in the range {range}.").format( + value=rv, range=self._describe_range() + ), + param, + ctx, + ) + + return rv + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + """Find the valid value to clamp to bound in the given + direction. + + :param bound: The boundary value. + :param dir: 1 or -1 indicating the direction to move. + :param open: If true, the range does not include the bound. + """ + raise NotImplementedError + + def _describe_range(self) -> str: + """Describe the range for use in help text.""" + if self.min is None: + op = "<" if self.max_open else "<=" + return f"x{op}{self.max}" + + if self.max is None: + op = ">" if self.min_open else ">=" + return f"x{op}{self.min}" + + lop = "<" if self.min_open else "<=" + rop = "<" if self.max_open else "<=" + return f"{self.min}{lop}x{rop}{self.max}" + + def __repr__(self) -> str: + clamp = " clamped" if self.clamp else "" + return f"<{type(self).__name__} {self._describe_range()}{clamp}>" + + +class IntParamType(_NumberParamTypeBase): + name = "integer" + _number_class = int + + def __repr__(self) -> str: + return "INT" + + +class IntRange(_NumberRangeBase, IntParamType): + """Restrict an :data:`click.INT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "integer range" + + def _clamp( # type: ignore + self, bound: int, dir: "te.Literal[1, -1]", open: bool + ) -> int: + if not open: + return bound + + return bound + dir + + +class FloatParamType(_NumberParamTypeBase): + name = "float" + _number_class = float + + def __repr__(self) -> str: + return "FLOAT" + + +class FloatRange(_NumberRangeBase, FloatParamType): + """Restrict a :data:`click.FLOAT` value to a range of accepted + values. See :ref:`ranges`. + + If ``min`` or ``max`` are not passed, any value is accepted in that + direction. If ``min_open`` or ``max_open`` are enabled, the + corresponding boundary is not included in the range. + + If ``clamp`` is enabled, a value outside the range is clamped to the + boundary instead of failing. This is not supported if either + boundary is marked ``open``. + + .. versionchanged:: 8.0 + Added the ``min_open`` and ``max_open`` parameters. + """ + + name = "float range" + + def __init__( + self, + min: t.Optional[float] = None, + max: t.Optional[float] = None, + min_open: bool = False, + max_open: bool = False, + clamp: bool = False, + ) -> None: + super().__init__( + min=min, max=max, min_open=min_open, max_open=max_open, clamp=clamp + ) + + if (min_open or max_open) and clamp: + raise TypeError("Clamping is not supported for open bounds.") + + def _clamp(self, bound: float, dir: "te.Literal[1, -1]", open: bool) -> float: + if not open: + return bound + + # Could use Python 3.9's math.nextafter here, but clamping an + # open float range doesn't seem to be particularly useful. It's + # left up to the user to write a callback to do it if needed. + raise RuntimeError("Clamping is not supported for open bounds.") + + +class BoolParamType(ParamType): + name = "boolean" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + if value in {False, True}: + return bool(value) + + norm = value.strip().lower() + + if norm in {"1", "true", "t", "yes", "y", "on"}: + return True + + if norm in {"0", "false", "f", "no", "n", "off"}: + return False + + self.fail( + _("{value!r} is not a valid boolean.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "BOOL" + + +class UUIDParameterType(ParamType): + name = "uuid" + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + import uuid + + if isinstance(value, uuid.UUID): + return value + + value = value.strip() + + try: + return uuid.UUID(value) + except ValueError: + self.fail( + _("{value!r} is not a valid UUID.").format(value=value), param, ctx + ) + + def __repr__(self) -> str: + return "UUID" + + +class File(ParamType): + """Declares a parameter to be a file for reading or writing. The file + is automatically closed once the context tears down (after the command + finished working). + + Files can be opened for reading or writing. The special value ``-`` + indicates stdin or stdout depending on the mode. + + By default, the file is opened for reading text data, but it can also be + opened in binary mode or for writing. The encoding parameter can be used + to force a specific encoding. + + The `lazy` flag controls if the file should be opened immediately or upon + first IO. The default is to be non-lazy for standard input and output + streams as well as files opened for reading, `lazy` otherwise. When opening a + file lazily for reading, it is still opened temporarily for validation, but + will not be held open until first IO. lazy is mainly useful when opening + for writing to avoid creating the file until it is needed. + + Starting with Click 2.0, files can also be opened atomically in which + case all writes go into a separate file in the same folder and upon + completion the file will be moved over to the original location. This + is useful if a file regularly read by other users is modified. + + See :ref:`file-args` for more information. + """ + + name = "filename" + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: t.Optional[bool] = None, + atomic: bool = False, + ) -> None: + self.mode = mode + self.encoding = encoding + self.errors = errors + self.lazy = lazy + self.atomic = atomic + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update(mode=self.mode, encoding=self.encoding) + return info_dict + + def resolve_lazy_flag(self, value: "t.Union[str, os.PathLike[str]]") -> bool: + if self.lazy is not None: + return self.lazy + if os.fspath(value) == "-": + return False + elif "w" in self.mode: + return True + return False + + def convert( + self, + value: t.Union[str, "os.PathLike[str]", t.IO[t.Any]], + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> t.IO[t.Any]: + if _is_file_like(value): + return value + + value = t.cast("t.Union[str, os.PathLike[str]]", value) + + try: + lazy = self.resolve_lazy_flag(value) + + if lazy: + lf = LazyFile( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + if ctx is not None: + ctx.call_on_close(lf.close_intelligently) + + return t.cast(t.IO[t.Any], lf) + + f, should_close = open_stream( + value, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + + # If a context is provided, we automatically close the file + # at the end of the context execution (or flush out). If a + # context does not exist, it's the caller's responsibility to + # properly close the file. This for instance happens when the + # type is used with prompts. + if ctx is not None: + if should_close: + ctx.call_on_close(safecall(f.close)) + else: + ctx.call_on_close(safecall(f.flush)) + + return f + except OSError as e: # noqa: B014 + self.fail(f"'{format_filename(value)}': {e.strerror}", param, ctx) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide file path completions. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + return [CompletionItem(incomplete, type="file")] + + +def _is_file_like(value: t.Any) -> "te.TypeGuard[t.IO[t.Any]]": + return hasattr(value, "read") or hasattr(value, "write") + + +class Path(ParamType): + """The ``Path`` type is similar to the :class:`File` type, but + returns the filename instead of an open file. Various checks can be + enabled to validate the type of file and permissions. + + :param exists: The file or directory needs to exist for the value to + be valid. If this is not set to ``True``, and the file does not + exist, then all further checks are silently skipped. + :param file_okay: Allow a file as a value. + :param dir_okay: Allow a directory as a value. + :param readable: if true, a readable check is performed. + :param writable: if true, a writable check is performed. + :param executable: if true, an executable check is performed. + :param resolve_path: Make the value absolute and resolve any + symlinks. A ``~`` is not expanded, as this is supposed to be + done by the shell only. + :param allow_dash: Allow a single dash as a value, which indicates + a standard stream (but does not open it). Use + :func:`~click.open_file` to handle opening this value. + :param path_type: Convert the incoming path value to this type. If + ``None``, keep Python's default, which is ``str``. Useful to + convert to :class:`pathlib.Path`. + + .. versionchanged:: 8.1 + Added the ``executable`` parameter. + + .. versionchanged:: 8.0 + Allow passing ``path_type=pathlib.Path``. + + .. versionchanged:: 6.0 + Added the ``allow_dash`` parameter. + """ + + envvar_list_splitter: t.ClassVar[str] = os.path.pathsep + + def __init__( + self, + exists: bool = False, + file_okay: bool = True, + dir_okay: bool = True, + writable: bool = False, + readable: bool = True, + resolve_path: bool = False, + allow_dash: bool = False, + path_type: t.Optional[t.Type[t.Any]] = None, + executable: bool = False, + ): + self.exists = exists + self.file_okay = file_okay + self.dir_okay = dir_okay + self.readable = readable + self.writable = writable + self.executable = executable + self.resolve_path = resolve_path + self.allow_dash = allow_dash + self.type = path_type + + if self.file_okay and not self.dir_okay: + self.name: str = _("file") + elif self.dir_okay and not self.file_okay: + self.name = _("directory") + else: + self.name = _("path") + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict.update( + exists=self.exists, + file_okay=self.file_okay, + dir_okay=self.dir_okay, + writable=self.writable, + readable=self.readable, + allow_dash=self.allow_dash, + ) + return info_dict + + def coerce_path_result( + self, value: "t.Union[str, os.PathLike[str]]" + ) -> "t.Union[str, bytes, os.PathLike[str]]": + if self.type is not None and not isinstance(value, self.type): + if self.type is str: + return os.fsdecode(value) + elif self.type is bytes: + return os.fsencode(value) + else: + return t.cast("os.PathLike[str]", self.type(value)) + + return value + + def convert( + self, + value: "t.Union[str, os.PathLike[str]]", + param: t.Optional["Parameter"], + ctx: t.Optional["Context"], + ) -> "t.Union[str, bytes, os.PathLike[str]]": + rv = value + + is_dash = self.file_okay and self.allow_dash and rv in (b"-", "-") + + if not is_dash: + if self.resolve_path: + # os.path.realpath doesn't resolve symlinks on Windows + # until Python 3.8. Use pathlib for now. + import pathlib + + rv = os.fsdecode(pathlib.Path(rv).resolve()) + + try: + st = os.stat(rv) + except OSError: + if not self.exists: + return self.coerce_path_result(rv) + self.fail( + _("{name} {filename!r} does not exist.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if not self.file_okay and stat.S_ISREG(st.st_mode): + self.fail( + _("{name} {filename!r} is a file.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + if not self.dir_okay and stat.S_ISDIR(st.st_mode): + self.fail( + _("{name} '{filename}' is a directory.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.readable and not os.access(rv, os.R_OK): + self.fail( + _("{name} {filename!r} is not readable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.writable and not os.access(rv, os.W_OK): + self.fail( + _("{name} {filename!r} is not writable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + if self.executable and not os.access(value, os.X_OK): + self.fail( + _("{name} {filename!r} is not executable.").format( + name=self.name.title(), filename=format_filename(value) + ), + param, + ctx, + ) + + return self.coerce_path_result(rv) + + def shell_complete( + self, ctx: "Context", param: "Parameter", incomplete: str + ) -> t.List["CompletionItem"]: + """Return a special completion marker that tells the completion + system to use the shell to provide path completions for only + directories or any paths. + + :param ctx: Invocation context for this command. + :param param: The parameter that is requesting completion. + :param incomplete: Value being completed. May be empty. + + .. versionadded:: 8.0 + """ + from click.shell_completion import CompletionItem + + type = "dir" if self.dir_okay and not self.file_okay else "file" + return [CompletionItem(incomplete, type=type)] + + +class Tuple(CompositeParamType): + """The default behavior of Click is to apply a type on a value directly. + This works well in most cases, except for when `nargs` is set to a fixed + count and different types should be used for different items. In this + case the :class:`Tuple` type can be used. This type can only be used + if `nargs` is set to a fixed number. + + For more information see :ref:`tuple-type`. + + This can be selected by using a Python tuple literal as a type. + + :param types: a list of types that should be used for the tuple items. + """ + + def __init__(self, types: t.Sequence[t.Union[t.Type[t.Any], ParamType]]) -> None: + self.types: t.Sequence[ParamType] = [convert_type(ty) for ty in types] + + def to_info_dict(self) -> t.Dict[str, t.Any]: + info_dict = super().to_info_dict() + info_dict["types"] = [t.to_info_dict() for t in self.types] + return info_dict + + @property + def name(self) -> str: # type: ignore + return f"<{' '.join(ty.name for ty in self.types)}>" + + @property + def arity(self) -> int: # type: ignore + return len(self.types) + + def convert( + self, value: t.Any, param: t.Optional["Parameter"], ctx: t.Optional["Context"] + ) -> t.Any: + len_type = len(self.types) + len_value = len(value) + + if len_value != len_type: + self.fail( + ngettext( + "{len_type} values are required, but {len_value} was given.", + "{len_type} values are required, but {len_value} were given.", + len_value, + ).format(len_type=len_type, len_value=len_value), + param=param, + ctx=ctx, + ) + + return tuple(ty(x, param, ctx) for ty, x in zip(self.types, value)) + + +def convert_type(ty: t.Optional[t.Any], default: t.Optional[t.Any] = None) -> ParamType: + """Find the most appropriate :class:`ParamType` for the given Python + type. If the type isn't provided, it can be inferred from a default + value. + """ + guessed_type = False + + if ty is None and default is not None: + if isinstance(default, (tuple, list)): + # If the default is empty, ty will remain None and will + # return STRING. + if default: + item = default[0] + + # A tuple of tuples needs to detect the inner types. + # Can't call convert recursively because that would + # incorrectly unwind the tuple to a single type. + if isinstance(item, (tuple, list)): + ty = tuple(map(type, item)) + else: + ty = type(item) + else: + ty = type(default) + + guessed_type = True + + if isinstance(ty, tuple): + return Tuple(ty) + + if isinstance(ty, ParamType): + return ty + + if ty is str or ty is None: + return STRING + + if ty is int: + return INT + + if ty is float: + return FLOAT + + if ty is bool: + return BOOL + + if guessed_type: + return STRING + + if __debug__: + try: + if issubclass(ty, ParamType): + raise AssertionError( + f"Attempted to use an uninstantiated parameter type ({ty})." + ) + except TypeError: + # ty is an instance (correct), so issubclass fails. + pass + + return FuncParamType(ty) + + +#: A dummy parameter type that just does nothing. From a user's +#: perspective this appears to just be the same as `STRING` but +#: internally no string conversion takes place if the input was bytes. +#: This is usually useful when working with file paths as they can +#: appear in bytes and unicode. +#: +#: For path related uses the :class:`Path` type is a better choice but +#: there are situations where an unprocessed type is useful which is why +#: it is is provided. +#: +#: .. versionadded:: 4.0 +UNPROCESSED = UnprocessedParamType() + +#: A unicode string parameter type which is the implicit default. This +#: can also be selected by using ``str`` as type. +STRING = StringParamType() + +#: An integer parameter. This can also be selected by using ``int`` as +#: type. +INT = IntParamType() + +#: A floating point value parameter. This can also be selected by using +#: ``float`` as type. +FLOAT = FloatParamType() + +#: A boolean parameter. This is the default for boolean flags. This can +#: also be selected by using ``bool`` as a type. +BOOL = BoolParamType() + +#: A UUID parameter. +UUID = UUIDParameterType() diff --git a/venv/lib/python3.12/site-packages/click/utils.py b/venv/lib/python3.12/site-packages/click/utils.py new file mode 100644 index 0000000..d536434 --- /dev/null +++ b/venv/lib/python3.12/site-packages/click/utils.py @@ -0,0 +1,624 @@ +import os +import re +import sys +import typing as t +from functools import update_wrapper +from types import ModuleType +from types import TracebackType + +from ._compat import _default_text_stderr +from ._compat import _default_text_stdout +from ._compat import _find_binary_writer +from ._compat import auto_wrap_for_ansi +from ._compat import binary_streams +from ._compat import open_stream +from ._compat import should_strip_ansi +from ._compat import strip_ansi +from ._compat import text_streams +from ._compat import WIN +from .globals import resolve_color_default + +if t.TYPE_CHECKING: + import typing_extensions as te + + P = te.ParamSpec("P") + +R = t.TypeVar("R") + + +def _posixify(name: str) -> str: + return "-".join(name.split()).lower() + + +def safecall(func: "t.Callable[P, R]") -> "t.Callable[P, t.Optional[R]]": + """Wraps a function so that it swallows exceptions.""" + + def wrapper(*args: "P.args", **kwargs: "P.kwargs") -> t.Optional[R]: + try: + return func(*args, **kwargs) + except Exception: + pass + return None + + return update_wrapper(wrapper, func) + + +def make_str(value: t.Any) -> str: + """Converts a value into a valid string.""" + if isinstance(value, bytes): + try: + return value.decode(sys.getfilesystemencoding()) + except UnicodeError: + return value.decode("utf-8", "replace") + return str(value) + + +def make_default_short_help(help: str, max_length: int = 45) -> str: + """Returns a condensed version of help string.""" + # Consider only the first paragraph. + paragraph_end = help.find("\n\n") + + if paragraph_end != -1: + help = help[:paragraph_end] + + # Collapse newlines, tabs, and spaces. + words = help.split() + + if not words: + return "" + + # The first paragraph started with a "no rewrap" marker, ignore it. + if words[0] == "\b": + words = words[1:] + + total_length = 0 + last_index = len(words) - 1 + + for i, word in enumerate(words): + total_length += len(word) + (i > 0) + + if total_length > max_length: # too long, truncate + break + + if word[-1] == ".": # sentence end, truncate without "..." + return " ".join(words[: i + 1]) + + if total_length == max_length and i != last_index: + break # not at sentence end, truncate with "..." + else: + return " ".join(words) # no truncation needed + + # Account for the length of the suffix. + total_length += len("...") + + # remove words until the length is short enough + while i > 0: + total_length -= len(words[i]) + (i > 0) + + if total_length <= max_length: + break + + i -= 1 + + return " ".join(words[:i]) + "..." + + +class LazyFile: + """A lazy file works like a regular file but it does not fully open + the file but it does perform some basic checks early to see if the + filename parameter does make sense. This is useful for safely opening + files for writing. + """ + + def __init__( + self, + filename: t.Union[str, "os.PathLike[str]"], + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + atomic: bool = False, + ): + self.name: str = os.fspath(filename) + self.mode = mode + self.encoding = encoding + self.errors = errors + self.atomic = atomic + self._f: t.Optional[t.IO[t.Any]] + self.should_close: bool + + if self.name == "-": + self._f, self.should_close = open_stream(filename, mode, encoding, errors) + else: + if "r" in mode: + # Open and close the file in case we're opening it for + # reading so that we can catch at least some errors in + # some cases early. + open(filename, mode).close() + self._f = None + self.should_close = True + + def __getattr__(self, name: str) -> t.Any: + return getattr(self.open(), name) + + def __repr__(self) -> str: + if self._f is not None: + return repr(self._f) + return f"" + + def open(self) -> t.IO[t.Any]: + """Opens the file if it's not yet open. This call might fail with + a :exc:`FileError`. Not handling this error will produce an error + that Click shows. + """ + if self._f is not None: + return self._f + try: + rv, self.should_close = open_stream( + self.name, self.mode, self.encoding, self.errors, atomic=self.atomic + ) + except OSError as e: # noqa: E402 + from .exceptions import FileError + + raise FileError(self.name, hint=e.strerror) from e + self._f = rv + return rv + + def close(self) -> None: + """Closes the underlying file, no matter what.""" + if self._f is not None: + self._f.close() + + def close_intelligently(self) -> None: + """This function only closes the file if it was opened by the lazy + file wrapper. For instance this will never close stdin. + """ + if self.should_close: + self.close() + + def __enter__(self) -> "LazyFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + self.close_intelligently() + + def __iter__(self) -> t.Iterator[t.AnyStr]: + self.open() + return iter(self._f) # type: ignore + + +class KeepOpenFile: + def __init__(self, file: t.IO[t.Any]) -> None: + self._file: t.IO[t.Any] = file + + def __getattr__(self, name: str) -> t.Any: + return getattr(self._file, name) + + def __enter__(self) -> "KeepOpenFile": + return self + + def __exit__( + self, + exc_type: t.Optional[t.Type[BaseException]], + exc_value: t.Optional[BaseException], + tb: t.Optional[TracebackType], + ) -> None: + pass + + def __repr__(self) -> str: + return repr(self._file) + + def __iter__(self) -> t.Iterator[t.AnyStr]: + return iter(self._file) + + +def echo( + message: t.Optional[t.Any] = None, + file: t.Optional[t.IO[t.Any]] = None, + nl: bool = True, + err: bool = False, + color: t.Optional[bool] = None, +) -> None: + """Print a message and newline to stdout or a file. This should be + used instead of :func:`print` because it provides better support + for different data, files, and environments. + + Compared to :func:`print`, this does the following: + + - Ensures that the output encoding is not misconfigured on Linux. + - Supports Unicode in the Windows console. + - Supports writing to binary outputs, and supports writing bytes + to text outputs. + - Supports colors and styles on Windows. + - Removes ANSI color and style codes if the output does not look + like an interactive terminal. + - Always flushes the output. + + :param message: The string or bytes to output. Other objects are + converted to strings. + :param file: The file to write to. Defaults to ``stdout``. + :param err: Write to ``stderr`` instead of ``stdout``. + :param nl: Print a newline after the message. Enabled by default. + :param color: Force showing or hiding colors and other styles. By + default Click will remove color if the output does not look like + an interactive terminal. + + .. versionchanged:: 6.0 + Support Unicode output on the Windows console. Click does not + modify ``sys.stdout``, so ``sys.stdout.write()`` and ``print()`` + will still not support Unicode. + + .. versionchanged:: 4.0 + Added the ``color`` parameter. + + .. versionadded:: 3.0 + Added the ``err`` parameter. + + .. versionchanged:: 2.0 + Support colors on Windows if colorama is installed. + """ + if file is None: + if err: + file = _default_text_stderr() + else: + file = _default_text_stdout() + + # There are no standard streams attached to write to. For example, + # pythonw on Windows. + if file is None: + return + + # Convert non bytes/text into the native string type. + if message is not None and not isinstance(message, (str, bytes, bytearray)): + out: t.Optional[t.Union[str, bytes]] = str(message) + else: + out = message + + if nl: + out = out or "" + if isinstance(out, str): + out += "\n" + else: + out += b"\n" + + if not out: + file.flush() + return + + # If there is a message and the value looks like bytes, we manually + # need to find the binary stream and write the message in there. + # This is done separately so that most stream types will work as you + # would expect. Eg: you can write to StringIO for other cases. + if isinstance(out, (bytes, bytearray)): + binary_file = _find_binary_writer(file) + + if binary_file is not None: + file.flush() + binary_file.write(out) + binary_file.flush() + return + + # ANSI style code support. For no message or bytes, nothing happens. + # When outputting to a file instead of a terminal, strip codes. + else: + color = resolve_color_default(color) + + if should_strip_ansi(file, color): + out = strip_ansi(out) + elif WIN: + if auto_wrap_for_ansi is not None: + file = auto_wrap_for_ansi(file) # type: ignore + elif not color: + out = strip_ansi(out) + + file.write(out) # type: ignore + file.flush() + + +def get_binary_stream(name: "te.Literal['stdin', 'stdout', 'stderr']") -> t.BinaryIO: + """Returns a system stream for byte processing. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + """ + opener = binary_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener() + + +def get_text_stream( + name: "te.Literal['stdin', 'stdout', 'stderr']", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", +) -> t.TextIO: + """Returns a system stream for text processing. This usually returns + a wrapped stream around a binary stream returned from + :func:`get_binary_stream` but it also can take shortcuts for already + correctly configured streams. + + :param name: the name of the stream to open. Valid names are ``'stdin'``, + ``'stdout'`` and ``'stderr'`` + :param encoding: overrides the detected default encoding. + :param errors: overrides the default error mode. + """ + opener = text_streams.get(name) + if opener is None: + raise TypeError(f"Unknown standard stream '{name}'") + return opener(encoding, errors) + + +def open_file( + filename: str, + mode: str = "r", + encoding: t.Optional[str] = None, + errors: t.Optional[str] = "strict", + lazy: bool = False, + atomic: bool = False, +) -> t.IO[t.Any]: + """Open a file, with extra behavior to handle ``'-'`` to indicate + a standard stream, lazy open on write, and atomic write. Similar to + the behavior of the :class:`~click.File` param type. + + If ``'-'`` is given to open ``stdout`` or ``stdin``, the stream is + wrapped so that using it in a context manager will not close it. + This makes it possible to use the function without accidentally + closing a standard stream: + + .. code-block:: python + + with open_file(filename) as f: + ... + + :param filename: The name of the file to open, or ``'-'`` for + ``stdin``/``stdout``. + :param mode: The mode in which to open the file. + :param encoding: The encoding to decode or encode a file opened in + text mode. + :param errors: The error handling mode. + :param lazy: Wait to open the file until it is accessed. For read + mode, the file is temporarily opened to raise access errors + early, then closed until it is read again. + :param atomic: Write to a temporary file and replace the given file + on close. + + .. versionadded:: 3.0 + """ + if lazy: + return t.cast( + t.IO[t.Any], LazyFile(filename, mode, encoding, errors, atomic=atomic) + ) + + f, should_close = open_stream(filename, mode, encoding, errors, atomic=atomic) + + if not should_close: + f = t.cast(t.IO[t.Any], KeepOpenFile(f)) + + return f + + +def format_filename( + filename: "t.Union[str, bytes, os.PathLike[str], os.PathLike[bytes]]", + shorten: bool = False, +) -> str: + """Format a filename as a string for display. Ensures the filename can be + displayed by replacing any invalid bytes or surrogate escapes in the name + with the replacement character ``�``. + + Invalid bytes or surrogate escapes will raise an error when written to a + stream with ``errors="strict". This will typically happen with ``stdout`` + when the locale is something like ``en_GB.UTF-8``. + + Many scenarios *are* safe to write surrogates though, due to PEP 538 and + PEP 540, including: + + - Writing to ``stderr``, which uses ``errors="backslashreplace"``. + - The system has ``LANG=C.UTF-8``, ``C``, or ``POSIX``. Python opens + stdout and stderr with ``errors="surrogateescape"``. + - None of ``LANG/LC_*`` are set. Python assumes ``LANG=C.UTF-8``. + - Python is started in UTF-8 mode with ``PYTHONUTF8=1`` or ``-X utf8``. + Python opens stdout and stderr with ``errors="surrogateescape"``. + + :param filename: formats a filename for UI display. This will also convert + the filename into unicode without failing. + :param shorten: this optionally shortens the filename to strip of the + path that leads up to it. + """ + if shorten: + filename = os.path.basename(filename) + else: + filename = os.fspath(filename) + + if isinstance(filename, bytes): + filename = filename.decode(sys.getfilesystemencoding(), "replace") + else: + filename = filename.encode("utf-8", "surrogateescape").decode( + "utf-8", "replace" + ) + + return filename + + +def get_app_dir(app_name: str, roaming: bool = True, force_posix: bool = False) -> str: + r"""Returns the config folder for the application. The default behavior + is to return whatever is most appropriate for the operating system. + + To give you an idea, for an app called ``"Foo Bar"``, something like + the following folders could be returned: + + Mac OS X: + ``~/Library/Application Support/Foo Bar`` + Mac OS X (POSIX): + ``~/.foo-bar`` + Unix: + ``~/.config/foo-bar`` + Unix (POSIX): + ``~/.foo-bar`` + Windows (roaming): + ``C:\Users\\AppData\Roaming\Foo Bar`` + Windows (not roaming): + ``C:\Users\\AppData\Local\Foo Bar`` + + .. versionadded:: 2.0 + + :param app_name: the application name. This should be properly capitalized + and can contain whitespace. + :param roaming: controls if the folder should be roaming or not on Windows. + Has no effect otherwise. + :param force_posix: if this is set to `True` then on any POSIX system the + folder will be stored in the home folder with a leading + dot instead of the XDG config home or darwin's + application support folder. + """ + if WIN: + key = "APPDATA" if roaming else "LOCALAPPDATA" + folder = os.environ.get(key) + if folder is None: + folder = os.path.expanduser("~") + return os.path.join(folder, app_name) + if force_posix: + return os.path.join(os.path.expanduser(f"~/.{_posixify(app_name)}")) + if sys.platform == "darwin": + return os.path.join( + os.path.expanduser("~/Library/Application Support"), app_name + ) + return os.path.join( + os.environ.get("XDG_CONFIG_HOME", os.path.expanduser("~/.config")), + _posixify(app_name), + ) + + +class PacifyFlushWrapper: + """This wrapper is used to catch and suppress BrokenPipeErrors resulting + from ``.flush()`` being called on broken pipe during the shutdown/final-GC + of the Python interpreter. Notably ``.flush()`` is always called on + ``sys.stdout`` and ``sys.stderr``. So as to have minimal impact on any + other cleanup code, and the case where the underlying file is not a broken + pipe, all calls and attributes are proxied. + """ + + def __init__(self, wrapped: t.IO[t.Any]) -> None: + self.wrapped = wrapped + + def flush(self) -> None: + try: + self.wrapped.flush() + except OSError as e: + import errno + + if e.errno != errno.EPIPE: + raise + + def __getattr__(self, attr: str) -> t.Any: + return getattr(self.wrapped, attr) + + +def _detect_program_name( + path: t.Optional[str] = None, _main: t.Optional[ModuleType] = None +) -> str: + """Determine the command used to run the program, for use in help + text. If a file or entry point was executed, the file name is + returned. If ``python -m`` was used to execute a module or package, + ``python -m name`` is returned. + + This doesn't try to be too precise, the goal is to give a concise + name for help text. Files are only shown as their name without the + path. ``python`` is only shown for modules, and the full path to + ``sys.executable`` is not shown. + + :param path: The Python file being executed. Python puts this in + ``sys.argv[0]``, which is used by default. + :param _main: The ``__main__`` module. This should only be passed + during internal testing. + + .. versionadded:: 8.0 + Based on command args detection in the Werkzeug reloader. + + :meta private: + """ + if _main is None: + _main = sys.modules["__main__"] + + if not path: + path = sys.argv[0] + + # The value of __package__ indicates how Python was called. It may + # not exist if a setuptools script is installed as an egg. It may be + # set incorrectly for entry points created with pip on Windows. + # It is set to "" inside a Shiv or PEX zipapp. + if getattr(_main, "__package__", None) in {None, ""} or ( + os.name == "nt" + and _main.__package__ == "" + and not os.path.exists(path) + and os.path.exists(f"{path}.exe") + ): + # Executed a file, like "python app.py". + return os.path.basename(path) + + # Executed a module, like "python -m example". + # Rewritten by Python from "-m script" to "/path/to/script.py". + # Need to look at main module to determine how it was executed. + py_module = t.cast(str, _main.__package__) + name = os.path.splitext(os.path.basename(path))[0] + + # A submodule like "example.cli". + if name != "__main__": + py_module = f"{py_module}.{name}" + + return f"python -m {py_module.lstrip('.')}" + + +def _expand_args( + args: t.Iterable[str], + *, + user: bool = True, + env: bool = True, + glob_recursive: bool = True, +) -> t.List[str]: + """Simulate Unix shell expansion with Python functions. + + See :func:`glob.glob`, :func:`os.path.expanduser`, and + :func:`os.path.expandvars`. + + This is intended for use on Windows, where the shell does not do any + expansion. It may not exactly match what a Unix shell would do. + + :param args: List of command line arguments to expand. + :param user: Expand user home directory. + :param env: Expand environment variables. + :param glob_recursive: ``**`` matches directories recursively. + + .. versionchanged:: 8.1 + Invalid glob patterns are treated as empty expansions rather + than raising an error. + + .. versionadded:: 8.0 + + :meta private: + """ + from glob import glob + + out = [] + + for arg in args: + if user: + arg = os.path.expanduser(arg) + + if env: + arg = os.path.expandvars(arg) + + try: + matches = glob(arg, recursive=glob_recursive) + except re.error: + matches = [] + + if not matches: + out.append(arg) + else: + out.extend(matches) + + return out diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..9d227a0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2010 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA new file mode 100644 index 0000000..c49ceb9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/METADATA @@ -0,0 +1,81 @@ +Metadata-Version: 2.3 +Name: Flask +Version: 3.1.0 +Summary: A simple framework for building complex web applications. +Maintainer-email: Pallets +Requires-Python: >=3.9 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Framework :: Flask +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI +Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application +Classifier: Topic :: Software Development :: Libraries :: Application Frameworks +Classifier: Typing :: Typed +Requires-Dist: Werkzeug>=3.1 +Requires-Dist: Jinja2>=3.1.2 +Requires-Dist: itsdangerous>=2.2 +Requires-Dist: click>=8.1.3 +Requires-Dist: blinker>=1.9 +Requires-Dist: importlib-metadata>=3.6; python_version < '3.10' +Requires-Dist: asgiref>=3.2 ; extra == "async" +Requires-Dist: python-dotenv ; extra == "dotenv" +Project-URL: Changes, https://flask.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://flask.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/flask/ +Provides-Extra: async +Provides-Extra: dotenv + +# Flask + +Flask is a lightweight [WSGI][] web application framework. It is designed +to make getting started quick and easy, with the ability to scale up to +complex applications. It began as a simple wrapper around [Werkzeug][] +and [Jinja][], and has become one of the most popular Python web +application frameworks. + +Flask offers suggestions, but doesn't enforce any dependencies or +project layout. It is up to the developer to choose the tools and +libraries they want to use. There are many extensions provided by the +community that make adding new functionality easy. + +[WSGI]: https://wsgi.readthedocs.io/ +[Werkzeug]: https://werkzeug.palletsprojects.com/ +[Jinja]: https://jinja.palletsprojects.com/ + + +## A Simple Example + +```python +# save this as app.py +from flask import Flask + +app = Flask(__name__) + +@app.route("/") +def hello(): + return "Hello, World!" +``` + +``` +$ flask run + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) +``` + + +## Donate + +The Pallets organization develops and supports Flask and the libraries +it uses. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD new file mode 100644 index 0000000..39b269d --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/RECORD @@ -0,0 +1,58 @@ +../../../bin/flask,sha256=VErsPu9UYgelfVNgchpa7ESsZyT8-PmYB-RKgUcGJus,255 +flask-3.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +flask-3.1.0.dist-info/LICENSE.txt,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475 +flask-3.1.0.dist-info/METADATA,sha256=Wvf66xwUclGRu89cNcvErpaMf1rMgcxeqIkTc4EmD90,2718 +flask-3.1.0.dist-info/RECORD,, +flask-3.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask-3.1.0.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82 +flask-3.1.0.dist-info/entry_points.txt,sha256=bBP7hTOS5fz9zLtC7sPofBZAlMkEvBxu7KqS6l5lvc4,40 +flask/__init__.py,sha256=6xMqdVA0FIQ2U1KVaGX3lzNCdXPzoHPaa0hvQCNcfSk,2625 +flask/__main__.py,sha256=bYt9eEaoRQWdejEHFD8REx9jxVEdZptECFsV7F49Ink,30 +flask/__pycache__/__init__.cpython-312.pyc,, +flask/__pycache__/__main__.cpython-312.pyc,, +flask/__pycache__/app.cpython-312.pyc,, +flask/__pycache__/blueprints.cpython-312.pyc,, +flask/__pycache__/cli.cpython-312.pyc,, +flask/__pycache__/config.cpython-312.pyc,, +flask/__pycache__/ctx.cpython-312.pyc,, +flask/__pycache__/debughelpers.cpython-312.pyc,, +flask/__pycache__/globals.cpython-312.pyc,, +flask/__pycache__/helpers.cpython-312.pyc,, +flask/__pycache__/logging.cpython-312.pyc,, +flask/__pycache__/sessions.cpython-312.pyc,, +flask/__pycache__/signals.cpython-312.pyc,, +flask/__pycache__/templating.cpython-312.pyc,, +flask/__pycache__/testing.cpython-312.pyc,, +flask/__pycache__/typing.cpython-312.pyc,, +flask/__pycache__/views.cpython-312.pyc,, +flask/__pycache__/wrappers.cpython-312.pyc,, +flask/app.py,sha256=GE7QOE_N9THDjuzKx0gUI9aF4hLh0xwBDa7hLVsjy-o,61725 +flask/blueprints.py,sha256=p5QE2lY18GItbdr_RKRpZ8Do17g0PvQGIgZkSUDhX2k,4541 +flask/cli.py,sha256=XdmkBD74SnT0jrt2gqyHrE9oXGdWlcdTrJQR-i5aApY,37093 +flask/config.py,sha256=PiqF0DPam6HW0FH4CH1hpXTBe30NSzjPEOwrz1b6kt0,13219 +flask/ctx.py,sha256=4atDhJJ_cpV1VMq4qsfU4E_61M1oN93jlS2H9gjrl58,15120 +flask/debughelpers.py,sha256=PGIDhStW_efRjpaa3zHIpo-htStJOR41Ip3OJWPYBwo,6080 +flask/globals.py,sha256=XdQZmStBmPIs8t93tjx6pO7Bm3gobAaONWkFcUHaGas,1713 +flask/helpers.py,sha256=7njmzkFJvrPSQudsgONsgQzaGrGppeBINevKgWescPk,23521 +flask/json/__init__.py,sha256=hLNR898paqoefdeAhraa5wyJy-bmRB2k2dV4EgVy2Z8,5602 +flask/json/__pycache__/__init__.cpython-312.pyc,, +flask/json/__pycache__/provider.cpython-312.pyc,, +flask/json/__pycache__/tag.cpython-312.pyc,, +flask/json/provider.py,sha256=5imEzY5HjV2HoUVrQbJLqXCzMNpZXfD0Y1XqdLV2XBA,7672 +flask/json/tag.py,sha256=DhaNwuIOhdt2R74oOC9Y4Z8ZprxFYiRb5dUP5byyINw,9281 +flask/logging.py,sha256=8sM3WMTubi1cBb2c_lPkWpN0J8dMAqrgKRYLLi1dCVI,2377 +flask/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +flask/sansio/README.md,sha256=-0X1tECnilmz1cogx-YhNw5d7guK7GKrq_DEV2OzlU0,228 +flask/sansio/__pycache__/app.cpython-312.pyc,, +flask/sansio/__pycache__/blueprints.cpython-312.pyc,, +flask/sansio/__pycache__/scaffold.cpython-312.pyc,, +flask/sansio/app.py,sha256=Wj9NVGtiR1jvkZ9gSFd91usUlM8H0g06aPVz2sMh4bw,38116 +flask/sansio/blueprints.py,sha256=Tqe-7EkZ-tbWchm8iDoCfD848f0_3nLv6NNjeIPvHwM,24637 +flask/sansio/scaffold.py,sha256=q6wM4Y4aYMGGN_Litsj3PYKpBS3Zvut0xhDmpBEHFdo,30387 +flask/sessions.py,sha256=pImSFQIDCPtV-XSI8ttAyTTbvtRMkhDeqJ8VPZZUaf0,15430 +flask/signals.py,sha256=V7lMUww7CqgJ2ThUBn1PiatZtQanOyt7OZpu2GZI-34,750 +flask/templating.py,sha256=2TcXLT85Asflm2W9WOSFxKCmYn5e49w_Jkg9-NaaJWo,7537 +flask/testing.py,sha256=5Dxg6VZ0ZPhjwG9ReUl4TrhvkjBYvgIzV949jkY0jIU,10100 +flask/typing.py,sha256=b7mMBIeAoOcAI_vFzzhfOm7KeZ_n868SIMw6xpX5KYQ,3166 +flask/views.py,sha256=xzJx6oJqGElThtEghZN7ZQGMw5TDFyuRxUkecwRuAoA,6962 +flask/wrappers.py,sha256=jUkv4mVek2Iq4hwxd4RvqrIMb69Bv0PElDgWLmd5ORo,9406 diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/REQUESTED new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL new file mode 100644 index 0000000..e3c6fee --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.10.1 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt new file mode 100644 index 0000000..eec6733 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask-3.1.0.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +flask=flask.cli:main + diff --git a/venv/lib/python3.12/site-packages/flask/__init__.py b/venv/lib/python3.12/site-packages/flask/__init__.py new file mode 100644 index 0000000..e86eb43 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/__init__.py @@ -0,0 +1,60 @@ +from __future__ import annotations + +import typing as t + +from . import json as json +from .app import Flask as Flask +from .blueprints import Blueprint as Blueprint +from .config import Config as Config +from .ctx import after_this_request as after_this_request +from .ctx import copy_current_request_context as copy_current_request_context +from .ctx import has_app_context as has_app_context +from .ctx import has_request_context as has_request_context +from .globals import current_app as current_app +from .globals import g as g +from .globals import request as request +from .globals import session as session +from .helpers import abort as abort +from .helpers import flash as flash +from .helpers import get_flashed_messages as get_flashed_messages +from .helpers import get_template_attribute as get_template_attribute +from .helpers import make_response as make_response +from .helpers import redirect as redirect +from .helpers import send_file as send_file +from .helpers import send_from_directory as send_from_directory +from .helpers import stream_with_context as stream_with_context +from .helpers import url_for as url_for +from .json import jsonify as jsonify +from .signals import appcontext_popped as appcontext_popped +from .signals import appcontext_pushed as appcontext_pushed +from .signals import appcontext_tearing_down as appcontext_tearing_down +from .signals import before_render_template as before_render_template +from .signals import got_request_exception as got_request_exception +from .signals import message_flashed as message_flashed +from .signals import request_finished as request_finished +from .signals import request_started as request_started +from .signals import request_tearing_down as request_tearing_down +from .signals import template_rendered as template_rendered +from .templating import render_template as render_template +from .templating import render_template_string as render_template_string +from .templating import stream_template as stream_template +from .templating import stream_template_string as stream_template_string +from .wrappers import Request as Request +from .wrappers import Response as Response + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.1. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") + + raise AttributeError(name) diff --git a/venv/lib/python3.12/site-packages/flask/__main__.py b/venv/lib/python3.12/site-packages/flask/__main__.py new file mode 100644 index 0000000..4e28416 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/__main__.py @@ -0,0 +1,3 @@ +from .cli import main + +main() diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bab03dee8eba419a641a2a3b6fab8620da954566 GIT binary patch literal 2489 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/blueprints.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/blueprints.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31d741e57b159e3d77c7483c965dea672c3ff092 GIT binary patch literal 5009 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%0DqR~b?EpoTXXuhf;G1p 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 OtGgfu6G|8?|9=6mfm;&* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/config.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/config.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06e7708bb8e7aa2a1fabda9a14fdddce182d4b38 GIT binary patch literal 16218 zcmd5@Yiu0Xb)MPX*$3ZmQ4dO^hea-JE-l;jgO+4b6eUZRNJXTbh>E;B+!>NfEqCde zSy7~yiIb@HDo|=FP9r+DVHqtN8#Yk4C|VaS(8>*v7X1;bQX+cn0&0`|$iGdbz^U`6 z-??{Yc9x`KH$Z_7!P%MnIQQIh&pppO|5jaHA>jI(n@7k0^g%)RDZMyXkUxmGEj(Nn zR6!Nf!jw27iuCMD`$l~1*FWNCzk!he`;|r{_8S}t;n$xIPen!|qM(H)n;g)kU%i60 ztsJRR1FDp+o~jwC5d|N$-dt+sJgLEVME*Qd=MxSIYUsS6hS7GL)1vgN)vd?NJAS); z18W~a`wFemEp3|hMJseSS9RyX5@si!jIzo3y(>hGPN zw#4Bihs*EwAmZ)wc)u)Y!icB}AdfiWj{w1l;QXl()qh?Z324$}l@|biRx8xN`M^7N z#YpHbttwT?+e!_qRca7WLuxe$5*P_%QZ-g>Up6zA8t*lM{bbC-hmL9VLRIOJ7fI&mavizyiJ&~Q#x-<9d>a5m% zAe+ohX&KY#MrWgYde)rCX5vOt*EIZ0D7w~tR?D32PNzog$_Hb+9_Thwrq(sBB+n@0 zn$bO$R*W+Q0Az?w&k|axOv;SM=UV&9X%lm5))7jLxV<10gTnf@Lf~Tca$9F1@Z<1? z+b9;wNJ9mTGyyzZ#`N_{JiINu?bmDYVEMD7la`d7$!NMWPrZ&RLh(2eCO)@rH6pB{ z4Xq3bw--dA3EVUqY|#YG!&-j6z>(~9eB^(d#|S6q3&v(?elKg3B31`6`^)M@)L4vGdC zvGo=zp!KtS`dNcU0$a(Sg8TA_I z3%*;GwKprM;-$A;E0Uf0C{cni28+~k! ziu&}8cw=*pa^7OowWPC3I;WK_Hu08mH{N0uF@Q3NQ!w8h(SrY_iVGDB4_)4KY0tlh zx3WnvHjW1MS~Rl!5Pyu&b8Tj61?-hBt>!7)2wDs#ZljK9yB-X%bph@%VE&C2fl^&{NGO<8i$n z%`MTi!dXbObXHN>zS6g#m~TAVrJUa)^h7rzvvCr)^TLOL2Ov@oi^s&GKOo(^+_aAW zcJ#B~TaoJ963UBJLNN5=$k#@!z@FQFAy~H@*mFw?@{-5xlE?1^B2vSh7E$Wt3r1rl z@$X*tP7`nc7m8j4^R3WHRgOl2eyT1AW1{LiUkwFbqt-GFC84}d3r><8TXCs@*F;b6 zdT6822y~oU<0)-m8Y!YSGL2M0HEL6--g#1+)i5+yC2GAGwWtx4qC{QiwB)~Pt6G7Y zYIVI@2~Ag15YCAswL?O5gB9eWRQV9>^u?@x#*nphO43Zv%IVY@O;%(zl{95&LU~%x zo=vGxg)_>mL8@;ol}^hkQy$Z^Q}m)46(l>dx@=5q$&`|2ePI?TdP*~5vOGMY=>Um; zb0!O|IW?8d$kR}(nx0`0r?b^l`=gYv!M~b@#$H@xT77=bh|t`Hr^iPJqC4INfTNyYtCvQhBK(DjioXS zKYO5@&MY4}JIxFrIhApd=Q{(hiV1|%X+!Rr(#(mT1VaEyPD`2zB9~2BvN5>rL`0bY ziP^Lj*$c>+$mY_jJgUjGmoyb*J#5M;7$|8YD^F()BLzXjEEA0{j}0bgaI_8B5Dr8o zqslX&D#y`5qeN3@a$H_AY$kIC*g=B@WK#hX^V0c1|Nf^B$$R8sJ;#@jh(FZdccOnd z{#5@-)U>M_NSd7{Lq$HL&9*bRYpoF{QHNs|*=ut+Badc*b5b$Dj2%P<*qQe7XJ+N& z%<5qbK*TMp=ae*}_pvdv8LVt>dRo&77U2Ri5{IfFY`JmAxEEBOV#Xkt-b-namcdJB zXKYZMU^X*&S&~dgh*`3b6@6B=+c6fQkzq*l(HXol^OEL*f>jL2(dKL?v&ALG<|_(r zN^8s@c%iEqIeSl(0ytgjg+krkVrh9xSNbG$)J$F{zb zVbEb%ru1xvE$dlqc~W>F6MzvMz)(JOQvw8fcC?=yeELN1@#9Ai_w^1R9vp}d^$!mp z9ym1QY)`O&If3EXvf0d-R&tr-1RJV+nr!b*C}-KGfGTHQ?~buebVfwl^)m|C6opu1 zFu`C(KAOtp&S9^r^5BsCB?idZTiQADd}IUO5F@*HW7u_fo7$fCZrb$SX4W>ny9tAK zTO4JuO*3kC#vnB01ZI)IDjBAxsP-!MOe?xFCF|L&87DwJjtr4!CQ``>MtaWOIy%X^ z2007S##RvX`r?FE5?r(w%P%e=WxgS4;o(wXj*vr~Z9H6cA77djR|e%^=#99{)4Uy0 zksPa@#8;T(5j#lkN6ei^BE~3ePY>L$KT(6p$m9t~CL#U0tw^;8oCxCRk zpFFc3Jp74xSukBqeF4_?w_sK0edk2OCkiRy9otJ2xd-QSnmQ(?-;#_R1PC{CA}-pF zdEJE$R@gz?ip1kd%+G+aNoar^FL2X`tfV>H_jKK=XHjU7PxG4>ggX^Nq~=2CTDWzw z^?RGIoVXG0SYE%a5cpQjY6F`50ye`x#)Ef$Yk3)KdJ&>CZ}K9HhP+P~XGN3jN_MF* z$zS!U{?}b^zapnDa-@Ac#Y`VeXkd*%hNsmIDfE&vtiX%8cGQm`2^<1REp$a9exGWaH>(jM-v^pt@o z44J^3Q9v+em&isgnFKM%a-e^y`@y;O!*`jEJa?8P3#mYw0SQ<@0~n}!7I$#0ktDN# zsGY|O8nOjDw!N)-2mq;TGEtct;yS1t7GaI(RFKmpDp|g)VTEjJTYf|ptf~_^sIV!m zpBTid^jMGfCbz1cG1E7K%!M~>!xBAxGeyOphC`i>c zaE0ocZq{zOR=eej@2!WIYPVdkePAj40Fx7#t3(TABpp#k0?ri}BY2}=#jA)~zV4eB zO45TS?37F?MmP*PLWngp3U@jC0h756AKjm23wyc2l+C!uDBn${> zO(m~L)pSn}5*m(TUxgoekU);Rkctiq$+oK@KR{=9Sd^wz`N+`V07LISm{7@dj?I<4 zTxzUB-W#SD*CFy{X+{W=PQmES$QhW%AQH+XFqmX?co7Hl!q zY>v$0Tn5uKlAstom_#Cu#f`?~!(+gJTi;Wfnj%LSJzezGtY&1|O*rU45y%sNz{SJp z6rY8^otoor3xE(kW*LeeBHDU_^GlD+_z4WUXwKiBAqh@UnpWQHk`|Gv=EM0MPt%Mtj(1VhGq*)`hiNhNatlX z6|uRPK3`#m>Pm`u9i)S%NsVW)0JIf}`)#Jd5K{_FYwQD#VvNET?sNzdhYtb5=GsXk zn~AY0!d!LR#$qxyia`MoawvOx!iw~tOKL3E0Lv4uoQY5zi<$>{1N|}T?+4%L6uGlP$(*jkEU+YSrfFCK z6RO_|uotq|XhQ5_cBoa))fapI8p!Ds+zB$yKxOSMExHUnl~;yy0~j$Qz7`X z#`Ujld!zG}&Yv{iQ|Mc6Y`MJm(%vgOZ!|`i>so)-)N=XAr6Y^RrNKh~azpdYhHcjx zwq1GndP8TSuNVkaH-FgLwy3>YwICHMpvV>z9TbsGzZmN#yG zo%tp2gy97g=fx~rD5b<|$BiEPErj&zW7qsbVXmFpt zFE34Qa7s(Rrdu{irq_zgQ%k#I#pS7$S5)D3%zswUrIVQ1yz~`mHmHVx!M4@yU^9hZ z_vfX!OW&{CeP%@00;o`ivAj=Ds}Sy7c-gAT4&d0LjP@ENkSCPoxHXQ5bmhpXMzIaZ zD+o01E4Y?84AA>;uyebw6_Rwu@W?V-j1y>bOL~~Vblw~%g(L4^N}5sQ zAzP>@J4ob6o3dYJ)X1ihYh^wJ_j(Y2ExozH3LcwraW4ZxFXVo+xW_8}^Z(g5a_6&J zVcZ{k#I42r5_}p7%n`vJ4N=YS zH^sQ6!xE#z(MG0$NI5|51SS!>(^>pNV#b_Rag6cMFf2Pt3R6d>n8H9~j2(;h_VEPgo(m57R>!I+rPK+gaiP zC*-o2iVHgo$6PE+RIN(Rats$s)C>}V#0X9XlQM|qt`?8`|2@i$AK?a9YnuR-^vI=0 zF7Ljy`%2*ZHE-6u7rx&3SRwpzRsGGXP1mY6Eq>{G)y{&r+}u_WFIE(Np-98W_00wd5G{fDnN@BgRXA0D}SID-~Oz&A&v(+oOMZ z^auC+u#rT-xebP@Tox) zz8bFHf3I-0`TqS|{2xeRJb$o7+TRiSU`L3a?~NR&_kZxvo�>e}1?H_a9VAC~+M^ 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/debughelpers.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/debughelpers.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..21cd2f2806cb197de60128f2ae5b42224c7a4921 GIT binary patch literal 9141 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 Cgwc=y literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/globals.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/globals.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f52156c24dbe6b768b37431e35848776acddaf0c GIT binary patch literal 1874 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/logging.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f29de62480ae83440b19c68648fa677eb7e4f45 GIT binary patch literal 3279 zcmZuz&2JmW6`xsBB*jllvQ*er?LjMBqHB|B1LwdBPFq`&ji`z*Z5!?ID#D1aMD93!^|!MgNChq{xMYO#-+`0yIDmg5?5fPJM5dE6SDz z*qygC?|bI`-u@$%iW3-r+n%jm>nG$h{0K&$Ptd*p0I^OCVo-}TXpvH+HA^dMY7P}c zY7Q6sU=CT4Mzk0Op0Lqp#Txy^eoA=X!tp?DZx#{YiCBq7vX}&(sF5(Dcfyal48@d@ zG-7wc#k5Aaws5K^7f?L)i28K#7(ce~onXB;E6K6mcR(5afn+d)zbPXQ)`r?zHvJ_s zW~rCZZQF5m*K}-o9lqnUPDQtF2xqzdC7On%sNlb9ap?jX`cbo42~6Ou!4o2c?#%(Q zPF!45Lk#uk1>|~R81w|J+$3%|*jR`JRBygXvYP%L_%UtT26OA2H5}&6ggFigqxifi8D=b7cynCq}|c}dpHoYE!B z<@3w|En>-(oVDO7mt|Y#q-y{}xtxnDEugmTv{=Qlt7fewIDQG{EZMA3v2-a5Wl&x- z?ON`pa_*{b8x|L!9K{-Xn=R?K3)Yo3G~?F6vmgXNBIP~u>tLWIK^v=@7H1HrVOHFI z>ncAzZjZanY&0DK22iVE3SM!owr?EvAt6-`$#R$p`IJhmT;|JeA)l{;`-{22 zd(2G9&rHd83R8f2TuB_rS~e{30KF);Z<)fey%6Ngi}*?VGugvK{dzuMcN#ozza)${ z&tGvWtp>MUnTI6Ge6#J=9lInef^(Sa5OV$&XvX82)C$Y>YnUVW%uf6@?_Gae7M(o1piS+%#T45tREKDC>Pgy0=jxBQPl+||~}Dp@$Vk32Afy8ex}N^a9tDkfc!^2a@`N)37^wn`WFZ+x&v z$d!HBM_s*wwl&~Aq9&x)Pud~ai}mCKN?E1vPPRkY@X805>%6ka%qo@yTpzsltnS}J zX4Kc~g$8%)g)*;J;ZngCv-mA;vB|fB zW0+N(xf*w;0-jl9xzxQm&t(^L^fF?|BoOb>*9Zk9StV}{5tYS-Ah-kbnzne7kl)jF zO3Ay!VbUgl2`$kqMFi_p&SXQLmV3#IcHK`4%v;7)X;WvY%@8wl|0*-+DRYp%={}p@JS-Qm7f0V8`~GBKDsysYBhc`@~V<<4Ut;Y{K}7uO5A z>xx1dl;`}OP*UuZKF%x4Ib6Z&j3cnWQHN^pO1*WE%i!~^S{adq+xoo4jq^-)1L!)U zE<(`M3Wo0Ly*_wl>c>Bw0qLp=Ml$&EK=EEb1;>4yvYmaP3i_e1AF}fT>YQh~VK80! z9W>s39D2U%}0#S;RiCPsOjw)Qf}DSA8hXQ>Qjlryj_M%kM95r6xMlPonX=?RVM_ zMjnoSFuD^<-_NXNK8!w0y`Op3_R+3=_M`}S9q%ie;@$C0_)z3)+}cp@Yw&yNX`A?##HI@ z)v3#`UAsQx#iedb)5&4dlu;~CKhLS>Zh$z8x{`1r)9NT)F1-GIQYBPi;j7^NoW~}8 zB)cSDfepkcDdDvnqLhA0zWo_Ve@x;Zlff^@nJ>ublTi5XtM9z}Y54SRglNg9T9S_J zg@D>s)Tv{1VD}sun)vPb_Tc#D;P}QwVQcUQoy-o&Y?IMVGP)BU?#yh5hd0B+8za}Z S!mmFIX;ga_AEtxKss96OI#K8V literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/sessions.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33758acea7e6c84df140a5714475de2cab3cb619 GIT binary patch literal 17142 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 VKWbJ*@u}6`fuG=$SCQ}g{{U2dX$=4X literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/signals.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/signals.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8189d3aaf31c4f03c9b6d97ecb599528f6841cd8 GIT binary patch literal 1231 zcmZ{jO>fgM7=WF&bX~hH`{>qffCd8ziqr)dUlOqKu_M~LT%?ulfS~l zD=9puW9%@UnGU96IKHLZh`M?Wb*34zT}x-EOb|8@K}Ki3is}xLfwBZTDnV~rh_W(e zI$;8wl7YI3P1+QZf{ZYv6B9SehVvG8<{AzY=?9C^UJbe7Mmj~^b!!f0Xpe~^BmDHp zgxl&TJ`-|WSJYC40@WL+T(|U)*(y!(EQIwIYY_w?2`?fat6C=BL4>5jQ3g`8fpv@W z^q|8deJJ($P=6SJQlCqGIMnA-A4+{L^~IvT4h;2qs4ueh^GpdP`rkdMkO$S3-BM6CCQzuBks|HBM(dmi&u}950|~tbAR!L2j+vBrJmN+yp=V7 z=H7uC%wFtmbT_%f0>XzIWrPUtISArIjP? aQ1foR^p`e0Pz=tOJ3k&R_g*ChvF-mhR#c_{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/templating.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bd808d254eeebd5d8d693c8457de4026b3480f5 GIT binary patch literal 9916 zcmdT~TWlLwdOmX@IlPIwQCC|U%Ze?=wq)74*s(WW`66H9$Z7044IP&naYhnlid4>w zBuk+RB^zv{u3IZzbR|Euae)@K;V$ZjqDX;0G(aB~XwiyM)?^1Z;9{{r_f4skHuY2g z|I7?YX{p#*6zJ~QJm;Tt`OleizW;WP{wWyr5qSPKcYf&I?S%XcU!2Ef5!{-}5wb{B zqH;+x%0)R2X+FtE1;~Y@IO>YJSeXd4JL+My3uq}SG1?8ZH|ho2qe@BNs6Xmwv=`_= zG{9&d(7|Ys(SD#Sq7{q|BtxT>(Mm=KlU1YD(P~Cl09_NU;fN-TbU0Hk=Cm5d3MIp% zbRUB?}K;WaYfh8rxjJBSbHipk)Y|+sFpI|Rl1~&jwKaC1G>_o`_e{l zdOW560`?9$dSda3m@+no-I1i)yW^UU-Tm=#N`aGI>nYaM=myo4(b#0d7>>o$DMP!C z9qI0 zbh+PN^!~j*8J>O}8o=K7%SuX>`-l2FS#h7q4bcFMWqRxe5jXYXyD+2~6emS%F~K%8 z3`s;V-LUC#G(K8O7DWH>Rn?~#&9|n z)8karARAVw)-|D}Cc2V|0lV^GXZL|FJz;43#+3LqWk}Pz263~y?2k^QhC0Wl%+{D{ zEk*$=F_=lLun@Ev=Fk|YhyH#GUQ1% zjGmT_Va1RWh8$N?032-$L=MU{#wVo!Z(srMC0&g)%xh2s;f!n0))r1(P7KN^4S}c7 zDGN^VQpv*4^P~JF*)phHhM(YQ4M;*k5~0F=?%6qDoEL{h?H!ljN)<->%I{-FNCgm%8&cb#vk$NOT+Y?E`tl(PxHbwe(x0o4P!cS?!`&AO8beM~Xp!=MS6lvp-w`kfxx+EfeR$#fc| z3XDoAUQ-O%u(8QRoLNGq43(rML>obm=0u}<8C>I61KPN?YWCF(eT5~NB6m43uWZjE zJZ*;xM(fy1mP;_xTK+={@Hq?}bX3IvpAtaCVd%mm0>!410b-GW87fp2iSkCQ5gO2H z=z+Vs>48t;@7bGs5xIIcHGtQRZBXPIPW{ds=X=if#V(zC9f(V(V&^aPoIKliIwGW?!~u-<@lp9$Kk6 zxg0o|57p#C?b%TK?JM^?RzgRXr6WuxHtYtv0Bkqhpx_qC5SbBFG9$wJl~H)G!glFN za&C zRBd2#>CM zMJS)%y9Irwd~Kf?7!depyieMzPa9o-c{Ze zY|4k5bKzat@UGkM-9NJu{>}mq0={r0-?VMv1i&#EzIkE(!qVm2m+!o}ylwwa1Kq13 z(t6~pYT`Y~{ks&o)Be{TcRTK%`E>XT>GWfN#oRH}59c0Mv@Bg;spwdiI=)^HliK$G zBpi;__(%Mz0Mrv5O~{|r^&H?oJK#S~T%R4|Al-mq)CCN|3qUY^@-*baQZnQUGa?{Y zd>V4&JV!1P@!9Ysa0IY)z`+vjhDm`=K;bPS1N^9VEGX{0Cswl8I(`z{UTb$>g4gNY z&#=3wfUZDe{W2tMW99Z-Yj?J_`+moR)+6&5z64TeWM>o%dHQ`?u$->o5RV>RqmG`#jM0xN-X@ z4YwL{josPC?gxzr=g#KCExGWXYxhIZuZT5s1a*X>@Z-2J78G`;XY%zgTx zr?yAtKCAaa8ZVWif{Y!9($cWhS>PFPXUi>ZIY*dnax1vhD6oU1O z#DbJ$3OdBAh%0&u64O0Crh?aRRwNU;Q7}0=?Zrv~!Y5P28e4myGp$2tZJCGD$OUn? zS$Vt$Wz)}X0kn++rLp_>A(+`QK?aDQEWt+NIn!3LT9C#MY z$-8p$i&^=_2lC4cXY#d8i|0N*w{-odwH;pyWXGXZ#Nm2?RMsx^{vfj~HQTX-<%n6a z#BP`z#bYjrFqrb(fd$NV3UEq8v3~lXF+P^muE6_V84@`oW3;hXHabs$+pG*g-Ic3* z<$-iMdDX7G3X;o&_5$)_Ty`6sXThv1Mw(u+7&-?wd*$LW)YYrtFthevTuU7EYQ#q) z$mV%W_F%FXlQvA4bAZ;GqEffa0`3sSz^f#*>B3h`UVxuI3JHcbyh~b>I9L6u+vPf% zZ+?DN!2G4dEPw1hy5@rS)rvY-gjHgWm5{Sa$XEAEb|vOm2|25Te63b;b*$G0T-&Uf z;P@L%ZNXW505wlHwcJx9Vi05Gx#>Z-@vpdhwwPk9Tuvzzow^yp@H;HZDVz*ijAt1~ zxJd5ueRl=3BBtn5sd#LXLg1xQ3t=AT?9Xl1TasFkQRi5YR=_+k{sylPA^?3H&IgeZ z$|{}`(h$_!p@jvwOHjakJAH$FfP+fA$J@~0_uywA3gtylPHfGJt+zd2h#e2bChILP z`Ik<7a^cp6`@=u+d?oNMH#lX!>YJ_etxNSQ-W{{YABy3e*pwBU$~FyD%$~J^gUxCm zR+d|vh6$9a{c@`Q9<;#+RcX0hD68&?qcUL+3yL4zc~F<=Nx%c=h@1lMKY5cap{x|5 zV|idoW~V=RGRwl`p#&VwIY*40J|EiKSH={oj21ds2M%fQ*Fj!ikuSliQRxYi6RFAU z015Z3Q$9P$7$GwS4!v|Ziqd5^6etzwKbW9U#<)N)?K-xYOeB-?fCh(9$U{@DnB1O= z4J2#y356z5Dd{-msDejo6H0>VDLG+9|IVZ=CZPWj?q&^h?44t42o&H9)%02p3Phh~ z9mbCEp>P@mH3h6vMATi;3_DymtO#X*WHyOelZ~hhS)Wtn)epRWAAUNjGdQxWCH}gc zFOu~|R(yMAPvk?@H)rN&a-oCS(81*w&aQ;c&7OJauU{TUfJB1klbvR0z9X3Pgq)d#^Ww(duRGzs(_@Rtv|N&d!v8uoTMwC-9*d zDA0ExG5z>WG3yf?bhxc)eKQ>DHo?K+fiCMU_~~fr02LKmprRui>bO(465787C~OS? zOb991p1*;YkH|;dNBkn0FMCWeUpS_CngyCi4rMIEJU73=0;$3rfwOdOP=FJ{z>EM# z5kf)ViALd;g!+q?sOS!Y!wAO_5wVZH33HF**EkQ3eGoM)3eg`6R=hONmpgo!FF25= z;K<@VSeqa5i~RRpE{L(d`Q&-aujJ>sQad|EUM4p>Sj_WVFrA2KN<&%-eISh)E_xYC z>04MOSZ*s*7EDjzR?W`NTEWdQyi7MD8sOfn^Jp?1SCaaxoer}fLp3|e`q~Ov{Pk(>E zb7Ti`I{PS!5$a#SPk#fFCoI->NzZ1P|63AWzApn{o`29Zd;BXmkwOoH^6l!CVEY{Z z7_Vo3ja8!Z!(YJ?%WwsxppHa1Fim!87)+>j830u&xZAN@ZM?{VcA!i3z4GL6B0kLS ze87;7>u`^Qd{}>r7phzcg2v#U4y-ULW<{PzXpZ zQ&mlUUOSLHYm7Z}`^W8z_J;{>$L2+XOzxZAd}Wf5qmu+pv{0 z`4qRoF$0xqBF-Xm4E^Eu@oGe}^n4{wjwyRIzm|)WMv5ITTmTA=7h;e-c@Aa@M+BGb z>ti6DD8Hois>NZ~W)3PAAh)vh&oq|=^tR_h$I5WB>$e<<)$hd1)xmMNc!kSVDgYbP zZA^^;;!Msk-7H`@Kv6%i%T&4pDYh~mZ0oTup>_5r7S>-^VEAGG1%`90fp!%B9wRXX z*ZaC$`v(a})j-1v=v_ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/testing.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/testing.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25abc882fedc43c46d12737f3566bd32faa8ff33 GIT binary patch literal 13585 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 iC_!u{MXLn)I6xY|@$T&LCV? z_F_CqP6;RC$xyRZvX@==w12={`kmUUO?8!3R?TT|SaaLcJe{PIl-ohwRMGwP^Y!~Z zzxSi~+2OEL@cY}pzmEU0jiP?lKJ=fhV$i?+Vxg!U#Zes1Q=4>zrZwBdn<5NmHmrJj z{VjGvoZ-!zEs>UTF5)el)`+!in|a%&Jz}RRsP)xrbc<`jZPhEqaArh>6 zbPK8sD`KW<%~?IO{>E)5#2i{IX3?IJPGhcs*u?xt_Dd%w@KIlcwvaj#htjcCO_wtv{J6 zo=5<)uGFKtRZ$_*(}WGPF{NkL-#8GbaiBJHvkYeATD?ZMaGbMsH_mfv2at+jl8_Hi%qUj9A zRfanhH=OdSzL!3SBkX|_*_8K)!O1Yd4Q-nS+y0|nr-QWG$|jS7%*qKNDSZpy&PNaK zEX<`+d?H$Qg3EFjvm6#BFs;j2NzE5|N%2IbbJrFY zAMfCFJjAgwE6HLys&$jf;HtkCmDr?|5JC{CGgQqFlQ5aeKp8OFma(KFJ|W2}Gnd>} zE#I)IG8OBBj73%!#QGfHvwRw>W;vbWvD#XZpyIPWz(1sMGK$r%EjFH_NLo5c-~Y6M#}86ffaz)jH4eJi7*%wz(}fA(u_h zTnzXvYp{}BO9NMSMX+vXJy>9g-_4;D!~KuT4l|DhZojZzUD`3g21aD zy=tX#%+80)U*EzpHqF;Z?*U&~+WR6%_u&AZ+oC9lciAMzH()!Kg)~sE%6mxt25Uk6 zmkqBAn>d`jEOOg8d`pO?H*r#y!co}e;ncRgE+ki_sE9GV)>#pUf5gcj!+c_`8XOCa zjE1Fzj4!3w=wmjHrEm;Rz~gXblZR5Uq}MhDF3scXqIR#*@F)4<%p5Z`O~0ki{z`Se zW6-nNKhM5Jp|>df7L6RYP_E9LC2J|6_7Z}pt%R%@*9-4+@9xq&WPY}=yO4?QjpQb> z6PXQyx=Y|&++EB_yZ3Z6O_2B4X)$-bXKXIhQ^#?Da(29kKacN4^Wz0(|7rmj=a1aQ zyDtUBH$mF3JZ%No4%dsV=UXM@(Arc`rj_OZgtfK0wg<%7 z&i`<*v%jMZ&5*w9#67DxX9>EYF}g_urEciz1xjbmzOuix7e|Zo(fk|NKfV9(9xama ztTH@Hf;SZEbjj_>O=c(cDe0U&YtPS+jzPsaRJ^4)FB3Fk9GrW-bhz{ek&82mbB3Vn z8uSef+5^xX0Np?EYVxJtIRk3snf!ML5BDGD?Zkafah@Zn|HGN&!aT_2J@gh9Nne<_ zFIO07y~m(+KeP@)>%gglzzv*z7j}iADDORr30Bk!+;k zE^x)MBl_>=znY6vf~OEI zj=Y{YoG5INGb6+|s-Ur>6$M>|d3fA$|vOBV3FC literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/__pycache__/views.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34a93687446fdb0b2f1c99fc140eeae0f969ed9a GIT binary patch literal 7015 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/app.py b/venv/lib/python3.12/site-packages/flask/app.py new file mode 100644 index 0000000..905b247 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/app.py @@ -0,0 +1,1536 @@ +from __future__ import annotations + +import collections.abc as cabc +import os +import sys +import typing as t +import weakref +from datetime import timedelta +from inspect import iscoroutinefunction +from itertools import chain +from types import TracebackType +from urllib.parse import quote as _url_quote + +import click +from werkzeug.datastructures import Headers +from werkzeug.datastructures import ImmutableDict +from werkzeug.exceptions import BadRequestKeyError +from werkzeug.exceptions import HTTPException +from werkzeug.exceptions import InternalServerError +from werkzeug.routing import BuildError +from werkzeug.routing import MapAdapter +from werkzeug.routing import RequestRedirect +from werkzeug.routing import RoutingException +from werkzeug.routing import Rule +from werkzeug.serving import is_running_from_reloader +from werkzeug.wrappers import Response as BaseResponse +from werkzeug.wsgi import get_host + +from . import cli +from . import typing as ft +from .ctx import AppContext +from .ctx import RequestContext +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import g +from .globals import request +from .globals import request_ctx +from .globals import session +from .helpers import get_debug_flag +from .helpers import get_flashed_messages +from .helpers import get_load_dotenv +from .helpers import send_from_directory +from .sansio.app import App +from .sansio.scaffold import _sentinel +from .sessions import SecureCookieSessionInterface +from .sessions import SessionInterface +from .signals import appcontext_tearing_down +from .signals import got_request_exception +from .signals import request_finished +from .signals import request_started +from .signals import request_tearing_down +from .templating import Environment +from .wrappers import Request +from .wrappers import Response + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIEnvironment + + from .testing import FlaskClient + from .testing import FlaskCliRunner + from .typing import HeadersValue + +T_shell_context_processor = t.TypeVar( + "T_shell_context_processor", bound=ft.ShellContextProcessorCallable +) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) + + +def _make_timedelta(value: timedelta | int | None) -> timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class Flask(App): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + default_config = ImmutableDict( + { + "DEBUG": None, + "TESTING": False, + "PROPAGATE_EXCEPTIONS": None, + "SECRET_KEY": None, + "SECRET_KEY_FALLBACKS": None, + "PERMANENT_SESSION_LIFETIME": timedelta(days=31), + "USE_X_SENDFILE": False, + "TRUSTED_HOSTS": None, + "SERVER_NAME": None, + "APPLICATION_ROOT": "/", + "SESSION_COOKIE_NAME": "session", + "SESSION_COOKIE_DOMAIN": None, + "SESSION_COOKIE_PATH": None, + "SESSION_COOKIE_HTTPONLY": True, + "SESSION_COOKIE_SECURE": False, + "SESSION_COOKIE_PARTITIONED": False, + "SESSION_COOKIE_SAMESITE": None, + "SESSION_REFRESH_EACH_REQUEST": True, + "MAX_CONTENT_LENGTH": None, + "MAX_FORM_MEMORY_SIZE": 500_000, + "MAX_FORM_PARTS": 1_000, + "SEND_FILE_MAX_AGE_DEFAULT": None, + "TRAP_BAD_REQUEST_ERRORS": None, + "TRAP_HTTP_EXCEPTIONS": False, + "EXPLAIN_TEMPLATE_LOADING": False, + "PREFERRED_URL_SCHEME": "http", + "TEMPLATES_AUTO_RELOAD": None, + "MAX_COOKIE_SIZE": 4093, + "PROVIDE_AUTOMATIC_OPTIONS": True, + } + ) + + #: The class that is used for request objects. See :class:`~flask.Request` + #: for more information. + request_class: type[Request] = Request + + #: The class that is used for response objects. See + #: :class:`~flask.Response` for more information. + response_class: type[Response] = Response + + #: the session interface to use. By default an instance of + #: :class:`~flask.sessions.SecureCookieSessionInterface` is used here. + #: + #: .. versionadded:: 0.8 + session_interface: SessionInterface = SecureCookieSessionInterface() + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ): + super().__init__( + import_name=import_name, + static_url_path=static_url_path, + static_folder=static_folder, + static_host=static_host, + host_matching=host_matching, + subdomain_matching=subdomain_matching, + template_folder=template_folder, + instance_path=instance_path, + instance_relative_config=instance_relative_config, + root_path=root_path, + ) + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = cli.AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + # Add a static route using the provided static_url_path, static_host, + # and static_folder if there is a configured static_folder. + # Note we do this without checking if static_folder exists. + # For one, it might be created while the server is running (e.g. during + # development). Also, Google App Engine stores static files somewhere + if self.has_static_folder: + assert ( + bool(static_host) == host_matching + ), "Invalid static_host/host_matching combination" + # Use a weakref to avoid creating a reference cycle between the app + # and the view function (see #3761). + self_ref = weakref.ref(self) + self.add_url_rule( + f"{self.static_url_path}/", + endpoint="static", + host=static_host, + view_func=lambda **kw: self_ref().send_static_file(**kw), # type: ignore # noqa: B950 + ) + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value # type: ignore[no-any-return] + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource( + self, resource: str, mode: str = "rb", encoding: str | None = None + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for reading. + + For example, if the file ``schema.sql`` is next to the file + ``app.py`` where the ``Flask`` app is defined, it can be opened + with: + + .. code-block:: python + + with app.open_resource("schema.sql") as f: + conn.executescript(f.read()) + + :param resource: Path to the resource relative to :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is supported, + valid values are ``"r"`` (or ``"rt"``) and ``"rb"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) + + def open_instance_resource( + self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to the application's instance folder + :attr:`instance_path`. Unlike :meth:`open_resource`, files in the + instance folder can be opened for writing. + + :param resource: Path to the resource relative to :attr:`instance_path`. + :param mode: Open the file in this mode. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + path = os.path.join(self.instance_path, resource) + + if "b" in mode: + return open(path, mode) + + return open(path, mode, encoding=encoding) + + def create_jinja_environment(self) -> Environment: + """Create the Jinja environment based on :attr:`jinja_options` + and the various Jinja-related methods of the app. Changing + :attr:`jinja_options` after this will have no effect. Also adds + Flask-related globals and filters to the environment. + + .. versionchanged:: 0.11 + ``Environment.auto_reload`` set in accordance with + ``TEMPLATES_AUTO_RELOAD`` configuration option. + + .. versionadded:: 0.5 + """ + options = dict(self.jinja_options) + + if "autoescape" not in options: + options["autoescape"] = self.select_jinja_autoescape + + if "auto_reload" not in options: + auto_reload = self.config["TEMPLATES_AUTO_RELOAD"] + + if auto_reload is None: + auto_reload = self.debug + + options["auto_reload"] = auto_reload + + rv = self.jinja_environment(self, **options) + rv.globals.update( + url_for=self.url_for, + get_flashed_messages=get_flashed_messages, + config=self.config, + # request, session and g are normally added with the + # context processor for efficiency reasons but for imported + # templates we also want the proxies in there. + request=request, + session=session, + g=g, + ) + rv.policies["json.dumps_function"] = self.json.dumps + return rv + + def create_url_adapter(self, request: Request | None) -> MapAdapter | None: + """Creates a URL adapter for the given request. The URL adapter + is created at a point where the request context is not yet set + up so the request is passed explicitly. + + .. versionchanged:: 3.1 + If :data:`SERVER_NAME` is set, it does not restrict requests to + only that domain, for both ``subdomain_matching`` and + ``host_matching``. + + .. versionchanged:: 1.0 + :data:`SERVER_NAME` no longer implicitly enables subdomain + matching. Use :attr:`subdomain_matching` instead. + + .. versionchanged:: 0.9 + This can be called outside a request when the URL adapter is created + for an application context. + + .. versionadded:: 0.6 + """ + if request is not None: + if (trusted_hosts := self.config["TRUSTED_HOSTS"]) is not None: + request.trusted_hosts = trusted_hosts + + # Check trusted_hosts here until bind_to_environ does. + request.host = get_host(request.environ, request.trusted_hosts) # pyright: ignore + subdomain = None + server_name = self.config["SERVER_NAME"] + + if self.url_map.host_matching: + # Don't pass SERVER_NAME, otherwise it's used and the actual + # host is ignored, which breaks host matching. + server_name = None + elif not self.subdomain_matching: + # Werkzeug doesn't implement subdomain matching yet. Until then, + # disable it by forcing the current subdomain to the default, or + # the empty string. + subdomain = self.url_map.default_subdomain or "" + + return self.url_map.bind_to_environ( + request.environ, server_name=server_name, subdomain=subdomain + ) + + # Need at least SERVER_NAME to match/build outside a request. + if self.config["SERVER_NAME"] is not None: + return self.url_map.bind( + self.config["SERVER_NAME"], + script_name=self.config["APPLICATION_ROOT"], + url_scheme=self.config["PREFERRED_URL_SCHEME"], + ) + + return None + + def raise_routing_exception(self, request: Request) -> t.NoReturn: + """Intercept routing exceptions and possibly do something else. + + In debug mode, intercept a routing redirect and replace it with + an error if the body will be discarded. + + With modern Werkzeug this shouldn't occur, since it now uses a + 308 status which tells the browser to resend the method and + body. + + .. versionchanged:: 2.1 + Don't intercept 307 and 308 redirects. + + :meta private: + :internal: + """ + if ( + not self.debug + or not isinstance(request.routing_exception, RequestRedirect) + or request.routing_exception.code in {307, 308} + or request.method in {"GET", "HEAD", "OPTIONS"} + ): + raise request.routing_exception # type: ignore[misc] + + from .debughelpers import FormDataRoutingRedirect + + raise FormDataRoutingRedirect(request) + + def update_template_context(self, context: dict[str, t.Any]) -> None: + """Update the template context with some commonly used variables. + This injects request, session, config and g into the template + context as well as everything template context processors want + to inject. Note that the as of Flask 0.6, the original values + in the context will not be overridden if a context processor + decides to return a value with the same key. + + :param context: the context as a dictionary that is updated in place + to add extra variables. + """ + names: t.Iterable[str | None] = (None,) + + # A template may be rendered outside a request context. + if request: + names = chain(names, reversed(request.blueprints)) + + # The values passed to render_template take precedence. Keep a + # copy to re-apply after all context functions. + orig_ctx = context.copy() + + for name in names: + if name in self.template_context_processors: + for func in self.template_context_processors[name]: + context.update(self.ensure_sync(func)()) + + context.update(orig_ctx) + + def make_shell_context(self) -> dict[str, t.Any]: + """Returns the shell context for an interactive shell for this + application. This runs all the registered shell context + processors. + + .. versionadded:: 0.11 + """ + rv = {"app": self, "g": g} + for processor in self.shell_context_processors: + rv.update(processor()) + return rv + + def run( + self, + host: str | None = None, + port: int | None = None, + debug: bool | None = None, + load_dotenv: bool = True, + **options: t.Any, + ) -> None: + """Runs the application on a local development server. + + Do not use ``run()`` in a production setting. It is not intended to + meet security and performance requirements for a production server. + Instead, see :doc:`/deploying/index` for WSGI server recommendations. + + If the :attr:`debug` flag is set the server will automatically reload + for code changes and show a debugger in case an exception happened. + + If you want to run the application in debug mode, but disable the + code execution on the interactive debugger, you can pass + ``use_evalex=False`` as parameter. This will keep the debugger's + traceback screen active, but disable code execution. + + It is not recommended to use this function for development with + automatic reloading as this is badly supported. Instead you should + be using the :command:`flask` command line script's ``run`` support. + + .. admonition:: Keep in Mind + + Flask will suppress any server error with a generic error page + unless it is in debug mode. As such to enable just the + interactive debugger without the code reloading, you have to + invoke :meth:`run` with ``debug=True`` and ``use_reloader=False``. + Setting ``use_debugger`` to ``True`` without being in debug mode + won't catch any exceptions because there won't be any to + catch. + + :param host: the hostname to listen on. Set this to ``'0.0.0.0'`` to + have the server available externally as well. Defaults to + ``'127.0.0.1'`` or the host in the ``SERVER_NAME`` config variable + if present. + :param port: the port of the webserver. Defaults to ``5000`` or the + port defined in the ``SERVER_NAME`` config variable if present. + :param debug: if given, enable or disable debug mode. See + :attr:`debug`. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param options: the options to be forwarded to the underlying Werkzeug + server. See :func:`werkzeug.serving.run_simple` for more + information. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment + variables from :file:`.env` and :file:`.flaskenv` files. + + The :envvar:`FLASK_DEBUG` environment variable will override :attr:`debug`. + + Threaded mode is enabled by default. + + .. versionchanged:: 0.10 + The default port is now picked from the ``SERVER_NAME`` + variable. + """ + # Ignore this call so that it doesn't start another server if + # the 'flask run' command is used. + if os.environ.get("FLASK_RUN_FROM_CLI") == "true": + if not is_running_from_reloader(): + click.secho( + " * Ignoring a call to 'app.run()' that would block" + " the current 'flask' CLI command.\n" + " Only call 'app.run()' in an 'if __name__ ==" + ' "__main__"\' guard.', + fg="red", + ) + + return + + if get_load_dotenv(load_dotenv): + cli.load_dotenv() + + # if set, env var overrides existing value + if "FLASK_DEBUG" in os.environ: + self.debug = get_debug_flag() + + # debug passed to method overrides all other sources + if debug is not None: + self.debug = bool(debug) + + server_name = self.config.get("SERVER_NAME") + sn_host = sn_port = None + + if server_name: + sn_host, _, sn_port = server_name.partition(":") + + if not host: + if sn_host: + host = sn_host + else: + host = "127.0.0.1" + + if port or port == 0: + port = int(port) + elif sn_port: + port = int(sn_port) + else: + port = 5000 + + options.setdefault("use_reloader", self.debug) + options.setdefault("use_debugger", self.debug) + options.setdefault("threaded", True) + + cli.show_server_banner(self.debug, self.name) + + from werkzeug.serving import run_simple + + try: + run_simple(t.cast(str, host), port, self, **options) + finally: + # reset the first request information if the development server + # reset normally. This makes it possible to restart the server + # without reloader and that stuff from an interactive shell. + self._got_first_request = False + + def test_client(self, use_cookies: bool = True, **kwargs: t.Any) -> FlaskClient: + """Creates a test client for this application. For information + about unit testing head over to :doc:`/testing`. + + Note that if you are testing for assertions or exceptions in your + application code, you must set ``app.testing = True`` in order for the + exceptions to propagate to the test client. Otherwise, the exception + will be handled by the application (not visible to the test client) and + the only indication of an AssertionError or other exception will be a + 500 status code response to the test client. See the :attr:`testing` + attribute. For example:: + + app.testing = True + client = app.test_client() + + The test client can be used in a ``with`` block to defer the closing down + of the context until the end of the ``with`` block. This is useful if + you want to access the context locals for testing:: + + with app.test_client() as c: + rv = c.get('/?vodka=42') + assert request.args['vodka'] == '42' + + Additionally, you may pass optional keyword arguments that will then + be passed to the application's :attr:`test_client_class` constructor. + For example:: + + from flask.testing import FlaskClient + + class CustomClient(FlaskClient): + def __init__(self, *args, **kwargs): + self._authentication = kwargs.pop("authentication") + super(CustomClient,self).__init__( *args, **kwargs) + + app.test_client_class = CustomClient + client = app.test_client(authentication='Basic ....') + + See :class:`~flask.testing.FlaskClient` for more information. + + .. versionchanged:: 0.4 + added support for ``with`` block usage for the client. + + .. versionadded:: 0.7 + The `use_cookies` parameter was added as well as the ability + to override the client to be used by setting the + :attr:`test_client_class` attribute. + + .. versionchanged:: 0.11 + Added `**kwargs` to support passing additional keyword arguments to + the constructor of :attr:`test_client_class`. + """ + cls = self.test_client_class + if cls is None: + from .testing import FlaskClient as cls + return cls( # type: ignore + self, self.response_class, use_cookies=use_cookies, **kwargs + ) + + def test_cli_runner(self, **kwargs: t.Any) -> FlaskCliRunner: + """Create a CLI runner for testing CLI commands. + See :ref:`testing-cli`. + + Returns an instance of :attr:`test_cli_runner_class`, by default + :class:`~flask.testing.FlaskCliRunner`. The Flask app object is + passed as the first argument. + + .. versionadded:: 1.0 + """ + cls = self.test_cli_runner_class + + if cls is None: + from .testing import FlaskCliRunner as cls + + return cls(self, **kwargs) # type: ignore + + def handle_http_exception( + self, e: HTTPException + ) -> HTTPException | ft.ResponseReturnValue: + """Handles an HTTP exception. By default this will invoke the + registered error handlers and fall back to returning the + exception as response. + + .. versionchanged:: 1.0.3 + ``RoutingException``, used internally for actions such as + slash redirects during routing, is not passed to error + handlers. + + .. versionchanged:: 1.0 + Exceptions are looked up by code *and* by MRO, so + ``HTTPException`` subclasses can be handled with a catch-all + handler for the base ``HTTPException``. + + .. versionadded:: 0.3 + """ + # Proxy exceptions don't have error codes. We want to always return + # those unchanged as errors + if e.code is None: + return e + + # RoutingExceptions are used internally to trigger routing + # actions, such as slash redirects raising RequestRedirect. They + # are not raised or handled in user code. + if isinstance(e, RoutingException): + return e + + handler = self._find_error_handler(e, request.blueprints) + if handler is None: + return e + return self.ensure_sync(handler)(e) # type: ignore[no-any-return] + + def handle_user_exception( + self, e: Exception + ) -> HTTPException | ft.ResponseReturnValue: + """This method is called whenever an exception occurs that + should be handled. A special case is :class:`~werkzeug + .exceptions.HTTPException` which is forwarded to the + :meth:`handle_http_exception` method. This function will either + return a response value or reraise the exception with the same + traceback. + + .. versionchanged:: 1.0 + Key errors raised from request data like ``form`` show the + bad key in debug mode rather than a generic bad request + message. + + .. versionadded:: 0.7 + """ + if isinstance(e, BadRequestKeyError) and ( + self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"] + ): + e.show_exception = True + + if isinstance(e, HTTPException) and not self.trap_http_exception(e): + return self.handle_http_exception(e) + + handler = self._find_error_handler(e, request.blueprints) + + if handler is None: + raise + + return self.ensure_sync(handler)(e) # type: ignore[no-any-return] + + def handle_exception(self, e: Exception) -> Response: + """Handle an exception that did not have an error handler + associated with it, or that was raised from an error handler. + This always causes a 500 ``InternalServerError``. + + Always sends the :data:`got_request_exception` signal. + + If :data:`PROPAGATE_EXCEPTIONS` is ``True``, such as in debug + mode, the error will be re-raised so that the debugger can + display it. Otherwise, the original exception is logged, and + an :exc:`~werkzeug.exceptions.InternalServerError` is returned. + + If an error handler is registered for ``InternalServerError`` or + ``500``, it will be used. For consistency, the handler will + always receive the ``InternalServerError``. The original + unhandled exception is available as ``e.original_exception``. + + .. versionchanged:: 1.1.0 + Always passes the ``InternalServerError`` instance to the + handler, setting ``original_exception`` to the unhandled + error. + + .. versionchanged:: 1.1.0 + ``after_request`` functions and other finalization is done + even for the default 500 response when there is no handler. + + .. versionadded:: 0.3 + """ + exc_info = sys.exc_info() + got_request_exception.send(self, _async_wrapper=self.ensure_sync, exception=e) + propagate = self.config["PROPAGATE_EXCEPTIONS"] + + if propagate is None: + propagate = self.testing or self.debug + + if propagate: + # Re-raise if called with an active exception, otherwise + # raise the passed in exception. + if exc_info[1] is e: + raise + + raise e + + self.log_exception(exc_info) + server_error: InternalServerError | ft.ResponseReturnValue + server_error = InternalServerError(original_exception=e) + handler = self._find_error_handler(server_error, request.blueprints) + + if handler is not None: + server_error = self.ensure_sync(handler)(server_error) + + return self.finalize_request(server_error, from_error_handler=True) + + def log_exception( + self, + exc_info: (tuple[type, BaseException, TracebackType] | tuple[None, None, None]), + ) -> None: + """Logs an exception. This is called by :meth:`handle_exception` + if debugging is disabled and right before the handler is called. + The default implementation logs the exception as error on the + :attr:`logger`. + + .. versionadded:: 0.8 + """ + self.logger.error( + f"Exception on {request.path} [{request.method}]", exc_info=exc_info + ) + + def dispatch_request(self) -> ft.ResponseReturnValue: + """Does the request dispatching. Matches the URL and returns the + return value of the view or error handler. This does not have to + be a response object. In order to convert the return value to a + proper response object, call :func:`make_response`. + + .. versionchanged:: 0.7 + This no longer does the exception handling, this code was + moved to the new :meth:`full_dispatch_request`. + """ + req = request_ctx.request + if req.routing_exception is not None: + self.raise_routing_exception(req) + rule: Rule = req.url_rule # type: ignore[assignment] + # if we provide automatic options for this URL and the + # request came with the OPTIONS method, reply automatically + if ( + getattr(rule, "provide_automatic_options", False) + and req.method == "OPTIONS" + ): + return self.make_default_options_response() + # otherwise dispatch to the handler for that endpoint + view_args: dict[str, t.Any] = req.view_args # type: ignore[assignment] + return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) # type: ignore[no-any-return] + + def full_dispatch_request(self) -> Response: + """Dispatches the request and on top of that performs request + pre and postprocessing as well as HTTP exception catching and + error handling. + + .. versionadded:: 0.7 + """ + self._got_first_request = True + + try: + request_started.send(self, _async_wrapper=self.ensure_sync) + rv = self.preprocess_request() + if rv is None: + rv = self.dispatch_request() + except Exception as e: + rv = self.handle_user_exception(e) + return self.finalize_request(rv) + + def finalize_request( + self, + rv: ft.ResponseReturnValue | HTTPException, + from_error_handler: bool = False, + ) -> Response: + """Given the return value from a view function this finalizes + the request by converting it into a response and invoking the + postprocessing functions. This is invoked for both normal + request dispatching as well as error handlers. + + Because this means that it might be called as a result of a + failure a special safe mode is available which can be enabled + with the `from_error_handler` flag. If enabled, failures in + response processing will be logged and otherwise ignored. + + :internal: + """ + response = self.make_response(rv) + try: + response = self.process_response(response) + request_finished.send( + self, _async_wrapper=self.ensure_sync, response=response + ) + except Exception: + if not from_error_handler: + raise + self.logger.exception( + "Request finalizing failed with an error while handling an error" + ) + return response + + def make_default_options_response(self) -> Response: + """This method is called to create the default ``OPTIONS`` response. + This can be changed through subclassing to change the default + behavior of ``OPTIONS`` responses. + + .. versionadded:: 0.7 + """ + adapter = request_ctx.url_adapter + methods = adapter.allowed_methods() # type: ignore[union-attr] + rv = self.response_class() + rv.allow.update(methods) + return rv + + def ensure_sync(self, func: t.Callable[..., t.Any]) -> t.Callable[..., t.Any]: + """Ensure that the function is synchronous for WSGI workers. + Plain ``def`` functions are returned as-is. ``async def`` + functions are wrapped to run and wait for the response. + + Override this method to change how the app runs async views. + + .. versionadded:: 2.0 + """ + if iscoroutinefunction(func): + return self.async_to_sync(func) + + return func + + def async_to_sync( + self, func: t.Callable[..., t.Coroutine[t.Any, t.Any, t.Any]] + ) -> t.Callable[..., t.Any]: + """Return a sync function that will run the coroutine function. + + .. code-block:: python + + result = app.async_to_sync(func)(*args, **kwargs) + + Override this method to change how the app converts async code + to be synchronously callable. + + .. versionadded:: 2.0 + """ + try: + from asgiref.sync import async_to_sync as asgiref_async_to_sync + except ImportError: + raise RuntimeError( + "Install Flask with the 'async' extra in order to use async views." + ) from None + + return asgiref_async_to_sync(func) + + def url_for( + self, + /, + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, + ) -> str: + """Generate a URL to the given endpoint with the given values. + + This is called by :func:`flask.url_for`, and can be called + directly as well. + + An *endpoint* is the name of a URL rule, usually added with + :meth:`@app.route() `, and usually the same name as the + view function. A route defined in a :class:`~flask.Blueprint` + will prepend the blueprint's name separated by a ``.`` to the + endpoint. + + In some cases, such as email messages, you want URLs to include + the scheme and domain, like ``https://example.com/hello``. When + not in an active request, URLs will be external by default, but + this requires setting :data:`SERVER_NAME` so Flask knows what + domain to use. :data:`APPLICATION_ROOT` and + :data:`PREFERRED_URL_SCHEME` should also be configured as + needed. This config is only used when not in an active request. + + Functions can be decorated with :meth:`url_defaults` to modify + keyword arguments before the URL is built. + + If building fails for some reason, such as an unknown endpoint + or incorrect values, the app's :meth:`handle_url_build_error` + method is called. If that returns a string, that is returned, + otherwise a :exc:`~werkzeug.routing.BuildError` is raised. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it + is external. + :param _external: If given, prefer the URL to be internal + (False) or require it to be external (True). External URLs + include the scheme and domain. When not in an active + request, URLs are external by default. + :param values: Values to use for the variable parts of the URL + rule. Unknown keys are appended as query string arguments, + like ``?a=b&c=d``. + + .. versionadded:: 2.2 + Moved from ``flask.url_for``, which calls this method. + """ + req_ctx = _cv_request.get(None) + + if req_ctx is not None: + url_adapter = req_ctx.url_adapter + blueprint_name = req_ctx.request.blueprint + + # If the endpoint starts with "." and the request matches a + # blueprint, the endpoint is relative to the blueprint. + if endpoint[:1] == ".": + if blueprint_name is not None: + endpoint = f"{blueprint_name}{endpoint}" + else: + endpoint = endpoint[1:] + + # When in a request, generate a URL without scheme and + # domain by default, unless a scheme is given. + if _external is None: + _external = _scheme is not None + else: + app_ctx = _cv_app.get(None) + + # If called by helpers.url_for, an app context is active, + # use its url_adapter. Otherwise, app.url_for was called + # directly, build an adapter. + if app_ctx is not None: + url_adapter = app_ctx.url_adapter + else: + url_adapter = self.create_url_adapter(None) + + if url_adapter is None: + raise RuntimeError( + "Unable to build URLs outside an active request" + " without 'SERVER_NAME' configured. Also configure" + " 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as" + " needed." + ) + + # When outside a request, generate a URL with scheme and + # domain by default. + if _external is None: + _external = True + + # It is an error to set _scheme when _external=False, in order + # to avoid accidental insecure URLs. + if _scheme is not None and not _external: + raise ValueError("When specifying '_scheme', '_external' must be True.") + + self.inject_url_defaults(endpoint, values) + + try: + rv = url_adapter.build( # type: ignore[union-attr] + endpoint, + values, + method=_method, + url_scheme=_scheme, + force_external=_external, + ) + except BuildError as error: + values.update( + _anchor=_anchor, _method=_method, _scheme=_scheme, _external=_external + ) + return self.handle_url_build_error(error, endpoint, values) + + if _anchor is not None: + _anchor = _url_quote(_anchor, safe="%!#$&'()*+,/:;=?@") + rv = f"{rv}#{_anchor}" + + return rv + + def make_response(self, rv: ft.ResponseReturnValue) -> Response: + """Convert the return value from a view function to an instance of + :attr:`response_class`. + + :param rv: the return value from the view function. The view function + must return a response. Returning ``None``, or the view ending + without returning, is not allowed. The following types are allowed + for ``view_rv``: + + ``str`` + A response object is created with the string encoded to UTF-8 + as the body. + + ``bytes`` + A response object is created with the bytes as the body. + + ``dict`` + A dictionary that will be jsonify'd before being returned. + + ``list`` + A list that will be jsonify'd before being returned. + + ``generator`` or ``iterator`` + A generator that returns ``str`` or ``bytes`` to be + streamed as the response. + + ``tuple`` + Either ``(body, status, headers)``, ``(body, status)``, or + ``(body, headers)``, where ``body`` is any of the other types + allowed here, ``status`` is a string or an integer, and + ``headers`` is a dictionary or a list of ``(key, value)`` + tuples. If ``body`` is a :attr:`response_class` instance, + ``status`` overwrites the exiting value and ``headers`` are + extended. + + :attr:`response_class` + The object is returned unchanged. + + other :class:`~werkzeug.wrappers.Response` class + The object is coerced to :attr:`response_class`. + + :func:`callable` + The function is called as a WSGI application. The result is + used to create a response object. + + .. versionchanged:: 2.2 + A generator will be converted to a streaming response. + A list will be converted to a JSON response. + + .. versionchanged:: 1.1 + A dict will be converted to a JSON response. + + .. versionchanged:: 0.9 + Previously a tuple was interpreted as the arguments for the + response object. + """ + + status: int | None = None + headers: HeadersValue | None = None + + # unpack tuple returns + if isinstance(rv, tuple): + len_rv = len(rv) + + # a 3-tuple is unpacked directly + if len_rv == 3: + rv, status, headers = rv # type: ignore[misc] + # decide if a 2-tuple has status or headers + elif len_rv == 2: + if isinstance(rv[1], (Headers, dict, tuple, list)): + rv, headers = rv # pyright: ignore + else: + rv, status = rv # type: ignore[assignment,misc] + # other sized tuples are not allowed + else: + raise TypeError( + "The view function did not return a valid response tuple." + " The tuple must have the form (body, status, headers)," + " (body, status), or (body, headers)." + ) + + # the body must not be None + if rv is None: + raise TypeError( + f"The view function for {request.endpoint!r} did not" + " return a valid response. The function either returned" + " None or ended without a return statement." + ) + + # make sure the body is an instance of the response class + if not isinstance(rv, self.response_class): + if isinstance(rv, (str, bytes, bytearray)) or isinstance(rv, cabc.Iterator): + # let the response class set the status and headers instead of + # waiting to do it manually, so that the class can handle any + # special logic + rv = self.response_class( + rv, + status=status, + headers=headers, # type: ignore[arg-type] + ) + status = headers = None + elif isinstance(rv, (dict, list)): + rv = self.json.response(rv) + elif isinstance(rv, BaseResponse) or callable(rv): + # evaluate a WSGI callable, or coerce a different response + # class to the correct type + try: + rv = self.response_class.force_type( + rv, # type: ignore[arg-type] + request.environ, + ) + except TypeError as e: + raise TypeError( + f"{e}\nThe view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it" + f" was a {type(rv).__name__}." + ).with_traceback(sys.exc_info()[2]) from None + else: + raise TypeError( + "The view function did not return a valid" + " response. The return type must be a string," + " dict, list, tuple with headers or status," + " Response instance, or WSGI callable, but it was a" + f" {type(rv).__name__}." + ) + + rv = t.cast(Response, rv) + # prefer the status if it was provided + if status is not None: + if isinstance(status, (str, bytes, bytearray)): + rv.status = status + else: + rv.status_code = status + + # extend existing headers with provided headers + if headers: + rv.headers.update(headers) + + return rv + + def preprocess_request(self) -> ft.ResponseReturnValue | None: + """Called before the request is dispatched. Calls + :attr:`url_value_preprocessors` registered with the app and the + current blueprint (if any). Then calls :attr:`before_request_funcs` + registered with the app and the blueprint. + + If any :meth:`before_request` handler returns a non-None value, the + value is handled as if it was the return value from the view, and + further request handling is stopped. + """ + names = (None, *reversed(request.blueprints)) + + for name in names: + if name in self.url_value_preprocessors: + for url_func in self.url_value_preprocessors[name]: + url_func(request.endpoint, request.view_args) + + for name in names: + if name in self.before_request_funcs: + for before_func in self.before_request_funcs[name]: + rv = self.ensure_sync(before_func)() + + if rv is not None: + return rv # type: ignore[no-any-return] + + return None + + def process_response(self, response: Response) -> Response: + """Can be overridden in order to modify the response object + before it's sent to the WSGI server. By default this will + call all the :meth:`after_request` decorated functions. + + .. versionchanged:: 0.5 + As of Flask 0.5 the functions registered for after request + execution are called in reverse order of registration. + + :param response: a :attr:`response_class` object. + :return: a new response object or the same, has to be an + instance of :attr:`response_class`. + """ + ctx = request_ctx._get_current_object() # type: ignore[attr-defined] + + for func in ctx._after_request_functions: + response = self.ensure_sync(func)(response) + + for name in chain(request.blueprints, (None,)): + if name in self.after_request_funcs: + for func in reversed(self.after_request_funcs[name]): + response = self.ensure_sync(func)(response) + + if not self.session_interface.is_null_session(ctx.session): + self.session_interface.save_session(self, ctx.session, response) + + return response + + def do_teardown_request( + self, + exc: BaseException | None = _sentinel, # type: ignore[assignment] + ) -> None: + """Called after the request is dispatched and the response is + returned, right before the request context is popped. + + This calls all functions decorated with + :meth:`teardown_request`, and :meth:`Blueprint.teardown_request` + if a blueprint handled the request. Finally, the + :data:`request_tearing_down` signal is sent. + + This is called by + :meth:`RequestContext.pop() `, + which may be delayed during testing to maintain access to + resources. + + :param exc: An unhandled exception raised while dispatching the + request. Detected from the current exception information if + not passed. Passed to each teardown function. + + .. versionchanged:: 0.9 + Added the ``exc`` argument. + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for name in chain(request.blueprints, (None,)): + if name in self.teardown_request_funcs: + for func in reversed(self.teardown_request_funcs[name]): + self.ensure_sync(func)(exc) + + request_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def do_teardown_appcontext( + self, + exc: BaseException | None = _sentinel, # type: ignore[assignment] + ) -> None: + """Called right before the application context is popped. + + When handling a request, the application context is popped + after the request context. See :meth:`do_teardown_request`. + + This calls all functions decorated with + :meth:`teardown_appcontext`. Then the + :data:`appcontext_tearing_down` signal is sent. + + This is called by + :meth:`AppContext.pop() `. + + .. versionadded:: 0.9 + """ + if exc is _sentinel: + exc = sys.exc_info()[1] + + for func in reversed(self.teardown_appcontext_funcs): + self.ensure_sync(func)(exc) + + appcontext_tearing_down.send(self, _async_wrapper=self.ensure_sync, exc=exc) + + def app_context(self) -> AppContext: + """Create an :class:`~flask.ctx.AppContext`. Use as a ``with`` + block to push the context, which will make :data:`current_app` + point at this application. + + An application context is automatically pushed by + :meth:`RequestContext.push() ` + when handling a request, and when running a CLI command. Use + this to manually create a context outside of these situations. + + :: + + with app.app_context(): + init_db() + + See :doc:`/appcontext`. + + .. versionadded:: 0.9 + """ + return AppContext(self) + + def request_context(self, environ: WSGIEnvironment) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` representing a + WSGI environment. Use a ``with`` block to push the context, + which will make :data:`request` point at this request. + + See :doc:`/reqcontext`. + + Typically you should not call this from your own code. A request + context is automatically pushed by the :meth:`wsgi_app` when + handling a request. Use :meth:`test_request_context` to create + an environment and context instead of this method. + + :param environ: a WSGI environment + """ + return RequestContext(self, environ) + + def test_request_context(self, *args: t.Any, **kwargs: t.Any) -> RequestContext: + """Create a :class:`~flask.ctx.RequestContext` for a WSGI + environment created from the given values. This is mostly useful + during testing, where you may want to run a function that uses + request data without dispatching a full request. + + See :doc:`/reqcontext`. + + Use a ``with`` block to push the context, which will make + :data:`request` point at the request for the created + environment. :: + + with app.test_request_context(...): + generate_report() + + When using the shell, it may be easier to push and pop the + context manually to avoid indentation. :: + + ctx = app.test_request_context(...) + ctx.push() + ... + ctx.pop() + + Takes the same arguments as Werkzeug's + :class:`~werkzeug.test.EnvironBuilder`, with some defaults from + the application. See the linked Werkzeug docs for most of the + available arguments. Flask-specific behavior is listed here. + + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to + :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param data: The request body, either as a string or a dict of + form keys and values. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + from .testing import EnvironBuilder + + builder = EnvironBuilder(self, *args, **kwargs) + + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() + + def wsgi_app( + self, environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """The actual WSGI application. This is not implemented in + :meth:`__call__` so that middlewares can be applied without + losing a reference to the app object. Instead of doing this:: + + app = MyMiddleware(app) + + It's a better idea to do this instead:: + + app.wsgi_app = MyMiddleware(app.wsgi_app) + + Then you still have the original application object around and + can continue to call methods on it. + + .. versionchanged:: 0.7 + Teardown events for the request and app contexts are called + even if an unhandled error occurs. Other events may not be + called depending on when an error occurs during dispatch. + See :ref:`callbacks-and-errors`. + + :param environ: A WSGI environment. + :param start_response: A callable accepting a status code, + a list of headers, and an optional exception context to + start the response. + """ + ctx = self.request_context(environ) + error: BaseException | None = None + try: + try: + ctx.push() + response = self.full_dispatch_request() + except Exception as e: + error = e + response = self.handle_exception(e) + except: # noqa: B001 + error = sys.exc_info()[1] + raise + return response(environ, start_response) + finally: + if "werkzeug.debug.preserve_context" in environ: + environ["werkzeug.debug.preserve_context"](_cv_app.get()) + environ["werkzeug.debug.preserve_context"](_cv_request.get()) + + if error is not None and self.should_ignore_error(error): + error = None + + ctx.pop(error) + + def __call__( + self, environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + """The WSGI server calls the Flask application object as the + WSGI application. This calls :meth:`wsgi_app`, which can be + wrapped to apply middleware. + """ + return self.wsgi_app(environ, start_response) diff --git a/venv/lib/python3.12/site-packages/flask/blueprints.py b/venv/lib/python3.12/site-packages/flask/blueprints.py new file mode 100644 index 0000000..b6d4e43 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/blueprints.py @@ -0,0 +1,128 @@ +from __future__ import annotations + +import os +import typing as t +from datetime import timedelta + +from .cli import AppGroup +from .globals import current_app +from .helpers import send_from_directory +from .sansio.blueprints import Blueprint as SansioBlueprint +from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa +from .sansio.scaffold import _sentinel + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +class Blueprint(SansioBlueprint): + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore + ) -> None: + super().__init__( + name, + import_name, + static_folder, + static_url_path, + template_folder, + url_prefix, + subdomain, + url_defaults, + root_path, + cli_group, + ) + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + + def get_send_file_max_age(self, filename: str | None) -> int | None: + """Used by :func:`send_file` to determine the ``max_age`` cache + value for a given file path if it wasn't passed. + + By default, this returns :data:`SEND_FILE_MAX_AGE_DEFAULT` from + the configuration of :data:`~flask.current_app`. This defaults + to ``None``, which tells the browser to use conditional requests + instead of a timed cache, which is usually preferable. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionchanged:: 2.0 + The default configuration is ``None`` instead of 12 hours. + + .. versionadded:: 0.9 + """ + value = current_app.config["SEND_FILE_MAX_AGE_DEFAULT"] + + if value is None: + return None + + if isinstance(value, timedelta): + return int(value.total_seconds()) + + return value # type: ignore[no-any-return] + + def send_static_file(self, filename: str) -> Response: + """The view function used to serve files from + :attr:`static_folder`. A route is automatically registered for + this view at :attr:`static_url_path` if :attr:`static_folder` is + set. + + Note this is a duplicate of the same method in the Flask + class. + + .. versionadded:: 0.5 + + """ + if not self.has_static_folder: + raise RuntimeError("'static_folder' must be set to serve static_files.") + + # send_file only knows to call get_send_file_max_age on the app, + # call it here so it works for blueprints too. + max_age = self.get_send_file_max_age(filename) + return send_from_directory( + t.cast(str, self.static_folder), filename, max_age=max_age + ) + + def open_resource( + self, resource: str, mode: str = "rb", encoding: str | None = "utf-8" + ) -> t.IO[t.AnyStr]: + """Open a resource file relative to :attr:`root_path` for reading. The + blueprint-relative equivalent of the app's :meth:`~.Flask.open_resource` + method. + + :param resource: Path to the resource relative to :attr:`root_path`. + :param mode: Open the file in this mode. Only reading is supported, + valid values are ``"r"`` (or ``"rt"``) and ``"rb"``. + :param encoding: Open the file with this encoding when opening in text + mode. This is ignored when opening in binary mode. + + .. versionchanged:: 3.1 + Added the ``encoding`` parameter. + """ + if mode not in {"r", "rt", "rb"}: + raise ValueError("Resources can only be opened for reading.") + + path = os.path.join(self.root_path, resource) + + if mode == "rb": + return open(path, mode) # pyright: ignore + + return open(path, mode, encoding=encoding) diff --git a/venv/lib/python3.12/site-packages/flask/cli.py b/venv/lib/python3.12/site-packages/flask/cli.py new file mode 100644 index 0000000..dd03f3c --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/cli.py @@ -0,0 +1,1133 @@ +from __future__ import annotations + +import ast +import collections.abc as cabc +import importlib.metadata +import inspect +import os +import platform +import re +import sys +import traceback +import typing as t +from functools import update_wrapper +from operator import itemgetter +from types import ModuleType + +import click +from click.core import ParameterSource +from werkzeug import run_simple +from werkzeug.serving import is_running_from_reloader +from werkzeug.utils import import_string + +from .globals import current_app +from .helpers import get_debug_flag +from .helpers import get_load_dotenv + +if t.TYPE_CHECKING: + import ssl + + from _typeshed.wsgi import StartResponse + from _typeshed.wsgi import WSGIApplication + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + + +class NoAppException(click.UsageError): + """Raised if an application cannot be found or loaded.""" + + +def find_best_app(module: ModuleType) -> Flask: + """Given a module instance this tries to find the best possible + application in the module or raises an exception. + """ + from . import Flask + + # Search for the most common names first. + for attr_name in ("app", "application"): + app = getattr(module, attr_name, None) + + if isinstance(app, Flask): + return app + + # Otherwise find the only object that is a Flask instance. + matches = [v for v in module.__dict__.values() if isinstance(v, Flask)] + + if len(matches) == 1: + return matches[0] + elif len(matches) > 1: + raise NoAppException( + "Detected multiple Flask applications in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify the correct one." + ) + + # Search for app factory functions. + for attr_name in ("create_app", "make_app"): + app_factory = getattr(module, attr_name, None) + + if inspect.isfunction(app_factory): + try: + app = app_factory() + + if isinstance(app, Flask): + return app + except TypeError as e: + if not _called_with_wrong_args(app_factory): + raise + + raise NoAppException( + f"Detected factory '{attr_name}' in module '{module.__name__}'," + " but could not call it without arguments. Use" + f" '{module.__name__}:{attr_name}(args)'" + " to specify arguments." + ) from e + + raise NoAppException( + "Failed to find Flask application or factory in module" + f" '{module.__name__}'. Use '{module.__name__}:name'" + " to specify one." + ) + + +def _called_with_wrong_args(f: t.Callable[..., Flask]) -> bool: + """Check whether calling a function raised a ``TypeError`` because + the call failed or because something in the factory raised the + error. + + :param f: The function that was called. + :return: ``True`` if the call failed. + """ + tb = sys.exc_info()[2] + + try: + while tb is not None: + if tb.tb_frame.f_code is f.__code__: + # In the function, it was called successfully. + return False + + tb = tb.tb_next + + # Didn't reach the function. + return True + finally: + # Delete tb to break a circular reference. + # https://docs.python.org/2/library/sys.html#sys.exc_info + del tb + + +def find_app_by_string(module: ModuleType, app_name: str) -> Flask: + """Check if the given string is a variable name or a function. Call + a function to get the app instance, or return the variable directly. + """ + from . import Flask + + # Parse app_name as a single expression to determine if it's a valid + # attribute name or function call. + try: + expr = ast.parse(app_name.strip(), mode="eval").body + except SyntaxError: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) from None + + if isinstance(expr, ast.Name): + name = expr.id + args = [] + kwargs = {} + elif isinstance(expr, ast.Call): + # Ensure the function name is an attribute name only. + if not isinstance(expr.func, ast.Name): + raise NoAppException( + f"Function reference must be a simple name: {app_name!r}." + ) + + name = expr.func.id + + # Parse the positional and keyword arguments as literals. + try: + args = [ast.literal_eval(arg) for arg in expr.args] + kwargs = { + kw.arg: ast.literal_eval(kw.value) + for kw in expr.keywords + if kw.arg is not None + } + except ValueError: + # literal_eval gives cryptic error messages, show a generic + # message with the full expression instead. + raise NoAppException( + f"Failed to parse arguments as literal values: {app_name!r}." + ) from None + else: + raise NoAppException( + f"Failed to parse {app_name!r} as an attribute name or function call." + ) + + try: + attr = getattr(module, name) + except AttributeError as e: + raise NoAppException( + f"Failed to find attribute {name!r} in {module.__name__!r}." + ) from e + + # If the attribute is a function, call it with any args and kwargs + # to get the real application. + if inspect.isfunction(attr): + try: + app = attr(*args, **kwargs) + except TypeError as e: + if not _called_with_wrong_args(attr): + raise + + raise NoAppException( + f"The factory {app_name!r} in module" + f" {module.__name__!r} could not be called with the" + " specified arguments." + ) from e + else: + app = attr + + if isinstance(app, Flask): + return app + + raise NoAppException( + "A valid Flask application was not obtained from" + f" '{module.__name__}:{app_name}'." + ) + + +def prepare_import(path: str) -> str: + """Given a filename this will try to calculate the python path, add it + to the search path and return the actual module name that is expected. + """ + path = os.path.realpath(path) + + fname, ext = os.path.splitext(path) + if ext == ".py": + path = fname + + if os.path.basename(path) == "__init__": + path = os.path.dirname(path) + + module_name = [] + + # move up until outside package structure (no __init__.py) + while True: + path, name = os.path.split(path) + module_name.append(name) + + if not os.path.exists(os.path.join(path, "__init__.py")): + break + + if sys.path[0] != path: + sys.path.insert(0, path) + + return ".".join(module_name[::-1]) + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[True] = True +) -> Flask: ... + + +@t.overload +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: t.Literal[False] = ... +) -> Flask | None: ... + + +def locate_app( + module_name: str, app_name: str | None, raise_if_not_found: bool = True +) -> Flask | None: + try: + __import__(module_name) + except ImportError: + # Reraise the ImportError if it occurred within the imported module. + # Determine this by checking whether the trace has a depth > 1. + if sys.exc_info()[2].tb_next: # type: ignore[union-attr] + raise NoAppException( + f"While importing {module_name!r}, an ImportError was" + f" raised:\n\n{traceback.format_exc()}" + ) from None + elif raise_if_not_found: + raise NoAppException(f"Could not import {module_name!r}.") from None + else: + return None + + module = sys.modules[module_name] + + if app_name is None: + return find_best_app(module) + else: + return find_app_by_string(module, app_name) + + +def get_version(ctx: click.Context, param: click.Parameter, value: t.Any) -> None: + if not value or ctx.resilient_parsing: + return + + flask_version = importlib.metadata.version("flask") + werkzeug_version = importlib.metadata.version("werkzeug") + + click.echo( + f"Python {platform.python_version()}\n" + f"Flask {flask_version}\n" + f"Werkzeug {werkzeug_version}", + color=ctx.color, + ) + ctx.exit() + + +version_option = click.Option( + ["--version"], + help="Show the Flask version.", + expose_value=False, + callback=get_version, + is_flag=True, + is_eager=True, +) + + +class ScriptInfo: + """Helper object to deal with Flask applications. This is usually not + necessary to interface with as it's used internally in the dispatching + to click. In future versions of Flask this object will most likely play + a bigger role. Typically it's created automatically by the + :class:`FlaskGroup` but you can also manually create it and pass it + onwards as click object. + + .. versionchanged:: 3.1 + Added the ``load_dotenv_defaults`` parameter and attribute. + """ + + def __init__( + self, + app_import_path: str | None = None, + create_app: t.Callable[..., Flask] | None = None, + set_debug_flag: bool = True, + load_dotenv_defaults: bool = True, + ) -> None: + #: Optionally the import path for the Flask application. + self.app_import_path = app_import_path + #: Optionally a function that is passed the script info to create + #: the instance of the application. + self.create_app = create_app + #: A dictionary with arbitrary data that can be associated with + #: this script info. + self.data: dict[t.Any, t.Any] = {} + self.set_debug_flag = set_debug_flag + + self.load_dotenv_defaults = get_load_dotenv(load_dotenv_defaults) + """Whether default ``.flaskenv`` and ``.env`` files should be loaded. + + ``ScriptInfo`` doesn't load anything, this is for reference when doing + the load elsewhere during processing. + + .. versionadded:: 3.1 + """ + + self._loaded_app: Flask | None = None + + def load_app(self) -> Flask: + """Loads the Flask app (if not yet loaded) and returns it. Calling + this multiple times will just result in the already loaded app to + be returned. + """ + if self._loaded_app is not None: + return self._loaded_app + app: Flask | None = None + if self.create_app is not None: + app = self.create_app() + else: + if self.app_import_path: + path, name = ( + re.split(r":(?![\\/])", self.app_import_path, maxsplit=1) + [None] + )[:2] + import_name = prepare_import(path) + app = locate_app(import_name, name) + else: + for path in ("wsgi.py", "app.py"): + import_name = prepare_import(path) + app = locate_app(import_name, None, raise_if_not_found=False) + + if app is not None: + break + + if app is None: + raise NoAppException( + "Could not locate a Flask application. Use the" + " 'flask --app' option, 'FLASK_APP' environment" + " variable, or a 'wsgi.py' or 'app.py' file in the" + " current directory." + ) + + if self.set_debug_flag: + # Update the app's debug flag through the descriptor so that + # other values repopulate as well. + app.debug = get_debug_flag() + + self._loaded_app = app + return app + + +pass_script_info = click.make_pass_decorator(ScriptInfo, ensure=True) + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def with_appcontext(f: F) -> F: + """Wraps a callback so that it's guaranteed to be executed with the + script's application context. + + Custom commands (and their options) registered under ``app.cli`` or + ``blueprint.cli`` will always have an app context available, this + decorator is not required in that case. + + .. versionchanged:: 2.2 + The app context is active for subcommands as well as the + decorated callback. The app context is always available to + ``app.cli`` command and parameter callbacks. + """ + + @click.pass_context + def decorator(ctx: click.Context, /, *args: t.Any, **kwargs: t.Any) -> t.Any: + if not current_app: + app = ctx.ensure_object(ScriptInfo).load_app() + ctx.with_resource(app.app_context()) + + return ctx.invoke(f, *args, **kwargs) + + return update_wrapper(decorator, f) # type: ignore[return-value] + + +class AppGroup(click.Group): + """This works similar to a regular click :class:`~click.Group` but it + changes the behavior of the :meth:`command` decorator so that it + automatically wraps the functions in :func:`with_appcontext`. + + Not to be confused with :class:`FlaskGroup`. + """ + + def command( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Command]: + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it wraps callbacks in :func:`with_appcontext` + unless it's disabled by passing ``with_appcontext=False``. + """ + wrap_for_ctx = kwargs.pop("with_appcontext", True) + + def decorator(f: t.Callable[..., t.Any]) -> click.Command: + if wrap_for_ctx: + f = with_appcontext(f) + return super(AppGroup, self).command(*args, **kwargs)(f) # type: ignore[no-any-return] + + return decorator + + def group( # type: ignore[override] + self, *args: t.Any, **kwargs: t.Any + ) -> t.Callable[[t.Callable[..., t.Any]], click.Group]: + """This works exactly like the method of the same name on a regular + :class:`click.Group` but it defaults the group class to + :class:`AppGroup`. + """ + kwargs.setdefault("cls", AppGroup) + return super().group(*args, **kwargs) # type: ignore[no-any-return] + + +def _set_app(ctx: click.Context, param: click.Option, value: str | None) -> str | None: + if value is None: + return None + + info = ctx.ensure_object(ScriptInfo) + info.app_import_path = value + return value + + +# This option is eager so the app will be available if --help is given. +# --help is also eager, so --app must be before it in the param list. +# no_args_is_help bypasses eager processing, so this option must be +# processed manually in that case to ensure FLASK_APP gets picked up. +_app_option = click.Option( + ["-A", "--app"], + metavar="IMPORT", + help=( + "The Flask application or factory function to load, in the form 'module:name'." + " Module can be a dotted import or file path. Name is not required if it is" + " 'app', 'application', 'create_app', or 'make_app', and can be 'name(args)' to" + " pass arguments." + ), + is_eager=True, + expose_value=False, + callback=_set_app, +) + + +def _set_debug(ctx: click.Context, param: click.Option, value: bool) -> bool | None: + # If the flag isn't provided, it will default to False. Don't use + # that, let debug be set by env in that case. + source = ctx.get_parameter_source(param.name) # type: ignore[arg-type] + + if source is not None and source in ( + ParameterSource.DEFAULT, + ParameterSource.DEFAULT_MAP, + ): + return None + + # Set with env var instead of ScriptInfo.load so that it can be + # accessed early during a factory function. + os.environ["FLASK_DEBUG"] = "1" if value else "0" + return value + + +_debug_option = click.Option( + ["--debug/--no-debug"], + help="Set debug mode.", + expose_value=False, + callback=_set_debug, +) + + +def _env_file_callback( + ctx: click.Context, param: click.Option, value: str | None +) -> str | None: + try: + import dotenv # noqa: F401 + except ImportError: + # Only show an error if a value was passed, otherwise we still want to + # call load_dotenv and show a message without exiting. + if value is not None: + raise click.BadParameter( + "python-dotenv must be installed to load an env file.", + ctx=ctx, + param=param, + ) from None + + # Load if a value was passed, or we want to load default files, or both. + if value is not None or ctx.obj.load_dotenv_defaults: + load_dotenv(value, load_defaults=ctx.obj.load_dotenv_defaults) + + return value + + +# This option is eager so env vars are loaded as early as possible to be +# used by other options. +_env_file_option = click.Option( + ["-e", "--env-file"], + type=click.Path(exists=True, dir_okay=False), + help=( + "Load environment variables from this file, taking precedence over" + " those set by '.env' and '.flaskenv'. Variables set directly in the" + " environment take highest precedence. python-dotenv must be installed." + ), + is_eager=True, + expose_value=False, + callback=_env_file_callback, +) + + +class FlaskGroup(AppGroup): + """Special subclass of the :class:`AppGroup` group that supports + loading more commands from the configured Flask app. Normally a + developer does not have to interface with this class but there are + some very advanced use cases for which it makes sense to create an + instance of this. see :ref:`custom-scripts`. + + :param add_default_commands: if this is True then the default run and + shell commands will be added. + :param add_version_option: adds the ``--version`` option. + :param create_app: an optional callback that is passed the script info and + returns the loaded app. + :param load_dotenv: Load the nearest :file:`.env` and :file:`.flaskenv` + files to set environment variables. Will also change the working + directory to the directory containing the first file found. + :param set_debug_flag: Set the app's debug flag. + + .. versionchanged:: 3.1 + ``-e path`` takes precedence over default ``.env`` and ``.flaskenv`` files. + + .. versionchanged:: 2.2 + Added the ``-A/--app``, ``--debug/--no-debug``, ``-e/--env-file`` options. + + .. versionchanged:: 2.2 + An app context is pushed when running ``app.cli`` commands, so + ``@with_appcontext`` is no longer required for those commands. + + .. versionchanged:: 1.0 + If installed, python-dotenv will be used to load environment variables + from :file:`.env` and :file:`.flaskenv` files. + """ + + def __init__( + self, + add_default_commands: bool = True, + create_app: t.Callable[..., Flask] | None = None, + add_version_option: bool = True, + load_dotenv: bool = True, + set_debug_flag: bool = True, + **extra: t.Any, + ) -> None: + params: list[click.Parameter] = list(extra.pop("params", None) or ()) + # Processing is done with option callbacks instead of a group + # callback. This allows users to make a custom group callback + # without losing the behavior. --env-file must come first so + # that it is eagerly evaluated before --app. + params.extend((_env_file_option, _app_option, _debug_option)) + + if add_version_option: + params.append(version_option) + + if "context_settings" not in extra: + extra["context_settings"] = {} + + extra["context_settings"].setdefault("auto_envvar_prefix", "FLASK") + + super().__init__(params=params, **extra) + + self.create_app = create_app + self.load_dotenv = load_dotenv + self.set_debug_flag = set_debug_flag + + if add_default_commands: + self.add_command(run_command) + self.add_command(shell_command) + self.add_command(routes_command) + + self._loaded_plugin_commands = False + + def _load_plugin_commands(self) -> None: + if self._loaded_plugin_commands: + return + + if sys.version_info >= (3, 10): + from importlib import metadata + else: + # Use a backport on Python < 3.10. We technically have + # importlib.metadata on 3.8+, but the API changed in 3.10, + # so use the backport for consistency. + import importlib_metadata as metadata # pyright: ignore + + for ep in metadata.entry_points(group="flask.commands"): + self.add_command(ep.load(), ep.name) + + self._loaded_plugin_commands = True + + def get_command(self, ctx: click.Context, name: str) -> click.Command | None: + self._load_plugin_commands() + # Look up built-in and plugin commands, which should be + # available even if the app fails to load. + rv = super().get_command(ctx, name) + + if rv is not None: + return rv + + info = ctx.ensure_object(ScriptInfo) + + # Look up commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + app = info.load_app() + except NoAppException as e: + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + return None + + # Push an app context for the loaded app unless it is already + # active somehow. This makes the context available to parameter + # and command callbacks without needing @with_appcontext. + if not current_app or current_app._get_current_object() is not app: # type: ignore[attr-defined] + ctx.with_resource(app.app_context()) + + return app.cli.get_command(ctx, name) + + def list_commands(self, ctx: click.Context) -> list[str]: + self._load_plugin_commands() + # Start with the built-in and plugin commands. + rv = set(super().list_commands(ctx)) + info = ctx.ensure_object(ScriptInfo) + + # Add commands provided by the app, showing an error and + # continuing if the app couldn't be loaded. + try: + rv.update(info.load_app().cli.list_commands(ctx)) + except NoAppException as e: + # When an app couldn't be loaded, show the error message + # without the traceback. + click.secho(f"Error: {e.format_message()}\n", err=True, fg="red") + except Exception: + # When any other errors occurred during loading, show the + # full traceback. + click.secho(f"{traceback.format_exc()}\n", err=True, fg="red") + + return sorted(rv) + + def make_context( + self, + info_name: str | None, + args: list[str], + parent: click.Context | None = None, + **extra: t.Any, + ) -> click.Context: + # Set a flag to tell app.run to become a no-op. If app.run was + # not in a __name__ == __main__ guard, it would start the server + # when importing, blocking whatever command is being called. + os.environ["FLASK_RUN_FROM_CLI"] = "true" + + if "obj" not in extra and "obj" not in self.context_settings: + extra["obj"] = ScriptInfo( + create_app=self.create_app, + set_debug_flag=self.set_debug_flag, + load_dotenv_defaults=self.load_dotenv, + ) + + return super().make_context(info_name, args, parent=parent, **extra) + + def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: + if not args and self.no_args_is_help: + # Attempt to load --env-file and --app early in case they + # were given as env vars. Otherwise no_args_is_help will not + # see commands from app.cli. + _env_file_option.handle_parse_result(ctx, {}, []) + _app_option.handle_parse_result(ctx, {}, []) + + return super().parse_args(ctx, args) + + +def _path_is_ancestor(path: str, other: str) -> bool: + """Take ``other`` and remove the length of ``path`` from it. Then join it + to ``path``. If it is the original value, ``path`` is an ancestor of + ``other``.""" + return os.path.join(path, other[len(path) :].lstrip(os.sep)) == other + + +def load_dotenv( + path: str | os.PathLike[str] | None = None, load_defaults: bool = True +) -> bool: + """Load "dotenv" files to set environment variables. A given path takes + precedence over ``.env``, which takes precedence over ``.flaskenv``. After + loading and combining these files, values are only set if the key is not + already set in ``os.environ``. + + This is a no-op if `python-dotenv`_ is not installed. + + .. _python-dotenv: https://github.com/theskumar/python-dotenv#readme + + :param path: Load the file at this location. + :param load_defaults: Search for and load the default ``.flaskenv`` and + ``.env`` files. + :return: ``True`` if at least one env var was loaded. + + .. versionchanged:: 3.1 + Added the ``load_defaults`` parameter. A given path takes precedence + over default files. + + .. versionchanged:: 2.0 + The current directory is not changed to the location of the + loaded file. + + .. versionchanged:: 2.0 + When loading the env files, set the default encoding to UTF-8. + + .. versionchanged:: 1.1.0 + Returns ``False`` when python-dotenv is not installed, or when + the given path isn't a file. + + .. versionadded:: 1.0 + """ + try: + import dotenv + except ImportError: + if path or os.path.isfile(".env") or os.path.isfile(".flaskenv"): + click.secho( + " * Tip: There are .env files present. Install python-dotenv" + " to use them.", + fg="yellow", + err=True, + ) + + return False + + data: dict[str, str | None] = {} + + if load_defaults: + for default_name in (".flaskenv", ".env"): + if not (default_path := dotenv.find_dotenv(default_name, usecwd=True)): + continue + + data |= dotenv.dotenv_values(default_path, encoding="utf-8") + + if path is not None and os.path.isfile(path): + data |= dotenv.dotenv_values(path, encoding="utf-8") + + for key, value in data.items(): + if key in os.environ or value is None: + continue + + os.environ[key] = value + + return bool(data) # True if at least one env var was loaded. + + +def show_server_banner(debug: bool, app_import_path: str | None) -> None: + """Show extra startup messages the first time the server is run, + ignoring the reloader. + """ + if is_running_from_reloader(): + return + + if app_import_path is not None: + click.echo(f" * Serving Flask app '{app_import_path}'") + + if debug is not None: + click.echo(f" * Debug mode: {'on' if debug else 'off'}") + + +class CertParamType(click.ParamType): + """Click option type for the ``--cert`` option. Allows either an + existing file, the string ``'adhoc'``, or an import for a + :class:`~ssl.SSLContext` object. + """ + + name = "path" + + def __init__(self) -> None: + self.path_type = click.Path(exists=True, dir_okay=False, resolve_path=True) + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + try: + import ssl + except ImportError: + raise click.BadParameter( + 'Using "--cert" requires Python to be compiled with SSL support.', + ctx, + param, + ) from None + + try: + return self.path_type(value, param, ctx) + except click.BadParameter: + value = click.STRING(value, param, ctx).lower() + + if value == "adhoc": + try: + import cryptography # noqa: F401 + except ImportError: + raise click.BadParameter( + "Using ad-hoc certificates requires the cryptography library.", + ctx, + param, + ) from None + + return value + + obj = import_string(value, silent=True) + + if isinstance(obj, ssl.SSLContext): + return obj + + raise + + +def _validate_key(ctx: click.Context, param: click.Parameter, value: t.Any) -> t.Any: + """The ``--key`` option must be specified when ``--cert`` is a file. + Modifies the ``cert`` param to be a ``(cert, key)`` pair if needed. + """ + cert = ctx.params.get("cert") + is_adhoc = cert == "adhoc" + + try: + import ssl + except ImportError: + is_context = False + else: + is_context = isinstance(cert, ssl.SSLContext) + + if value is not None: + if is_adhoc: + raise click.BadParameter( + 'When "--cert" is "adhoc", "--key" is not used.', ctx, param + ) + + if is_context: + raise click.BadParameter( + 'When "--cert" is an SSLContext object, "--key" is not used.', + ctx, + param, + ) + + if not cert: + raise click.BadParameter('"--cert" must also be specified.', ctx, param) + + ctx.params["cert"] = cert, value + + else: + if cert and not (is_adhoc or is_context): + raise click.BadParameter('Required when using "--cert".', ctx, param) + + return value + + +class SeparatedPathType(click.Path): + """Click option type that accepts a list of values separated by the + OS's path separator (``:``, ``;`` on Windows). Each value is + validated as a :class:`click.Path` type. + """ + + def convert( + self, value: t.Any, param: click.Parameter | None, ctx: click.Context | None + ) -> t.Any: + items = self.split_envvar_value(value) + # can't call no-arg super() inside list comprehension until Python 3.12 + super_convert = super().convert + return [super_convert(item, param, ctx) for item in items] + + +@click.command("run", short_help="Run a development server.") +@click.option("--host", "-h", default="127.0.0.1", help="The interface to bind to.") +@click.option("--port", "-p", default=5000, help="The port to bind to.") +@click.option( + "--cert", + type=CertParamType(), + help="Specify a certificate file to use HTTPS.", + is_eager=True, +) +@click.option( + "--key", + type=click.Path(exists=True, dir_okay=False, resolve_path=True), + callback=_validate_key, + expose_value=False, + help="The key file to use when specifying a certificate.", +) +@click.option( + "--reload/--no-reload", + default=None, + help="Enable or disable the reloader. By default the reloader " + "is active if debug is enabled.", +) +@click.option( + "--debugger/--no-debugger", + default=None, + help="Enable or disable the debugger. By default the debugger " + "is active if debug is enabled.", +) +@click.option( + "--with-threads/--without-threads", + default=True, + help="Enable or disable multithreading.", +) +@click.option( + "--extra-files", + default=None, + type=SeparatedPathType(), + help=( + "Extra files that trigger a reload on change. Multiple paths" + f" are separated by {os.path.pathsep!r}." + ), +) +@click.option( + "--exclude-patterns", + default=None, + type=SeparatedPathType(), + help=( + "Files matching these fnmatch patterns will not trigger a reload" + " on change. Multiple patterns are separated by" + f" {os.path.pathsep!r}." + ), +) +@pass_script_info +def run_command( + info: ScriptInfo, + host: str, + port: int, + reload: bool, + debugger: bool, + with_threads: bool, + cert: ssl.SSLContext | tuple[str, str | None] | t.Literal["adhoc"] | None, + extra_files: list[str] | None, + exclude_patterns: list[str] | None, +) -> None: + """Run a local development server. + + This server is for development purposes only. It does not provide + the stability, security, or performance of production WSGI servers. + + The reloader and debugger are enabled by default with the '--debug' + option. + """ + try: + app: WSGIApplication = info.load_app() # pyright: ignore + except Exception as e: + if is_running_from_reloader(): + # When reloading, print out the error immediately, but raise + # it later so the debugger or server can handle it. + traceback.print_exc() + err = e + + def app( + environ: WSGIEnvironment, start_response: StartResponse + ) -> cabc.Iterable[bytes]: + raise err from None + + else: + # When not reloading, raise the error immediately so the + # command fails. + raise e from None + + debug = get_debug_flag() + + if reload is None: + reload = debug + + if debugger is None: + debugger = debug + + show_server_banner(debug, info.app_import_path) + + run_simple( + host, + port, + app, + use_reloader=reload, + use_debugger=debugger, + threaded=with_threads, + ssl_context=cert, + extra_files=extra_files, + exclude_patterns=exclude_patterns, + ) + + +run_command.params.insert(0, _debug_option) + + +@click.command("shell", short_help="Run a shell in the app context.") +@with_appcontext +def shell_command() -> None: + """Run an interactive Python shell in the context of a given + Flask application. The application will populate the default + namespace of this shell according to its configuration. + + This is useful for executing small snippets of management code + without having to manually configure the application. + """ + import code + + banner = ( + f"Python {sys.version} on {sys.platform}\n" + f"App: {current_app.import_name}\n" + f"Instance: {current_app.instance_path}" + ) + ctx: dict[str, t.Any] = {} + + # Support the regular Python interpreter startup script if someone + # is using it. + startup = os.environ.get("PYTHONSTARTUP") + if startup and os.path.isfile(startup): + with open(startup) as f: + eval(compile(f.read(), startup, "exec"), ctx) + + ctx.update(current_app.make_shell_context()) + + # Site, customize, or startup script can set a hook to call when + # entering interactive mode. The default one sets up readline with + # tab and history completion. + interactive_hook = getattr(sys, "__interactivehook__", None) + + if interactive_hook is not None: + try: + import readline + from rlcompleter import Completer + except ImportError: + pass + else: + # rlcompleter uses __main__.__dict__ by default, which is + # flask.__main__. Use the shell context instead. + readline.set_completer(Completer(ctx).complete) + + interactive_hook() + + code.interact(banner=banner, local=ctx) + + +@click.command("routes", short_help="Show the routes for the app.") +@click.option( + "--sort", + "-s", + type=click.Choice(("endpoint", "methods", "domain", "rule", "match")), + default="endpoint", + help=( + "Method to sort routes by. 'match' is the order that Flask will match routes" + " when dispatching a request." + ), +) +@click.option("--all-methods", is_flag=True, help="Show HEAD and OPTIONS methods.") +@with_appcontext +def routes_command(sort: str, all_methods: bool) -> None: + """Show all registered routes with endpoints and methods.""" + rules = list(current_app.url_map.iter_rules()) + + if not rules: + click.echo("No routes were registered.") + return + + ignored_methods = set() if all_methods else {"HEAD", "OPTIONS"} + host_matching = current_app.url_map.host_matching + has_domain = any(rule.host if host_matching else rule.subdomain for rule in rules) + rows = [] + + for rule in rules: + row = [ + rule.endpoint, + ", ".join(sorted((rule.methods or set()) - ignored_methods)), + ] + + if has_domain: + row.append((rule.host if host_matching else rule.subdomain) or "") + + row.append(rule.rule) + rows.append(row) + + headers = ["Endpoint", "Methods"] + sorts = ["endpoint", "methods"] + + if has_domain: + headers.append("Host" if host_matching else "Subdomain") + sorts.append("domain") + + headers.append("Rule") + sorts.append("rule") + + try: + rows.sort(key=itemgetter(sorts.index(sort))) + except ValueError: + pass + + rows.insert(0, headers) + widths = [max(len(row[i]) for row in rows) for i in range(len(headers))] + rows.insert(1, ["-" * w for w in widths]) + template = " ".join(f"{{{i}:<{w}}}" for i, w in enumerate(widths)) + + for row in rows: + click.echo(template.format(*row)) + + +cli = FlaskGroup( + name="flask", + help="""\ +A general utility script for Flask applications. + +An application to load must be given with the '--app' option, +'FLASK_APP' environment variable, or with a 'wsgi.py' or 'app.py' file +in the current directory. +""", +) + + +def main() -> None: + cli.main() + + +if __name__ == "__main__": + main() diff --git a/venv/lib/python3.12/site-packages/flask/config.py b/venv/lib/python3.12/site-packages/flask/config.py new file mode 100644 index 0000000..34ef1a5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/config.py @@ -0,0 +1,367 @@ +from __future__ import annotations + +import errno +import json +import os +import types +import typing as t + +from werkzeug.utils import import_string + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .sansio.app import App + + +T = t.TypeVar("T") + + +class ConfigAttribute(t.Generic[T]): + """Makes an attribute forward to the config""" + + def __init__( + self, name: str, get_converter: t.Callable[[t.Any], T] | None = None + ) -> None: + self.__name__ = name + self.get_converter = get_converter + + @t.overload + def __get__(self, obj: None, owner: None) -> te.Self: ... + + @t.overload + def __get__(self, obj: App, owner: type[App]) -> T: ... + + def __get__(self, obj: App | None, owner: type[App] | None = None) -> T | te.Self: + if obj is None: + return self + + rv = obj.config[self.__name__] + + if self.get_converter is not None: + rv = self.get_converter(rv) + + return rv # type: ignore[no-any-return] + + def __set__(self, obj: App, value: t.Any) -> None: + obj.config[self.__name__] = value + + +class Config(dict): # type: ignore[type-arg] + """Works exactly like a dict but provides ways to fill it from files + or special dictionaries. There are two common patterns to populate the + config. + + Either you can fill the config from a config file:: + + app.config.from_pyfile('yourconfig.cfg') + + Or alternatively you can define the configuration options in the + module that calls :meth:`from_object` or provide an import path to + a module that should be loaded. It is also possible to tell it to + use the same module and with that provide the configuration values + just before the call:: + + DEBUG = True + SECRET_KEY = 'development key' + app.config.from_object(__name__) + + In both cases (loading from any Python file or loading from modules), + only uppercase keys are added to the config. This makes it possible to use + lowercase values in the config file for temporary values that are not added + to the config or to define the config keys in the same file that implements + the application. + + Probably the most interesting way to load configurations is from an + environment variable pointing to a file:: + + app.config.from_envvar('YOURAPPLICATION_SETTINGS') + + In this case before launching the application you have to set this + environment variable to the file you want to use. On Linux and OS X + use the export statement:: + + export YOURAPPLICATION_SETTINGS='/path/to/config/file' + + On windows use `set` instead. + + :param root_path: path to which files are read relative from. When the + config object is created by the application, this is + the application's :attr:`~flask.Flask.root_path`. + :param defaults: an optional dictionary of default values + """ + + def __init__( + self, + root_path: str | os.PathLike[str], + defaults: dict[str, t.Any] | None = None, + ) -> None: + super().__init__(defaults or {}) + self.root_path = root_path + + def from_envvar(self, variable_name: str, silent: bool = False) -> bool: + """Loads a configuration from an environment variable pointing to + a configuration file. This is basically just a shortcut with nicer + error messages for this line of code:: + + app.config.from_pyfile(os.environ['YOURAPPLICATION_SETTINGS']) + + :param variable_name: name of the environment variable + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + """ + rv = os.environ.get(variable_name) + if not rv: + if silent: + return False + raise RuntimeError( + f"The environment variable {variable_name!r} is not set" + " and as such configuration could not be loaded. Set" + " this variable and make it point to a configuration" + " file" + ) + return self.from_pyfile(rv, silent=silent) + + def from_prefixed_env( + self, prefix: str = "FLASK", *, loads: t.Callable[[str], t.Any] = json.loads + ) -> bool: + """Load any environment variables that start with ``FLASK_``, + dropping the prefix from the env key for the config key. Values + are passed through a loading function to attempt to convert them + to more specific types than strings. + + Keys are loaded in :func:`sorted` order. + + The default loading function attempts to parse values as any + valid JSON type, including dicts and lists. + + Specific items in nested dicts can be set by separating the + keys with double underscores (``__``). If an intermediate key + doesn't exist, it will be initialized to an empty dict. + + :param prefix: Load env vars that start with this prefix, + separated with an underscore (``_``). + :param loads: Pass each string value to this function and use + the returned value as the config value. If any error is + raised it is ignored and the value remains a string. The + default is :func:`json.loads`. + + .. versionadded:: 2.1 + """ + prefix = f"{prefix}_" + + for key in sorted(os.environ): + if not key.startswith(prefix): + continue + + value = os.environ[key] + key = key.removeprefix(prefix) + + try: + value = loads(value) + except Exception: + # Keep the value as a string if loading failed. + pass + + if "__" not in key: + # A non-nested key, set directly. + self[key] = value + continue + + # Traverse nested dictionaries with keys separated by "__". + current = self + *parts, tail = key.split("__") + + for part in parts: + # If an intermediate dict does not exist, create it. + if part not in current: + current[part] = {} + + current = current[part] + + current[tail] = value + + return True + + def from_pyfile( + self, filename: str | os.PathLike[str], silent: bool = False + ) -> bool: + """Updates the values in the config from a Python file. This function + behaves as if the file was imported as module with the + :meth:`from_object` function. + + :param filename: the filename of the config. This can either be an + absolute filename or a filename relative to the + root path. + :param silent: set to ``True`` if you want silent failure for missing + files. + :return: ``True`` if the file was loaded successfully. + + .. versionadded:: 0.7 + `silent` parameter. + """ + filename = os.path.join(self.root_path, filename) + d = types.ModuleType("config") + d.__file__ = filename + try: + with open(filename, mode="rb") as config_file: + exec(compile(config_file.read(), filename, "exec"), d.__dict__) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR, errno.ENOTDIR): + return False + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + self.from_object(d) + return True + + def from_object(self, obj: object | str) -> None: + """Updates the values from the given object. An object can be of one + of the following two types: + + - a string: in this case the object with that name will be imported + - an actual object reference: that object is used directly + + Objects are usually either modules or classes. :meth:`from_object` + loads only the uppercase attributes of the module/class. A ``dict`` + object will not work with :meth:`from_object` because the keys of a + ``dict`` are not attributes of the ``dict`` class. + + Example of module-based configuration:: + + app.config.from_object('yourapplication.default_config') + from yourapplication import default_config + app.config.from_object(default_config) + + Nothing is done to the object before loading. If the object is a + class and has ``@property`` attributes, it needs to be + instantiated before being passed to this method. + + You should not use this function to load the actual configuration but + rather configuration defaults. The actual config should be loaded + with :meth:`from_pyfile` and ideally from a location not within the + package because the package might be installed system wide. + + See :ref:`config-dev-prod` for an example of class-based configuration + using :meth:`from_object`. + + :param obj: an import name or object + """ + if isinstance(obj, str): + obj = import_string(obj) + for key in dir(obj): + if key.isupper(): + self[key] = getattr(obj, key) + + def from_file( + self, + filename: str | os.PathLike[str], + load: t.Callable[[t.IO[t.Any]], t.Mapping[str, t.Any]], + silent: bool = False, + text: bool = True, + ) -> bool: + """Update the values in the config from a file that is loaded + using the ``load`` parameter. The loaded data is passed to the + :meth:`from_mapping` method. + + .. code-block:: python + + import json + app.config.from_file("config.json", load=json.load) + + import tomllib + app.config.from_file("config.toml", load=tomllib.load, text=False) + + :param filename: The path to the data file. This can be an + absolute path or relative to the config root path. + :param load: A callable that takes a file handle and returns a + mapping of loaded data from the file. + :type load: ``Callable[[Reader], Mapping]`` where ``Reader`` + implements a ``read`` method. + :param silent: Ignore the file if it doesn't exist. + :param text: Open the file in text or binary mode. + :return: ``True`` if the file was loaded successfully. + + .. versionchanged:: 2.3 + The ``text`` parameter was added. + + .. versionadded:: 2.0 + """ + filename = os.path.join(self.root_path, filename) + + try: + with open(filename, "r" if text else "rb") as f: + obj = load(f) + except OSError as e: + if silent and e.errno in (errno.ENOENT, errno.EISDIR): + return False + + e.strerror = f"Unable to load configuration file ({e.strerror})" + raise + + return self.from_mapping(obj) + + def from_mapping( + self, mapping: t.Mapping[str, t.Any] | None = None, **kwargs: t.Any + ) -> bool: + """Updates the config like :meth:`update` ignoring items with + non-upper keys. + + :return: Always returns ``True``. + + .. versionadded:: 0.11 + """ + mappings: dict[str, t.Any] = {} + if mapping is not None: + mappings.update(mapping) + mappings.update(kwargs) + for key, value in mappings.items(): + if key.isupper(): + self[key] = value + return True + + def get_namespace( + self, namespace: str, lowercase: bool = True, trim_namespace: bool = True + ) -> dict[str, t.Any]: + """Returns a dictionary containing a subset of configuration options + that match the specified namespace/prefix. Example usage:: + + app.config['IMAGE_STORE_TYPE'] = 'fs' + app.config['IMAGE_STORE_PATH'] = '/var/app/images' + app.config['IMAGE_STORE_BASE_URL'] = 'http://img.website.com' + image_store_config = app.config.get_namespace('IMAGE_STORE_') + + The resulting dictionary `image_store_config` would look like:: + + { + 'type': 'fs', + 'path': '/var/app/images', + 'base_url': 'http://img.website.com' + } + + This is often useful when configuration options map directly to + keyword arguments in functions or class constructors. + + :param namespace: a configuration namespace + :param lowercase: a flag indicating if the keys of the resulting + dictionary should be lowercase + :param trim_namespace: a flag indicating if the keys of the resulting + dictionary should not include the namespace + + .. versionadded:: 0.11 + """ + rv = {} + for k, v in self.items(): + if not k.startswith(namespace): + continue + if trim_namespace: + key = k[len(namespace) :] + else: + key = k + if lowercase: + key = key.lower() + rv[key] = v + return rv + + def __repr__(self) -> str: + return f"<{type(self).__name__} {dict.__repr__(self)}>" diff --git a/venv/lib/python3.12/site-packages/flask/ctx.py b/venv/lib/python3.12/site-packages/flask/ctx.py new file mode 100644 index 0000000..9b164d3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/ctx.py @@ -0,0 +1,449 @@ +from __future__ import annotations + +import contextvars +import sys +import typing as t +from functools import update_wrapper +from types import TracebackType + +from werkzeug.exceptions import HTTPException + +from . import typing as ft +from .globals import _cv_app +from .globals import _cv_request +from .signals import appcontext_popped +from .signals import appcontext_pushed + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIEnvironment + + from .app import Flask + from .sessions import SessionMixin + from .wrappers import Request + + +# a singleton sentinel value for parameter defaults +_sentinel = object() + + +class _AppCtxGlobals: + """A plain object. Used as a namespace for storing data during an + application context. + + Creating an app context automatically creates this object, which is + made available as the :data:`g` proxy. + + .. describe:: 'key' in g + + Check whether an attribute is present. + + .. versionadded:: 0.10 + + .. describe:: iter(g) + + Return an iterator over the attribute names. + + .. versionadded:: 0.10 + """ + + # Define attr methods to let mypy know this is a namespace object + # that has arbitrary attributes. + + def __getattr__(self, name: str) -> t.Any: + try: + return self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def __setattr__(self, name: str, value: t.Any) -> None: + self.__dict__[name] = value + + def __delattr__(self, name: str) -> None: + try: + del self.__dict__[name] + except KeyError: + raise AttributeError(name) from None + + def get(self, name: str, default: t.Any | None = None) -> t.Any: + """Get an attribute by name, or a default value. Like + :meth:`dict.get`. + + :param name: Name of attribute to get. + :param default: Value to return if the attribute is not present. + + .. versionadded:: 0.10 + """ + return self.__dict__.get(name, default) + + def pop(self, name: str, default: t.Any = _sentinel) -> t.Any: + """Get and remove an attribute by name. Like :meth:`dict.pop`. + + :param name: Name of attribute to pop. + :param default: Value to return if the attribute is not present, + instead of raising a ``KeyError``. + + .. versionadded:: 0.11 + """ + if default is _sentinel: + return self.__dict__.pop(name) + else: + return self.__dict__.pop(name, default) + + def setdefault(self, name: str, default: t.Any = None) -> t.Any: + """Get the value of an attribute if it is present, otherwise + set and return a default value. Like :meth:`dict.setdefault`. + + :param name: Name of attribute to get. + :param default: Value to set and return if the attribute is not + present. + + .. versionadded:: 0.11 + """ + return self.__dict__.setdefault(name, default) + + def __contains__(self, item: str) -> bool: + return item in self.__dict__ + + def __iter__(self) -> t.Iterator[str]: + return iter(self.__dict__) + + def __repr__(self) -> str: + ctx = _cv_app.get(None) + if ctx is not None: + return f"" + return object.__repr__(self) + + +def after_this_request( + f: ft.AfterRequestCallable[t.Any], +) -> ft.AfterRequestCallable[t.Any]: + """Executes a function after this request. This is useful to modify + response objects. The function is passed the response object and has + to return the same or a new one. + + Example:: + + @app.route('/') + def index(): + @after_this_request + def add_header(response): + response.headers['X-Foo'] = 'Parachute' + return response + return 'Hello World!' + + This is more useful if a function other than the view function wants to + modify a response. For instance think of a decorator that wants to add + some headers without converting the return value into a response object. + + .. versionadded:: 0.9 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'after_this_request' can only be used when a request" + " context is active, such as in a view function." + ) + + ctx._after_request_functions.append(f) + return f + + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + + +def copy_current_request_context(f: F) -> F: + """A helper function that decorates a function to retain the current + request context. This is useful when working with greenlets. The moment + the function is decorated a copy of the request context is created and + then pushed when the function is called. The current session is also + included in the copied request context. + + Example:: + + import gevent + from flask import copy_current_request_context + + @app.route('/') + def index(): + @copy_current_request_context + def do_some_work(): + # do some work here, it can access flask.request or + # flask.session like you would otherwise in the view function. + ... + gevent.spawn(do_some_work) + return 'Regular response' + + .. versionadded:: 0.10 + """ + ctx = _cv_request.get(None) + + if ctx is None: + raise RuntimeError( + "'copy_current_request_context' can only be used when a" + " request context is active, such as in a view function." + ) + + ctx = ctx.copy() + + def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any: + with ctx: # type: ignore[union-attr] + return ctx.app.ensure_sync(f)(*args, **kwargs) # type: ignore[union-attr] + + return update_wrapper(wrapper, f) # type: ignore[return-value] + + +def has_request_context() -> bool: + """If you have code that wants to test if a request context is there or + not this function can be used. For instance, you may want to take advantage + of request information if the request object is available, but fail + silently if it is unavailable. + + :: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and has_request_context(): + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + Alternatively you can also just test any of the context bound objects + (such as :class:`request` or :class:`g`) for truthness:: + + class User(db.Model): + + def __init__(self, username, remote_addr=None): + self.username = username + if remote_addr is None and request: + remote_addr = request.remote_addr + self.remote_addr = remote_addr + + .. versionadded:: 0.7 + """ + return _cv_request.get(None) is not None + + +def has_app_context() -> bool: + """Works like :func:`has_request_context` but for the application + context. You can also just do a boolean check on the + :data:`current_app` object instead. + + .. versionadded:: 0.9 + """ + return _cv_app.get(None) is not None + + +class AppContext: + """The app context contains application-specific information. An app + context is created and pushed at the beginning of each request if + one is not already active. An app context is also pushed when + running CLI commands. + """ + + def __init__(self, app: Flask) -> None: + self.app = app + self.url_adapter = app.create_url_adapter(None) + self.g: _AppCtxGlobals = app.app_ctx_globals_class() + self._cv_tokens: list[contextvars.Token[AppContext]] = [] + + def push(self) -> None: + """Binds the app context to the current context.""" + self._cv_tokens.append(_cv_app.set(self)) + appcontext_pushed.send(self.app, _async_wrapper=self.app.ensure_sync) + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the app context.""" + try: + if len(self._cv_tokens) == 1: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_appcontext(exc) + finally: + ctx = _cv_app.get() + _cv_app.reset(self._cv_tokens.pop()) + + if ctx is not self: + raise AssertionError( + f"Popped wrong app context. ({ctx!r} instead of {self!r})" + ) + + appcontext_popped.send(self.app, _async_wrapper=self.app.ensure_sync) + + def __enter__(self) -> AppContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + +class RequestContext: + """The request context contains per-request information. The Flask + app creates and pushes it at the beginning of the request, then pops + it at the end of the request. It will create the URL adapter and + request object for the WSGI environment provided. + + Do not attempt to use this class directly, instead use + :meth:`~flask.Flask.test_request_context` and + :meth:`~flask.Flask.request_context` to create this object. + + When the request context is popped, it will evaluate all the + functions registered on the application for teardown execution + (:meth:`~flask.Flask.teardown_request`). + + The request context is automatically popped at the end of the + request. When using the interactive debugger, the context will be + restored so ``request`` is still accessible. Similarly, the test + client can preserve the context after the request ends. However, + teardown functions may already have closed some resources such as + database connections. + """ + + def __init__( + self, + app: Flask, + environ: WSGIEnvironment, + request: Request | None = None, + session: SessionMixin | None = None, + ) -> None: + self.app = app + if request is None: + request = app.request_class(environ) + request.json_module = app.json + self.request: Request = request + self.url_adapter = None + try: + self.url_adapter = app.create_url_adapter(self.request) + except HTTPException as e: + self.request.routing_exception = e + self.flashes: list[tuple[str, str]] | None = None + self.session: SessionMixin | None = session + # Functions that should be executed after the request on the response + # object. These will be called before the regular "after_request" + # functions. + self._after_request_functions: list[ft.AfterRequestCallable[t.Any]] = [] + + self._cv_tokens: list[ + tuple[contextvars.Token[RequestContext], AppContext | None] + ] = [] + + def copy(self) -> RequestContext: + """Creates a copy of this request context with the same request object. + This can be used to move a request context to a different greenlet. + Because the actual request object is the same this cannot be used to + move a request context to a different thread unless access to the + request object is locked. + + .. versionadded:: 0.10 + + .. versionchanged:: 1.1 + The current session object is used instead of reloading the original + data. This prevents `flask.session` pointing to an out-of-date object. + """ + return self.__class__( + self.app, + environ=self.request.environ, + request=self.request, + session=self.session, + ) + + def match_request(self) -> None: + """Can be overridden by a subclass to hook into the matching + of the request. + """ + try: + result = self.url_adapter.match(return_rule=True) # type: ignore + self.request.url_rule, self.request.view_args = result # type: ignore + except HTTPException as e: + self.request.routing_exception = e + + def push(self) -> None: + # Before we push the request context we have to ensure that there + # is an application context. + app_ctx = _cv_app.get(None) + + if app_ctx is None or app_ctx.app is not self.app: + app_ctx = self.app.app_context() + app_ctx.push() + else: + app_ctx = None + + self._cv_tokens.append((_cv_request.set(self), app_ctx)) + + # Open the session at the moment that the request context is available. + # This allows a custom open_session method to use the request context. + # Only open a new session if this is the first time the request was + # pushed, otherwise stream_with_context loses the session. + if self.session is None: + session_interface = self.app.session_interface + self.session = session_interface.open_session(self.app, self.request) + + if self.session is None: + self.session = session_interface.make_null_session(self.app) + + # Match the request URL after loading the session, so that the + # session is available in custom URL converters. + if self.url_adapter is not None: + self.match_request() + + def pop(self, exc: BaseException | None = _sentinel) -> None: # type: ignore + """Pops the request context and unbinds it by doing that. This will + also trigger the execution of functions registered by the + :meth:`~flask.Flask.teardown_request` decorator. + + .. versionchanged:: 0.9 + Added the `exc` argument. + """ + clear_request = len(self._cv_tokens) == 1 + + try: + if clear_request: + if exc is _sentinel: + exc = sys.exc_info()[1] + self.app.do_teardown_request(exc) + + request_close = getattr(self.request, "close", None) + if request_close is not None: + request_close() + finally: + ctx = _cv_request.get() + token, app_ctx = self._cv_tokens.pop() + _cv_request.reset(token) + + # get rid of circular dependencies at the end of the request + # so that we don't require the GC to be active. + if clear_request: + ctx.request.environ["werkzeug.request"] = None + + if app_ctx is not None: + app_ctx.pop(exc) + + if ctx is not self: + raise AssertionError( + f"Popped wrong request context. ({ctx!r} instead of {self!r})" + ) + + def __enter__(self) -> RequestContext: + self.push() + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.pop(exc_value) + + def __repr__(self) -> str: + return ( + f"<{type(self).__name__} {self.request.url!r}" + f" [{self.request.method}] of {self.app.name}>" + ) diff --git a/venv/lib/python3.12/site-packages/flask/debughelpers.py b/venv/lib/python3.12/site-packages/flask/debughelpers.py new file mode 100644 index 0000000..2c8c4c4 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/debughelpers.py @@ -0,0 +1,178 @@ +from __future__ import annotations + +import typing as t + +from jinja2.loaders import BaseLoader +from werkzeug.routing import RequestRedirect + +from .blueprints import Blueprint +from .globals import request_ctx +from .sansio.app import App + +if t.TYPE_CHECKING: + from .sansio.scaffold import Scaffold + from .wrappers import Request + + +class UnexpectedUnicodeError(AssertionError, UnicodeError): + """Raised in places where we want some better error reporting for + unexpected unicode or binary data. + """ + + +class DebugFilesKeyError(KeyError, AssertionError): + """Raised from request.files during debugging. The idea is that it can + provide a better error message than just a generic KeyError/BadRequest. + """ + + def __init__(self, request: Request, key: str) -> None: + form_matches = request.form.getlist(key) + buf = [ + f"You tried to access the file {key!r} in the request.files" + " dictionary but it does not exist. The mimetype for the" + f" request is {request.mimetype!r} instead of" + " 'multipart/form-data' which means that no file contents" + " were transmitted. To fix this error you should provide" + ' enctype="multipart/form-data" in your form.' + ] + if form_matches: + names = ", ".join(repr(x) for x in form_matches) + buf.append( + "\n\nThe browser instead transmitted some file names. " + f"This was submitted: {names}" + ) + self.msg = "".join(buf) + + def __str__(self) -> str: + return self.msg + + +class FormDataRoutingRedirect(AssertionError): + """This exception is raised in debug mode if a routing redirect + would cause the browser to drop the method or body. This happens + when method is not GET, HEAD or OPTIONS and the status code is not + 307 or 308. + """ + + def __init__(self, request: Request) -> None: + exc = request.routing_exception + assert isinstance(exc, RequestRedirect) + buf = [ + f"A request was sent to '{request.url}', but routing issued" + f" a redirect to the canonical URL '{exc.new_url}'." + ] + + if f"{request.base_url}/" == exc.new_url.partition("?")[0]: + buf.append( + " The URL was defined with a trailing slash. Flask" + " will redirect to the URL with a trailing slash if it" + " was accessed without one." + ) + + buf.append( + " Send requests to the canonical URL, or use 307 or 308 for" + " routing redirects. Otherwise, browsers will drop form" + " data.\n\n" + "This exception is only raised in debug mode." + ) + super().__init__("".join(buf)) + + +def attach_enctype_error_multidict(request: Request) -> None: + """Patch ``request.files.__getitem__`` to raise a descriptive error + about ``enctype=multipart/form-data``. + + :param request: The request to patch. + :meta private: + """ + oldcls = request.files.__class__ + + class newcls(oldcls): # type: ignore[valid-type, misc] + def __getitem__(self, key: str) -> t.Any: + try: + return super().__getitem__(key) + except KeyError as e: + if key not in request.form: + raise + + raise DebugFilesKeyError(request, key).with_traceback( + e.__traceback__ + ) from None + + newcls.__name__ = oldcls.__name__ + newcls.__module__ = oldcls.__module__ + request.files.__class__ = newcls + + +def _dump_loader_info(loader: BaseLoader) -> t.Iterator[str]: + yield f"class: {type(loader).__module__}.{type(loader).__name__}" + for key, value in sorted(loader.__dict__.items()): + if key.startswith("_"): + continue + if isinstance(value, (tuple, list)): + if not all(isinstance(x, str) for x in value): + continue + yield f"{key}:" + for item in value: + yield f" - {item}" + continue + elif not isinstance(value, (str, int, float, bool)): + continue + yield f"{key}: {value!r}" + + +def explain_template_loading_attempts( + app: App, + template: str, + attempts: list[ + tuple[ + BaseLoader, + Scaffold, + tuple[str, str | None, t.Callable[[], bool] | None] | None, + ] + ], +) -> None: + """This should help developers understand what failed""" + info = [f"Locating template {template!r}:"] + total_found = 0 + blueprint = None + if request_ctx and request_ctx.request.blueprint is not None: + blueprint = request_ctx.request.blueprint + + for idx, (loader, srcobj, triple) in enumerate(attempts): + if isinstance(srcobj, App): + src_info = f"application {srcobj.import_name!r}" + elif isinstance(srcobj, Blueprint): + src_info = f"blueprint {srcobj.name!r} ({srcobj.import_name})" + else: + src_info = repr(srcobj) + + info.append(f"{idx + 1:5}: trying loader of {src_info}") + + for line in _dump_loader_info(loader): + info.append(f" {line}") + + if triple is None: + detail = "no match" + else: + detail = f"found ({triple[1] or ''!r})" + total_found += 1 + info.append(f" -> {detail}") + + seems_fishy = False + if total_found == 0: + info.append("Error: the template could not be found.") + seems_fishy = True + elif total_found > 1: + info.append("Warning: multiple loaders returned a match for the template.") + seems_fishy = True + + if blueprint is not None and seems_fishy: + info.append( + " The template was looked up from an endpoint that belongs" + f" to the blueprint {blueprint!r}." + ) + info.append(" Maybe you did not place a template in the right folder?") + info.append(" See https://flask.palletsprojects.com/blueprints/#templates") + + app.logger.info("\n".join(info)) diff --git a/venv/lib/python3.12/site-packages/flask/globals.py b/venv/lib/python3.12/site-packages/flask/globals.py new file mode 100644 index 0000000..e2c410c --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/globals.py @@ -0,0 +1,51 @@ +from __future__ import annotations + +import typing as t +from contextvars import ContextVar + +from werkzeug.local import LocalProxy + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .ctx import _AppCtxGlobals + from .ctx import AppContext + from .ctx import RequestContext + from .sessions import SessionMixin + from .wrappers import Request + + +_no_app_msg = """\ +Working outside of application context. + +This typically means that you attempted to use functionality that needed +the current application. To solve this, set up an application context +with app.app_context(). See the documentation for more information.\ +""" +_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx") +app_ctx: AppContext = LocalProxy( # type: ignore[assignment] + _cv_app, unbound_message=_no_app_msg +) +current_app: Flask = LocalProxy( # type: ignore[assignment] + _cv_app, "app", unbound_message=_no_app_msg +) +g: _AppCtxGlobals = LocalProxy( # type: ignore[assignment] + _cv_app, "g", unbound_message=_no_app_msg +) + +_no_req_msg = """\ +Working outside of request context. + +This typically means that you attempted to use functionality that needed +an active HTTP request. Consult the documentation on testing for +information about how to avoid this problem.\ +""" +_cv_request: ContextVar[RequestContext] = ContextVar("flask.request_ctx") +request_ctx: RequestContext = LocalProxy( # type: ignore[assignment] + _cv_request, unbound_message=_no_req_msg +) +request: Request = LocalProxy( # type: ignore[assignment] + _cv_request, "request", unbound_message=_no_req_msg +) +session: SessionMixin = LocalProxy( # type: ignore[assignment] + _cv_request, "session", unbound_message=_no_req_msg +) diff --git a/venv/lib/python3.12/site-packages/flask/helpers.py b/venv/lib/python3.12/site-packages/flask/helpers.py new file mode 100644 index 0000000..a6b7e15 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/helpers.py @@ -0,0 +1,634 @@ +from __future__ import annotations + +import importlib.util +import os +import sys +import typing as t +from datetime import datetime +from functools import cache +from functools import update_wrapper + +import werkzeug.utils +from werkzeug.exceptions import abort as _wz_abort +from werkzeug.utils import redirect as _wz_redirect +from werkzeug.wrappers import Response as BaseResponse + +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .globals import request_ctx +from .globals import session +from .signals import message_flashed + +if t.TYPE_CHECKING: # pragma: no cover + from .wrappers import Response + + +def get_debug_flag() -> bool: + """Get whether debug mode should be enabled for the app, indicated by the + :envvar:`FLASK_DEBUG` environment variable. The default is ``False``. + """ + val = os.environ.get("FLASK_DEBUG") + return bool(val and val.lower() not in {"0", "false", "no"}) + + +def get_load_dotenv(default: bool = True) -> bool: + """Get whether the user has disabled loading default dotenv files by + setting :envvar:`FLASK_SKIP_DOTENV`. The default is ``True``, load + the files. + + :param default: What to return if the env var isn't set. + """ + val = os.environ.get("FLASK_SKIP_DOTENV") + + if not val: + return default + + return val.lower() in ("0", "false", "no") + + +@t.overload +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr], +) -> t.Iterator[t.AnyStr]: ... + + +@t.overload +def stream_with_context( + generator_or_function: t.Callable[..., t.Iterator[t.AnyStr]], +) -> t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]: ... + + +def stream_with_context( + generator_or_function: t.Iterator[t.AnyStr] | t.Callable[..., t.Iterator[t.AnyStr]], +) -> t.Iterator[t.AnyStr] | t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]: + """Request contexts disappear when the response is started on the server. + This is done for efficiency reasons and to make it less likely to encounter + memory leaks with badly written WSGI middlewares. The downside is that if + you are using streamed responses, the generator cannot access request bound + information any more. + + This function however can help you keep the context around for longer:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + @stream_with_context + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(generate()) + + Alternatively it can also be used around a specific generator:: + + from flask import stream_with_context, request, Response + + @app.route('/stream') + def streamed_response(): + def generate(): + yield 'Hello ' + yield request.args['name'] + yield '!' + return Response(stream_with_context(generate())) + + .. versionadded:: 0.9 + """ + try: + gen = iter(generator_or_function) # type: ignore[arg-type] + except TypeError: + + def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any: + gen = generator_or_function(*args, **kwargs) # type: ignore[operator] + return stream_with_context(gen) + + return update_wrapper(decorator, generator_or_function) # type: ignore[arg-type] + + def generator() -> t.Iterator[t.AnyStr | None]: + ctx = _cv_request.get(None) + if ctx is None: + raise RuntimeError( + "'stream_with_context' can only be used when a request" + " context is active, such as in a view function." + ) + with ctx: + # Dummy sentinel. Has to be inside the context block or we're + # not actually keeping the context around. + yield None + + # The try/finally is here so that if someone passes a WSGI level + # iterator in we're still running the cleanup logic. Generators + # don't need that because they are closed on their destruction + # automatically. + try: + yield from gen + finally: + if hasattr(gen, "close"): + gen.close() + + # The trick is to start the generator. Then the code execution runs until + # the first dummy None is yielded at which point the context was already + # pushed. This item is discarded. Then when the iteration continues the + # real generator is executed. + wrapped_g = generator() + next(wrapped_g) + return wrapped_g # type: ignore[return-value] + + +def make_response(*args: t.Any) -> Response: + """Sometimes it is necessary to set additional headers in a view. Because + views do not have to return response objects but can return a value that + is converted into a response object by Flask itself, it becomes tricky to + add headers to it. This function can be called instead of using a return + and you will get a response object which you can use to attach headers. + + If view looked like this and you want to add a new header:: + + def index(): + return render_template('index.html', foo=42) + + You can now do something like this:: + + def index(): + response = make_response(render_template('index.html', foo=42)) + response.headers['X-Parachutes'] = 'parachutes are cool' + return response + + This function accepts the very same arguments you can return from a + view function. This for example creates a response with a 404 error + code:: + + response = make_response(render_template('not_found.html'), 404) + + The other use case of this function is to force the return value of a + view function into a response which is helpful with view + decorators:: + + response = make_response(view_function()) + response.headers['X-Parachutes'] = 'parachutes are cool' + + Internally this function does the following things: + + - if no arguments are passed, it creates a new response argument + - if one argument is passed, :meth:`flask.Flask.make_response` + is invoked with it. + - if more than one argument is passed, the arguments are passed + to the :meth:`flask.Flask.make_response` function as tuple. + + .. versionadded:: 0.6 + """ + if not args: + return current_app.response_class() + if len(args) == 1: + args = args[0] + return current_app.make_response(args) + + +def url_for( + endpoint: str, + *, + _anchor: str | None = None, + _method: str | None = None, + _scheme: str | None = None, + _external: bool | None = None, + **values: t.Any, +) -> str: + """Generate a URL to the given endpoint with the given values. + + This requires an active request or application context, and calls + :meth:`current_app.url_for() `. See that method + for full documentation. + + :param endpoint: The endpoint name associated with the URL to + generate. If this starts with a ``.``, the current blueprint + name (if any) will be used. + :param _anchor: If given, append this as ``#anchor`` to the URL. + :param _method: If given, generate the URL associated with this + method for the endpoint. + :param _scheme: If given, the URL will have this scheme if it is + external. + :param _external: If given, prefer the URL to be internal (False) or + require it to be external (True). External URLs include the + scheme and domain. When not in an active request, URLs are + external by default. + :param values: Values to use for the variable parts of the URL rule. + Unknown keys are appended as query string arguments, like + ``?a=b&c=d``. + + .. versionchanged:: 2.2 + Calls ``current_app.url_for``, allowing an app to override the + behavior. + + .. versionchanged:: 0.10 + The ``_scheme`` parameter was added. + + .. versionchanged:: 0.9 + The ``_anchor`` and ``_method`` parameters were added. + + .. versionchanged:: 0.9 + Calls ``app.handle_url_build_error`` on build errors. + """ + return current_app.url_for( + endpoint, + _anchor=_anchor, + _method=_method, + _scheme=_scheme, + _external=_external, + **values, + ) + + +def redirect( + location: str, code: int = 302, Response: type[BaseResponse] | None = None +) -> BaseResponse: + """Create a redirect response object. + + If :data:`~flask.current_app` is available, it will use its + :meth:`~flask.Flask.redirect` method, otherwise it will use + :func:`werkzeug.utils.redirect`. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + :param Response: The response class to use. Not used when + ``current_app`` is active, which uses ``app.response_class``. + + .. versionadded:: 2.2 + Calls ``current_app.redirect`` if available instead of always + using Werkzeug's default ``redirect``. + """ + if current_app: + return current_app.redirect(location, code=code) + + return _wz_redirect(location, code=code, Response=Response) + + +def abort(code: int | BaseResponse, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + """Raise an :exc:`~werkzeug.exceptions.HTTPException` for the given + status code. + + If :data:`~flask.current_app` is available, it will call its + :attr:`~flask.Flask.aborter` object, otherwise it will use + :func:`werkzeug.exceptions.abort`. + + :param code: The status code for the exception, which must be + registered in ``app.aborter``. + :param args: Passed to the exception. + :param kwargs: Passed to the exception. + + .. versionadded:: 2.2 + Calls ``current_app.aborter`` if available instead of always + using Werkzeug's default ``abort``. + """ + if current_app: + current_app.aborter(code, *args, **kwargs) + + _wz_abort(code, *args, **kwargs) + + +def get_template_attribute(template_name: str, attribute: str) -> t.Any: + """Loads a macro (or variable) a template exports. This can be used to + invoke a macro from within Python code. If you for example have a + template named :file:`_cider.html` with the following contents: + + .. sourcecode:: html+jinja + + {% macro hello(name) %}Hello {{ name }}!{% endmacro %} + + You can access this from Python code like this:: + + hello = get_template_attribute('_cider.html', 'hello') + return hello('World') + + .. versionadded:: 0.2 + + :param template_name: the name of the template + :param attribute: the name of the variable of macro to access + """ + return getattr(current_app.jinja_env.get_template(template_name).module, attribute) + + +def flash(message: str, category: str = "message") -> None: + """Flashes a message to the next request. In order to remove the + flashed message from the session and to display it to the user, + the template has to call :func:`get_flashed_messages`. + + .. versionchanged:: 0.3 + `category` parameter added. + + :param message: the message to be flashed. + :param category: the category for the message. The following values + are recommended: ``'message'`` for any kind of message, + ``'error'`` for errors, ``'info'`` for information + messages and ``'warning'`` for warnings. However any + kind of string can be used as category. + """ + # Original implementation: + # + # session.setdefault('_flashes', []).append((category, message)) + # + # This assumed that changes made to mutable structures in the session are + # always in sync with the session object, which is not true for session + # implementations that use external storage for keeping their keys/values. + flashes = session.get("_flashes", []) + flashes.append((category, message)) + session["_flashes"] = flashes + app = current_app._get_current_object() # type: ignore + message_flashed.send( + app, + _async_wrapper=app.ensure_sync, + message=message, + category=category, + ) + + +def get_flashed_messages( + with_categories: bool = False, category_filter: t.Iterable[str] = () +) -> list[str] | list[tuple[str, str]]: + """Pulls all flashed messages from the session and returns them. + Further calls in the same request to the function will return + the same messages. By default just the messages are returned, + but when `with_categories` is set to ``True``, the return value will + be a list of tuples in the form ``(category, message)`` instead. + + Filter the flashed messages to one or more categories by providing those + categories in `category_filter`. This allows rendering categories in + separate html blocks. The `with_categories` and `category_filter` + arguments are distinct: + + * `with_categories` controls whether categories are returned with message + text (``True`` gives a tuple, where ``False`` gives just the message text). + * `category_filter` filters the messages down to only those matching the + provided categories. + + See :doc:`/patterns/flashing` for examples. + + .. versionchanged:: 0.3 + `with_categories` parameter added. + + .. versionchanged:: 0.9 + `category_filter` parameter added. + + :param with_categories: set to ``True`` to also receive categories. + :param category_filter: filter of categories to limit return values. Only + categories in the list will be returned. + """ + flashes = request_ctx.flashes + if flashes is None: + flashes = session.pop("_flashes") if "_flashes" in session else [] + request_ctx.flashes = flashes + if category_filter: + flashes = list(filter(lambda f: f[0] in category_filter, flashes)) + if not with_categories: + return [x[1] for x in flashes] + return flashes + + +def _prepare_send_file_kwargs(**kwargs: t.Any) -> dict[str, t.Any]: + if kwargs.get("max_age") is None: + kwargs["max_age"] = current_app.get_send_file_max_age + + kwargs.update( + environ=request.environ, + use_x_sendfile=current_app.config["USE_X_SENDFILE"], + response_class=current_app.response_class, + _root_path=current_app.root_path, # type: ignore + ) + return kwargs + + +def send_file( + path_or_file: os.PathLike[t.AnyStr] | str | t.BinaryIO, + mimetype: str | None = None, + as_attachment: bool = False, + download_name: str | None = None, + conditional: bool = True, + etag: bool | str = True, + last_modified: datetime | int | float | None = None, + max_age: None | (int | t.Callable[[str | None], int | None]) = None, +) -> Response: + """Send the contents of a file to the client. + + The first argument can be a file path or a file-like object. Paths + are preferred in most cases because Werkzeug can manage the file and + get extra information from the path. Passing a file-like object + requires that the file is opened in binary mode, and is mostly + useful when building a file in memory with :class:`io.BytesIO`. + + Never pass file paths provided by a user. The path is assumed to be + trusted, so a user could craft a path to access a file you didn't + intend. Use :func:`send_from_directory` to safely serve + user-requested paths from within a directory. + + If the WSGI server sets a ``file_wrapper`` in ``environ``, it is + used, otherwise Werkzeug's built-in wrapper is used. Alternatively, + if the HTTP server supports ``X-Sendfile``, configuring Flask with + ``USE_X_SENDFILE = True`` will tell the server to send the given + path, which is much more efficient than reading it in Python. + + :param path_or_file: The path to the file to send, relative to the + current working directory if a relative path is given. + Alternatively, a file-like object opened in binary mode. Make + sure the file pointer is seeked to the start of the data. + :param mimetype: The MIME type to send for the file. If not + provided, it will try to detect it from the file name. + :param as_attachment: Indicate to a browser that it should offer to + save the file instead of displaying it. + :param download_name: The default name browsers will use when saving + the file. Defaults to the passed file name. + :param conditional: Enable conditional and range responses based on + request headers. Requires passing a file path and ``environ``. + :param etag: Calculate an ETag for the file, which requires passing + a file path. Can also be a string to use instead. + :param last_modified: The last modified time to send for the file, + in seconds. If not provided, it will try to detect it from the + file path. + :param max_age: How long the client should cache the file, in + seconds. If set, ``Cache-Control`` will be ``public``, otherwise + it will be ``no-cache`` to prefer conditional caching. + + .. versionchanged:: 2.0 + ``download_name`` replaces the ``attachment_filename`` + parameter. If ``as_attachment=False``, it is passed with + ``Content-Disposition: inline`` instead. + + .. versionchanged:: 2.0 + ``max_age`` replaces the ``cache_timeout`` parameter. + ``conditional`` is enabled and ``max_age`` is not set by + default. + + .. versionchanged:: 2.0 + ``etag`` replaces the ``add_etags`` parameter. It can be a + string to use instead of generating one. + + .. versionchanged:: 2.0 + Passing a file-like object that inherits from + :class:`~io.TextIOBase` will raise a :exc:`ValueError` rather + than sending an empty file. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionchanged:: 1.1 + ``filename`` may be a :class:`~os.PathLike` object. + + .. versionchanged:: 1.1 + Passing a :class:`~io.BytesIO` object supports range requests. + + .. versionchanged:: 1.0.3 + Filenames are encoded with ASCII instead of Latin-1 for broader + compatibility with WSGI servers. + + .. versionchanged:: 1.0 + UTF-8 filenames as specified in :rfc:`2231` are supported. + + .. versionchanged:: 0.12 + The filename is no longer automatically inferred from file + objects. If you want to use automatic MIME and etag support, + pass a filename via ``filename_or_fp`` or + ``attachment_filename``. + + .. versionchanged:: 0.12 + ``attachment_filename`` is preferred over ``filename`` for MIME + detection. + + .. versionchanged:: 0.9 + ``cache_timeout`` defaults to + :meth:`Flask.get_send_file_max_age`. + + .. versionchanged:: 0.7 + MIME guessing and etag support for file-like objects was + removed because it was unreliable. Pass a filename if you are + able to, otherwise attach an etag yourself. + + .. versionchanged:: 0.5 + The ``add_etags``, ``cache_timeout`` and ``conditional`` + parameters were added. The default behavior is to add etags. + + .. versionadded:: 0.2 + """ + return werkzeug.utils.send_file( # type: ignore[return-value] + **_prepare_send_file_kwargs( + path_or_file=path_or_file, + environ=request.environ, + mimetype=mimetype, + as_attachment=as_attachment, + download_name=download_name, + conditional=conditional, + etag=etag, + last_modified=last_modified, + max_age=max_age, + ) + ) + + +def send_from_directory( + directory: os.PathLike[str] | str, + path: os.PathLike[str] | str, + **kwargs: t.Any, +) -> Response: + """Send a file from within a directory using :func:`send_file`. + + .. code-block:: python + + @app.route("/uploads/") + def download_file(name): + return send_from_directory( + app.config['UPLOAD_FOLDER'], name, as_attachment=True + ) + + This is a secure way to serve files from a folder, such as static + files or uploads. Uses :func:`~werkzeug.security.safe_join` to + ensure the path coming from the client is not maliciously crafted to + point outside the specified directory. + + If the final path does not point to an existing regular file, + raises a 404 :exc:`~werkzeug.exceptions.NotFound` error. + + :param directory: The directory that ``path`` must be located under, + relative to the current application's root path. This *must not* + be a value provided by the client, otherwise it becomes insecure. + :param path: The path to the file to send, relative to + ``directory``. + :param kwargs: Arguments to pass to :func:`send_file`. + + .. versionchanged:: 2.0 + ``path`` replaces the ``filename`` parameter. + + .. versionadded:: 2.0 + Moved the implementation to Werkzeug. This is now a wrapper to + pass some Flask-specific arguments. + + .. versionadded:: 0.5 + """ + return werkzeug.utils.send_from_directory( # type: ignore[return-value] + directory, path, **_prepare_send_file_kwargs(**kwargs) + ) + + +def get_root_path(import_name: str) -> str: + """Find the root path of a package, or the path that contains a + module. If it cannot be found, returns the current working + directory. + + Not to be confused with the value returned by :func:`find_package`. + + :meta private: + """ + # Module already imported and has a file attribute. Use that first. + mod = sys.modules.get(import_name) + + if mod is not None and hasattr(mod, "__file__") and mod.__file__ is not None: + return os.path.dirname(os.path.abspath(mod.__file__)) + + # Next attempt: check the loader. + try: + spec = importlib.util.find_spec(import_name) + + if spec is None: + raise ValueError + except (ImportError, ValueError): + loader = None + else: + loader = spec.loader + + # Loader does not exist or we're referring to an unloaded main + # module or a main module without path (interactive sessions), go + # with the current working directory. + if loader is None: + return os.getcwd() + + if hasattr(loader, "get_filename"): + filepath = loader.get_filename(import_name) # pyright: ignore + else: + # Fall back to imports. + __import__(import_name) + mod = sys.modules[import_name] + filepath = getattr(mod, "__file__", None) + + # If we don't have a file path it might be because it is a + # namespace package. In this case pick the root path from the + # first module that is contained in the package. + if filepath is None: + raise RuntimeError( + "No root path can be found for the provided module" + f" {import_name!r}. This can happen because the module" + " came from an import hook that does not provide file" + " name information or because it's a namespace package." + " In this case the root path needs to be explicitly" + " provided." + ) + + # filepath is import_name.py for a module, or __init__.py for a package. + return os.path.dirname(os.path.abspath(filepath)) # type: ignore[no-any-return] + + +@cache +def _split_blueprint_path(name: str) -> list[str]: + out: list[str] = [name] + + if "." in name: + out.extend(_split_blueprint_path(name.rpartition(".")[0])) + + return out diff --git a/venv/lib/python3.12/site-packages/flask/json/__init__.py b/venv/lib/python3.12/site-packages/flask/json/__init__.py new file mode 100644 index 0000000..c0941d0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/json/__init__.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import json as _json +import typing as t + +from ..globals import current_app +from .provider import _default + +if t.TYPE_CHECKING: # pragma: no cover + from ..wrappers import Response + + +def dumps(obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dumps() ` + method, otherwise it will use :func:`json.dumps`. + + :param obj: The data to serialize. + :param kwargs: Arguments passed to the ``dumps`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dumps``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.dumps(obj, **kwargs) + + kwargs.setdefault("default", _default) + return _json.dumps(obj, **kwargs) + + +def dump(obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.dump() ` + method, otherwise it will use :func:`json.dump`. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: Arguments passed to the ``dump`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.dump``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + Writing to a binary file, and the ``encoding`` argument, will be + removed in Flask 2.1. + """ + if current_app: + current_app.json.dump(obj, fp, **kwargs) + else: + kwargs.setdefault("default", _default) + _json.dump(obj, fp, **kwargs) + + +def loads(s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.loads() ` + method, otherwise it will use :func:`json.loads`. + + :param s: Text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``loads`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.loads``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The data must be a + string or UTF-8 bytes. + + .. versionchanged:: 1.0.3 + ``app`` can be passed directly, rather than requiring an app + context for configuration. + """ + if current_app: + return current_app.json.loads(s, **kwargs) + + return _json.loads(s, **kwargs) + + +def load(fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + If :data:`~flask.current_app` is available, it will use its + :meth:`app.json.load() ` + method, otherwise it will use :func:`json.load`. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: Arguments passed to the ``load`` implementation. + + .. versionchanged:: 2.3 + The ``app`` parameter was removed. + + .. versionchanged:: 2.2 + Calls ``current_app.json.load``, allowing an app to override + the behavior. + + .. versionchanged:: 2.2 + The ``app`` parameter will be removed in Flask 2.3. + + .. versionchanged:: 2.0 + ``encoding`` will be removed in Flask 2.1. The file must be text + mode, or binary mode with UTF-8 bytes. + """ + if current_app: + return current_app.json.load(fp, **kwargs) + + return _json.load(fp, **kwargs) + + +def jsonify(*args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. A dict or list returned from a view will be converted to a + JSON response automatically without needing to call this. + + This requires an active request or application context, and calls + :meth:`app.json.response() `. + + In debug mode, the output is formatted with indentation to make it + easier to read. This may also be controlled by the provider. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + + .. versionchanged:: 2.2 + Calls ``current_app.json.response``, allowing an app to override + the behavior. + + .. versionchanged:: 2.0.2 + :class:`decimal.Decimal` is supported by converting to a string. + + .. versionchanged:: 0.11 + Added support for serializing top-level arrays. This was a + security risk in ancient browsers. See :ref:`security-json`. + + .. versionadded:: 0.2 + """ + return current_app.json.response(*args, **kwargs) # type: ignore[return-value] diff --git a/venv/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/json/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b68d96131d91c83331d0f841407a956186380aaa GIT binary patch literal 6702 zcmd5=O>Y~=8Q!HRX)Ri!?Zk~^*YPBli?WrMk{r7MV>mJVk-8sF5UF1(3UbIDN-HgQ znc1aO8b%Qm0Sfof_!b|1FbWq1dd#25MMMG!U~Rx?+JkQelwNY`^UmxpsgJ0#s{|&% z-PxU)cV^yw=b7hyJ{cVyG4T6%?I-j9IBXc7(?jyh=z_Wa0SX@(j^UV|(J<#slgb${ zGdG~_*||Yyz{z?;jp4ar)D1dAp4Helx6d@h;NtU%x!zq4q5ZIzYwVxfkM^UE^+9%S z)ERU3;XdZ%oe|vg&H*Qf`vK>mvmf_^?M&g&V=_`OyE*RrLBu0B@WbnmX`=M9){;{A zQJFWJk4^o~Dm$XiTV8~E>s=8x(LvOxGWiXnkTVQ({m&?TWJJk(L$WAsw;1~(twdol z+yA7?H;uaK8aK^*=AXVRR)2aPb*Yj8_6ex$P zf2kp&g;E8sv=_s`x1Cm_8Gg6G&TDJxT~h|jt|O#P&cG{dvZHhVf|rurDQioLZp; zRmB2db_2QNz>{`w=u!hvoMk< z?>tUAwMs?!wZK6KcuECSRU|%QuFtMg9Ky9zJJ_4DC;MEVxV;94z*hWO9aoB4i14-+vyYnsd!{^pP)E!O`Vn`Aebh8wX-9Z&I z-H}j4alNFy+#M`abs^IoKy-G8bnJz+jT!rLp|}tR&UoLuXHLg5kPfZs?Hxj3tytc&WMOakZtw>`Q%VpPhqjK49w&i{d zs4k-@gm2;UzVV-PhV|To{L!`iiBA5+TK-fgf9h_nlYjO8&v99`UVW4uS<4>oWDnnV z?;ZIp`@ILb10TMA>-F1VCwJ;j9hcSYsdbn#YW;AR0_5LNvjHGqc^ZJcY1T7<$P7WG zX|yvpGkXV;n{5{cxcQYpi8yiCiiEdytk+#n#F6=Rfak8U^QoZo>5#MD1Zpx`I18G> z2L{k4A)hD&z^<{`%tFxe9CbDj_WW%2>gm_gy_IZu@*pn0pTKW!>NZ$2=1~^Gf zqnjmslY|}$*W?&Vg#nqTx=g((51IyD^9Gf7=dTz}+(y@-L zS;srp@jJD<(;aK_{%}{Td%yh5vL9HZACBA_xqaqNregtfKDAEC zL$Fj!nHC;Wz`22k4S@51GqNb zX_ih%?0vPp!2}`^J|V}_hM!fA70+(3Iaa#&Hf+%yxlfPKHdy&prN^t#*7!RgC$*lihuY6T!0zV+t3u=$xq)uhs&xp z{m+<|yw}N{ymJ+o)$GY<86}SHfD)jk9H*)b8UXjNkzvr6*cHQ|hED|=n=oU0>OiYa zsKb^prjuybjDY6(%rXK!xjhDxUb;5Bea1;C`t}*snH@5!X?rromnTFiMGO;^q8utU z)Ce5t1~@NbzCzF7BhkXv17rhYWXW?eU`Xgq##YEUN^j}n;h#XpjOd?HHNc2Eg(v)4{a*RzMS=P|_|TTifeR$$WMNYDwb@2}oV@nIo#L zd8PxE{D@UFu@KA^ISv*`iie6=*LM;{h|-t_Um_JuElu#yC4C{lVz^`D=tlPjZ$qgG zRl-Ayk%8yI7St0OCe_5WbFN@dz(O-XRu9R6d*qHK(OwCp(-$YPz@frtfYVFjj<58j64r1T1zFoDXUfcxB-dO zg*c|`Lo7Mn>k-x-Q6zI6UhqcRcUz7)+v}j>a$^T&cRMmO-6vRmrB;@F>Ala#`bJOo z=HAO?llIh9>e!2pgSd(HHq`|B^0BT&YR3lZP4v!oABKz9gzed$>dR-)=ep%WW zuzCa!H*#pfZtARNQ$uA8?dUAJF{aF^Da>rOnKV6)rg{#PBkK~Q5~=!yL*0>bx!wZO zi*i|l8EOZrGp{=YyvDcfno)On-V3UL5v@5|32bPQadh@q?_4Qg`r(yJKfZSTt**5q zfuQ)BY6z|Uscc-)Yjt3f&;Md5Un=I^wax?jTAsKdzmF<9>B84=`S*Znnh%XvJ~y8K zyK(4W#>)?lmmUpd|M14|-*}ikxjuBl{LcDi^BAt@zip1MUpQute{r6f=al9D0+$d; A-~a#s literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/json/__pycache__/provider.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4be01ab540a2af41d58779616a14fc539a38644e GIT binary patch literal 9269 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 L$^Ve($$9tRdiFXZ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/json/__pycache__/tag.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/json/__pycache__/tag.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf9b50743980e04472172c47ecb5c574261055ee GIT binary patch literal 13964 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/json/provider.py b/venv/lib/python3.12/site-packages/flask/json/provider.py new file mode 100644 index 0000000..ea7e475 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/json/provider.py @@ -0,0 +1,215 @@ +from __future__ import annotations + +import dataclasses +import decimal +import json +import typing as t +import uuid +import weakref +from datetime import date + +from werkzeug.http import http_date + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.sansio.response import Response + + from ..sansio.app import App + + +class JSONProvider: + """A standard set of JSON operations for an application. Subclasses + of this can be used to customize JSON behavior or use different + JSON libraries. + + To implement a provider for a specific library, subclass this base + class and implement at least :meth:`dumps` and :meth:`loads`. All + other methods have default implementations. + + To use a different provider, either subclass ``Flask`` and set + :attr:`~flask.Flask.json_provider_class` to a provider class, or set + :attr:`app.json ` to an instance of the class. + + :param app: An application instance. This will be stored as a + :class:`weakref.proxy` on the :attr:`_app` attribute. + + .. versionadded:: 2.2 + """ + + def __init__(self, app: App) -> None: + self._app: App = weakref.proxy(app) + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON. + + :param obj: The data to serialize. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def dump(self, obj: t.Any, fp: t.IO[str], **kwargs: t.Any) -> None: + """Serialize data as JSON and write to a file. + + :param obj: The data to serialize. + :param fp: A file opened for writing text. Should use the UTF-8 + encoding to be valid JSON. + :param kwargs: May be passed to the underlying JSON library. + """ + fp.write(self.dumps(obj, **kwargs)) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON. + + :param s: Text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + raise NotImplementedError + + def load(self, fp: t.IO[t.AnyStr], **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON read from a file. + + :param fp: A file opened for reading text or UTF-8 bytes. + :param kwargs: May be passed to the underlying JSON library. + """ + return self.loads(fp.read(), **kwargs) + + def _prepare_response_obj( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> t.Any: + if args and kwargs: + raise TypeError("app.json.response() takes either args or kwargs, not both") + + if not args and not kwargs: + return None + + if len(args) == 1: + return args[0] + + return args or kwargs + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with the ``application/json`` + mimetype. + + The :func:`~flask.json.jsonify` function calls this method for + the current application. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + return self._app.response_class(self.dumps(obj), mimetype="application/json") + + +def _default(o: t.Any) -> t.Any: + if isinstance(o, date): + return http_date(o) + + if isinstance(o, (decimal.Decimal, uuid.UUID)): + return str(o) + + if dataclasses and dataclasses.is_dataclass(o): + return dataclasses.asdict(o) # type: ignore[arg-type] + + if hasattr(o, "__html__"): + return str(o.__html__()) + + raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable") + + +class DefaultJSONProvider(JSONProvider): + """Provide JSON operations using Python's built-in :mod:`json` + library. Serializes the following additional data types: + + - :class:`datetime.datetime` and :class:`datetime.date` are + serialized to :rfc:`822` strings. This is the same as the HTTP + date format. + - :class:`uuid.UUID` is serialized to a string. + - :class:`dataclasses.dataclass` is passed to + :func:`dataclasses.asdict`. + - :class:`~markupsafe.Markup` (or any object with a ``__html__`` + method) will call the ``__html__`` method to get a string. + """ + + default: t.Callable[[t.Any], t.Any] = staticmethod(_default) # type: ignore[assignment] + """Apply this function to any object that :meth:`json.dumps` does + not know how to serialize. It should return a valid JSON type or + raise a ``TypeError``. + """ + + ensure_ascii = True + """Replace non-ASCII characters with escape sequences. This may be + more compatible with some clients, but can be disabled for better + performance and size. + """ + + sort_keys = True + """Sort the keys in any serialized dicts. This may be useful for + some caching situations, but can be disabled for better performance. + When enabled, keys must all be strings, they are not converted + before sorting. + """ + + compact: bool | None = None + """If ``True``, or ``None`` out of debug mode, the :meth:`response` + output will not add indentation, newlines, or spaces. If ``False``, + or ``None`` in debug mode, it will use a non-compact representation. + """ + + mimetype = "application/json" + """The mimetype set in :meth:`response`.""" + + def dumps(self, obj: t.Any, **kwargs: t.Any) -> str: + """Serialize data as JSON to a string. + + Keyword arguments are passed to :func:`json.dumps`. Sets some + parameter defaults from the :attr:`default`, + :attr:`ensure_ascii`, and :attr:`sort_keys` attributes. + + :param obj: The data to serialize. + :param kwargs: Passed to :func:`json.dumps`. + """ + kwargs.setdefault("default", self.default) + kwargs.setdefault("ensure_ascii", self.ensure_ascii) + kwargs.setdefault("sort_keys", self.sort_keys) + return json.dumps(obj, **kwargs) + + def loads(self, s: str | bytes, **kwargs: t.Any) -> t.Any: + """Deserialize data as JSON from a string or bytes. + + :param s: Text or UTF-8 bytes. + :param kwargs: Passed to :func:`json.loads`. + """ + return json.loads(s, **kwargs) + + def response(self, *args: t.Any, **kwargs: t.Any) -> Response: + """Serialize the given arguments as JSON, and return a + :class:`~flask.Response` object with it. The response mimetype + will be "application/json" and can be changed with + :attr:`mimetype`. + + If :attr:`compact` is ``False`` or debug mode is enabled, the + output will be formatted to be easier to read. + + Either positional or keyword arguments can be given, not both. + If no arguments are given, ``None`` is serialized. + + :param args: A single value to serialize, or multiple values to + treat as a list to serialize. + :param kwargs: Treat as a dict to serialize. + """ + obj = self._prepare_response_obj(args, kwargs) + dump_args: dict[str, t.Any] = {} + + if (self.compact is None and self._app.debug) or self.compact is False: + dump_args.setdefault("indent", 2) + else: + dump_args.setdefault("separators", (",", ":")) + + return self._app.response_class( + f"{self.dumps(obj, **dump_args)}\n", mimetype=self.mimetype + ) diff --git a/venv/lib/python3.12/site-packages/flask/json/tag.py b/venv/lib/python3.12/site-packages/flask/json/tag.py new file mode 100644 index 0000000..8dc3629 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/json/tag.py @@ -0,0 +1,327 @@ +""" +Tagged JSON +~~~~~~~~~~~ + +A compact representation for lossless serialization of non-standard JSON +types. :class:`~flask.sessions.SecureCookieSessionInterface` uses this +to serialize the session data, but it may be useful in other places. It +can be extended to support other types. + +.. autoclass:: TaggedJSONSerializer + :members: + +.. autoclass:: JSONTag + :members: + +Let's see an example that adds support for +:class:`~collections.OrderedDict`. Dicts don't have an order in JSON, so +to handle this we will dump the items as a list of ``[key, value]`` +pairs. Subclass :class:`JSONTag` and give it the new key ``' od'`` to +identify the type. The session serializer processes dicts first, so +insert the new tag at the front of the order since ``OrderedDict`` must +be processed before ``dict``. + +.. code-block:: python + + from flask.json.tag import JSONTag + + class TagOrderedDict(JSONTag): + __slots__ = ('serializer',) + key = ' od' + + def check(self, value): + return isinstance(value, OrderedDict) + + def to_json(self, value): + return [[k, self.serializer.tag(v)] for k, v in iteritems(value)] + + def to_python(self, value): + return OrderedDict(value) + + app.session_interface.serializer.register(TagOrderedDict, index=0) +""" + +from __future__ import annotations + +import typing as t +from base64 import b64decode +from base64 import b64encode +from datetime import datetime +from uuid import UUID + +from markupsafe import Markup +from werkzeug.http import http_date +from werkzeug.http import parse_date + +from ..json import dumps +from ..json import loads + + +class JSONTag: + """Base class for defining type tags for :class:`TaggedJSONSerializer`.""" + + __slots__ = ("serializer",) + + #: The tag to mark the serialized object with. If empty, this tag is + #: only used as an intermediate step during tagging. + key: str = "" + + def __init__(self, serializer: TaggedJSONSerializer) -> None: + """Create a tagger for the given serializer.""" + self.serializer = serializer + + def check(self, value: t.Any) -> bool: + """Check if the given value should be tagged by this tag.""" + raise NotImplementedError + + def to_json(self, value: t.Any) -> t.Any: + """Convert the Python object to an object that is a valid JSON type. + The tag will be added later.""" + raise NotImplementedError + + def to_python(self, value: t.Any) -> t.Any: + """Convert the JSON representation back to the correct type. The tag + will already be removed.""" + raise NotImplementedError + + def tag(self, value: t.Any) -> dict[str, t.Any]: + """Convert the value to a valid JSON type and add the tag structure + around it.""" + return {self.key: self.to_json(value)} + + +class TagDict(JSONTag): + """Tag for 1-item dicts whose only key matches a registered tag. + + Internally, the dict key is suffixed with `__`, and the suffix is removed + when deserializing. + """ + + __slots__ = () + key = " di" + + def check(self, value: t.Any) -> bool: + return ( + isinstance(value, dict) + and len(value) == 1 + and next(iter(value)) in self.serializer.tags + ) + + def to_json(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {f"{key}__": self.serializer.tag(value[key])} + + def to_python(self, value: t.Any) -> t.Any: + key = next(iter(value)) + return {key[:-2]: value[key]} + + +class PassDict(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, dict) + + def to_json(self, value: t.Any) -> t.Any: + # JSON objects may only have string keys, so don't bother tagging the + # key here. + return {k: self.serializer.tag(v) for k, v in value.items()} + + tag = to_json + + +class TagTuple(JSONTag): + __slots__ = () + key = " t" + + def check(self, value: t.Any) -> bool: + return isinstance(value, tuple) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + def to_python(self, value: t.Any) -> t.Any: + return tuple(value) + + +class PassList(JSONTag): + __slots__ = () + + def check(self, value: t.Any) -> bool: + return isinstance(value, list) + + def to_json(self, value: t.Any) -> t.Any: + return [self.serializer.tag(item) for item in value] + + tag = to_json + + +class TagBytes(JSONTag): + __slots__ = () + key = " b" + + def check(self, value: t.Any) -> bool: + return isinstance(value, bytes) + + def to_json(self, value: t.Any) -> t.Any: + return b64encode(value).decode("ascii") + + def to_python(self, value: t.Any) -> t.Any: + return b64decode(value) + + +class TagMarkup(JSONTag): + """Serialize anything matching the :class:`~markupsafe.Markup` API by + having a ``__html__`` method to the result of that method. Always + deserializes to an instance of :class:`~markupsafe.Markup`.""" + + __slots__ = () + key = " m" + + def check(self, value: t.Any) -> bool: + return callable(getattr(value, "__html__", None)) + + def to_json(self, value: t.Any) -> t.Any: + return str(value.__html__()) + + def to_python(self, value: t.Any) -> t.Any: + return Markup(value) + + +class TagUUID(JSONTag): + __slots__ = () + key = " u" + + def check(self, value: t.Any) -> bool: + return isinstance(value, UUID) + + def to_json(self, value: t.Any) -> t.Any: + return value.hex + + def to_python(self, value: t.Any) -> t.Any: + return UUID(value) + + +class TagDateTime(JSONTag): + __slots__ = () + key = " d" + + def check(self, value: t.Any) -> bool: + return isinstance(value, datetime) + + def to_json(self, value: t.Any) -> t.Any: + return http_date(value) + + def to_python(self, value: t.Any) -> t.Any: + return parse_date(value) + + +class TaggedJSONSerializer: + """Serializer that uses a tag system to compactly represent objects that + are not JSON types. Passed as the intermediate serializer to + :class:`itsdangerous.Serializer`. + + The following extra types are supported: + + * :class:`dict` + * :class:`tuple` + * :class:`bytes` + * :class:`~markupsafe.Markup` + * :class:`~uuid.UUID` + * :class:`~datetime.datetime` + """ + + __slots__ = ("tags", "order") + + #: Tag classes to bind when creating the serializer. Other tags can be + #: added later using :meth:`~register`. + default_tags = [ + TagDict, + PassDict, + TagTuple, + PassList, + TagBytes, + TagMarkup, + TagUUID, + TagDateTime, + ] + + def __init__(self) -> None: + self.tags: dict[str, JSONTag] = {} + self.order: list[JSONTag] = [] + + for cls in self.default_tags: + self.register(cls) + + def register( + self, + tag_class: type[JSONTag], + force: bool = False, + index: int | None = None, + ) -> None: + """Register a new tag with this serializer. + + :param tag_class: tag class to register. Will be instantiated with this + serializer instance. + :param force: overwrite an existing tag. If false (default), a + :exc:`KeyError` is raised. + :param index: index to insert the new tag in the tag order. Useful when + the new tag is a special case of an existing tag. If ``None`` + (default), the tag is appended to the end of the order. + + :raise KeyError: if the tag key is already registered and ``force`` is + not true. + """ + tag = tag_class(self) + key = tag.key + + if key: + if not force and key in self.tags: + raise KeyError(f"Tag '{key}' is already registered.") + + self.tags[key] = tag + + if index is None: + self.order.append(tag) + else: + self.order.insert(index, tag) + + def tag(self, value: t.Any) -> t.Any: + """Convert a value to a tagged representation if necessary.""" + for tag in self.order: + if tag.check(value): + return tag.tag(value) + + return value + + def untag(self, value: dict[str, t.Any]) -> t.Any: + """Convert a tagged representation back to the original type.""" + if len(value) != 1: + return value + + key = next(iter(value)) + + if key not in self.tags: + return value + + return self.tags[key].to_python(value[key]) + + def _untag_scan(self, value: t.Any) -> t.Any: + if isinstance(value, dict): + # untag each item recursively + value = {k: self._untag_scan(v) for k, v in value.items()} + # untag the dict itself + value = self.untag(value) + elif isinstance(value, list): + # untag each item recursively + value = [self._untag_scan(item) for item in value] + + return value + + def dumps(self, value: t.Any) -> str: + """Tag the value and dump it to a compact JSON string.""" + return dumps(self.tag(value), separators=(",", ":")) + + def loads(self, value: str) -> t.Any: + """Load data from a JSON string and deserialized any tagged objects.""" + return self._untag_scan(loads(value)) diff --git a/venv/lib/python3.12/site-packages/flask/logging.py b/venv/lib/python3.12/site-packages/flask/logging.py new file mode 100644 index 0000000..0cb8f43 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/logging.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +import logging +import sys +import typing as t + +from werkzeug.local import LocalProxy + +from .globals import request + +if t.TYPE_CHECKING: # pragma: no cover + from .sansio.app import App + + +@LocalProxy +def wsgi_errors_stream() -> t.TextIO: + """Find the most appropriate error stream for the application. If a request + is active, log to ``wsgi.errors``, otherwise use ``sys.stderr``. + + If you configure your own :class:`logging.StreamHandler`, you may want to + use this for the stream. If you are using file or dict configuration and + can't import this directly, you can refer to it as + ``ext://flask.logging.wsgi_errors_stream``. + """ + if request: + return request.environ["wsgi.errors"] # type: ignore[no-any-return] + + return sys.stderr + + +def has_level_handler(logger: logging.Logger) -> bool: + """Check if there is a handler in the logging chain that will handle the + given logger's :meth:`effective level <~logging.Logger.getEffectiveLevel>`. + """ + level = logger.getEffectiveLevel() + current = logger + + while current: + if any(handler.level <= level for handler in current.handlers): + return True + + if not current.propagate: + break + + current = current.parent # type: ignore + + return False + + +#: Log messages to :func:`~flask.logging.wsgi_errors_stream` with the format +#: ``[%(asctime)s] %(levelname)s in %(module)s: %(message)s``. +default_handler = logging.StreamHandler(wsgi_errors_stream) # type: ignore +default_handler.setFormatter( + logging.Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s") +) + + +def create_logger(app: App) -> logging.Logger: + """Get the Flask app's logger and configure it if needed. + + The logger name will be the same as + :attr:`app.import_name `. + + When :attr:`~flask.Flask.debug` is enabled, set the logger level to + :data:`logging.DEBUG` if it is not set. + + If there is no handler for the logger's effective level, add a + :class:`~logging.StreamHandler` for + :func:`~flask.logging.wsgi_errors_stream` with a basic format. + """ + logger = logging.getLogger(app.name) + + if app.debug and not logger.level: + logger.setLevel(logging.DEBUG) + + if not has_level_handler(logger): + logger.addHandler(default_handler) + + return logger diff --git a/venv/lib/python3.12/site-packages/flask/py.typed b/venv/lib/python3.12/site-packages/flask/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/flask/sansio/README.md b/venv/lib/python3.12/site-packages/flask/sansio/README.md new file mode 100644 index 0000000..623ac19 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/sansio/README.md @@ -0,0 +1,6 @@ +# Sansio + +This folder contains code that can be used by alternative Flask +implementations, for example Quart. The code therefore cannot do any +IO, nor be part of a likely IO path. Finally this code cannot use the +Flask globals. diff --git a/venv/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/sansio/__pycache__/app.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8f4889e87af48e437b37aa9d440ea51b8ca5e73 GIT binary patch literal 33696 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
    -!e#BMZUE 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc b/venv/lib/python3.12/site-packages/flask/sansio/__pycache__/blueprints.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7fd9e28f712be63613467ac87a015e3e142f29c3 GIT binary patch literal 31193 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 timedelta | None: + if value is None or isinstance(value, timedelta): + return value + + return timedelta(seconds=value) + + +class App(Scaffold): + """The flask object implements a WSGI application and acts as the central + object. It is passed the name of the module or package of the + application. Once it is created it will act as a central registry for + the view functions, the URL rules, template configuration and much more. + + The name of the package is used to resolve resources from inside the + package or the folder the module is contained in depending on if the + package parameter resolves to an actual python package (a folder with + an :file:`__init__.py` file inside) or a standard module (just a ``.py`` file). + + For more information about resource loading, see :func:`open_resource`. + + Usually you create a :class:`Flask` instance in your main module or + in the :file:`__init__.py` file of your package like this:: + + from flask import Flask + app = Flask(__name__) + + .. admonition:: About the First Parameter + + The idea of the first parameter is to give Flask an idea of what + belongs to your application. This name is used to find resources + on the filesystem, can be used by extensions to improve debugging + information and a lot more. + + So it's important what you provide there. If you are using a single + module, `__name__` is always the correct value. If you however are + using a package, it's usually recommended to hardcode the name of + your package there. + + For example if your application is defined in :file:`yourapplication/app.py` + you should create it with one of the two versions below:: + + app = Flask('yourapplication') + app = Flask(__name__.split('.')[0]) + + Why is that? The application will work even with `__name__`, thanks + to how resources are looked up. However it will make debugging more + painful. Certain extensions can make assumptions based on the + import name of your application. For example the Flask-SQLAlchemy + extension will look for the code in your application that triggered + an SQL query in debug mode. If the import name is not properly set + up, that debugging information is lost. (For example it would only + pick up SQL queries in `yourapplication.app` and not + `yourapplication.views.frontend`) + + .. versionadded:: 0.7 + The `static_url_path`, `static_folder`, and `template_folder` + parameters were added. + + .. versionadded:: 0.8 + The `instance_path` and `instance_relative_config` parameters were + added. + + .. versionadded:: 0.11 + The `root_path` parameter was added. + + .. versionadded:: 1.0 + The ``host_matching`` and ``static_host`` parameters were added. + + .. versionadded:: 1.0 + The ``subdomain_matching`` parameter was added. Subdomain + matching needs to be enabled manually now. Setting + :data:`SERVER_NAME` does not implicitly enable it. + + :param import_name: the name of the application package + :param static_url_path: can be used to specify a different path for the + static files on the web. Defaults to the name + of the `static_folder` folder. + :param static_folder: The folder with static files that is served at + ``static_url_path``. Relative to the application ``root_path`` + or an absolute path. Defaults to ``'static'``. + :param static_host: the host to use when adding the static route. + Defaults to None. Required when using ``host_matching=True`` + with a ``static_folder`` configured. + :param host_matching: set ``url_map.host_matching`` attribute. + Defaults to False. + :param subdomain_matching: consider the subdomain relative to + :data:`SERVER_NAME` when matching routes. Defaults to False. + :param template_folder: the folder that contains the templates that should + be used by the application. Defaults to + ``'templates'`` folder in the root path of the + application. + :param instance_path: An alternative instance path for the application. + By default the folder ``'instance'`` next to the + package or module is assumed to be the instance + path. + :param instance_relative_config: if set to ``True`` relative filenames + for loading the config are assumed to + be relative to the instance path instead + of the application root. + :param root_path: The path to the root of the application files. + This should only be set manually when it can't be detected + automatically, such as for namespace packages. + """ + + #: The class of the object assigned to :attr:`aborter`, created by + #: :meth:`create_aborter`. That object is called by + #: :func:`flask.abort` to raise HTTP errors, and can be + #: called directly as well. + #: + #: Defaults to :class:`werkzeug.exceptions.Aborter`. + #: + #: .. versionadded:: 2.2 + aborter_class = Aborter + + #: The class that is used for the Jinja environment. + #: + #: .. versionadded:: 0.11 + jinja_environment = Environment + + #: The class that is used for the :data:`~flask.g` instance. + #: + #: Example use cases for a custom class: + #: + #: 1. Store arbitrary attributes on flask.g. + #: 2. Add a property for lazy per-request database connectors. + #: 3. Return None instead of AttributeError on unexpected attributes. + #: 4. Raise exception if an unexpected attr is set, a "controlled" flask.g. + #: + #: In Flask 0.9 this property was called `request_globals_class` but it + #: was changed in 0.10 to :attr:`app_ctx_globals_class` because the + #: flask.g object is now application context scoped. + #: + #: .. versionadded:: 0.10 + app_ctx_globals_class = _AppCtxGlobals + + #: The class that is used for the ``config`` attribute of this app. + #: Defaults to :class:`~flask.Config`. + #: + #: Example use cases for a custom class: + #: + #: 1. Default values for certain config options. + #: 2. Access to config values through attributes in addition to keys. + #: + #: .. versionadded:: 0.11 + config_class = Config + + #: The testing flag. Set this to ``True`` to enable the test mode of + #: Flask extensions (and in the future probably also Flask itself). + #: For example this might activate test helpers that have an + #: additional runtime cost which should not be enabled by default. + #: + #: If this is enabled and PROPAGATE_EXCEPTIONS is not changed from the + #: default it's implicitly enabled. + #: + #: This attribute can also be configured from the config with the + #: ``TESTING`` configuration key. Defaults to ``False``. + testing = ConfigAttribute[bool]("TESTING") + + #: If a secret key is set, cryptographic components can use this to + #: sign cookies and other things. Set this to a complex random value + #: when you want to use the secure cookie for instance. + #: + #: This attribute can also be configured from the config with the + #: :data:`SECRET_KEY` configuration key. Defaults to ``None``. + secret_key = ConfigAttribute[t.Union[str, bytes, None]]("SECRET_KEY") + + #: A :class:`~datetime.timedelta` which is used to set the expiration + #: date of a permanent session. The default is 31 days which makes a + #: permanent session survive for roughly one month. + #: + #: This attribute can also be configured from the config with the + #: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to + #: ``timedelta(days=31)`` + permanent_session_lifetime = ConfigAttribute[timedelta]( + "PERMANENT_SESSION_LIFETIME", + get_converter=_make_timedelta, # type: ignore[arg-type] + ) + + json_provider_class: type[JSONProvider] = DefaultJSONProvider + """A subclass of :class:`~flask.json.provider.JSONProvider`. An + instance is created and assigned to :attr:`app.json` when creating + the app. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, uses + Python's built-in :mod:`json` library. A different provider can use + a different JSON library. + + .. versionadded:: 2.2 + """ + + #: Options that are passed to the Jinja environment in + #: :meth:`create_jinja_environment`. Changing these options after + #: the environment is created (accessing :attr:`jinja_env`) will + #: have no effect. + #: + #: .. versionchanged:: 1.1.0 + #: This is a ``dict`` instead of an ``ImmutableDict`` to allow + #: easier configuration. + #: + jinja_options: dict[str, t.Any] = {} + + #: The rule object to use for URL rules created. This is used by + #: :meth:`add_url_rule`. Defaults to :class:`werkzeug.routing.Rule`. + #: + #: .. versionadded:: 0.7 + url_rule_class = Rule + + #: The map object to use for storing the URL rules and routing + #: configuration parameters. Defaults to :class:`werkzeug.routing.Map`. + #: + #: .. versionadded:: 1.1.0 + url_map_class = Map + + #: The :meth:`test_client` method creates an instance of this test + #: client class. Defaults to :class:`~flask.testing.FlaskClient`. + #: + #: .. versionadded:: 0.7 + test_client_class: type[FlaskClient] | None = None + + #: The :class:`~click.testing.CliRunner` subclass, by default + #: :class:`~flask.testing.FlaskCliRunner` that is used by + #: :meth:`test_cli_runner`. Its ``__init__`` method should take a + #: Flask app object as the first argument. + #: + #: .. versionadded:: 1.0 + test_cli_runner_class: type[FlaskCliRunner] | None = None + + default_config: dict[str, t.Any] + response_class: type[Response] + + def __init__( + self, + import_name: str, + static_url_path: str | None = None, + static_folder: str | os.PathLike[str] | None = "static", + static_host: str | None = None, + host_matching: bool = False, + subdomain_matching: bool = False, + template_folder: str | os.PathLike[str] | None = "templates", + instance_path: str | None = None, + instance_relative_config: bool = False, + root_path: str | None = None, + ) -> None: + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if instance_path is None: + instance_path = self.auto_find_instance_path() + elif not os.path.isabs(instance_path): + raise ValueError( + "If an instance path is provided it must be absolute." + " A relative path was given instead." + ) + + #: Holds the path to the instance folder. + #: + #: .. versionadded:: 0.8 + self.instance_path = instance_path + + #: The configuration dictionary as :class:`Config`. This behaves + #: exactly like a regular dictionary but supports additional methods + #: to load a config from files. + self.config = self.make_config(instance_relative_config) + + #: An instance of :attr:`aborter_class` created by + #: :meth:`make_aborter`. This is called by :func:`flask.abort` + #: to raise HTTP errors, and can be called directly as well. + #: + #: .. versionadded:: 2.2 + #: Moved from ``flask.abort``, which calls this object. + self.aborter = self.make_aborter() + + self.json: JSONProvider = self.json_provider_class(self) + """Provides access to JSON methods. Functions in ``flask.json`` + will call methods on this provider when the application context + is active. Used for handling JSON requests and responses. + + An instance of :attr:`json_provider_class`. Can be customized by + changing that attribute on a subclass, or by assigning to this + attribute afterwards. + + The default, :class:`~flask.json.provider.DefaultJSONProvider`, + uses Python's built-in :mod:`json` library. A different provider + can use a different JSON library. + + .. versionadded:: 2.2 + """ + + #: A list of functions that are called by + #: :meth:`handle_url_build_error` when :meth:`.url_for` raises a + #: :exc:`~werkzeug.routing.BuildError`. Each function is called + #: with ``error``, ``endpoint`` and ``values``. If a function + #: returns ``None`` or raises a ``BuildError``, it is skipped. + #: Otherwise, its return value is returned by ``url_for``. + #: + #: .. versionadded:: 0.9 + self.url_build_error_handlers: list[ + t.Callable[[Exception, str, dict[str, t.Any]], str] + ] = [] + + #: A list of functions that are called when the application context + #: is destroyed. Since the application context is also torn down + #: if the request ends this is the place to store code that disconnects + #: from databases. + #: + #: .. versionadded:: 0.9 + self.teardown_appcontext_funcs: list[ft.TeardownCallable] = [] + + #: A list of shell context processor functions that should be run + #: when a shell context is created. + #: + #: .. versionadded:: 0.11 + self.shell_context_processors: list[ft.ShellContextProcessorCallable] = [] + + #: Maps registered blueprint names to blueprint objects. The + #: dict retains the order the blueprints were registered in. + #: Blueprints can be registered multiple times, this dict does + #: not track how often they were attached. + #: + #: .. versionadded:: 0.7 + self.blueprints: dict[str, Blueprint] = {} + + #: a place where extensions can store application specific state. For + #: example this is where an extension could store database engines and + #: similar things. + #: + #: The key must match the name of the extension module. For example in + #: case of a "Flask-Foo" extension in `flask_foo`, the key would be + #: ``'foo'``. + #: + #: .. versionadded:: 0.7 + self.extensions: dict[str, t.Any] = {} + + #: The :class:`~werkzeug.routing.Map` for this instance. You can use + #: this to change the routing converters after the class was created + #: but before any routes are connected. Example:: + #: + #: from werkzeug.routing import BaseConverter + #: + #: class ListConverter(BaseConverter): + #: def to_python(self, value): + #: return value.split(',') + #: def to_url(self, values): + #: return ','.join(super(ListConverter, self).to_url(value) + #: for value in values) + #: + #: app = Flask(__name__) + #: app.url_map.converters['list'] = ListConverter + self.url_map = self.url_map_class(host_matching=host_matching) + + self.subdomain_matching = subdomain_matching + + # tracks internally if the application already handled at least one + # request. + self._got_first_request = False + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_first_request: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called" + " on the application. It has already handled its first" + " request, any changes will not be applied" + " consistently.\n" + "Make sure all imports, decorators, functions, etc." + " needed to set up the application are done before" + " running it." + ) + + @cached_property + def name(self) -> str: # type: ignore + """The name of the application. This is usually the import name + with the difference that it's guessed from the run file if the + import name is main. This name is used as a display name when + Flask needs the name of the application. It can be set and overridden + to change the value. + + .. versionadded:: 0.8 + """ + if self.import_name == "__main__": + fn: str | None = getattr(sys.modules["__main__"], "__file__", None) + if fn is None: + return "__main__" + return os.path.splitext(os.path.basename(fn))[0] + return self.import_name + + @cached_property + def logger(self) -> logging.Logger: + """A standard Python :class:`~logging.Logger` for the app, with + the same name as :attr:`name`. + + In debug mode, the logger's :attr:`~logging.Logger.level` will + be set to :data:`~logging.DEBUG`. + + If there are no handlers configured, a default handler will be + added. See :doc:`/logging` for more information. + + .. versionchanged:: 1.1.0 + The logger takes the same name as :attr:`name` rather than + hard-coding ``"flask.app"``. + + .. versionchanged:: 1.0.0 + Behavior was simplified. The logger is always named + ``"flask.app"``. The level is only set during configuration, + it doesn't check ``app.debug`` each time. Only one format is + used, not different ones depending on ``app.debug``. No + handlers are removed, and a handler is only added if no + handlers are already configured. + + .. versionadded:: 0.3 + """ + return create_logger(self) + + @cached_property + def jinja_env(self) -> Environment: + """The Jinja environment used to load templates. + + The environment is created the first time this property is + accessed. Changing :attr:`jinja_options` after that will have no + effect. + """ + return self.create_jinja_environment() + + def create_jinja_environment(self) -> Environment: + raise NotImplementedError() + + def make_config(self, instance_relative: bool = False) -> Config: + """Used to create the config attribute by the Flask constructor. + The `instance_relative` parameter is passed in from the constructor + of Flask (there named `instance_relative_config`) and indicates if + the config should be relative to the instance path or the root path + of the application. + + .. versionadded:: 0.8 + """ + root_path = self.root_path + if instance_relative: + root_path = self.instance_path + defaults = dict(self.default_config) + defaults["DEBUG"] = get_debug_flag() + return self.config_class(root_path, defaults) + + def make_aborter(self) -> Aborter: + """Create the object to assign to :attr:`aborter`. That object + is called by :func:`flask.abort` to raise HTTP errors, and can + be called directly as well. + + By default, this creates an instance of :attr:`aborter_class`, + which defaults to :class:`werkzeug.exceptions.Aborter`. + + .. versionadded:: 2.2 + """ + return self.aborter_class() + + def auto_find_instance_path(self) -> str: + """Tries to locate the instance path if it was not provided to the + constructor of the application class. It will basically calculate + the path to a folder named ``instance`` next to your main file or + the package. + + .. versionadded:: 0.8 + """ + prefix, package_path = find_package(self.import_name) + if prefix is None: + return os.path.join(package_path, "instance") + return os.path.join(prefix, "var", f"{self.name}-instance") + + def create_global_jinja_loader(self) -> DispatchingJinjaLoader: + """Creates the loader for the Jinja2 environment. Can be used to + override just the loader and keeping the rest unchanged. It's + discouraged to override this function. Instead one should override + the :meth:`jinja_loader` function instead. + + The global loader dispatches between the loaders of the application + and the individual blueprints. + + .. versionadded:: 0.7 + """ + return DispatchingJinjaLoader(self) + + def select_jinja_autoescape(self, filename: str) -> bool: + """Returns ``True`` if autoescaping should be active for the given + template name. If no template name is given, returns `True`. + + .. versionchanged:: 2.2 + Autoescaping is now enabled by default for ``.svg`` files. + + .. versionadded:: 0.5 + """ + if filename is None: + return True + return filename.endswith((".html", ".htm", ".xml", ".xhtml", ".svg")) + + @property + def debug(self) -> bool: + """Whether debug mode is enabled. When using ``flask run`` to start the + development server, an interactive debugger will be shown for unhandled + exceptions, and the server will be reloaded when code changes. This maps to the + :data:`DEBUG` config key. It may not behave as expected if set late. + + **Do not enable debug mode when deploying in production.** + + Default: ``False`` + """ + return self.config["DEBUG"] # type: ignore[no-any-return] + + @debug.setter + def debug(self, value: bool) -> None: + self.config["DEBUG"] = value + + if self.config["TEMPLATES_AUTO_RELOAD"] is None: + self.jinja_env.auto_reload = value + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on the application. Keyword + arguments passed to this method will override the defaults set on the + blueprint. + + Calls the blueprint's :meth:`~flask.Blueprint.register` method after + recording the blueprint in the application's :attr:`blueprints`. + + :param blueprint: The blueprint to register. + :param url_prefix: Blueprint routes will be prefixed with this. + :param subdomain: Blueprint routes will match on this subdomain. + :param url_defaults: Blueprint routes will use these default values for + view arguments. + :param options: Additional keyword arguments are passed to + :class:`~flask.blueprints.BlueprintSetupState`. They can be + accessed in :meth:`~flask.Blueprint.record` callbacks. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 0.7 + """ + blueprint.register(self, options) + + def iter_blueprints(self) -> t.ValuesView[Blueprint]: + """Iterates over all blueprints by the order they were registered. + + .. versionadded:: 0.11 + """ + return self.blueprints.values() + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + options["endpoint"] = endpoint + methods = options.pop("methods", None) + + # if the methods are not given and the view_func object knows its + # methods we can use that instead. If neither exists, we go with + # a tuple of only ``GET`` as default. + if methods is None: + methods = getattr(view_func, "methods", None) or ("GET",) + if isinstance(methods, str): + raise TypeError( + "Allowed methods must be a list of strings, for" + ' example: @app.route(..., methods=["POST"])' + ) + methods = {item.upper() for item in methods} + + # Methods that should always be added + required_methods: set[str] = set(getattr(view_func, "required_methods", ())) + + # starting with Flask 0.8 the view_func object can disable and + # force-enable the automatic options handling. + if provide_automatic_options is None: + provide_automatic_options = getattr( + view_func, "provide_automatic_options", None + ) + + if provide_automatic_options is None: + if "OPTIONS" not in methods and self.config["PROVIDE_AUTOMATIC_OPTIONS"]: + provide_automatic_options = True + required_methods.add("OPTIONS") + else: + provide_automatic_options = False + + # Add the required methods now. + methods |= required_methods + + rule_obj = self.url_rule_class(rule, methods=methods, **options) + rule_obj.provide_automatic_options = provide_automatic_options # type: ignore[attr-defined] + + self.url_map.add(rule_obj) + if view_func is not None: + old_func = self.view_functions.get(endpoint) + if old_func is not None and old_func != view_func: + raise AssertionError( + "View function mapping is overwriting an existing" + f" endpoint function: {endpoint}" + ) + self.view_functions[endpoint] = view_func + + @setupmethod + def template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """A decorator that is used to register custom template filter. + You can specify a name for the filter, otherwise the function + name will be used. Example:: + + @app.template_filter() + def reverse(s): + return s[::-1] + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a custom template filter. Works exactly like the + :meth:`template_filter` decorator. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + self.jinja_env.filters[name or f.__name__] = f + + @setupmethod + def template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """A decorator that is used to register custom template test. + You can specify a name for the test, otherwise the function + name will be used. Example:: + + @app.template_test() + def is_prime(n): + if n == 2: + return True + for i in range(2, int(math.ceil(math.sqrt(n))) + 1): + if n % i == 0: + return False + return True + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a custom template test. Works exactly like the + :meth:`template_test` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + self.jinja_env.tests[name or f.__name__] = f + + @setupmethod + def template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """A decorator that is used to register a custom template global function. + You can specify a name for the global function, otherwise the function + name will be used. Example:: + + @app.template_global() + def double(n): + return 2 * n + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a custom template global function. Works exactly like the + :meth:`template_global` decorator. + + .. versionadded:: 0.10 + + :param name: the optional name of the global function, otherwise the + function name will be used. + """ + self.jinja_env.globals[name or f.__name__] = f + + @setupmethod + def teardown_appcontext(self, f: T_teardown) -> T_teardown: + """Registers a function to be called when the application + context is popped. The application context is typically popped + after the request context for each request, at the end of CLI + commands, or after a manually pushed context ends. + + .. code-block:: python + + with app.app_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the app context is + made inactive. Since a request context typically also manages an + application context it would also be called when you pop a + request context. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + .. versionadded:: 0.9 + """ + self.teardown_appcontext_funcs.append(f) + return f + + @setupmethod + def shell_context_processor( + self, f: T_shell_context_processor + ) -> T_shell_context_processor: + """Registers a shell context processor function. + + .. versionadded:: 0.11 + """ + self.shell_context_processors.append(f) + return f + + def _find_error_handler( + self, e: Exception, blueprints: list[str] + ) -> ft.ErrorHandlerCallable | None: + """Return a registered error handler for an exception in this order: + blueprint handler for a specific code, app handler for a specific code, + blueprint handler for an exception class, app handler for an exception + class, or ``None`` if a suitable handler is not found. + """ + exc_class, code = self._get_exc_class_and_code(type(e)) + names = (*blueprints, None) + + for c in (code, None) if code is not None else (None,): + for name in names: + handler_map = self.error_handler_spec[name][c] + + if not handler_map: + continue + + for cls in exc_class.__mro__: + handler = handler_map.get(cls) + + if handler is not None: + return handler + return None + + def trap_http_exception(self, e: Exception) -> bool: + """Checks if an HTTP exception should be trapped or not. By default + this will return ``False`` for all exceptions except for a bad request + key error if ``TRAP_BAD_REQUEST_ERRORS`` is set to ``True``. It + also returns ``True`` if ``TRAP_HTTP_EXCEPTIONS`` is set to ``True``. + + This is called for all HTTP exceptions raised by a view function. + If it returns ``True`` for any exception the error handler for this + exception is not called and it shows up as regular exception in the + traceback. This is helpful for debugging implicitly raised HTTP + exceptions. + + .. versionchanged:: 1.0 + Bad request errors are not trapped by default in debug mode. + + .. versionadded:: 0.8 + """ + if self.config["TRAP_HTTP_EXCEPTIONS"]: + return True + + trap_bad_request = self.config["TRAP_BAD_REQUEST_ERRORS"] + + # if unset, trap key errors in debug mode + if ( + trap_bad_request is None + and self.debug + and isinstance(e, BadRequestKeyError) + ): + return True + + if trap_bad_request: + return isinstance(e, BadRequest) + + return False + + def should_ignore_error(self, error: BaseException | None) -> bool: + """This is called to figure out if an error should be ignored + or not as far as the teardown system is concerned. If this + function returns ``True`` then the teardown handlers will not be + passed the error. + + .. versionadded:: 0.10 + """ + return False + + def redirect(self, location: str, code: int = 302) -> BaseResponse: + """Create a redirect response object. + + This is called by :func:`flask.redirect`, and can be called + directly as well. + + :param location: The URL to redirect to. + :param code: The status code for the redirect. + + .. versionadded:: 2.2 + Moved from ``flask.redirect``, which calls this method. + """ + return _wz_redirect( + location, + code=code, + Response=self.response_class, # type: ignore[arg-type] + ) + + def inject_url_defaults(self, endpoint: str, values: dict[str, t.Any]) -> None: + """Injects the URL defaults for the given endpoint directly into + the values dictionary passed. This is used internally and + automatically called on URL building. + + .. versionadded:: 0.7 + """ + names: t.Iterable[str | None] = (None,) + + # url_for may be called outside a request context, parse the + # passed endpoint instead of using request.blueprints. + if "." in endpoint: + names = chain( + names, reversed(_split_blueprint_path(endpoint.rpartition(".")[0])) + ) + + for name in names: + if name in self.url_default_functions: + for func in self.url_default_functions[name]: + func(endpoint, values) + + def handle_url_build_error( + self, error: BuildError, endpoint: str, values: dict[str, t.Any] + ) -> str: + """Called by :meth:`.url_for` if a + :exc:`~werkzeug.routing.BuildError` was raised. If this returns + a value, it will be returned by ``url_for``, otherwise the error + will be re-raised. + + Each function in :attr:`url_build_error_handlers` is called with + ``error``, ``endpoint`` and ``values``. If a function returns + ``None`` or raises a ``BuildError``, it is skipped. Otherwise, + its return value is returned by ``url_for``. + + :param error: The active ``BuildError`` being handled. + :param endpoint: The endpoint being built. + :param values: The keyword arguments passed to ``url_for``. + """ + for handler in self.url_build_error_handlers: + try: + rv = handler(error, endpoint, values) + except BuildError as e: + # make error available outside except block + error = e + else: + if rv is not None: + return rv + + # Re-raise if called with an active exception, otherwise raise + # the passed in exception. + if error is sys.exc_info()[1]: + raise + + raise error diff --git a/venv/lib/python3.12/site-packages/flask/sansio/blueprints.py b/venv/lib/python3.12/site-packages/flask/sansio/blueprints.py new file mode 100644 index 0000000..4f912cc --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/sansio/blueprints.py @@ -0,0 +1,632 @@ +from __future__ import annotations + +import os +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from .. import typing as ft +from .scaffold import _endpoint_from_view_func +from .scaffold import _sentinel +from .scaffold import Scaffold +from .scaffold import setupmethod + +if t.TYPE_CHECKING: # pragma: no cover + from .app import App + +DeferredSetupFunction = t.Callable[["BlueprintSetupState"], None] +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_template_filter = t.TypeVar("T_template_filter", bound=ft.TemplateFilterCallable) +T_template_global = t.TypeVar("T_template_global", bound=ft.TemplateGlobalCallable) +T_template_test = t.TypeVar("T_template_test", bound=ft.TemplateTestCallable) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) + + +class BlueprintSetupState: + """Temporary holder object for registering a blueprint with the + application. An instance of this class is created by the + :meth:`~flask.Blueprint.make_setup_state` method and later passed + to all register callback functions. + """ + + def __init__( + self, + blueprint: Blueprint, + app: App, + options: t.Any, + first_registration: bool, + ) -> None: + #: a reference to the current application + self.app = app + + #: a reference to the blueprint that created this setup state. + self.blueprint = blueprint + + #: a dictionary with all options that were passed to the + #: :meth:`~flask.Flask.register_blueprint` method. + self.options = options + + #: as blueprints can be registered multiple times with the + #: application and not everything wants to be registered + #: multiple times on it, this attribute can be used to figure + #: out if the blueprint was registered in the past already. + self.first_registration = first_registration + + subdomain = self.options.get("subdomain") + if subdomain is None: + subdomain = self.blueprint.subdomain + + #: The subdomain that the blueprint should be active for, ``None`` + #: otherwise. + self.subdomain = subdomain + + url_prefix = self.options.get("url_prefix") + if url_prefix is None: + url_prefix = self.blueprint.url_prefix + #: The prefix that should be used for all URLs defined on the + #: blueprint. + self.url_prefix = url_prefix + + self.name = self.options.get("name", blueprint.name) + self.name_prefix = self.options.get("name_prefix", "") + + #: A dictionary with URL defaults that is added to each and every + #: URL that was defined with the blueprint. + self.url_defaults = dict(self.blueprint.url_values_defaults) + self.url_defaults.update(self.options.get("url_defaults", ())) + + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + **options: t.Any, + ) -> None: + """A helper method to register a rule (and optionally a view function) + to the application. The endpoint is automatically prefixed with the + blueprint's name. + """ + if self.url_prefix is not None: + if rule: + rule = "/".join((self.url_prefix.rstrip("/"), rule.lstrip("/"))) + else: + rule = self.url_prefix + options.setdefault("subdomain", self.subdomain) + if endpoint is None: + endpoint = _endpoint_from_view_func(view_func) # type: ignore + defaults = self.url_defaults + if "defaults" in options: + defaults = dict(defaults, **options.pop("defaults")) + + self.app.add_url_rule( + rule, + f"{self.name_prefix}.{self.name}.{endpoint}".lstrip("."), + view_func, + defaults=defaults, + **options, + ) + + +class Blueprint(Scaffold): + """Represents a blueprint, a collection of routes and other + app-related functions that can be registered on a real application + later. + + A blueprint is an object that allows defining application functions + without requiring an application object ahead of time. It uses the + same decorators as :class:`~flask.Flask`, but defers the need for an + application by recording them for later registration. + + Decorating a function with a blueprint creates a deferred function + that is called with :class:`~flask.blueprints.BlueprintSetupState` + when the blueprint is registered on an application. + + See :doc:`/blueprints` for more information. + + :param name: The name of the blueprint. Will be prepended to each + endpoint name. + :param import_name: The name of the blueprint package, usually + ``__name__``. This helps locate the ``root_path`` for the + blueprint. + :param static_folder: A folder with static files that should be + served by the blueprint's static route. The path is relative to + the blueprint's root path. Blueprint static files are disabled + by default. + :param static_url_path: The url to serve static files from. + Defaults to ``static_folder``. If the blueprint does not have + a ``url_prefix``, the app's static route will take precedence, + and the blueprint's static files won't be accessible. + :param template_folder: A folder with templates that should be added + to the app's template search path. The path is relative to the + blueprint's root path. Blueprint templates are disabled by + default. Blueprint templates have a lower precedence than those + in the app's templates folder. + :param url_prefix: A path to prepend to all of the blueprint's URLs, + to make them distinct from the rest of the app's routes. + :param subdomain: A subdomain that blueprint routes will match on by + default. + :param url_defaults: A dict of default values that blueprint routes + will receive by default. + :param root_path: By default, the blueprint will automatically set + this based on ``import_name``. In certain situations this + automatic detection can fail, so the path can be specified + manually instead. + + .. versionchanged:: 1.1.0 + Blueprints have a ``cli`` group to register nested CLI commands. + The ``cli_group`` parameter controls the name of the group under + the ``flask`` command. + + .. versionadded:: 0.7 + """ + + _got_registered_once = False + + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore[assignment] + ): + super().__init__( + import_name=import_name, + static_folder=static_folder, + static_url_path=static_url_path, + template_folder=template_folder, + root_path=root_path, + ) + + if not name: + raise ValueError("'name' may not be empty.") + + if "." in name: + raise ValueError("'name' may not contain a dot '.' character.") + + self.name = name + self.url_prefix = url_prefix + self.subdomain = subdomain + self.deferred_functions: list[DeferredSetupFunction] = [] + + if url_defaults is None: + url_defaults = {} + + self.url_values_defaults = url_defaults + self.cli_group = cli_group + self._blueprints: list[tuple[Blueprint, dict[str, t.Any]]] = [] + + def _check_setup_finished(self, f_name: str) -> None: + if self._got_registered_once: + raise AssertionError( + f"The setup method '{f_name}' can no longer be called on the blueprint" + f" '{self.name}'. It has already been registered at least once, any" + " changes will not be applied consistently.\n" + "Make sure all imports, decorators, functions, etc. needed to set up" + " the blueprint are done before registering it." + ) + + @setupmethod + def record(self, func: DeferredSetupFunction) -> None: + """Registers a function that is called when the blueprint is + registered on the application. This function is called with the + state as argument as returned by the :meth:`make_setup_state` + method. + """ + self.deferred_functions.append(func) + + @setupmethod + def record_once(self, func: DeferredSetupFunction) -> None: + """Works like :meth:`record` but wraps the function in another + function that will ensure the function is only called once. If the + blueprint is registered a second time on the application, the + function passed is not called. + """ + + def wrapper(state: BlueprintSetupState) -> None: + if state.first_registration: + func(state) + + self.record(update_wrapper(wrapper, func)) + + def make_setup_state( + self, app: App, options: dict[str, t.Any], first_registration: bool = False + ) -> BlueprintSetupState: + """Creates an instance of :meth:`~flask.blueprints.BlueprintSetupState` + object that is later passed to the register callback functions. + Subclasses can override this to return a subclass of the setup state. + """ + return BlueprintSetupState(self, app, options, first_registration) + + @setupmethod + def register_blueprint(self, blueprint: Blueprint, **options: t.Any) -> None: + """Register a :class:`~flask.Blueprint` on this blueprint. Keyword + arguments passed to this method will override the defaults set + on the blueprint. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + + .. versionadded:: 2.0 + """ + if blueprint is self: + raise ValueError("Cannot register a blueprint on itself") + self._blueprints.append((blueprint, options)) + + def register(self, app: App, options: dict[str, t.Any]) -> None: + """Called by :meth:`Flask.register_blueprint` to register all + views and callbacks registered on the blueprint with the + application. Creates a :class:`.BlueprintSetupState` and calls + each :meth:`record` callback with it. + + :param app: The application this blueprint is being registered + with. + :param options: Keyword arguments forwarded from + :meth:`~Flask.register_blueprint`. + + .. versionchanged:: 2.3 + Nested blueprints now correctly apply subdomains. + + .. versionchanged:: 2.1 + Registering the same blueprint with the same name multiple + times is an error. + + .. versionchanged:: 2.0.1 + Nested blueprints are registered with their dotted name. + This allows different blueprints with the same name to be + nested at different locations. + + .. versionchanged:: 2.0.1 + The ``name`` option can be used to change the (pre-dotted) + name the blueprint is registered with. This allows the same + blueprint to be registered multiple times with unique names + for ``url_for``. + """ + name_prefix = options.get("name_prefix", "") + self_name = options.get("name", self.name) + name = f"{name_prefix}.{self_name}".lstrip(".") + + if name in app.blueprints: + bp_desc = "this" if app.blueprints[name] is self else "a different" + existing_at = f" '{name}'" if self_name != name else "" + + raise ValueError( + f"The name '{self_name}' is already registered for" + f" {bp_desc} blueprint{existing_at}. Use 'name=' to" + f" provide a unique name." + ) + + first_bp_registration = not any(bp is self for bp in app.blueprints.values()) + first_name_registration = name not in app.blueprints + + app.blueprints[name] = self + self._got_registered_once = True + state = self.make_setup_state(app, options, first_bp_registration) + + if self.has_static_folder: + state.add_url_rule( + f"{self.static_url_path}/", + view_func=self.send_static_file, # type: ignore[attr-defined] + endpoint="static", + ) + + # Merge blueprint data into parent. + if first_bp_registration or first_name_registration: + self._merge_blueprint_funcs(app, name) + + for deferred in self.deferred_functions: + deferred(state) + + cli_resolved_group = options.get("cli_group", self.cli_group) + + if self.cli.commands: + if cli_resolved_group is None: + app.cli.commands.update(self.cli.commands) + elif cli_resolved_group is _sentinel: + self.cli.name = name + app.cli.add_command(self.cli) + else: + self.cli.name = cli_resolved_group + app.cli.add_command(self.cli) + + for blueprint, bp_options in self._blueprints: + bp_options = bp_options.copy() + bp_url_prefix = bp_options.get("url_prefix") + bp_subdomain = bp_options.get("subdomain") + + if bp_subdomain is None: + bp_subdomain = blueprint.subdomain + + if state.subdomain is not None and bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + "." + state.subdomain + elif bp_subdomain is not None: + bp_options["subdomain"] = bp_subdomain + elif state.subdomain is not None: + bp_options["subdomain"] = state.subdomain + + if bp_url_prefix is None: + bp_url_prefix = blueprint.url_prefix + + if state.url_prefix is not None and bp_url_prefix is not None: + bp_options["url_prefix"] = ( + state.url_prefix.rstrip("/") + "/" + bp_url_prefix.lstrip("/") + ) + elif bp_url_prefix is not None: + bp_options["url_prefix"] = bp_url_prefix + elif state.url_prefix is not None: + bp_options["url_prefix"] = state.url_prefix + + bp_options["name_prefix"] = name + blueprint.register(app, bp_options) + + def _merge_blueprint_funcs(self, app: App, name: str) -> None: + def extend( + bp_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + parent_dict: dict[ft.AppOrBlueprintKey, list[t.Any]], + ) -> None: + for key, values in bp_dict.items(): + key = name if key is None else f"{name}.{key}" + parent_dict[key].extend(values) + + for key, value in self.error_handler_spec.items(): + key = name if key is None else f"{name}.{key}" + value = defaultdict( + dict, + { + code: {exc_class: func for exc_class, func in code_values.items()} + for code, code_values in value.items() + }, + ) + app.error_handler_spec[key] = value + + for endpoint, func in self.view_functions.items(): + app.view_functions[endpoint] = func + + extend(self.before_request_funcs, app.before_request_funcs) + extend(self.after_request_funcs, app.after_request_funcs) + extend( + self.teardown_request_funcs, + app.teardown_request_funcs, + ) + extend(self.url_default_functions, app.url_default_functions) + extend(self.url_value_preprocessors, app.url_value_preprocessors) + extend(self.template_context_processors, app.template_context_processors) + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a URL rule with the blueprint. See :meth:`.Flask.add_url_rule` for + full documentation. + + The URL rule is prefixed with the blueprint's URL prefix. The endpoint name, + used with :func:`url_for`, is prefixed with the blueprint's name. + """ + if endpoint and "." in endpoint: + raise ValueError("'endpoint' may not contain a dot '.' character.") + + if view_func and hasattr(view_func, "__name__") and "." in view_func.__name__: + raise ValueError("'view_func' name may not contain a dot '.' character.") + + self.record( + lambda s: s.add_url_rule( + rule, + endpoint, + view_func, + provide_automatic_options=provide_automatic_options, + **options, + ) + ) + + @setupmethod + def app_template_filter( + self, name: str | None = None + ) -> t.Callable[[T_template_filter], T_template_filter]: + """Register a template filter, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def decorator(f: T_template_filter) -> T_template_filter: + self.add_app_template_filter(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_filter( + self, f: ft.TemplateFilterCallable, name: str | None = None + ) -> None: + """Register a template filter, available in any template rendered by the + application. Works like the :meth:`app_template_filter` decorator. Equivalent to + :meth:`.Flask.add_template_filter`. + + :param name: the optional name of the filter, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.filters[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_test( + self, name: str | None = None + ) -> t.Callable[[T_template_test], T_template_test]: + """Register a template test, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def decorator(f: T_template_test) -> T_template_test: + self.add_app_template_test(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_test( + self, f: ft.TemplateTestCallable, name: str | None = None + ) -> None: + """Register a template test, available in any template rendered by the + application. Works like the :meth:`app_template_test` decorator. Equivalent to + :meth:`.Flask.add_template_test`. + + .. versionadded:: 0.10 + + :param name: the optional name of the test, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.tests[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def app_template_global( + self, name: str | None = None + ) -> t.Callable[[T_template_global], T_template_global]: + """Register a template global, available in any template rendered by the + application. Equivalent to :meth:`.Flask.template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def decorator(f: T_template_global) -> T_template_global: + self.add_app_template_global(f, name=name) + return f + + return decorator + + @setupmethod + def add_app_template_global( + self, f: ft.TemplateGlobalCallable, name: str | None = None + ) -> None: + """Register a template global, available in any template rendered by the + application. Works like the :meth:`app_template_global` decorator. Equivalent to + :meth:`.Flask.add_template_global`. + + .. versionadded:: 0.10 + + :param name: the optional name of the global, otherwise the + function name will be used. + """ + + def register_template(state: BlueprintSetupState) -> None: + state.app.jinja_env.globals[name or f.__name__] = f + + self.record_once(register_template) + + @setupmethod + def before_app_request(self, f: T_before_request) -> T_before_request: + """Like :meth:`before_request`, but before every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.before_request`. + """ + self.record_once( + lambda s: s.app.before_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def after_app_request(self, f: T_after_request) -> T_after_request: + """Like :meth:`after_request`, but after every request, not only those handled + by the blueprint. Equivalent to :meth:`.Flask.after_request`. + """ + self.record_once( + lambda s: s.app.after_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def teardown_app_request(self, f: T_teardown) -> T_teardown: + """Like :meth:`teardown_request`, but after every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.teardown_request`. + """ + self.record_once( + lambda s: s.app.teardown_request_funcs.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_context_processor( + self, f: T_template_context_processor + ) -> T_template_context_processor: + """Like :meth:`context_processor`, but for templates rendered by every view, not + only by the blueprint. Equivalent to :meth:`.Flask.context_processor`. + """ + self.record_once( + lambda s: s.app.template_context_processors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_errorhandler( + self, code: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Like :meth:`errorhandler`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.errorhandler`. + """ + + def decorator(f: T_error_handler) -> T_error_handler: + def from_blueprint(state: BlueprintSetupState) -> None: + state.app.errorhandler(code)(f) + + self.record_once(from_blueprint) + return f + + return decorator + + @setupmethod + def app_url_value_preprocessor( + self, f: T_url_value_preprocessor + ) -> T_url_value_preprocessor: + """Like :meth:`url_value_preprocessor`, but for every request, not only those + handled by the blueprint. Equivalent to :meth:`.Flask.url_value_preprocessor`. + """ + self.record_once( + lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) + ) + return f + + @setupmethod + def app_url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Like :meth:`url_defaults`, but for every request, not only those handled by + the blueprint. Equivalent to :meth:`.Flask.url_defaults`. + """ + self.record_once( + lambda s: s.app.url_default_functions.setdefault(None, []).append(f) + ) + return f diff --git a/venv/lib/python3.12/site-packages/flask/sansio/scaffold.py b/venv/lib/python3.12/site-packages/flask/sansio/scaffold.py new file mode 100644 index 0000000..3a839f5 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/sansio/scaffold.py @@ -0,0 +1,792 @@ +from __future__ import annotations + +import importlib.util +import os +import pathlib +import sys +import typing as t +from collections import defaultdict +from functools import update_wrapper + +from jinja2 import BaseLoader +from jinja2 import FileSystemLoader +from werkzeug.exceptions import default_exceptions +from werkzeug.exceptions import HTTPException +from werkzeug.utils import cached_property + +from .. import typing as ft +from ..helpers import get_root_path +from ..templating import _default_template_ctx_processor + +if t.TYPE_CHECKING: # pragma: no cover + from click import Group + +# a singleton sentinel value for parameter defaults +_sentinel = object() + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) +T_after_request = t.TypeVar("T_after_request", bound=ft.AfterRequestCallable[t.Any]) +T_before_request = t.TypeVar("T_before_request", bound=ft.BeforeRequestCallable) +T_error_handler = t.TypeVar("T_error_handler", bound=ft.ErrorHandlerCallable) +T_teardown = t.TypeVar("T_teardown", bound=ft.TeardownCallable) +T_template_context_processor = t.TypeVar( + "T_template_context_processor", bound=ft.TemplateContextProcessorCallable +) +T_url_defaults = t.TypeVar("T_url_defaults", bound=ft.URLDefaultCallable) +T_url_value_preprocessor = t.TypeVar( + "T_url_value_preprocessor", bound=ft.URLValuePreprocessorCallable +) +T_route = t.TypeVar("T_route", bound=ft.RouteCallable) + + +def setupmethod(f: F) -> F: + f_name = f.__name__ + + def wrapper_func(self: Scaffold, *args: t.Any, **kwargs: t.Any) -> t.Any: + self._check_setup_finished(f_name) + return f(self, *args, **kwargs) + + return t.cast(F, update_wrapper(wrapper_func, f)) + + +class Scaffold: + """Common behavior shared between :class:`~flask.Flask` and + :class:`~flask.blueprints.Blueprint`. + + :param import_name: The import name of the module where this object + is defined. Usually :attr:`__name__` should be used. + :param static_folder: Path to a folder of static files to serve. + If this is set, a static route will be added. + :param static_url_path: URL prefix for the static route. + :param template_folder: Path to a folder containing template files. + for rendering. If this is set, a Jinja loader will be added. + :param root_path: The path that static, template, and resource files + are relative to. Typically not set, it is discovered based on + the ``import_name``. + + .. versionadded:: 2.0 + """ + + cli: Group + name: str + _static_folder: str | None = None + _static_url_path: str | None = None + + def __init__( + self, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + root_path: str | None = None, + ): + #: The name of the package or module that this object belongs + #: to. Do not change this once it is set by the constructor. + self.import_name = import_name + + self.static_folder = static_folder # type: ignore + self.static_url_path = static_url_path + + #: The path to the templates folder, relative to + #: :attr:`root_path`, to add to the template loader. ``None`` if + #: templates should not be added. + self.template_folder = template_folder + + if root_path is None: + root_path = get_root_path(self.import_name) + + #: Absolute path to the package on the filesystem. Used to look + #: up resources contained in the package. + self.root_path = root_path + + #: A dictionary mapping endpoint names to view functions. + #: + #: To register a view function, use the :meth:`route` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.view_functions: dict[str, ft.RouteCallable] = {} + + #: A data structure of registered error handlers, in the format + #: ``{scope: {code: {class: handler}}}``. The ``scope`` key is + #: the name of a blueprint the handlers are active for, or + #: ``None`` for all requests. The ``code`` key is the HTTP + #: status code for ``HTTPException``, or ``None`` for + #: other exceptions. The innermost dictionary maps exception + #: classes to handler functions. + #: + #: To register an error handler, use the :meth:`errorhandler` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.error_handler_spec: dict[ + ft.AppOrBlueprintKey, + dict[int | None, dict[type[Exception], ft.ErrorHandlerCallable]], + ] = defaultdict(lambda: defaultdict(dict)) + + #: A data structure of functions to call at the beginning of + #: each request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`before_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.before_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.BeforeRequestCallable] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request, in the format ``{scope: [functions]}``. The + #: ``scope`` key is the name of a blueprint the functions are + #: active for, or ``None`` for all requests. + #: + #: To register a function, use the :meth:`after_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.after_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.AfterRequestCallable[t.Any]] + ] = defaultdict(list) + + #: A data structure of functions to call at the end of each + #: request even if an exception is raised, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`teardown_request` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.teardown_request_funcs: dict[ + ft.AppOrBlueprintKey, list[ft.TeardownCallable] + ] = defaultdict(list) + + #: A data structure of functions to call to pass extra context + #: values when rendering templates, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`context_processor` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.template_context_processors: dict[ + ft.AppOrBlueprintKey, list[ft.TemplateContextProcessorCallable] + ] = defaultdict(list, {None: [_default_template_ctx_processor]}) + + #: A data structure of functions to call to modify the keyword + #: arguments passed to the view function, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the + #: :meth:`url_value_preprocessor` decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_value_preprocessors: dict[ + ft.AppOrBlueprintKey, + list[ft.URLValuePreprocessorCallable], + ] = defaultdict(list) + + #: A data structure of functions to call to modify the keyword + #: arguments when generating URLs, in the format + #: ``{scope: [functions]}``. The ``scope`` key is the name of a + #: blueprint the functions are active for, or ``None`` for all + #: requests. + #: + #: To register a function, use the :meth:`url_defaults` + #: decorator. + #: + #: This data structure is internal. It should not be modified + #: directly and its format may change at any time. + self.url_default_functions: dict[ + ft.AppOrBlueprintKey, list[ft.URLDefaultCallable] + ] = defaultdict(list) + + def __repr__(self) -> str: + return f"<{type(self).__name__} {self.name!r}>" + + def _check_setup_finished(self, f_name: str) -> None: + raise NotImplementedError + + @property + def static_folder(self) -> str | None: + """The absolute path to the configured static folder. ``None`` + if no static folder is set. + """ + if self._static_folder is not None: + return os.path.join(self.root_path, self._static_folder) + else: + return None + + @static_folder.setter + def static_folder(self, value: str | os.PathLike[str] | None) -> None: + if value is not None: + value = os.fspath(value).rstrip(r"\/") + + self._static_folder = value + + @property + def has_static_folder(self) -> bool: + """``True`` if :attr:`static_folder` is set. + + .. versionadded:: 0.5 + """ + return self.static_folder is not None + + @property + def static_url_path(self) -> str | None: + """The URL prefix that the static route will be accessible from. + + If it was not configured during init, it is derived from + :attr:`static_folder`. + """ + if self._static_url_path is not None: + return self._static_url_path + + if self.static_folder is not None: + basename = os.path.basename(self.static_folder) + return f"/{basename}".rstrip("/") + + return None + + @static_url_path.setter + def static_url_path(self, value: str | None) -> None: + if value is not None: + value = value.rstrip("/") + + self._static_url_path = value + + @cached_property + def jinja_loader(self) -> BaseLoader | None: + """The Jinja loader for this object's templates. By default this + is a class :class:`jinja2.loaders.FileSystemLoader` to + :attr:`template_folder` if it is set. + + .. versionadded:: 0.5 + """ + if self.template_folder is not None: + return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) + else: + return None + + def _method_route( + self, + method: str, + rule: str, + options: dict[str, t.Any], + ) -> t.Callable[[T_route], T_route]: + if "methods" in options: + raise TypeError("Use the 'route' decorator to use the 'methods' argument.") + + return self.route(rule, methods=[method], **options) + + @setupmethod + def get(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["GET"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("GET", rule, options) + + @setupmethod + def post(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["POST"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("POST", rule, options) + + @setupmethod + def put(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PUT"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PUT", rule, options) + + @setupmethod + def delete(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["DELETE"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("DELETE", rule, options) + + @setupmethod + def patch(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Shortcut for :meth:`route` with ``methods=["PATCH"]``. + + .. versionadded:: 2.0 + """ + return self._method_route("PATCH", rule, options) + + @setupmethod + def route(self, rule: str, **options: t.Any) -> t.Callable[[T_route], T_route]: + """Decorate a view function to register it with the given URL + rule and options. Calls :meth:`add_url_rule`, which has more + details about the implementation. + + .. code-block:: python + + @app.route("/") + def index(): + return "Hello, World!" + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` and + ``OPTIONS`` are added automatically. + + :param rule: The URL rule string. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + + def decorator(f: T_route) -> T_route: + endpoint = options.pop("endpoint", None) + self.add_url_rule(rule, endpoint, f, **options) + return f + + return decorator + + @setupmethod + def add_url_rule( + self, + rule: str, + endpoint: str | None = None, + view_func: ft.RouteCallable | None = None, + provide_automatic_options: bool | None = None, + **options: t.Any, + ) -> None: + """Register a rule for routing incoming requests and building + URLs. The :meth:`route` decorator is a shortcut to call this + with the ``view_func`` argument. These are equivalent: + + .. code-block:: python + + @app.route("/") + def index(): + ... + + .. code-block:: python + + def index(): + ... + + app.add_url_rule("/", view_func=index) + + See :ref:`url-route-registrations`. + + The endpoint name for the route defaults to the name of the view + function if the ``endpoint`` parameter isn't passed. An error + will be raised if a function has already been registered for the + endpoint. + + The ``methods`` parameter defaults to ``["GET"]``. ``HEAD`` is + always added automatically, and ``OPTIONS`` is added + automatically by default. + + ``view_func`` does not necessarily need to be passed, but if the + rule should participate in routing an endpoint name must be + associated with a view function at some point with the + :meth:`endpoint` decorator. + + .. code-block:: python + + app.add_url_rule("/", endpoint="index") + + @app.endpoint("index") + def index(): + ... + + If ``view_func`` has a ``required_methods`` attribute, those + methods are added to the passed and automatic methods. If it + has a ``provide_automatic_methods`` attribute, it is used as the + default if the parameter is not passed. + + :param rule: The URL rule string. + :param endpoint: The endpoint name to associate with the rule + and view function. Used when routing and building URLs. + Defaults to ``view_func.__name__``. + :param view_func: The view function to associate with the + endpoint name. + :param provide_automatic_options: Add the ``OPTIONS`` method and + respond to ``OPTIONS`` requests automatically. + :param options: Extra options passed to the + :class:`~werkzeug.routing.Rule` object. + """ + raise NotImplementedError + + @setupmethod + def endpoint(self, endpoint: str) -> t.Callable[[F], F]: + """Decorate a view function to register it for the given + endpoint. Used if a rule is added without a ``view_func`` with + :meth:`add_url_rule`. + + .. code-block:: python + + app.add_url_rule("/ex", endpoint="example") + + @app.endpoint("example") + def example(): + ... + + :param endpoint: The endpoint name to associate with the view + function. + """ + + def decorator(f: F) -> F: + self.view_functions[endpoint] = f + return f + + return decorator + + @setupmethod + def before_request(self, f: T_before_request) -> T_before_request: + """Register a function to run before each request. + + For example, this can be used to open a database connection, or + to load the logged in user from the session. + + .. code-block:: python + + @app.before_request + def load_user(): + if "user_id" in session: + g.user = db.session.get(session["user_id"]) + + The function will be called without any arguments. If it returns + a non-``None`` value, the value is handled as if it was the + return value from the view, and further request handling is + stopped. + + This is available on both app and blueprint objects. When used on an app, this + executes before every request. When used on a blueprint, this executes before + every request that the blueprint handles. To register with a blueprint and + execute before every request, use :meth:`.Blueprint.before_app_request`. + """ + self.before_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def after_request(self, f: T_after_request) -> T_after_request: + """Register a function to run after each request to this object. + + The function is called with the response object, and must return + a response object. This allows the functions to modify or + replace the response before it is sent. + + If a function raises an exception, any remaining + ``after_request`` functions will not be called. Therefore, this + should not be used for actions that must execute, such as to + close resources. Use :meth:`teardown_request` for that. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.after_app_request`. + """ + self.after_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def teardown_request(self, f: T_teardown) -> T_teardown: + """Register a function to be called when the request context is + popped. Typically this happens at the end of each request, but + contexts may be pushed manually as well during testing. + + .. code-block:: python + + with app.test_request_context(): + ... + + When the ``with`` block exits (or ``ctx.pop()`` is called), the + teardown functions are called just before the request context is + made inactive. + + When a teardown function was called because of an unhandled + exception it will be passed an error object. If an + :meth:`errorhandler` is registered, it will handle the exception + and the teardown will not receive it. + + Teardown functions must avoid raising exceptions. If they + execute code that might fail they must surround that code with a + ``try``/``except`` block and log any errors. + + The return values of teardown functions are ignored. + + This is available on both app and blueprint objects. When used on an app, this + executes after every request. When used on a blueprint, this executes after + every request that the blueprint handles. To register with a blueprint and + execute after every request, use :meth:`.Blueprint.teardown_app_request`. + """ + self.teardown_request_funcs.setdefault(None, []).append(f) + return f + + @setupmethod + def context_processor( + self, + f: T_template_context_processor, + ) -> T_template_context_processor: + """Registers a template context processor function. These functions run before + rendering a template. The keys of the returned dict are added as variables + available in the template. + + This is available on both app and blueprint objects. When used on an app, this + is called for every rendered template. When used on a blueprint, this is called + for templates rendered from the blueprint's views. To register with a blueprint + and affect every template, use :meth:`.Blueprint.app_context_processor`. + """ + self.template_context_processors[None].append(f) + return f + + @setupmethod + def url_value_preprocessor( + self, + f: T_url_value_preprocessor, + ) -> T_url_value_preprocessor: + """Register a URL value preprocessor function for all view + functions in the application. These functions will be called before the + :meth:`before_request` functions. + + The function can modify the values captured from the matched url before + they are passed to the view. For example, this can be used to pop a + common language code value and place it in ``g`` rather than pass it to + every view. + + The function is passed the endpoint name and values dict. The return + value is ignored. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_value_preprocessor`. + """ + self.url_value_preprocessors[None].append(f) + return f + + @setupmethod + def url_defaults(self, f: T_url_defaults) -> T_url_defaults: + """Callback function for URL defaults for all view functions of the + application. It's called with the endpoint and values and should + update the values passed in place. + + This is available on both app and blueprint objects. When used on an app, this + is called for every request. When used on a blueprint, this is called for + requests that the blueprint handles. To register with a blueprint and affect + every request, use :meth:`.Blueprint.app_url_defaults`. + """ + self.url_default_functions[None].append(f) + return f + + @setupmethod + def errorhandler( + self, code_or_exception: type[Exception] | int + ) -> t.Callable[[T_error_handler], T_error_handler]: + """Register a function to handle errors by code or exception class. + + A decorator that is used to register a function given an + error code. Example:: + + @app.errorhandler(404) + def page_not_found(error): + return 'This page does not exist', 404 + + You can also register handlers for arbitrary exceptions:: + + @app.errorhandler(DatabaseError) + def special_exception_handler(error): + return 'Database connection failed', 500 + + This is available on both app and blueprint objects. When used on an app, this + can handle errors from every request. When used on a blueprint, this can handle + errors from requests that the blueprint handles. To register with a blueprint + and affect every request, use :meth:`.Blueprint.app_errorhandler`. + + .. versionadded:: 0.7 + Use :meth:`register_error_handler` instead of modifying + :attr:`error_handler_spec` directly, for application wide error + handlers. + + .. versionadded:: 0.7 + One can now additionally also register custom exception types + that do not necessarily have to be a subclass of the + :class:`~werkzeug.exceptions.HTTPException` class. + + :param code_or_exception: the code as integer for the handler, or + an arbitrary exception + """ + + def decorator(f: T_error_handler) -> T_error_handler: + self.register_error_handler(code_or_exception, f) + return f + + return decorator + + @setupmethod + def register_error_handler( + self, + code_or_exception: type[Exception] | int, + f: ft.ErrorHandlerCallable, + ) -> None: + """Alternative error attach function to the :meth:`errorhandler` + decorator that is more straightforward to use for non decorator + usage. + + .. versionadded:: 0.7 + """ + exc_class, code = self._get_exc_class_and_code(code_or_exception) + self.error_handler_spec[None][code][exc_class] = f + + @staticmethod + def _get_exc_class_and_code( + exc_class_or_code: type[Exception] | int, + ) -> tuple[type[Exception], int | None]: + """Get the exception class being handled. For HTTP status codes + or ``HTTPException`` subclasses, return both the exception and + status code. + + :param exc_class_or_code: Any exception class, or an HTTP status + code as an integer. + """ + exc_class: type[Exception] + + if isinstance(exc_class_or_code, int): + try: + exc_class = default_exceptions[exc_class_or_code] + except KeyError: + raise ValueError( + f"'{exc_class_or_code}' is not a recognized HTTP" + " error code. Use a subclass of HTTPException with" + " that code instead." + ) from None + else: + exc_class = exc_class_or_code + + if isinstance(exc_class, Exception): + raise TypeError( + f"{exc_class!r} is an instance, not a class. Handlers" + " can only be registered for Exception classes or HTTP" + " error codes." + ) + + if not issubclass(exc_class, Exception): + raise ValueError( + f"'{exc_class.__name__}' is not a subclass of Exception." + " Handlers can only be registered for Exception classes" + " or HTTP error codes." + ) + + if issubclass(exc_class, HTTPException): + return exc_class, exc_class.code + else: + return exc_class, None + + +def _endpoint_from_view_func(view_func: ft.RouteCallable) -> str: + """Internal helper that returns the default endpoint for a given + function. This always is the function name. + """ + assert view_func is not None, "expected view func if endpoint is not provided." + return view_func.__name__ + + +def _find_package_path(import_name: str) -> str: + """Find the path that contains the package or module.""" + root_mod_name, _, _ = import_name.partition(".") + + try: + root_spec = importlib.util.find_spec(root_mod_name) + + if root_spec is None: + raise ValueError("not found") + except (ImportError, ValueError): + # ImportError: the machinery told us it does not exist + # ValueError: + # - the module name was invalid + # - the module name is __main__ + # - we raised `ValueError` due to `root_spec` being `None` + return os.getcwd() + + if root_spec.submodule_search_locations: + if root_spec.origin is None or root_spec.origin == "namespace": + # namespace package + package_spec = importlib.util.find_spec(import_name) + + if package_spec is not None and package_spec.submodule_search_locations: + # Pick the path in the namespace that contains the submodule. + package_path = pathlib.Path( + os.path.commonpath(package_spec.submodule_search_locations) + ) + search_location = next( + location + for location in root_spec.submodule_search_locations + if package_path.is_relative_to(location) + ) + else: + # Pick the first path. + search_location = root_spec.submodule_search_locations[0] + + return os.path.dirname(search_location) + else: + # package with __init__.py + return os.path.dirname(os.path.dirname(root_spec.origin)) + else: + # module + return os.path.dirname(root_spec.origin) # type: ignore[type-var, return-value] + + +def find_package(import_name: str) -> tuple[str | None, str]: + """Find the prefix that a package is installed under, and the path + that it would be imported from. + + The prefix is the directory containing the standard directory + hierarchy (lib, bin, etc.). If the package is not installed to the + system (:attr:`sys.prefix`) or a virtualenv (``site-packages``), + ``None`` is returned. + + The path is the entry in :attr:`sys.path` that contains the package + for import. If the package is not installed, it's assumed that the + package was imported from the current working directory. + """ + package_path = _find_package_path(import_name) + py_prefix = os.path.abspath(sys.prefix) + + # installed to the system + if pathlib.PurePath(package_path).is_relative_to(py_prefix): + return py_prefix, package_path + + site_parent, site_folder = os.path.split(package_path) + + # installed to a virtualenv + if site_folder.lower() == "site-packages": + parent, folder = os.path.split(site_parent) + + # Windows (prefix/lib/site-packages) + if folder.lower() == "lib": + return parent, package_path + + # Unix (prefix/lib/pythonX.Y/site-packages) + if os.path.basename(parent).lower() == "lib": + return os.path.dirname(parent), package_path + + # something else (prefix/site-packages) + return site_parent, package_path + + # not installed + return None, package_path diff --git a/venv/lib/python3.12/site-packages/flask/sessions.py b/venv/lib/python3.12/site-packages/flask/sessions.py new file mode 100644 index 0000000..375de06 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/sessions.py @@ -0,0 +1,398 @@ +from __future__ import annotations + +import collections.abc as c +import hashlib +import typing as t +from collections.abc import MutableMapping +from datetime import datetime +from datetime import timezone + +from itsdangerous import BadSignature +from itsdangerous import URLSafeTimedSerializer +from werkzeug.datastructures import CallbackDict + +from .json.tag import TaggedJSONSerializer + +if t.TYPE_CHECKING: # pragma: no cover + import typing_extensions as te + + from .app import Flask + from .wrappers import Request + from .wrappers import Response + + +class SessionMixin(MutableMapping[str, t.Any]): + """Expands a basic dictionary with session attributes.""" + + @property + def permanent(self) -> bool: + """This reflects the ``'_permanent'`` key in the dict.""" + return self.get("_permanent", False) + + @permanent.setter + def permanent(self, value: bool) -> None: + self["_permanent"] = bool(value) + + #: Some implementations can detect whether a session is newly + #: created, but that is not guaranteed. Use with caution. The mixin + # default is hard-coded ``False``. + new = False + + #: Some implementations can detect changes to the session and set + #: this when that happens. The mixin default is hard coded to + #: ``True``. + modified = True + + #: Some implementations can detect when session data is read or + #: written and set this when that happens. The mixin default is hard + #: coded to ``True``. + accessed = True + + +class SecureCookieSession(CallbackDict[str, t.Any], SessionMixin): + """Base class for sessions based on signed cookies. + + This session backend will set the :attr:`modified` and + :attr:`accessed` attributes. It cannot reliably track whether a + session is new (vs. empty), so :attr:`new` remains hard coded to + ``False``. + """ + + #: When data is changed, this is set to ``True``. Only the session + #: dictionary itself is tracked; if the session contains mutable + #: data (for example a nested dict) then this must be set to + #: ``True`` manually when modifying that data. The session cookie + #: will only be written to the response if this is ``True``. + modified = False + + #: When data is read or written, this is set to ``True``. Used by + # :class:`.SecureCookieSessionInterface` to add a ``Vary: Cookie`` + #: header, which allows caching proxies to cache different pages for + #: different users. + accessed = False + + def __init__( + self, + initial: c.Mapping[str, t.Any] | c.Iterable[tuple[str, t.Any]] | None = None, + ) -> None: + def on_update(self: te.Self) -> None: + self.modified = True + self.accessed = True + + super().__init__(initial, on_update) + + def __getitem__(self, key: str) -> t.Any: + self.accessed = True + return super().__getitem__(key) + + def get(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().get(key, default) + + def setdefault(self, key: str, default: t.Any = None) -> t.Any: + self.accessed = True + return super().setdefault(key, default) + + +class NullSession(SecureCookieSession): + """Class used to generate nicer error messages if sessions are not + available. Will still allow read-only access to the empty session + but fail on setting. + """ + + def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn: + raise RuntimeError( + "The session is unavailable because no secret " + "key was set. Set the secret_key on the " + "application to something unique and secret." + ) + + __setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950 + del _fail + + +class SessionInterface: + """The basic interface you have to implement in order to replace the + default session interface which uses werkzeug's securecookie + implementation. The only methods you have to implement are + :meth:`open_session` and :meth:`save_session`, the others have + useful defaults which you don't need to change. + + The session object returned by the :meth:`open_session` method has to + provide a dictionary like interface plus the properties and methods + from the :class:`SessionMixin`. We recommend just subclassing a dict + and adding that mixin:: + + class Session(dict, SessionMixin): + pass + + If :meth:`open_session` returns ``None`` Flask will call into + :meth:`make_null_session` to create a session that acts as replacement + if the session support cannot work because some requirement is not + fulfilled. The default :class:`NullSession` class that is created + will complain that the secret key was not set. + + To replace the session interface on an application all you have to do + is to assign :attr:`flask.Flask.session_interface`:: + + app = Flask(__name__) + app.session_interface = MySessionInterface() + + Multiple requests with the same session may be sent and handled + concurrently. When implementing a new session interface, consider + whether reads or writes to the backing store must be synchronized. + There is no guarantee on the order in which the session for each + request is opened or saved, it will occur in the order that requests + begin and end processing. + + .. versionadded:: 0.8 + """ + + #: :meth:`make_null_session` will look here for the class that should + #: be created when a null session is requested. Likewise the + #: :meth:`is_null_session` method will perform a typecheck against + #: this type. + null_session_class = NullSession + + #: A flag that indicates if the session interface is pickle based. + #: This can be used by Flask extensions to make a decision in regards + #: to how to deal with the session object. + #: + #: .. versionadded:: 0.10 + pickle_based = False + + def make_null_session(self, app: Flask) -> NullSession: + """Creates a null session which acts as a replacement object if the + real session support could not be loaded due to a configuration + error. This mainly aids the user experience because the job of the + null session is to still support lookup without complaining but + modifications are answered with a helpful error message of what + failed. + + This creates an instance of :attr:`null_session_class` by default. + """ + return self.null_session_class() + + def is_null_session(self, obj: object) -> bool: + """Checks if a given object is a null session. Null sessions are + not asked to be saved. + + This checks if the object is an instance of :attr:`null_session_class` + by default. + """ + return isinstance(obj, self.null_session_class) + + def get_cookie_name(self, app: Flask) -> str: + """The name of the session cookie. Uses``app.config["SESSION_COOKIE_NAME"]``.""" + return app.config["SESSION_COOKIE_NAME"] # type: ignore[no-any-return] + + def get_cookie_domain(self, app: Flask) -> str | None: + """The value of the ``Domain`` parameter on the session cookie. If not set, + browsers will only send the cookie to the exact domain it was set from. + Otherwise, they will send it to any subdomain of the given value as well. + + Uses the :data:`SESSION_COOKIE_DOMAIN` config. + + .. versionchanged:: 2.3 + Not set by default, does not fall back to ``SERVER_NAME``. + """ + return app.config["SESSION_COOKIE_DOMAIN"] # type: ignore[no-any-return] + + def get_cookie_path(self, app: Flask) -> str: + """Returns the path for which the cookie should be valid. The + default implementation uses the value from the ``SESSION_COOKIE_PATH`` + config var if it's set, and falls back to ``APPLICATION_ROOT`` or + uses ``/`` if it's ``None``. + """ + return app.config["SESSION_COOKIE_PATH"] or app.config["APPLICATION_ROOT"] # type: ignore[no-any-return] + + def get_cookie_httponly(self, app: Flask) -> bool: + """Returns True if the session cookie should be httponly. This + currently just returns the value of the ``SESSION_COOKIE_HTTPONLY`` + config var. + """ + return app.config["SESSION_COOKIE_HTTPONLY"] # type: ignore[no-any-return] + + def get_cookie_secure(self, app: Flask) -> bool: + """Returns True if the cookie should be secure. This currently + just returns the value of the ``SESSION_COOKIE_SECURE`` setting. + """ + return app.config["SESSION_COOKIE_SECURE"] # type: ignore[no-any-return] + + def get_cookie_samesite(self, app: Flask) -> str | None: + """Return ``'Strict'`` or ``'Lax'`` if the cookie should use the + ``SameSite`` attribute. This currently just returns the value of + the :data:`SESSION_COOKIE_SAMESITE` setting. + """ + return app.config["SESSION_COOKIE_SAMESITE"] # type: ignore[no-any-return] + + def get_cookie_partitioned(self, app: Flask) -> bool: + """Returns True if the cookie should be partitioned. By default, uses + the value of :data:`SESSION_COOKIE_PARTITIONED`. + + .. versionadded:: 3.1 + """ + return app.config["SESSION_COOKIE_PARTITIONED"] # type: ignore[no-any-return] + + def get_expiration_time(self, app: Flask, session: SessionMixin) -> datetime | None: + """A helper method that returns an expiration date for the session + or ``None`` if the session is linked to the browser session. The + default implementation returns now + the permanent session + lifetime configured on the application. + """ + if session.permanent: + return datetime.now(timezone.utc) + app.permanent_session_lifetime + return None + + def should_set_cookie(self, app: Flask, session: SessionMixin) -> bool: + """Used by session backends to determine if a ``Set-Cookie`` header + should be set for this session cookie for this response. If the session + has been modified, the cookie is set. If the session is permanent and + the ``SESSION_REFRESH_EACH_REQUEST`` config is true, the cookie is + always set. + + This check is usually skipped if the session was deleted. + + .. versionadded:: 0.11 + """ + + return session.modified or ( + session.permanent and app.config["SESSION_REFRESH_EACH_REQUEST"] + ) + + def open_session(self, app: Flask, request: Request) -> SessionMixin | None: + """This is called at the beginning of each request, after + pushing the request context, before matching the URL. + + This must return an object which implements a dictionary-like + interface as well as the :class:`SessionMixin` interface. + + This will return ``None`` to indicate that loading failed in + some way that is not immediately an error. The request + context will fall back to using :meth:`make_null_session` + in this case. + """ + raise NotImplementedError() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + """This is called at the end of each request, after generating + a response, before removing the request context. It is skipped + if :meth:`is_null_session` returns ``True``. + """ + raise NotImplementedError() + + +session_json_serializer = TaggedJSONSerializer() + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +class SecureCookieSessionInterface(SessionInterface): + """The default session interface that stores sessions in signed cookies + through the :mod:`itsdangerous` module. + """ + + #: the salt that should be applied on top of the secret key for the + #: signing of cookie based sessions. + salt = "cookie-session" + #: the hash function to use for the signature. The default is sha1 + digest_method = staticmethod(_lazy_sha1) + #: the name of the itsdangerous supported key derivation. The default + #: is hmac. + key_derivation = "hmac" + #: A python serializer for the payload. The default is a compact + #: JSON derived serializer with support for some extra Python types + #: such as datetime objects or tuples. + serializer = session_json_serializer + session_class = SecureCookieSession + + def get_signing_serializer(self, app: Flask) -> URLSafeTimedSerializer | None: + if not app.secret_key: + return None + + keys: list[str | bytes] = [app.secret_key] + + if fallbacks := app.config["SECRET_KEY_FALLBACKS"]: + keys.extend(fallbacks) + + return URLSafeTimedSerializer( + keys, # type: ignore[arg-type] + salt=self.salt, + serializer=self.serializer, + signer_kwargs={ + "key_derivation": self.key_derivation, + "digest_method": self.digest_method, + }, + ) + + def open_session(self, app: Flask, request: Request) -> SecureCookieSession | None: + s = self.get_signing_serializer(app) + if s is None: + return None + val = request.cookies.get(self.get_cookie_name(app)) + if not val: + return self.session_class() + max_age = int(app.permanent_session_lifetime.total_seconds()) + try: + data = s.loads(val, max_age=max_age) + return self.session_class(data) + except BadSignature: + return self.session_class() + + def save_session( + self, app: Flask, session: SessionMixin, response: Response + ) -> None: + name = self.get_cookie_name(app) + domain = self.get_cookie_domain(app) + path = self.get_cookie_path(app) + secure = self.get_cookie_secure(app) + partitioned = self.get_cookie_partitioned(app) + samesite = self.get_cookie_samesite(app) + httponly = self.get_cookie_httponly(app) + + # Add a "Vary: Cookie" header if the session was accessed at all. + if session.accessed: + response.vary.add("Cookie") + + # If the session is modified to be empty, remove the cookie. + # If the session is empty, return without setting the cookie. + if not session: + if session.modified: + response.delete_cookie( + name, + domain=domain, + path=path, + secure=secure, + partitioned=partitioned, + samesite=samesite, + httponly=httponly, + ) + response.vary.add("Cookie") + + return + + if not self.should_set_cookie(app, session): + return + + expires = self.get_expiration_time(app, session) + val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore[union-attr] + response.set_cookie( + name, + val, + expires=expires, + httponly=httponly, + domain=domain, + path=path, + secure=secure, + partitioned=partitioned, + samesite=samesite, + ) + response.vary.add("Cookie") diff --git a/venv/lib/python3.12/site-packages/flask/signals.py b/venv/lib/python3.12/site-packages/flask/signals.py new file mode 100644 index 0000000..444fda9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/signals.py @@ -0,0 +1,17 @@ +from __future__ import annotations + +from blinker import Namespace + +# This namespace is only for signals provided by Flask itself. +_signals = Namespace() + +template_rendered = _signals.signal("template-rendered") +before_render_template = _signals.signal("before-render-template") +request_started = _signals.signal("request-started") +request_finished = _signals.signal("request-finished") +request_tearing_down = _signals.signal("request-tearing-down") +got_request_exception = _signals.signal("got-request-exception") +appcontext_tearing_down = _signals.signal("appcontext-tearing-down") +appcontext_pushed = _signals.signal("appcontext-pushed") +appcontext_popped = _signals.signal("appcontext-popped") +message_flashed = _signals.signal("message-flashed") diff --git a/venv/lib/python3.12/site-packages/flask/templating.py b/venv/lib/python3.12/site-packages/flask/templating.py new file mode 100644 index 0000000..618a3b3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/templating.py @@ -0,0 +1,219 @@ +from __future__ import annotations + +import typing as t + +from jinja2 import BaseLoader +from jinja2 import Environment as BaseEnvironment +from jinja2 import Template +from jinja2 import TemplateNotFound + +from .globals import _cv_app +from .globals import _cv_request +from .globals import current_app +from .globals import request +from .helpers import stream_with_context +from .signals import before_render_template +from .signals import template_rendered + +if t.TYPE_CHECKING: # pragma: no cover + from .app import Flask + from .sansio.app import App + from .sansio.scaffold import Scaffold + + +def _default_template_ctx_processor() -> dict[str, t.Any]: + """Default template context processor. Injects `request`, + `session` and `g`. + """ + appctx = _cv_app.get(None) + reqctx = _cv_request.get(None) + rv: dict[str, t.Any] = {} + if appctx is not None: + rv["g"] = appctx.g + if reqctx is not None: + rv["request"] = reqctx.request + rv["session"] = reqctx.session + return rv + + +class Environment(BaseEnvironment): + """Works like a regular Jinja2 environment but has some additional + knowledge of how Flask's blueprint works so that it can prepend the + name of the blueprint to referenced templates if necessary. + """ + + def __init__(self, app: App, **options: t.Any) -> None: + if "loader" not in options: + options["loader"] = app.create_global_jinja_loader() + BaseEnvironment.__init__(self, **options) + self.app = app + + +class DispatchingJinjaLoader(BaseLoader): + """A loader that looks for templates in the application and all + the blueprint folders. + """ + + def __init__(self, app: App) -> None: + self.app = app + + def get_source( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + if self.app.config["EXPLAIN_TEMPLATE_LOADING"]: + return self._get_source_explained(environment, template) + return self._get_source_fast(environment, template) + + def _get_source_explained( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + attempts = [] + rv: tuple[str, str | None, t.Callable[[], bool] | None] | None + trv: None | (tuple[str, str | None, t.Callable[[], bool] | None]) = None + + for srcobj, loader in self._iter_loaders(template): + try: + rv = loader.get_source(environment, template) + if trv is None: + trv = rv + except TemplateNotFound: + rv = None + attempts.append((loader, srcobj, rv)) + + from .debughelpers import explain_template_loading_attempts + + explain_template_loading_attempts(self.app, template, attempts) + + if trv is not None: + return trv + raise TemplateNotFound(template) + + def _get_source_fast( + self, environment: BaseEnvironment, template: str + ) -> tuple[str, str | None, t.Callable[[], bool] | None]: + for _srcobj, loader in self._iter_loaders(template): + try: + return loader.get_source(environment, template) + except TemplateNotFound: + continue + raise TemplateNotFound(template) + + def _iter_loaders(self, template: str) -> t.Iterator[tuple[Scaffold, BaseLoader]]: + loader = self.app.jinja_loader + if loader is not None: + yield self.app, loader + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + yield blueprint, loader + + def list_templates(self) -> list[str]: + result = set() + loader = self.app.jinja_loader + if loader is not None: + result.update(loader.list_templates()) + + for blueprint in self.app.iter_blueprints(): + loader = blueprint.jinja_loader + if loader is not None: + for template in loader.list_templates(): + result.add(template) + + return list(result) + + +def _render(app: Flask, template: Template, context: dict[str, t.Any]) -> str: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + rv = template.render(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + return rv + + +def render_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> str: + """Render a template by name with the given context. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _render(app, template, context) + + +def render_template_string(source: str, **context: t.Any) -> str: + """Render a template from the given source string with the given + context. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _render(app, template, context) + + +def _stream( + app: Flask, template: Template, context: dict[str, t.Any] +) -> t.Iterator[str]: + app.update_template_context(context) + before_render_template.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + def generate() -> t.Iterator[str]: + yield from template.generate(context) + template_rendered.send( + app, _async_wrapper=app.ensure_sync, template=template, context=context + ) + + rv = generate() + + # If a request context is active, keep it while generating. + if request: + rv = stream_with_context(rv) + + return rv + + +def stream_template( + template_name_or_list: str | Template | list[str | Template], + **context: t.Any, +) -> t.Iterator[str]: + """Render a template by name with the given context as a stream. + This returns an iterator of strings, which can be used as a + streaming response from a view. + + :param template_name_or_list: The name of the template to render. If + a list is given, the first name to exist will be rendered. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.get_or_select_template(template_name_or_list) + return _stream(app, template, context) + + +def stream_template_string(source: str, **context: t.Any) -> t.Iterator[str]: + """Render a template from the given source string with the given + context as a stream. This returns an iterator of strings, which can + be used as a streaming response from a view. + + :param source: The source code of the template to render. + :param context: The variables to make available in the template. + + .. versionadded:: 2.2 + """ + app = current_app._get_current_object() # type: ignore[attr-defined] + template = app.jinja_env.from_string(source) + return _stream(app, template, context) diff --git a/venv/lib/python3.12/site-packages/flask/testing.py b/venv/lib/python3.12/site-packages/flask/testing.py new file mode 100644 index 0000000..602b773 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/testing.py @@ -0,0 +1,297 @@ +from __future__ import annotations + +import importlib.metadata +import typing as t +from contextlib import contextmanager +from contextlib import ExitStack +from copy import copy +from types import TracebackType +from urllib.parse import urlsplit + +import werkzeug.test +from click.testing import CliRunner +from werkzeug.test import Client +from werkzeug.wrappers import Request as BaseRequest + +from .cli import ScriptInfo +from .sessions import SessionMixin + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIEnvironment + from werkzeug.test import TestResponse + + from .app import Flask + + +class EnvironBuilder(werkzeug.test.EnvironBuilder): + """An :class:`~werkzeug.test.EnvironBuilder`, that takes defaults from the + application. + + :param app: The Flask application to configure the environment from. + :param path: URL path being requested. + :param base_url: Base URL where the app is being served, which + ``path`` is relative to. If not given, built from + :data:`PREFERRED_URL_SCHEME`, ``subdomain``, + :data:`SERVER_NAME`, and :data:`APPLICATION_ROOT`. + :param subdomain: Subdomain name to append to :data:`SERVER_NAME`. + :param url_scheme: Scheme to use instead of + :data:`PREFERRED_URL_SCHEME`. + :param json: If given, this is serialized as JSON and passed as + ``data``. Also defaults ``content_type`` to + ``application/json``. + :param args: other positional arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + :param kwargs: other keyword arguments passed to + :class:`~werkzeug.test.EnvironBuilder`. + """ + + def __init__( + self, + app: Flask, + path: str = "/", + base_url: str | None = None, + subdomain: str | None = None, + url_scheme: str | None = None, + *args: t.Any, + **kwargs: t.Any, + ) -> None: + assert not (base_url or subdomain or url_scheme) or ( + base_url is not None + ) != bool( + subdomain or url_scheme + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + + if base_url is None: + http_host = app.config.get("SERVER_NAME") or "localhost" + app_root = app.config["APPLICATION_ROOT"] + + if subdomain: + http_host = f"{subdomain}.{http_host}" + + if url_scheme is None: + url_scheme = app.config["PREFERRED_URL_SCHEME"] + + url = urlsplit(path) + base_url = ( + f"{url.scheme or url_scheme}://{url.netloc or http_host}" + f"/{app_root.lstrip('/')}" + ) + path = url.path + + if url.query: + path = f"{path}?{url.query}" + + self.app = app + super().__init__(path, base_url, *args, **kwargs) + + def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore + """Serialize ``obj`` to a JSON-formatted string. + + The serialization will be configured according to the config associated + with this EnvironBuilder's ``app``. + """ + return self.app.json.dumps(obj, **kwargs) + + +_werkzeug_version = "" + + +def _get_werkzeug_version() -> str: + global _werkzeug_version + + if not _werkzeug_version: + _werkzeug_version = importlib.metadata.version("werkzeug") + + return _werkzeug_version + + +class FlaskClient(Client): + """Works like a regular Werkzeug test client but has knowledge about + Flask's contexts to defer the cleanup of the request context until + the end of a ``with`` block. For general information about how to + use this class refer to :class:`werkzeug.test.Client`. + + .. versionchanged:: 0.12 + `app.test_client()` includes preset default environment, which can be + set after instantiation of the `app.test_client()` object in + `client.environ_base`. + + Basic usage is outlined in the :doc:`/testing` chapter. + """ + + application: Flask + + def __init__(self, *args: t.Any, **kwargs: t.Any) -> None: + super().__init__(*args, **kwargs) + self.preserve_context = False + self._new_contexts: list[t.ContextManager[t.Any]] = [] + self._context_stack = ExitStack() + self.environ_base = { + "REMOTE_ADDR": "127.0.0.1", + "HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}", + } + + @contextmanager + def session_transaction( + self, *args: t.Any, **kwargs: t.Any + ) -> t.Iterator[SessionMixin]: + """When used in combination with a ``with`` statement this opens a + session transaction. This can be used to modify the session that + the test client uses. Once the ``with`` block is left the session is + stored back. + + :: + + with client.session_transaction() as session: + session['value'] = 42 + + Internally this is implemented by going through a temporary test + request context and since session handling could depend on + request variables this function accepts the same arguments as + :meth:`~flask.Flask.test_request_context` which are directly + passed through. + """ + if self._cookies is None: + raise TypeError( + "Cookies are disabled. Create a client with 'use_cookies=True'." + ) + + app = self.application + ctx = app.test_request_context(*args, **kwargs) + self._add_cookies_to_wsgi(ctx.request.environ) + + with ctx: + sess = app.session_interface.open_session(app, ctx.request) + + if sess is None: + raise RuntimeError("Session backend did not open a session.") + + yield sess + resp = app.response_class() + + if app.session_interface.is_null_session(sess): + return + + with ctx: + app.session_interface.save_session(app, sess, resp) + + self._update_cookies_from_response( + ctx.request.host.partition(":")[0], + ctx.request.path, + resp.headers.getlist("Set-Cookie"), + ) + + def _copy_environ(self, other: WSGIEnvironment) -> WSGIEnvironment: + out = {**self.environ_base, **other} + + if self.preserve_context: + out["werkzeug.debug.preserve_context"] = self._new_contexts.append + + return out + + def _request_from_builder_args( + self, args: tuple[t.Any, ...], kwargs: dict[str, t.Any] + ) -> BaseRequest: + kwargs["environ_base"] = self._copy_environ(kwargs.get("environ_base", {})) + builder = EnvironBuilder(self.application, *args, **kwargs) + + try: + return builder.get_request() + finally: + builder.close() + + def open( + self, + *args: t.Any, + buffered: bool = False, + follow_redirects: bool = False, + **kwargs: t.Any, + ) -> TestResponse: + if args and isinstance( + args[0], (werkzeug.test.EnvironBuilder, dict, BaseRequest) + ): + if isinstance(args[0], werkzeug.test.EnvironBuilder): + builder = copy(args[0]) + builder.environ_base = self._copy_environ(builder.environ_base or {}) # type: ignore[arg-type] + request = builder.get_request() + elif isinstance(args[0], dict): + request = EnvironBuilder.from_environ( + args[0], app=self.application, environ_base=self._copy_environ({}) + ).get_request() + else: + # isinstance(args[0], BaseRequest) + request = copy(args[0]) + request.environ = self._copy_environ(request.environ) + else: + # request is None + request = self._request_from_builder_args(args, kwargs) + + # Pop any previously preserved contexts. This prevents contexts + # from being preserved across redirects or multiple requests + # within a single block. + self._context_stack.close() + + response = super().open( + request, + buffered=buffered, + follow_redirects=follow_redirects, + ) + response.json_module = self.application.json # type: ignore[assignment] + + # Re-push contexts that were preserved during the request. + while self._new_contexts: + cm = self._new_contexts.pop() + self._context_stack.enter_context(cm) + + return response + + def __enter__(self) -> FlaskClient: + if self.preserve_context: + raise RuntimeError("Cannot nest client invocations") + self.preserve_context = True + return self + + def __exit__( + self, + exc_type: type | None, + exc_value: BaseException | None, + tb: TracebackType | None, + ) -> None: + self.preserve_context = False + self._context_stack.close() + + +class FlaskCliRunner(CliRunner): + """A :class:`~click.testing.CliRunner` for testing a Flask app's + CLI commands. Typically created using + :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`. + """ + + def __init__(self, app: Flask, **kwargs: t.Any) -> None: + self.app = app + super().__init__(**kwargs) + + def invoke( # type: ignore + self, cli: t.Any = None, args: t.Any = None, **kwargs: t.Any + ) -> t.Any: + """Invokes a CLI command in an isolated environment. See + :meth:`CliRunner.invoke ` for + full method documentation. See :ref:`testing-cli` for examples. + + If the ``obj`` argument is not given, passes an instance of + :class:`~flask.cli.ScriptInfo` that knows how to load the Flask + app being tested. + + :param cli: Command object to invoke. Default is the app's + :attr:`~flask.app.Flask.cli` group. + :param args: List of strings to invoke the command with. + + :return: a :class:`~click.testing.Result` object. + """ + if cli is None: + cli = self.app.cli + + if "obj" not in kwargs: + kwargs["obj"] = ScriptInfo(create_app=lambda: self.app) + + return super().invoke(cli, args, **kwargs) diff --git a/venv/lib/python3.12/site-packages/flask/typing.py b/venv/lib/python3.12/site-packages/flask/typing.py new file mode 100644 index 0000000..e7234e9 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/typing.py @@ -0,0 +1,90 @@ +from __future__ import annotations + +import typing as t + +if t.TYPE_CHECKING: # pragma: no cover + from _typeshed.wsgi import WSGIApplication # noqa: F401 + from werkzeug.datastructures import Headers # noqa: F401 + from werkzeug.sansio.response import Response # noqa: F401 + +# The possible types that are directly convertible or are a Response object. +ResponseValue = t.Union[ + "Response", + str, + bytes, + list[t.Any], + # Only dict is actually accepted, but Mapping allows for TypedDict. + t.Mapping[str, t.Any], + t.Iterator[str], + t.Iterator[bytes], +] + +# the possible types for an individual HTTP header +# This should be a Union, but mypy doesn't pass unless it's a TypeVar. +HeaderValue = t.Union[str, list[str], tuple[str, ...]] + +# the possible types for HTTP headers +HeadersValue = t.Union[ + "Headers", + t.Mapping[str, HeaderValue], + t.Sequence[tuple[str, HeaderValue]], +] + +# The possible types returned by a route function. +ResponseReturnValue = t.Union[ + ResponseValue, + tuple[ResponseValue, HeadersValue], + tuple[ResponseValue, int], + tuple[ResponseValue, int, HeadersValue], + "WSGIApplication", +] + +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + +AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named +AfterRequestCallable = t.Union[ + t.Callable[[ResponseClass], ResponseClass], + t.Callable[[ResponseClass], t.Awaitable[ResponseClass]], +] +BeforeFirstRequestCallable = t.Union[ + t.Callable[[], None], t.Callable[[], t.Awaitable[None]] +] +BeforeRequestCallable = t.Union[ + t.Callable[[], t.Optional[ResponseReturnValue]], + t.Callable[[], t.Awaitable[t.Optional[ResponseReturnValue]]], +] +ShellContextProcessorCallable = t.Callable[[], dict[str, t.Any]] +TeardownCallable = t.Union[ + t.Callable[[t.Optional[BaseException]], None], + t.Callable[[t.Optional[BaseException]], t.Awaitable[None]], +] +TemplateContextProcessorCallable = t.Union[ + t.Callable[[], dict[str, t.Any]], + t.Callable[[], t.Awaitable[dict[str, t.Any]]], +] +TemplateFilterCallable = t.Callable[..., t.Any] +TemplateGlobalCallable = t.Callable[..., t.Any] +TemplateTestCallable = t.Callable[..., bool] +URLDefaultCallable = t.Callable[[str, dict[str, t.Any]], None] +URLValuePreprocessorCallable = t.Callable[ + [t.Optional[str], t.Optional[dict[str, t.Any]]], None +] + +# This should take Exception, but that either breaks typing the argument +# with a specific exception, or decorating multiple times with different +# exceptions (and using a union type on the argument). +# https://github.com/pallets/flask/issues/4095 +# https://github.com/pallets/flask/issues/4295 +# https://github.com/pallets/flask/issues/4297 +ErrorHandlerCallable = t.Union[ + t.Callable[[t.Any], ResponseReturnValue], + t.Callable[[t.Any], t.Awaitable[ResponseReturnValue]], +] + +RouteCallable = t.Union[ + t.Callable[..., ResponseReturnValue], + t.Callable[..., t.Awaitable[ResponseReturnValue]], +] diff --git a/venv/lib/python3.12/site-packages/flask/views.py b/venv/lib/python3.12/site-packages/flask/views.py new file mode 100644 index 0000000..53fe976 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/views.py @@ -0,0 +1,191 @@ +from __future__ import annotations + +import typing as t + +from . import typing as ft +from .globals import current_app +from .globals import request + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +http_method_funcs = frozenset( + ["get", "post", "head", "options", "delete", "put", "trace", "patch"] +) + + +class View: + """Subclass this class and override :meth:`dispatch_request` to + create a generic class-based view. Call :meth:`as_view` to create a + view function that creates an instance of the class with the given + arguments and calls its ``dispatch_request`` method with any URL + variables. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class Hello(View): + init_every_request = False + + def dispatch_request(self, name): + return f"Hello, {name}!" + + app.add_url_rule( + "/hello/", view_func=Hello.as_view("hello") + ) + + Set :attr:`methods` on the class to change what methods the view + accepts. + + Set :attr:`decorators` on the class to apply a list of decorators to + the generated view function. Decorators applied to the class itself + will not be applied to the generated view function! + + Set :attr:`init_every_request` to ``False`` for efficiency, unless + you need to store request-global data on ``self``. + """ + + #: The methods this view is registered for. Uses the same default + #: (``["GET", "HEAD", "OPTIONS"]``) as ``route`` and + #: ``add_url_rule`` by default. + methods: t.ClassVar[t.Collection[str] | None] = None + + #: Control whether the ``OPTIONS`` method is handled automatically. + #: Uses the same default (``True``) as ``route`` and + #: ``add_url_rule`` by default. + provide_automatic_options: t.ClassVar[bool | None] = None + + #: A list of decorators to apply, in order, to the generated view + #: function. Remember that ``@decorator`` syntax is applied bottom + #: to top, so the first decorator in the list would be the bottom + #: decorator. + #: + #: .. versionadded:: 0.8 + decorators: t.ClassVar[list[t.Callable[..., t.Any]]] = [] + + #: Create a new instance of this view class for every request by + #: default. If a view subclass sets this to ``False``, the same + #: instance is used for every request. + #: + #: A single instance is more efficient, especially if complex setup + #: is done during init. However, storing data on ``self`` is no + #: longer safe across requests, and :data:`~flask.g` should be used + #: instead. + #: + #: .. versionadded:: 2.2 + init_every_request: t.ClassVar[bool] = True + + def dispatch_request(self) -> ft.ResponseReturnValue: + """The actual view function behavior. Subclasses must override + this and return a valid response. Any variables from the URL + rule are passed as keyword arguments. + """ + raise NotImplementedError() + + @classmethod + def as_view( + cls, name: str, *class_args: t.Any, **class_kwargs: t.Any + ) -> ft.RouteCallable: + """Convert the class into a view function that can be registered + for a route. + + By default, the generated view will create a new instance of the + view class for every request and call its + :meth:`dispatch_request` method. If the view class sets + :attr:`init_every_request` to ``False``, the same instance will + be used for every request. + + Except for ``name``, all other arguments passed to this method + are forwarded to the view class ``__init__`` method. + + .. versionchanged:: 2.2 + Added the ``init_every_request`` class attribute. + """ + if cls.init_every_request: + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + self = view.view_class( # type: ignore[attr-defined] + *class_args, **class_kwargs + ) + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + else: + self = cls(*class_args, **class_kwargs) # pyright: ignore + + def view(**kwargs: t.Any) -> ft.ResponseReturnValue: + return current_app.ensure_sync(self.dispatch_request)(**kwargs) # type: ignore[no-any-return] + + if cls.decorators: + view.__name__ = name + view.__module__ = cls.__module__ + for decorator in cls.decorators: + view = decorator(view) + + # We attach the view class to the view function for two reasons: + # first of all it allows us to easily figure out what class-based + # view this thing came from, secondly it's also used for instantiating + # the view class so you can actually replace it with something else + # for testing purposes and debugging. + view.view_class = cls # type: ignore + view.__name__ = name + view.__doc__ = cls.__doc__ + view.__module__ = cls.__module__ + view.methods = cls.methods # type: ignore + view.provide_automatic_options = cls.provide_automatic_options # type: ignore + return view + + +class MethodView(View): + """Dispatches request methods to the corresponding instance methods. + For example, if you implement a ``get`` method, it will be used to + handle ``GET`` requests. + + This can be useful for defining a REST API. + + :attr:`methods` is automatically set based on the methods defined on + the class. + + See :doc:`views` for a detailed guide. + + .. code-block:: python + + class CounterAPI(MethodView): + def get(self): + return str(session.get("counter", 0)) + + def post(self): + session["counter"] = session.get("counter", 0) + 1 + return redirect(url_for("counter")) + + app.add_url_rule( + "/counter", view_func=CounterAPI.as_view("counter") + ) + """ + + def __init_subclass__(cls, **kwargs: t.Any) -> None: + super().__init_subclass__(**kwargs) + + if "methods" not in cls.__dict__: + methods = set() + + for base in cls.__bases__: + if getattr(base, "methods", None): + methods.update(base.methods) # type: ignore[attr-defined] + + for key in http_method_funcs: + if hasattr(cls, key): + methods.add(key.upper()) + + if methods: + cls.methods = methods + + def dispatch_request(self, **kwargs: t.Any) -> ft.ResponseReturnValue: + meth = getattr(self, request.method.lower(), None) + + # If the request method is HEAD and we don't have a handler for it + # retry with GET. + if meth is None and request.method == "HEAD": + meth = getattr(self, "get", None) + + assert meth is not None, f"Unimplemented method {request.method!r}" + return current_app.ensure_sync(meth)(**kwargs) # type: ignore[no-any-return] diff --git a/venv/lib/python3.12/site-packages/flask/wrappers.py b/venv/lib/python3.12/site-packages/flask/wrappers.py new file mode 100644 index 0000000..bab6102 --- /dev/null +++ b/venv/lib/python3.12/site-packages/flask/wrappers.py @@ -0,0 +1,257 @@ +from __future__ import annotations + +import typing as t + +from werkzeug.exceptions import BadRequest +from werkzeug.exceptions import HTTPException +from werkzeug.wrappers import Request as RequestBase +from werkzeug.wrappers import Response as ResponseBase + +from . import json +from .globals import current_app +from .helpers import _split_blueprint_path + +if t.TYPE_CHECKING: # pragma: no cover + from werkzeug.routing import Rule + + +class Request(RequestBase): + """The request object used by default in Flask. Remembers the + matched endpoint and view arguments. + + It is what ends up as :class:`~flask.request`. If you want to replace + the request object used you can subclass this and set + :attr:`~flask.Flask.request_class` to your subclass. + + The request object is a :class:`~werkzeug.wrappers.Request` subclass and + provides all of the attributes Werkzeug defines plus a few Flask + specific ones. + """ + + json_module: t.Any = json + + #: The internal URL rule that matched the request. This can be + #: useful to inspect which methods are allowed for the URL from + #: a before/after handler (``request.url_rule.methods``) etc. + #: Though if the request's method was invalid for the URL rule, + #: the valid list is available in ``routing_exception.valid_methods`` + #: instead (an attribute of the Werkzeug exception + #: :exc:`~werkzeug.exceptions.MethodNotAllowed`) + #: because the request was never internally bound. + #: + #: .. versionadded:: 0.6 + url_rule: Rule | None = None + + #: A dict of view arguments that matched the request. If an exception + #: happened when matching, this will be ``None``. + view_args: dict[str, t.Any] | None = None + + #: If matching the URL failed, this is the exception that will be + #: raised / was raised as part of the request handling. This is + #: usually a :exc:`~werkzeug.exceptions.NotFound` exception or + #: something similar. + routing_exception: HTTPException | None = None + + _max_content_length: int | None = None + _max_form_memory_size: int | None = None + _max_form_parts: int | None = None + + @property + def max_content_length(self) -> int | None: + """The maximum number of bytes that will be read during this request. If + this limit is exceeded, a 413 :exc:`~werkzeug.exceptions.RequestEntityTooLarge` + error is raised. If it is set to ``None``, no limit is enforced at the + Flask application level. However, if it is ``None`` and the request has + no ``Content-Length`` header and the WSGI server does not indicate that + it terminates the stream, then no data is read to avoid an infinite + stream. + + Each request defaults to the :data:`MAX_CONTENT_LENGTH` config, which + defaults to ``None``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This can be set per-request. + + .. versionchanged:: 0.6 + This is configurable through Flask config. + """ + if self._max_content_length is not None: + return self._max_content_length + + if not current_app: + return super().max_content_length + + return current_app.config["MAX_CONTENT_LENGTH"] # type: ignore[no-any-return] + + @max_content_length.setter + def max_content_length(self, value: int | None) -> None: + self._max_content_length = value + + @property + def max_form_memory_size(self) -> int | None: + """The maximum size in bytes any non-file form field may be in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_MEMORY_SIZE` config, which + defaults to ``500_000``. It can be set on a specific ``request`` to + apply the limit to that specific view. This should be set appropriately + based on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_memory_size is not None: + return self._max_form_memory_size + + if not current_app: + return super().max_form_memory_size + + return current_app.config["MAX_FORM_MEMORY_SIZE"] # type: ignore[no-any-return] + + @max_form_memory_size.setter + def max_form_memory_size(self, value: int | None) -> None: + self._max_form_memory_size = value + + @property # type: ignore[override] + def max_form_parts(self) -> int | None: + """The maximum number of fields that may be present in a + ``multipart/form-data`` body. If this limit is exceeded, a 413 + :exc:`~werkzeug.exceptions.RequestEntityTooLarge` error is raised. If it + is set to ``None``, no limit is enforced at the Flask application level. + + Each request defaults to the :data:`MAX_FORM_PARTS` config, which + defaults to ``1_000``. It can be set on a specific ``request`` to apply + the limit to that specific view. This should be set appropriately based + on an application's or view's specific needs. + + .. versionchanged:: 3.1 + This is configurable through Flask config. + """ + if self._max_form_parts is not None: + return self._max_form_parts + + if not current_app: + return super().max_form_parts + + return current_app.config["MAX_FORM_PARTS"] # type: ignore[no-any-return] + + @max_form_parts.setter + def max_form_parts(self, value: int | None) -> None: + self._max_form_parts = value + + @property + def endpoint(self) -> str | None: + """The endpoint that matched the request URL. + + This will be ``None`` if matching failed or has not been + performed yet. + + This in combination with :attr:`view_args` can be used to + reconstruct the same URL or a modified URL. + """ + if self.url_rule is not None: + return self.url_rule.endpoint # type: ignore[no-any-return] + + return None + + @property + def blueprint(self) -> str | None: + """The registered name of the current blueprint. + + This will be ``None`` if the endpoint is not part of a + blueprint, or if URL matching failed or has not been performed + yet. + + This does not necessarily match the name the blueprint was + created with. It may have been nested, or registered with a + different name. + """ + endpoint = self.endpoint + + if endpoint is not None and "." in endpoint: + return endpoint.rpartition(".")[0] + + return None + + @property + def blueprints(self) -> list[str]: + """The registered names of the current blueprint upwards through + parent blueprints. + + This will be an empty list if there is no current blueprint, or + if URL matching failed. + + .. versionadded:: 2.0.1 + """ + name = self.blueprint + + if name is None: + return [] + + return _split_blueprint_path(name) + + def _load_form_data(self) -> None: + super()._load_form_data() + + # In debug mode we're replacing the files multidict with an ad-hoc + # subclass that raises a different error for key errors. + if ( + current_app + and current_app.debug + and self.mimetype != "multipart/form-data" + and not self.files + ): + from .debughelpers import attach_enctype_error_multidict + + attach_enctype_error_multidict(self) + + def on_json_loading_failed(self, e: ValueError | None) -> t.Any: + try: + return super().on_json_loading_failed(e) + except BadRequest as ebr: + if current_app and current_app.debug: + raise + + raise BadRequest() from ebr + + +class Response(ResponseBase): + """The response object that is used by default in Flask. Works like the + response object from Werkzeug but is set to have an HTML mimetype by + default. Quite often you don't have to create this object yourself because + :meth:`~flask.Flask.make_response` will take care of that for you. + + If you want to replace the response object used you can subclass this and + set :attr:`~flask.Flask.response_class` to your subclass. + + .. versionchanged:: 1.0 + JSON support is added to the response, like the request. This is useful + when testing to get the test client response data as JSON. + + .. versionchanged:: 1.0 + + Added :attr:`max_cookie_size`. + """ + + default_mimetype: str | None = "text/html" + + json_module = json + + autocorrect_location_header = False + + @property + def max_cookie_size(self) -> int: # type: ignore + """Read-only view of the :data:`MAX_COOKIE_SIZE` config key. + + See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in + Werkzeug's docs. + """ + if current_app: + return current_app.config["MAX_COOKIE_SIZE"] # type: ignore[no-any-return] + + # return Werkzeug's default when not in an app context + return super().max_cookie_size diff --git a/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..7b190ca --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2011 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA new file mode 100644 index 0000000..ddf5464 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.1 +Name: itsdangerous +Version: 2.2.0 +Summary: Safely pass data to untrusted environments and back. +Maintainer-email: Pallets +Requires-Python: >=3.8 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Typing :: Typed +Project-URL: Changes, https://itsdangerous.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://itsdangerous.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/itsdangerous/ + +# ItsDangerous + +... so better sign this + +Various helpers to pass data to untrusted environments and to get it +back safe and sound. Data is cryptographically signed to ensure that a +token has not been tampered with. + +It's possible to customize how data is serialized. Data is compressed as +needed. A timestamp can be added and verified automatically while +loading a token. + + +## A Simple Example + +Here's how you could generate a token for transmitting a user's id and +name between web requests. + +```python +from itsdangerous import URLSafeSerializer +auth_s = URLSafeSerializer("secret key", "auth") +token = auth_s.dumps({"id": 5, "name": "itsdangerous"}) + +print(token) +# eyJpZCI6NSwibmFtZSI6Iml0c2Rhbmdlcm91cyJ9.6YP6T0BaO67XP--9UzTrmurXSmg + +data = auth_s.loads(token) +print(data["name"]) +# itsdangerous +``` + + +## Donate + +The Pallets organization develops and supports ItsDangerous and other +popular packages. In order to grow the community of contributors and +users, and allow the maintainers to devote more time to the projects, +[please donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD new file mode 100644 index 0000000..245f43e --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/RECORD @@ -0,0 +1,22 @@ +itsdangerous-2.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +itsdangerous-2.2.0.dist-info/LICENSE.txt,sha256=Y68JiRtr6K0aQlLtQ68PTvun_JSOIoNnvtfzxa4LCdc,1475 +itsdangerous-2.2.0.dist-info/METADATA,sha256=0rk0-1ZwihuU5DnwJVwPWoEI4yWOyCexih3JyZHblhE,1924 +itsdangerous-2.2.0.dist-info/RECORD,, +itsdangerous-2.2.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +itsdangerous/__init__.py,sha256=4SK75sCe29xbRgQE1ZQtMHnKUuZYAf3bSpZOrff1IAY,1427 +itsdangerous/__pycache__/__init__.cpython-312.pyc,, +itsdangerous/__pycache__/_json.cpython-312.pyc,, +itsdangerous/__pycache__/encoding.cpython-312.pyc,, +itsdangerous/__pycache__/exc.cpython-312.pyc,, +itsdangerous/__pycache__/serializer.cpython-312.pyc,, +itsdangerous/__pycache__/signer.cpython-312.pyc,, +itsdangerous/__pycache__/timed.cpython-312.pyc,, +itsdangerous/__pycache__/url_safe.cpython-312.pyc,, +itsdangerous/_json.py,sha256=wPQGmge2yZ9328EHKF6gadGeyGYCJQKxtU-iLKE6UnA,473 +itsdangerous/encoding.py,sha256=wwTz5q_3zLcaAdunk6_vSoStwGqYWe307Zl_U87aRFM,1409 +itsdangerous/exc.py,sha256=Rr3exo0MRFEcPZltwecyK16VV1bE2K9_F1-d-ljcUn4,3201 +itsdangerous/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +itsdangerous/serializer.py,sha256=PmdwADLqkSyQLZ0jOKAgDsAW4k_H0TlA71Ei3z0C5aI,15601 +itsdangerous/signer.py,sha256=YO0CV7NBvHA6j549REHJFUjUojw2pHqwcUpQnU7yNYQ,9647 +itsdangerous/timed.py,sha256=6RvDMqNumGMxf0-HlpaZdN9PUQQmRvrQGplKhxuivUs,8083 +itsdangerous/url_safe.py,sha256=az4e5fXi_vs-YbWj8YZwn4wiVKfeD--GEKRT5Ueu4P4,2505 diff --git a/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous-2.2.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__init__.py b/venv/lib/python3.12/site-packages/itsdangerous/__init__.py new file mode 100644 index 0000000..ea55256 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/__init__.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import typing as t + +from .encoding import base64_decode as base64_decode +from .encoding import base64_encode as base64_encode +from .encoding import want_bytes as want_bytes +from .exc import BadData as BadData +from .exc import BadHeader as BadHeader +from .exc import BadPayload as BadPayload +from .exc import BadSignature as BadSignature +from .exc import BadTimeSignature as BadTimeSignature +from .exc import SignatureExpired as SignatureExpired +from .serializer import Serializer as Serializer +from .signer import HMACAlgorithm as HMACAlgorithm +from .signer import NoneAlgorithm as NoneAlgorithm +from .signer import Signer as Signer +from .timed import TimedSerializer as TimedSerializer +from .timed import TimestampSigner as TimestampSigner +from .url_safe import URLSafeSerializer as URLSafeSerializer +from .url_safe import URLSafeTimedSerializer as URLSafeTimedSerializer + + +def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings + + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " ItsDangerous 2.3. Use feature detection or" + " 'importlib.metadata.version(\"itsdangerous\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("itsdangerous") + + raise AttributeError(name) diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f531328ad5cb66a8a69ce2d3adfc0085fe7321e GIT binary patch literal 1641 zcmZXU&u<$=6vt=%W4&H`ZO8dtqIMGs?jCBFq##vPNTDedsf`eBg|wH|#51us-5=J> zIH{vVLWl#LIB;mM+(6~bKf$G?hg4fxLMj|0^$;mJapKLyj+`=D&3@i@W}n~8d(VGZ zmWg2eesH(_Qx>7u(in}@DQL%U03IWPh!&twb2UwJDoD9$k|voT6K35kXlarK)?Hn( z4xDpyigSSx=H0wv1K4y;#d+X@TTpBQ7u}-b0cls%3_D~+( z(UJm=qF7+z#}QvY)J{cf19SS(b&t?iOepLc2{alC<_?a8x6v1r!*cFZOxCc#fO)_> z6cft8Fv0i|_k$P{u!>+c{dR;!k4dK$u7JbXTuEHuuzR*^;=xyUn|PC++cz^5-}2CsH#8bh zPAH9#cKih3G1`Ojd3XgO_AyBj6rg=gy|w++UTRD3eQS`k&_@!<{FZ$RzU0u*p0;J2 z^7y<}7`IND=ud|cHIcAJ>w9RVeycgT^`zi=+mvz0vF9;a^t(Ub?@+roCf95%1oJm~ zg4#Z}3GFi4!h#YTN5tOogTUUPHlty@4VoX>UkJX2qc&x6kK4=jmAd_aQ+t!D?85hg zwq#M+F|%ua*o~P8{Ed1@1tw4_^BsYvBDXorHIM^iiYR7ah23-eQ!(tAiPBY}07F z0aq|wT&aJs+~B^TSG#aL+@`!Sez=C``H?R?uiov;^tIvMAV5gpdl0~!jHC(EH|S-q z@csUuxrJB8;wxkJFQf9K^@DYkN?D(4Cpxk&y_}spDxmz#3DWcCQ3+M%56X+r%ZmqP z=Xu%rrT(IP) zN>b3d>SR`yTPkvzkaAYYwq{i+OiID%vB2Zd!fZ-v({hsc^ebZTOTG+KV%!X4(hKM( zYz0i&HT)J#M`=yd259Lus{Vtn59CuHpmztTHbBk*T^*ng)pKotmeq54q}&{!&rbA` Ic1iune;v}vQ2+n{ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/_json.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60e588c66a852b548e1fb4e8d675d069b653aebd GIT binary patch literal 1195 zcmZ`&y=xRf6rb6ztobk)qnJWij0zj$ttO%%B8Z|Oauz9sZI;Q-}J^QBYR}K^wc6D}+?O*}c1{;K054?faPb-tWD8Juxwg;JkW&tML&d z^i6#Xj!^;JI|pC`QABYYb+C`I!dhGN_3}1+Q$sfp)z=X#0#G)Qn9+lLqYmkH?A5-LO6#F_es7bYTW3%t?o1n2E&7Q`}4R@p%53VMil!Wr; z((U^Fg*%+2DdP^|NfuM5C6d_bBs6O?M>dIcgyc~woV8{onSd}>3!(MlQ5C@t_vQg? zAUU+P`mGH;0d&!3-@XKW)?KYI1C_8a+X^8h+(qUeFhSQvR*OD;n zuviK&1ZKQ6m(3&&M93L~t4TQXR$092wWH;}aj|xG!4pvVX{h`zX)xhMQcw~%7_=+A zGJ7q}xee*=PyNYEtt>;$TO0uK5PhGVe)8bagQpkXPR?%GvprCvzo;-lF{Y?k1+am- zxHTk0`BsNwstu-&|L3FcZ3afNKXimz{T&;;rS2|T!4bUk96!cDs#!0_Su8Tn0wTgF zx?YS5mJ&{6!Ugb+=L>w%)s`fBfgZ_m83XP(wxoOoxS`7r#Re=+*bUi{praPiHg`|Ko$E!*Wl z8LGPm->2RmgLQMd&TN#=%aDz zt9f8Y!{+gxj;yI|g|;m~JDP6JmAan_Rqv>1C=Ci)$)Fo3j;nzdhFbiJdrRhN6gLVi v%Ut{@*!PMk>`PTEm-#U;sGSl=Ky2$6<1gsgH#GeTP5rXQ@Z1gpQAYj-mkk=9 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/encoding.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..517a105c041be831e5764915ed051fa5b8b9fab6 GIT binary patch literal 2695 zcma(SU2GIZc;HI@g1FMcz7+j8K8bGP$-Gv7D! z{eSaIEEYvDeySdy{3MLfA94{4-AC~1OBkU`h#-O;G>uajOFZO+QXvJkl%}Ab(iIG+ z45AU;X_$_rA{aFy(%cC1`j51b@MqyvBZ(8^Gd&dr*Z|O^TCO_~z78)V*neVu9blIc ziF~8wdV=*jB#qZVV>wbSAw>0@r51G)iLUXq($?J8I-**n+TpB`d**QpG2z7a$M>&= z{Jm5sX(dfyQ5R_=F@W8(p+x&VNlakRv|TqZY>~~oeC(c76gC?U+vJEX?2P7Lp=KEX zSmV`K0l9=k%_xNCkf@15C=klp=1>ko_~@9!bD@A|9!{PDabpS1i)MM&<-&F|)YG_N zorTQpV|m88RLruh2f5@_ewrrTU5w1q@c{cLupIkA&n>BUj7+U@hSs3OI8O5AXXp!2uPV94fwd*yeP2 z$nyPa*%o*iJZj}9EM=0FXO^Jn#h~@Z6tx)T1xHA_PXyOR!QU3QC#WUzR)JG1>soKV zew+^~!m70GKtflZ@r-dL%xf($M;=L!4-ff*J%dTXGmvG5uK|}QEf#~>i}~l$J}>Kp zy$$ejncm>#2x{(LGAgmn3!`_;)~eZ8Hv6uOR?Hn$b5GgabA6~{j+FEf)&lHx&X$>| zoP86JdS??%Lf>oGYL1pUN%VEMue;bpBwREQD#BewP<9?#h*-<;98ew|>t|1)J|rRm zU8p7}R}-PFh_%jRA&pmq7(vkH@TVctFpodR=kPgnUV9gv!-+`oWG#$@%JP6PLI?&_ zRQ^Xitt?l;QZe=8=7nvZ$!0wxJL%>bO@x?CYt|&ER+#R|yemHWihI^}vc&S^GvLRE zSOl8HSfarXy5>-qwE=rw*nLI4#y4hX=uug`Ui2;7Dfl>(4g{GU@)V|A_7UrmT<|Yo z7LYc<$0wsLcSS?^yMUD37h{yQxl z)t3HpOaHP_X-SqM$-nP3bzCf#%-+8c26A&psdI0odFaNLQsjkyRy5dqz@=8-ZP=v+cP^YQJ8^c))i;Y z)TN?KG?j|OfYhgA5c*s#8G&JK)K~MEDmU<)7fXYPw8;B?$updwx-_>i{cveDJy?uXys}2QPuc_OdSR9;a3LQgwJlhkK@YRCop8ak@NxM9`v!G=+w*nL zl@FKuD;xJz%)QqSmCfOjKCG;Qh8Ql0iGdNn3uQzi!em)KFu{M;oZt2QQcy~&dXO0O zFDeSm^}#Vjj zGi8rcxbc*Kvr3@hp>$1Z?e((eK)k{nL3;aOgqy z63}Hk=Rd*(RfO^HsP_*P`>pnG`xAAqM9}^tcttaC>~=$&51-oN!)Henyc>?LhJn7? z7RJx7#-n)u$|ls+Q|;Vd?%ZDL*s(nN!-=aWmS4QlS86|4Z9iIWKl<}zrG2b~;&}xmG_NR;wKkks|Ln{_ahiT Hr;Pd+)n;P( literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/exc.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37933d26213744bcdd902f90cebc9cf078d7dbc9 GIT binary patch literal 3955 zcmbVP-H#hr6~AN8*yCOAN7AI5(0oiN+r>@SPC@`_RS_tuCyX_u>V-S3Qs@`o;ofZ?^Znodl>16}j=$q< zbI-v>+=+G^9(ElS$=JEel_SDN)CprDg;#anZ~Dr?zql#zg%WcPo}EZKJO~_duOZs{ z*cj)r^TSx(=Haf8QAatR*zrT5s&o32YSq~jQsIi+^Mtpt;asa;|E3;l;t&EXFM?yrGb8rx!Lz!_So303uIq<>?7ID8ODM&6 z1;$Jzf*m=J1^Ok|Z3J8?*HyHwuuQdm`Mc1^#wA_>JoI8#U#}V!h29zr>EJ=Euq#8Knk`Roh)jP~Klool+eg za}ip#0`bLt_D_4^LGf?)xj(LaY+rf0a_P|gpnQZO)=2M8eMWt4t*@Z-i1pYnNIUb~ zVbX@GV(43=0ezUFPaR2H_KPq;EM0ehX?!BBI8762_I>tr>6PF09`ru4Uz1BvRC0+4 z^O#r3^$SwO9T`gcpi(5mhrA_V_&L{YMP4VMe%W<@)!{)pf=#`s;kw!u@)SPoFQoox zh#+v?$A(;hRv+}c`k=CacP)xEK%0GWz@Fty%l^Eavo0UohIK(7Pfu!KJbTQfXB@qO z&X?FT=FdVMOagB#@W$$wVURoiZpd*vvA;Sd4|mi^?Rb$;4hZbDc-&}K8-%6NLw)U_ z6X2Xb0nUKwzBzx18lbv`IBePB{u@YiD$>c8!iPJ76*1eC| zI(F;!q+2QMu2Z1%COk|bFx=yTKM@dtfX=oKA3BI3h;Hb&jjc(0Z&i~Jm%_&i9uyP`rDu?IZu~%SmjEDNiU-F>kdgHAaCaBqhMm+1hIHdoIHM z)>e`_wf8Y+j223_8%P5hCsRO7v9bwjpTMWbEV&d#Y`HoTZ=<6q8XmCcIhZM#L&H-S zPvK`AZD8ai;!IOVQ)yIDOw*?Xw7e%cZoL1OS=)d!O+7?bNeP1%l|@TX&Cp8Ai6{)Z z+AvMtZi`UqdO`{5gJJt95|Uz~$@c{8maeGli(QJecm23Y<%nJ(bID7}j2kx-4iflB zPsYJ_pqb&I_1`(z15e%jXt8dZV9kj*T}aN|UyP)`>xVpWg_My5MJS(6gzY!!^(qM+ zz$wKML#HTuIx~94%^zW&T7w{NF3xh(W~)~Z&EL+07T0ePNz<&I-vmqT6IrUyq4`RO zd9nQNsJ444VZV;Kk_6dNeIG&-)&gPA5MeLB{`6{XFu!Eo(ws$`a+Z2FJ9TkTqTU=k zUpb~(&lp4kVp{cN5dTjpd=9qzNs=@9O$2~R(5AU`0VF z8X@s>{Kf@m!LpB+E$h~E29cnZCRNH*@9uP{SVUnGrVxtSbNwTGBm?$dBgr_Wo^jN4$CXXt%v0yLo>X&i2lmw42|CSKZy%~ A%>V!Z literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/serializer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8cc8328bd5ae6bd32082bb8b5668d2a42fd9a4de GIT binary patch literal 15423 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/signer.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf0df34cd423bddb41e30e64e4f77b166a4406b6 GIT binary patch literal 11300 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 X;<@e$ZMyLMOY^%99=e%wM$mr)5vr_v literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/timed.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff9c1571d8e234d40ece672a0b11fd8c1b81328e GIT binary patch literal 8744 zcmdT}du&_hb^q?YynIun__AKMuAV7li*lS)OBC0L9m|fFM2REiVJ0qh#d|5!=0myn zQnolMa9nSdyKGU`c6KooRnY)dW&`v78B$<>G(`dg7%)&}Ffpt%cvw527zVJBf*KAm z?40jDNGVRb{kbdZyXSkH^S#gcopb-m=W`Qy{$b;(x$pK8^6!{2AG=O4n|Fb@N+cpN zS(0NC41+YAWpiA@X3%_sr)Bnp1KwQLnR6zbw9W>!E8zl~m+V=0&Xe#^+5xmT;ia?_ zXkWrdX&2CKi8e~Rf%Yf-l=fr;x%NamrM*B06G2M*fDR=>ly1w0bCE=Z(te<$i72H5 z*AZd_fbn zOd+pMLf$Efnyh7VGSc`i74q_L8NIP@R#fG&hmw+OMlhveFNM`aH zH1NU;bF>)p?(-rPm^tqeQJTuk7K~ZeE{y>AznrDCblmn>i;7+8J3;~e(B$c+tZFdXs6w)-W!g^-%bAp(cgp`;UW@VwM%95ZJ1exxM zfGy}Is&QfZjLtlsleIJBGsQes&Ip(*==_S9QDtFVzK}9TLRpRNoe?s$S2_Tl8T(F) znJjcUE2l*0+Zq<-6f&wY5GhXCQg~j?2e%%s1+#e&h^s`i>NMlB5OS6^8#mwPW?nbi z!$LEq>E~oPs(F2xQbk3P^O}ImMHipWT}T)6DZEZXuBd9TuE+pOM+b(B3O7QYlNEiW zSP*0D92C}VCpzbV1H9jAk>lM&*O?2M&y?8BHFU7gOiNIawXeXsRUUVFZPuI*MIN@%hEN zZ%&4bYR;szd)g%RlM>%ny&J}+Mj*LJwwxpo`rboVA9?GM?><`f_g0*}o4AOn)+M#J z;3=qS-GX~9e3{XV+X@?F=xdZ{J~x=_hHTgpRuo{N9xvn z3KyYeG;l`svjC@9R0WY%p>iG3JD;)ootfDtM(Tv1EKSY;Q|tfs2C!h)c5U_N5CMNMul zN@-~45xHlx0g#|}Ljp%7Kmr{b{-JgM(CX}sm;UaRcV79(KVET;D_u~(?ZDu+!|h}? z-v^@gz?7Nm#(i93n)g@3Inbv}&N@uG`QCY#Eg5W68vv)X$zf7fORmh6xe^qYSxlE0 zD^JdP%+}3!bDY?k>W*=|NxJ5kgU!nes-~D)m8xJ-)5O#n8JfV|gCmzNC^>4F<1xE} zeJD6U1;LGi2EERy^1Oa=E&U67O!tsq5VJ+O?y~ko=?4xK_a6_0zOgoBD}{INBbJU} z>jWeh$*%)l*S=m2^eywZ!hLV=Thlg153i3Nu8uxl?LS%#Pb|A`wRKzz|ES{!9o4q} zWv&*8T;tyIT+6Hn?px+-{_u)=sWY| zERuJa$#=**#+1A`E?G+IGjrs`3rWyt^?-h>n!0PpB<;ElDMfcqQ!jrQx>E7TTqF%I zX%GJ|Mx}fWnkz9(?niDMt+l919CBaQ*<;w;>a2h0i=AO5T>>|x-)F7@LeQW{f3CEZ z$zQ-xZyv5Co5U>fn#*hfhnQktGq1m`L+mI!%C-eYX)p5%Tjnn@n$K)0ab?>Lo2gkZ zF=g9XzggFOmmLysws{3~#FBH#1tW07zXwLzZno4yCRKKsy_@ePcbR{EZ`u8N&_!Up zcwBcpWw+JV(;T4&SYCh1yjfp%mOVEdCbET5yD$2h9Fo24+%_ln^;zh#&y>@An+l@r zF2VXO`O3aBd+sP~@SrwewvwD>-`^0)Rc0Y||B#2i|G?Xa_maJAU*gO5d)d|tjLL#{!7kZOfoHU2f6czays=-W z&NJu91@06%&w#|Rxhf!$W5_A;#(%cdqS>I2)@4yWCY9!ZC$!}KvVAIhF99lF^1kM6 z_89Yt{{?#g%TTS3G!0N2HxVadTZF5qT-|s<@d53TK@(p6681gVfR^s)hd zDPk5t7h56_Wz5OoVTf74qi4j0OhJhYC(>Y!cj}@UfDS5@Pb)NmWpT*6oTqpUr3rDq;n7c-=K|AtleFAD{@B zcfWuJc|uVNO5O3ylur1b0T7wa7S8Kg4o)7m>`EK3#QfBhD|>-f_F;lX8M>0yVpglW zU`|OG7|3H}YTcDVtaoav?qApKK%rm3!&}no9Qa#x4o#*jnWU#WnN(57(|chh7b!OQ zN;CEZFsU1GAMb$C6nNM0tw`5fFTVB7)u*bF2bPc3I(n8*Y`KZQvjr72+KAV`l3w@p zeC+S2MSEBLzYg|S2F8AF|0sC8;yr%5OZd^q4@TCwwUgDZ(JTICe)&Reci*zT);F}w zH*B1%{Z^#!?U9?#YX2kE$oTRxFxTEl#Us@Gk&3^s!8+P|Ydyk7&)9m;*v*A%&!LqG zK%Ak0w;x_i^Mz{H z!Aj_0#e49!KfLU{vvr&$fu2tZ>l&_gbS|H$MWR;rBk)hRrzdZJNgNKUGx8fww z`6*#s?H_vs4G!L)Zv{!`z}v@foUZJ8^i#sO_iouq_ug8^$j#yw$96|=ckcn-Nblzj z2UOlw55oq3tNrKzd9Ncp;U(`q&_2;k-XCyHxVZQC1t)CW2R0t)54^644(@|p45r=T zV=VWEV5v0@LJNxv^9&I zX=`G(lKf0QyJ)HPZTOnvMXV~yap5_`bGMXnCT;0b)aa-pbk!hV$fz24Xb|lH-@z;U?+u+G*OFQpZm0Y1XVldlm0CTqL{A)miff-hA@P zlh?d!bIVVDgRsU^m7nE0Ih&=1_hmR z@Bt7iQCgWm3RfRWQ9s=EfRYi)0u8~@+B&a?#iFV2(+FAKb5MV zQb3D81>pp+eJ>va!z!QFdpM3gu#?kYkf5Nl&{_RWR z-;VY*czA>63iiOg1Iq_I&O#74~$*Y*f2ji|aYKAUh- z8a$QOKgo*`*o2G5Q{CXI`}BCK)C?+@o_SsczubgeJ8ma#{ovP1TFZ zV}R2cJ?vMCXp8gm%R2;}uD2PiI$%-m9TPznimqWZc5$yTn$!|TyTXFw2tcLjIGRoz zhR`PO?n#NWsrU)J)>=XN!mvPfOhTV^TS^4w@gS0Ir~{HZ(uO#gp$Q>$DP}eOr0c5C zKoc(kPiYTMw`Eo1+hzPcv{CyY0aO9@DbW7r!j*+ebnGAbpE=eap8Qa&K0ICZKVNY^ zue;4w%m-NP@K4RlFc_8Am1)j+i2`b#MaIwHObLnpzX*xn@+jalxg#u-yT$JEOh=-TsREQn5fL@fp?%}bOyl{!|_8D*~AXAa$l3zSjyLS zTyV=Z)jx(bKLLQ@WSbZtY#$Bx;jN))qwYoHk~EzjJSDm>g4a@c5t5ikkNYudQ;c#7 zD(Y?U#YaoRChFcu-Hr<@gA<~E%afELltFzZ4%`V9d&WIA9v#Z?*uPqe?7YFW_-DYO z{uC0pw>`wSYvt8He|njzb?#nnyB+P?h{o2Vv9-Z}iH-thXZ^mR+R)ygp8oOaS~zm; z{JY@>M}{BVBYedMd{ab^?A9yo;CH=iuRu5I%4pf{6?rix>K=k z+vk9vd_#9t{Cx3~k;4br_d*P&2ZBce{4Z?m5fA?h4-a(8Fh
    MYqHubM?!CD<^?& z$S^lpQ#XKao97eF4&>eyt=tq*hus6rQ2K~P2IC~2gSvBYcf!}&!pHj{9==@fTx z;$&Oe2Mu5cNN=A&c~8R`N7JV~iOEx#JdFv(QPV)x{mEp@*K9y)^a6?4NXFz@Oin`5 z3d5$b5R<>fitCWv`BQ*lEbjy)G;;9bWF;J{+8%||bbq|Tar_HREj+9fw_W#r#$yQ} zG>VF91NSvN1N?)xJ<$daZvz$~rK2LGz%lNlt-wQc`!{`9_AG+}fZJu~pJOOH5(Ymd zoybP35mxp5-h-w3&f(}|-3VRNMf{QuGe;v=_ooWkEJT7p8>?}!@ZkMJ0#;~z9$QFp86H+eVy9|N literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/url_safe.cpython-312.pyc b/venv/lib/python3.12/site-packages/itsdangerous/__pycache__/url_safe.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..512f2485beb3c5e6f705a9a9bdabf4c0a21efd20 GIT binary patch literal 3545 zcmbtWZ)_Y#6`#G`z5jpwCwI1!7*FF=&4uKyP0}Eo0Cf@?S~YHkTLrEP>-Fu}UVCr% znBA-6)0svnh>I#v^8qClMY5`XNEMKRgb<%lgTx0!KO{9$ttF9yT0ZpKrFKP>e&M~@ zyPRW65imZ_ym{}<+nG1-_vZaMm5LK+zy093*+0by`4A_a76}Mx{XHNq5rY_#MJiHB zl8_Erp^_{{rKA|Lp;&4qTnd9sHdHH8iI$>*4g(!4#RMI(;*~@xA?T=;tfWdQLC1hj zm(qfcTbW8vsYfCqa*`N{^TbH9H0vFLJzSN89hLfoECsSO>w6$o+R}a@&49EAq&@Am z9qG2EP`>wLRLx6%Lbq+l(>>F%-HDH-fSJ^eJC&+l_MV-5egc$I)4IzJAJPm~b_}+O z!R$68eoQxB(3dPnH$dE@y>LSJ^hw4|-7@Qp126v2Ec2pSVMdo#4t5^&?Tt$7-+}p$ z!SRfgB!iSfFTn+rWTuo+`PMK#-yZ#;w%%G-C7fo-D>XftDnx%8e;QA@iJ`bjNfOl8NFtC zTK7T`>EZ1YnSs)rK^WvMtRBU2SuDq#*$q$abth-~q2@$@=+p}=tuFV>G7cWRbF0c*5qLG#a094z#W$Ln#-s&L*ZiC*)pplFyUI# z4mW2_TemdExx?$@U2_dG?HSapMFEKx+ zX=O`yT}^ZG(h)S+&fT9c&N&rUv>)fj5-Xl?%C!o!J-1kf^i-@ad2^1fxn<5640AeX z#aEd9N)dM179K1-aiHj$9@`J;YeAo7Zqf8yL$_xccWQ32#w`s2Q>ZTSLHKfg^z(B- zVe8-GcRuH}X=>zAirUud3O8yapt+fu@@ z?5%#fGO*g8Z=SfDCdphY6iyA@8rX5^)r+sLc&h{ZURO5Kq$hh}@n&Xp<;0E5*p)-? zXU47_zL^=j5gog?F+zHVJ|PMi>f5>2b82mbZm4p9x)mndvaN`m%6`_8LHgN7AK5kx zieNoQ*S4Kr8{G|x1AU-4I0TBlL#UV{)W;4`X=53O(Rr?b>is&j=UF``7p`u{xWPw2(Z%H=zUetmf#$oQ`?ry|c{g7HMfZEqLFC=aYzt!L_-bZPQ&}4v zZl-Q!hc2DDcxL6$YIaXE{!t>`tiSe+H_I!#e{NoRo%Xa{MU-b&(_L9JJJt=6~ zpc9VGIOJTyzl{1}&b%78#U!urM>_((52?M-!BZR6G+VDQP4nZLR&k7)g>+KWzF*U= zwj`oyhEvuwjzPoI(D@ln+f<)`2r(<%=cn2!q|7W!)ACZ_YD~FL1y05{f@6o-$bA{Q zdp{y~L$Vre#mN(2yP@Q64DMf5j<%9y_ny14FR4fF^yXSBjDVaTfEZFyl6|CwGFa0; z*h(OkB=O9rDWLxGl$2Hn?h@#DzVo$*Dw*~>D6RK^xLe0y6$3?>?Dzgl_Nl*n+TjZ> zwM-}$#zc}Fn<{iGlqou0^C-rM3vYx$F;BTrsz7}q9{o558fLgo;enacbUn=e@T_1( zQmaA=Z!cbCybQG+EkiPedJp)4k}#uN)j55dc~p1lBDfjHsj0`b$EK$CA+a9_VF%~} z&_Tg5@s7gxqc$FL^Hv}Nd>QHwQ3eS3b9|>c)@8oxVeQT_>H0F% zk^*GGm5Mz*yiY%RG{F1U`7v05h!9|G$&w`9Cc8c)eSam1zmt*MWK{fi+$MW~55JA@ zVQJuU>5BY@wn2d0;F2OmZwwZ$#eaA3*O?6hvyC*eh7VrT-krSp t.Any: + return _json.loads(payload) + + @staticmethod + def dumps(obj: t.Any, **kwargs: t.Any) -> str: + kwargs.setdefault("ensure_ascii", False) + kwargs.setdefault("separators", (",", ":")) + return _json.dumps(obj, **kwargs) diff --git a/venv/lib/python3.12/site-packages/itsdangerous/encoding.py b/venv/lib/python3.12/site-packages/itsdangerous/encoding.py new file mode 100644 index 0000000..f5ca80f --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/encoding.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import base64 +import string +import struct +import typing as t + +from .exc import BadData + + +def want_bytes( + s: str | bytes, encoding: str = "utf-8", errors: str = "strict" +) -> bytes: + if isinstance(s, str): + s = s.encode(encoding, errors) + + return s + + +def base64_encode(string: str | bytes) -> bytes: + """Base64 encode a string of bytes or text. The resulting bytes are + safe to use in URLs. + """ + string = want_bytes(string) + return base64.urlsafe_b64encode(string).rstrip(b"=") + + +def base64_decode(string: str | bytes) -> bytes: + """Base64 decode a URL-safe string of bytes or text. The result is + bytes. + """ + string = want_bytes(string, encoding="ascii", errors="ignore") + string += b"=" * (-len(string) % 4) + + try: + return base64.urlsafe_b64decode(string) + except (TypeError, ValueError) as e: + raise BadData("Invalid base64-encoded data") from e + + +# The alphabet used by base64.urlsafe_* +_base64_alphabet = f"{string.ascii_letters}{string.digits}-_=".encode("ascii") + +_int64_struct = struct.Struct(">Q") +_int_to_bytes = _int64_struct.pack +_bytes_to_int = t.cast("t.Callable[[bytes], tuple[int]]", _int64_struct.unpack) + + +def int_to_bytes(num: int) -> bytes: + return _int_to_bytes(num).lstrip(b"\x00") + + +def bytes_to_int(bytestr: bytes) -> int: + return _bytes_to_int(bytestr.rjust(8, b"\x00"))[0] diff --git a/venv/lib/python3.12/site-packages/itsdangerous/exc.py b/venv/lib/python3.12/site-packages/itsdangerous/exc.py new file mode 100644 index 0000000..a75adcd --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/exc.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import typing as t +from datetime import datetime + + +class BadData(Exception): + """Raised if bad data of any sort was encountered. This is the base + for all exceptions that ItsDangerous defines. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str): + super().__init__(message) + self.message = message + + def __str__(self) -> str: + return self.message + + +class BadSignature(BadData): + """Raised if a signature does not match.""" + + def __init__(self, message: str, payload: t.Any | None = None): + super().__init__(message) + + #: The payload that failed the signature test. In some + #: situations you might still want to inspect this, even if + #: you know it was tampered with. + #: + #: .. versionadded:: 0.14 + self.payload: t.Any | None = payload + + +class BadTimeSignature(BadSignature): + """Raised if a time-based signature is invalid. This is a subclass + of :class:`BadSignature`. + """ + + def __init__( + self, + message: str, + payload: t.Any | None = None, + date_signed: datetime | None = None, + ): + super().__init__(message, payload) + + #: If the signature expired this exposes the date of when the + #: signature was created. This can be helpful in order to + #: tell the user how long a link has been gone stale. + #: + #: .. versionchanged:: 2.0 + #: The datetime value is timezone-aware rather than naive. + #: + #: .. versionadded:: 0.14 + self.date_signed = date_signed + + +class SignatureExpired(BadTimeSignature): + """Raised if a signature timestamp is older than ``max_age``. This + is a subclass of :exc:`BadTimeSignature`. + """ + + +class BadHeader(BadSignature): + """Raised if a signed header is invalid in some form. This only + happens for serializers that have a header that goes with the + signature. + + .. versionadded:: 0.24 + """ + + def __init__( + self, + message: str, + payload: t.Any | None = None, + header: t.Any | None = None, + original_error: Exception | None = None, + ): + super().__init__(message, payload) + + #: If the header is actually available but just malformed it + #: might be stored here. + self.header: t.Any | None = header + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = original_error + + +class BadPayload(BadData): + """Raised if a payload is invalid. This could happen if the payload + is loaded despite an invalid signature, or if there is a mismatch + between the serializer and deserializer. The original exception + that occurred during loading is stored on as :attr:`original_error`. + + .. versionadded:: 0.15 + """ + + def __init__(self, message: str, original_error: Exception | None = None): + super().__init__(message) + + #: If available, the error that indicates why the payload was + #: not valid. This might be ``None``. + self.original_error: Exception | None = original_error diff --git a/venv/lib/python3.12/site-packages/itsdangerous/py.typed b/venv/lib/python3.12/site-packages/itsdangerous/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/venv/lib/python3.12/site-packages/itsdangerous/serializer.py b/venv/lib/python3.12/site-packages/itsdangerous/serializer.py new file mode 100644 index 0000000..5ddf387 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/serializer.py @@ -0,0 +1,406 @@ +from __future__ import annotations + +import collections.abc as cabc +import json +import typing as t + +from .encoding import want_bytes +from .exc import BadPayload +from .exc import BadSignature +from .signer import _make_keys_list +from .signer import Signer + +if t.TYPE_CHECKING: + import typing_extensions as te + + # This should be either be str or bytes. To avoid having to specify the + # bound type, it falls back to a union if structural matching fails. + _TSerialized = te.TypeVar( + "_TSerialized", bound=t.Union[str, bytes], default=t.Union[str, bytes] + ) +else: + # Still available at runtime on Python < 3.13, but without the default. + _TSerialized = t.TypeVar("_TSerialized", bound=t.Union[str, bytes]) + + +class _PDataSerializer(t.Protocol[_TSerialized]): + def loads(self, payload: _TSerialized, /) -> t.Any: ... + # A signature with additional arguments is not handled correctly by type + # checkers right now, so an overload is used below for serializers that + # don't match this strict protocol. + def dumps(self, obj: t.Any, /) -> _TSerialized: ... + + +# Use TypeIs once it's available in typing_extensions or 3.13. +def is_text_serializer( + serializer: _PDataSerializer[t.Any], +) -> te.TypeGuard[_PDataSerializer[str]]: + """Checks whether a serializer generates text or binary.""" + return isinstance(serializer.dumps({}), str) + + +class Serializer(t.Generic[_TSerialized]): + """A serializer wraps a :class:`~itsdangerous.signer.Signer` to + enable serializing and securely signing data other than bytes. It + can unsign to verify that the data hasn't been changed. + + The serializer provides :meth:`dumps` and :meth:`loads`, similar to + :mod:`json`, and by default uses :mod:`json` internally to serialize + the data to bytes. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param serializer: An object that provides ``dumps`` and ``loads`` + methods for serializing data to a string. Defaults to + :attr:`default_serializer`, which defaults to :mod:`json`. + :param serializer_kwargs: Keyword arguments to pass when calling + ``serializer.dumps``. + :param signer: A ``Signer`` class to instantiate when signing data. + Defaults to :attr:`default_signer`, which defaults to + :class:`~itsdangerous.signer.Signer`. + :param signer_kwargs: Keyword arguments to pass when instantiating + the ``Signer`` class. + :param fallback_signers: List of signer parameters to try when + unsigning with the default signer fails. Each item can be a dict + of ``signer_kwargs``, a ``Signer`` class, or a tuple of + ``(signer, signer_kwargs)``. Defaults to + :attr:`default_fallback_signers`. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 2.0 + Removed the default SHA-512 fallback signer from + ``default_fallback_signers``. + + .. versionchanged:: 1.1 + Added support for ``fallback_signers`` and configured a default + SHA-512 fallback. This fallback is for users who used the yanked + 1.0.0 release which defaulted to SHA-512. + + .. versionchanged:: 0.14 + The ``signer`` and ``signer_kwargs`` parameters were added to + the constructor. + """ + + #: The default serialization module to use to serialize data to a + #: string internally. The default is :mod:`json`, but can be changed + #: to any object that provides ``dumps`` and ``loads`` methods. + default_serializer: _PDataSerializer[t.Any] = json + + #: The default ``Signer`` class to instantiate when signing data. + #: The default is :class:`itsdangerous.signer.Signer`. + default_signer: type[Signer] = Signer + + #: The default fallback signers to try when unsigning fails. + default_fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = [] + + # Serializer[str] if no data serializer is provided, or if it returns str. + @t.overload + def __init__( + self: Serializer[str], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: None | _PDataSerializer[str] = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer positional argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Serializer[bytes] with a bytes data serializer keyword argument. + @t.overload + def __init__( + self: Serializer[bytes], + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: _PDataSerializer[bytes], + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a positional argument. If the strict signature of + # _PDataSerializer doesn't match, fall back to a union, requiring the user + # to specify the type. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + # Fall back with a keyword argument. + @t.overload + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + *, + serializer: t.Any, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): ... + + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous", + serializer: t.Any | None = None, + serializer_kwargs: dict[str, t.Any] | None = None, + signer: type[Signer] | None = None, + signer_kwargs: dict[str, t.Any] | None = None, + fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] + | None = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: list[bytes] = _make_keys_list(secret_key) + + if salt is not None: + salt = want_bytes(salt) + # if salt is None then the signer's default is used + + self.salt = salt + + if serializer is None: + serializer = self.default_serializer + + self.serializer: _PDataSerializer[_TSerialized] = serializer + self.is_text_serializer: bool = is_text_serializer(serializer) + + if signer is None: + signer = self.default_signer + + self.signer: type[Signer] = signer + self.signer_kwargs: dict[str, t.Any] = signer_kwargs or {} + + if fallback_signers is None: + fallback_signers = list(self.default_fallback_signers) + + self.fallback_signers: list[ + dict[str, t.Any] | tuple[type[Signer], dict[str, t.Any]] | type[Signer] + ] = fallback_signers + self.serializer_kwargs: dict[str, t.Any] = serializer_kwargs or {} + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def load_payload( + self, payload: bytes, serializer: _PDataSerializer[t.Any] | None = None + ) -> t.Any: + """Loads the encoded object. This function raises + :class:`.BadPayload` if the payload is not valid. The + ``serializer`` parameter can be used to override the serializer + stored on the class. The encoded ``payload`` should always be + bytes. + """ + if serializer is None: + use_serializer = self.serializer + is_text = self.is_text_serializer + else: + use_serializer = serializer + is_text = is_text_serializer(serializer) + + try: + if is_text: + return use_serializer.loads(payload.decode("utf-8")) # type: ignore[arg-type] + + return use_serializer.loads(payload) # type: ignore[arg-type] + except Exception as e: + raise BadPayload( + "Could not load the payload because an exception" + " occurred on unserializing the data.", + original_error=e, + ) from e + + def dump_payload(self, obj: t.Any) -> bytes: + """Dumps the encoded object. The return value is always bytes. + If the internal serializer returns text, the value will be + encoded as UTF-8. + """ + return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs)) + + def make_signer(self, salt: str | bytes | None = None) -> Signer: + """Creates a new instance of the signer to be used. The default + implementation uses the :class:`.Signer` base class. + """ + if salt is None: + salt = self.salt + + return self.signer(self.secret_keys, salt=salt, **self.signer_kwargs) + + def iter_unsigners(self, salt: str | bytes | None = None) -> cabc.Iterator[Signer]: + """Iterates over all signers to be tried for unsigning. Starts + with the configured signer, then constructs each signer + specified in ``fallback_signers``. + """ + if salt is None: + salt = self.salt + + yield self.make_signer(salt) + + for fallback in self.fallback_signers: + if isinstance(fallback, dict): + kwargs = fallback + fallback = self.signer + elif isinstance(fallback, tuple): + fallback, kwargs = fallback + else: + kwargs = self.signer_kwargs + + for secret_key in self.secret_keys: + yield fallback(secret_key, salt=salt, **kwargs) + + def dumps(self, obj: t.Any, salt: str | bytes | None = None) -> _TSerialized: + """Returns a signed string serialized with the internal + serializer. The return value can be either a byte or unicode + string depending on the format of the internal serializer. + """ + payload = want_bytes(self.dump_payload(obj)) + rv = self.make_signer(salt).sign(payload) + + if self.is_text_serializer: + return rv.decode("utf-8") # type: ignore[return-value] + + return rv # type: ignore[return-value] + + def dump(self, obj: t.Any, f: t.IO[t.Any], salt: str | bytes | None = None) -> None: + """Like :meth:`dumps` but dumps into a file. The file handle has + to be compatible with what the internal serializer expects. + """ + f.write(self.dumps(obj, salt)) + + def loads( + self, s: str | bytes, salt: str | bytes | None = None, **kwargs: t.Any + ) -> t.Any: + """Reverse of :meth:`dumps`. Raises :exc:`.BadSignature` if the + signature validation fails. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + return self.load_payload(signer.unsign(s)) + except BadSignature as err: + last_exception = err + + raise t.cast(BadSignature, last_exception) + + def load(self, f: t.IO[t.Any], salt: str | bytes | None = None) -> t.Any: + """Like :meth:`loads` but loads from a file.""" + return self.loads(f.read(), salt) + + def loads_unsafe( + self, s: str | bytes, salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """Like :meth:`loads` but without verifying the signature. This + is potentially very dangerous to use depending on how your + serializer works. The return value is ``(signature_valid, + payload)`` instead of just the payload. The first item will be a + boolean that indicates if the signature is valid. This function + never fails. + + Use it for debugging only and if you know that your serializer + module is not exploitable (for example, do not use it with a + pickle serializer). + + .. versionadded:: 0.15 + """ + return self._loads_unsafe_impl(s, salt) + + def _loads_unsafe_impl( + self, + s: str | bytes, + salt: str | bytes | None, + load_kwargs: dict[str, t.Any] | None = None, + load_payload_kwargs: dict[str, t.Any] | None = None, + ) -> tuple[bool, t.Any]: + """Low level helper function to implement :meth:`loads_unsafe` + in serializer subclasses. + """ + if load_kwargs is None: + load_kwargs = {} + + try: + return True, self.loads(s, salt=salt, **load_kwargs) + except BadSignature as e: + if e.payload is None: + return False, None + + if load_payload_kwargs is None: + load_payload_kwargs = {} + + try: + return ( + False, + self.load_payload(e.payload, **load_payload_kwargs), + ) + except BadPayload: + return False, None + + def load_unsafe( + self, f: t.IO[t.Any], salt: str | bytes | None = None + ) -> tuple[bool, t.Any]: + """Like :meth:`loads_unsafe` but loads from a file. + + .. versionadded:: 0.15 + """ + return self.loads_unsafe(f.read(), salt=salt) diff --git a/venv/lib/python3.12/site-packages/itsdangerous/signer.py b/venv/lib/python3.12/site-packages/itsdangerous/signer.py new file mode 100644 index 0000000..e324dc0 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/signer.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +import collections.abc as cabc +import hashlib +import hmac +import typing as t + +from .encoding import _base64_alphabet +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import want_bytes +from .exc import BadSignature + + +class SigningAlgorithm: + """Subclasses must implement :meth:`get_signature` to provide + signature generation functionality. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + """Returns the signature for the given key and value.""" + raise NotImplementedError() + + def verify_signature(self, key: bytes, value: bytes, sig: bytes) -> bool: + """Verifies the given signature matches the expected + signature. + """ + return hmac.compare_digest(sig, self.get_signature(key, value)) + + +class NoneAlgorithm(SigningAlgorithm): + """Provides an algorithm that does not perform any signing and + returns an empty signature. + """ + + def get_signature(self, key: bytes, value: bytes) -> bytes: + return b"" + + +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + +class HMACAlgorithm(SigningAlgorithm): + """Provides signature generation using HMACs.""" + + #: The digest method to use with the MAC algorithm. This defaults to + #: SHA1, but can be changed to any other function in the hashlib + #: module. + default_digest_method: t.Any = staticmethod(_lazy_sha1) + + def __init__(self, digest_method: t.Any = None): + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: t.Any = digest_method + + def get_signature(self, key: bytes, value: bytes) -> bytes: + mac = hmac.new(key, msg=value, digestmod=self.digest_method) + return mac.digest() + + +def _make_keys_list( + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], +) -> list[bytes]: + if isinstance(secret_key, (str, bytes)): + return [want_bytes(secret_key)] + + return [want_bytes(s) for s in secret_key] # pyright: ignore + + +class Signer: + """A signer securely signs bytes, then unsigns them to verify that + the value hasn't been changed. + + The secret key should be a random string of ``bytes`` and should not + be saved to code or version control. Different salts should be used + to distinguish signing in different contexts. See :doc:`/concepts` + for information about the security of the secret key and salt. + + :param secret_key: The secret key to sign and verify with. Can be a + list of keys, oldest to newest, to support key rotation. + :param salt: Extra key to combine with ``secret_key`` to distinguish + signatures in different contexts. + :param sep: Separator between the signature and value. + :param key_derivation: How to derive the signing key from the secret + key and salt. Possible values are ``concat``, ``django-concat``, + or ``hmac``. Defaults to :attr:`default_key_derivation`, which + defaults to ``django-concat``. + :param digest_method: Hash function to use when generating the HMAC + signature. Defaults to :attr:`default_digest_method`, which + defaults to :func:`hashlib.sha1`. Note that the security of the + hash alone doesn't apply when used intermediately in HMAC. + :param algorithm: A :class:`SigningAlgorithm` instance to use + instead of building a default :class:`HMACAlgorithm` with the + ``digest_method``. + + .. versionchanged:: 2.0 + Added support for key rotation by passing a list to + ``secret_key``. + + .. versionchanged:: 0.18 + ``algorithm`` was added as an argument to the class constructor. + + .. versionchanged:: 0.14 + ``key_derivation`` and ``digest_method`` were added as arguments + to the class constructor. + """ + + #: The default digest method to use for the signer. The default is + #: :func:`hashlib.sha1`, but can be changed to any :mod:`hashlib` or + #: compatible object. Note that the security of the hash alone + #: doesn't apply when used intermediately in HMAC. + #: + #: .. versionadded:: 0.14 + default_digest_method: t.Any = staticmethod(_lazy_sha1) + + #: The default scheme to use to derive the signing key from the + #: secret key and salt. The default is ``django-concat``. Possible + #: values are ``concat``, ``django-concat``, and ``hmac``. + #: + #: .. versionadded:: 0.14 + default_key_derivation: str = "django-concat" + + def __init__( + self, + secret_key: str | bytes | cabc.Iterable[str] | cabc.Iterable[bytes], + salt: str | bytes | None = b"itsdangerous.Signer", + sep: str | bytes = b".", + key_derivation: str | None = None, + digest_method: t.Any | None = None, + algorithm: SigningAlgorithm | None = None, + ): + #: The list of secret keys to try for verifying signatures, from + #: oldest to newest. The newest (last) key is used for signing. + #: + #: This allows a key rotation system to keep a list of allowed + #: keys and remove expired ones. + self.secret_keys: list[bytes] = _make_keys_list(secret_key) + self.sep: bytes = want_bytes(sep) + + if self.sep in _base64_alphabet: + raise ValueError( + "The given separator cannot be used because it may be" + " contained in the signature itself. ASCII letters," + " digits, and '-_=' must not be used." + ) + + if salt is not None: + salt = want_bytes(salt) + else: + salt = b"itsdangerous.Signer" + + self.salt = salt + + if key_derivation is None: + key_derivation = self.default_key_derivation + + self.key_derivation: str = key_derivation + + if digest_method is None: + digest_method = self.default_digest_method + + self.digest_method: t.Any = digest_method + + if algorithm is None: + algorithm = HMACAlgorithm(self.digest_method) + + self.algorithm: SigningAlgorithm = algorithm + + @property + def secret_key(self) -> bytes: + """The newest (last) entry in the :attr:`secret_keys` list. This + is for compatibility from before key rotation support was added. + """ + return self.secret_keys[-1] + + def derive_key(self, secret_key: str | bytes | None = None) -> bytes: + """This method is called to derive the key. The default key + derivation choices can be overridden here. Key derivation is not + intended to be used as a security method to make a complex key + out of a short password. Instead you should use large random + secret keys. + + :param secret_key: A specific secret key to derive from. + Defaults to the last item in :attr:`secret_keys`. + + .. versionchanged:: 2.0 + Added the ``secret_key`` parameter. + """ + if secret_key is None: + secret_key = self.secret_keys[-1] + else: + secret_key = want_bytes(secret_key) + + if self.key_derivation == "concat": + return t.cast(bytes, self.digest_method(self.salt + secret_key).digest()) + elif self.key_derivation == "django-concat": + return t.cast( + bytes, self.digest_method(self.salt + b"signer" + secret_key).digest() + ) + elif self.key_derivation == "hmac": + mac = hmac.new(secret_key, digestmod=self.digest_method) + mac.update(self.salt) + return mac.digest() + elif self.key_derivation == "none": + return secret_key + else: + raise TypeError("Unknown key derivation method") + + def get_signature(self, value: str | bytes) -> bytes: + """Returns the signature for the given value.""" + value = want_bytes(value) + key = self.derive_key() + sig = self.algorithm.get_signature(key, value) + return base64_encode(sig) + + def sign(self, value: str | bytes) -> bytes: + """Signs the given string.""" + value = want_bytes(value) + return value + self.sep + self.get_signature(value) + + def verify_signature(self, value: str | bytes, sig: str | bytes) -> bool: + """Verifies the signature for the given value.""" + try: + sig = base64_decode(sig) + except Exception: + return False + + value = want_bytes(value) + + for secret_key in reversed(self.secret_keys): + key = self.derive_key(secret_key) + + if self.algorithm.verify_signature(key, value, sig): + return True + + return False + + def unsign(self, signed_value: str | bytes) -> bytes: + """Unsigns the given string.""" + signed_value = want_bytes(signed_value) + + if self.sep not in signed_value: + raise BadSignature(f"No {self.sep!r} found in value") + + value, sig = signed_value.rsplit(self.sep, 1) + + if self.verify_signature(value, sig): + return value + + raise BadSignature(f"Signature {sig!r} does not match", payload=value) + + def validate(self, signed_value: str | bytes) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid. + """ + try: + self.unsign(signed_value) + return True + except BadSignature: + return False diff --git a/venv/lib/python3.12/site-packages/itsdangerous/timed.py b/venv/lib/python3.12/site-packages/itsdangerous/timed.py new file mode 100644 index 0000000..7384375 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/timed.py @@ -0,0 +1,228 @@ +from __future__ import annotations + +import collections.abc as cabc +import time +import typing as t +from datetime import datetime +from datetime import timezone + +from .encoding import base64_decode +from .encoding import base64_encode +from .encoding import bytes_to_int +from .encoding import int_to_bytes +from .encoding import want_bytes +from .exc import BadSignature +from .exc import BadTimeSignature +from .exc import SignatureExpired +from .serializer import _TSerialized +from .serializer import Serializer +from .signer import Signer + + +class TimestampSigner(Signer): + """Works like the regular :class:`.Signer` but also records the time + of the signing and can be used to expire signatures. The + :meth:`unsign` method can raise :exc:`.SignatureExpired` if the + unsigning failed because the signature is expired. + """ + + def get_timestamp(self) -> int: + """Returns the current timestamp. The function must return an + integer. + """ + return int(time.time()) + + def timestamp_to_datetime(self, ts: int) -> datetime: + """Convert the timestamp from :meth:`get_timestamp` into an + aware :class`datetime.datetime` in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + return datetime.fromtimestamp(ts, tz=timezone.utc) + + def sign(self, value: str | bytes) -> bytes: + """Signs the given string and also attaches time information.""" + value = want_bytes(value) + timestamp = base64_encode(int_to_bytes(self.get_timestamp())) + sep = want_bytes(self.sep) + value = value + sep + timestamp + return value + sep + self.get_signature(value) + + # Ignore overlapping signatures check, return_timestamp is the only + # parameter that affects the return type. + + @t.overload + def unsign( # type: ignore[overload-overlap] + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[False] = False, + ) -> bytes: ... + + @t.overload + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: t.Literal[True] = True, + ) -> tuple[bytes, datetime]: ... + + def unsign( + self, + signed_value: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + ) -> tuple[bytes, datetime] | bytes: + """Works like the regular :meth:`.Signer.unsign` but can also + validate the time. See the base docstring of the class for + the general behavior. If ``return_timestamp`` is ``True`` the + timestamp of the signature will be returned as an aware + :class:`datetime.datetime` object in UTC. + + .. versionchanged:: 2.0 + The timestamp is returned as a timezone-aware ``datetime`` + in UTC rather than a naive ``datetime`` assumed to be UTC. + """ + try: + result = super().unsign(signed_value) + sig_error = None + except BadSignature as e: + sig_error = e + result = e.payload or b"" + + sep = want_bytes(self.sep) + + # If there is no timestamp in the result there is something + # seriously wrong. In case there was a signature error, we raise + # that one directly, otherwise we have a weird situation in + # which we shouldn't have come except someone uses a time-based + # serializer on non-timestamp data, so catch that. + if sep not in result: + if sig_error: + raise sig_error + + raise BadTimeSignature("timestamp missing", payload=result) + + value, ts_bytes = result.rsplit(sep, 1) + ts_int: int | None = None + ts_dt: datetime | None = None + + try: + ts_int = bytes_to_int(base64_decode(ts_bytes)) + except Exception: + pass + + # Signature is *not* okay. Raise a proper error now that we have + # split the value and the timestamp. + if sig_error is not None: + if ts_int is not None: + try: + ts_dt = self.timestamp_to_datetime(ts_int) + except (ValueError, OSError, OverflowError) as exc: + # Windows raises OSError + # 32-bit raises OverflowError + raise BadTimeSignature( + "Malformed timestamp", payload=value + ) from exc + + raise BadTimeSignature(str(sig_error), payload=value, date_signed=ts_dt) + + # Signature was okay but the timestamp is actually not there or + # malformed. Should not happen, but we handle it anyway. + if ts_int is None: + raise BadTimeSignature("Malformed timestamp", payload=value) + + # Check timestamp is not older than max_age + if max_age is not None: + age = self.get_timestamp() - ts_int + + if age > max_age: + raise SignatureExpired( + f"Signature age {age} > {max_age} seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if age < 0: + raise SignatureExpired( + f"Signature age {age} < 0 seconds", + payload=value, + date_signed=self.timestamp_to_datetime(ts_int), + ) + + if return_timestamp: + return value, self.timestamp_to_datetime(ts_int) + + return value + + def validate(self, signed_value: str | bytes, max_age: int | None = None) -> bool: + """Only validates the given signed value. Returns ``True`` if + the signature exists and is valid.""" + try: + self.unsign(signed_value, max_age=max_age) + return True + except BadSignature: + return False + + +class TimedSerializer(Serializer[_TSerialized]): + """Uses :class:`TimestampSigner` instead of the default + :class:`.Signer`. + """ + + default_signer: type[TimestampSigner] = TimestampSigner + + def iter_unsigners( + self, salt: str | bytes | None = None + ) -> cabc.Iterator[TimestampSigner]: + return t.cast("cabc.Iterator[TimestampSigner]", super().iter_unsigners(salt)) + + # TODO: Signature is incompatible because parameters were added + # before salt. + + def loads( # type: ignore[override] + self, + s: str | bytes, + max_age: int | None = None, + return_timestamp: bool = False, + salt: str | bytes | None = None, + ) -> t.Any: + """Reverse of :meth:`dumps`, raises :exc:`.BadSignature` if the + signature validation fails. If a ``max_age`` is provided it will + ensure the signature is not older than that time in seconds. In + case the signature is outdated, :exc:`.SignatureExpired` is + raised. All arguments are forwarded to the signer's + :meth:`~TimestampSigner.unsign` method. + """ + s = want_bytes(s) + last_exception = None + + for signer in self.iter_unsigners(salt): + try: + base64d, timestamp = signer.unsign( + s, max_age=max_age, return_timestamp=True + ) + payload = self.load_payload(base64d) + + if return_timestamp: + return payload, timestamp + + return payload + except SignatureExpired: + # The signature was unsigned successfully but was + # expired. Do not try the next signer. + raise + except BadSignature as err: + last_exception = err + + raise t.cast(BadSignature, last_exception) + + def loads_unsafe( # type: ignore[override] + self, + s: str | bytes, + max_age: int | None = None, + salt: str | bytes | None = None, + ) -> tuple[bool, t.Any]: + return self._loads_unsafe_impl(s, salt, load_kwargs={"max_age": max_age}) diff --git a/venv/lib/python3.12/site-packages/itsdangerous/url_safe.py b/venv/lib/python3.12/site-packages/itsdangerous/url_safe.py new file mode 100644 index 0000000..56a0793 --- /dev/null +++ b/venv/lib/python3.12/site-packages/itsdangerous/url_safe.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +import typing as t +import zlib + +from ._json import _CompactJSON +from .encoding import base64_decode +from .encoding import base64_encode +from .exc import BadPayload +from .serializer import _PDataSerializer +from .serializer import Serializer +from .timed import TimedSerializer + + +class URLSafeSerializerMixin(Serializer[str]): + """Mixed in with a regular serializer it will attempt to zlib + compress the string to make it shorter if necessary. It will also + base64 encode the string so that it can safely be placed in a URL. + """ + + default_serializer: _PDataSerializer[str] = _CompactJSON + + def load_payload( + self, + payload: bytes, + *args: t.Any, + serializer: t.Any | None = None, + **kwargs: t.Any, + ) -> t.Any: + decompress = False + + if payload.startswith(b"."): + payload = payload[1:] + decompress = True + + try: + json = base64_decode(payload) + except Exception as e: + raise BadPayload( + "Could not base64 decode the payload because of an exception", + original_error=e, + ) from e + + if decompress: + try: + json = zlib.decompress(json) + except Exception as e: + raise BadPayload( + "Could not zlib decompress the payload before decoding the payload", + original_error=e, + ) from e + + return super().load_payload(json, *args, **kwargs) + + def dump_payload(self, obj: t.Any) -> bytes: + json = super().dump_payload(obj) + is_compressed = False + compressed = zlib.compress(json) + + if len(compressed) < (len(json) - 1): + json = compressed + is_compressed = True + + base64d = base64_encode(json) + + if is_compressed: + base64d = b"." + base64d + + return base64d + + +class URLSafeSerializer(URLSafeSerializerMixin, Serializer[str]): + """Works like :class:`.Serializer` but dumps and loads into a URL + safe string consisting of the upper and lowercase character of the + alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ + + +class URLSafeTimedSerializer(URLSafeSerializerMixin, TimedSerializer[str]): + """Works like :class:`.TimedSerializer` but dumps and loads into a + URL safe string consisting of the upper and lowercase character of + the alphabet as well as ``'_'``, ``'-'`` and ``'.'``. + """ diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt new file mode 100644 index 0000000..c37cae4 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/LICENSE.txt @@ -0,0 +1,28 @@ +Copyright 2007 Pallets + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA new file mode 100644 index 0000000..265cc32 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/METADATA @@ -0,0 +1,76 @@ +Metadata-Version: 2.1 +Name: Jinja2 +Version: 3.1.4 +Summary: A very fast and expressive template engine. +Maintainer-email: Pallets +Requires-Python: >=3.7 +Description-Content-Type: text/markdown +Classifier: Development Status :: 5 - Production/Stable +Classifier: Environment :: Web Environment +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content +Classifier: Topic :: Text Processing :: Markup :: HTML +Classifier: Typing :: Typed +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ +Provides-Extra: i18n + +# Jinja + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +possible, it shouldn't make the template designer's job difficult by +restricting functionality too much. + + +## In A Nutshell + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +## Donate + +The Pallets organization develops and supports Jinja and other popular +packages. In order to grow the community of contributors and users, and +allow the maintainers to devote more time to the projects, [please +donate today][]. + +[please donate today]: https://palletsprojects.com/donate + diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD new file mode 100644 index 0000000..df3acaf --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/RECORD @@ -0,0 +1,57 @@ +jinja2-3.1.4.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +jinja2-3.1.4.dist-info/LICENSE.txt,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475 +jinja2-3.1.4.dist-info/METADATA,sha256=R_brzpPQVBvpGcsm-WbrtgotO7suQ1D0F-qkhTzeEfY,2640 +jinja2-3.1.4.dist-info/RECORD,, +jinja2-3.1.4.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81 +jinja2-3.1.4.dist-info/entry_points.txt,sha256=OL85gYU1eD8cuPlikifFngXpeBjaxl6rIJ8KkC_3r-I,58 +jinja2/__init__.py,sha256=wIl45IM20KGw-kfr7jJhaBxxX5g4-kihlBYjxopX7Pw,1928 +jinja2/__pycache__/__init__.cpython-312.pyc,, +jinja2/__pycache__/_identifier.cpython-312.pyc,, +jinja2/__pycache__/async_utils.cpython-312.pyc,, +jinja2/__pycache__/bccache.cpython-312.pyc,, +jinja2/__pycache__/compiler.cpython-312.pyc,, +jinja2/__pycache__/constants.cpython-312.pyc,, +jinja2/__pycache__/debug.cpython-312.pyc,, +jinja2/__pycache__/defaults.cpython-312.pyc,, +jinja2/__pycache__/environment.cpython-312.pyc,, +jinja2/__pycache__/exceptions.cpython-312.pyc,, +jinja2/__pycache__/ext.cpython-312.pyc,, +jinja2/__pycache__/filters.cpython-312.pyc,, +jinja2/__pycache__/idtracking.cpython-312.pyc,, +jinja2/__pycache__/lexer.cpython-312.pyc,, +jinja2/__pycache__/loaders.cpython-312.pyc,, +jinja2/__pycache__/meta.cpython-312.pyc,, +jinja2/__pycache__/nativetypes.cpython-312.pyc,, +jinja2/__pycache__/nodes.cpython-312.pyc,, +jinja2/__pycache__/optimizer.cpython-312.pyc,, +jinja2/__pycache__/parser.cpython-312.pyc,, +jinja2/__pycache__/runtime.cpython-312.pyc,, +jinja2/__pycache__/sandbox.cpython-312.pyc,, +jinja2/__pycache__/tests.cpython-312.pyc,, +jinja2/__pycache__/utils.cpython-312.pyc,, +jinja2/__pycache__/visitor.cpython-312.pyc,, +jinja2/_identifier.py,sha256=_zYctNKzRqlk_murTNlzrju1FFJL7Va_Ijqqd7ii2lU,1958 +jinja2/async_utils.py,sha256=JXKWCAXmTx0iZB4-hAsF50vgjxw_RJTjiLOlGGTBso0,2477 +jinja2/bccache.py,sha256=gh0qs9rulnXo0PhX5jTJy2UHzI8wFnQ63o_vw7nhzRg,14061 +jinja2/compiler.py,sha256=dpV-n6_iQUP4uSwlXwGUavJmwjvXdyxKzJ-AonFjPBk,72271 +jinja2/constants.py,sha256=GMoFydBF_kdpaRKPoM5cl5MviquVRLVyZtfp5-16jg0,1433 +jinja2/debug.py,sha256=iWJ432RadxJNnaMOPrjIDInz50UEgni3_HKuFXi2vuQ,6299 +jinja2/defaults.py,sha256=boBcSw78h-lp20YbaXSJsqkAI2uN_mD_TtCydpeq5wU,1267 +jinja2/environment.py,sha256=xhFkmxO0CESA76Ki5tz4XWq9yzGu-t0p93JCCVBVNps,61538 +jinja2/exceptions.py,sha256=ioHeHrWwCWNaXX1inHmHVblvc4haO7AXsjCp3GfWvx0,5071 +jinja2/ext.py,sha256=igsBH7c6C0byHaOtMbE-ugpt4GjLGgR-ywskyXtKgq8,31877 +jinja2/filters.py,sha256=bKeqjFjjz88TkHVLSyyMIEB75CzAN6b3Airgx0phJDg,54611 +jinja2/idtracking.py,sha256=GfNmadir4oDALVxzn3DL9YInhJDr69ebXeA2ygfuCGA,10704 +jinja2/lexer.py,sha256=xnWWXhPndHFsoqzpc5VTjheDE9JuKk9MUo9DZkrM8Os,29754 +jinja2/loaders.py,sha256=ru0GIWHo5KiHJi7_MoI_LvGDoBBvP6rd0hiC1ReaTwk,23167 +jinja2/meta.py,sha256=OTDPkaFvU2Hgvx-6akz7154F8BIWaRmvJcBFvwopHww,4397 +jinja2/nativetypes.py,sha256=7GIGALVJgdyL80oZJdQUaUfwSt5q2lSSZbXt0dNf_M4,4210 +jinja2/nodes.py,sha256=m1Duzcr6qhZI8JQ6VyJgUNinjAf5bQzijSmDnMsvUx8,34579 +jinja2/optimizer.py,sha256=rJnCRlQ7pZsEEmMhsQDgC_pKyDHxP5TPS6zVPGsgcu8,1651 +jinja2/parser.py,sha256=DV1iF1FR2Rsaj_5zl8rmx7j6Bj4S8iLHoYsvJ0bfEis,39890 +jinja2/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +jinja2/runtime.py,sha256=POXT3tKNKJRENx2CymwUsOOXH2JwGPjW702njB5__cQ,33435 +jinja2/sandbox.py,sha256=TJjBNS9qRJ2ZgBMWdAgRBpyDLOHea2kT-2mk4PrjYx0,14616 +jinja2/tests.py,sha256=VLsBhVFnWg-PxSBz1MhRnNWgP1ovXk3neO1FLQMeC9Q,5926 +jinja2/utils.py,sha256=nV7IpWLvRCMyHW1irBAK8CIPAnOFfkb2ukggDBjbBEY,23952 +jinja2/visitor.py,sha256=EcnL1PIwf_4RVCOMxsRNuR8AXHbS1qfAdMOE2ngKJz4,3557 diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL new file mode 100644 index 0000000..3b5e64b --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: flit 3.9.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt new file mode 100644 index 0000000..abc3eae --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2-3.1.4.dist-info/entry_points.txt @@ -0,0 +1,3 @@ +[babel.extractors] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/venv/lib/python3.12/site-packages/jinja2/__init__.py b/venv/lib/python3.12/site-packages/jinja2/__init__.py new file mode 100644 index 0000000..2f0b5b2 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/__init__.py @@ -0,0 +1,38 @@ +"""Jinja is a template engine written in pure Python. It provides a +non-XML syntax that supports inline expressions and an optional +sandboxed environment. +""" + +from .bccache import BytecodeCache as BytecodeCache +from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache +from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache +from .environment import Environment as Environment +from .environment import Template as Template +from .exceptions import TemplateAssertionError as TemplateAssertionError +from .exceptions import TemplateError as TemplateError +from .exceptions import TemplateNotFound as TemplateNotFound +from .exceptions import TemplateRuntimeError as TemplateRuntimeError +from .exceptions import TemplatesNotFound as TemplatesNotFound +from .exceptions import TemplateSyntaxError as TemplateSyntaxError +from .exceptions import UndefinedError as UndefinedError +from .loaders import BaseLoader as BaseLoader +from .loaders import ChoiceLoader as ChoiceLoader +from .loaders import DictLoader as DictLoader +from .loaders import FileSystemLoader as FileSystemLoader +from .loaders import FunctionLoader as FunctionLoader +from .loaders import ModuleLoader as ModuleLoader +from .loaders import PackageLoader as PackageLoader +from .loaders import PrefixLoader as PrefixLoader +from .runtime import ChainableUndefined as ChainableUndefined +from .runtime import DebugUndefined as DebugUndefined +from .runtime import make_logging_undefined as make_logging_undefined +from .runtime import StrictUndefined as StrictUndefined +from .runtime import Undefined as Undefined +from .utils import clear_caches as clear_caches +from .utils import is_undefined as is_undefined +from .utils import pass_context as pass_context +from .utils import pass_environment as pass_environment +from .utils import pass_eval_context as pass_eval_context +from .utils import select_autoescape as select_autoescape + +__version__ = "3.1.4" diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca8a6094f2bfe3aad7887a7ac212a4f7e52dc3ec GIT binary patch literal 1666 zcmZ9M*>2lL6oyBOEs5H9@22gfg%Mb6mM#I(0QHu(umdAbfnsh5ikwPJ$Qfd0q)NGJ z@A?MqEA$2W5`BOI0tgi7Rqt8^z3ElYj7>=mA^rHyKWA2+;jiVgf#CV&w~N6KIfVXD zLGq+;;q7-RgnmRG!pKW`=^z!RaXO_q1DwGb%~{|q&T3u>R>D=hs(BSShjW^9K|U_ulTm^36hUOY@6E`*2 zfm^txxdGh9ZOu*K4(@1f0e5j%a~pUKuW9ZC>){68(A)*y#G9JefVc3L=5^q0ysdcy zcn9xj-VAm_6Pud1fcNm8=5648ysvo&_y8Yh-UYsc?`SrG@8Y|_d-%QS{^7x!pT6|z zE64PO>6ns)QQ$~o5<2iHF~8-$l!Tf-HKP$H=G9aV8SR;0NHgMW?0W=y8I;kZuP-l5 zF{RR(m~!YyQ;edBaVel{phhB-h!Y`vMxh7w;BT@>Lg)mB0He<)#Di(aK4&x}RQ8NN zp+3-IYF0j;O5!q)oH*`~fYCko19CkTu-bQT+n%DswK+OznIFy^6KyLL~a#-kca$z|r zxdCywt>2hX+w{f%`j;X{2-{^;l8J=&nvR#M1iboai#5yBqPFgBJyVC zVefwL(euOiXF1#Um}}d!T;J7G^9)oP&nj5~nH862;H%1pj~JR6Wa1KCw1VfATTr6D zbiAmfq@=8*0y4`5`t1o`RaQ+&T}eYpQ%OrnTS*6Gmg6@C#JkE`Q?jmPL&+w{Y-J?< zK=3VPY%AGOva7^YvIjCN+V+@mb=7S9XY>{<^si?PSx7AU0r#fFI%V!i-7#Uo(F!Zl zx7rpiCxqH!=x}0<;Rvk2@834U**&m?FUe7KQ#8VQr9K-EEZg>}FKxRQO=tNhp)Rqf z{0Jsh*H=)GzcQ&*>hE+WmHo#+sYfw-7NfHmJ&e&&j6RRiM=^R5qth5YjnQ$8KGFVt nt&d~$VT^zw8T3;fLf?;LbT39$@`DgEAOBuye_!PHV9Ngh3F+(N literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/_identifier.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..678726bb3dd4bf4aed1ffa91aefb1b6f116d2e9f GIT binary patch literal 2147 zcmYL~%Wvb>8O3EA?KBOt?5>NVyQH{Lnl8F2y6Up%ACR^PTw9&-bjCJpPl{QUddm;S zqCF#7wk6Y|UL-|R5~+u+7tn1Vi!8>OahmzAyz1SUfOlQ>Tr@!i{CLj&?$N#9B_;50 z@4ff^5I()@Uq7rp2!(Ft;M>o_H|G8$n0#nCv^@7D^hszw6bU_^|2Fi0U7ok+{x|w$ z{`uVd3;&jb-#q&{mi_JT{`}Ye-xc-`_n+x6;_Qp`D~-JxznWf0uVdGV>*RI%%Pjly z`1LM(efGL_lVdlhH)rgoa#O!)+*s_!`AYk$#s0PPb&Y-9dTX<{-rF(hIYxSc^b?3d zdKFS9-Gn%FUSM>7LdGE@@;MXY(#C9>@wK~+33lhQWM!`oSGwQBI_i`Nt2Ty2T?~QCr3`6oH98EUBu`D z5jRF|3X&mr2cnXjrR_`@oH`@wAnGN^ zL)6QVhp4BL_maFEd1dkp^0A~JCx1x(hs28JNoccS| z-)Gc+LH!){kKoRz-=V%ogEkF(MuRK5#C^E@oUYn*g~HV(T@C4KM8gcDp-Q788Wm{N zrBRrQ8Voz42wTg76xihCO?+{TVY z!4(CciNaVMm&EazIBAKKw$NijPYHcj=mrydU6d73j*2pZMp76$q%Dl8sMMIKIHHhRH;uC(O7o_k^hmbI61_7FJ7G9VRSaSbbp)gf$V?RM=5r z+f3N5u)D(U2^TxNmT;TGb?%y_yMe;)2K#pd9pc^%yt{#acd4?w%l*62G{~mML3URU zvTBdvausCpU&SR3k{|{4WMLl+q>&MP&#r=6ko7Al`t=|?PQi?`fu<-7ml!}^i>AO7 zCWcC^CCyc!C1fUnN}?`}A85%WKsM_g~@e+ zJW(F~Qq{UFzrriscJ&E&?DAUD~EnH&Tsogyd&#blM?Vgg5+4!|jj zcuK`oQkq?0N#g{??HJ5{ZHOscr(8ddGlat?dkf;6PWeI zt*yw$su{YM@7Di33_n_X8VRp{w6Xj=68_cN(zBVd-qqWsfHJR-F{S61| literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/async_utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ddb69fa0e37eb6f3b0604d3ad0a308a41127c3c5 GIT binary patch literal 4091 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/bccache.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb096330d138fafab1e3291f3b1618b3f2a929ed GIT binary patch literal 19338 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/compiler.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82c6736c4a0b1a6c86534e2d02bbb8aeaab84e77 GIT binary patch literal 102271 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ďJwX`Hk1}8Yrg` z7T$h!-<5sg&9enCOS<5?i?jns`2NAr;meO)dL+~blvR!+#Ey^4ExBE>oX%)Y=cj(6 zDqihP>#ef=NtM*wn2|IKiTGl(@Fhe(!z@fiWYb2(bQx#cox_g&RTKkTCTwuoxUvym zK89~0pZJjP5SEQ%8bNy9Jc1nyIjU`cP~Pem?PHrIw>y^870v1Tl&P$|TG?&;Z_*Z9 za<5SM4LBfW$%0MN9h9t*R#q6Pfz*xCAS)TN61CC5`T#>Aqi@jI0|b(8 z{4IrWBV#dWFkk^r@WH(`WnLUOPPMprrNszEpk^K!f4{V)upa(CK;C8buQe)B^<1+#XW+fm4uB z-JGW(;%)@S^EM^m8hZ6FZ1$X7#=~HAD!dZm>@ARP5LK1`1Yg5Z!1t(8JLpDJn74f$ zGy1+gtF*s04=n3_^-o-H$;qmX@UqN0fQ zYOW6CDA5-7T;2&tjA!X?!{XWfkDnYJJkkF&tfnw}i!*bx&3nXcXuE-xtBaTaE+w3y zn|MD+urC+TXS12_tP`*W{)9j7 z4N0d|*$PIA+ZLSd%C?Sefz%nRpT54=dRNd9g6F5z*VO@*m8wnpLv~H2|_`7z3Z-L>z<+R;Na+4bW3VFPlQu^RuYuc znGJwc0W4!*Mhmy;GSYs4NU&GSFmmd-Ig`<0wB1p>Ct#~84FA1DXPz0AQ=IH7iF;_w z8&QmYvfF;XbGkD)I1SP0TD9}q$x}xV=GJd@xONW3r0OHn;g)~^K~E5UXu6C&fgVIJ zm@gyc#|euJWz)k&7j61VD3h>(puZF=z4Y3_fn!7B1y4=Ak9ur1YN7X77dPUa;`~x5 z+(u1hOVv3<{a%IFA+EN z&)9S|NoXhw|E>G&o?G^tnB9>)A=$(Vkg3OEd359{=n1x5QH;+puHCXdQ(Wna?fM&A zR70HNt`OyXgt~&b+rYAFS4?dVZM(et(rz%ggdQ-o?dFls(Q5FX;Tb?Qxqi!HQW^nO zUTo|SW=?^qZ~qqpX^*ymUM8wCp2f8)kHNMWXK*g>suB(h+n*g98leL8j#?#xndSKg zsGAy+yD3uG44;bqSNbE(chAb#>VD#V+k34%;=XqQhpQWqH))TqO|e6_=rrIIfW7$= zcNYzsj?Z-~;Ed9aAyEzkKMC-QA_-6SB*U|i(Gc9%4i1@((TQ`Nr0SE9gmK=AE3fTC zw%wxgfIMoX>B4%atZ`~cR4LcJQIOMD#6VWbtG#VVhV@JzcBaW~TrHY*DKdYNno9Ou zjZIa7@AO;>BxT174Dg7YNCkMwF7?=;#T`UU509J%HW4>XS)Zv*luf)otEo@xlz=Fbj(G32%%kA zjlIa~tnnH2I_Q>TSq>q;L3GfL_Y|6dy+_Nw=`xi}sM2()BS_dAhAWs0n1G{&_yOF3 zmwW|pcykTzy%}C-+d6j8{2bvzDu!#)>Xs=Sl)#*I(`=B>;#(WvD}7eZo^!zcfzJ%Sf&&^7^;iac0_AC;OVP& zQ>5lDUAtD*n|(4;3@_G=`mPdImZ0k4Xuy-0V`bE_GSrLo8+;0e+ow*<6|DtN;Fp_+ zoYfd})J7e(n)ejr+MAA+u{rrA^d;t`kZ}&N_^+fEiziKSF^Qeb`c8#pMdzl**~JVu z3QieB=c;0UpNi;Vv6*xr*(J^?Zi$gE_tLN10oTxE)r3Yxf-TTw^*{h5#aV8@wrD(T zdFc;TZB=q~mrwKn2sF*ye+!#FhrHSGj8SF=+0X5_nHV9OW^z2k&!v>PT{qHFWha}< zrb#^G1m}^+OhcKlDHEmOeDG3b4+A@FL|mXo_m298Y1b2I5K&XxmuH-&iSsIoWt3D& z#rg49$0t;WiIK{d@H1DRyYgK4soAzj`Q30nt|}!wbN=k~+0YP#q@e|y)4f-Rr}a}tjKA%y-&&aV$AxuUH%WioW5qpb6Qz-|d-&84vS3tX zhviCWa7DCCY44DqVOkVT7c+NYHA)g8pOE@6P7_RB4XpG66^#}NC5Y&dWPf0!(IRez zHf{8hO$&jb9oT!*5^FOq#aI#m=4Dt2mO;9I;OU`8Z=hsZf;>bP?-k=k4!&%xMMWTB ziC6f12oa#Om4Ti6r1N)FM+xj8n9jT6&e4|QUUC@+)fJyVM8_xl;fZ( zJ`LDX;S<1kV2x-pq|E+1G$rWRT$vKF;%gs}FN;za)Ts8cwp9z2u^*8;%@e2FDzg z@H`nDR@NRoiIlFJX`Wdz`^8A{mIcRFwl{#L{EkENAEIjfAkE56OA_0PSg`0Dgn{${ z|Cy1&YWZ8V?tVX|BP;H{D*X_!#_s*{2o?GwZg5f|gWi;Ggeu5Cr({MGuwC!J&`)Nq>YMBpV(iO5riXt@ zzrh@~6r|3rR zqT~nY_7L43q#L7Nh%}MU(XE|sjKE>$a3<&{vw}wqE%}e==busRZMyv~{rnMb@r>Og zgC|d;&3{h6(m8u1p0xuWL3mt_P~LgE{S{@g?HHBik0_S5`W`zLs18v6r&11uZPYsPdIqKsMOqeT^Lgbd2 z4N+$Qb0aliH9ccSK-W@P>D(NrypjFjR=wmd`jKrg@g;Afw<7fZU*Z;*m{}8f3qAc4 zYC|u@n&`HZZhPtWr<8CnVsSgE-pc#w;l1>FCZDxid_FaL@bu$q^xo4a)#$e2r{l{0 zdIwIDWcsbVd*A3YY7`5f8r=dtTE)%xepxR(U|ysw&fNwcnEVnwa-nib+!^_s^td<$J4T+ORB93DlDtAcCB{RLf0M--vXw7T z+-aoS<=>)5ZUNGkX|0Htro__n?;+jfY)>Y}4!bp@b^f=UH3)Ax2tq!3L^|ai-8XFoQWqRxCRn&;9Sd({ z<}68gzSNi|Ro!%?NwvXVD!Mjor;=-LIwT4EnS=#Fc;M>sE5~OG-zxh-S+r#vdltFx z&=RF3a&1yY@HBn2BJ81$R^X%Cth=l?ZRygA#e7eKg_X5DY+8M_=}Obg;Wv-GaU|Mw z4|~Y!g3Jk5rj#GDUe3Cd74Ep&eWg2Ey&+-2vssjn;2o5YAW`I$DyRGj3xeR-5(SAB zmfhAp_@pEiu}@N1QF(FCg*~Cumjjmq(Tep6mbi603)v@;>1M8kKHrj@5$$Tawvw9J z^bYzF0i-{A?!KA1QEI)BoA>e)lTW}8`0?rE+$isi^k&u@S&^ddXl_qJLLNYit1yv4 zF^8qNgyqb?TzaWA+%{u}Os?Zmy!ZY=6Hoegl zZMZ98!Lw_1OB5s?vF1vfX;ct|+m|S~S)DFzwbC;RXWM!B&bB4?`=-k(?XrdeJrrKU z5K|br|IiYPB+{+Y`k6OX=!|;0 z5;m5+btjM9$jo}Vc(Qn^FzA@7ie}afnNKFLiK10^?8!#Ac4YJbOVJ;1!+=U0uZ_( zj20o7L30r#a;;KF7*hnn3~OS?5?a_y&0NRZw=R)xmsW=G2?PnJRXS`9p@I~KF^wps z9Btvj1aiRiFlB68a;8b%gu^TCw}#Qv6waXgDa4pq?y+tI?47n^nsKr(!GEl7CMcd6 zimu+opD?hae2Ed8SE>jxWi%?Uf_e!7^%8=_1J*{V2H>^k(wc+?(OL8W0)hhsi9^

    j5K!+RNO*uO zLfbFzzqFsAeZ?$N5nMy6f<+oaL$OsGqpLPj5G920RqhW znR*t?ZX@`tPn4ud^`VZ-n=fr9bXY%&R0P+Mir^z4%F3YiqVt0DBmAz!{7x^xwpJ<& zO6W2A-yv8|uYr@`whU6?+5G0OT zC23{YdNu1x*37y$JKpGsHg-{YD`x?h2okw&sh;3#&-9*zjp7Z>JnRHc!|xlJ&Ls(9 zqAAyqk>Zq*LduAc4L8C>b*5CIl}K^QNFilJ$TA{K6y0kDyeVKoaRLhp2`nf~JeHO& zHL5ufr3?rt9YMn7kyhzrf*&*{2xv?YB-R#7CF+xO1K2UwK{^}5+yTYiCmf)NodoTDZzyESuUE%`E*;LI(OEFDP-q%Bq(uZBPLk zQR+hk)Q1R^>LHe>W|^@*sPKy@K>~u=Z68vgWJXNsB@a3rDCRprF^Ce1L2wP35h$4v zOEjb88{7BXw0Wp?%EYHQO;ZXtZ)G8->4y@2Yp+%&n$s}fw6R*n$7&THt5pf7O|Jl= zQ~?Bp;}9gWFxdE9%+qq+(?Zlz$>K(=UkDjKV4win(vXFIQ5J+O3sIgRM)zY0LNU$P zJ*Y4H+0o4-N-nIPSy&9&^t?{f6F+ErBB1F>>m*k06~^=xJbeXEhy58Fh)nuQ({&GI zi|JQeCkvHttYBm@%R=^CDXDd_`)(HMm9+xIlo3IcIs^fA2m-3ZDir_`B>+S~0Ei%w zF6pU=a`eMe@hg$*#H1ng!`g=*RDT3ie*}q&Y^j@7Zq0SinuLvhZNT!3kW~(0qAW{- zo(Q$E?YgHeVPiixZQ&8*`beTDjO`;|##YC>L%vG;#&l@c5qqSQeq;^uecH+4$N6?M zleyC#9X;un?UW&HcvL11DKvz!4;^C(#6FWR((Z}4f#lu<1wF+KANe6%#$D_YBa?BE zIAbSEbMWVvv8!SdHgK&rc!H`zEK50;Zh3Sgmb**}s4~e?$gOmv!>_n>8a9{wT&IxE zy5v1{E25;FLl57#y}x(Y_TIg_`*z0jc_Sg&u1M$j<7udWFXb<${27O!WB9;;O!B@K z&MGRQL^9dWHuK!r=U#e7+y?o6x)CoxW(=JfiiIgNV|?|~PaoZWPPgAjLfm$6XiR>A zeloriF}~u?1E;aYeQIdCEMrIiJSF~Dx_yamZB*QKim`3zG{s2fhx6(ko4D)F&GP?7 zKJ+=%R}cZC+iHE!vf*zn1s_=IKd{t&U@88rQR}p>Sj4BH($9B?(QKGv zqKC?!_u!RQ_M4h{_=Uq0Z7&>Il92xK3dy?arUkc;UH4h7o|_iBe{?L(iY@I_^G6m6 zKXSON4Z#y1SrB}*%57a0-20IQ!AH$@t7EF`BMX9$a>q-pz1FF{zp$_fgQ@=q5Ry`* literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/constants.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..886159653902c3fad4b4f754a019d3970e77143b GIT binary patch literal 1569 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 oE?fO$6*x`NPe1s##a}JnOa14O-yZ+3U8I3*RZ zAdSM>^645Mk?{$DWCD*|2MfC5|LD@5E+b9ij5LL_(m9-i)%gK?o?IZ)Bu-)^L56YR zc|^L1NAVaI;4==t2|TI_ID?DNqtXmSTJrNawPYOlJEwCWZ3YIJPV!hip)~c9yP7Yd z)~F<~p{07GC9ZD(47bFM76*}9udNXZD8EGvLKU0Hnn{T+s~xMWbH)3n3JyTArlJ$8 zqqK<=cs%C>=AM9k>;#^0JL?2ypRhus-W27HR<$Lrh|QL~wk|H!KVmtLuC1<|A(xmC zch1|S+)!$m-W!6Vqua?-F*S-tv>QMRe7>jbm(qPSGO*MQ2cHtMyyxKWy85xdt>jV&hF zY-m%}pjsA%7YnfwUp%;27Pg6HThu#d(sz1S&B9$<)hrr;b##aiQ9khZktJInuZeQ) zj#yi+H*d4dNjMpDBZdW;TP$D`mc7+jtu6DrU2nm-&ZX%SPHZmvOyPs-dcAt9;Wfdj zF!wKgMw|B=;y-(4efCsI`5y|4u6B4G6^#Yqme`0aD~4g(3MVaDrU@=eKw>Mhm(~VL zHh7+EgDFjNL19@G*W}iEwGMrCTORZmO@WV&a6!heTeG?%Zmd;nA|2y=Xp#3@uxj+a zN5?>*zj0;T)Jes7gW?{kESl}EP7K?sv>~5Lr)O`Q2DAtz1kAQVN#!9i9#%B<^MUit z^3`h<3%Y*+-l+%57O^TjsArgdcI#)~ zK0r6z@pG{DD2`G&cR1~)X53Vse>25b$)Q4^k1|K2X!3%aoq|~I)U-P`?!vS<_rmT^ pT!GcEGO^b|mfpR%e`)X1v)nV~JMt}gR{SaZ+FvLp1n4z5>p#R-(-;5% literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/environment.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3eff7f71a5adfe1bb0d6693d4697965354b35c55 GIT binary patch literal 76715 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 S`6LG6ZS>ID{RKVnWB)%55~Y&> literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/ext.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d33d0cf21e0f920c25b95678488a254e245c9df1 GIT binary patch literal 41881 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/idtracking.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9f5c5f2bab1f71cd5e294e4d6b5097941f859930 GIT binary patch literal 19162 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 {k$|!h4DWT90 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/meta.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8df4dfee3515fde554bba4e1723e7c865c3ecf24 GIT binary patch literal 5483 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/nativetypes.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cdcb31523c63bc3bee8db8423c0968d3f17be96e GIT binary patch literal 7032 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 ZX_0b4k+O`Y|Hm`vG8TW|Kxftm|37??0U!VX literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/runtime.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98a6f6891caa0b551e3519af2088a0ec5bb120bb GIT binary patch literal 48505 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/sandbox.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..46d4ad6e7d027f55f887306383d389e45984302c GIT binary patch literal 17903 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/tests.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de6e309ff3c79ba850b03fed62e8b8e8b97a2a73 GIT binary patch literal 9063 zcmcgwU2Ggja-P{A?sAu;C`y$0ui^inwG{Pdnfmb$McF!E=-iPEVqS9OaHlCQwYx+0 z%t|7q103HWp>T(o!XY7bI6zDg<0SYYeh7lR<}JXztgQ$8CNW^(k_SI!&b)`g6ny{u*>`XCom7^nfvk|~yqbeQERL@omIFgQK;p)-4jucVkT^QR}cC56=ZqW2spy>h4Kv|kz@bG=#I*aweoHc{Mv%@~jI+Rk3es=WdsxiPC zP!6(VD2G@h%3*c_K`tUpJw#%$wdG1r0lvm&hzVa!BX%#E^`H-Y(~KS!~~Y;Tpre5e95U!?V+Z`r%x zk1N)g;ecM_<}bq^s88M00i;xG@#g29wJPvRl%$Sx8bg*l)>Oy z_xHsp&E`3#r4|LZcXgi97t&~3nrRq`uV@;MFr++Jo~yhXfJLilf6zyk%nTdJp5ewS z8@X;KbHt!Ek~Fi{$jYj{WM=2ABxelOlFr%4UC1$#PAz!IbBWQjBUZ|0r&sjkZT%Lr zMwV0AW&P}k*u})ksuLw>4s7sxEO`X~4gv2eU&iYj+gPx+Rz_f(Lb zf!hSH!NgqbKrKOaD5Uh9m~pBFe?-cUqfI|QN(F7X6U^o^NgC{b`!w=UYDD!k5?DJu zzQmHZNf)|SstF@?H)W+rEeoqaVPaTJqR81`Kxl?HVkwK3(KN|nz2LAgd|{O%*HFm4 zS;VN^$#ah`Z*_hWZ_S5V1?RiAG6XVVMm+#F6}w3BJ_h^+LB!xB9DmH`y(-)i0BiiK{JcAW7>lU#eqL6 zQe#S%w%Gm&isqj+ZOvn|um}yy8ej$si_R&AQ;$FMDuyTi9y|2%ht0=#&Kx(n_i7ntlS3P3X%@| z7Mb9C%J18h`j)NUe`tPjWH=um&WDB%(Q6lmRMIPHb?x+bQ@2Y6B_B1fE#z#m0VZ~V z3lX^q=@OibY~P8g6Kofx=j|XG!Ee!ddQbV!c;g29<-0H9{rOP8cZ%ROcof)!j}l1@ z=cYbXmI3Yk?n--XhCP;?EKfJ=eu}&`PE=OUu!J^avBg|k9zKsG1C1>(p%in)PMKLf zoyGyYtEbZBBohVeCA&SnkT#RI%UN%KM(4K;^Io=}T&p+#9`hBp3V*IW)O>2KvdtDo z?IGP|r#NAE8MjCT!(axuJeN2l1Vc!PNOr8}0Z#iVy?m(~i3_z!DozG-9=~-A#e0g| zq0}7R7~g#R@!R?MseI^^v^CEofJ9LU7Cz(~Y3u#n+M=bk!*nGG{x3C^Hgks1l9+j~ zjyzvPYJwt(cCQm5Pvk4*VQvM1zf_9?d$9M}H85@7J9wb4SE8n`j4SgwC|!G>`#RJt z!X&@NJE6T@K}Ci=Lh@eVZV=wHg+6HuHy_{3$J_Iv_WgdRU<-8pm1#+iPHAARQb^94 zS(cdOheTqc;Qg4Fl2VI;w+wLC*RSS7O^5JuqJ)?GsufZxT?z=kf@_lpgfeqsnI&y9 z09{)!%{0@qGWZl-!k*)HHZeLX&fD~jgGG=Y-J6ULf+L-zpm>c#7Nd=Y9G}LAwkEb` zwkGqTp+f}Px4G9372<}DSXi0$GMvZA6y_Fb4n7QaQ^YsrNy)N_8+OMJWp^40 zYh`Yy58h|bdNBn*4Ic08WwxBLgg_{q*cgCH0rS4fW5S5koC?@CC{^U$HxCsKmXylc z>=qKdLU<`}OUV3Mz>gEen0?V!nv^#iKLffo{1zQrBndF76Nt7`FXEk_#wWMg$LI5X zF9Z6QiGOR%Ux9&5?$=mh6DSB&+60j`+&ElVZ82@?c4bL@Im3c}pQN4%(p>x;So<-_ zDKlJO&Y2hS?tG|wzf7c5p;!uPyJh+ap@_a^!teR~*C`?8&;e5VS)B|MaOO!J7sJG0 zzzM>0I+2tmTznZ>B<^J_`cwQnl-W~$RJWe{>DXuS_D|yNFG`}V$ERTN|3e-T)qHvQ z1*}W*h~6^tNZe&mZs6yasGw`o!IzD1Y+ii_Y<#J6#!jcQx3KBrmdk`Hwr!tg~5*=;+;+tD(enmwO?V-nUgRY8c1zOn)-v;iZ9pu_BBV(^d? zb5W*sK`Aj=gA@59Im15DrHAn5=dXeG7x*n{ZT`ubdisMWKX?%z%!dXK*@17YvVjAn zEj=rR`>n4u+P;09OQp%1FnN$jEdJo)Gs&`##{UcA_dpQ7t zJ)f$q2D%lypwb?N2UX==WmUbW+z-C1+*9$g^23TETI^1a;dYnMraTC#1ZRc2swI?Y zFX^`E#xn_*HxA19ZcGmbonV?}o%r0`EoK9onVWN}C+;VixTfsety&SH{YCkk5b9U> zEs6<<($P@3@js&R^@*RwK9AOZ7H$4C+U!P^n)?6weMG5g{8~}NjlVf^+zq1sgGj92 zKiQ)EqPj2mq1qR8!s7CG@CD7!L>{Ulol@8SyLc1JYTi*@F%hIJx*XG8+QM~A%dm{e zao57*53_(;LR{2wCC4pOY>gcGZQc(SO*5g}@CUfEirk&n(Qy}}#AR;|Pkdm2Rvf^Y zxcnjIBiy`5ndWh|&)!Ni+sq24{B*oDMHg8JOqrg}_*=B;WL5qHjpus=C;U4={1Z`l z$$c71NS$O;CrhJM5N;3&P z3^*Y|I@QywD{O*ulb10%-*ovT82(q1jxux@T_{LKSF=9zvv>tti`OZCUELCVqP7GN z4i}UH?e@NgTH;{?YaIm_2%2P8QeQz#cA|50OLitbH%GVOCEX&m?~_M5OK%J( z=kaS2$M-o68yB{QUc`Izp?%av`j>?Jp*5gEz zIDX^;F-)8mC*o!;X5z38ZZ&nud=d)LP&QhNaoyIVUnVXP8O2)u{h;?^M~V6o(xZ^Ciu68dpF( zs90RaSjoJ_>0mk$p3B;)jC{R=z;-Ha@d#mRr{DeKiMjE&CdS{sIr*j&FL~V;?_8YT z!<-Q9rg-)iPs`%j)(O6zT@`PA;@wOpGhLt-*Kl$1757GQ2@{tak@Jg$m{TUnDg6=| zjtKQ4Y>HSQJdZe_!mOR@aWiY{c;Ms0ZaCfOc!mm-3c53Ki;5f-_fR4~Z7DS73h zyiUG9N3Uc|BbR2^_+O%rvQ*2!{veR3>Ti@Qzg3R>yVCH5()xwc@?T2F7fSb+!O&m5 z`u?k5ga+KIfZDP#?kcFZuJ2Ig#;9vbc1;($+O`B$+jf#LZO;tCw7Ic5^`$NKY4}Ol zRRC`H>`>))1=NA9&ZoUkdWm{qTTDHG3wEHv4b-XH#-9_p_UxRfK0g07wRVC&+U*ih zgW9oi)m2bEJ0_}+kAF=qj}VYM6i}NtzPCB^c!m~g-m;0UW;YgAhkdpH5?iR;`Y=S( zH`!z6qTR9`qV5*zE=&TDCPC#kgw=P{;w5=pFxb*=@CiX|$GKdk4 zHuHe4u8ljJxyLzTxoi74QFal_L&e30kUy#eo26AS(BGK<)Ea2S}@=NCRXH7fc(hNM8b^#j#`&qLMgm)szrFGI2Qn{F78Tcv~>^2fT} z2sNTgxNiNSTTO6G3D<9QxN(AOlyL3(ZMT--Iwc&(;3EXrOZX_k4RY);f{!cVn)O+? zk>C@O<|M&QlBSv97D>}eaGQkN3GR^aDS|b*ZYRNAV(jm_3GR{oy#)6u;UgQhZa={T z5*{RYh~TI@Oz=yR{xrb}$-@Z2XOwXDdcQkL@L7TfJ{W#9?4G0c`C|J5wJ*}R`yV`b z^uT?Y+Lwy>SExN!Y+t7K6(t;9Z~CD1QLB5E+SiKsSE>D)ik;uMw0ZgQW%qTJdfq^f u&%(IqxnAt~-Gu15p(?Qkn)Gv2;PvzRrp@@{xZjeUU%x}Ne-Rc@?SBEC)*C$l literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/utils.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e49722c2bd360f4ec86d35e5e125c4b8f12dbd02 GIT binary patch literal 34481 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 literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc b/venv/lib/python3.12/site-packages/jinja2/__pycache__/visitor.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b2021847d9238252439c2421a8359c10ce9a7fd GIT binary patch literal 5366 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 aze5j5y>|$7cl)IS()NWj|03`ZO8plbN-uW+ literal 0 HcmV?d00001 diff --git a/venv/lib/python3.12/site-packages/jinja2/_identifier.py b/venv/lib/python3.12/site-packages/jinja2/_identifier.py new file mode 100644 index 0000000..928c150 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/_identifier.py @@ -0,0 +1,6 @@ +import re + +# generated by scripts/generate_identifier_pattern.py +pattern = re.compile( + r"[\w·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-ٰٟۖ-ۜ۟-۪ۤۧۨ-ܑۭܰ-݊ަ-ް߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛࣓-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣঁ-ঃ়া-ৄেৈো-্ৗৢৣ৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑੰੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣஂா-ூெ-ைொ-்ௗఀ-ఄా-ౄె-ైొ-్ౕౖౢౣಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣංඃ්ා-ුූෘ-ෟෲෳัิ-ฺ็-๎ັິ-ູົຼ່-ໍ༹༘༙༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏႚ-ႝ፝-፟ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝᠋-᠍ᢅᢆᢩᤠ-ᤫᤰ-᤻ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼᪰-᪽ᬀ-ᬄ᬴-᭄᭫-᭳ᮀ-ᮂᮡ-ᮭ᯦-᯳ᰤ-᰷᳐-᳔᳒-᳨᳭ᳲ-᳴᳷-᳹᷀-᷹᷻-᷿‿⁀⁔⃐-⃥⃜⃡-⃰℘℮⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-ꣅ꣠-꣱ꣿꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀ꧥꨩ-ꨶꩃꩌꩍꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭ﬞ︀-️︠-︯︳︴﹍-﹏_𐇽𐋠𐍶-𐍺𐨁-𐨃𐨅𐨆𐨌-𐨏𐨸-𐨿𐨺𐫦𐫥𐴤-𐽆𐴧-𐽐𑀀-𑀂𑀸-𑁆𑁿-𑂂𑂰-𑂺𑄀-𑄂𑄧-𑄴𑅅𑅆𑅳𑆀-𑆂𑆳-𑇀𑇉-𑇌𑈬-𑈷𑈾𑋟-𑋪𑌀-𑌃𑌻𑌼𑌾-𑍄𑍇𑍈𑍋-𑍍𑍗𑍢𑍣𑍦-𑍬𑍰-𑍴𑐵-𑑆𑑞𑒰-𑓃𑖯-𑖵𑖸-𑗀𑗜𑗝𑘰-𑙀𑚫-𑚷𑜝-𑜫𑠬-𑠺𑨁-𑨊𑨳-𑨹𑨻-𑨾𑩇𑩑-𑩛𑪊-𑪙𑰯-𑰶𑰸-𑰿𑲒-𑲧𑲩-𑲶𑴱-𑴶𑴺𑴼𑴽𑴿-𑵅𑵇𑶊-𑶎𑶐𑶑𑶓-𑶗𑻳-𑻶𖫰-𖫴𖬰-𖬶𖽑-𖽾𖾏-𖾒𛲝𛲞𝅥-𝅩𝅭-𝅲𝅻-𝆂𝆅-𝆋𝆪-𝆭𝉂-𝉄𝨀-𝨶𝨻-𝩬𝩵𝪄𝪛-𝪟𝪡-𝪯𞀀-𞀆𞀈-𞀘𞀛-𞀡𞀣𞀤𞀦-𞣐𞀪-𞣖𞥄-𞥊󠄀-󠇯]+" # noqa: B950 +) diff --git a/venv/lib/python3.12/site-packages/jinja2/async_utils.py b/venv/lib/python3.12/site-packages/jinja2/async_utils.py new file mode 100644 index 0000000..e65219e --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/async_utils.py @@ -0,0 +1,84 @@ +import inspect +import typing as t +from functools import WRAPPER_ASSIGNMENTS +from functools import wraps + +from .utils import _PassArg +from .utils import pass_eval_context + +V = t.TypeVar("V") + + +def async_variant(normal_func): # type: ignore + def decorator(async_func): # type: ignore + pass_arg = _PassArg.from_obj(normal_func) + need_eval_context = pass_arg is None + + if pass_arg is _PassArg.environment: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].is_async) + + else: + + def is_async(args: t.Any) -> bool: + return t.cast(bool, args[0].environment.is_async) + + # Take the doc and annotations from the sync function, but the + # name from the async function. Pallets-Sphinx-Themes + # build_function_directive expects __wrapped__ to point to the + # sync function. + async_func_attrs = ("__module__", "__name__", "__qualname__") + normal_func_attrs = tuple(set(WRAPPER_ASSIGNMENTS).difference(async_func_attrs)) + + @wraps(normal_func, assigned=normal_func_attrs) + @wraps(async_func, assigned=async_func_attrs, updated=()) + def wrapper(*args, **kwargs): # type: ignore + b = is_async(args) + + if need_eval_context: + args = args[1:] + + if b: + return async_func(*args, **kwargs) + + return normal_func(*args, **kwargs) + + if need_eval_context: + wrapper = pass_eval_context(wrapper) + + wrapper.jinja_async_variant = True # type: ignore[attr-defined] + return wrapper + + return decorator + + +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + +async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + + if inspect.isawaitable(value): + return await t.cast("t.Awaitable[V]", value) + + return t.cast("V", value) + + +async def auto_aiter( + iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> "t.AsyncIterator[V]": + if hasattr(iterable, "__aiter__"): + async for item in t.cast("t.AsyncIterable[V]", iterable): + yield item + else: + for item in iterable: + yield item + + +async def auto_to_list( + value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", +) -> t.List["V"]: + return [x async for x in auto_aiter(value)] diff --git a/venv/lib/python3.12/site-packages/jinja2/bccache.py b/venv/lib/python3.12/site-packages/jinja2/bccache.py new file mode 100644 index 0000000..ada8b09 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/bccache.py @@ -0,0 +1,408 @@ +"""The optional bytecode cache system. This is useful if you have very +complex template situations and the compilation of all those templates +slows down your application too much. + +Situations where this is useful are often forking web applications that +are initialized on the first request. +""" + +import errno +import fnmatch +import marshal +import os +import pickle +import stat +import sys +import tempfile +import typing as t +from hashlib import sha1 +from io import BytesIO +from types import CodeType + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + + class _MemcachedClient(te.Protocol): + def get(self, key: str) -> bytes: ... + + def set( + self, key: str, value: bytes, timeout: t.Optional[int] = None + ) -> None: ... + + +bc_version = 5 +# Magic bytes to identify Jinja bytecode cache files. Contains the +# Python major and minor version to avoid loading incompatible bytecode +# if a project upgrades its Python version. +bc_magic = ( + b"j2" + + pickle.dumps(bc_version, 2) + + pickle.dumps((sys.version_info[0] << 24) | sys.version_info[1], 2) +) + + +class Bucket: + """Buckets are used to store the bytecode for one template. It's created + and initialized by the bytecode cache and passed to the loading functions. + + The buckets get an internal checksum from the cache assigned and use this + to automatically reject outdated cache material. Individual bytecode + cache subclasses don't have to care about cache invalidation. + """ + + def __init__(self, environment: "Environment", key: str, checksum: str) -> None: + self.environment = environment + self.key = key + self.checksum = checksum + self.reset() + + def reset(self) -> None: + """Resets the bucket (unloads the bytecode).""" + self.code: t.Optional[CodeType] = None + + def load_bytecode(self, f: t.BinaryIO) -> None: + """Loads bytecode from a file or file like object.""" + # make sure the magic header is correct + magic = f.read(len(bc_magic)) + if magic != bc_magic: + self.reset() + return + # the source code of the file changed, we need to reload + checksum = pickle.load(f) + if self.checksum != checksum: + self.reset() + return + # if marshal_load fails then we need to reload + try: + self.code = marshal.load(f) + except (EOFError, ValueError, TypeError): + self.reset() + return + + def write_bytecode(self, f: t.IO[bytes]) -> None: + """Dump the bytecode into the file or file like object passed.""" + if self.code is None: + raise TypeError("can't write empty bucket") + f.write(bc_magic) + pickle.dump(self.checksum, f, 2) + marshal.dump(self.code, f) + + def bytecode_from_string(self, string: bytes) -> None: + """Load bytecode from bytes.""" + self.load_bytecode(BytesIO(string)) + + def bytecode_to_string(self) -> bytes: + """Return the bytecode as bytes.""" + out = BytesIO() + self.write_bytecode(out) + return out.getvalue() + + +class BytecodeCache: + """To implement your own bytecode cache you have to subclass this class + and override :meth:`load_bytecode` and :meth:`dump_bytecode`. Both of + these methods are passed a :class:`~jinja2.bccache.Bucket`. + + A very basic bytecode cache that saves the bytecode on the file system:: + + from os import path + + class MyCache(BytecodeCache): + + def __init__(self, directory): + self.directory = directory + + def load_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + if path.exists(filename): + with open(filename, 'rb') as f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket): + filename = path.join(self.directory, bucket.key) + with open(filename, 'wb') as f: + bucket.write_bytecode(f) + + A more advanced version of a filesystem based bytecode cache is part of + Jinja. + """ + + def load_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to load bytecode into a + bucket. If they are not able to find code in the cache for the + bucket, it must not do anything. + """ + raise NotImplementedError() + + def dump_bytecode(self, bucket: Bucket) -> None: + """Subclasses have to override this method to write the bytecode + from a bucket back to the cache. If it unable to do so it must not + fail silently but raise an exception. + """ + raise NotImplementedError() + + def clear(self) -> None: + """Clears the cache. This method is not used by Jinja but should be + implemented to allow applications to clear the bytecode cache used + by a particular environment. + """ + + def get_cache_key( + self, name: str, filename: t.Optional[t.Union[str]] = None + ) -> str: + """Returns the unique hash key for this template name.""" + hash = sha1(name.encode("utf-8")) + + if filename is not None: + hash.update(f"|{filename}".encode()) + + return hash.hexdigest() + + def get_source_checksum(self, source: str) -> str: + """Returns a checksum for the source.""" + return sha1(source.encode("utf-8")).hexdigest() + + def get_bucket( + self, + environment: "Environment", + name: str, + filename: t.Optional[str], + source: str, + ) -> Bucket: + """Return a cache bucket for the given template. All arguments are + mandatory but filename may be `None`. + """ + key = self.get_cache_key(name, filename) + checksum = self.get_source_checksum(source) + bucket = Bucket(environment, key, checksum) + self.load_bytecode(bucket) + return bucket + + def set_bucket(self, bucket: Bucket) -> None: + """Put the bucket into the cache.""" + self.dump_bytecode(bucket) + + +class FileSystemBytecodeCache(BytecodeCache): + """A bytecode cache that stores bytecode on the filesystem. It accepts + two arguments: The directory where the cache items are stored and a + pattern string that is used to build the filename. + + If no directory is specified a default cache directory is selected. On + Windows the user's temp directory is used, on UNIX systems a directory + is created for the user in the system temp directory. + + The pattern can be used to have multiple separate caches operate on the + same directory. The default pattern is ``'__jinja2_%s.cache'``. ``%s`` + is replaced with the cache key. + + >>> bcc = FileSystemBytecodeCache('/tmp/jinja_cache', '%s.cache') + + This bytecode cache supports clearing of the cache using the clear method. + """ + + def __init__( + self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache" + ) -> None: + if directory is None: + directory = self._get_default_cache_dir() + self.directory = directory + self.pattern = pattern + + def _get_default_cache_dir(self) -> str: + def _unsafe_dir() -> "te.NoReturn": + raise RuntimeError( + "Cannot determine safe temp directory. You " + "need to explicitly provide one." + ) + + tmpdir = tempfile.gettempdir() + + # On windows the temporary directory is used specific unless + # explicitly forced otherwise. We can just use that. + if os.name == "nt": + return tmpdir + if not hasattr(os, "getuid"): + _unsafe_dir() + + dirname = f"_jinja2-cache-{os.getuid()}" + actual_dir = os.path.join(tmpdir, dirname) + + try: + os.mkdir(actual_dir, stat.S_IRWXU) + except OSError as e: + if e.errno != errno.EEXIST: + raise + try: + os.chmod(actual_dir, stat.S_IRWXU) + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + except OSError as e: + if e.errno != errno.EEXIST: + raise + + actual_dir_stat = os.lstat(actual_dir) + if ( + actual_dir_stat.st_uid != os.getuid() + or not stat.S_ISDIR(actual_dir_stat.st_mode) + or stat.S_IMODE(actual_dir_stat.st_mode) != stat.S_IRWXU + ): + _unsafe_dir() + + return actual_dir + + def _get_cache_filename(self, bucket: Bucket) -> str: + return os.path.join(self.directory, self.pattern % (bucket.key,)) + + def load_bytecode(self, bucket: Bucket) -> None: + filename = self._get_cache_filename(bucket) + + # Don't test for existence before opening the file, since the + # file could disappear after the test before the open. + try: + f = open(filename, "rb") + except (FileNotFoundError, IsADirectoryError, PermissionError): + # PermissionError can occur on Windows when an operation is + # in progress, such as calling clear(). + return + + with f: + bucket.load_bytecode(f) + + def dump_bytecode(self, bucket: Bucket) -> None: + # Write to a temporary file, then rename to the real name after + # writing. This avoids another process reading the file before + # it is fully written. + name = self._get_cache_filename(bucket) + f = tempfile.NamedTemporaryFile( + mode="wb", + dir=os.path.dirname(name), + prefix=os.path.basename(name), + suffix=".tmp", + delete=False, + ) + + def remove_silent() -> None: + try: + os.remove(f.name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + pass + + try: + with f: + bucket.write_bytecode(f) + except BaseException: + remove_silent() + raise + + try: + os.replace(f.name, name) + except OSError: + # Another process may have called clear(). On Windows, + # another program may be holding the file open. + remove_silent() + except BaseException: + remove_silent() + raise + + def clear(self) -> None: + # imported lazily here because google app-engine doesn't support + # write access on the file system and the function does not exist + # normally. + from os import remove + + files = fnmatch.filter(os.listdir(self.directory), self.pattern % ("*",)) + for filename in files: + try: + remove(os.path.join(self.directory, filename)) + except OSError: + pass + + +class MemcachedBytecodeCache(BytecodeCache): + """This class implements a bytecode cache that uses a memcache cache for + storing the information. It does not enforce a specific memcache library + (tummy's memcache or cmemcache) but will accept any class that provides + the minimal interface required. + + Libraries compatible with this class: + + - `cachelib `_ + - `python-memcached `_ + + (Unfortunately the django cache interface is not compatible because it + does not support storing binary data, only text. You can however pass + the underlying cache client to the bytecode cache which is available + as `django.core.cache.cache._client`.) + + The minimal interface for the client passed to the constructor is this: + + .. class:: MinimalClientInterface + + .. method:: set(key, value[, timeout]) + + Stores the bytecode in the cache. `value` is a string and + `timeout` the timeout of the key. If timeout is not provided + a default timeout or no timeout should be assumed, if it's + provided it's an integer with the number of seconds the cache + item should exist. + + .. method:: get(key) + + Returns the value for the cache key. If the item does not + exist in the cache the return value must be `None`. + + The other arguments to the constructor are the prefix for all keys that + is added before the actual cache key and the timeout for the bytecode in + the cache system. We recommend a high (or no) timeout. + + This bytecode cache does not support clearing of used items in the cache. + The clear method is a no-operation function. + + .. versionadded:: 2.7 + Added support for ignoring memcache errors through the + `ignore_memcache_errors` parameter. + """ + + def __init__( + self, + client: "_MemcachedClient", + prefix: str = "jinja2/bytecode/", + timeout: t.Optional[int] = None, + ignore_memcache_errors: bool = True, + ): + self.client = client + self.prefix = prefix + self.timeout = timeout + self.ignore_memcache_errors = ignore_memcache_errors + + def load_bytecode(self, bucket: Bucket) -> None: + try: + code = self.client.get(self.prefix + bucket.key) + except Exception: + if not self.ignore_memcache_errors: + raise + else: + bucket.bytecode_from_string(code) + + def dump_bytecode(self, bucket: Bucket) -> None: + key = self.prefix + bucket.key + value = bucket.bytecode_to_string() + + try: + if self.timeout is not None: + self.client.set(key, value, self.timeout) + else: + self.client.set(key, value) + except Exception: + if not self.ignore_memcache_errors: + raise diff --git a/venv/lib/python3.12/site-packages/jinja2/compiler.py b/venv/lib/python3.12/site-packages/jinja2/compiler.py new file mode 100644 index 0000000..2740717 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/compiler.py @@ -0,0 +1,1960 @@ +"""Compiles nodes from the parser into Python code.""" + +import typing as t +from contextlib import contextmanager +from functools import update_wrapper +from io import StringIO +from itertools import chain +from keyword import iskeyword as is_python_keyword + +from markupsafe import escape +from markupsafe import Markup + +from . import nodes +from .exceptions import TemplateAssertionError +from .idtracking import Symbols +from .idtracking import VAR_LOAD_ALIAS +from .idtracking import VAR_LOAD_PARAMETER +from .idtracking import VAR_LOAD_RESOLVE +from .idtracking import VAR_LOAD_UNDEFINED +from .nodes import EvalContext +from .optimizer import Optimizer +from .utils import _PassArg +from .utils import concat +from .visitor import NodeVisitor + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .environment import Environment + +F = t.TypeVar("F", bound=t.Callable[..., t.Any]) + +operators = { + "eq": "==", + "ne": "!=", + "gt": ">", + "gteq": ">=", + "lt": "<", + "lteq": "<=", + "in": "in", + "notin": "not in", +} + + +def optimizeconst(f: F) -> F: + def new_func( + self: "CodeGenerator", node: nodes.Expr, frame: "Frame", **kwargs: t.Any + ) -> t.Any: + # Only optimize if the frame is not volatile + if self.optimizer is not None and not frame.eval_ctx.volatile: + new_node = self.optimizer.visit(node, frame.eval_ctx) + + if new_node != node: + return self.visit(new_node, frame) + + return f(self, node, frame, **kwargs) + + return update_wrapper(t.cast(F, new_func), f) + + +def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_binops # type: ignore + ): + self.write(f"environment.call_binop(context, {op!r}, ") + self.visit(node.left, frame) + self.write(", ") + self.visit(node.right, frame) + else: + self.write("(") + self.visit(node.left, frame) + self.write(f" {op} ") + self.visit(node.right, frame) + + self.write(")") + + return visitor + + +def _make_unop( + op: str, +) -> t.Callable[["CodeGenerator", nodes.UnaryExpr, "Frame"], None]: + @optimizeconst + def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: + if ( + self.environment.sandboxed and op in self.environment.intercepted_unops # type: ignore + ): + self.write(f"environment.call_unop(context, {op!r}, ") + self.visit(node.node, frame) + else: + self.write("(" + op) + self.visit(node.node, frame) + + self.write(")") + + return visitor + + +def generate( + node: nodes.Template, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, +) -> t.Optional[str]: + """Generate the python source for a node tree.""" + if not isinstance(node, nodes.Template): + raise TypeError("Can't compile non template nodes") + + generator = environment.code_generator_class( + environment, name, filename, stream, defer_init, optimized + ) + generator.visit(node) + + if stream is None: + return generator.stream.getvalue() # type: ignore + + return None + + +def has_safe_repr(value: t.Any) -> bool: + """Does the node have a safe representation?""" + if value is None or value is NotImplemented or value is Ellipsis: + return True + + if type(value) in {bool, int, float, complex, range, str, Markup}: + return True + + if type(value) in {tuple, list, set, frozenset}: + return all(has_safe_repr(v) for v in value) + + if type(value) is dict: # noqa E721 + return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) + + return False + + +def find_undeclared( + nodes: t.Iterable[nodes.Node], names: t.Iterable[str] +) -> t.Set[str]: + """Check if the names passed are accessed undeclared. The return value + is a set of all the undeclared names from the sequence of names found. + """ + visitor = UndeclaredNameVisitor(names) + try: + for node in nodes: + visitor.visit(node) + except VisitorExit: + pass + return visitor.undeclared + + +class MacroRef: + def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None: + self.node = node + self.accesses_caller = False + self.accesses_kwargs = False + self.accesses_varargs = False + + +class Frame: + """Holds compile time information for us.""" + + def __init__( + self, + eval_ctx: EvalContext, + parent: t.Optional["Frame"] = None, + level: t.Optional[int] = None, + ) -> None: + self.eval_ctx = eval_ctx + + # the parent of this frame + self.parent = parent + + if parent is None: + self.symbols = Symbols(level=level) + + # in some dynamic inheritance situations the compiler needs to add + # write tests around output statements. + self.require_output_check = False + + # inside some tags we are using a buffer rather than yield statements. + # this for example affects {% filter %} or {% macro %}. If a frame + # is buffered this variable points to the name of the list used as + # buffer. + self.buffer: t.Optional[str] = None + + # the name of the block we're in, otherwise None. + self.block: t.Optional[str] = None + + else: + self.symbols = Symbols(parent.symbols, level=level) + self.require_output_check = parent.require_output_check + self.buffer = parent.buffer + self.block = parent.block + + # a toplevel frame is the root + soft frames such as if conditions. + self.toplevel = False + + # the root frame is basically just the outermost frame, so no if + # conditions. This information is used to optimize inheritance + # situations. + self.rootlevel = False + + # variables set inside of loops and blocks should not affect outer frames, + # but they still needs to be kept track of as part of the active context. + self.loop_frame = False + self.block_frame = False + + # track whether the frame is being used in an if-statement or conditional + # expression as it determines which errors should be raised during runtime + # or compile time. + self.soft_frame = False + + def copy(self) -> "Frame": + """Create a copy of the current one.""" + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.symbols = self.symbols.copy() + return rv + + def inner(self, isolated: bool = False) -> "Frame": + """Return an inner frame.""" + if isolated: + return Frame(self.eval_ctx, level=self.symbols.level + 1) + return Frame(self.eval_ctx, self) + + def soft(self) -> "Frame": + """Return a soft frame. A soft frame may not be modified as + standalone thing as it shares the resources with the frame it + was created of, but it's not a rootlevel frame any longer. + + This is only used to implement if-statements and conditional + expressions. + """ + rv = self.copy() + rv.rootlevel = False + rv.soft_frame = True + return rv + + __copy__ = copy + + +class VisitorExit(RuntimeError): + """Exception used by the `UndeclaredNameVisitor` to signal a stop.""" + + +class DependencyFinderVisitor(NodeVisitor): + """A visitor that collects filter and test calls.""" + + def __init__(self) -> None: + self.filters: t.Set[str] = set() + self.tests: t.Set[str] = set() + + def visit_Filter(self, node: nodes.Filter) -> None: + self.generic_visit(node) + self.filters.add(node.name) + + def visit_Test(self, node: nodes.Test) -> None: + self.generic_visit(node) + self.tests.add(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting at blocks.""" + + +class UndeclaredNameVisitor(NodeVisitor): + """A visitor that checks if a name is accessed without being + declared. This is different from the frame visitor as it will + not stop at closure frames. + """ + + def __init__(self, names: t.Iterable[str]) -> None: + self.names = set(names) + self.undeclared: t.Set[str] = set() + + def visit_Name(self, node: nodes.Name) -> None: + if node.ctx == "load" and node.name in self.names: + self.undeclared.add(node.name) + if self.undeclared == self.names: + raise VisitorExit() + else: + self.names.discard(node.name) + + def visit_Block(self, node: nodes.Block) -> None: + """Stop visiting a blocks.""" + + +class CompilerExit(Exception): + """Raised if the compiler encountered a situation where it just + doesn't make sense to further process the code. Any block that + raises such an exception is not further processed. + """ + + +class CodeGenerator(NodeVisitor): + def __init__( + self, + environment: "Environment", + name: t.Optional[str], + filename: t.Optional[str], + stream: t.Optional[t.TextIO] = None, + defer_init: bool = False, + optimized: bool = True, + ) -> None: + if stream is None: + stream = StringIO() + self.environment = environment + self.name = name + self.filename = filename + self.stream = stream + self.created_block_context = False + self.defer_init = defer_init + self.optimizer: t.Optional[Optimizer] = None + + if optimized: + self.optimizer = Optimizer(environment) + + # aliases for imports + self.import_aliases: t.Dict[str, str] = {} + + # a registry for all blocks. Because blocks are moved out + # into the global python scope they are registered here + self.blocks: t.Dict[str, nodes.Block] = {} + + # the number of extends statements so far + self.extends_so_far = 0 + + # some templates have a rootlevel extends. In this case we + # can safely assume that we're a child template and do some + # more optimizations. + self.has_known_extends = False + + # the current line number + self.code_lineno = 1 + + # registry of all filters and tests (global, not block local) + self.tests: t.Dict[str, str] = {} + self.filters: t.Dict[str, str] = {} + + # the debug information + self.debug_info: t.List[t.Tuple[int, int]] = [] + self._write_debug_info: t.Optional[int] = None + + # the number of new lines before the next write() + self._new_lines = 0 + + # the line number of the last written statement + self._last_line = 0 + + # true if nothing was written so far. + self._first_write = True + + # used by the `temporary_identifier` method to get new + # unique, temporary identifier + self._last_identifier = 0 + + # the current indentation + self._indentation = 0 + + # Tracks toplevel assignments + self._assign_stack: t.List[t.Set[str]] = [] + + # Tracks parameter definition blocks + self._param_def_block: t.List[t.Set[str]] = [] + + # Tracks the current context. + self._context_reference_stack = ["context"] + + @property + def optimized(self) -> bool: + return self.optimizer is not None + + # -- Various compilation helpers + + def fail(self, msg: str, lineno: int) -> "te.NoReturn": + """Fail with a :exc:`TemplateAssertionError`.""" + raise TemplateAssertionError(msg, lineno, self.name, self.filename) + + def temporary_identifier(self) -> str: + """Get a new unique identifier.""" + self._last_identifier += 1 + return f"t_{self._last_identifier}" + + def buffer(self, frame: Frame) -> None: + """Enable buffering for the frame from that point onwards.""" + frame.buffer = self.temporary_identifier() + self.writeline(f"{frame.buffer} = []") + + def return_buffer_contents( + self, frame: Frame, force_unescaped: bool = False + ) -> None: + """Return the buffer contents of the frame.""" + if not force_unescaped: + if frame.eval_ctx.volatile: + self.writeline("if context.eval_ctx.autoescape:") + self.indent() + self.writeline(f"return Markup(concat({frame.buffer}))") + self.outdent() + self.writeline("else:") + self.indent() + self.writeline(f"return concat({frame.buffer})") + self.outdent() + return + elif frame.eval_ctx.autoescape: + self.writeline(f"return Markup(concat({frame.buffer}))") + return + self.writeline(f"return concat({frame.buffer})") + + def indent(self) -> None: + """Indent by one.""" + self._indentation += 1 + + def outdent(self, step: int = 1) -> None: + """Outdent by step.""" + self._indentation -= step + + def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None: + """Yield or write into the frame buffer.""" + if frame.buffer is None: + self.writeline("yield ", node) + else: + self.writeline(f"{frame.buffer}.append(", node) + + def end_write(self, frame: Frame) -> None: + """End the writing process started by `start_write`.""" + if frame.buffer is not None: + self.write(")") + + def simple_write( + self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None + ) -> None: + """Simple shortcut for start_write + write + end_write.""" + self.start_write(frame, node) + self.write(s) + self.end_write(frame) + + def blockvisit(self, nodes: t.Iterable[nodes.Node], frame: Frame) -> None: + """Visit a list of nodes as block in a frame. If the current frame + is no buffer a dummy ``if 0: yield None`` is written automatically. + """ + try: + self.writeline("pass") + for node in nodes: + self.visit(node, frame) + except CompilerExit: + pass + + def write(self, x: str) -> None: + """Write a string into the output stream.""" + if self._new_lines: + if not self._first_write: + self.stream.write("\n" * self._new_lines) + self.code_lineno += self._new_lines + if self._write_debug_info is not None: + self.debug_info.append((self._write_debug_info, self.code_lineno)) + self._write_debug_info = None + self._first_write = False + self.stream.write(" " * self._indentation) + self._new_lines = 0 + self.stream.write(x) + + def writeline( + self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0 + ) -> None: + """Combination of newline and write.""" + self.newline(node, extra) + self.write(x) + + def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None: + """Add one or more newlines before the next write.""" + self._new_lines = max(self._new_lines, 1 + extra) + if node is not None and node.lineno != self._last_line: + self._write_debug_info = node.lineno + self._last_line = node.lineno + + def signature( + self, + node: t.Union[nodes.Call, nodes.Filter, nodes.Test], + frame: Frame, + extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + ) -> None: + """Writes a function call to the stream for the current node. + A leading comma is added automatically. The extra keyword + arguments may not include python keywords otherwise a syntax + error could occur. The extra keyword arguments should be given + as python dict. + """ + # if any of the given keyword arguments is a python keyword + # we have to make sure that no invalid call is created. + kwarg_workaround = any( + is_python_keyword(t.cast(str, k)) + for k in chain((x.key for x in node.kwargs), extra_kwargs or ()) + ) + + for arg in node.args: + self.write(", ") + self.visit(arg, frame) + + if not kwarg_workaround: + for kwarg in node.kwargs: + self.write(", ") + self.visit(kwarg, frame) + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f", {key}={value}") + if node.dyn_args: + self.write(", *") + self.visit(node.dyn_args, frame) + + if kwarg_workaround: + if node.dyn_kwargs is not None: + self.write(", **dict({") + else: + self.write(", **{") + for kwarg in node.kwargs: + self.write(f"{kwarg.key!r}: ") + self.visit(kwarg.value, frame) + self.write(", ") + if extra_kwargs is not None: + for key, value in extra_kwargs.items(): + self.write(f"{key!r}: {value}, ") + if node.dyn_kwargs is not None: + self.write("}, **") + self.visit(node.dyn_kwargs, frame) + self.write(")") + else: + self.write("}") + + elif node.dyn_kwargs is not None: + self.write(", **") + self.visit(node.dyn_kwargs, frame) + + def pull_dependencies(self, nodes: t.Iterable[nodes.Node]) -> None: + """Find all filter and test names used in the template and + assign them to variables in the compiled namespace. Checking + that the names are registered with the environment is done when + compiling the Filter and Test nodes. If the node is in an If or + CondExpr node, the check is done at runtime instead. + + .. versionchanged:: 3.0 + Filters and tests in If and CondExpr nodes are checked at + runtime instead of compile time. + """ + visitor = DependencyFinderVisitor() + + for node in nodes: + visitor.visit(node) + + for id_map, names, dependency in ( + (self.filters, visitor.filters, "filters"), + ( + self.tests, + visitor.tests, + "tests", + ), + ): + for name in sorted(names): + if name not in id_map: + id_map[name] = self.temporary_identifier() + + # add check during runtime that dependencies used inside of executed + # blocks are defined, as this step may be skipped during compile time + self.writeline("try:") + self.indent() + self.writeline(f"{id_map[name]} = environment.{dependency}[{name!r}]") + self.outdent() + self.writeline("except KeyError:") + self.indent() + self.writeline("@internalcode") + self.writeline(f"def {id_map[name]}(*unused):") + self.indent() + self.writeline( + f'raise TemplateRuntimeError("No {dependency[:-1]}' + f' named {name!r} found.")' + ) + self.outdent() + self.outdent() + + def enter_frame(self, frame: Frame) -> None: + undefs = [] + for target, (action, param) in frame.symbols.loads.items(): + if action == VAR_LOAD_PARAMETER: + pass + elif action == VAR_LOAD_RESOLVE: + self.writeline(f"{target} = {self.get_resolve_func()}({param!r})") + elif action == VAR_LOAD_ALIAS: + self.writeline(f"{target} = {param}") + elif action == VAR_LOAD_UNDEFINED: + undefs.append(target) + else: + raise NotImplementedError("unknown load instruction") + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def leave_frame(self, frame: Frame, with_python_scope: bool = False) -> None: + if not with_python_scope: + undefs = [] + for target in frame.symbols.loads: + undefs.append(target) + if undefs: + self.writeline(f"{' = '.join(undefs)} = missing") + + def choose_async(self, async_value: str = "async ", sync_value: str = "") -> str: + return async_value if self.environment.is_async else sync_value + + def func(self, name: str) -> str: + return f"{self.choose_async()}def {name}" + + def macro_body( + self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame + ) -> t.Tuple[Frame, MacroRef]: + """Dump the function def of a macro or call block.""" + frame = frame.inner() + frame.symbols.analyze_node(node) + macro_ref = MacroRef(node) + + explicit_caller = None + skip_special_params = set() + args = [] + + for idx, arg in enumerate(node.args): + if arg.name == "caller": + explicit_caller = idx + if arg.name in ("kwargs", "varargs"): + skip_special_params.add(arg.name) + args.append(frame.symbols.ref(arg.name)) + + undeclared = find_undeclared(node.body, ("caller", "kwargs", "varargs")) + + if "caller" in undeclared: + # In older Jinja versions there was a bug that allowed caller + # to retain the special behavior even if it was mentioned in + # the argument list. However thankfully this was only really + # working if it was the last argument. So we are explicitly + # checking this now and error out if it is anywhere else in + # the argument list. + if explicit_caller is not None: + try: + node.defaults[explicit_caller - len(node.args)] + except IndexError: + self.fail( + "When defining macros or call blocks the " + 'special "caller" argument must be omitted ' + "or be given a default.", + node.lineno, + ) + else: + args.append(frame.symbols.declare_parameter("caller")) + macro_ref.accesses_caller = True + if "kwargs" in undeclared and "kwargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("kwargs")) + macro_ref.accesses_kwargs = True + if "varargs" in undeclared and "varargs" not in skip_special_params: + args.append(frame.symbols.declare_parameter("varargs")) + macro_ref.accesses_varargs = True + + # macros are delayed, they never require output checks + frame.require_output_check = False + frame.symbols.analyze_node(node) + self.writeline(f"{self.func('macro')}({', '.join(args)}):", node) + self.indent() + + self.buffer(frame) + self.enter_frame(frame) + + self.push_parameter_definitions(frame) + for idx, arg in enumerate(node.args): + ref = frame.symbols.ref(arg.name) + self.writeline(f"if {ref} is missing:") + self.indent() + try: + default = node.defaults[idx - len(node.args)] + except IndexError: + self.writeline( + f'{ref} = undefined("parameter {arg.name!r} was not provided",' + f" name={arg.name!r})" + ) + else: + self.writeline(f"{ref} = ") + self.visit(default, frame) + self.mark_parameter_stored(ref) + self.outdent() + self.pop_parameter_definitions() + + self.blockvisit(node.body, frame) + self.return_buffer_contents(frame, force_unescaped=True) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + return frame, macro_ref + + def macro_def(self, macro_ref: MacroRef, frame: Frame) -> None: + """Dump the macro definition for the def created by macro_body.""" + arg_tuple = ", ".join(repr(x.name) for x in macro_ref.node.args) + name = getattr(macro_ref.node, "name", None) + if len(macro_ref.node.args) == 1: + arg_tuple += "," + self.write( + f"Macro(environment, macro, {name!r}, ({arg_tuple})," + f" {macro_ref.accesses_kwargs!r}, {macro_ref.accesses_varargs!r}," + f" {macro_ref.accesses_caller!r}, context.eval_ctx.autoescape)" + ) + + def position(self, node: nodes.Node) -> str: + """Return a human readable position for the node.""" + rv = f"line {node.lineno}" + if self.name is not None: + rv = f"{rv} in {self.name!r}" + return rv + + def dump_local_context(self, frame: Frame) -> str: + items_kv = ", ".join( + f"{name!r}: {target}" + for name, target in frame.symbols.dump_stores().items() + ) + return f"{{{items_kv}}}" + + def write_commons(self) -> None: + """Writes a common preamble that is used by root and block functions. + Primarily this sets up common local helpers and enforces a generator + through a dead branch. + """ + self.writeline("resolve = context.resolve_or_missing") + self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") + # always use the standard Undefined class for the implicit else of + # conditional expressions + self.writeline("cond_expr_undefined = Undefined") + self.writeline("if 0: yield None") + + def push_parameter_definitions(self, frame: Frame) -> None: + """Pushes all parameter targets from the given frame into a local + stack that permits tracking of yet to be assigned parameters. In + particular this enables the optimization from `visit_Name` to skip + undefined expressions for parameters in macros as macros can reference + otherwise unbound parameters. + """ + self._param_def_block.append(frame.symbols.dump_param_targets()) + + def pop_parameter_definitions(self) -> None: + """Pops the current parameter definitions set.""" + self._param_def_block.pop() + + def mark_parameter_stored(self, target: str) -> None: + """Marks a parameter in the current parameter definitions as stored. + This will skip the enforced undefined checks. + """ + if self._param_def_block: + self._param_def_block[-1].discard(target) + + def push_context_reference(self, target: str) -> None: + self._context_reference_stack.append(target) + + def pop_context_reference(self) -> None: + self._context_reference_stack.pop() + + def get_context_ref(self) -> str: + return self._context_reference_stack[-1] + + def get_resolve_func(self) -> str: + target = self._context_reference_stack[-1] + if target == "context": + return "resolve" + return f"{target}.resolve" + + def derive_context(self, frame: Frame) -> str: + return f"{self.get_context_ref()}.derived({self.dump_local_context(frame)})" + + def parameter_is_undeclared(self, target: str) -> bool: + """Checks if a given target is an undeclared parameter.""" + if not self._param_def_block: + return False + return target in self._param_def_block[-1] + + def push_assign_tracking(self) -> None: + """Pushes a new layer for assignment tracking.""" + self._assign_stack.append(set()) + + def pop_assign_tracking(self, frame: Frame) -> None: + """Pops the topmost level for assignment tracking and updates the + context variables if necessary. + """ + vars = self._assign_stack.pop() + if ( + not frame.block_frame + and not frame.loop_frame + and not frame.toplevel + or not vars + ): + return + public_names = [x for x in vars if x[:1] != "_"] + if len(vars) == 1: + name = next(iter(vars)) + ref = frame.symbols.ref(name) + if frame.loop_frame: + self.writeline(f"_loop_vars[{name!r}] = {ref}") + return + if frame.block_frame: + self.writeline(f"_block_vars[{name!r}] = {ref}") + return + self.writeline(f"context.vars[{name!r}] = {ref}") + else: + if frame.loop_frame: + self.writeline("_loop_vars.update({") + elif frame.block_frame: + self.writeline("_block_vars.update({") + else: + self.writeline("context.vars.update({") + for idx, name in enumerate(vars): + if idx: + self.write(", ") + ref = frame.symbols.ref(name) + self.write(f"{name!r}: {ref}") + self.write("})") + if not frame.block_frame and not frame.loop_frame and public_names: + if len(public_names) == 1: + self.writeline(f"context.exported_vars.add({public_names[0]!r})") + else: + names_str = ", ".join(map(repr, public_names)) + self.writeline(f"context.exported_vars.update(({names_str}))") + + # -- Statement Visitors + + def visit_Template( + self, node: nodes.Template, frame: t.Optional[Frame] = None + ) -> None: + assert frame is None, "no root frame allowed" + eval_ctx = EvalContext(self.environment, self.name) + + from .runtime import async_exported + from .runtime import exported + + if self.environment.is_async: + exported_names = sorted(exported + async_exported) + else: + exported_names = sorted(exported) + + self.writeline("from jinja2.runtime import " + ", ".join(exported_names)) + + # if we want a deferred initialization we cannot move the + # environment into a local name + envenv = "" if self.defer_init else ", environment=environment" + + # do we have an extends tag at all? If not, we can save some + # overhead by just not processing any inheritance code. + have_extends = node.find(nodes.Extends) is not None + + # find all blocks + for block in node.find_all(nodes.Block): + if block.name in self.blocks: + self.fail(f"block {block.name!r} defined twice", block.lineno) + self.blocks[block.name] = block + + # find all imports and import them + for import_ in node.find_all(nodes.ImportedName): + if import_.importname not in self.import_aliases: + imp = import_.importname + self.import_aliases[imp] = alias = self.temporary_identifier() + if "." in imp: + module, obj = imp.rsplit(".", 1) + self.writeline(f"from {module} import {obj} as {alias}") + else: + self.writeline(f"import {imp} as {alias}") + + # add the load name + self.writeline(f"name = {self.name!r}") + + # generate the root render function. + self.writeline( + f"{self.func('root')}(context, missing=missing{envenv}):", extra=1 + ) + self.indent() + self.write_commons() + + # process the root + frame = Frame(eval_ctx) + if "self" in find_undeclared(node.body, ("self",)): + ref = frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + frame.symbols.analyze_node(node) + frame.toplevel = frame.rootlevel = True + frame.require_output_check = have_extends and not self.has_known_extends + if have_extends: + self.writeline("parent_template = None") + self.enter_frame(frame) + self.pull_dependencies(node.body) + self.blockvisit(node.body, frame) + self.leave_frame(frame, with_python_scope=True) + self.outdent() + + # make sure that the parent root is called. + if have_extends: + if not self.has_known_extends: + self.indent() + self.writeline("if parent_template is not None:") + self.indent() + if not self.environment.is_async: + self.writeline("yield from parent_template.root_render_func(context)") + else: + self.writeline( + "async for event in parent_template.root_render_func(context):" + ) + self.indent() + self.writeline("yield event") + self.outdent() + self.outdent(1 + (not self.has_known_extends)) + + # at this point we now have the blocks collected and can visit them too. + for name, block in self.blocks.items(): + self.writeline( + f"{self.func('block_' + name)}(context, missing=missing{envenv}):", + block, + 1, + ) + self.indent() + self.write_commons() + # It's important that we do not make this frame a child of the + # toplevel template. This would cause a variety of + # interesting issues with identifier tracking. + block_frame = Frame(eval_ctx) + block_frame.block_frame = True + undeclared = find_undeclared(block.body, ("self", "super")) + if "self" in undeclared: + ref = block_frame.symbols.declare_parameter("self") + self.writeline(f"{ref} = TemplateReference(context)") + if "super" in undeclared: + ref = block_frame.symbols.declare_parameter("super") + self.writeline(f"{ref} = context.super({name!r}, block_{name})") + block_frame.symbols.analyze_node(block) + block_frame.block = name + self.writeline("_block_vars = {}") + self.enter_frame(block_frame) + self.pull_dependencies(block.body) + self.blockvisit(block.body, block_frame) + self.leave_frame(block_frame, with_python_scope=True) + self.outdent() + + blocks_kv_str = ", ".join(f"{x!r}: block_{x}" for x in self.blocks) + self.writeline(f"blocks = {{{blocks_kv_str}}}", extra=1) + debug_kv_str = "&".join(f"{k}={v}" for k, v in self.debug_info) + self.writeline(f"debug_info = {debug_kv_str!r}") + + def visit_Block(self, node: nodes.Block, frame: Frame) -> None: + """Call a block and register it for the template.""" + level = 0 + if frame.toplevel: + # if we know that we are a child template, there is no need to + # check if we are one + if self.has_known_extends: + return + if self.extends_so_far > 0: + self.writeline("if parent_template is None:") + self.indent() + level += 1 + + if node.scoped: + context = self.derive_context(frame) + else: + context = self.get_context_ref() + + if node.required: + self.writeline(f"if len(context.blocks[{node.name!r}]) <= 1:", node) + self.indent() + self.writeline( + f'raise TemplateRuntimeError("Required block {node.name!r} not found")', + node, + ) + self.outdent() + + if not self.environment.is_async and frame.buffer is None: + self.writeline( + f"yield from context.blocks[{node.name!r}][0]({context})", node + ) + else: + self.writeline( + f"{self.choose_async()}for event in" + f" context.blocks[{node.name!r}][0]({context}):", + node, + ) + self.indent() + self.simple_write("event", frame) + self.outdent() + + self.outdent(level) + + def visit_Extends(self, node: nodes.Extends, frame: Frame) -> None: + """Calls the extender.""" + if not frame.toplevel: + self.fail("cannot use extend from a non top-level scope", node.lineno) + + # if the number of extends statements in general is zero so + # far, we don't have to add a check if something extended + # the template before this one. + if self.extends_so_far > 0: + # if we have a known extends we just add a template runtime + # error into the generated code. We could catch that at compile + # time too, but i welcome it not to confuse users by throwing the + # same error at different times just "because we can". + if not self.has_known_extends: + self.writeline("if parent_template is not None:") + self.indent() + self.writeline('raise TemplateRuntimeError("extended multiple times")') + + # if we have a known extends already we don't need that code here + # as we know that the template execution will end here. + if self.has_known_extends: + raise CompilerExit() + else: + self.outdent() + + self.writeline("parent_template = environment.get_template(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + self.writeline("for name, parent_block in parent_template.blocks.items():") + self.indent() + self.writeline("context.blocks.setdefault(name, []).append(parent_block)") + self.outdent() + + # if this extends statement was in the root level we can take + # advantage of that information and simplify the generated code + # in the top level from this point onwards + if frame.rootlevel: + self.has_known_extends = True + + # and now we have one more + self.extends_so_far += 1 + + def visit_Include(self, node: nodes.Include, frame: Frame) -> None: + """Handles includes.""" + if node.ignore_missing: + self.writeline("try:") + self.indent() + + func_name = "get_or_select_template" + if isinstance(node.template, nodes.Const): + if isinstance(node.template.value, str): + func_name = "get_template" + elif isinstance(node.template.value, (tuple, list)): + func_name = "select_template" + elif isinstance(node.template, (nodes.Tuple, nodes.List)): + func_name = "select_template" + + self.writeline(f"template = environment.{func_name}(", node) + self.visit(node.template, frame) + self.write(f", {self.name!r})") + if node.ignore_missing: + self.outdent() + self.writeline("except TemplateNotFound:") + self.indent() + self.writeline("pass") + self.outdent() + self.writeline("else:") + self.indent() + + skip_event_yield = False + if node.with_context: + self.writeline( + f"{self.choose_async()}for event in template.root_render_func(" + "template.new_context(context.get_all(), True," + f" {self.dump_local_context(frame)})):" + ) + elif self.environment.is_async: + self.writeline( + "for event in (await template._get_default_module_async())" + "._body_stream:" + ) + else: + self.writeline("yield from template._get_default_module()._body_stream") + skip_event_yield = True + + if not skip_event_yield: + self.indent() + self.simple_write("event", frame) + self.outdent() + + if node.ignore_missing: + self.outdent() + + def _import_common( + self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame + ) -> None: + self.write(f"{self.choose_async('await ')}environment.get_template(") + self.visit(node.template, frame) + self.write(f", {self.name!r}).") + + if node.with_context: + f_name = f"make_module{self.choose_async('_async')}" + self.write( + f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" + ) + else: + self.write(f"_get_default_module{self.choose_async('_async')}(context)") + + def visit_Import(self, node: nodes.Import, frame: Frame) -> None: + """Visit regular imports.""" + self.writeline(f"{frame.symbols.ref(node.target)} = ", node) + if frame.toplevel: + self.write(f"context.vars[{node.target!r}] = ") + + self._import_common(node, frame) + + if frame.toplevel and not node.target.startswith("_"): + self.writeline(f"context.exported_vars.discard({node.target!r})") + + def visit_FromImport(self, node: nodes.FromImport, frame: Frame) -> None: + """Visit named imports.""" + self.newline(node) + self.write("included_template = ") + self._import_common(node, frame) + var_names = [] + discarded_names = [] + for name in node.names: + if isinstance(name, tuple): + name, alias = name + else: + alias = name + self.writeline( + f"{frame.symbols.ref(alias)} =" + f" getattr(included_template, {name!r}, missing)" + ) + self.writeline(f"if {frame.symbols.ref(alias)} is missing:") + self.indent() + message = ( + "the template {included_template.__name__!r}" + f" (imported on {self.position(node)})" + f" does not export the requested name {name!r}" + ) + self.writeline( + f"{frame.symbols.ref(alias)} = undefined(f{message!r}, name={name!r})" + ) + self.outdent() + if frame.toplevel: + var_names.append(alias) + if not alias.startswith("_"): + discarded_names.append(alias) + + if var_names: + if len(var_names) == 1: + name = var_names[0] + self.writeline(f"context.vars[{name!r}] = {frame.symbols.ref(name)}") + else: + names_kv = ", ".join( + f"{name!r}: {frame.symbols.ref(name)}" for name in var_names + ) + self.writeline(f"context.vars.update({{{names_kv}}})") + if discarded_names: + if len(discarded_names) == 1: + self.writeline(f"context.exported_vars.discard({discarded_names[0]!r})") + else: + names_str = ", ".join(map(repr, discarded_names)) + self.writeline( + f"context.exported_vars.difference_update(({names_str}))" + ) + + def visit_For(self, node: nodes.For, frame: Frame) -> None: + loop_frame = frame.inner() + loop_frame.loop_frame = True + test_frame = frame.inner() + else_frame = frame.inner() + + # try to figure out if we have an extended loop. An extended loop + # is necessary if the loop is in recursive mode if the special loop + # variable is accessed in the body if the body is a scoped block. + extended_loop = ( + node.recursive + or "loop" + in find_undeclared(node.iter_child_nodes(only=("body",)), ("loop",)) + or any(block.scoped for block in node.find_all(nodes.Block)) + ) + + loop_ref = None + if extended_loop: + loop_ref = loop_frame.symbols.declare_parameter("loop") + + loop_frame.symbols.analyze_node(node, for_branch="body") + if node.else_: + else_frame.symbols.analyze_node(node, for_branch="else") + + if node.test: + loop_filter_func = self.temporary_identifier() + test_frame.symbols.analyze_node(node, for_branch="test") + self.writeline(f"{self.func(loop_filter_func)}(fiter):", node.test) + self.indent() + self.enter_frame(test_frame) + self.writeline(self.choose_async("async for ", "for ")) + self.visit(node.target, loop_frame) + self.write(" in ") + self.write(self.choose_async("auto_aiter(fiter)", "fiter")) + self.write(":") + self.indent() + self.writeline("if ", node.test) + self.visit(node.test, test_frame) + self.write(":") + self.indent() + self.writeline("yield ") + self.visit(node.target, loop_frame) + self.outdent(3) + self.leave_frame(test_frame, with_python_scope=True) + + # if we don't have an recursive loop we have to find the shadowed + # variables at that point. Because loops can be nested but the loop + # variable is a special one we have to enforce aliasing for it. + if node.recursive: + self.writeline( + f"{self.func('loop')}(reciter, loop_render_func, depth=0):", node + ) + self.indent() + self.buffer(loop_frame) + + # Use the same buffer for the else frame + else_frame.buffer = loop_frame.buffer + + # make sure the loop variable is a special one and raise a template + # assertion error if a loop tries to write to loop + if extended_loop: + self.writeline(f"{loop_ref} = missing") + + for name in node.find_all(nodes.Name): + if name.ctx == "store" and name.name == "loop": + self.fail( + "Can't assign to special loop variable in for-loop target", + name.lineno, + ) + + if node.else_: + iteration_indicator = self.temporary_identifier() + self.writeline(f"{iteration_indicator} = 1") + + self.writeline(self.choose_async("async for ", "for "), node) + self.visit(node.target, loop_frame) + if extended_loop: + self.write(f", {loop_ref} in {self.choose_async('Async')}LoopContext(") + else: + self.write(" in ") + + if node.test: + self.write(f"{loop_filter_func}(") + if node.recursive: + self.write("reciter") + else: + if self.environment.is_async and not extended_loop: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async and not extended_loop: + self.write(")") + if node.test: + self.write(")") + + if node.recursive: + self.write(", undefined, loop_render_func, depth):") + else: + self.write(", undefined):" if extended_loop else ":") + + self.indent() + self.enter_frame(loop_frame) + + self.writeline("_loop_vars = {}") + self.blockvisit(node.body, loop_frame) + if node.else_: + self.writeline(f"{iteration_indicator} = 0") + self.outdent() + self.leave_frame( + loop_frame, with_python_scope=node.recursive and not node.else_ + ) + + if node.else_: + self.writeline(f"if {iteration_indicator}:") + self.indent() + self.enter_frame(else_frame) + self.blockvisit(node.else_, else_frame) + self.leave_frame(else_frame) + self.outdent() + + # if the node was recursive we have to return the buffer contents + # and start the iteration code + if node.recursive: + self.return_buffer_contents(loop_frame) + self.outdent() + self.start_write(frame, node) + self.write(f"{self.choose_async('await ')}loop(") + if self.environment.is_async: + self.write("auto_aiter(") + self.visit(node.iter, frame) + if self.environment.is_async: + self.write(")") + self.write(", loop)") + self.end_write(frame) + + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + + def visit_If(self, node: nodes.If, frame: Frame) -> None: + if_frame = frame.soft() + self.writeline("if ", node) + self.visit(node.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(node.body, if_frame) + self.outdent() + for elif_ in node.elif_: + self.writeline("elif ", elif_) + self.visit(elif_.test, if_frame) + self.write(":") + self.indent() + self.blockvisit(elif_.body, if_frame) + self.outdent() + if node.else_: + self.writeline("else:") + self.indent() + self.blockvisit(node.else_, if_frame) + self.outdent() + + def visit_Macro(self, node: nodes.Macro, frame: Frame) -> None: + macro_frame, macro_ref = self.macro_body(node, frame) + self.newline() + if frame.toplevel: + if not node.name.startswith("_"): + self.write(f"context.exported_vars.add({node.name!r})") + self.writeline(f"context.vars[{node.name!r}] = ") + self.write(f"{frame.symbols.ref(node.name)} = ") + self.macro_def(macro_ref, macro_frame) + + def visit_CallBlock(self, node: nodes.CallBlock, frame: Frame) -> None: + call_frame, macro_ref = self.macro_body(node, frame) + self.writeline("caller = ") + self.macro_def(macro_ref, call_frame) + self.start_write(frame, node) + self.visit_Call(node.call, frame, forward_caller=True) + self.end_write(frame) + + def visit_FilterBlock(self, node: nodes.FilterBlock, frame: Frame) -> None: + filter_frame = frame.inner() + filter_frame.symbols.analyze_node(node) + self.enter_frame(filter_frame) + self.buffer(filter_frame) + self.blockvisit(node.body, filter_frame) + self.start_write(frame, node) + self.visit_Filter(node.filter, filter_frame) + self.end_write(frame) + self.leave_frame(filter_frame) + + def visit_With(self, node: nodes.With, frame: Frame) -> None: + with_frame = frame.inner() + with_frame.symbols.analyze_node(node) + self.enter_frame(with_frame) + for target, expr in zip(node.targets, node.values): + self.newline() + self.visit(target, with_frame) + self.write(" = ") + self.visit(expr, frame) + self.blockvisit(node.body, with_frame) + self.leave_frame(with_frame) + + def visit_ExprStmt(self, node: nodes.ExprStmt, frame: Frame) -> None: + self.newline(node) + self.visit(node.node, frame) + + class _FinalizeInfo(t.NamedTuple): + const: t.Optional[t.Callable[..., str]] + src: t.Optional[str] + + @staticmethod + def _default_finalize(value: t.Any) -> t.Any: + """The default finalize function if the environment isn't + configured with one. Or, if the environment has one, this is + called on that function's output for constants. + """ + return str(value) + + _finalize: t.Optional[_FinalizeInfo] = None + + def _make_finalize(self) -> _FinalizeInfo: + """Build the finalize function to be used on constants and at + runtime. Cached so it's only created once for all output nodes. + + Returns a ``namedtuple`` with the following attributes: + + ``const`` + A function to finalize constant data at compile time. + + ``src`` + Source code to output around nodes to be evaluated at + runtime. + """ + if self._finalize is not None: + return self._finalize + + finalize: t.Optional[t.Callable[..., t.Any]] + finalize = default = self._default_finalize + src = None + + if self.environment.finalize: + src = "environment.finalize(" + env_finalize = self.environment.finalize + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(env_finalize) # type: ignore + ) + finalize = None + + if pass_arg is None: + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(value)) + + else: + src = f"{src}{pass_arg}, " + + if pass_arg == "environment": + + def finalize(value: t.Any) -> t.Any: # noqa: F811 + return default(env_finalize(self.environment, value)) + + self._finalize = self._FinalizeInfo(finalize, src) + return self._finalize + + def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: + """Given a group of constant values converted from ``Output`` + child nodes, produce a string to write to the template module + source. + """ + return repr(concat(group)) + + def _output_child_to_const( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> str: + """Try to optimize a child of an ``Output`` node by trying to + convert it to constant, finalized data at compile time. + + If :exc:`Impossible` is raised, the node is not constant and + will be evaluated at runtime. Any other exception will also be + evaluated at runtime for easier debugging. + """ + const = node.as_const(frame.eval_ctx) + + if frame.eval_ctx.autoescape: + const = escape(const) + + # Template data doesn't go through finalize. + if isinstance(node, nodes.TemplateData): + return str(const) + + return finalize.const(const) # type: ignore + + def _output_child_pre( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code before visiting a child of an + ``Output`` node. + """ + if frame.eval_ctx.volatile: + self.write("(escape if context.eval_ctx.autoescape else str)(") + elif frame.eval_ctx.autoescape: + self.write("escape(") + else: + self.write("str(") + + if finalize.src is not None: + self.write(finalize.src) + + def _output_child_post( + self, node: nodes.Expr, frame: Frame, finalize: _FinalizeInfo + ) -> None: + """Output extra source code after visiting a child of an + ``Output`` node. + """ + self.write(")") + + if finalize.src is not None: + self.write(")") + + def visit_Output(self, node: nodes.Output, frame: Frame) -> None: + # If an extends is active, don't render outside a block. + if frame.require_output_check: + # A top-level extends is known to exist at compile time. + if self.has_known_extends: + return + + self.writeline("if parent_template is None:") + self.indent() + + finalize = self._make_finalize() + body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = [] + + # Evaluate constants at compile time if possible. Each item in + # body will be either a list of static data or a node to be + # evaluated at runtime. + for child in node.nodes: + try: + if not ( + # If the finalize function requires runtime context, + # constants can't be evaluated at compile time. + finalize.const + # Unless it's basic template data that won't be + # finalized anyway. + or isinstance(child, nodes.TemplateData) + ): + raise nodes.Impossible() + + const = self._output_child_to_const(child, frame, finalize) + except (nodes.Impossible, Exception): + # The node was not constant and needs to be evaluated at + # runtime. Or another error was raised, which is easier + # to debug at runtime. + body.append(child) + continue + + if body and isinstance(body[-1], list): + body[-1].append(const) + else: + body.append([const]) + + if frame.buffer is not None: + if len(body) == 1: + self.writeline(f"{frame.buffer}.append(") + else: + self.writeline(f"{frame.buffer}.extend((") + + self.indent() + + for item in body: + if isinstance(item, list): + # A group of constant data to join and output. + val = self._output_const_repr(item) + + if frame.buffer is None: + self.writeline("yield " + val) + else: + self.writeline(val + ",") + else: + if frame.buffer is None: + self.writeline("yield ", item) + else: + self.newline(item) + + # A node to be evaluated at runtime. + self._output_child_pre(item, frame, finalize) + self.visit(item, frame) + self._output_child_post(item, frame, finalize) + + if frame.buffer is not None: + self.write(",") + + if frame.buffer is not None: + self.outdent() + self.writeline(")" if len(body) == 1 else "))") + + if frame.require_output_check: + self.outdent() + + def visit_Assign(self, node: nodes.Assign, frame: Frame) -> None: + self.push_assign_tracking() + self.newline(node) + self.visit(node.target, frame) + self.write(" = ") + self.visit(node.node, frame) + self.pop_assign_tracking(frame) + + def visit_AssignBlock(self, node: nodes.AssignBlock, frame: Frame) -> None: + self.push_assign_tracking() + block_frame = frame.inner() + # This is a special case. Since a set block always captures we + # will disable output checks. This way one can use set blocks + # toplevel even in extended templates. + block_frame.require_output_check = False + block_frame.symbols.analyze_node(node) + self.enter_frame(block_frame) + self.buffer(block_frame) + self.blockvisit(node.body, block_frame) + self.newline(node) + self.visit(node.target, frame) + self.write(" = (Markup if context.eval_ctx.autoescape else identity)(") + if node.filter is not None: + self.visit_Filter(node.filter, block_frame) + else: + self.write(f"concat({block_frame.buffer})") + self.write(")") + self.pop_assign_tracking(frame) + self.leave_frame(block_frame) + + # -- Expression Visitors + + def visit_Name(self, node: nodes.Name, frame: Frame) -> None: + if node.ctx == "store" and ( + frame.toplevel or frame.loop_frame or frame.block_frame + ): + if self._assign_stack: + self._assign_stack[-1].add(node.name) + ref = frame.symbols.ref(node.name) + + # If we are looking up a variable we might have to deal with the + # case where it's undefined. We can skip that case if the load + # instruction indicates a parameter which are always defined. + if node.ctx == "load": + load = frame.symbols.find_load(ref) + if not ( + load is not None + and load[0] == VAR_LOAD_PARAMETER + and not self.parameter_is_undeclared(ref) + ): + self.write( + f"(undefined(name={node.name!r}) if {ref} is missing else {ref})" + ) + return + + self.write(ref) + + def visit_NSRef(self, node: nodes.NSRef, frame: Frame) -> None: + # NSRefs can only be used to store values; since they use the normal + # `foo.bar` notation they will be parsed as a normal attribute access + # when used anywhere but in a `set` context + ref = frame.symbols.ref(node.name) + self.writeline(f"if not isinstance({ref}, Namespace):") + self.indent() + self.writeline( + "raise TemplateRuntimeError" + '("cannot assign attribute on non-namespace object")' + ) + self.outdent() + self.writeline(f"{ref}[{node.attr!r}]") + + def visit_Const(self, node: nodes.Const, frame: Frame) -> None: + val = node.as_const(frame.eval_ctx) + if isinstance(val, float): + self.write(str(val)) + else: + self.write(repr(val)) + + def visit_TemplateData(self, node: nodes.TemplateData, frame: Frame) -> None: + try: + self.write(repr(node.as_const(frame.eval_ctx))) + except nodes.Impossible: + self.write( + f"(Markup if context.eval_ctx.autoescape else identity)({node.data!r})" + ) + + def visit_Tuple(self, node: nodes.Tuple, frame: Frame) -> None: + self.write("(") + idx = -1 + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write(",)" if idx == 0 else ")") + + def visit_List(self, node: nodes.List, frame: Frame) -> None: + self.write("[") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item, frame) + self.write("]") + + def visit_Dict(self, node: nodes.Dict, frame: Frame) -> None: + self.write("{") + for idx, item in enumerate(node.items): + if idx: + self.write(", ") + self.visit(item.key, frame) + self.write(": ") + self.visit(item.value, frame) + self.write("}") + + visit_Add = _make_binop("+") + visit_Sub = _make_binop("-") + visit_Mul = _make_binop("*") + visit_Div = _make_binop("/") + visit_FloorDiv = _make_binop("//") + visit_Pow = _make_binop("**") + visit_Mod = _make_binop("%") + visit_And = _make_binop("and") + visit_Or = _make_binop("or") + visit_Pos = _make_unop("+") + visit_Neg = _make_unop("-") + visit_Not = _make_unop("not ") + + @optimizeconst + def visit_Concat(self, node: nodes.Concat, frame: Frame) -> None: + if frame.eval_ctx.volatile: + func_name = "(markup_join if context.eval_ctx.volatile else str_join)" + elif frame.eval_ctx.autoescape: + func_name = "markup_join" + else: + func_name = "str_join" + self.write(f"{func_name}((") + for arg in node.nodes: + self.visit(arg, frame) + self.write(", ") + self.write("))") + + @optimizeconst + def visit_Compare(self, node: nodes.Compare, frame: Frame) -> None: + self.write("(") + self.visit(node.expr, frame) + for op in node.ops: + self.visit(op, frame) + self.write(")") + + def visit_Operand(self, node: nodes.Operand, frame: Frame) -> None: + self.write(f" {operators[node.op]} ") + self.visit(node.expr, frame) + + @optimizeconst + def visit_Getattr(self, node: nodes.Getattr, frame: Frame) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getattr(") + self.visit(node.node, frame) + self.write(f", {node.attr!r})") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Getitem(self, node: nodes.Getitem, frame: Frame) -> None: + # slices bypass the environment getitem method. + if isinstance(node.arg, nodes.Slice): + self.visit(node.node, frame) + self.write("[") + self.visit(node.arg, frame) + self.write("]") + else: + if self.environment.is_async: + self.write("(await auto_await(") + + self.write("environment.getitem(") + self.visit(node.node, frame) + self.write(", ") + self.visit(node.arg, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + def visit_Slice(self, node: nodes.Slice, frame: Frame) -> None: + if node.start is not None: + self.visit(node.start, frame) + self.write(":") + if node.stop is not None: + self.visit(node.stop, frame) + if node.step is not None: + self.write(":") + self.visit(node.step, frame) + + @contextmanager + def _filter_test_common( + self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool + ) -> t.Iterator[None]: + if self.environment.is_async: + self.write("(await auto_await(") + + if is_filter: + self.write(f"{self.filters[node.name]}(") + func = self.environment.filters.get(node.name) + else: + self.write(f"{self.tests[node.name]}(") + func = self.environment.tests.get(node.name) + + # When inside an If or CondExpr frame, allow the filter to be + # undefined at compile time and only raise an error if it's + # actually called at runtime. See pull_dependencies. + if func is None and not frame.soft_frame: + type_name = "filter" if is_filter else "test" + self.fail(f"No {type_name} named {node.name!r}.", node.lineno) + + pass_arg = { + _PassArg.context: "context", + _PassArg.eval_context: "context.eval_ctx", + _PassArg.environment: "environment", + }.get( + _PassArg.from_obj(func) # type: ignore + ) + + if pass_arg is not None: + self.write(f"{pass_arg}, ") + + # Back to the visitor function to handle visiting the target of + # the filter or test. + yield + + self.signature(node, frame) + self.write(")") + + if self.environment.is_async: + self.write("))") + + @optimizeconst + def visit_Filter(self, node: nodes.Filter, frame: Frame) -> None: + with self._filter_test_common(node, frame, True): + # if the filter node is None we are inside a filter block + # and want to write to the current buffer + if node.node is not None: + self.visit(node.node, frame) + elif frame.eval_ctx.volatile: + self.write( + f"(Markup(concat({frame.buffer}))" + f" if context.eval_ctx.autoescape else concat({frame.buffer}))" + ) + elif frame.eval_ctx.autoescape: + self.write(f"Markup(concat({frame.buffer}))") + else: + self.write(f"concat({frame.buffer})") + + @optimizeconst + def visit_Test(self, node: nodes.Test, frame: Frame) -> None: + with self._filter_test_common(node, frame, False): + self.visit(node.node, frame) + + @optimizeconst + def visit_CondExpr(self, node: nodes.CondExpr, frame: Frame) -> None: + frame = frame.soft() + + def write_expr2() -> None: + if node.expr2 is not None: + self.visit(node.expr2, frame) + return + + self.write( + f'cond_expr_undefined("the inline if-expression on' + f" {self.position(node)} evaluated to false and no else" + f' section was defined.")' + ) + + self.write("(") + self.visit(node.expr1, frame) + self.write(" if ") + self.visit(node.test, frame) + self.write(" else ") + write_expr2() + self.write(")") + + @optimizeconst + def visit_Call( + self, node: nodes.Call, frame: Frame, forward_caller: bool = False + ) -> None: + if self.environment.is_async: + self.write("(await auto_await(") + if self.environment.sandboxed: + self.write("environment.call(context, ") + else: + self.write("context.call(") + self.visit(node.node, frame) + extra_kwargs = {"caller": "caller"} if forward_caller else None + loop_kwargs = {"_loop_vars": "_loop_vars"} if frame.loop_frame else {} + block_kwargs = {"_block_vars": "_block_vars"} if frame.block_frame else {} + if extra_kwargs: + extra_kwargs.update(loop_kwargs, **block_kwargs) + elif loop_kwargs or block_kwargs: + extra_kwargs = dict(loop_kwargs, **block_kwargs) + self.signature(node, frame, extra_kwargs) + self.write(")") + if self.environment.is_async: + self.write("))") + + def visit_Keyword(self, node: nodes.Keyword, frame: Frame) -> None: + self.write(node.key + "=") + self.visit(node.value, frame) + + # -- Unused nodes for extensions + + def visit_MarkSafe(self, node: nodes.MarkSafe, frame: Frame) -> None: + self.write("Markup(") + self.visit(node.expr, frame) + self.write(")") + + def visit_MarkSafeIfAutoescape( + self, node: nodes.MarkSafeIfAutoescape, frame: Frame + ) -> None: + self.write("(Markup if context.eval_ctx.autoescape else identity)(") + self.visit(node.expr, frame) + self.write(")") + + def visit_EnvironmentAttribute( + self, node: nodes.EnvironmentAttribute, frame: Frame + ) -> None: + self.write("environment." + node.name) + + def visit_ExtensionAttribute( + self, node: nodes.ExtensionAttribute, frame: Frame + ) -> None: + self.write(f"environment.extensions[{node.identifier!r}].{node.name}") + + def visit_ImportedName(self, node: nodes.ImportedName, frame: Frame) -> None: + self.write(self.import_aliases[node.importname]) + + def visit_InternalName(self, node: nodes.InternalName, frame: Frame) -> None: + self.write(node.name) + + def visit_ContextReference( + self, node: nodes.ContextReference, frame: Frame + ) -> None: + self.write("context") + + def visit_DerivedContextReference( + self, node: nodes.DerivedContextReference, frame: Frame + ) -> None: + self.write(self.derive_context(frame)) + + def visit_Continue(self, node: nodes.Continue, frame: Frame) -> None: + self.writeline("continue", node) + + def visit_Break(self, node: nodes.Break, frame: Frame) -> None: + self.writeline("break", node) + + def visit_Scope(self, node: nodes.Scope, frame: Frame) -> None: + scope_frame = frame.inner() + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + + def visit_OverlayScope(self, node: nodes.OverlayScope, frame: Frame) -> None: + ctx = self.temporary_identifier() + self.writeline(f"{ctx} = {self.derive_context(frame)}") + self.writeline(f"{ctx}.vars = ") + self.visit(node.context, frame) + self.push_context_reference(ctx) + + scope_frame = frame.inner(isolated=True) + scope_frame.symbols.analyze_node(node) + self.enter_frame(scope_frame) + self.blockvisit(node.body, scope_frame) + self.leave_frame(scope_frame) + self.pop_context_reference() + + def visit_EvalContextModifier( + self, node: nodes.EvalContextModifier, frame: Frame + ) -> None: + for keyword in node.options: + self.writeline(f"context.eval_ctx.{keyword.key} = ") + self.visit(keyword.value, frame) + try: + val = keyword.value.as_const(frame.eval_ctx) + except nodes.Impossible: + frame.eval_ctx.volatile = True + else: + setattr(frame.eval_ctx, keyword.key, val) + + def visit_ScopedEvalContextModifier( + self, node: nodes.ScopedEvalContextModifier, frame: Frame + ) -> None: + old_ctx_name = self.temporary_identifier() + saved_ctx = frame.eval_ctx.save() + self.writeline(f"{old_ctx_name} = context.eval_ctx.save()") + self.visit_EvalContextModifier(node, frame) + for child in node.body: + self.visit(child, frame) + frame.eval_ctx.revert(saved_ctx) + self.writeline(f"context.eval_ctx.revert({old_ctx_name})") diff --git a/venv/lib/python3.12/site-packages/jinja2/constants.py b/venv/lib/python3.12/site-packages/jinja2/constants.py new file mode 100644 index 0000000..41a1c23 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/constants.py @@ -0,0 +1,20 @@ +#: list of lorem ipsum words used by the lipsum() helper function +LOREM_IPSUM_WORDS = """\ +a ac accumsan ad adipiscing aenean aliquam aliquet amet ante aptent arcu at +auctor augue bibendum blandit class commodo condimentum congue consectetuer +consequat conubia convallis cras cubilia cum curabitur curae cursus dapibus +diam dictum dictumst dignissim dis dolor donec dui duis egestas eget eleifend +elementum elit enim erat eros est et etiam eu euismod facilisi facilisis fames +faucibus felis fermentum feugiat fringilla fusce gravida habitant habitasse hac +hendrerit hymenaeos iaculis id imperdiet in inceptos integer interdum ipsum +justo lacinia lacus laoreet lectus leo libero ligula litora lobortis lorem +luctus maecenas magna magnis malesuada massa mattis mauris metus mi molestie +mollis montes morbi mus nam nascetur natoque nec neque netus nibh nisi nisl non +nonummy nostra nulla nullam nunc odio orci ornare parturient pede pellentesque +penatibus per pharetra phasellus placerat platea porta porttitor posuere +potenti praesent pretium primis proin pulvinar purus quam quis quisque rhoncus +ridiculus risus rutrum sagittis sapien scelerisque sed sem semper senectus sit +sociis sociosqu sodales sollicitudin suscipit suspendisse taciti tellus tempor +tempus tincidunt torquent tortor tristique turpis ullamcorper ultrices +ultricies urna ut varius vehicula vel velit venenatis vestibulum vitae vivamus +viverra volutpat vulputate""" diff --git a/venv/lib/python3.12/site-packages/jinja2/debug.py b/venv/lib/python3.12/site-packages/jinja2/debug.py new file mode 100644 index 0000000..7ed7e92 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/debug.py @@ -0,0 +1,191 @@ +import sys +import typing as t +from types import CodeType +from types import TracebackType + +from .exceptions import TemplateSyntaxError +from .utils import internal_code +from .utils import missing + +if t.TYPE_CHECKING: + from .runtime import Context + + +def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException: + """Rewrite the current exception to replace any tracebacks from + within compiled template code with tracebacks that look like they + came from the template source. + + This must be called within an ``except`` block. + + :param source: For ``TemplateSyntaxError``, the original source if + known. + :return: The original exception with the rewritten traceback. + """ + _, exc_value, tb = sys.exc_info() + exc_value = t.cast(BaseException, exc_value) + tb = t.cast(TracebackType, tb) + + if isinstance(exc_value, TemplateSyntaxError) and not exc_value.translated: + exc_value.translated = True + exc_value.source = source + # Remove the old traceback, otherwise the frames from the + # compiler still show up. + exc_value.with_traceback(None) + # Outside of runtime, so the frame isn't executing template + # code, but it still needs to point at the template. + tb = fake_traceback( + exc_value, None, exc_value.filename or "", exc_value.lineno + ) + else: + # Skip the frame for the render function. + tb = tb.tb_next + + stack = [] + + # Build the stack of traceback object, replacing any in template + # code with the source file and line information. + while tb is not None: + # Skip frames decorated with @internalcode. These are internal + # calls that aren't useful in template debugging output. + if tb.tb_frame.f_code in internal_code: + tb = tb.tb_next + continue + + template = tb.tb_frame.f_globals.get("__jinja_template__") + + if template is not None: + lineno = template.get_corresponding_lineno(tb.tb_lineno) + fake_tb = fake_traceback(exc_value, tb, template.filename, lineno) + stack.append(fake_tb) + else: + stack.append(tb) + + tb = tb.tb_next + + tb_next = None + + # Assign tb_next in reverse to avoid circular references. + for tb in reversed(stack): + tb.tb_next = tb_next + tb_next = tb + + return exc_value.with_traceback(tb_next) + + +def fake_traceback( # type: ignore + exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int +) -> TracebackType: + """Produce a new traceback object that looks like it came from the + template source instead of the compiled code. The filename, line + number, and location name will point to the template, and the local + variables will be the current template context. + + :param exc_value: The original exception to be re-raised to create + the new traceback. + :param tb: The original traceback to get the local variables and + code info from. + :param filename: The template filename. + :param lineno: The line number in the template source. + """ + if tb is not None: + # Replace the real locals with the context that would be + # available at that point in the template. + locals = get_template_locals(tb.tb_frame.f_locals) + locals.pop("__jinja_exception__", None) + else: + locals = {} + + globals = { + "__name__": filename, + "__file__": filename, + "__jinja_exception__": exc_value, + } + # Raise an exception at the correct line number. + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) + + # Build a new code object that points to the template file and + # replaces the location with a block name. + location = "template" + + if tb is not None: + function = tb.tb_frame.f_code.co_name + + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) + + # Execute the new code, which is guaranteed to raise, and return + # the new traceback without this frame. + try: + exec(code, globals, locals) + except BaseException: + return sys.exc_info()[2].tb_next # type: ignore + + +def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]: + """Based on the runtime locals, get the context that would be + available at that point in the template. + """ + # Start with the current template context. + ctx: "t.Optional[Context]" = real_locals.get("context") + + if ctx is not None: + data: t.Dict[str, t.Any] = ctx.get_all().copy() + else: + data = {} + + # Might be in a derived context that only sets local variables + # rather than pushing a context. Local variables follow the scheme + # l_depth_name. Find the highest-depth local that has a value for + # each name. + local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {} + + for name, value in real_locals.items(): + if not name.startswith("l_") or value is missing: + # Not a template variable, or no longer relevant. + continue + + try: + _, depth_str, name = name.split("_", 2) + depth = int(depth_str) + except ValueError: + continue + + cur_depth = local_overrides.get(name, (-1,))[0] + + if cur_depth < depth: + local_overrides[name] = (depth, value) + + # Modify the context with any derived context. + for name, (_, value) in local_overrides.items(): + if value is missing: + data.pop(name, None) + else: + data[name] = value + + return data diff --git a/venv/lib/python3.12/site-packages/jinja2/defaults.py b/venv/lib/python3.12/site-packages/jinja2/defaults.py new file mode 100644 index 0000000..638cad3 --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/defaults.py @@ -0,0 +1,48 @@ +import typing as t + +from .filters import FILTERS as DEFAULT_FILTERS # noqa: F401 +from .tests import TESTS as DEFAULT_TESTS # noqa: F401 +from .utils import Cycler +from .utils import generate_lorem_ipsum +from .utils import Joiner +from .utils import Namespace + +if t.TYPE_CHECKING: + import typing_extensions as te + +# defaults for the parser / lexer +BLOCK_START_STRING = "{%" +BLOCK_END_STRING = "%}" +VARIABLE_START_STRING = "{{" +VARIABLE_END_STRING = "}}" +COMMENT_START_STRING = "{#" +COMMENT_END_STRING = "#}" +LINE_STATEMENT_PREFIX: t.Optional[str] = None +LINE_COMMENT_PREFIX: t.Optional[str] = None +TRIM_BLOCKS = False +LSTRIP_BLOCKS = False +NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n" +KEEP_TRAILING_NEWLINE = False + +# default filters, tests and namespace + +DEFAULT_NAMESPACE = { + "range": range, + "dict": dict, + "lipsum": generate_lorem_ipsum, + "cycler": Cycler, + "joiner": Joiner, + "namespace": Namespace, +} + +# default policies +DEFAULT_POLICIES: t.Dict[str, t.Any] = { + "compiler.ascii_str": True, + "urlize.rel": "noopener", + "urlize.target": None, + "urlize.extra_schemes": None, + "truncate.leeway": 5, + "json.dumps_function": None, + "json.dumps_kwargs": {"sort_keys": True}, + "ext.i18n.trimmed": False, +} diff --git a/venv/lib/python3.12/site-packages/jinja2/environment.py b/venv/lib/python3.12/site-packages/jinja2/environment.py new file mode 100644 index 0000000..1d3be0b --- /dev/null +++ b/venv/lib/python3.12/site-packages/jinja2/environment.py @@ -0,0 +1,1675 @@ +"""Classes for managing templates and their runtime and compile time +options. +""" + +import os +import typing +import typing as t +import weakref +from collections import ChainMap +from functools import lru_cache +from functools import partial +from functools import reduce +from types import CodeType + +from markupsafe import Markup + +from . import nodes +from .compiler import CodeGenerator +from .compiler import generate +from .defaults import BLOCK_END_STRING +from .defaults import BLOCK_START_STRING +from .defaults import COMMENT_END_STRING +from .defaults import COMMENT_START_STRING +from .defaults import DEFAULT_FILTERS # type: ignore[attr-defined] +from .defaults import DEFAULT_NAMESPACE +from .defaults import DEFAULT_POLICIES +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] +from .defaults import KEEP_TRAILING_NEWLINE +from .defaults import LINE_COMMENT_PREFIX +from .defaults import LINE_STATEMENT_PREFIX +from .defaults import LSTRIP_BLOCKS +from .defaults import NEWLINE_SEQUENCE +from .defaults import TRIM_BLOCKS +from .defaults import VARIABLE_END_STRING +from .defaults import VARIABLE_START_STRING +from .exceptions import TemplateNotFound +from .exceptions import TemplateRuntimeError +from .exceptions import TemplatesNotFound +from .exceptions import TemplateSyntaxError +from .exceptions import UndefinedError +from .lexer import get_lexer +from .lexer import Lexer +from .lexer import TokenStream +from .nodes import EvalContext +from .parser import Parser +from .runtime import Context +from .runtime import new_context +from .runtime import Undefined +from .utils import _PassArg +from .utils import concat +from .utils import consume +from .utils import import_string +from .utils import internalcode +from .utils import LRUCache +from .utils import missing + +if t.TYPE_CHECKING: + import typing_extensions as te + + from .bccache import BytecodeCache + from .ext import Extension + from .loaders import BaseLoader + +_env_bound = t.TypeVar("_env_bound", bound="Environment") + + +# for direct template usage we have up to ten living environments +@lru_cache(maxsize=10) +def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound: + """Return a new spontaneous environment. A spontaneous environment + is used for templates created directly rather than through an + existing environment. + + :param cls: Environment class to create. + :param args: Positional arguments passed to environment. + """ + env = cls(*args) + env.shared = True + return env + + +def create_cache( + size: int, +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Return the cache class for the given size.""" + if size == 0: + return None + + if size < 0: + return {} + + return LRUCache(size) # type: ignore + + +def copy_cache( + cache: t.Optional[t.MutableMapping[t.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: + """Create an empty copy of the given cache.""" + if cache is None: + return None + + if type(cache) is dict: # noqa E721 + return {} + + return LRUCache(cache.capacity) # type: ignore + + +def load_extensions( + environment: "Environment", + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]], +) -> t.Dict[str, "Extension"]: + """Load the extensions from the list and bind it to the environment. + Returns a dict of instantiated extensions. + """ + result = {} + + for extension in extensions: + if isinstance(extension, str): + extension = t.cast(t.Type["Extension"], import_string(extension)) + + result[extension.identifier] = extension(environment) + + return result + + +def _environment_config_check(environment: "Environment") -> "Environment": + """Perform a sanity check on the environment.""" + assert issubclass( + environment.undefined, Undefined + ), "'undefined' must be a subclass of 'jinja2.Undefined'." + assert ( + environment.block_start_string + != environment.variable_start_string + != environment.comment_start_string + ), "block, variable and comment start strings must be different." + assert environment.newline_sequence in { + "\r", + "\r\n", + "\n", + }, "'newline_sequence' must be one of '\\n', '\\r\\n', or '\\r'." + return environment + + +class Environment: + r"""The core component of Jinja is the `Environment`. It contains + important shared variables like configuration, filters, tests, + globals and others. Instances of this class may be modified if + they are not shared and if no template was loaded so far. + Modifications on environments after the first template was loaded + will lead to surprising effects and undefined behavior. + + Here are the possible initialization parameters: + + `block_start_string` + The string marking the beginning of a block. Defaults to ``'{%'``. + + `block_end_string` + The string marking the end of a block. Defaults to ``'%}'``. + + `variable_start_string` + The string marking the beginning of a print statement. + Defaults to ``'{{'``. + + `variable_end_string` + The string marking the end of a print statement. Defaults to + ``'}}'``. + + `comment_start_string` + The string marking the beginning of a comment. Defaults to ``'{#'``. + + `comment_end_string` + The string marking the end of a comment. Defaults to ``'#}'``. + + `line_statement_prefix` + If given and a string, this will be used as prefix for line based + statements. See also :ref:`line-statements`. + + `line_comment_prefix` + If given and a string, this will be used as prefix for line based + comments. See also :ref:`line-statements`. + + .. versionadded:: 2.2 + + `trim_blocks` + If this is set to ``True`` the first newline after a block is + removed (block, not variable tag!). Defaults to `False`. + + `lstrip_blocks` + If this is set to ``True`` leading spaces and tabs are stripped + from the start of a line to a block. Defaults to `False`. + + `newline_sequence` + The sequence that starts a newline. Must be one of ``'\r'``, + ``'\n'`` or ``'\r\n'``. The default is ``'\n'`` which is a + useful default for Linux and OS X systems as well as web + applications. + + `keep_trailing_newline` + Preserve the trailing newline when rendering templates. + The default is ``False``, which causes a single newline, + if present, to be stripped from the end of the template. + + .. versionadded:: 2.7 + + `extensions` + List of Jinja extensions to use. This can either be import paths + as strings or extension classes. For more information have a + look at :ref:`the extensions documentation `. + + `optimized` + should the optimizer be enabled? Default is ``True``. + + `undefined` + :class:`Undefined` or a subclass of it that is used to represent + undefined values in the template. + + `finalize` + A callable that can be used to process the result of a variable + expression before it is output. For example one can convert + ``None`` implicitly into an empty string here. + + `autoescape` + If set to ``True`` the XML/HTML autoescaping feature is enabled by + default. For more details about autoescaping see + :class:`~markupsafe.Markup`. As of Jinja 2.4 this can also + be a callable that is passed the template name and has to + return ``True`` or ``False`` depending on autoescape should be + enabled by default. + + .. versionchanged:: 2.4 + `autoescape` can now be a function + + `loader` + The template loader for this environment. + + `cache_size` + The size of the cache. Per default this is ``400`` which means + that if more than 400 templates are loaded the loader will clean + out the least recently used template. If the cache size is set to + ``0`` templates are recompiled all the time, if the cache size is + ``-1`` the cache will not be cleaned. + + .. versionchanged:: 2.8 + The cache size was increased to 400 from a low 50. + + `auto_reload` + Some loaders load templates from locations where the template + sources may change (ie: file system or database). If + ``auto_reload`` is set to ``True`` (default) every time a template is + requested the loader checks if the source changed and if yes, it + will reload the template. For higher performance it's possible to + disable that. + + `bytecode_cache` + If set to a bytecode cache object, this object will provide a + cache for the internal Jinja bytecode so that templates don't + have to be parsed if they were not changed. + + See :ref:`bytecode-cache` for more information. + + `enable_async` + If set to true this enables async template execution which + allows using async functions and generators. + """ + + #: if this environment is sandboxed. Modifying this variable won't make + #: the environment sandboxed though. For a real sandboxed environment + #: have a look at jinja2.sandbox. This flag alone controls the code + #: generation by the compiler. + sandboxed = False + + #: True if the environment is just an overlay + overlayed = False + + #: the environment this environment is linked to if it is an overlay + linked_to: t.Optional["Environment"] = None + + #: shared environments have this set to `True`. A shared environment + #: must not be modified + shared = False + + #: the class that is used for code generation. See + #: :class:`~jinja2.compiler.CodeGenerator` for more information. + code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + + concat = "".join + + #: the context class that is used for templates. See + #: :class:`~jinja2.runtime.Context` for more information. + context_class: t.Type[Context] = Context + + template_class: t.Type["Template"] + + def __init__( + self, + block_start_string: str = BLOCK_START_STRING, + block_end_string: str = BLOCK_END_STRING, + variable_start_string: str = VARIABLE_START_STRING, + variable_end_string: str = VARIABLE_END_STRING, + comment_start_string: str = COMMENT_START_STRING, + comment_end_string: str = COMMENT_END_STRING, + line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX, + line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX, + trim_blocks: bool = TRIM_BLOCKS, + lstrip_blocks: bool = LSTRIP_BLOCKS, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE, + keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (), + optimized: bool = True, + undefined: t.Type[Undefined] = Undefined, + finalize: t.Optional[t.Callable[..., t.Any]] = None, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False, + loader: t.Optional["BaseLoader"] = None, + cache_size: int = 400, + auto_reload: bool = True, + bytecode_cache: t.Optional["BytecodeCache"] = None, + enable_async: bool = False, + ): + # !!Important notice!! + # The constructor accepts quite a few arguments that should be + # passed by keyword rather than position. However it's important to + # not change the order of arguments because it's used at least + # internally in those cases: + # - spontaneous environments (i18n extension and Template) + # - unittests + # If parameter changes are required only add parameters at the end + # and don't change the arguments (or the defaults!) of the arguments + # existing already. + + # lexer / parser information + self.block_start_string = block_start_string + self.block_end_string = block_end_string + self.variable_start_string = variable_start_string + self.variable_end_string = variable_end_string + self.comment_start_string = comment_start_string + self.comment_end_string = comment_end_string + self.line_statement_prefix = line_statement_prefix + self.line_comment_prefix = line_comment_prefix + self.trim_blocks = trim_blocks + self.lstrip_blocks = lstrip_blocks + self.newline_sequence = newline_sequence + self.keep_trailing_newline = keep_trailing_newline + + # runtime information + self.undefined: t.Type[Undefined] = undefined + self.optimized = optimized + self.finalize = finalize + self.autoescape = autoescape + + # defaults + self.filters = DEFAULT_FILTERS.copy() + self.tests = DEFAULT_TESTS.copy() + self.globals = DEFAULT_NAMESPACE.copy() + + # set the loader provided + self.loader = loader + self.cache = create_cache(cache_size) + self.bytecode_cache = bytecode_cache + self.auto_reload = auto_reload + + # configurable policies + self.policies = DEFAULT_POLICIES.copy() + + # load extensions + self.extensions = load_extensions(self, extensions) + + self.is_async = enable_async + _environment_config_check(self) + + def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None: + """Adds an extension after the environment was created. + + .. versionadded:: 2.5 + """ + self.extensions.update(load_extensions(self, [extension])) + + def extend(self, **attributes: t.Any) -> None: + """Add the items to the instance of the environment if they do not exist + yet. This is used by :ref:`extensions ` to register + callbacks and configuration values without breaking inheritance. + """ + for key, value in attributes.items(): + if not hasattr(self, key): + setattr(self, key, value) + + def overlay( + self, + block_start_string: str = missing, + block_end_string: str = missing, + variable_start_string: str = missing, + variable_end_string: str = missing, + comment_start_string: str = missing, + comment_end_string: str = missing, + line_statement_prefix: t.Optional[str] = missing, + line_comment_prefix: t.Optional[str] = missing, + trim_blocks: bool = missing, + lstrip_blocks: bool = missing, + newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing, + keep_trailing_newline: bool = missing, + extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing, + optimized: bool = missing, + undefined: t.Type[Undefined] = missing, + finalize: t.Optional[t.Callable[..., t.Any]] = missing, + autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing, + loader: t.Optional["BaseLoader"] = missing, + cache_size: int = missing, + auto_reload: bool = missing, + bytecode_cache: t.Optional["BytecodeCache"] = missing, + enable_async: bool = False, + ) -> "Environment": + """Create a new overlay environment that shares all the data with the + current environment except for cache and the overridden attributes. + Extensions cannot be removed for an overlayed environment. An overlayed + environment automatically gets all the extensions of the environment it + is linked to plus optional extra extensions. + + Creating overlays should happen after the initial environment was set + up completely. Not all attributes are truly linked, some are just + copied over so modifications on the original environment may not shine + through. + + .. versionchanged:: 3.1.2 + Added the ``newline_sequence``,, ``keep_trailing_newline``, + and ``enable_async`` parameters to match ``__init__``. + """ + args = dict(locals()) + del args["self"], args["cache_size"], args["extensions"], args["enable_async"] + + rv = object.__new__(self.__class__) + rv.__dict__.update(self.__dict__) + rv.overlayed = True + rv.linked_to = self + + for key, value in args.items(): + if value is not missing: + setattr(rv, key, value) + + if cache_size is not missing: + rv.cache = create_cache(cache_size) + else: + rv.cache = copy_cache(self.cache) + + rv.extensions = {} + for key, value in self.extensions.items(): + rv.extensions[key] = value.bind(rv) + if extensions is not missing: + rv.extensions.update(load_extensions(rv, extensions)) + + if enable_async is not missing: + rv.is_async = enable_async + + return _environment_config_check(rv) + + @property + def lexer(self) -> Lexer: + """The lexer for this environment.""" + return get_lexer(self) + + def iter_extensions(self) -> t.Iterator["Extension"]: + """Iterates over the extensions by priority.""" + return iter(sorted(self.extensions.values(), key=lambda x: x.priority)) + + def getitem( + self, obj: t.Any, argument: t.Union[str, t.Any] + ) -> t.Union[t.Any, Undefined]: + """Get an item or attribute of an object but prefer the item.""" + try: + return obj[argument] + except (AttributeError, TypeError, LookupError): + if isinstance(argument, str): + try: + attr = str(argument) + except Exception: + pass + else: + try: + return getattr(obj, attr) + except AttributeError: + pass + return self.undefined(obj=obj, name=argument) + + def getattr(self, obj: t.Any, attribute: str) -> t.Any: + """Get an item or attribute of an object but prefer the attribute. + Unlike :meth:`getitem` the attribute *must* be a string. + """ + try: + return getattr(obj, attribute) + except AttributeError: + pass + try: + return obj[attribute] + except (TypeError, LookupError, AttributeError): + return self.undefined(obj=obj, name=attribute) + + def _filter_test_common( + self, + name: t.Union[str, Undefined], + value: t.Any, + args: t.Optional[t.Sequence[t.Any]], + kwargs: t.Optional[t.Mapping[str, t.Any]], + context: t.Optional[Context], + eval_ctx: t.Optional[EvalContext], + is_filter: bool, + ) -> t.Any: + if is_filter: + env_map = self.filters + type_name = "filter" + else: + env_map = self.tests + type_name = "test" + + func = env_map.get(name) # type: ignore + + if func is None: + msg = f"No {type_name} named {name!r}." + + if isinstance(name, Undefined): + try: + name._fail_with_undefined_error() + except Exception as e: + msg = f"{msg} ({e}; did you forget to quote the callable name?)" + + raise TemplateRuntimeError(msg) + + args = [value, *(args if args is not None else ())] + kwargs = kwargs if kwargs is not None else {} + pass_arg = _PassArg.from_obj(func) + + if pass_arg is _PassArg.context: + if context is None: + raise TemplateRuntimeError( + f"Attempted to invoke a context {type_name} without context." + ) + + args.insert(0, context) + elif pass_arg is _PassArg.eval_context: + if eval_ctx is None: + if context is not None: + eval_ctx = context.eval_ctx + else: + eval_ctx = EvalContext(self) + + args.insert(0, eval_ctx) + elif pass_arg is _PassArg.environment: + args.insert(0, self) + + return func(*args, **kwargs) + + def call_filter( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a filter on a value the same way the compiler does. + + This might return a coroutine if the filter is running from an + environment in async mode and the filter supports async + execution. It's your responsibility to await this if needed. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, True + ) + + def call_test( + self, + name: str, + value: t.Any, + args: t.Optional[t.Sequence[t.Any]] = None, + kwargs: t.Optional[t.Mapping[str, t.Any]] = None, + context: t.Optional[Context] = None, + eval_ctx: t.Optional[EvalContext] = None, + ) -> t.Any: + """Invoke a test on a value the same way the compiler does. + + This might return a coroutine if the test is running from an + environment in async mode and the test supports async execution. + It's your responsibility to await this if needed. + + .. versionchanged:: 3.0 + Tests support ``@pass_context``, etc. decorators. Added + the ``context`` and ``eval_ctx`` parameters. + + .. versionadded:: 2.7 + """ + return self._filter_test_common( + name, value, args, kwargs, context, eval_ctx, False + ) + + @internalcode + def parse( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> nodes.Template: + """Parse the sourcecode and return the abstract syntax tree. This + tree of nodes is used by the compiler to convert the template into + executable source- or bytecode. This is useful for debugging or to + extract information from templates. + + If you are :ref:`developing Jinja extensions ` + this gives you a good overview of the node tree generated. + """ + try: + return self._parse(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def _parse( + self, source: str, name: t.Optional[str], filename: t.Optional[str] + ) -> nodes.Template: + """Internal parsing function used by `parse` and `compile`.""" + return Parser(self, source, name, filename).parse() + + def lex( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> t.Iterator[t.Tuple[int, str, str]]: + """Lex the given sourcecode and return a generator that yields + tokens as tuples in the form ``(lineno, token_type, value)``. + This can be useful for :ref:`extension development ` + and debugging templates. + + This does not perform preprocessing. If you want the preprocessing + of the extensions to be applied you have to filter source through + the :meth:`preprocess` method. + """ + source = str(source) + try: + return self.lexer.tokeniter(source, name, filename) + except TemplateSyntaxError: + self.handle_exception(source=source) + + def preprocess( + self, + source: str, + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + ) -> str: + """Preprocesses the source with all extensions. This is automatically + called for all parsing and compiling methods but *not* for :meth:`lex` + because there you usually only want the actual source tokenized. + """ + return reduce( + lambda s, e: e.preprocess(s, name, filename), + self.iter_extensions(), + str(source), + ) + + def _tokenize( + self, + source: str, + name: t.Optional[str], + filename: t.Optional[str] = None, + state: t.Optional[str] = None, + ) -> TokenStream: + """Called by the parser to do the preprocessing and filtering + for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`. + """ + source = self.preprocess(source, name, filename) + stream = self.lexer.tokenize(source, name, filename, state) + + for ext in self.iter_extensions(): + stream = ext.filter_stream(stream) # type: ignore + + if not isinstance(stream, TokenStream): + stream = TokenStream(stream, name, filename) + + return stream + + def _generate( + self, + source: nodes.Template, + name: t.Optional[str], + filename: t.Optional[str], + defer_init: bool = False, + ) -> str: + """Internal hook that can be overridden to hook a different generate + method in. + + .. versionadded:: 2.5 + """ + return generate( # type: ignore + source, + self, + name, + filename, + defer_init=defer_init, + optimized=self.optimized, + ) + + def _compile(self, source: str, filename: str) -> CodeType: + """Internal hook that can be overridden to hook a different compile + method in. + + .. versionadded:: 2.5 + """ + return compile(source, filename, "exec") + + @typing.overload + def compile( # type: ignore + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[False]" = False, + defer_init: bool = False, + ) -> CodeType: ... + + @typing.overload + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: "te.Literal[True]" = ..., + defer_init: bool = False, + ) -> str: ... + + @internalcode + def compile( + self, + source: t.Union[str, nodes.Template], + name: t.Optional[str] = None, + filename: t.Optional[str] = None, + raw: bool = False, + defer_init: bool = False, + ) -> t.Union[str, CodeType]: + """Compile a node or template source code. The `name` parameter is + the load name of the template after it was joined using + :meth:`join_path` if necessary, not the filename on the file system. + the `filename` parameter is the estimated filename of the template on + the file system. If the template came from a database or memory this + can be omitted. + + The return value of this method is a python code object. If the `raw` + parameter is `True` the return value will be a string with python + code equivalent to the bytecode returned otherwise. This method is + mainly used internally. + + `defer_init` is use internally to aid the module code generator. This + causes the generated code to be able to import without the global + environment variable to be set. + + .. versionadded:: 2.4 + `defer_init` parameter added. + """ + source_hint = None + try: + if isinstance(source, str): + source_hint = source + source = self._parse(source, name, filename) + source = self._generate(source, name, filename, defer_init=defer_init) + if raw: + return source + if filename is None: + filename = "