From e5fa07ccc149fedf14f888147bc5ef4bcda487b5 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 15:07:57 +0100 Subject: [PATCH 01/18] docs: fix formatting of docstring in haiku.py Refs: OPS-92 --- senju/haiku.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/senju/haiku.py b/senju/haiku.py index e9b322a..fda04ea 100644 --- a/senju/haiku.py +++ b/senju/haiku.py @@ -16,8 +16,7 @@ Classes ------- Haiku A dataclass representation of a haiku poem, providing structure -for storage, - manipulation and serialization of poem data. + for storage, manipulation and serialization of poem data. **Methods**: From 97b57916debe14916b2c48d85eef2560b7f6352d Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 15:13:08 +0100 Subject: [PATCH 02/18] docs: specify the correct exceptions raised by request_haiku Refs: OPS-92 --- senju/haiku.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/senju/haiku.py b/senju/haiku.py index fda04ea..128ba79 100644 --- a/senju/haiku.py +++ b/senju/haiku.py @@ -108,8 +108,8 @@ class Haiku: :return: A new Haiku object containing the generated three lines. :rtype: Haiku - :raises: Possible JSONDecodeError which is caught and handled - with retries. + :raises: Exception if took the llm too many tries to write a fitting + haiku or JSONDecodeError if working with JSON failed """ ai_gen_request = { "model": "haiku", From a1d44646aef8b8ac8999eb2bd41cc91848e67eb1 Mon Sep 17 00:00:00 2001 From: Amrasil <134395490+Amrasil@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:22:59 +0100 Subject: [PATCH 03/18] Update main.py description image recognition --- senju/main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/senju/main.py b/senju/main.py index 8befcf0..d09d266 100644 --- a/senju/main.py +++ b/senju/main.py @@ -168,6 +168,9 @@ def scan_view(): @app.route("/api/v1/image_reco", methods=['POST']) def image_recognition(): + """ + returns json formatted description of an image + """ # note that the classifier is a singleton if 'image' not in request.files: return "No image file provided", 400 From d876ca230134a8df78c00ff2c1d4316a71bfabea Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 15:23:19 +0100 Subject: [PATCH 04/18] docs: add sphinx documentation for image_reco module Refs: OPS-92 OPS-93 --- senju/image_reco.py | 84 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 75 insertions(+), 9 deletions(-) diff --git a/senju/image_reco.py b/senju/image_reco.py index 49d2db8..272e985 100644 --- a/senju/image_reco.py +++ b/senju/image_reco.py @@ -1,3 +1,40 @@ +""" +Senju Image Recognition Module +============================= + +A module providing image description generation capabilities for the Senju haiku application. + +This module leverages pre-trained vision-language models (specifically BLIP) to generate +textual descriptions of uploaded images. These descriptions can then be used as input +for the haiku generation process, enabling image-to-haiku functionality. + +Classes +------- +ImageDescriptionGenerator + The primary class responsible for loading the vision-language model + and generating descriptions from image data. + +Functions +--------- +gen_response + A helper function that wraps the description generation process + for API integration. + +Dependencies +------------ +* torch: Deep learning framework required for model operations +* PIL.Image: Image processing capabilities +* io: Utilities for working with binary data streams +* transformers: Hugging Face's library providing access to pre-trained models + +Implementation Details +--------------------- +The module initializes a BLIP model (Bootstrapped Language-Image Pre-training) +which can understand visual content and generate natural language descriptions. +The implementation handles image loading, preprocessing, model inference, +and post-processing to return structured description data. +""" + import torch from PIL import Image import io @@ -5,14 +42,28 @@ from transformers import BlipProcessor, BlipForConditionalGeneration class ImageDescriptionGenerator: + """ + A class for generating textual descriptions of images using a vision-language model. + + This class handles the loading of a pre-trained BLIP model, image preprocessing, + and caption generation. It provides an interface for converting raw image data + into natural language descriptions that can be used for haiku inspiration. + + :ivar processor: The BLIP processor for handling image inputs + :type processor: BlipProcessor + :ivar model: The BLIP model for conditional text generation + :type model: BlipForConditionalGeneration + :ivar device: The computation device (CUDA or CPU) + :type device: str + """ + def __init__(self, model_name="Salesforce/blip-image-captioning-base"): """ Initialize an image description generator using a vision-language model. - Args: - model_name: The name of the model to use - (default: BLIP captioning model) + :param model_name: The name of the pre-trained model to use + :type model_name: str """ self.device = "cuda" if torch.cuda.is_available() else "cpu" print(f"Using device: {self.device}") @@ -24,13 +75,15 @@ class ImageDescriptionGenerator: """ Generate a descriptive caption for the given image. - Args: - image_data: Raw image data (bytes) - max_length: Maximum length of the generated caption + This method processes the raw image data, runs inference with the BLIP model, + and returns a structured response with the generated description. - Returns: - dict: A dictionary containing the generated description - and confidence score + :param image_data: Raw binary image data + :type image_data: bytes + :param max_length: Maximum token length for the generated caption + :type max_length: int + :return: Dictionary containing the generated description and confidence score + :rtype: dict """ # Convert uploaded bytes to image img = Image.open(io.BytesIO(image_data)).convert("RGB") @@ -59,8 +112,21 @@ class ImageDescriptionGenerator: } +# Global instance of the description generator g_descriptor: ImageDescriptionGenerator = ImageDescriptionGenerator() def gen_response(image_data) -> dict: + """ + Generate a description for an image using the global description generator. + + This function provides a simplified interface to the image description functionality + for use in API endpoints. + + :param image_data: Raw binary image data + :type image_data: bytes + :return: Dictionary containing the image description and confidence information + :rtype: dict + :raises Exception: If image processing or description generation fails + """ return g_descriptor.generate_description(image_data) From c3877f894e72266ea564bdede5b6a4f402a5f81b Mon Sep 17 00:00:00 2001 From: Amrasil <134395490+Amrasil@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:24:24 +0100 Subject: [PATCH 05/18] Update main.py --- senju/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/senju/main.py b/senju/main.py index d09d266..8f05bb3 100644 --- a/senju/main.py +++ b/senju/main.py @@ -169,7 +169,9 @@ def scan_view(): @app.route("/api/v1/image_reco", methods=['POST']) def image_recognition(): """ - returns json formatted description of an image + generate a description of an image + + :return: json """ # note that the classifier is a singleton if 'image' not in request.files: From a02e6ccb422c04dd9f02385c8f3017226f5ac33c Mon Sep 17 00:00:00 2001 From: Amrasil <134395490+Amrasil@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:25:09 +0100 Subject: [PATCH 06/18] Update main.py --- senju/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/senju/main.py b/senju/main.py index 8f05bb3..d4b99c8 100644 --- a/senju/main.py +++ b/senju/main.py @@ -171,7 +171,8 @@ def image_recognition(): """ generate a description of an image - :return: json + :return: json formatted description + :rtype: json """ # note that the classifier is a singleton if 'image' not in request.files: From bfd52423b787f33fe22bff9925532341bbb5e52c Mon Sep 17 00:00:00 2001 From: Amrasil <134395490+Amrasil@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:36:46 +0100 Subject: [PATCH 07/18] Update image_reco.py shortend some lines --- senju/image_reco.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/senju/image_reco.py b/senju/image_reco.py index 272e985..e0f4b30 100644 --- a/senju/image_reco.py +++ b/senju/image_reco.py @@ -2,10 +2,13 @@ Senju Image Recognition Module ============================= -A module providing image description generation capabilities for the Senju haiku application. +A module providing image description generation capabilities for the Senju +haiku application. -This module leverages pre-trained vision-language models (specifically BLIP) to generate -textual descriptions of uploaded images. These descriptions can then be used as input +This module leverages pre-trained vision-language models (specifically BLIP) +to generate +textual descriptions of uploaded images. These descriptions can then be +used as input for the haiku generation process, enabling image-to-haiku functionality. Classes @@ -43,11 +46,13 @@ from transformers import BlipProcessor, BlipForConditionalGeneration class ImageDescriptionGenerator: """ - A class for generating textual descriptions of images using a vision-language model. + A class for generating textual descriptions of images using + a vision-language model. - This class handles the loading of a pre-trained BLIP model, image preprocessing, - and caption generation. It provides an interface for converting raw image data - into natural language descriptions that can be used for haiku inspiration. + This class handles the loading of a pre-trained BLIP model, image + preprocessing, and caption generation. It provides an interface for + converting raw image data into natural language descriptions that can + be used for haiku inspiration. :ivar processor: The BLIP processor for handling image inputs :type processor: BlipProcessor @@ -75,14 +80,16 @@ class ImageDescriptionGenerator: """ Generate a descriptive caption for the given image. - This method processes the raw image data, runs inference with the BLIP model, - and returns a structured response with the generated description. + This method processes the raw image data, runs inference with + the BLIP model, and returns a structured response with the + generated description. :param image_data: Raw binary image data :type image_data: bytes :param max_length: Maximum token length for the generated caption :type max_length: int - :return: Dictionary containing the generated description and confidence score + :return: Dictionary containing the generated description and + confidence score :rtype: dict """ # Convert uploaded bytes to image @@ -120,12 +127,13 @@ def gen_response(image_data) -> dict: """ Generate a description for an image using the global description generator. - This function provides a simplified interface to the image description functionality - for use in API endpoints. + This function provides a simplified interface to the image + description functionality for use in API endpoints. :param image_data: Raw binary image data :type image_data: bytes - :return: Dictionary containing the image description and confidence information + :return: Dictionary containing the image description and + confidence information :rtype: dict :raises Exception: If image processing or description generation fails """ From 55b1c77ff87bb45c9a22111772e2e99b2c950c0f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 14:37:06 +0000 Subject: [PATCH 08/18] ci: automatic Python Formatter changes --- senju/image_reco.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/senju/image_reco.py b/senju/image_reco.py index e0f4b30..e4f45c9 100644 --- a/senju/image_reco.py +++ b/senju/image_reco.py @@ -2,12 +2,12 @@ Senju Image Recognition Module ============================= -A module providing image description generation capabilities for the Senju +A module providing image description generation capabilities for the Senju haiku application. This module leverages pre-trained vision-language models (specifically BLIP) to generate -textual descriptions of uploaded images. These descriptions can then be +textual descriptions of uploaded images. These descriptions can then be used as input for the haiku generation process, enabling image-to-haiku functionality. @@ -46,12 +46,12 @@ from transformers import BlipProcessor, BlipForConditionalGeneration class ImageDescriptionGenerator: """ - A class for generating textual descriptions of images using + A class for generating textual descriptions of images using a vision-language model. - This class handles the loading of a pre-trained BLIP model, image - preprocessing, and caption generation. It provides an interface for - converting raw image data into natural language descriptions that can + This class handles the loading of a pre-trained BLIP model, image + preprocessing, and caption generation. It provides an interface for + converting raw image data into natural language descriptions that can be used for haiku inspiration. :ivar processor: The BLIP processor for handling image inputs @@ -80,15 +80,15 @@ class ImageDescriptionGenerator: """ Generate a descriptive caption for the given image. - This method processes the raw image data, runs inference with - the BLIP model, and returns a structured response with the + This method processes the raw image data, runs inference with + the BLIP model, and returns a structured response with the generated description. :param image_data: Raw binary image data :type image_data: bytes :param max_length: Maximum token length for the generated caption :type max_length: int - :return: Dictionary containing the generated description and + :return: Dictionary containing the generated description and confidence score :rtype: dict """ @@ -127,12 +127,12 @@ def gen_response(image_data) -> dict: """ Generate a description for an image using the global description generator. - This function provides a simplified interface to the image + This function provides a simplified interface to the image description functionality for use in API endpoints. :param image_data: Raw binary image data :type image_data: bytes - :return: Dictionary containing the image description and + :return: Dictionary containing the image description and confidence information :rtype: dict :raises Exception: If image processing or description generation fails From b1bd55d7590b9dbe90a112010cc273e4362d56fd Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 15:59:55 +0100 Subject: [PATCH 09/18] chore: update sphinx conf for authors and copyright Refs: OPS-92 --- docs/source/conf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index f7adaa5..f385dc8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -13,9 +13,9 @@ import sys sys.path.insert(0, os.path.abspath("../../senju")) project = 'senju' -copyright = '2025, senju hashirama' -author = 'senju hashirama' -release = 'before the light' +copyright = '2025, senju project' +author = 'senju project' +# release = '' # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration From 22268beaba6686f1d45fbf424c97f023e1991087 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:00:15 +0100 Subject: [PATCH 10/18] docs: fix doc warnings Refs: OPS-92 --- senju/haiku.py | 2 +- senju/image_reco.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/senju/haiku.py b/senju/haiku.py index 128ba79..195ae76 100644 --- a/senju/haiku.py +++ b/senju/haiku.py @@ -109,7 +109,7 @@ class Haiku: :rtype: Haiku :raises: Exception if took the llm too many tries to write a fitting - haiku or JSONDecodeError if working with JSON failed + haiku or JSONDecodeError if working with JSON failed """ ai_gen_request = { "model": "haiku", diff --git a/senju/image_reco.py b/senju/image_reco.py index e4f45c9..4fdc093 100644 --- a/senju/image_reco.py +++ b/senju/image_reco.py @@ -1,6 +1,6 @@ """ Senju Image Recognition Module -============================= +============================== A module providing image description generation capabilities for the Senju haiku application. @@ -31,7 +31,7 @@ Dependencies * transformers: Hugging Face's library providing access to pre-trained models Implementation Details ---------------------- +---------------------- The module initializes a BLIP model (Bootstrapped Language-Image Pre-training) which can understand visual content and generate natural language descriptions. The implementation handles image loading, preprocessing, model inference, From 1f6abff63b559c35fc03580cfdf27ad4e15a866c Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:15:39 +0100 Subject: [PATCH 11/18] docs: write out a readme Refs: OPS-92 --- README.md | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8a62376..0a262c8 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,119 @@ -![Codecov](https://codecov.io/gh/senju1337/senju/branch/master/graph/badge.svg) +
+ senju logo +

千手 Senju

+

πŸŽ‹ Poetry in Motion 🎎

+

+ A web service for Haiku generation from text or from images and Haiku + sharing +

+
+ + Code Coverage + + + Build Status + + + License + + + Release + +
+ + Python Versions + + + Powered by Flask + + + AI PyTorch + +
-# senju -API / Webservice for Phrases/Words/Kanji/Haiku +## 🌊 Overview + +Senju (千手, "thousand hands") is a web service for haiku poetry generation and sharing, with image-to-haiku functionality. + +## ✨ Features + +- **🎏 AI-Powered Haiku Generation**: Create beautiful three-line haiku poetry from text prompts +- **πŸ–ΌοΈ Image-to-Haiku**: Turn uploaded images into poetic haiku (experimental) +- **πŸ” Browse Existing Haiku**: Gallery view of previously generated poetry +- **πŸ’Ύ Persistent Storage**: All generated haiku are stored for future retrieval +- **πŸ–₯️ Web Interface**: Clean, efficient, minimalist user experience for human interaction + +## πŸ”§ Installation + +```bash +# Clone the repository +git clone https://github.com/senju1337/senju.git +cd senju + +docker compose up +``` + +### πŸ“‹ Dependencies + +- Python +- Flask +- TinyDB +- PyTorch +- Transformers +- Pillow + +See `pyproject.toml` for a complete list of dependencies. + +## 🏯 Architecture + +Senju is built around several key components: + +- **Flask Application**: Core web framework providing routing and template rendering +- **Haiku Generator**: Interfaces with a machine learning model for poetry creation +- **Image Recognition**: Vision-language model for extracting descriptions from images +- **Storage Manager**: TinyDB-based persistence layer for haiku retrieval and storage + +## πŸ“ Documentation + +Senju is documented with sphinx. The documentation of the latest release is +available on [github-pages](https://senju1337.github.io/senju/). + +It can be generated like this (after installing the dependencies, see above): + +```bash +cd docs +bash auto_docu.sh +# now open the documentation with a web browser of your choice +firefox ./build/html/ +``` + +## πŸ§ͺ Testing + +```bash +# Run tests +pytest + +# Run tests with coverage +bash coverage.sh +``` + +## πŸ“œ License + +Distributed under the GPL-3 License. See `LICENSE` for more information. + +## πŸ™ Acknowledgements + +- [Ollama](https://ollama.ai/) for providing the AI backend +- [BLIP](https://github.com/salesforce/BLIP) for the image captioning model +- [PyTorch](https://pytorch.org/) and [Transformers](https://huggingface.co/docs/transformers/index) for ML infrastructure +- [Flask](https://flask.palletsprojects.com/) for the web framework +- [TinyDB](https://tinydb.readthedocs.io/) for the document database + +
+ +
+ Purple petals rise
+ Defying fragile beauty
+ Fiercely breathing life
+
From 50961cdc1f6511ffa78a2497f6e716d8db9a6f44 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:17:14 +0100 Subject: [PATCH 12/18] chore: rename poetry script action Refs: OPS-92 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 49b85d7..f877da4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ requires = ["poetry-core>=2.0.0,<3.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry.scripts] -sennen = "senju.main:main" +senju = "senju.main:main" [tool.poetry.group.dev.dependencies] sphinx = "8.1.3" From 34b5e8339efffbfedafa375f1726223e3b05ae7a Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:18:46 +0100 Subject: [PATCH 13/18] docs: add GPL-3 license Refs: OPS-92 --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 6ed24ae2aa41f18c8962dfac0b4c18f83264e32c Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:19:24 +0100 Subject: [PATCH 14/18] chore: add license to pyproject.toml Refs: OPS-92 --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index f877da4..75ed24a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ "transformers (>=4.50.0,<5.0.0)", "waitress (>=3.0.2,<4.0.0)", ] +license = { file = "LICENSE" } [build-system] From ed6d17de5b71fbb4aa6d834fa6e89299b295a4cd Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:21:46 +0100 Subject: [PATCH 15/18] docs: fix ci shield link in readme Refs: OPS-92 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a262c8..ef1ce36 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Code Coverage - Build Status + Tests Status License From 414ad8f6ea4e381008494ad844ae84022d48fadc Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:28:28 +0100 Subject: [PATCH 16/18] docs: use the same logo everywhere Refs: OPS-92 --- README.md | 3 +- senju/static/img/kanji.png | 1 + senju/static/img/senju-nobg.png | Bin 17684 -> 0 bytes senju/static/img/senju-nobg.svg | 113 -------------------------------- senju/static/img/senju.png | Bin 18734 -> 0 bytes senju/static/img/senju.svg | 110 ------------------------------- senju/templates/base.html | 3 +- 7 files changed, 3 insertions(+), 227 deletions(-) create mode 120000 senju/static/img/kanji.png delete mode 100644 senju/static/img/senju-nobg.png delete mode 100644 senju/static/img/senju-nobg.svg delete mode 100644 senju/static/img/senju.png delete mode 100644 senju/static/img/senju.svg diff --git a/README.md b/README.md index ef1ce36..a160959 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@
- senju logo + senju logo

千手 Senju

πŸŽ‹ Poetry in Motion 🎎

diff --git a/senju/static/img/kanji.png b/senju/static/img/kanji.png new file mode 120000 index 0000000..e3f549b --- /dev/null +++ b/senju/static/img/kanji.png @@ -0,0 +1 @@ +/home/plex/Dokumente/code/py/senju/docs/source/_static/kanji.png \ No newline at end of file diff --git a/senju/static/img/senju-nobg.png b/senju/static/img/senju-nobg.png deleted file mode 100644 index 6c88f3c66af1b82b5dcfd54c6ec1d353ab419fb0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17684 zcmd>mbx@SyALqM4cO%^)-5m-@ha!!#fCxy3bS%;>C?O5fl7fIzOP2!Dk_!lkfV+V7 z0=NF|Zsun0ZtniPnfqhs-Q9WjeV%VT-}-!J3~20ATD}kP|*G z_QEcsW`w;EcxqYr003#xm#ud)S9OdAs2JGT%(Y>bp0@tC!j{=IHIc{Ta+TJ{C^6{5w_t{x} z_ZhXb*_g`Z|6IASY2^8zcZPDTKK|ReXd&UkDb92_IYVC*IRo(_QhR$Pk!9v7#D z%MT)_pcrA}2Cz5WDTS(H?~i;7#Kpxudrb*YP^1w*`v2iaNjbYp>ZQ)RD)n(m2|Zjo zn7+%4XN!%^gpo8gg~=p5<;;oA%06e!_OFQ>!le5bT)roM{R=-fCaikZQ~kFosr6WO zu`ww#<6IuSr6DYTi-y+^Es`Y_55GiIM40h6hDzLaN)ZZpvw1$hNcFH&j6C+pa~wV- z9yf+6f)zK5WIU?0trkIA4}PA@dd?Jm=$w=#0C2h_mqD5K&`yi&$>#AUV$ux0 zCuIv){NCd0-&kQBa&?jm{p$k@SEH1hkr4Mi-Srx>n$$+LpA8gN7p+oAW~+EVKGtbd zIo2$l)FLN~60nG(kz+LXPD=z$Gd(rrE{dZ6DcVJTlj)w|%V4dAIAbo*SLmXkr}8?; zmt~Nq-xMW-Q#!t}_n;*;slT7LOWTkWLHEbFGZ!RK)m-Ha3R9=q7wF>?cxe>0~#ryO^Nek~o=HT^kZ`s`y*TfqIdro~WI z+(ZVNyId?9Q%Rwmb>IH_{n2O7vFuj{!*E(4!U*$N4jIM}e8i9_RRz&6R`g#F^N1%e zc15NYG409UxsU)-JfXu5#~|r*sI#38@T}o0H$ZC;=&PaVYcSQ=&o&1|6p?Ha!(1<> zep9!N!YlxfO`aqVp(Dyoy~r}nCC9-hV7;M0>Hv}LmLdD~?p%C6&})!jo;EQD%Zpto zoWmGihWkY5_2w(d-l~TVVC4HkuqU5U$(snZ>%lM7pJzsm)e1HrBac8LR`0+=Ni7qC z$I>Y$a8eKZC*VP<2KjMe`ZZ`6*)p_4{x@mO?t|vilxBP*T!!B}#o=*#wHt{P^L1`h zGzX1_pa6w4E0sd-A$Nnaz$#Wcp)Wl$EmU~)~@6s*Dy>2HWU||<8{tj zLhHKy!X^WCuc^rZ``8(V)ppVF#jQLolXm#C;{MggVQWnU*=Y}C#o`!1 zm4S2s952sNLmG#a--b~1#ue=q>p$X!%T3x7_!ce_@WGH-iaz#pvzLJ99>xXtLx#VL zE0N&NVZFd>o^q^L=mddaocnb3*4Jco!Fn>^sApb@< z)-T+fvfOZc&wv=XBfM!UMS~#~D?8sV6nP-u(rJ#nhjcYRRE_tcm3Xr_TtW*P%midR z+}2w@T4i^~EnMXEOfc(^rVh-SSraR3Mbz60;%td*KA$*TYPP4+e)I29)p2^)F}q4D zQ23+%Ih7rP#m@rKP8*NbC;-G#+qZ-~ybyu_JV#Vao%H;~=+Dtanw{ghI#>QjB(-=M z5$P--t>Em=rVX8xrrgWd8S*CJ8gg_fk_0B=VI{j`P1e$Y+w)7EH%Iq@HPr}pGBB(f zPX`h=Pib({ll`?i;Z0=Mc(fW~F9=Fizz7V6nWfU-h@`m`^~FD^s51tLa(@OAok#Ua zc(pz$MtIShzUUy@G|*YrX1uMu{2C$FLDiV5;o!x6{1*G*hbm-lrm!IpO@HPfKEBGm zWSm9*L*-sV&*Q?T$DeDxqOJy)%zYIe4a>%C6ulBtOV-Yijj|3QQ2pHY4JIS~qemq} zC#mOd-JC-ycUrCryivSCd@^GCq4N22e{fyR$LLD+dz?UepblV}*Rx1{PAN)iuiZ;o zw;91LmRZt2MZY;ZUosjcoa%MJVTMcg+HBR6p-?mPMoDJF(x>s+1AwwcXCQ-8Bnejh zeCBK|ofE)CK{D|MCnv4|Cr46rb>F_E{hPt}(4tuy3$o2$!$aGwoH=4!R0qmZzmBY+ zf6FKgzuuh(nq>mP$eKroK8xc-vmG;Rni2XOVdE;#al+!gSV3p9iWHia+M?O&5y``c zVtG<69y>NqPMC;ZFjA2eh$RLx`I`GZgUdqPbuNNqB|f?Q4HpGkj^< zEBB7_jGl;4K|96?syg);ybXA)cj%|IdTs+g1c}gZJ%L04xs?9>X>|-8tP3wDw|1O1 z2N$h8@P#q}#H%Ol5Dn5>Mkw|9ok5DEFmD%1&pMiS_YtewBx#I#MOt+0`Zp5l^FJ%e z977Y9ZMpr>et!&WY_#*S`6%y40}}sxD}F5D8h1w(wbv@ZHnbNNneG!2D2t+4?bns{ z86A3O@U+xn6My3H16Nl(j!sBQ4{x~~oun^&Zd&{ouVzay8iORlJ)o9jwV%koJSZJ5 zqZR%1R2$wyNxchn0sHE{N11Qqf3}Sx-{=PsmM6WUgqxcE6!XqA@4DBWEI}6l+4+VO z?!NO9Cd^&FL9_L+{sz1^}mCBr*Kn6vCSB)wB511Tlv z@tJ2Y5I<$KDS1a1M3YT^Xc3l10Yoxs2t&(Linja-sOHxFAp7?s-Z*VeQZ%=lW3BsU zQ-IzE%F{pNN)SM>sgXwqml?Am=ZPMJ?15NW%9CmMy?H=|$^1Odp8pO->N-2U9UX#g zJ1ueGcVLitiA=fo_hL7^Cmr+a6o7y@jV#3e9Vk@)kdwD4NywiQkk@dQpr;>E0K#BcaO^W)ox`bIW=y+pu)Jy8#T zFAE6hzBBJ5E7)rcrwTlzc=DW^bdC*g4{;twD0J=C*HkcBp-K#4Ih)IFxZAnmHvxY8HM;Ab%j%J3cw4sCAUm;86G!| zkG|dFIffFFT;aa^DhG@t+;#m6j{2|_q4MZ65=8=IB|A?SSr(RUD?Q;Dsq1_HbD>Ug zMPh*#YpZ0Qb1m+=`VEWQ-V5&WIjA5C^rT>u3>*8!N;ch=AH?U!->9^G>d|yLP-FO) zKlxs0HE@>$qsN==#9uZEc^nLw3__?3@YKz!a{+jwNe(~ABU z7SHvfy+j_MZ1lTu>^xtC|9}t3n@Kdih|azeigd`cF@6RiGw)lH?Okg7^mNalBfs6t zASI+h(y6DenTs0`H~MG{Xr}t zZ~L%s@vu@4sM)20kD{E3Ma<2w{}kOz?YI~Jq$B@|WARRiajGEKzI`?Ug%rE@{$rEo zS*J~uASQg4%oB*c(2}jRMp%DIxW7i8fyYiAyQSq{MZ~WYVfLNX(2FWkK@<8xMq)gd);AP zP`K)n_F>SlBbhPA*>OP%h-CSkG5Wnw`tk?t+~~s&$mWcx`*d_5exzxbKR$H-^izi4YRcjpZAvP6c1f%T3C-x%5Du?q{WL4xLt zHe8zr09m~apC{EDXv+kv)HcrctW6(NpED$O`Clh94T+TJSC<38sLvlV6UEnz4ap4| z)SMq~?|7yB)KbHCYLHnUC^GV;Yj8kW!t5>NIv*YyiY7l)wGW6IRd-Ui0*xi&X3_f| zeokwC80||2_HLkM1cDg%i(U7Q1QAUt9Q?;%a-9y->Ty1Qr%Mq-@uOKnpF%T1&NBnt9g;9 zi=2QUJt%vEpslQ&R+naNdWXI(d-}Xe^DS`ERX#3w7uftr39 zukA-0?2Cb=c2C>;={Od{2K&ToPfVU!mCUiyON@LseyQ;E@VV?`nomxHzbWQ73cy+( z6fpjcB%BY2)8S6P&iFPfDVSy?K2iW5WM9$u(j3>`-DO~#0{%sz_n}nTxFLB=M*Tv0 zD*4(0PGi3jeiZe0UbLGom&D%YztJ>*==S4YeLWKgOG;DFKvcwWJ;kR+*@wo!h#MrS zdVp0EOdcBP&r+5=_F!^cs{-ILvG#hNT-06uP&nP>9oNYc=n zK>Bt4?jtHxNsuO`IY|jE(5327*2bQ(bD72B>-CI4b%t7t+#GwT8f3W_MoMjTWm2gfFVvY;_nIC}Bd0NBfk9E)A0^qjfsaOi4?AX= zf{fk3NP5lS*OTb(Cj0(RnjK0X(Ib=FBssTaCf)cAh?vK#d7CUZvA;^Iy9DMF_thRJ z$1-IN&Zy0tHN*Z6!<==#vgI{-^vMk*V7}kI?ZUfd>SmsO*CQ^wRu_QyAm39jx5Y6x z(%%F(X2_fSm#0j21&_8{`F5a5WK^chS8Ri^=FPwKDcbJr46%6nSoe?)^)jwi2(S#B zsGO-Fr82Mvuz+UUPbX}}e4-n!`q}aH@bjmB@e`e65^q^ejjt?gyXXMHeD&F4zC-$Z zfrpl9iA8q4TQ1ZVV_;>KqM1L)CrmUdd$@857z%T*Nww={uS>q}$e8EH=BaQ)bwx>Q z3kPS4e}|mOhtvIWq7d$e8^#GO6-o2U(IGEv5M2{H@F3k7rYmUY;N#xkcdN#IZ#GWTRfDnu+s7p^&_2Q7t3qS5oDE;ncx|D(4`269 zzjyi|PB3aB1BR`iR%_5z$QjCud4Ql!j(!8x;QEOw_pL~~uses7`wx>p61xpMli;<& zBl*NZ3!EE)V-UKBKRtV+Ly0V8!LSBF?$ZG|CXPg@Z`|hlauEHI?M7vgOT7Nki=+Z}Af_9jgs;7F(Z6z4qKHg4S8LPc zBc;LPMc!Ve#?@cGlt{{9-SM?16X8_U34(-Y9ovG!Q-k(ww|)mP`Zi2VDzkbW)W1)% zH)nBQ`QkCT#l+pkk~GysOdMzT%0F<|I32vu{~MY2Gb5H~_C+HB09R81;n{^`1+*yN zyn~AjOd9kxQm*yNN^TUl;>+GWgmXz@y$VF;l1~-}S(}YvVR3t$(Rb^)g)cBfLjBTc zbd+Mk>Tw$C;RV4lxE{5Nsoae=;hVeBp3`9>%rpF3u^s+q^QYxi9C-%txS&R>jR)bA zr-yie$bY|I&$>wuCOsPc9icy=6XKr@{i9`eSg7|9%oa&<1C=Y_kg;GtDqpPhi))j< z9E}_g=csd+SoT7gJ~M-L-^`nS(VU{ z#e2*IriuOK2JcJJkyG3NmEBtYuof6dK9Ib70}3qvvvc>uC>%9^%BN z-{D2((H^3esTUTK3aLDcMaoCtV_WF#m_w5i(nO1e-NRK{-Id$QmJd1LxS7E{+@!?YPTU zbTXCaT>lSB`)_x@ToHk6D(AoT!AKGm@5wUVsvx`RrMnq$ zN@68GM7wO&lZijxeX_&lu{msMM^6y>iO-w&ea)s(SvPruhtkgI7U-?&^i4a+Ad1(^K|Q4&6QMbe)DcvwXM{p-F}6h{4Vf zlR4_e&ws5_<^~4$|2|Lq)G4pQ;&A9u{qPSvY^;>btg(S%Bcs0=0)tbI8#-+cNeR}} zFba5ajT5L(ybNFM8-)w?z=U*M6Pp+tlxCBcX~e>`QVLxbRF>WXT3nH2#-*{pI(tuy zb;0DTXm@7cKxxp}kk?TGjcirNH&?C#4wy?Uoy$SEB=KBXzYRL>_&{?WsrFWOVd*?r z@L*sVMywG=5@H`$k+%iH_?;NV} zKhdm23rQToARBH)@#aSVrx;9v$zNIgZV?8xGwieeS}4he((^utrkAeqBtHD{0E|OJITAa0Nu{Lye8HC}Lj8BKsQw4SMYcXo;8y;2 z!mR^WQEbuHA<{2lKmPDZM@a9xLz9UC|Mc7*b3zQTsTET|8bGqi<&F80w(3d(CUk{_ z(ArD%t`Jgj7Fe<=Vz$GQtVX;7-)HrGqFn2{*d-@Z(MR|h{PY`-dDft)QBZcenYRYH zQAZrUmqK+rN3;%+2MPy*a7_fS$rz+1Qh#b4De)SF-%s;CpR^3} z+!Pu)a#O{7c1Pe$b1==K^15X?cuK_!~twR)`kp2rPA`&GwOuyhS`<0 z3vb~WZ1#w=Ghk|4mslk$BP(ToU_Y!BYZ%6Vz-RgDe{ymg3)`QEa=FAIogh><$U5<1St-jQM^<8`PEx^@tboHt>&yRlhhzLEt zQyo-&!U8%?l*gOl!gzMYs`-huBA zaTiqsr)VQ~@=dTg*XJKvpYmNBa)*QJZFVRmq^UVlD{BS!aTXBQKVsk!t6d>+nX7_` z?IDAbMgfB13SSq?+2=?We&`~^tzvyHx~LX{-n%-J1YETv3^$1l8O)CN!3~(KMoeL2 zfyor9hI-COe_sTNo%`SAn6?W@!`DJYJq~I8`nJvUwZ8It2F=G)=Q*69223O34gy53 zn6ed4E&QB<;!ey-9hsl&*VQwV1z zX_IG>r5#j>IAJCi_Qw9Sf1Hu*lnxe8Zxu?HFzw0Uc=#5jOtdd>DCJbx7o@^y6FgPP zaJKDiCP+|!3c@2fOv>oFCEi;}-jY!67UsxU^(SmF_?mnJMTIGDOS|kan~|ra5B3`n z%+qQKxO{~of_M-eEXqAEG7Zm$r z$xUdHS11KK9XzlYjp)bsjRln@+EW}10-%P~Q za)aJip<7%OM)RxN;6%j@^Zw6lOGdm1T4+ndpf+~hI#@Vll~v895VxCb?@D^kcx=^% z!ujr-Fpw*Y&-)3)a+^Qp%y-HmK*IiotN2{Irk`Z5@KOZaN3 zq2QC9tC>1O+EzC)lWA;BHv?(C48huo((nP%*Tjl@S0r;1!UZj*X{CjL`PxII5C zsKQssLhOe{alWaN8V>>F*-NK$rjE@o=S#H`h2ARXsrE12UgD=DR0%n=?XHm5@*T!MT0O!HXU?$g zYzwZKsX~@uGtj=K-F8dyvHophNa@5;DtWkVM)r^3bN8m{6g$vZcdj44&{z-{U$`ht z<&FKQ4W;Er4EJoJ&l9Wtsa!BRCD*q10j$uC6Zzk{0I}fu3i6(=b#Tw>cXv7Jw8uEz zAU|CN!nEfZe@bN6%HjTb;1*g>X|AU>!D$FD0q}3?3Egwb@WuFzxL@ z$4e;ITGexmHg7bK>cV?#3@KA^sj2oa)DS}EU7S728qZ|?c2ALXz}*8O$~S}h01#ps zF3SL00t|T9mkJq&Oi;_fVR-w66xRy{Ny0Uza!76(BbBx>*a%yQ@K(e`d25R46fHPcPo-( zP7L^OSyS7)y5rtT*?dOf#af|yj{5Np-tm()2x-sdA6yk0t&NV~Qf%0mq6rR-f0lX@iX)qGX=uno zrf9XJ%+OTNejtq^jCerv+_lwCapsAWKPRrVscQB$V@ zLmyu5t8oPr_Z{)VZ&TFWZ#clU>Ho~?Vzf*m+elig0<_pK#K!dx)-e!W97nvz#%(Sa zOI{Fw{==~vD7he6q*89m8YQOi>rJ=T*BVD~M=&!wx>=24q-0L#pRH8xIS0c`lZBLU z2l5YBT--F(aX;>|Mzk#Tv>GT-r`5dphBa2jO($mi2=%ZF?K{xOGLsMWn) zVf3eeD~?&pU{|agDr%GSTpNDslnPN;U#Xwr6ioa25%U=B5)tnl%aQ)FHXi`idC&b@ zaO&!hXj1Q^?{pjw1jTTt^UqPiLWdw(ul2r>QdlI-8Dd?nP-avCDs25#f;Do(@BC+0 zI=(I!RgDJ+)a+F_tJ^V^GyOLk{7TDJB{Btf8*|i4Bx8nQ!%$D_bYA#$FnQbE1GbIL zTP=lGIp(MsSRiZ`D|4EL!#~Z~>mqv0Z}e$b{4r4I()t^z{k6aQEFGJ_n%|Qng1Vun znhf5<-G7M$3z1bNRTe^B<@<@|VQX$N1yV(W*>1$?A#c zk(g-@)~!%^fFGabmdKPOwoM^PphA$5bZ^r%V4lFTBA<{M|LHqy=5%%K3E(3+i}FH@ z!xSLA_7_=jD|{DA>s9hkcWeCJ8i*oD{_Xk!7F(DpYVL=Vg}5OykyfuD7j$Cn(s@fP z!TICHagVZPdmk~O@V<=Mgd>j5;D$r(29>%2iS`$fh%iW!VOcmuRXin7b$k#T;|HzT*kOh=+S|ne)f?;ODc&L0*J^hCHte)o) z^|`P@4k01N44}*)CK+g*Co2LUuq2{RhM$GS*#0@>OZ-K8_uIqRAmIznd z3!i!1%&RV4BFT6bDzwJ1HM3NMiRMLb8Jr&$4m;d>XZ2%ItU1l|#|s;xbEEtD-ykYX z^8O})?rG=zpx2fmvN6&hF9zL}HsQ7QPP^S=&0^sEaNN4OaFtWp2D#M}0U;imDl%^1 z5#-jFIQiM%{pgk_@eYT1Do=wMId@58TSOpDdkbTMMho;PrggDZ4sl9LDBpYg3o;1f zz@*Vv0=NjXNASr;@X*Y-{b932x-f4y{Dhg5#h<-)zNb6E{|Ti}`@;grHut3AVkS5< zwW@X=E|^y+O8mibBUhFiAemtFcsq#Ab>rLxB_f6clY_wA`G@{Kh>5(tQx()LwSRJa zIB>|qJnSy|N48}L$pRkg(opX}=z%*~$msRR-wcj1Rw#zQU=RcC*eeZKOn)#LAVYV@ zb)XqiDf!%iEoD6%&TIdo;_LiC&{$X58$x!={%EF7`Q#gmxJ{Mu9$DeD2Drtz_BeE?xRN98+jGnfLL8a5mmk1L_*qeIdS25R}!z zGk&}taiZIOIhaL*Lr)e_c=z!9UGf_19saz%y#>FQ9mo4ej}h*iAzNjlehgh!y5Fi2 zB&oQ8kxBYq@6)HKLgR5?EaD(w)+rY^`W?dCL@`ju)y9VHw3s z%)f)Ah|bX}BjUixy8C`pS|);X3tC&|M2 zB`#^xNHN<}M~zmBY+u0{k77i@26{UO7g%RkR^FPzLx_i7>PSVR}j72r>yN7GD;E?i%sAfm=osXf-? zJJ5MPK}7#`Jfg0!jCsH=aHl}NU$gYknF3}$6W;~BpH=lUm%%-BhvSZ#EBDRMZm5yeg4kdv4J%|<%!1_y^y-;_ z_W6;lNEwI>X{Ygh^-^gaAbqq!(TqDKeL@((j=^`FCjr zRE}!^3p8(#D=!gqfE85;35=w{1WwR+q9Bi=pmhp*H*llLWW{XZ$lY*2MfUMZs>8^EoU{EC+E{_4V_B_kYFLN5Uj}Sis$k31`tnY*ge0 z{OGfz`I7xMrWyqbZ>k<1Fje2>wR8(6iJR_bbqHcV+8xg54LPlAH}<;B?_6LOg0K zIE#IGq>;R#MOpOwkI&c%to?Onb_UUgfk-JWa>Wx~xy zZ8$jYPZ7YkY)V@gO>(3So+(Q+fp5$%TzvQUxnUPxYG=h%3+n10g?B074iVgxem^)bai7|bL%`w&nnr>dFO>xV-yF+RFNdke;B?DAo4WgBTn`+RP+1F z?kPW*O=5+R0&6yfq1CtQzebA`{o4OV8%CZ_1ekw|bB&2m+1Qui9o7|`FTQDZCj6gC zz}T%xT1?R6E5A0_`K&D_IhC?ymRg+Ork_-tyv48+>=KMqh?=f-v@yoPl>ey?FsdN5Zk^>%O{WV)=hK$b49h%xj-YBF;bu1gE@M38>Tc zfexQC^{b}Uu^vCeW<#uEc#8P{!$h9qP^B0tni6Ti>^Wn2q?|o5E&JdOhR+6S;X2=k?tyvIa-_&?|97;S1NF4h?D> zaXe3NEMT_`jJuF_z8ILDQ5)|8zIy2iA4uzsVIcD_?J|$t!!W*?#Zl`H&iwOO`wJ60 zr>*ZXm{oOkyORI9<^L6V+L@v#?%6{T^ozxNTA2$^oHa$Wu}tfcqUA$unUB>DmwpcT zf6K|H1tr8ua*o-6YN!nDH|GZYLq)Ltx5a-(bvj*y3%?JWPtpgbQ~u=;jwwN5aH8{G zK{vUf0>?L90#zl8wTT{oJ%uFp=Ap^KQS&Z})aobfG18>{M+!re2Khhs0)|Mjy2VH3 zfxc>CJ4`Iswy4V#Pg+MIPM$$`FDzUjvzsArLPr5i;cT$@U!Cp$mQMZ~h#UT8al`ia z9tXFySXWEtg?J_^wO*;pV2S4Z=S=mZyI8Na#6$#C>*!Qt{GByl>kk}6%uoUjfBpw< zx+IQ~S=b%4-r_?o-P~M1tdMzcftfe{Pw}m@{phhbMq(?d^&bwbQ5*hnlcE68)oUFr zcRB~#D5ii^@CHwj?cMo)S{xkC-x+}T=hG^$PHtGK3jtEd7xwJcghuQ&V6M$?au+hj%BYLuv^L%X_~sMzHT8^RYq-mVzM_98VnDGy;%9cD zj9j#vP8JiIJ$1M|#K$!xaO2VU;4Ih$v#4M(zJ~gvVkp~KjR%fkI5G4Vw;Q@pa!Ggf z1?dm#jFsH~HWj1{?IA(vm~`0*PLf#TUGO$wZu_3sSa$;&>QnEbY%cq4*5?E=;lk(L z5v<17B;E~Pu%cEFcoEH(?t{<<=~-`!Pn=H0Ne>HKxR zzr7%-qE^0Xm+_vLN<%1|-jMji;(O#3^2x1Uv)SGqJhyP1HJ+ZQI{+P|Vm<$id!b&E zaV#8=#XT1%FJ;nC+V?`z|7xSIi1y&C)g(}zWsn6mYN-b9ut9>C7H8w`*!^86q!I0k>C%fEPzV{SL-|0pR9*+D zo`VsX%j>{t;sl)5XWQp?635 z6gruCm;p>wL(BuyWn4eWRWFyth+(v)6U$wQ>)@lwZsY8knllSDjZ+PC0JgQILj?)` zaCh8+ZDhbcKyrDO{7bpd zB<%NBS)jzw3a$|iup(Ddhi2;f^*8|&U1#jna~@dY#wcSXqJn1`^*4#HfBe-i_Qh}D zO+N9TB@2^-I;!4&3TUO(|HQGkM2ZQ39m}7f?|QPW%0c$7c^7y$oLicOevY%>?Dl~@ zrKt`3+iz)nmL73(V;|24Y7pSLciVzg02IICpKHz^@|E3@Xd_{1Q z%h5%u!@FVZQE7bjh#M(r>87tZ@FM*PIFC2_Qpz9OQ0pIxe0_8}%>8dA z3*-*SapMVD1#=QHr!`yw2ZJ|LvD&Yi3c6a)zpYGqPfCDz)pBe_neqtB2XX*CT;Z}n!pddvXDZm}EQ!pF3WML4w;aGwClL4 zZH`P6-yMMW zObtKri@1&+T#0`Oey+O974rMQ8PAx`&ze-Zi}5EZXf16pHz@E;!|>$0fSr72yf+rM z&byHaGF(&rqM`6e{XT^{M&&wrUV!Lw_e$}cHNs(Y*F~#7G9Qu`$=^h7v81 z(HE+wa`zfuuYGv&leY>AY!}u9;;#4p4DxBn?J#)O-%b7} zg0m;XNal)ggbn2LbdhJq1Dp+P$_)w^H2V}JRDMe9aN&%o;yRAsbVuq1?1-EzdvHzK z_%s#F79H#%ZFoK#D$DdPkGx|^)_!&3_VmVoa2`f~ZGi=JZFJ%L)`xXHB}=&T{^Y*)sf9gXoY(BK3A$&w!msGH=tFA zdu33ww8X#<0(z&(vQ(&bhDtl$ltY(^=ZHSvIo~PJ7t4&9lP6FOc(mGz=u-1OZa!8b z3zKgyj4%vi&!nwAyMhgwUF_e&ZE&TT6Ivx5GP<5Snk7fKw)c>Nl%DPnvtR-9aKsgS3?b6j&Y~w* z5Hp1#fd7LiS&5lIdOC7BVMuYld_uC@+HD!1Jq1!sEJf;Dcrc=lG`vy)^`VM2K5I*c z-I}+7&Lm&U=@yT9ZO*Qo!Tbh-41RSmQc2mc&`Eql6>!r0CAnAX1z5CjONHPx7oGPe z=8)L)jwpl&qqO(l?OQHjJ|XLL#c=)|LFgPywH}DpWjiNQ-um;f)$XDYbW0Y1v(JEh z!DpT5-%V*&^oVz^75ugfd@6;6s44F41niup6Mt|ppGbI}OV~o!fU_IE2+bzK5H1?@ z@^)Ly7ceM+;1^5I6|Zio%{fm`U5@Xf=RN;6`-alCE=k*9XLQNY{^b;_)Mh#gd3Tj? z{O)*433`pi8HP5kruKZ*lu}$S-7l98a3fr=L^$FqdK0f&97v`D3x7?DoAE@W(J1i) zu;uYdmVgsWtpBY@8cQxab`Xz6LF4fvuF1_C-LI3LQk>(hYe&!bxcEP}y?%Vm1*bu;~t&kVhiK|G?0=7?$RKZas zslQPm>U)%aFY{KkK|=J-0x5l#yQ*3c*|`L@Ar`03eZloD5BTb+G^Vyhfm~yI2g%wv z@@TLs_El(JAv{xAPBLyz&H@&^(SdIf939KAT5w`z1KG) zk)7Z&Gd39_ohJBvL@Qf1(SZ*PlWSqKdzWMw8zQ#dh`JyRkmOcX*9QLx2{;ww^QbzS ze>%fy(tJzzRk|+@0rNq4;I%{AXtq~Zh#fi@c|rI)m*w~Wn4@1}fhcG6NWgsG)(hKM zkV>(aN<`9Ndz1^=Ho1XZhnnn=33L_kL0@EyJkJWxhnRxHsrcZXR$q%rr zs_@DEi;F0?RA$d{#1g8y*)1kI(Z7|g;|B_GRo@guGL9?2D%8-4F^s2fW!QoKUaq+^ zd@mQ#-`rPq4|LAEaDenzJ$(8rtonP)WqBbGHRNFc3WL@ZdZJ|dva4t`Yc1Du5YEUY zE+#`-5j4B|RQw{}IhIjy(ikJbuui>t`Fg1f z!yoPf8^MAG5m^z_Mdz{orYEV71$cmCi;1hE0|De(@n^bFGD*DsLgX3vEMg5$qEO4{ zHybwmUi#swq+HJI*%04Sy(PWV5>LRJS^s*1mb_}fB48&X{_it0y;nCv#mzJenTWws zAA|vu4uTj--Er)JEi*m|asd#FHNP!&m<+@FU&ftzvHpLu)HO$V04%Kd`bx}pwobBx z^d_)lFNdOAT=5Co2x$cSvA{`H^-Teh^YTg2b1cN1AcwyTxj*e zckz3Y`5e}hYWzvCjhjtLqYFXO;2z>jz)qsJZ>BY^LuYu@@=2-x@h#o?_WLgv5G<&B zIL>;{%LHvtFs79tnXon!{_=|oP7757>9Ez7I^*20HLWOBD4+JKF1osYn{`Ols0R5Ls zK`(%?$b$|opyhWp!D>5K{8FgMKFb~QSq-iP7kjy<$(7EW;GdUn?H{@nVWZ)LsZqiA zJ^?=soC{h->@``JBM)$2olxqVD+=tfD3Ydn=6lV1{GI5K>REg}{KJTC5RebbuJg zX_;3WVX&*ob19s#SN;!}ub-Ona{=@}MR31hVF_2*#N#tHt2KFqGBQ8Pr<~&@GI;$- zR_WBItyJ!sweR>$=T>c%^{*$?zw>hgvjnY`ey>ov=26w(35}FM9KM1w^piT0Igl^8d)AA7L;b0cKQZIq9(@p|EjS6IJS0DC}pAqsH)o2@A~v*MTQK)%?NqVpz^ocDAv4gMgc(D0;?DT33+}olW6K z9}7&1+<0M{=z|EFDN^m647W)C4jKHU?>m`Dj z+5p%B*pgqvOL{d>RVTFK2?2U4pY6^@k*M@5VfX4s(UjTc0y)_^~ z0bGc?^vaxy!`U`#GylyrDHzzZzyS92ArDZV)V!Bms;w0M343Bwam&jF0sjhCg zcQ0;1_`30llKT8>G(FA}g+$-qc2J6~;sKM<9=0St{1Q^i2Nn3mi9gGVk~G#T`V^+_ z%YR+yIPQ|@M(rF4H#Lb&IP6@HU+o0CA4GO^V;m>0_`99;dpXUk)x)wnygU9p#AwQg z0|_D*;bWhlLgtFj>BBIikzuU3swY#t3dn7uw`U$o1HY90Rd_{2lAUbMYHk2Pi*6fs z%?Mi~4?m%5F5qOn_*`u(Wh&oEAfI~A#SpbP`vyU^H9_?mNW?wkZ3xb5iY6(uM(!!9 zg}RJp70*U*7`Gke<6VR90Gk=6t*Tc)R)0h|ww+COf@(YUW&NZ$fg=CKvh#w7g88p> z#R2gl`)Ad$QeIP^@roC4b{`IRx-H^dP#|q#KB1A*_%lZxXrrk`0%X22stt5OSxThZ zddZ(u@fKuM=o>_(*q{|CaYpG0k8qsR_egmemZO|Q1$YKG7EQoUSJvLH#cU*d31!K? zocgWUOv{FfY6hI~N@L-q)XZ8->@V5;`8>4pwoO`jzDYTu3gY-(r+>V8{d5gITCduw z_-n0$dPDBI`VR0dZTuyh%9FZ`v@CdZd&e)HTfq-c0z0DH!9FHYt08oSZcrg+L-S>- z9oud#?Y~e?tO{j(oVJm^kRIyXm6CEfxLkidMkZDDkrK=<^Rk6e&o9I-{R?-%J2u* zK0is`f5leIb5dK-y2~G3?;hSUIW6wKuJ;#>4~$#HZGU)AGKu1~WoCHtbhX3W;vOJ( z>#RyPhe;}-t9GU{sCfR}!*$1eR%~pn{MkAa&sjf38dN-2O_>gq;X1)EK}A!6* k1|9~_NlZq=PVg7|dWPz)J8TbvPCH@nboFyt=akR{0G?38S^xk5 diff --git a/senju/static/img/senju-nobg.svg b/senju/static/img/senju-nobg.svg deleted file mode 100644 index 2fa3790..0000000 --- a/senju/static/img/senju-nobg.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - 選集 - γ›γ‚“γ˜γ‚…γ† - - diff --git a/senju/static/img/senju.png b/senju/static/img/senju.png deleted file mode 100644 index dff566c1f888946cb1774058082d8c615b35233c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18734 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 II;Vst0AvWuYXATM diff --git a/senju/static/img/senju.svg b/senju/static/img/senju.svg deleted file mode 100644 index 0afb3b1..0000000 --- a/senju/static/img/senju.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - 選集 - γ›γ‚“γ˜γ‚…γ† - - diff --git a/senju/templates/base.html b/senju/templates/base.html index 5492e5f..78e9c22 100644 --- a/senju/templates/base.html +++ b/senju/templates/base.html @@ -21,8 +21,7 @@

From 1a17ba6e7332dcf68c156dbde1611b93e38248a3 Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:29:47 +0100 Subject: [PATCH 17/18] docs: make logo in readme a bit smaller Refs: OPS-92 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a160959..4662535 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@
- senju logo + senju logo

千手 Senju

πŸŽ‹ Poetry in Motion 🎎

From ed23d17a4f15d182c0543500fee8dc7eedcbc77d Mon Sep 17 00:00:00 2001 From: "Christoph J. Scherr" Date: Thu, 27 Mar 2025 16:31:11 +0100 Subject: [PATCH 18/18] chore: use a copied file instead of a link for the logo Refs: OPS-92 --- senju/static/img/kanji.png | Bin 64 -> 2386 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 120000 => 100644 senju/static/img/kanji.png diff --git a/senju/static/img/kanji.png b/senju/static/img/kanji.png deleted file mode 120000 index e3f549b..0000000 --- a/senju/static/img/kanji.png +++ /dev/null @@ -1 +0,0 @@ -/home/plex/Dokumente/code/py/senju/docs/source/_static/kanji.png \ No newline at end of file diff --git a/senju/static/img/kanji.png b/senju/static/img/kanji.png new file mode 100644 index 0000000000000000000000000000000000000000..345f5a566d7fddd89a42ab6af12e6ad3903c725f GIT binary patch literal 2386 zcmV-Y39a^tP)Yn!ql5Qft&vusm4Y_)A=hi(7=KYYs* zBZ7d^8{@_EaTk<3ki#$xgMpQmm6es1m6es1m6es1m6es1m6cUT`LpQVMR>7B&T01U zGQ3s`$8qMPcbDRoT02i|XW_dG@-jKOh9jx(F%+fp?u(rtYbcm5`A(_zNTMG7;p#97 zVm_yv{#?^@;x;7upGq8{rMS<@ev!*{l6$|(vZ<=p^RBEO58iItw!@Jw)AX-;`?@1!;`vBp6QEQ@u3gHV1tgK3nOl8I|l4HnD zU>M;{{sYW~jc@}ArKTX*2!ao4Gm&<~Ta0mz&a#?T@MzE2( za(QqO!m;8mnFkjkoU*Z|CoG{NgpKqjyBo_h-S*Vv4~mXn&%Rwto% zN|TLW(Ne=tQ9*gqNEj@Ogo#=iWCSe1irZiM2%|AcDP@dS5*Z974N#@D5eCpmLV=L~lgiPqotjk4!2|ON7j;5M?Q=AoFy7Vy_iD!w3@7}n@y*YQeT~_K@w|$+9PN~CTxJs< zs0viDs2}}`9bGXBp{U-M@a2M!D%3@e9oGkv%2Q;Y4wY4L|{ggSQDqPxS; zsbx!z_gVgBX%=lDJl>}QZG;YSfN;Zk2BQX_nzutNOc%tZ;yA7<)o}DG-XE zR*^d2V37H!ZmNGYU_8{ObNU|IBcVrxSwDKB=L-EH%-oExwf?C;gz2((Q}2L#Lzr6E zSOYzBA$+z`b|8qJ5QaDIS&^O)4t6u%TBI+8e03w-^`3BM3DFZCdQUj% zJ>jPJgwx&=Ud!AZ%NTaThkg;fo-mAl$RX?@=bVNb zp_h(6iQbDD+7U)S$qEFrcnpV}QYjGz`QW2BE`~B;@O7MC99q1{L@IGG6=C zWs>gDg5!(aXql3P{=EJcT~V=Egpr&4t~qp%wQiEX7|cq!KQ|!!Y!DMr(`6AX!XNhg zQmx5_GT?L{w|DOp7eghIsv6;d6ENnn3WU>75Nnb9_>P2aJWiwt8F!UDG)yY*i%C1? zm@v8%sz&CLCX5)qW_S9ID^Pg;5pa-buC8w#(M{NWDP4*C-(78z0hUhup$iZO>e9f+ zBLqgYrw**&lK3TF_>VVt1q>>2&E8uDWp4=oZ7yNioo;yUWnipmm|q!8m{%el9gB#x z-@ zI^epGMvH^dgyESV5-tSWYK`^=qX{3YHf}DkVbL75)^I|;rm_XcN(ib@5O)bFA&4D) z6IlI_5&|25D0VbbLShu=FMV_2Bm@Dpgr`1G5`r*x;;=**2}5G(-iz%-7zx3AP2$uw zLPB7Emoa7{BqUb2p^PmPAEA_i4G0~f*nx%;HbO8^NM5*uj1XKdFMA9b86jCS-DJ1D za1oL#2IOyMKt%|qqw-tqmH{0AaBx zTEdnX9&@Yc_|VaZ)d0f0H(5avH=o5^4xN4H%CHi1J(sApP-Z?$z+d8XUZ_7EzJd9( zwD>c()M$8Gz}M%^cBy!8E>HQ7rRQNS6;?K?)7$Va-`cLLO}dRXFVN|-UnUywaSgv_ zuHLg~T^0MjSp~APva+(Wva+(Wva+(Wva+(Wva;%+f9z~*#L!c=P5=M^07*qoM6N<$ Ef`xT#761SM literal 0 HcmV?d00001