diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8b32e7b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# Declare files that always have LF line endings on checkout +* text eol=lf + +# Denote all files that are truly binary and should not be modified +*.bin binary +*.heif binary +*.heic binary +*.hif binary +*.avif binary +*.png binary +*.gif binary +*.webp binary +*.tiff binary +*.jpeg binary +*.jpg binary diff --git a/.github/workflows/docs-check.yml b/.github/workflows/docs-check.yml new file mode 100644 index 0000000..9901978 --- /dev/null +++ b/.github/workflows/docs-check.yml @@ -0,0 +1,23 @@ +name: Docs check +on: + pull_request: + +permissions: + contents: read + +jobs: + build_docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install Docs dependencies + run: python3 -m pip install -r requirements.txt + + - name: Build and push Docs + run: | + make html SPHINXOPTS="-W" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..15cc784 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,46 @@ +name: Docs +on: + push: + branches: [ main ] + +permissions: + contents: read + +jobs: + build_push_docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install Docs dependencies + run: python3 -m pip install -r requirements.txt + + - name: Zip the flows folder + run: zip -r flows.zip flows -x "flows/models_catalog.json" + + - name: Build and push Docs + run: | + export CHANGES_DATE=`date -d"@$(git log -1 --pretty=%ct)" --iso-8601=seconds` + make html + git config --global user.name bigcat88 + git config --global user.email "bigcat88@users.noreply.github.com" + docroot=`mktemp -d` + rsync -av "docs/_build/html/" "${docroot}/" + rsync -av "flows.zip" "${docroot}/" + rsync -av "flows/models_catalog.json" "${docroot}/" + pushd "${docroot}" + git init + git remote add deploy "https://token:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" + git checkout -b gh-pages + touch .nojekyll + git add . + msg="Docs: commit ${GITHUB_SHA} made on ${CHANGES_DATE} from ${GITHUB_REF} by ${GITHUB_ACTOR}" + git commit -am "${msg}" + git push deploy gh-pages --force + popd + env: + GITHUB_TOKEN: ${{ secrets.TOKEN_DOCS }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2aa91f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,104 @@ +.DS_Store +node_modules/ +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln + +.marginalia + +/js/ +build/ +coverage/ +vendor +.php-cs-fixer.cache +.phpunit.result.cache + +/out +/dev/ +local +tmp +.phpdoc +clover.unit.xml +clover.integration.xml +proto/thrift/gen-* + +# Python Part + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# Pycharm settings +.idea/ + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Distribution / packaging +.Python +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST +converted/ + +geckodriver.log + +vix_backend +vix_flows +vix_models +vix_tasks_files +vix_worker_tasks_files +scripts/visionatrix +tasks_history.db +/flows.zip diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9134b71 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,8 @@ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace + - id: mixed-line-ending diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..bcf8329 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,14 @@ +Here is an inevitably incomplete list of MUCH-APPRECIATED CONTRIBUTORS -- +people who have submitted new Visionatrix or ComfyUI workflows, reported bugs, helped +answer newbie questions, and generally made Visionatrix project that much better: + + Andrey Borysenko + Alexander Piskun + + +A big THANK YOU goes to: + + All ComfyUI community. + All Python community. + + Guido van Rossum for creating Python. diff --git a/README.md b/README.md index c4505ee..9000ae5 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -# Flows -Visionatrix Workflows and documentation +# Visionatrix Flows and Documentation Repository + +The Visionatrix documentation, as well as the workflows sources, have been moved from the main repository to this one. diff --git a/docs/CommandLineOptions.rst b/docs/CommandLineOptions.rst new file mode 100644 index 0000000..78e48c6 --- /dev/null +++ b/docs/CommandLineOptions.rst @@ -0,0 +1,101 @@ +Command Line Options +==================== + +Most of the options supported by `ComfyUI` are supported. + +They can be specified when starting manually: + +.. code-block:: shell + + python3 -m visionatrix run --ui --use-split-cross-attention --disable-smart-memory + +Here are the list of the supported options command line options related to `Visionatrix` for **run** command: + + --backend_dir BACKEND_DIR + Directory for the backend(folder with ComfyUI) + Default: ``vix_backend`` + --flows_dir FLOWS_DIR + Directory for the flows + Default: ``vix_flows`` + --models_dir MODELS_DIR + Directory for the models + Default: ```vix_models`` + --tasks_files_dir TASKS_FILES_DIR + Directory for input/output files + Default: ``vix_task_files`` + --host HOST Host to be used by Visionatrix + --port PORT Port to be used by Visionatrix + --ui Flag to enable User interface(JS frontend). + +Supported **ComfyUI** options +----------------------------- + + --cuda-device DEVICE_ID + Set the id of the cuda device this instance will use. + --cuda-malloc Enable cudaMallocAsync (enabled by default for torch + 2.0 and up). + --disable-cuda-malloc + Disable cudaMallocAsync. + --force-fp32 Force fp32 (If this makes your GPU work better please report it). + --force-fp16 Force fp16. + --bf16-unet Run the UNET in bf16. This should only be used for + testing stuff. + --fp16-unet Store unet weights in fp16. + --fp8_e4m3fn-unet Store unet weights in fp8_e4m3fn. + --fp8_e5m2-unet Store unet weights in fp8_e5m2. + --fp16-vae Run the VAE in fp16, might cause black images. + --fp32-vae Run the VAE in full precision fp32. + --bf16-vae Run the VAE in bf16. + --cpu-vae Run the VAE on the CPU. + --fp8_e4m3fn-text-enc + Store text encoder weights in fp8 (e4m3fn variant). + --fp8_e5m2-text-enc Store text encoder weights in fp8 (e5m2 variant). + --fp16-text-enc Store text encoder weights in fp16. + --fp32-text-enc Store text encoder weights in fp32. + --disable-ipex-optimize + Disables ipex.optimize when loading models with Intel GPUs. + --use-split-cross-attention + Use the split cross attention optimization. Ignored when xformers is used. + --use-quad-cross-attention + Use the sub-quadratic cross attention optimization. Ignored when xformers is used. + --use-pytorch-cross-attention + Use the new pytorch 2.0 cross attention function. + --disable-xformers Disable xformers. + + --force-upcast-attention + Force enable attention upcasting, please report if it fixes black images. + --dont-upcast-attention + Disable all upcasting of attention. Should be unnecessary except for debugging. + + --gpu-only Store and run everything (text encoders/CLIP models, + etc... on the GPU). + --highvram By default models will be unloaded to CPU memory after + being used. This option keeps them in GPU memory. + --normalvram Used to force normal vram use if lowvram gets + automatically enabled. + --lowvram Split the unet in parts to use less vram. + --novram When lowvram isn't enough. + --cpu To use the CPU for everything (slow). + --disable-smart-memory + Force ComfyUI to aggressively offload to regular ram + instead of keeping models in vram when it can. + +Additional commands +------------------- + +install-flow +'''''''''''' + +Can be used for Workers that do not have a user interface. + +.. code-block:: shell + + python3 -m visionatrix install-flow --directory path_to_folder + +Folder should contain ``flow.json`` and ``flow_comfy.json`` + +.. code-block:: shell + + python3 -m visionatrix install-flow --name photo_stickers + +This will install flow by it's ``ID`` which is equal to it's folder name `here `_ diff --git a/docs/Flows/ComicuPortrait.rst b/docs/Flows/ComicuPortrait.rst new file mode 100644 index 0000000..758c73e --- /dev/null +++ b/docs/Flows/ComicuPortrait.rst @@ -0,0 +1,35 @@ +.. _ComicuPortrait: + +ComicU Anime Portrait +===================== + +Create an anime(sketch by default) image from a photo of a person. + +**Prompt** is optional, something like emotions can be used there: *smile, sad, serious, etc*. + +.. note:: *If you ticked the "Disable Simple style" you can try add something like* **line-sketch** *to the prompt.* + +Part of the flow runs on the CPU, part on the GPU, the flow is quite fast and convenient for everyday use. + +Hardware +"""""""" + +- **Required memory: 8-10 GB** + +Time to process 1 image: + +- AMD 7900 XTX/Intel 10900: **21 sec** +- NVIDIA RTX 3060 (12 GB)/AMD 7900X: **28 sec** + +Examples +"""""""" + +.. note:: As a input files, the photos of `Bruce Lee` and `Shakira` were taken from the Internet and used. + +.. image:: /FlowsResults/ComicuPortrait_1.png + +.. image:: /FlowsResults/ComicuPortrait_2.png + +.. image:: /FlowsResults/ComicuPortrait_3.png + +.. image:: /FlowsResults/ComicuPortrait_4.png diff --git a/docs/Flows/GhibliPortrait.rst b/docs/Flows/GhibliPortrait.rst new file mode 100644 index 0000000..73cd742 --- /dev/null +++ b/docs/Flows/GhibliPortrait.rst @@ -0,0 +1,33 @@ +.. _GhibliPortrait: + +Ghibli Studio Portrait +====================== + +Create an anime image from a person photo. + +**Prompt** is optional, something like emotions can be used there: *smile, sad, serious, etc*. + +Part of the flow runs on the CPU, part on the GPU, the flow is quite fast and convenient for everyday use. + +Hardware +"""""""" + +- **Required memory: 8-10 GB** + +Time to process 1 image: + +- AMD 7900 XTX/Intel 10900: **19 sec** +- NVIDIA RTX 3060 (12 GB)/AMD 7900X: **29 sec** + +Examples +"""""""" + +.. note:: As a input files, the photos of `Bruce Lee` and `Shakira` were taken from the Internet and used. + +.. image:: /FlowsResults/GhibliPortrait_1.png + +.. image:: /FlowsResults/GhibliPortrait_2.png + +.. image:: /FlowsResults/GhibliPortrait_3.png + +.. image:: /FlowsResults/GhibliPortrait_4.png diff --git a/docs/Flows/Juggernaut_Lite.rst b/docs/Flows/Juggernaut_Lite.rst new file mode 100644 index 0000000..a80582d --- /dev/null +++ b/docs/Flows/Juggernaut_Lite.rst @@ -0,0 +1,36 @@ +.. _Juggernaut_Lite: + +Juggernaut Lite +=============== + +This flow is most suitable for generating people quickly and realistically. + +Although it sometimes has problems with eyes or hands, in most cases the quality is quite acceptable. + +**Supports various aspect ratios.** + +Hardware +"""""""" + +- **Required memory: works on 10 GB** + +Time to generate 1 image: + +- AMD 7900 XTX: **10.8 sec** +- NVIDIA RTX 3060 (12 GB): **23 sec** +- Apple M2 Max: **35 sec** + +Examples +"""""""" + +.. image:: /FlowsResults/Juggernaut_Lite_1.png + +Prompt: "*portrait of hero wearing cuirass sitting on the chair, high details, photo realistic*" (seed: 2) + +.. image:: /FlowsResults/Juggernaut_Lite_2.png + +Prompt: "*portrait of elf man in obsidian armor looking at viewer from the dark, contrast, high details*" (seed: 1) + +.. image:: /FlowsResults/Juggernaut_Lite_3.png + +Prompt: "*portrait rage tiger*" (seed: 2) diff --git a/docs/Flows/Juggernaut_XL.rst b/docs/Flows/Juggernaut_XL.rst new file mode 100644 index 0000000..4a73b2a --- /dev/null +++ b/docs/Flows/Juggernaut_XL.rst @@ -0,0 +1,40 @@ +.. _Juggernaut_XL: + +Juggernaut XL +============= + +A fairly simple flow at the moment, simply using the latest **Juggernaut X** model without any post-processing. + +.. note:: **Not Safe for Work (NSFW) version.** + +Prompting information can be found here: `Juggernaut-X prompting `_ + +**Supports various aspect ratios.** + +**Supports fast generation using the Align Steps technique** + +Hardware +"""""""" + +- **Required memory: works on 10 GB** + +Time to generate 1 image: + +- AMD 7900 XTX: **15.8 sec** / **6.7 sec** +- NVIDIA RTX 3060 (12 GB): **35 sec** / **13.5 sec** +- Apple M2 Max: **93 sec** / **39 sec** + +Examples +"""""""" + +.. image:: /FlowsResults/Juggernaut_XL_1.png + +Prompt: "*close portrait of hero wearing cuirass sitting on the chair, high details*" (seed: 2) + +.. image:: /FlowsResults/Juggernaut_XL_2.png + +Prompt: "*portrait of elf man in obsidian armor looking at viewer from the dark, contrast, high details*" (seed: 1) + +.. image:: /FlowsResults/Juggernaut_XL_3.png + +Prompt: "*portrait rage tiger, high resolution*" (seed: 3) diff --git a/docs/Flows/MemojiPortrait.rst b/docs/Flows/MemojiPortrait.rst new file mode 100644 index 0000000..4fa61ee --- /dev/null +++ b/docs/Flows/MemojiPortrait.rst @@ -0,0 +1,35 @@ +.. _MemojiPortrait: + +Memoji Portrait +=============== + +Create cute Memoji from a photo of a person. + +**Prompt** is required, simplest examples is: `cute girl` + +**Person's face pose** is optional. + +Part of the flow runs on the CPU, part on the GPU, the flow is quite fast and convenient for everyday use. + +Hardware +"""""""" + +- **Required memory: 8-10 GB** + +Time to process 1 image: + +- AMD 7900 XTX/Intel 10900: **14 sec** +- NVIDIA RTX 3060 (12 GB)/AMD 7900X: **? sec** + +Examples +"""""""" + +.. note:: As a input files, the photos of `Bruce Lee` and `Einstein` were taken from the Internet and used. + +.. image:: /FlowsResults/MemojiPortrait_1.png + +.. image:: /FlowsResults/MemojiPortrait_2.png + +.. image:: /FlowsResults/MemojiPortrait_3.png + +.. image:: /FlowsResults/MemojiPortrait_4.png diff --git a/docs/Flows/PhotoStickers.rst b/docs/Flows/PhotoStickers.rst new file mode 100644 index 0000000..0079e2e --- /dev/null +++ b/docs/Flows/PhotoStickers.rst @@ -0,0 +1,31 @@ +.. _PhotoStickers: + +Photo Stickers +============== + +Turns a photo into 4 anime stickers with different emotions. + +Part of the flow runs on the CPU, part on the GPU, the flow is quite fast and convenient for everyday use. + +Hardware +"""""""" + +- **Required memory: 8 GB** + +Time to process 1 image: + +- AMD 7900 XTX/Intel 10900: **50 sec** +- NVIDIA RTX 3060 (12 GB)/AMD 7900X: **47 sec** + +Examples +"""""""" + +.. note:: As a input file, the photo of `Bruce Lee` was taken from the Internet and used. + +.. image:: /FlowsResults/PhotoStickers_1.png + +.. image:: /FlowsResults/PhotoStickers_2.png + +.. image:: /FlowsResults/PhotoStickers_3.png + +.. image:: /FlowsResults/PhotoStickers_4.png diff --git a/docs/Flows/Photomaker_1.rst b/docs/Flows/Photomaker_1.rst new file mode 100644 index 0000000..befedc5 --- /dev/null +++ b/docs/Flows/Photomaker_1.rst @@ -0,0 +1,43 @@ +.. _Photomaker_1: + +Photomaker +========== + +Creates fairly good and realistic images of a person in different styles based on one photo. +The person's face in the incoming image should preferably occupy most of the screen. + +*Advanced parameter `Accuracy` currently applies only to one result image.* + +.. note:: **Recommended words to be present in the prompt**: `woman`/`girl`/`man`/`boy` + +Hardware +"""""""" + +- **Required memory: 10-11 GB** + +Time to generate 1 image: + +- AMD 7900 XTX: **18.5 sec** +- NVIDIA RTX 3060(12 GB):**27.1 sec** +- Apple M2 Max: **80 sec** + +Examples +"""""""" + +.. note:: The image of `Bruce Lee` was taken from the Internet and used as a basis for first two prompts, + for the third prompt `Erin Starlight` photo was used. + +.. image:: /FlowsResults/Photomaker_1_1_1.png +.. image:: /FlowsResults/Photomaker_1_1_2.png + +Prompt: "*portrait of man photomaker in green suite with dragons*" Style: Cinematic (seed: 2) + +.. image:: /FlowsResults/Photomaker_1_2_1.png +.. image:: /FlowsResults/Photomaker_1_2_2.png + +*Prompt: "*portrait of man photomaker looking at viewer from the dark, fire and flames*" Style: Neonpunk (seed: 3) + +.. image:: /FlowsResults/Photomaker_1_3_1.png +.. image:: /FlowsResults/Photomaker_1_3_2.png + +Prompt: "*portrait of woman photomaker wearing suite in the forest looking at viewer*" Style: Comic book (seed: 4) diff --git a/docs/Flows/Playground_2_5_aesthetic.rst b/docs/Flows/Playground_2_5_aesthetic.rst new file mode 100644 index 0000000..24e7de7 --- /dev/null +++ b/docs/Flows/Playground_2_5_aesthetic.rst @@ -0,0 +1,49 @@ +.. _Playground_2_5_aesthetic: + +Aesthetic images(Playground 2.5) +================================ + +The flow focuses on three key improvements: enhancing color and contrast, generating images across multiple aspect ratios, and aligning outputs with human aesthetic preferences. + + +It demonstrates superior performance over previous models and commercial systems in terms of aesthetic quality, especially in generating vibrant colors, accommodating different aspect ratios, and capturing fine details in human-centric images. + + +Playground v2.5 outperforms widely-used models and even some closed-source systems in user studies focusing on aesthetic preferences. + +**Supports various aspect ratios.** + +**Supports fast generation using the Align Steps technique** + +Hardware +"""""""" + +- **Required memory: works on 10 GB** + +Time to generate 1 image: + +- AMD 7900 XTX: **17.5 sec** (no face) / **29 sec** (one face) +- NVIDIA RTX 3060 (12 GB): **33 sec** (no face) / **46 sec** (one face) +- Apple M2 Max: **99.8 sec** (no face) / **160 sec** (one face) + +.. note:: Results may vary, as FaceDetailer will post-process image only if it detects face. + +Examples +"""""""" + +.. note:: *On the right is an image with the "fast run" option* + +.. image:: /FlowsResults/Playground_2_5_aesthetic_1.png +.. image:: /FlowsResults/Playground_2_5_aesthetic_1-fast.png + +Prompt: "*girl in suite looking at viewer, high quality, 8k, bright colors*" (seed: 5) + +.. image:: /FlowsResults/Playground_2_5_aesthetic_2.png +.. image:: /FlowsResults/Playground_2_5_aesthetic_2-fast.png + +Prompt: "*cat in suite looking at viewer, high quality, 8k, bright colors*" (seed: 5) + +.. image:: /FlowsResults/Playground_2_5_aesthetic_3.png +.. image:: /FlowsResults/Playground_2_5_aesthetic_3-fast.png + +Prompt: "*Dragon in forest, vivid colors*" (seed: 3) diff --git a/docs/Flows/SDXL_Lighting.rst b/docs/Flows/SDXL_Lighting.rst new file mode 100644 index 0000000..5d0da3b --- /dev/null +++ b/docs/Flows/SDXL_Lighting.rst @@ -0,0 +1,32 @@ +.. _SDXL_Lighting: + +SDXL Lighting +============= + +SDXL-Lightning is a fast text-to-image generation model. It can generate high-quality 1024px images in a few steps. + +Hardware +"""""""" + +- **Required memory: 6-7 GB** + +Time to generate 1 image(8 steps): + +- AMD 7900 XTX: **2.3 sec** +- NVIDIA RTX 3060 (12 GB): **3.4 sec** +- Apple M2 Max: **9.7 sec** + +Examples +"""""""" + +.. image:: /FlowsResults/SDXL_Lighting_8_1.png + +Prompt: "*A girl smiling*" (seed: 2) + +.. image:: /FlowsResults/SDXL_Lighting_8_2.png + +Prompt: "*lighting hero, anime*" (seed: 120) + +.. image:: /FlowsResults/SDXL_Lighting_8_3.png + +Prompt: "*portrait angry bear looking at viewer, vivid colours*" (seed: 124) diff --git a/docs/Flows/Stable_Cascade.rst b/docs/Flows/Stable_Cascade.rst new file mode 100644 index 0000000..c24f79c --- /dev/null +++ b/docs/Flows/Stable_Cascade.rst @@ -0,0 +1,39 @@ +.. _Stable_Cascade: + +Stable Cascade +============== + +This flow works much better with text rendering, and supports repeated rendering to generate images in increased resolution with more detail. + +Suitable for various fairy-tale or cartoon images or for generating postcards. + +One pass image resolution: **1024x576** + +Two pass image resolution: **1536x864** + +Three pass image resolution: **2048x1152** + +Hardware +"""""""" + +- **Required memory: 8-12 GB** + +Time to generate 1 image: + +- AMD 7900 XTX: **11.8 sec** / **36 sec** (2 pass) +- NVIDIA RTX 3060 (12 GB): **17 sec** / **49 sec** (2 pass) + +Examples +"""""""" + +.. image:: /FlowsResults/Stable_Cascade_1.png + +Prompt: "*portrait of bee, high details, 8k, vivid colors, contrast light*" (seed: 2) + +.. image:: /FlowsResults/Stable_Cascade_2.png + +Prompt: "*dolphin at sea, dawn, high details, 8k, vivid colors, contrast light*" Second Pass: false (seed: 2) + +.. image:: /FlowsResults/Stable_Cascade_3.png + +Prompt: "*girl with sign 'Cascade', high details, 8k, cinematic*" (seed: 3) diff --git a/docs/Flows/SupirUpscaler.rst b/docs/Flows/SupirUpscaler.rst new file mode 100644 index 0000000..f34cc12 --- /dev/null +++ b/docs/Flows/SupirUpscaler.rst @@ -0,0 +1,53 @@ +.. _SupirUpscaler: + +SUPIR Upscaler +============== + +*This workflow is added mostly for research purposes, it is still in development.* + +**Memory requirements(both VRAM and RAM) are directly related to the input image resolution.** + +.. note:: Currently for `macOS runners` `Diffusion type` must be set to `fp32`. + +.. note:: Low memory mode: reduces the size of processed tiles to **256**. + +.. note:: If you have a very small input image and the result is **less than 1024** (512 for low memory mode) pixels in width **or** height, **tiles should be disabled**. + +From `ComfyUI-SUPIR repo `_: + +`Memory requirements are directly related to the input image resolution. In my testing I was able to run 512x512 to 1024x1024 with a 10GB 3080 GPU, and other tests on 24GB GPU to up 3072x3072. System RAM requirements are also hefty, don't know numbers but I would guess under 32GB is going to have issues, tested with 64GB.` + +Hardware +"""""""" + +- **Minimum: 12 GB VRAM , 32 GB RAM** +- **Recommended: 16-24 GB VRAM, 64 GB RAM** + +*We will not describe the specific time it takes for scaling, because... the flow is still in development and we are constantly trying to improve it.* + +Examples +"""""""" + +*This Upscaler is still in development stage, results may be get better.* + +We specifically place one portrait example where results is not perfect. + +But for many tests we performed - portrait scaling is shiny compared to older scaling methods. + +Image of a classic car: + +.. image:: /FlowsResults/SupirUpscaler-classic-car-1024x683.jpg + +.. image:: /FlowsResults/SupirUpscaler-classic-car-result.png + +Jackie Chan portrait: + +.. image:: /FlowsResults/SupirUpscaler-jackie-chan-787x761.jpg + +.. image:: /FlowsResults/SupirUpscaler-jackie-chan-result.png + +Shakira: + +.. image:: /FlowsResults/SupirUpscaler-shakira-711x474.jpeg + +.. image:: /FlowsResults/SupirUpscaler-shakira-result.png diff --git a/docs/Flows/VintagePortrait.rst b/docs/Flows/VintagePortrait.rst new file mode 100644 index 0000000..73da1ae --- /dev/null +++ b/docs/Flows/VintagePortrait.rst @@ -0,0 +1,35 @@ +.. _VintagePortrait: + +Vintage Portrait +================ + +Create a vintage 20th century portrait from a photo of a person. + +**Prompt** is required, simplest examples is: `portrait of a girl, cinematic, masterpiece` + +**Person's face pose** is optional. + +Part of the flow runs on the CPU, part on the GPU, the flow is quite fast and convenient for everyday use. + +Hardware +"""""""" + +- **Required memory: 8-10 GB** + +Time to process 1 image: + +- AMD 7900 XTX/Intel 10900: **33 sec** +- NVIDIA RTX 3060 (12 GB)/AMD 7900X: **56 sec** + +Examples +"""""""" + +.. note:: As a input files, the photos of `Bruce Lee` and `Shakira` were taken from the Internet and used. + +.. image:: /FlowsResults/VintagePortrait_1.png + +.. image:: /FlowsResults/VintagePortrait_2.png + +.. image:: /FlowsResults/VintagePortrait_3.png + +.. image:: /FlowsResults/VintagePortrait_4.png diff --git a/docs/Flows/index.rst b/docs/Flows/index.rst new file mode 100644 index 0000000..81fb226 --- /dev/null +++ b/docs/Flows/index.rst @@ -0,0 +1,18 @@ +Available Flows +=============== + +.. toctree:: + :maxdepth: 1 + + SDXL_Lighting + Playground_2_5_aesthetic + Juggernaut_Lite + Juggernaut_XL + Stable_Cascade + VintagePortrait + Photomaker_1 + PhotoStickers + GhibliPortrait + ComicuPortrait + MemojiPortrait + SupirUpscaler diff --git a/docs/FlowsResults/ComicuPortrait_1.png b/docs/FlowsResults/ComicuPortrait_1.png new file mode 100644 index 0000000..0e0cd2c Binary files /dev/null and b/docs/FlowsResults/ComicuPortrait_1.png differ diff --git a/docs/FlowsResults/ComicuPortrait_2.png b/docs/FlowsResults/ComicuPortrait_2.png new file mode 100644 index 0000000..186d217 Binary files /dev/null and b/docs/FlowsResults/ComicuPortrait_2.png differ diff --git a/docs/FlowsResults/ComicuPortrait_3.png b/docs/FlowsResults/ComicuPortrait_3.png new file mode 100644 index 0000000..9f152af Binary files /dev/null and b/docs/FlowsResults/ComicuPortrait_3.png differ diff --git a/docs/FlowsResults/ComicuPortrait_4.png b/docs/FlowsResults/ComicuPortrait_4.png new file mode 100644 index 0000000..eafcda9 Binary files /dev/null and b/docs/FlowsResults/ComicuPortrait_4.png differ diff --git a/docs/FlowsResults/GhibliPortrait_1.png b/docs/FlowsResults/GhibliPortrait_1.png new file mode 100644 index 0000000..b3fac5c Binary files /dev/null and b/docs/FlowsResults/GhibliPortrait_1.png differ diff --git a/docs/FlowsResults/GhibliPortrait_2.png b/docs/FlowsResults/GhibliPortrait_2.png new file mode 100644 index 0000000..8c46b62 Binary files /dev/null and b/docs/FlowsResults/GhibliPortrait_2.png differ diff --git a/docs/FlowsResults/GhibliPortrait_3.png b/docs/FlowsResults/GhibliPortrait_3.png new file mode 100644 index 0000000..df41e0f Binary files /dev/null and b/docs/FlowsResults/GhibliPortrait_3.png differ diff --git a/docs/FlowsResults/GhibliPortrait_4.png b/docs/FlowsResults/GhibliPortrait_4.png new file mode 100644 index 0000000..d017e0e Binary files /dev/null and b/docs/FlowsResults/GhibliPortrait_4.png differ diff --git a/docs/FlowsResults/Juggernaut_Lite_1.png b/docs/FlowsResults/Juggernaut_Lite_1.png new file mode 100644 index 0000000..07f6856 Binary files /dev/null and b/docs/FlowsResults/Juggernaut_Lite_1.png differ diff --git a/docs/FlowsResults/Juggernaut_Lite_2.png b/docs/FlowsResults/Juggernaut_Lite_2.png new file mode 100644 index 0000000..0ff790f Binary files /dev/null and b/docs/FlowsResults/Juggernaut_Lite_2.png differ diff --git a/docs/FlowsResults/Juggernaut_Lite_3.png b/docs/FlowsResults/Juggernaut_Lite_3.png new file mode 100644 index 0000000..da477b8 Binary files /dev/null and b/docs/FlowsResults/Juggernaut_Lite_3.png differ diff --git a/docs/FlowsResults/Juggernaut_XL_1.png b/docs/FlowsResults/Juggernaut_XL_1.png new file mode 100644 index 0000000..ab66e51 Binary files /dev/null and b/docs/FlowsResults/Juggernaut_XL_1.png differ diff --git a/docs/FlowsResults/Juggernaut_XL_2.png b/docs/FlowsResults/Juggernaut_XL_2.png new file mode 100644 index 0000000..d857636 Binary files /dev/null and b/docs/FlowsResults/Juggernaut_XL_2.png differ diff --git a/docs/FlowsResults/Juggernaut_XL_3.png b/docs/FlowsResults/Juggernaut_XL_3.png new file mode 100644 index 0000000..b5e5aa7 Binary files /dev/null and b/docs/FlowsResults/Juggernaut_XL_3.png differ diff --git a/docs/FlowsResults/MemojiPortrait_1.png b/docs/FlowsResults/MemojiPortrait_1.png new file mode 100644 index 0000000..71e55aa Binary files /dev/null and b/docs/FlowsResults/MemojiPortrait_1.png differ diff --git a/docs/FlowsResults/MemojiPortrait_2.png b/docs/FlowsResults/MemojiPortrait_2.png new file mode 100644 index 0000000..c214500 Binary files /dev/null and b/docs/FlowsResults/MemojiPortrait_2.png differ diff --git a/docs/FlowsResults/MemojiPortrait_3.png b/docs/FlowsResults/MemojiPortrait_3.png new file mode 100644 index 0000000..cc5ff24 Binary files /dev/null and b/docs/FlowsResults/MemojiPortrait_3.png differ diff --git a/docs/FlowsResults/MemojiPortrait_4.png b/docs/FlowsResults/MemojiPortrait_4.png new file mode 100644 index 0000000..16703cc Binary files /dev/null and b/docs/FlowsResults/MemojiPortrait_4.png differ diff --git a/docs/FlowsResults/PhotoStickers_1.png b/docs/FlowsResults/PhotoStickers_1.png new file mode 100644 index 0000000..6d0aa44 Binary files /dev/null and b/docs/FlowsResults/PhotoStickers_1.png differ diff --git a/docs/FlowsResults/PhotoStickers_2.png b/docs/FlowsResults/PhotoStickers_2.png new file mode 100644 index 0000000..23c7edd Binary files /dev/null and b/docs/FlowsResults/PhotoStickers_2.png differ diff --git a/docs/FlowsResults/PhotoStickers_3.png b/docs/FlowsResults/PhotoStickers_3.png new file mode 100644 index 0000000..bb5508c Binary files /dev/null and b/docs/FlowsResults/PhotoStickers_3.png differ diff --git a/docs/FlowsResults/PhotoStickers_4.png b/docs/FlowsResults/PhotoStickers_4.png new file mode 100644 index 0000000..e17976f Binary files /dev/null and b/docs/FlowsResults/PhotoStickers_4.png differ diff --git a/docs/FlowsResults/Photomaker_1_1_1.png b/docs/FlowsResults/Photomaker_1_1_1.png new file mode 100644 index 0000000..f90fab0 Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_1_1.png differ diff --git a/docs/FlowsResults/Photomaker_1_1_2.png b/docs/FlowsResults/Photomaker_1_1_2.png new file mode 100644 index 0000000..d031408 Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_1_2.png differ diff --git a/docs/FlowsResults/Photomaker_1_2_1.png b/docs/FlowsResults/Photomaker_1_2_1.png new file mode 100644 index 0000000..8fc72ba Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_2_1.png differ diff --git a/docs/FlowsResults/Photomaker_1_2_2.png b/docs/FlowsResults/Photomaker_1_2_2.png new file mode 100644 index 0000000..f42709c Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_2_2.png differ diff --git a/docs/FlowsResults/Photomaker_1_3_1.png b/docs/FlowsResults/Photomaker_1_3_1.png new file mode 100644 index 0000000..93df1a7 Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_3_1.png differ diff --git a/docs/FlowsResults/Photomaker_1_3_2.png b/docs/FlowsResults/Photomaker_1_3_2.png new file mode 100644 index 0000000..f7467b6 Binary files /dev/null and b/docs/FlowsResults/Photomaker_1_3_2.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_1-fast.png b/docs/FlowsResults/Playground_2_5_aesthetic_1-fast.png new file mode 100644 index 0000000..7c1782f Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_1-fast.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_1.png b/docs/FlowsResults/Playground_2_5_aesthetic_1.png new file mode 100644 index 0000000..0eebb6e Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_1.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_2-fast.png b/docs/FlowsResults/Playground_2_5_aesthetic_2-fast.png new file mode 100644 index 0000000..3462695 Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_2-fast.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_2.png b/docs/FlowsResults/Playground_2_5_aesthetic_2.png new file mode 100644 index 0000000..691a634 Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_2.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_3-fast.png b/docs/FlowsResults/Playground_2_5_aesthetic_3-fast.png new file mode 100644 index 0000000..f38d973 Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_3-fast.png differ diff --git a/docs/FlowsResults/Playground_2_5_aesthetic_3.png b/docs/FlowsResults/Playground_2_5_aesthetic_3.png new file mode 100644 index 0000000..6c00667 Binary files /dev/null and b/docs/FlowsResults/Playground_2_5_aesthetic_3.png differ diff --git a/docs/FlowsResults/SDXL_Lighting_8_1.png b/docs/FlowsResults/SDXL_Lighting_8_1.png new file mode 100644 index 0000000..2ec2c58 Binary files /dev/null and b/docs/FlowsResults/SDXL_Lighting_8_1.png differ diff --git a/docs/FlowsResults/SDXL_Lighting_8_2.png b/docs/FlowsResults/SDXL_Lighting_8_2.png new file mode 100644 index 0000000..112780b Binary files /dev/null and b/docs/FlowsResults/SDXL_Lighting_8_2.png differ diff --git a/docs/FlowsResults/SDXL_Lighting_8_3.png b/docs/FlowsResults/SDXL_Lighting_8_3.png new file mode 100644 index 0000000..638e835 Binary files /dev/null and b/docs/FlowsResults/SDXL_Lighting_8_3.png differ diff --git a/docs/FlowsResults/Stable_Cascade_1.png b/docs/FlowsResults/Stable_Cascade_1.png new file mode 100644 index 0000000..f9a22f3 Binary files /dev/null and b/docs/FlowsResults/Stable_Cascade_1.png differ diff --git a/docs/FlowsResults/Stable_Cascade_2.png b/docs/FlowsResults/Stable_Cascade_2.png new file mode 100644 index 0000000..18fda6f Binary files /dev/null and b/docs/FlowsResults/Stable_Cascade_2.png differ diff --git a/docs/FlowsResults/Stable_Cascade_3.png b/docs/FlowsResults/Stable_Cascade_3.png new file mode 100644 index 0000000..d4283d1 Binary files /dev/null and b/docs/FlowsResults/Stable_Cascade_3.png differ diff --git a/docs/FlowsResults/SupirUpscaler-classic-car-1024x683.jpg b/docs/FlowsResults/SupirUpscaler-classic-car-1024x683.jpg new file mode 100644 index 0000000..e95d6b3 Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-classic-car-1024x683.jpg differ diff --git a/docs/FlowsResults/SupirUpscaler-classic-car-result.png b/docs/FlowsResults/SupirUpscaler-classic-car-result.png new file mode 100644 index 0000000..f2fc6dc Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-classic-car-result.png differ diff --git a/docs/FlowsResults/SupirUpscaler-jackie-chan-787x761.jpg b/docs/FlowsResults/SupirUpscaler-jackie-chan-787x761.jpg new file mode 100644 index 0000000..7a03899 Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-jackie-chan-787x761.jpg differ diff --git a/docs/FlowsResults/SupirUpscaler-jackie-chan-result.png b/docs/FlowsResults/SupirUpscaler-jackie-chan-result.png new file mode 100644 index 0000000..302340e Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-jackie-chan-result.png differ diff --git a/docs/FlowsResults/SupirUpscaler-shakira-711x474.jpeg b/docs/FlowsResults/SupirUpscaler-shakira-711x474.jpeg new file mode 100644 index 0000000..2b4689a Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-shakira-711x474.jpeg differ diff --git a/docs/FlowsResults/SupirUpscaler-shakira-result.png b/docs/FlowsResults/SupirUpscaler-shakira-result.png new file mode 100644 index 0000000..4c8b9f5 Binary files /dev/null and b/docs/FlowsResults/SupirUpscaler-shakira-result.png differ diff --git a/docs/FlowsResults/VintagePortrait_1.png b/docs/FlowsResults/VintagePortrait_1.png new file mode 100644 index 0000000..39df235 Binary files /dev/null and b/docs/FlowsResults/VintagePortrait_1.png differ diff --git a/docs/FlowsResults/VintagePortrait_2.png b/docs/FlowsResults/VintagePortrait_2.png new file mode 100644 index 0000000..e71f6df Binary files /dev/null and b/docs/FlowsResults/VintagePortrait_2.png differ diff --git a/docs/FlowsResults/VintagePortrait_3.png b/docs/FlowsResults/VintagePortrait_3.png new file mode 100644 index 0000000..b51e65b Binary files /dev/null and b/docs/FlowsResults/VintagePortrait_3.png differ diff --git a/docs/FlowsResults/VintagePortrait_4.png b/docs/FlowsResults/VintagePortrait_4.png new file mode 100644 index 0000000..1d23b4c Binary files /dev/null and b/docs/FlowsResults/VintagePortrait_4.png differ diff --git a/docs/Installation.rst b/docs/Installation.rst new file mode 100644 index 0000000..9732eed --- /dev/null +++ b/docs/Installation.rst @@ -0,0 +1,90 @@ +Manual Installation +=================== + +In most cases, we recommend using automatic installation via an ``easy-install`` script. + +For those who want to install everything manually, here you will find step-by-step instructions on what the script does. + +Virtual Environment creation +"""""""""""""""""""""""""""" + +First clone the repository with :command:`git`:: + + git clone https://github.com/Visionatrix/Visionatrix.git && cd Visionatrix + + +Setup the virtual environment with :command:`python`:: + + python -m venv venv + + +Activate Virtual Environment(**Linux/macOS**) with :command:`source`:: + + source venv/bin/activate + + +Activate Virtual Environment(**Windows**) with :command:`powershell`:: + + .\venv\Scripts\Activate.ps1 + + +**PyTorch** installation +"""""""""""""""""""""""" + +.. note:: + On macOS with Apple Silicon currently no action is needed. + +For AMD graphic cards on **Linux** install **ROCM** version of PyTorch using :command:`pip`:: + + pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/rocm6.0 + + +--------- + +For AMD graphics cards on **Windows** install PyTorch with DirectML support using :command:`pip`:: + + pip install torch-directml + + +.. note:: + **Python3.10** is the only currently supported version by **torch-directml**. + +--------- + +For NVIDIA graphics cards on **both Linux or Windows** install PyTorch using :command:`pip`:: + + pip install torch torchvision torchaudio + + +Install Visionatrix +""""""""""""""""""" + +Install Visionatrix from the previously cloned sources using :command:`pip`:: + + pip install . + + +Run **Visionatrix** initialization command using :command:`python`:: + + python -m visionatrix install + + +Run Visionatrix +""""""""""""""" + +Execute from the activated virtual environment **run** command using :command:`python`:: + + python -m visionatrix run --ui + + +Manual Update +""""""""""""" + +1. Pull last changes from repository with :command:`git`:: + + git pull + + +2. Execute **update** command from **activated** virtual environment with :command:`python`:: + + python -m visionatrix update diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..c078295 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,29 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +PYTHON = python3 +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SOURCEDIR = . +BUILDDIR = _build +LINKCHECKDIR = _build/linkcheck + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +github: + @make html + @cp -a build/html/. ./docs + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: links +links: + @$(SPHINXBUILD) -b linkcheck "$(SOURCEDIR)" "$(LINKCHECKDIR)" $(ALLSPHINXOPTS) diff --git a/docs/TechnicalInformation.rst b/docs/TechnicalInformation.rst new file mode 100644 index 0000000..e9a1ca6 --- /dev/null +++ b/docs/TechnicalInformation.rst @@ -0,0 +1,21 @@ +Technical Information +===================== + +Currently installed ComfyUI nodes: + + * `ComfyUI-Impact-Pack `_ + * `ComfyUI_InstantID `_ + * `ComfyUI_IPAdapter_plus `_ + * `efficiency-nodes-comfyui `_ + * `ComfyUI_UltimateSDUpscale `_ + * `ComfyUI-WD14-Tagger `_ + * `ComfyUI-SUPIR `_ + * `ComfyUI_essentials `_ + * `ComfyUI-Custom-Scripts `_ + * `rgthree-comfy `_ + * `comfyui_controlnet_aux `_ + * `ComfyUI-AutomaticCFG `_ + +We are gradually expanding the list. +The main reason many components are missing is that they are quite difficult to install and we take the position +that an easy installation process is more important in most cases. diff --git a/docs/VixWorkflows.rst b/docs/VixWorkflows.rst new file mode 100644 index 0000000..57d71dc --- /dev/null +++ b/docs/VixWorkflows.rst @@ -0,0 +1,243 @@ +Vix Workflows +============= + +Introduction +"""""""""""" + +ComfyUI workflows are designed for developers and those interested in diffusion processes. + +Visionatrix workflows are created on top of ComfyUI workflows for easy deployment and straightforward use. + +Currently, there are two main issues with using ComfyUI flows for the general public: + + 1. It's unclear where to get the model from and how to deploy/install it – a **deployment/installation issue** + 2. Without some experience, it's unclear how to just provide inputs to simple get results - a **usability issue** + +Automatic models mapping +"""""""""""""""""""""""" + +To address the first issue with model mapping, Visionatrix includes a `models_catalog.json `_ file. + +By default, it is taken and updated from the Visionatrix repository on GitHub, in case you add a new flow and need to add new model mappings you can change its path using an environment variable to a local file path. + +.. note:: + + We hope that after you add something locally, you will open a pull request so that the community can benefit from it. + +The file structure consists of a set of objects, each describing a ComfyUI Node class that loads or uses a model. + +.. code-block:: python + + "InstantID-ControlNet": { + "regexes": [ + { + "class_name": "ControlNetLoader", + "input_value": "^(?=.*(?i:instantid)).*" + } + ], + "save_path": "controlnet/instantid-controlnet.safetensors", + "url": "https://huggingface.co/InstantX/InstantID/resolve/main/ControlNetModel/diffusion_pytorch_model.safetensors", + "homepage": "https://huggingface.co/InstantX/InstantID", + "hash": "c8127be9f174101ebdafee9964d856b49b634435cf6daa396d3f593cf0bbbb05" + } + +"regexes" +''''''''' + +Regexes are used to understand the if this record related to the specified model from the ComfyUI workflow. + +``"input_name"``, ``"class_name"``, and ``"input_value"`` are supported, both together and separately. + +.. note:: + + If these conditions prove insufficient, please create an issue and we will find a solution together. + +"save_path" +''''''''''' + +Specifies where the model will be saved. +Default paths are relative to the root of the external models folder specified in the ComfyUI file `"extra_model_paths.yaml"` + +By default in Visionatrix, this is the path to the `"vix_models"` folder. + +If a Node does not support ComfyUI's model placement configurations and requires them to be located only in the ComfyUI folder, the entry may take the form: + +.. code-block:: + + save_path="{root}models/insightface/models/antelopev2.zip" + +"url" +''''' + +Indicates where to download the model from if it is not already present. + +It is preferable for the model to be hosted on Hugging Face, but "civitai.com" is also supported. + +"homepage" +'''''''''' + +An optional field with a link to the model's home page where you can view the license. + +"hash" +'''''' + +The SHA256 hash of the model. Used to verify the integrity of the model and check for download errors. + +Vix workflow overview +""""""""""""""""""""" + +Visionatrix workflows consist of two files: ``flow.json`` and ``flow_comfy.json`` + +The main purpose of a Vix Flow is to specify how to map incoming parameters to the ComfyUI workflow for the creation endpoint of a ComfyUI task. + +.. note:: + + The main difference between Visionatrix and ComfyUI: A task is created with a single request, which includes both incoming text parameters and input files. + +Consider the example of the VintagePortrait Vix flow: + +.. code-block:: json + + { + "name": "vintage_portrait", + "display_name": "Vintage Portrait", + "description": "Portrait photos in Vintage styles", + "author": "bigcat88", + "homepage": "https://github.com/bigcat88", + "license": "", + "documentation": "https://visionatrix.github.io/Visionatrix/Flows/VintagePortrait.html", + "input_params": [ + { + "name": "image", + "display_name": "Person's face", + "type": "image", + "optional": false, + "comfy_node_id": { + "37": { + "dest_field_name": ["inputs", "image"] + } + } + }, + { + "name": "prompt", + "display_name": "Prompt", + "type": "text", + "optional": false, + "advanced": false, + "comfy_node_id": { + "29": { + "dest_field_name": ["inputs", "positive"] + } + } + }, + { + "name": "pose", + "display_name": "Person's face pose", + "type": "image", + "optional": true, + "advanced": true, + "comfy_node_id": { + "44": { + "dest_field_name": ["inputs", "image"], + "node_connect": { + "node_id": "33", + "dest_field_name": ["inputs", "image_kps"] + } + } + } + } + ] + } + +"name" +'''''' + +The name of the workflow. It usually matches the name of the folder where the flow is stored. + +"display_name" +'''''''''''''' + +Used in the UI to display the name of the flow. + +"description" +''''''''''''' + +A brief description of the flow for user display. + +"author" +'''''''' + +The name of the ComfyUI flow author or the Visionatrix flow author. + +"homepage" +'''''''''' + +A link that will open when clicking on the flow author's name. + +"license" +''''''''' + +The general license under which the flow can be used (to simplify understanding whether it can be used behind the API service, whether it can be used commercially, etc.) + +"documentation" +''''''''''''''' + +Link to additional information about the flow. + +"input_params" +'''''''''''''' + +The most important part. Based on the information from this field, the Visionatrix UI dynamically displays the interface. + +The backend part fills in the ComfyUI workflow based on these data. + +Technically, this is a list of objects, where each object is one input parameter, which includes: + + * "name" - the key(used only when `"type"` is equal to `"text"`) + * "display_name" - the name of the parameter displayed in the UI + * "type" - a string that can have values: `"text"` or `"image"` + + .. note:: + `"video"` and `"audio"` types will be added as soon as there is the first Workflow requiring it. + + * "optional" - indicates whether the parameter is optional. If an optional field is not provided, the backend will fill it in automatically. + * "advanced" - used only in the UI, shows whether the field should be hidden by default (we do not want to overload the interface for regular users) + * "default" - the field value to initiate. + + .. note:: + Used for both UI and backend, but not mandatory even for optional fields (as in the ComfyUI flow, the Node value is still set) + + * "comfy_node_id" - a field only for the backend, which defines what to do with this value (where to use it in the ComfyUI Flow) + + +Create task based on Flow +""""""""""""""""""""""""" + + +.. code-block:: python + + @APP.post("/task") + async def task_run( + request: Request, + name: str = Form(description="Name of the flow from which the task should be created"), + count: int = Form(1, description="Number of tasks to be created"), + input_params: str = Form(None, description="List of input parameters as an encoded json string"), + files: list[UploadFile | str] = Form(None, description="List of input files for flow"), # noqa + ) -> TaskRunResults: + """ + Endpoint to initiate the creation and execution of tasks within the Vix workflow environment, + handling both file inputs and task-related parameters. + """ + pass + + +.. warning:: + + It's important to note that text parameters and files are passed in different parameters: + + * input_params - input parameters with "type" == "text" + * files - list of input files (files should be in the order they are defined in the Vix Flow) + +When this endpoint is called, a task will be created and queued for execution. + +*To be continued...* diff --git a/docs/WorkingModes.rst b/docs/WorkingModes.rst new file mode 100644 index 0000000..446573c --- /dev/null +++ b/docs/WorkingModes.rst @@ -0,0 +1,93 @@ +Working modes +============= + +DEFAULT +""""""" + +Visionatrix(**Vix**) consists of: + +1. A server component, namely, the backend `(in short - Server)` +2. A component responsible for processing tasks `(in short - Worker)` +3. TaskQueue - a database (SQLite *(default)*, MySQL/MariaDB, PgSQL) +4. A simple and understandable User Interface + +By default, Vix launches with all components integrated (Server + Worker + UI) for quick and easy use on a single computer. + +This is **DEFAULT** mode, in which everything is executed within a single process. + +Easy installation, no need to configure, just launch and use. + +.. note:: There is no support for multiple users or authentication in this case, as this mode uses **SQLite** as a database, which is limiting. + +SERVER +"""""" + +In most scenarios, including home use, you likely have more than one device capable of handling AI tasks. +In such cases, it is allowed and recommended to run the server part and the AI processing part of the task separately. + +.. warning:: **SQLite is not supported as a database in this mode.** + +Steps to run `Vix` in a Server mode: + +1. Set ``VIX_MODE`` environment variable to ``SERVER`` +2. Setup **PostgreSQL** *(recommended)* or **MariaDB** database and set correct ``DATABASE_URI`` environment variable to point on it. + + .. note:: `PgSQL example `_: ``DATABASE_URI="postgresql+psycopg://vix_user:vix_password@localhost:5432/vix_db"`` + + .. note:: For the `MySQL or MariaDB `_ to work you should additionally specify ``DATABASE_URI_ASYNC`` environment variable. + +3. Remove default ``admin`` user and create a new one with ``python3 -m visionatrix create-user`` command. + + .. note:: This step is only necessary if you plan to make the instance accessible from the Internet. + +4. Connect at least one Worker to handle task processing. + + +*We will provide a docker-compose file soon, with full server setup to deploy it in one click.* + +WORKER +"""""" + +Each worker can have a different set of tasks (Flows) installed, which is useful to avoid installing a task on a worker instance that cannot handle it. +A worker will only request the tasks installed for it. + +There is two worker modes, both will be described, we ourselves most use Vix in `Worker to Server` mode. + +Worker to Database-FS +''''''''''''''''''''' + +.. note:: Requirements: + + 1. The database used by the **Server** should be accessible for the worker. + 2. There should be the ability to map the **Server**'s ``vix_tasks_files`` folder to the worker. + +Set the environment variable ``VIX_MODE`` to **WORKER** and leave ``VIX_SERVER`` with an empty value; do not set it. + +In this scenario, the worker must be configured with the correct database path using the ``DATABASE_URI`` environment variable. +The format can be viewed here: `SqlAlchemy Database URLs `_ + +By using the ``TASKS_FILES_DIR`` environment variable or the ``--tasks_files_dir`` argument, you can change the location of the ``vix_tasks_files`` folder. +The worker must have access to the Server's ``vix_tasks_files`` folder. + +With this scaling method, workers independently retrieve tasks from the database and directly write the execution results to the servers *TASKS_FILES_DIR*. + +In this setup, you can imagine workers as Server threads operating remotely. + +Worker to Server +'''''''''''''''' + +This method implies that the workers do not have direct access to the database or the server file system. + +All communication occurs through the network, with workers accessing the server backend directly. + +Set the environment variable ``VIX_MODE`` to **WORKER** and set ``VIX_SERVER`` with the full address of the Server(including port number). + +.. note:: ``VIX_HOST``, ``VIX_PORT``, ``DATABASE_URI`` will be ignored, as the worker in this mode does not need it. + +In this use case, the **vix_tasks_files** directory will contain only temporary files; after uploading results to the Server, the results from the worker instance will be cleared. + +For authentication on the server worker will use ``WORKER_AUTH`` environment variable, which must contain "**USER_ID:PASSWORD**". + +.. note:: + + Workers with an administrator account can process all tasks of all users, workers assigned to a user account can only process tasks created by that user. diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..cc1a2c9 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,95 @@ +import os +import sys +import requests +import re +from datetime import datetime + +import sphinx_rtd_theme + +dir_path = os.path.dirname(os.path.realpath(__file__)) +sys.path.insert(0, os.path.abspath(dir_path + "/_ext")) +sys.path.insert(0, os.path.abspath("../.")) + +now = datetime.now() + +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.extlinks", + "sphinx.ext.intersphinx", + "sphinx.ext.viewcode", + "sphinx_copybutton", + "sphinx_inline_tabs", + "sphinx_issues", + "sphinx_rtd_theme", + "sphinxcontrib.autodoc_pydantic", +] + +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), +} + +autodoc_pydantic_model_show_json = False + +# General information about the project. +project = "Visionatrix" +copyright = str(now.year) + f" {project} Authors" # noqa + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. + +url = "https://raw.githubusercontent.com/Visionatrix/Visionatrix/main/visionatrix/_version.py" +response = requests.get(url) +response.raise_for_status() +match = re.search(r'__version__\s*=\s*"(.*?)"', response.text) +if not match: + raise ValueError("Version string not found in _version.py") + +version = match.group(1) +release = version + +html_theme = "sphinx_rtd_theme" +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] + +html_logo = "resources/logo.svg" + +html_theme_options = { + "display_version": True, + "logo_only": True, +} + +# If true, `todos` produce output. Else they produce nothing. +todo_include_todos = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + +# If true, Sphinx will warn about all references where the target cannot be found. +# Default is False. You can activate this mode temporarily using the -n command-line +# switch. +nitpicky = True +nitpick_ignore_regex = [ + (r"py:class", r"starlette\.requests\.Request"), + (r"py:class", r"starlette\.requests\.HTTPConnection"), + (r"py:class", r"ComputedFieldInfo"), + (r"py:.*", r"httpx.*"), +] + +autodoc_member_order = "bysource" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["resources"] + + +def setup(app): + app.add_js_file("js/script.js") + app.add_css_file("css/styles.css") + app.add_css_file("css/dark.css") + app.add_css_file("css/light.css") + + +issues_github_path = "Visionatrix/Visionatrix" diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..89f0c5c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ +Visionatrix documentation +========================= + +Here will leave all docs that is not suitable for Readme file. + +.. toctree:: + :maxdepth: 1 + + Flows/index.rst + Installation.rst + CommandLineOptions.rst + WorkingModes.rst + VixWorkflows.rst + TechnicalInformation.rst + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` diff --git a/docs/resources/css/dark.css b/docs/resources/css/dark.css new file mode 100644 index 0000000..8866c07 --- /dev/null +++ b/docs/resources/css/dark.css @@ -0,0 +1,1996 @@ +@media (prefers-color-scheme: dark) { + html { + background-color: #181a1b !important; + } + + html, body, input, textarea, select, button { + background-color: #181a1b; + } + + html, body, input, textarea, select, button { + border-color: #736b5e; + color: #e8e6e3; + } + + a { + color: #3391ff; + } + + table { + border-color: #545b5e; + } + + ::placeholder { + color: #b2aba1; + } + + input:-webkit-autofill, + textarea:-webkit-autofill, + select:-webkit-autofill { + background-color: #555b00 !important; + color: #e8e6e3 !important; + } + + ::selection { + background-color: #004daa !important; + color: #e8e6e3 !important; + } + + ::-moz-selection { + background-color: #004daa !important; + color: #e8e6e3 !important; + } + + /* Invert Style */ + .jfk-bubble.gtx-bubble, embed[type="application/pdf"] { + filter: invert(100%) hue-rotate(180deg) contrast(90%) !important; + } + + /* Override Style */ + .vimvixen-hint { + background-color: #7b5300 !important; + border-color: #d8b013 !important; + color: #f3e8c8 !important; + } + + ::placeholder { + opacity: 0.5 !important; + } + + /* Variables Style */ + :root { + --darkreader-neutral-background: #181a1b; + --darkreader-neutral-text: #e8e6e3; + --darkreader-selection-background: #004daa; + --darkreader-selection-text: #e8e6e3; + } + + /* Modified CSS */ + a:hover, + a:active { + outline-color: initial; + } + + abbr[title] { + border-bottom-color: initial; + } + + ins { + background-image: initial; + background-color: rgb(112, 112, 0); + color: rgb(232, 230, 227); + text-decoration-color: initial; + } + + mark { + background-image: initial; + background-color: rgb(204, 204, 0); + color: rgb(232, 230, 227); + } + + ul, + ol, + dl { + list-style-image: none; + } + + li { + list-style-image: initial; + } + + img { + border-color: initial; + } + + fieldset { + border-color: initial; + } + + legend { + border-color: initial; + } + + .chromeframe { + background-image: initial; + background-color: rgb(53, 57, 59); + color: rgb(232, 230, 227); + } + + .ir { + border-color: initial; + background-color: transparent; + } + + .visuallyhidden { + border-color: initial; + } + + .fa-border { + border-color: rgb(53, 57, 59); + } + + .fa-inverse { + color: rgb(232, 230, 227); + } + + .sr-only { + border-color: initial; + } + + .fa::before, + .wy-menu-vertical li span.toctree-expand::before, + .wy-menu-vertical li.on a span.toctree-expand::before, + .wy-menu-vertical li.current > a span.toctree-expand::before, + .rst-content .admonition-title::before, + .rst-content h1 .headerlink::before, + .rst-content h2 .headerlink::before, + .rst-content h3 .headerlink::before, + .rst-content h4 .headerlink::before, + .rst-content h5 .headerlink::before, + .rst-content h6 .headerlink::before, + .rst-content dl dt .headerlink::before, + .rst-content p.caption .headerlink::before, + .rst-content table > caption .headerlink::before, + .rst-content .code-block-caption .headerlink::before, + .rst-content tt.download span:first-child::before, + .rst-content code.download span:first-child::before, + .icon::before, + .wy-dropdown .caret::before, + .wy-inline-validate.wy-inline-validate-success .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-danger .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-warning .wy-input-context::before, + .wy-inline-validate.wy-inline-validate-info .wy-input-context::before { + text-decoration-color: inherit; + } + + a .fa, + a .wy-menu-vertical li span.toctree-expand, + .wy-menu-vertical li a span.toctree-expand, + .wy-menu-vertical li.on a span.toctree-expand, + .wy-menu-vertical li.current > a span.toctree-expand, + a .rst-content .admonition-title, + .rst-content a .admonition-title, + a .rst-content h1 .headerlink, + .rst-content h1 a .headerlink, + a .rst-content h2 .headerlink, + .rst-content h2 a .headerlink, + a .rst-content h3 .headerlink, + .rst-content h3 a .headerlink, + a .rst-content h4 .headerlink, + .rst-content h4 a .headerlink, + a .rst-content h5 .headerlink, + .rst-content h5 a .headerlink, + a .rst-content h6 .headerlink, + .rst-content h6 a .headerlink, + a .rst-content dl dt .headerlink, + .rst-content dl dt a .headerlink, + a .rst-content p.caption .headerlink, + .rst-content p.caption a .headerlink, + a .rst-content table > caption .headerlink, + .rst-content table > caption a .headerlink, + a .rst-content .code-block-caption .headerlink, + .rst-content .code-block-caption a .headerlink, + a .rst-content tt.download span:first-child, + .rst-content tt.download a span:first-child, + a .rst-content code.download span:first-child, + .rst-content code.download a span:first-child, + a .icon { + text-decoration-color: inherit; + } + + .wy-alert, + .rst-content .note, + .rst-content .attention, + .rst-content .caution, + .rst-content .danger, + .rst-content .error, + .rst-content .hint, + .rst-content .important, + .rst-content .tip, + .rst-content .warning, + .rst-content .seealso, + .rst-content .admonition-todo, + .rst-content .admonition { + background-image: initial; + background-color: rgb(32, 35, 36); + } + + .wy-alert-title, + .rst-content .admonition-title { + color: rgb(232, 230, 227); + background-image: initial; + background-color: rgb(29, 91, 131); + } + + .wy-alert.wy-alert-danger, + .rst-content .wy-alert-danger.note, + .rst-content .wy-alert-danger.attention, + .rst-content .wy-alert-danger.caution, + .rst-content .danger, + .rst-content .error, + .rst-content .wy-alert-danger.hint, + .rst-content .wy-alert-danger.important, + .rst-content .wy-alert-danger.tip, + .rst-content .wy-alert-danger.warning, + .rst-content .wy-alert-danger.seealso, + .rst-content .wy-alert-danger.admonition-todo, + .rst-content .wy-alert-danger.admonition { + background-image: initial; + background-color: rgb(52, 12, 8); + } + + .wy-alert.wy-alert-danger .wy-alert-title, + .rst-content .wy-alert-danger.note .wy-alert-title, + .rst-content .wy-alert-danger.attention .wy-alert-title, + .rst-content .wy-alert-danger.caution .wy-alert-title, + .rst-content .danger .wy-alert-title, + .rst-content .error .wy-alert-title, + .rst-content .wy-alert-danger.hint .wy-alert-title, + .rst-content .wy-alert-danger.important .wy-alert-title, + .rst-content .wy-alert-danger.tip .wy-alert-title, + .rst-content .wy-alert-danger.warning .wy-alert-title, + .rst-content .wy-alert-danger.seealso .wy-alert-title, + .rst-content .wy-alert-danger.admonition-todo .wy-alert-title, + .rst-content .wy-alert-danger.admonition .wy-alert-title, + .wy-alert.wy-alert-danger .rst-content .admonition-title, + .rst-content .wy-alert.wy-alert-danger .admonition-title, + .rst-content .wy-alert-danger.note .admonition-title, + .rst-content .wy-alert-danger.attention .admonition-title, + .rst-content .wy-alert-danger.caution .admonition-title, + .rst-content .danger .admonition-title, + .rst-content .error .admonition-title, + .rst-content .wy-alert-danger.hint .admonition-title, + .rst-content .wy-alert-danger.important .admonition-title, + .rst-content .wy-alert-danger.tip .admonition-title, + .rst-content .wy-alert-danger.warning .admonition-title, + .rst-content .wy-alert-danger.seealso .admonition-title, + .rst-content .wy-alert-danger.admonition-todo .admonition-title, + .rst-content .wy-alert-danger.admonition .admonition-title { + background-image: initial; + background-color: rgb(108, 22, 13); + } + + .wy-alert.wy-alert-warning, + .rst-content .wy-alert-warning.note, + .rst-content .attention, + .rst-content .caution, + .rst-content .wy-alert-warning.danger, + .rst-content .wy-alert-warning.error, + .rst-content .wy-alert-warning.hint, + .rst-content .wy-alert-warning.important, + .rst-content .wy-alert-warning.tip, + .rst-content .warning, + .rst-content .wy-alert-warning.seealso, + .rst-content .admonition-todo, + .rst-content .wy-alert-warning.admonition { + background-image: initial; + background-color: rgb(82, 53, 0); + } + + .wy-alert.wy-alert-warning .wy-alert-title, + .rst-content .wy-alert-warning.note .wy-alert-title, + .rst-content .attention .wy-alert-title, + .rst-content .caution .wy-alert-title, + .rst-content .wy-alert-warning.danger .wy-alert-title, + .rst-content .wy-alert-warning.error .wy-alert-title, + .rst-content .wy-alert-warning.hint .wy-alert-title, + .rst-content .wy-alert-warning.important .wy-alert-title, + .rst-content .wy-alert-warning.tip .wy-alert-title, + .rst-content .warning .wy-alert-title, + .rst-content .wy-alert-warning.seealso .wy-alert-title, + .rst-content .admonition-todo .wy-alert-title, + .rst-content .wy-alert-warning.admonition .wy-alert-title, + .wy-alert.wy-alert-warning .rst-content .admonition-title, + .rst-content .wy-alert.wy-alert-warning .admonition-title, + .rst-content .wy-alert-warning.note .admonition-title, + .rst-content .attention .admonition-title, + .rst-content .caution .admonition-title, + .rst-content .wy-alert-warning.danger .admonition-title, + .rst-content .wy-alert-warning.error .admonition-title, + .rst-content .wy-alert-warning.hint .admonition-title, + .rst-content .wy-alert-warning.important .admonition-title, + .rst-content .wy-alert-warning.tip .admonition-title, + .rst-content .warning .admonition-title, + .rst-content .wy-alert-warning.seealso .admonition-title, + .rst-content .admonition-todo .admonition-title, + .rst-content .wy-alert-warning.admonition .admonition-title { + background-image: initial; + background-color: rgb(123, 65, 14); + } + + .wy-alert.wy-alert-info, + .rst-content .note, + .rst-content .wy-alert-info.attention, + .rst-content .wy-alert-info.caution, + .rst-content .wy-alert-info.danger, + .rst-content .wy-alert-info.error, + .rst-content .wy-alert-info.hint, + .rst-content .wy-alert-info.important, + .rst-content .wy-alert-info.tip, + .rst-content .wy-alert-info.warning, + .rst-content .seealso, + .rst-content .wy-alert-info.admonition-todo, + .rst-content .wy-alert-info.admonition { + background-image: initial; + background-color: rgb(32, 35, 36); + } + + .wy-alert.wy-alert-info .wy-alert-title, + .rst-content .note .wy-alert-title, + .rst-content .wy-alert-info.attention .wy-alert-title, + .rst-content .wy-alert-info.caution .wy-alert-title, + .rst-content .wy-alert-info.danger .wy-alert-title, + .rst-content .wy-alert-info.error .wy-alert-title, + .rst-content .wy-alert-info.hint .wy-alert-title, + .rst-content .wy-alert-info.important .wy-alert-title, + .rst-content .wy-alert-info.tip .wy-alert-title, + .rst-content .wy-alert-info.warning .wy-alert-title, + .rst-content .seealso .wy-alert-title, + .rst-content .wy-alert-info.admonition-todo .wy-alert-title, + .rst-content .wy-alert-info.admonition .wy-alert-title, + .wy-alert.wy-alert-info .rst-content .admonition-title, + .rst-content .wy-alert.wy-alert-info .admonition-title, + .rst-content .note .admonition-title, + .rst-content .wy-alert-info.attention .admonition-title, + .rst-content .wy-alert-info.caution .admonition-title, + .rst-content .wy-alert-info.danger .admonition-title, + .rst-content .wy-alert-info.error .admonition-title, + .rst-content .wy-alert-info.hint .admonition-title, + .rst-content .wy-alert-info.important .admonition-title, + .rst-content .wy-alert-info.tip .admonition-title, + .rst-content .wy-alert-info.warning .admonition-title, + .rst-content .seealso .admonition-title, + .rst-content .wy-alert-info.admonition-todo .admonition-title, + .rst-content .wy-alert-info.admonition .admonition-title { + background-image: initial; + background-color: rgb(29, 91, 131); + } + + .wy-alert.wy-alert-success, + .rst-content .wy-alert-success.note, + .rst-content .wy-alert-success.attention, + .rst-content .wy-alert-success.caution, + .rst-content .wy-alert-success.danger, + .rst-content .wy-alert-success.error, + .rst-content .hint, + .rst-content .important, + .rst-content .tip, + .rst-content .wy-alert-success.warning, + .rst-content .wy-alert-success.seealso, + .rst-content .wy-alert-success.admonition-todo, + .rst-content .wy-alert-success.admonition { + background-image: initial; + background-color: rgb(9, 66, 58); + } + + .wy-alert.wy-alert-success .wy-alert-title, + .rst-content .wy-alert-success.note .wy-alert-title, + .rst-content .wy-alert-success.attention .wy-alert-title, + .rst-content .wy-alert-success.caution .wy-alert-title, + .rst-content .wy-alert-success.danger .wy-alert-title, + .rst-content .wy-alert-success.error .wy-alert-title, + .rst-content .hint .wy-alert-title, + .rst-content .important .wy-alert-title, + .rst-content .tip .wy-alert-title, + .rst-content .wy-alert-success.warning .wy-alert-title, + .rst-content .wy-alert-success.seealso .wy-alert-title, + .rst-content .wy-alert-success.admonition-todo .wy-alert-title, + .rst-content .wy-alert-success.admonition .wy-alert-title, + .wy-alert.wy-alert-success .rst-content .admonition-title, + .rst-content .wy-alert.wy-alert-success .admonition-title, + .rst-content .wy-alert-success.note .admonition-title, + .rst-content .wy-alert-success.attention .admonition-title, + .rst-content .wy-alert-success.caution .admonition-title, + .rst-content .wy-alert-success.danger .admonition-title, + .rst-content .wy-alert-success.error .admonition-title, + .rst-content .hint .admonition-title, + .rst-content .important .admonition-title, + .rst-content .tip .admonition-title, + .rst-content .wy-alert-success.warning .admonition-title, + .rst-content .wy-alert-success.seealso .admonition-title, + .rst-content .wy-alert-success.admonition-todo .admonition-title, + .rst-content .wy-alert-success.admonition .admonition-title { + background-image: initial; + background-color: rgb(21, 150, 125); + } + + .wy-alert.wy-alert-neutral, + .rst-content .wy-alert-neutral.note, + .rst-content .wy-alert-neutral.attention, + .rst-content .wy-alert-neutral.caution, + .rst-content .wy-alert-neutral.danger, + .rst-content .wy-alert-neutral.error, + .rst-content .wy-alert-neutral.hint, + .rst-content .wy-alert-neutral.important, + .rst-content .wy-alert-neutral.tip, + .rst-content .wy-alert-neutral.warning, + .rst-content .wy-alert-neutral.seealso, + .rst-content .wy-alert-neutral.admonition-todo, + .rst-content .wy-alert-neutral.admonition { + background-image: initial; + background-color: rgb(27, 36, 36); + } + + .wy-alert.wy-alert-neutral .wy-alert-title, + .rst-content .wy-alert-neutral.note .wy-alert-title, + .rst-content .wy-alert-neutral.attention .wy-alert-title, + .rst-content .wy-alert-neutral.caution .wy-alert-title, + .rst-content .wy-alert-neutral.danger .wy-alert-title, + .rst-content .wy-alert-neutral.error .wy-alert-title, + .rst-content .wy-alert-neutral.hint .wy-alert-title, + .rst-content .wy-alert-neutral.important .wy-alert-title, + .rst-content .wy-alert-neutral.tip .wy-alert-title, + .rst-content .wy-alert-neutral.warning .wy-alert-title, + .rst-content .wy-alert-neutral.seealso .wy-alert-title, + .rst-content .wy-alert-neutral.admonition-todo .wy-alert-title, + .rst-content .wy-alert-neutral.admonition .wy-alert-title, + .wy-alert.wy-alert-neutral .rst-content .admonition-title, + .rst-content .wy-alert.wy-alert-neutral .admonition-title, + .rst-content .wy-alert-neutral.note .admonition-title, + .rst-content .wy-alert-neutral.attention .admonition-title, + .rst-content .wy-alert-neutral.caution .admonition-title, + .rst-content .wy-alert-neutral.danger .admonition-title, + .rst-content .wy-alert-neutral.error .admonition-title, + .rst-content .wy-alert-neutral.hint .admonition-title, + .rst-content .wy-alert-neutral.important .admonition-title, + .rst-content .wy-alert-neutral.tip .admonition-title, + .rst-content .wy-alert-neutral.warning .admonition-title, + .rst-content .wy-alert-neutral.seealso .admonition-title, + .rst-content .wy-alert-neutral.admonition-todo .admonition-title, + .rst-content .wy-alert-neutral.admonition .admonition-title { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(40, 43, 45); + } + + .wy-alert.wy-alert-neutral a, + .rst-content .wy-alert-neutral.note a, + .rst-content .wy-alert-neutral.attention a, + .rst-content .wy-alert-neutral.caution a, + .rst-content .wy-alert-neutral.danger a, + .rst-content .wy-alert-neutral.error a, + .rst-content .wy-alert-neutral.hint a, + .rst-content .wy-alert-neutral.important a, + .rst-content .wy-alert-neutral.tip a, + .rst-content .wy-alert-neutral.warning a, + .rst-content .wy-alert-neutral.seealso a, + .rst-content .wy-alert-neutral.admonition-todo a, + .rst-content .wy-alert-neutral.admonition a { + color: rgb(84, 164, 217); + } + + .wy-tray-container li { + background-image: initial; + background-color: transparent; + color: rgb(232, 230, 227); + box-shadow: rgba(0, 0, 0, 0.1) 0px 5px 5px 0px; + } + + .wy-tray-container li.wy-tray-item-success { + background-image: initial; + background-color: rgb(31, 139, 77); + } + + .wy-tray-container li.wy-tray-item-info { + background-image: initial; + background-color: rgb(33, 102, 148); + } + + .wy-tray-container li.wy-tray-item-warning { + background-image: initial; + background-color: rgb(178, 94, 20); + } + + .wy-tray-container li.wy-tray-item-danger { + background-image: initial; + background-color: rgb(162, 33, 20); + } + + .btn { + color: rgb(232, 230, 227); + border-color: rgba(140, 130, 115, 0.1); + background-color: rgb(31, 139, 77); + text-decoration-color: initial; + box-shadow: rgba(24, 26, 27, 0.5) 0px 1px 2px -1px inset, + rgba(0, 0, 0, 0.1) 0px -2px 0px 0px inset; + } + + .btn-hover { + background-image: initial; + background-color: rgb(37, 114, 165); + color: rgb(232, 230, 227); + } + + .btn:hover { + background-image: initial; + background-color: rgb(35, 156, 86); + color: rgb(232, 230, 227); + } + + .btn:focus { + background-image: initial; + background-color: rgb(35, 156, 86); + outline-color: initial; + } + + .btn:active { + box-shadow: rgba(0, 0, 0, 0.05) 0px -1px 0px 0px inset, + rgba(0, 0, 0, 0.1) 0px 2px 0px 0px inset; + } + + .btn:visited { + color: rgb(232, 230, 227); + } + + .btn:disabled { + background-image: none; + box-shadow: none; + } + + .btn-disabled { + background-image: none; + box-shadow: none; + } + + .btn-disabled:hover, + .btn-disabled:focus, + .btn-disabled:active { + background-image: none; + box-shadow: none; + } + + .btn-info { + background-color: rgb(33, 102, 148) !important; + } + + .btn-info:hover { + background-color: rgb(37, 114, 165) !important; + } + + .btn-neutral { + background-color: rgb(27, 36, 36) !important; + color: rgb(192, 186, 178) !important; + } + + .btn-neutral:hover { + color: rgb(192, 186, 178); + background-color: rgb(34, 44, 44) !important; + } + + .btn-neutral:visited { + color: rgb(192, 186, 178) !important; + } + + .btn-success { + background-color: rgb(31, 139, 77) !important; + } + + .btn-success:hover { + background-color: rgb(27, 122, 68) !important; + } + + .btn-danger { + background-color: rgb(162, 33, 20) !important; + } + + .btn-danger:hover { + background-color: rgb(149, 30, 18) !important; + } + + .btn-warning { + background-color: rgb(178, 94, 20) !important; + } + + .btn-warning:hover { + background-color: rgb(165, 87, 18) !important; + } + + .btn-invert { + background-color: rgb(26, 28, 29); + } + + .btn-invert:hover { + background-color: rgb(35, 38, 40) !important; + } + + .btn-link { + color: rgb(84, 164, 217); + box-shadow: none; + background-color: transparent !important; + border-color: transparent !important; + } + + .btn-link:hover { + box-shadow: none; + background-color: transparent !important; + color: rgb(79, 162, 216) !important; + } + + .btn-link:active { + box-shadow: none; + background-color: transparent !important; + color: rgb(79, 162, 216) !important; + } + + .btn-link:visited { + color: rgb(164, 103, 188); + } + + .wy-dropdown-menu { + background-image: initial; + background-color: rgb(26, 28, 29); + border-color: rgb(60, 65, 67); + box-shadow: rgba(0, 0, 0, 0.1) 0px 2px 2px 0px; + } + + .wy-dropdown-menu > dd > a { + color: rgb(192, 186, 178); + } + + .wy-dropdown-menu > dd > a:hover { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + + .wy-dropdown-menu > dd.divider { + border-top-color: rgb(60, 65, 67); + } + + .wy-dropdown-menu > dd.call-to-action { + background-image: initial; + background-color: rgb(40, 43, 45); + } + + .wy-dropdown-menu > dd.call-to-action:hover { + background-image: initial; + background-color: rgb(40, 43, 45); + } + + .wy-dropdown-menu > dd.call-to-action .btn { + color: rgb(232, 230, 227); + } + + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu { + background-image: initial; + background-color: rgb(26, 28, 29); + } + + .wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + + .wy-dropdown-arrow::before { + border-bottom-color: rgb(51, 55, 57); + border-left-color: transparent; + border-right-color: transparent; + } + + fieldset { + border-color: initial; + } + + legend { + border-color: initial; + } + + label { + color: rgb(200, 195, 188); + } + + .wy-control-group.wy-control-group-required > label::after { + color: rgb(233, 88, 73); + } + + .wy-form-message-inline { + color: rgb(168, 160, 149); + } + + .wy-form-message { + color: rgb(168, 160, 149); + } + + input[type="text"], input[type="password"], input[type="email"], input[type="url"], input[type="date"], input[type="month"], input[type="time"], input[type="datetime"], input[type="datetime-local"], input[type="week"], input[type="number"], input[type="search"], input[type="tel"], input[type="color"] { + border-color: rgb(62, 68, 70); + box-shadow: rgb(43, 47, 49) 0px 1px 3px inset; + } + + input[type="text"]:focus, input[type="password"]:focus, input[type="email"]:focus, input[type="url"]:focus, input[type="date"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="week"]:focus, input[type="number"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="color"]:focus { + outline-color: initial; + border-color: rgb(123, 114, 101); + } + + input.no-focus:focus { + border-color: rgb(62, 68, 70) !important; + } + + input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { + outline-color: rgb(13, 113, 167); + } + + input[type="text"][disabled], input[type="password"][disabled], input[type="email"][disabled], input[type="url"][disabled], input[type="date"][disabled], input[type="month"][disabled], input[type="time"][disabled], input[type="datetime"][disabled], input[type="datetime-local"][disabled], input[type="week"][disabled], input[type="number"][disabled], input[type="search"][disabled], input[type="tel"][disabled], input[type="color"][disabled] { + background-color: rgb(27, 29, 30); + } + + input:focus:invalid, + textarea:focus:invalid, + select:focus:invalid { + color: rgb(233, 88, 73); + border-color: rgb(149, 31, 18); + } + + input:focus:invalid:focus, + textarea:focus:invalid:focus, + select:focus:invalid:focus { + border-color: rgb(149, 31, 18); + } + + input[type="file"]:focus:invalid:focus, input[type="radio"]:focus:invalid:focus, input[type="checkbox"]:focus:invalid:focus { + outline-color: rgb(149, 31, 18); + } + + select, + textarea { + border-color: rgb(62, 68, 70); + box-shadow: rgb(43, 47, 49) 0px 1px 3px inset; + } + + select { + border-color: rgb(62, 68, 70); + background-color: rgb(24, 26, 27); + } + + select:focus, + textarea:focus { + outline-color: initial; + } + + select[disabled], + textarea[disabled], + input[readonly], + select[readonly], + textarea[readonly] { + background-color: rgb(27, 29, 30); + } + + .wy-checkbox, + .wy-radio { + color: rgb(192, 186, 178); + } + + .wy-input-prefix .wy-input-context, + .wy-input-suffix .wy-input-context { + background-color: rgb(27, 36, 36); + border-color: rgb(62, 68, 70); + color: rgb(168, 160, 149); + } + + .wy-input-suffix .wy-input-context { + border-left-color: initial; + } + + .wy-input-prefix .wy-input-context { + border-right-color: initial; + } + + .wy-switch::before { + background-image: initial; + background-color: rgb(53, 57, 59); + } + + .wy-switch::after { + background-image: initial; + background-color: rgb(82, 88, 92); + } + + .wy-switch span { + color: rgb(200, 195, 188); + } + + .wy-switch.active::before { + background-image: initial; + background-color: rgb(24, 106, 58); + } + + .wy-switch.active::after { + background-image: initial; + background-color: rgb(31, 139, 77); + } + + .wy-control-group.wy-control-group-error .wy-form-message, + .wy-control-group.wy-control-group-error > label { + color: rgb(233, 88, 73); + } + + .wy-control-group.wy-control-group-error input[type="text"], .wy-control-group.wy-control-group-error input[type="password"], .wy-control-group.wy-control-group-error input[type="email"], .wy-control-group.wy-control-group-error input[type="url"], .wy-control-group.wy-control-group-error input[type="date"], .wy-control-group.wy-control-group-error input[type="month"], .wy-control-group.wy-control-group-error input[type="time"], .wy-control-group.wy-control-group-error input[type="datetime"], .wy-control-group.wy-control-group-error input[type="datetime-local"], .wy-control-group.wy-control-group-error input[type="week"], .wy-control-group.wy-control-group-error input[type="number"], .wy-control-group.wy-control-group-error input[type="search"], .wy-control-group.wy-control-group-error input[type="tel"], .wy-control-group.wy-control-group-error input[type="color"] { + border-color: rgb(149, 31, 18); + } + + .wy-control-group.wy-control-group-error textarea { + border-color: rgb(149, 31, 18); + } + + .wy-inline-validate.wy-inline-validate-success .wy-input-context { + color: rgb(92, 218, 145); + } + + .wy-inline-validate.wy-inline-validate-danger .wy-input-context { + color: rgb(233, 88, 73); + } + + .wy-inline-validate.wy-inline-validate-warning .wy-input-context { + color: rgb(232, 138, 54); + } + + .wy-inline-validate.wy-inline-validate-info .wy-input-context { + color: rgb(84, 164, 217); + } + + .wy-table caption, + .rst-content table.docutils caption, + .rst-content table.field-list caption { + color: rgb(232, 230, 227); + } + + .wy-table thead, + .rst-content table.docutils thead, + .rst-content table.field-list thead { + color: rgb(232, 230, 227); + } + + .wy-table thead th, + .rst-content table.docutils thead th, + .rst-content table.field-list thead th { + border-bottom-color: rgb(56, 61, 63); + } + + .wy-table td, + .rst-content table.docutils td, + .rst-content table.field-list td { + background-color: transparent; + } + + .wy-table-secondary { + color: rgb(152, 143, 129); + } + + .wy-table-tertiary { + color: rgb(152, 143, 129); + } + + .wy-table-odd td, + .wy-table-striped tr:nth-child(2n-1) td, + .rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td { + background-color: rgb(27, 36, 36); + } + + .wy-table-backed { + background-color: rgb(27, 36, 36); + } + + .wy-table-bordered-all, + .rst-content table.docutils { + border-color: rgb(56, 61, 63); + } + + .wy-table-bordered-all td, + .rst-content table.docutils td { + border-bottom-color: rgb(56, 61, 63); + border-left-color: rgb(56, 61, 63); + } + + .wy-table-bordered { + border-color: rgb(56, 61, 63); + } + + .wy-table-bordered-rows td { + border-bottom-color: rgb(56, 61, 63); + } + + .wy-table-horizontal td, + .wy-table-horizontal th { + border-bottom-color: rgb(56, 61, 63); + } + + a { + color: rgb(84, 164, 217); + text-decoration-color: initial; + } + + a:hover { + color: rgb(68, 156, 214); + } + + a:visited { + color: rgb(164, 103, 188); + } + + body { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(33, 35, 37); + } + + .wy-text-strike { + text-decoration-color: initial; + } + + .wy-text-warning { + color: rgb(232, 138, 54) !important; + } + + a.wy-text-warning:hover { + color: rgb(236, 157, 87) !important; + } + + .wy-text-info { + color: rgb(84, 164, 217) !important; + } + + a.wy-text-info:hover { + color: rgb(79, 162, 216) !important; + } + + .wy-text-success { + color: rgb(92, 218, 145) !important; + } + + a.wy-text-success:hover { + color: rgb(73, 214, 133) !important; + } + + .wy-text-danger { + color: rgb(233, 88, 73) !important; + } + + a.wy-text-danger:hover { + color: rgb(237, 118, 104) !important; + } + + .wy-text-neutral { + color: rgb(192, 186, 178) !important; + } + + a.wy-text-neutral:hover { + color: rgb(176, 169, 159) !important; + } + + hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(56, 61, 63); + } + + code, + .rst-content tt, + .rst-content code { + background-image: initial; + background-color: rgb(24, 26, 27); + border-color: rgb(56, 61, 63); + color: rgb(233, 88, 73); + } + + .wy-plain-list-disc, + .rst-content .section ul, + .rst-content .toctree-wrapper ul, + article ul { + list-style-image: initial; + } + + .wy-plain-list-disc li, + .rst-content .section ul li, + .rst-content .toctree-wrapper ul li, + article ul li { + list-style-image: initial; + } + + .wy-plain-list-disc li li, + .rst-content .section ul li li, + .rst-content .toctree-wrapper ul li li, + article ul li li { + list-style-image: initial; + } + + .wy-plain-list-disc li li li, + .rst-content .section ul li li li, + .rst-content .toctree-wrapper ul li li li, + article ul li li li { + list-style-image: initial; + } + + .wy-plain-list-disc li ol li, + .rst-content .section ul li ol li, + .rst-content .toctree-wrapper ul li ol li, + article ul li ol li { + list-style-image: initial; + } + + .wy-plain-list-decimal, + .rst-content .section ol, + .rst-content ol.arabic, + article ol { + list-style-image: initial; + } + + .wy-plain-list-decimal li, + .rst-content .section ol li, + .rst-content ol.arabic li, + article ol li { + list-style-image: initial; + } + + .wy-plain-list-decimal li ul li, + .rst-content .section ol li ul li, + .rst-content ol.arabic li ul li, + article ol li ul li { + list-style-image: initial; + } + + .wy-breadcrumbs li code, + .wy-breadcrumbs li .rst-content tt, + .rst-content .wy-breadcrumbs li tt { + border-color: initial; + background-image: none; + background-color: initial; + } + + .wy-breadcrumbs li code.literal, + .wy-breadcrumbs li .rst-content tt.literal, + .rst-content .wy-breadcrumbs li tt.literal { + color: rgb(192, 186, 178); + } + + .wy-breadcrumbs-extra { + color: rgb(184, 178, 169); + } + + .wy-menu a:hover { + text-decoration-color: initial; + } + + .wy-menu-horiz li:hover { + background-image: initial; + background-color: rgba(24, 26, 27, 0.1); + } + + .wy-menu-horiz li.divide-left { + border-left-color: rgb(119, 110, 98); + } + + .wy-menu-horiz li.divide-right { + border-right-color: rgb(119, 110, 98); + } + + .wy-menu-vertical header, + .wy-menu-vertical p.caption { + color: rgb(99, 161, 201); + } + + .wy-menu-vertical li.divide-top { + border-top-color: rgb(119, 110, 98); + } + + .wy-menu-vertical li.divide-bottom { + border-bottom-color: rgb(119, 110, 98); + } + + .wy-menu-vertical li.current { + background-image: initial; + background-color: rgb(40, 43, 45); + } + + .wy-menu-vertical li.current a { + color: rgb(152, 143, 129); + border-right-color: rgb(63, 69, 71); + } + + .wy-menu-vertical li.current a:hover { + background-image: initial; + background-color: rgb(47, 51, 53); + } + + .wy-menu-vertical li code, + .wy-menu-vertical li .rst-content tt, + .rst-content .wy-menu-vertical li tt { + border-color: initial; + background-image: inherit; + background-color: inherit; + color: inherit; + } + + .wy-menu-vertical li span.toctree-expand { + color: rgb(183, 177, 168); + } + + .wy-menu-vertical li.on a, + .wy-menu-vertical li.current > a { + color: rgb(192, 186, 178); + background-image: initial; + background-color: rgb(26, 28, 29); + border-color: initial; + } + + .wy-menu-vertical li.on a:hover, + .wy-menu-vertical li.current > a:hover { + background-image: initial; + background-color: rgb(26, 28, 29); + } + + .wy-menu-vertical li.on a:hover span.toctree-expand, + .wy-menu-vertical li.current > a:hover span.toctree-expand { + color: rgb(152, 143, 129); + } + + .wy-menu-vertical li.on a span.toctree-expand, + .wy-menu-vertical li.current > a span.toctree-expand { + color: rgb(200, 195, 188); + } + + .wy-menu-vertical li.toctree-l1.current > a { + border-bottom-color: rgb(63, 69, 71); + border-top-color: rgb(63, 69, 71); + } + + .wy-menu-vertical li.toctree-l2 a, + .wy-menu-vertical li.toctree-l3 a, + .wy-menu-vertical li.toctree-l4 a { + color: rgb(192, 186, 178); + } + + .wy-menu-vertical li.toctree-l2.current > a { + background-image: initial; + background-color: rgb(54, 59, 61); + } + + .wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a { + background-image: initial; + background-color: rgb(54, 59, 61); + } + + .wy-menu-vertical li.toctree-l2 a:hover span.toctree-expand { + color: rgb(152, 143, 129); + } + + .wy-menu-vertical li.toctree-l2 span.toctree-expand { + color: rgb(174, 167, 156); + } + + .wy-menu-vertical li.toctree-l3.current > a { + background-image: initial; + background-color: rgb(61, 66, 69); + } + + .wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a { + background-image: initial; + background-color: rgb(61, 66, 69); + } + + .wy-menu-vertical li.toctree-l3 a:hover span.toctree-expand { + color: rgb(152, 143, 129); + } + + .wy-menu-vertical li.toctree-l3 span.toctree-expand { + color: rgb(166, 158, 146); + } + + .wy-menu-vertical li.toctree-l2.current a, + .wy-menu-vertical li.toctree-l3.current a { + background-color: #363636; + } + + .wy-menu-vertical li ul li a { + color: rgb(208, 204, 198); + } + + .wy-menu-vertical a { + color: rgb(208, 204, 198); + } + + .wy-menu-vertical a:hover { + background-color: rgb(57, 62, 64); + } + + .wy-menu-vertical a:hover span.toctree-expand { + color: rgb(208, 204, 198); + } + + .wy-menu-vertical a:active { + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + + .wy-menu-vertical a:active span.toctree-expand { + color: rgb(232, 230, 227); + } + + .wy-side-nav-search { + background-color: rgb(33, 102, 148); + color: rgb(230, 228, 225); + } + + .wy-side-nav-search input[type="text"] { + border-color: rgb(35, 111, 160); + } + + .wy-side-nav-search img { + background-color: rgb(33, 102, 148); + } + + .wy-side-nav-search > a, + .wy-side-nav-search .wy-dropdown > a { + color: rgb(230, 228, 225); + } + + .wy-side-nav-search > a:hover, + .wy-side-nav-search .wy-dropdown > a:hover { + background-image: initial; + background-color: rgba(24, 26, 27, 0.1); + } + + .wy-side-nav-search > a img.logo, + .wy-side-nav-search .wy-dropdown > a img.logo { + background-image: initial; + background-color: transparent; + } + + .wy-side-nav-search > div.version { + color: rgba(232, 230, 227, 0.3); + } + + .wy-nav .wy-menu-vertical header { + color: rgb(84, 164, 217); + } + + .wy-nav .wy-menu-vertical a { + color: rgb(184, 178, 169); + } + + .wy-nav .wy-menu-vertical a:hover { + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + + .wy-body-for-nav { + background-image: initial; + background-color: rgb(24, 26, 27); + } + + .wy-nav-side { + color: rgb(169, 161, 150); + background-image: initial; + background-color: rgb(38, 41, 43); + } + + .wy-nav-top { + background-image: initial; + background-color: rgb(33, 102, 148); + color: rgb(232, 230, 227); + } + + .wy-nav-top a { + color: rgb(232, 230, 227); + } + + .wy-nav-top img { + background-color: rgb(33, 102, 148); + } + + .wy-nav-content-wrap { + background-image: initial; + background-color: rgb(26, 28, 29); + } + + .wy-body-mask { + background-image: initial; + background-color: rgba(0, 0, 0, 0.2); + } + + footer { + color: rgb(152, 143, 129); + } + + footer span.commit code, + footer span.commit .rst-content tt, + .rst-content footer span.commit tt { + background-image: none; + background-color: initial; + border-color: initial; + color: rgb(152, 143, 129); + } + + #search-results .search li { + border-bottom-color: rgb(56, 61, 63); + } + + #search-results .search li:first-child { + border-top-color: rgb(56, 61, 63); + } + + #search-results .context { + color: rgb(152, 143, 129); + } + + @media screen and (min-width: 1100px) { + .wy-nav-content-wrap { + background-image: initial; + background-color: rgba(0, 0, 0, 0.05); + } + + .wy-nav-content { + background-image: initial; + background-color: rgb(26, 28, 29); + } + } + .rst-versions { + color: rgb(230, 228, 225); + background-image: initial; + background-color: rgb(23, 24, 25); + } + + .rst-versions a { + color: rgb(84, 164, 217); + text-decoration-color: initial; + } + + .rst-versions .rst-current-version { + background-color: rgb(29, 31, 32); + color: rgb(92, 218, 145); + } + + .rst-versions .rst-current-version .fa, + .rst-versions .rst-current-version .wy-menu-vertical li span.toctree-expand, + .wy-menu-vertical li .rst-versions .rst-current-version span.toctree-expand, + .rst-versions .rst-current-version .rst-content .admonition-title, + .rst-content .rst-versions .rst-current-version .admonition-title, + .rst-versions .rst-current-version .rst-content h1 .headerlink, + .rst-content h1 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content h2 .headerlink, + .rst-content h2 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content h3 .headerlink, + .rst-content h3 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content h4 .headerlink, + .rst-content h4 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content h5 .headerlink, + .rst-content h5 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content h6 .headerlink, + .rst-content h6 .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content dl dt .headerlink, + .rst-content dl dt .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content p.caption .headerlink, + .rst-content p.caption .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content table > caption .headerlink, + .rst-content table > caption .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content .code-block-caption .headerlink, + .rst-content .code-block-caption .rst-versions .rst-current-version .headerlink, + .rst-versions .rst-current-version .rst-content tt.download span:first-child, + .rst-content tt.download .rst-versions .rst-current-version span:first-child, + .rst-versions .rst-current-version .rst-content code.download span:first-child, + .rst-content code.download .rst-versions .rst-current-version span:first-child, + .rst-versions .rst-current-version .icon { + color: rgb(230, 228, 225); + } + + .rst-versions .rst-current-version.rst-out-of-date { + background-color: rgb(162, 33, 20); + color: rgb(232, 230, 227); + } + + .rst-versions .rst-current-version.rst-active-old-version { + background-color: rgb(192, 156, 11); + color: rgb(232, 230, 227); + } + + .rst-versions .rst-other-versions { + color: rgb(152, 143, 129); + } + + .rst-versions .rst-other-versions hr { + border-right-color: initial; + border-bottom-color: initial; + border-left-color: initial; + border-top-color: rgb(119, 111, 98); + } + + .rst-versions .rst-other-versions dd a { + color: rgb(230, 228, 225); + } + + .rst-versions.rst-badge { + border-color: initial; + } + + .rst-content abbr[title] { + text-decoration-color: initial; + } + + .rst-content.style-external-links a.reference.external::after { + color: rgb(184, 178, 169); + } + + .rst-content pre.literal-block, .rst-content div[class^="highlight"] { + border-color: rgb(56, 61, 63); + } + + .rst-content pre.literal-block div[class^="highlight"], .rst-content div[class^="highlight"] div[class^="highlight"] { + border-color: initial; + } + + .rst-content .linenodiv pre { + border-right-color: rgb(54, 59, 61); + } + + .rst-content .admonition table { + border-color: rgba(140, 130, 115, 0.1); + } + + .rst-content .admonition table td, + .rst-content .admonition table th { + background-image: initial !important; + background-color: transparent !important; + border-color: rgba(140, 130, 115, 0.1) !important; + } + + .rst-content .section ol.loweralpha, + .rst-content .section ol.loweralpha li { + list-style-image: initial; + } + + .rst-content .section ol.upperalpha, + .rst-content .section ol.upperalpha li { + list-style-image: initial; + } + + .rst-content .toc-backref { + color: rgb(192, 186, 178); + } + + .rst-content .sidebar { + background-image: initial; + background-color: rgb(27, 36, 36); + border-color: rgb(56, 61, 63); + } + + .rst-content .sidebar .sidebar-title { + background-image: initial; + background-color: rgb(40, 43, 45); + } + + .rst-content .highlighted { + background-image: initial; + background-color: rgb(192, 156, 11); + } + + .rst-content table.docutils.citation, + .rst-content table.docutils.footnote { + background-image: none; + background-color: initial; + border-color: initial; + color: rgb(152, 143, 129); + } + + .rst-content table.docutils.citation td, + .rst-content table.docutils.citation tr, + .rst-content table.docutils.footnote td, + .rst-content table.docutils.footnote tr { + border-color: initial; + background-color: transparent !important; + } + + .rst-content table.docutils.citation tt, + .rst-content table.docutils.citation code, + .rst-content table.docutils.footnote tt, + .rst-content table.docutils.footnote code { + color: rgb(178, 172, 162); + } + + .rst-content table.docutils th { + border-color: rgb(56, 61, 63); + } + + .rst-content table.field-list { + border-color: initial; + } + + .rst-content table.field-list td { + border-color: initial; + } + + .rst-content tt, + .rst-content tt, + .rst-content code { + color: rgb(232, 230, 227); + } + + .rst-content tt.literal, + .rst-content tt.literal, + .rst-content code.literal { + color: rgb(233, 88, 73); + } + + .rst-content tt.xref, + a .rst-content tt, + .rst-content tt.xref, + .rst-content code.xref, + a .rst-content tt, + a .rst-content code { + color: rgb(192, 186, 178); + } + + .rst-content a tt, + .rst-content a tt, + .rst-content a code { + color: rgb(84, 164, 217); + } + + .rst-content dl:not(.docutils) dt { + background-image: initial; + background-color: rgb(32, 35, 36); + color: rgb(84, 164, 217); + border-top-color: rgb(28, 89, 128); + } + + .rst-content dl:not(.docutils) dt::before { + color: rgb(109, 178, 223); + } + + .rst-content dl:not(.docutils) dt .headerlink { + color: rgb(192, 186, 178); + } + + .rst-content dl:not(.docutils) dl dt { + border-top-color: initial; + border-right-color: initial; + border-bottom-color: initial; + border-left-color: rgb(62, 68, 70); + background-image: initial; + background-color: rgb(32, 35, 37); + color: rgb(178, 172, 162); + } + + .rst-content dl:not(.docutils) dl dt .headerlink { + color: rgb(192, 186, 178); + } + + .rst-content dl:not(.docutils) tt.descname, + .rst-content dl:not(.docutils) tt.descclassname, + .rst-content dl:not(.docutils) tt.descname, + .rst-content dl:not(.docutils) code.descname, + .rst-content dl:not(.docutils) tt.descclassname, + .rst-content dl:not(.docutils) code.descclassname { + background-color: transparent; + border-color: initial; + } + + .rst-content dl:not(.docutils) .optional { + color: rgb(232, 230, 227); + } + + .rst-content .viewcode-link, + .rst-content .viewcode-back { + color: rgb(92, 218, 145); + } + + .rst-content tt.download, + .rst-content code.download { + background-image: inherit; + background-color: inherit; + color: inherit; + border-color: inherit; + } + + .rst-content .guilabel { + border-color: rgb(27, 84, 122); + background-image: initial; + background-color: rgb(32, 35, 36); + } + + span[id*="MathJax-Span"] { + color: rgb(192, 186, 178); + } + + .highlight .hll { + background-color: rgb(82, 82, 0); + } + + .highlight { + background-image: initial; + background-color: rgb(61, 82, 0); + } + + .highlight .c { + color: rgb(119, 179, 195); + } + + .highlight .err { + border-color: rgb(179, 0, 0); + } + + .highlight .k { + color: rgb(126, 255, 163); + } + + .highlight .o { + color: rgb(168, 160, 149); + } + + .highlight .ch { + color: rgb(119, 179, 195); + } + + .highlight .cm { + color: rgb(119, 179, 195); + } + + .highlight .cp { + color: rgb(126, 255, 163); + } + + .highlight .cpf { + color: rgb(119, 179, 195); + } + + .highlight .c1 { + color: rgb(119, 179, 195); + } + + .highlight .cs { + color: rgb(119, 179, 195); + background-color: rgb(60, 0, 0); + } + + .highlight .gd { + color: rgb(255, 92, 92); + } + + .highlight .gr { + color: rgb(255, 26, 26); + } + + .highlight .gh { + color: rgb(127, 174, 255); + } + + .highlight .gi { + color: rgb(92, 255, 92); + } + + .highlight .go { + color: rgb(200, 195, 188); + } + + .highlight .gp { + color: rgb(246, 147, 68); + } + + .highlight .gu { + color: rgb(255, 114, 255); + } + + .highlight .gt { + color: rgb(71, 160, 255); + } + + .highlight .kc { + color: rgb(126, 255, 163); + } + + .highlight .kd { + color: rgb(126, 255, 163); + } + + .highlight .kn { + color: rgb(126, 255, 163); + } + + .highlight .kp { + color: rgb(126, 255, 163); + } + + .highlight .kr { + color: rgb(126, 255, 163); + } + + .highlight .kt { + color: rgb(255, 137, 103); + } + + .highlight .m { + color: rgb(125, 222, 174); + } + + .highlight .s { + color: rgb(123, 166, 202); + } + + .highlight .na { + color: rgb(123, 166, 202); + } + + .highlight .nb { + color: rgb(126, 255, 163); + } + + .highlight .nc { + color: rgb(81, 194, 242); + } + + .highlight .no { + color: rgb(103, 177, 215); + } + + .highlight .nd { + color: rgb(178, 172, 162); + } + + .highlight .ni { + color: rgb(217, 100, 73); + } + + .highlight .ne { + color: rgb(126, 255, 163); + } + + .highlight .nf { + color: rgb(131, 186, 249); + } + + .highlight .nl { + color: rgb(137, 193, 255); + } + + .highlight .nn { + color: rgb(81, 194, 242); + } + + .highlight .nt { + color: rgb(138, 191, 249); + } + + .highlight .nv { + color: rgb(190, 103, 215); + } + + .highlight .ow { + color: rgb(126, 255, 163); + } + + .highlight .w { + color: rgb(189, 183, 175); + } + + .highlight .mb { + color: rgb(125, 222, 174); + } + + .highlight .mf { + color: rgb(125, 222, 174); + } + + .highlight .mh { + color: rgb(125, 222, 174); + } + + .highlight .mi { + color: rgb(125, 222, 174); + } + + .highlight .mo { + color: rgb(125, 222, 174); + } + + .highlight .sa { + color: rgb(123, 166, 202); + } + + .highlight .sb { + color: rgb(123, 166, 202); + } + + .highlight .sc { + color: rgb(123, 166, 202); + } + + .highlight .dl { + color: rgb(123, 166, 202); + } + + .highlight .sd { + color: rgb(123, 166, 202); + } + + .highlight .s2 { + color: rgb(123, 166, 202); + } + + .highlight .se { + color: rgb(123, 166, 202); + } + + .highlight .sh { + color: rgb(123, 166, 202); + } + + .highlight .si { + color: rgb(117, 168, 209); + } + + .highlight .sx { + color: rgb(246, 147, 68); + } + + .highlight .sr { + color: rgb(133, 182, 224); + } + + .highlight .s1 { + color: rgb(123, 166, 202); + } + + .highlight .ss { + color: rgb(188, 230, 128); + } + + .highlight .bp { + color: rgb(126, 255, 163); + } + + .highlight .fm { + color: rgb(131, 186, 249); + } + + .highlight .vc { + color: rgb(190, 103, 215); + } + + .highlight .vg { + color: rgb(190, 103, 215); + } + + .highlight .vi { + color: rgb(190, 103, 215); + } + + .highlight .vm { + color: rgb(190, 103, 215); + } + + .highlight .il { + color: rgb(125, 222, 174); + } + + .rst-other-versions a { + border-color: initial; + } + + .ethical-sidebar .ethical-image-link, + .ethical-footer .ethical-image-link { + border-color: initial; + } + + .ethical-sidebar, + .ethical-footer { + background-color: rgb(34, 36, 38); + border-color: rgb(62, 68, 70); + color: rgb(226, 223, 219); + } + + .ethical-sidebar ul { + list-style-image: initial; + } + + .ethical-sidebar ul li { + background-color: rgb(5, 77, 121); + color: rgb(232, 230, 227); + } + + .ethical-sidebar a, + .ethical-sidebar a:visited, + .ethical-sidebar a:hover, + .ethical-sidebar a:active, + .ethical-footer a, + .ethical-footer a:visited, + .ethical-footer a:hover, + .ethical-footer a:active { + color: rgb(226, 223, 219); + text-decoration-color: initial !important; + border-bottom-color: initial !important; + } + + .ethical-callout a { + color: rgb(161, 153, 141) !important; + text-decoration-color: initial !important; + } + + .ethical-fixedfooter { + background-color: rgb(34, 36, 38); + border-top-color: rgb(66, 72, 74); + color: rgb(192, 186, 178); + } + + .ethical-fixedfooter .ethical-text::before { + background-color: rgb(61, 140, 64); + color: rgb(232, 230, 227); + } + + .ethical-fixedfooter .ethical-callout { + color: rgb(168, 160, 149); + } + + .ethical-fixedfooter a, + .ethical-fixedfooter a:hover, + .ethical-fixedfooter a:active, + .ethical-fixedfooter a:visited { + color: rgb(192, 186, 178); + text-decoration-color: initial; + } + + .ethical-rtd .ethical-sidebar { + color: rgb(184, 178, 169); + } + + .ethical-alabaster a.ethical-image-link { + border-color: initial !important; + } + + .ethical-dark-theme .ethical-sidebar { + background-color: rgb(58, 62, 65); + border-color: rgb(75, 81, 84); + color: rgb(193, 188, 180) !important; + } + + .ethical-dark-theme a, + .ethical-dark-theme a:visited { + color: rgb(216, 213, 208) !important; + border-bottom-color: initial !important; + } + + .ethical-dark-theme .ethical-callout a { + color: rgb(184, 178, 169) !important; + } + + .keep-us-sustainable { + border-color: rgb(87, 133, 38); + } + + .keep-us-sustainable a, + .keep-us-sustainable a:hover, + .keep-us-sustainable a:visited { + text-decoration-color: initial; + } + + .wy-body-for-nav .keep-us-sustainable { + color: rgb(184, 178, 169); + } + + .wy-body-for-nav .keep-us-sustainable a { + color: rgb(222, 219, 215); + } + + /* For black-on-white/transparent images at handbook/text-anchors.html */ + #text-anchors img { + filter: invert(1) brightness(0.85) hue-rotate(-60deg); + } +} diff --git a/docs/resources/css/light.css b/docs/resources/css/light.css new file mode 100644 index 0000000..04edd7b --- /dev/null +++ b/docs/resources/css/light.css @@ -0,0 +1,8 @@ +@media (prefers-color-scheme: light) { + + .wy-menu-vertical li.toctree-l2.current a, + .wy-menu-vertical li.toctree-l3.current a { + background-color: #c9c9c9; + } + +} diff --git a/docs/resources/css/styles.css b/docs/resources/css/styles.css new file mode 100644 index 0000000..62f995e --- /dev/null +++ b/docs/resources/css/styles.css @@ -0,0 +1,12 @@ +th p { + margin-bottom: 0; +} + +.rst-content tr .line-block { + font-size: 1rem; + margin-bottom: 0; +} + +.wy-nav-content { + max-width: 80% !important; +} diff --git a/docs/resources/js/script.js b/docs/resources/js/script.js new file mode 100644 index 0000000..5cb6494 --- /dev/null +++ b/docs/resources/js/script.js @@ -0,0 +1,58 @@ +jQuery(document).ready(function ($) { + setTimeout(function () { + var sectionID = 'base'; + var search = function ($section, $sidebarItem) { + $section.children('.section, .function, .method').each(function () { + if ($(this).hasClass('section')) { + sectionID = $(this).attr('id'); + search($(this), $sidebarItem.parent().find('[href="#'+sectionID+'"]')); + } else { + var $dt = $(this).children('dt'); + var id = $dt.attr('id'); + if (id === undefined) { + return; + } + + var $functionsUL = $sidebarItem.siblings('[data-sectionID='+sectionID+']'); + if (!$functionsUL.length) { + $functionsUL = $('