diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000000000000000000000000000000000..753b249880d57c22306cf155601bff986622b1a0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ipynb merge=nbdev-merge diff --git a/.gitconfig b/.gitconfig new file mode 100644 index 0000000000000000000000000000000000000000..9054574f90b84d27e89a016d7c76d5bdf7e479a4 --- /dev/null +++ b/.gitconfig @@ -0,0 +1,11 @@ +# Generated by nbdev_install_hooks +# +# If you need to disable this instrumentation do: +# git config --local --unset include.path +# +# To restore: +# git config --local include.path ../.gitconfig +# +[merge "nbdev-merge"] + name = resolve conflicts with nbdev_fix + driver = nbdev_merge %O %A %B %P diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..29bfc575f91ccd4637331abfa6c5faaee9b651c6 --- /dev/null +++ b/.github/workflows/deploy.yaml @@ -0,0 +1,14 @@ +name: Deploy to GitHub Pages + +permissions: + contents: write + pages: write + +on: + push: + branches: [ "main", "master" ] + workflow_dispatch: +jobs: + deploy: + runs-on: ubuntu-latest + steps: [uses: fastai/workflows/quarto-ghp@master] diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000000000000000000000000000000000000..56085923ac597c0618c5b3a9d710487ed4eef03c --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,7 @@ +name: CI +on: [workflow_dispatch, pull_request, push] + +jobs: + test: + runs-on: ubuntu-latest + steps: [uses: fastai/workflows/nbdev-ci@master] diff --git a/.gitignore b/.gitignore index 19607bb99583e9bcdc169fab8e5736d3229e8863..186e549864f8e1017c0ceafd56b6f6891965d6d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,163 @@ +*__pycache__ +*.ipynb_checkpoints + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments .env +.venv env/ -*__pycache__ -*.pyc -*.ipynb_checkpoints \ No newline at end of file +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..3b106e87c0610102b42d042be9c79bc967c84503 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022, fastai + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000000000000000000000000000000000000..5c0e7ced193cb35aee60cbadc3e022a1da0fd8cc --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,5 @@ +include settings.ini +include LICENSE +include CONTRIBUTING.md +include README.md +recursive-exclude * __pycache__ diff --git a/README.md b/README.md index 11877e881ba7b792b14b4bf45043e6faddbdfa1b..e53898ef813e596eeca4255ac0a4ebfd285d6f2e 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,127 @@ --- -title: Chatbot +title: lv-recipe-chatbot emoji: 🫑 colorFrom: green colorTo: indigo sdk: gradio sdk_version: 3.23.0 -app_file: chatbot/app.py +app_file: app.py pinned: false license: unknown --- +# lv-recipe-chatbot -# Vegan Recipe Chatbot + -![Screenshot of Chatbot initial interface](docs/assets/chatbot_init.png) +This file will become your README and also the index of your +documentation. -## Quickstart +## Install -`git clone` the repo +``` sh +pip install lv_recipe_chatbot +``` + +## How to use + +``` python +from dotenv import load_dotenv + +load_dotenv() + +app.launch_demo() +``` + + Running on local URL: http://127.0.0.1:7860 + + To create a public link, set `share=True` in `launch()`. + +or + +``` sh +python3 app.py +``` + +## Dev quick-start -```sh +`git clone` the repo + +``` sh cd lv-recipe-chatbot -``` +``` Make sure to use the version of python specified in `py_version.txt` Create a virtual environment. -```sh +``` sh python3 -m venv env ``` Activate the env and install dependencies. -```sh +``` sh source env/bin/activate pip install -r requirements.txt pip install -r requirements/dev.txt ``` +To make the Jupyter environment, git friendly: `nbdev_install_hooks` +If you want to render documentation locally, you will want to [install +Quarto](https://nbdev.fast.ai/tutorials/tutorial.html#install-quarto). + +`nbdev_install_quarto` + Put API secrets in .env -```sh +``` sh cp .env.example .env ``` Edit .env with your secret key(s). Only `OPEN_AI_KEY` is required. -Then start the Gradio demo from within the virtual environment. +Then start the Gradio demo from within the virtual environment. -```sh -python3 -m chatbot.app +``` sh +python3 app.py +``` + +Preview documentation + +``` sh +nbdev_preview ``` ## Dependencies -If a new dependency for devlepment is helpful for developers, add it to `dev.txt`. -If it is a dependency for the app that is imported in source code, add it to `core.txt`. +If a new dependency for development is helpful for developers, add it to +`dev.txt`. +If it is a dependency for the app that is imported in source code, add +it to `core.txt`. Then run: -```sh +``` sh pipreqs --force ``` -This will update our `requirements.txt` to include the depenency as it should be pinned in the environment. +This will update our `requirements.txt` to include the dependency as it +should be pinned in the environment. + +## Development + +[quick nbdev tutorial](https://nbdev.fast.ai/tutorials) + +Make changes in `/nbs`. +Update the package files with `nbdev_export` then reimport with +`pip install -e '.[dev]'` + +Preview doc `nbdev_preview` +Build docs, test and update README `nbdev_prepare` ## Useful links -* [Task Matrix (Formerly Visual ChatGPT)](https://github.com/microsoft/TaskMatrix) -* [LangChain](https://python.langchain.com/en/latest/index.html) -* [LLM Prompt Engineering](https://www.promptingguide.ai) -* [OpenAI best practices for prompts](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api) +- [Task Matrix (Formerly Visual + ChatGPT)](https://github.com/microsoft/TaskMatrix) +- [LangChain](https://python.langchain.com/en/latest/index.html) +- [LLM Prompt Engineering](https://www.promptingguide.ai) +- [OpenAI best practices for + prompts](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api) diff --git a/_proc/.gitignore b/_proc/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..075b2542afb820ca0c990f02a196dfbb35c41a3a --- /dev/null +++ b/_proc/.gitignore @@ -0,0 +1 @@ +/.quarto/ diff --git a/_proc/00_engineer_prompt.ipynb b/_proc/00_engineer_prompt.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..96b3f28a635954c7e4717d9e284c1aa61514f009 --- /dev/null +++ b/_proc/00_engineer_prompt.ipynb @@ -0,0 +1,231 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "description: Engineering prompts\n", + "output-file: engineer_prompt.html\n", + "title: engineer_prompt\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Setup env" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "load_dotenv()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evaluate chat backend " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Anthropic module not found. Install with `pip install anthropic`.\n", + "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "> Entering new ConversationChain chain...\n", + "Prompt after formatting:\n", + "System: The following is a conversation between a human and a friendly AI chef. \n", + "The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n", + "\n", + "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n", + "\n", + "Let's think step by step.\n", + "If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\n", + "AI: What ingredients do you wish to cook with?\n", + "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n", + "AI: Do you have any allergies I should be aware of?\n", + "Human: Allergies: \n", + "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n", + "Human: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\n", + "Respect the human's allergies (if any).\n", + "Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n", + "\n", + "###\n", + "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n", + "###\n", + "\n", + "Output format:\n", + "\n", + "**Vegan recipe name**\n", + "Preparation time (humanized)\n", + "\n", + "Ingredients (List of ingredients with quantities):\n", + "- \n", + "\n", + "Steps (detailed):\n", + "1.\n", + "2.\n", + "3.\n", + "...\n", + "AI: Sure! How about a vegan Thai tofu lettuce wraps recipe? It should take less than 30 minutes to prepare.\n", + "\n", + "**Vegan Thai Tofu Lettuce Wraps**\n", + "Preparation time: 25 minutes\n", + "\n", + "Ingredients:\n", + "- 1 package firm tofu\n", + "- 1/4 cup vegan fish sauce (you can use soy sauce as a substitute)\n", + "- 2 tablespoons maple syrup\n", + "- 1 tablespoon lime juice\n", + "- 1 teaspoon chili paste\n", + "- 1 bell pepper, sliced\n", + "- 2 carrots, julienned\n", + "- 1/4 cup sliced pickles\n", + "- 1/4 cup sliced olives\n", + "- 6 large lettuce leaves\n", + "- 1/4 cup chopped fresh cilantro\n", + "\n", + "Steps:\n", + "1. Preheat a skillet over medium-high heat and add cubed tofu. Cook for about 5-7 minutes, flipping occasionally, until all the pieces are golden brown. Set aside.\n", + "2. In a mixing bowl, whisk together the fish sauce (or soy sauce), maple syrup, lime juice, and chili paste until combined.\n", + "3. In a large mixing bowl, add the bell pepper, carrots, pickles, olives, and cooked tofu. Pour the dressing over the ingredients, and toss until everything is evenly coated with the sauce.\n", + "4. Assemble the lettuce wraps by separating the lettuce leaves and spooning the tofu mixture into each one. Top with fresh cilantro and serve immediately. Enjoy your delicious vegan Thai tofu lettuce wraps!\n", + "Human: Recommend a different recipe please.\n", + "\n", + "> Finished chain.\n", + "Of course! How about a Mediterranean-inspired sandwich that includes tofu, olives, and tomatoes?\n", + "\n", + "**Mediterranean Tofu Sandwich**\n", + "Preparation time: 20 minutes\n", + "\n", + "Ingredients:\n", + "- 1 package extra-firm tofu, drained and sliced into 1/2-inch slices\n", + "- 2 tablespoons olive oil\n", + "- 1 teaspoon dried oregano\n", + "- Salt and pepper\n", + "- 1/4 cup vegan mayo\n", + "- 1 garlic clove, minced\n", + "- 2 teaspoons lemon juice\n", + "- 1 large tomato, sliced\n", + "- 1/4 cup sliced kalamata olives\n", + "- 1/4 cup chopped lettuce\n", + "- 1/4 cup sliced pickles\n", + "- Bread of your choice (I recommend ciabatta)\n", + "\n", + "Steps:\n", + "1. Preheat a skillet over medium-high heat and add the olive oil.\n", + "2. Season the tofu slices with oregano, salt, and pepper, then add them to the skillet. Cook for about 5-7 minutes on each side or until golden brown. Set aside.\n", + "3. In a small bowl, mix the vegan mayo, minced garlic, and lemon juice. Spread the mixture onto the slices of bread.\n", + "4. Layer the tomato slices, cooked tofu, olives, lettuce, and pickles onto the bread. Add salt and pepper to taste.\n", + "5. Top with the other slice of bread, slice in half, and enjoy your delicious Mediterranean tofu sandwich!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n" + ] + } + ], + "source": [ + "chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n", + "memory = ConversationBufferMemory(return_messages=True)\n", + "chat_msgs = init_prompt.format_prompt(\n", + " ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n", + " allergies=\"\",\n", + " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n", + ")\n", + "\n", + "chat_msgs = chat_msgs.to_messages()\n", + "results = chat.generate([chat_msgs])\n", + "chat_msgs.extend(\n", + " [\n", + " results.generations[0][0].message,\n", + " MessagesPlaceholder(variable_name=\"history\"),\n", + " HumanMessagePromptTemplate.from_template(\"{input}\"),\n", + " ]\n", + ")\n", + "open_prompt = ChatPromptTemplate.from_messages(chat_msgs)\n", + "conversation = ConversationChain(\n", + " llm=chat, verbose=True, memory=memory, prompt=open_prompt\n", + ")\n", + "\n", + "result = conversation.predict(input=\"Recommend a different recipe please.\")\n", + "print(result)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_proc/01_app.ipynb b/_proc/01_app.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..6323b0ad147ab1341ba01aaa8b52931401a8cb60 --- /dev/null +++ b/_proc/01_app.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "description: Gradio app.py\n", + "output-file: app.html\n", + "title: app\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L23){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### ConversationBot\n", + "\n", + "> ConversationBot ()\n", + "\n", + "Initialize self. See help(type(self)) for accurate signature." + ], + "text/plain": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L23){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### ConversationBot\n", + "\n", + "> ConversationBot ()\n", + "\n", + "Initialize self. See help(type(self)) for accurate signature." + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#| echo: false\n", + "#| output: asis\n", + "show_doc(ConversationBot)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L86){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### launch_demo\n", + "\n", + "> launch_demo ()" + ], + "text/plain": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/app.py#L86){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### launch_demo\n", + "\n", + "> launch_demo ()" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#| echo: false\n", + "#| output: asis\n", + "show_doc(launch_demo)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load environment for the demo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running on local URL: http://127.0.0.1:7862\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + } + ], + "source": [ + "load_dotenv()\n", + "launch_demo()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_proc/02_lchain_tool.ipynb b/_proc/02_lchain_tool.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..fb6539a2f4dc82ba6814baa76dc38ea9516d1a8c --- /dev/null +++ b/_proc/02_lchain_tool.ipynb @@ -0,0 +1,2036 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "description: Exploring Langchain Tool capabilities\n", + "output-file: lchain_tool.html\n", + "title: lchain_tool\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "load_dotenv()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "tools = load_tools([\"llm-math\"], llm=llm)\n", + "agent = initialize_agent(\n", + " tools,\n", + " llm,\n", + " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", + " handle_parsing_errors=True,\n", + " verbose=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "> Entering new AgentExecutor chain...\n", + "We can calculate this using the Calculator tool.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"0.03 * 300 * 30\"\n", + "}\n", + "```\n", + "\n", + "\n", + "Observation: Answer: 270.0\n", + "Thought:Could not parse LLM output: This is the correct answer to the question.\n", + "Observation: Invalid or incomplete response\n", + "Thought:Let me try the same action again.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"0.03 * 300 * 30\"\n", + "}\n", + "```\n", + "\n", + "\n", + "Observation: Answer: 270.0\n", + "Thought:Could not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n", + "\n", + "Observation: Invalid or incomplete response\n", + "Thought:There seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"300 * 30 * 0.03\"\n", + "}\n", + "```\n", + "\n", + "\n", + "Observation: Answer: 270.0\n", + "Thought:I have successfully calculated the answer to the question using the calculator tool.\n", + "\n", + "Final Answer: 270.0\n", + "\n", + "> Finished chain.\n" + ] + }, + { + "data": { + "text/plain": [ + "{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"What is the 3% of of 300 * 30?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[SerpAPI Google Images](https://python.langchain.com/en/latest/modules/agents/tools/examples/google_serper.html#searching-for-google-images)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'title': 'Easy Tofu Pad Thai',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'source': 'Minimalist Baker',\n", + " 'rating': 4.9,\n", + " 'reviews': 117,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Pad thai rice',\n", + " 'peanut sauce',\n", + " 'thai red',\n", + " 'soy sauce',\n", + " 'bean sprouts']},\n", + " {'title': 'Vegan Pad Thai',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'source': 'Nora Cooks',\n", + " 'rating': 5.0,\n", + " 'reviews': 53,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Stir fry rice',\n", + " 'mung bean sprouts',\n", + " 'soy sauce',\n", + " 'maple syrup',\n", + " 'sriracha hot sauce']},\n", + " {'title': 'Vegan Pad Thai',\n", + " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n", + " 'source': 'Pick Up Limes',\n", + " 'rating': 5.0,\n", + " 'reviews': 34,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Brown rice noodles',\n", + " 'red hot',\n", + " 'soy sauce',\n", + " 'bean sprouts',\n", + " 'sriracha hot sauce']}]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "params = {\n", + " \"q\": \"Vegan pad thai recipes\",\n", + " \"location\": \"United States\",\n", + " \"hl\": \"en\",\n", + " \"gl\": \"us\",\n", + " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", + "}\n", + "\n", + "search = GoogleSearch(params)\n", + "results = search.get_dict()\n", + "recipes_results = results[\"recipes_results\"]\n", + "recipes_results" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "### SerpAPIWrapper\n", + "\n", + "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", + "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None,\n", + "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ], + "text/plain": [ + "---\n", + "\n", + "### SerpAPIWrapper\n", + "\n", + "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", + "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None,\n", + "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#| echo: false\n", + "#| output: asis\n", + "show_doc(SerpAPIWrapper)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/lchain_tool.py#L18){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### RecipeSerpAPIWrapper\n", + "\n", + "> RecipeSerpAPIWrapper (search_engine:Any=None, params:dict={'engine':\n", + "> 'google', 'google_domain': 'google.com', 'gl':\n", + "> 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None, aiosession:Opti\n", + "> onal[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ], + "text/plain": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/lchain_tool.py#L18){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### RecipeSerpAPIWrapper\n", + "\n", + "> RecipeSerpAPIWrapper (search_engine:Any=None, params:dict={'engine':\n", + "> 'google', 'google_domain': 'google.com', 'gl':\n", + "> 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None, aiosession:Opti\n", + "> onal[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#| echo: false\n", + "#| output: asis\n", + "show_doc(RecipeSerpAPIWrapper)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "params = {\n", + " \"location\": \"United States\",\n", + " \"hl\": \"en\",\n", + " \"gl\": \"us\",\n", + "}\n", + "search = RecipeSerpAPIWrapper(params=params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'title': 'Easy Vegan Fried Rice',\n", + " 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n", + " 'source': 'Minimalist Baker',\n", + " 'rating': 4.8,\n", + " 'reviews': 457,\n", + " 'total_time': '1 hr 15 min',\n", + " 'ingredients': ['Peanut butter',\n", + " 'grain brown rice',\n", + " 'soy sauce',\n", + " 'maple syrup',\n", + " 'chili garlic sauce']},\n", + " {'title': 'The Best Vegan Fried Rice',\n", + " 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n", + " 'source': 'Short Girl Tall Order',\n", + " 'rating': 4.8,\n", + " 'reviews': 65,\n", + " 'total_time': '28 min',\n", + " 'ingredients': ['Soy sauce',\n", + " 'white rice',\n", + " 'rice wine vinegar',\n", + " 'sugar',\n", + " 'fresh peas']},\n", + " {'title': 'Vegan Fried Rice',\n", + " 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n", + " 'source': 'Nora Cooks',\n", + " 'rating': 5.0,\n", + " 'reviews': 15,\n", + " 'total_time': '20 min',\n", + " 'ingredients': ['Gluten free',\n", + " 'nutritional yeast',\n", + " 'toasted sesame oil',\n", + " 'carrots',\n", + " 'olive oil']}]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vegan_recipes = search.run(\"Vegan fried rice recipes\")\n", + "vegan_recipes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'search_metadata': {'id': '647fff28b7b1ccd51d11a01d',\n", + " 'status': 'Success',\n", + " 'json_endpoint': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.json',\n", + " 'created_at': '2023-06-07 03:53:12 UTC',\n", + " 'processed_at': '2023-06-07 03:53:12 UTC',\n", + " 'google_images_url': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&oq=Vegan+pad+thai+recipes&uule=w+CAIQICINVW5pdGVkIFN0YXRlcw&hl=en&gl=us&tbm=isch',\n", + " 'raw_html_file': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.html',\n", + " 'total_time_taken': 10.18},\n", + " 'search_parameters': {'engine': 'google_images',\n", + " 'q': 'Vegan pad thai recipes',\n", + " 'location_requested': 'United States',\n", + " 'location_used': 'United States',\n", + " 'google_domain': 'google.com',\n", + " 'hl': 'en',\n", + " 'gl': 'us',\n", + " 'device': 'desktop'},\n", + " 'search_information': {'image_results_state': 'Results for exact spelling',\n", + " 'menu_items': [{'position': 1,\n", + " 'title': 'All',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEAI',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 2,\n", + " 'title': 'Videos',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=vid&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEAQ',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_videos&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 3, 'title': 'Images'},\n", + " {'position': 4,\n", + " 'title': 'Shopping',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=shop&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEAg',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_shopping&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 5,\n", + " 'title': 'Maps',\n", + " 'link': 'https://maps.google.com/maps?q=Vegan+pad+thai+recipes&source=lmns&entry=mc&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAR6BAgBEAo'},\n", + " {'position': 6,\n", + " 'title': 'Books',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=bks&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEA0'},\n", + " {'position': 7,\n", + " 'title': 'News',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=nws&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEA4',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes&tbm=nws'},\n", + " {'position': 8,\n", + " 'title': 'Flights',\n", + " 'link': 'https://www.google.com/travel/flights?q=Vegan+pad+thai+recipes&source=lmns&tbm=flm&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAJ6BAgBEA8'},\n", + " {'position': 9,\n", + " 'title': 'Finance',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=fin&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEBA'}]},\n", + " 'suggested_searches': [{'name': 'rice noodles',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAHoECAEQKw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Arice%2Bnoodles%3Agk0lY1Ku8x8%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b7f361a9f8fb38098b46394cb9c659c83.jpeg'},\n", + " {'name': 'gluten free',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAXoECAEQLQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Agluten%2Bfree%3A_Jv5VE84jYQ%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba4acd7acf58a4e539824754bccf790f0.jpeg'},\n", + " {'name': 'tofu',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAnoECAEQLw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Atofu%3AEdnrGNBK_3E%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b57cb6349f17e3b4997748a7fb2213981.jpeg'},\n", + " {'name': 'thai peanut sauce',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoA3oECAEQMQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bpeanut%2Bsauce%3AAOyraWKuKIU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2bc44c0d5d0eef2c4dfefe036887628a3c.jpeg'},\n", + " {'name': 'vegan gluten',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBHoECAEQMw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Avegan%2Bgluten%3AYD_J3kTgidI%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b631482aae166e90902888b39f9df86d4.jpeg'},\n", + " {'name': 'thai food',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBXoECAEQNQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bfood%3A0nWr99Uxrwc%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3abb47a217c7337c6259316ffb3146b6.jpeg'},\n", + " {'name': 'thai tofu pad',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBnoECAEQNw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Btofu%2Bpad%3A-u5KMb62hFM%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba9dc874972edb8879d31906ca8d02d1e.jpeg'},\n", + " {'name': 'food network',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoB3oECAEQOQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afood%2Bnetwork%3A4fsBYIFuk6M%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3542cf3034c40352d8800de25efd446c.jpeg'},\n", + " {'name': 'peanut butter',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCHoECAEQOw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Apeanut%2Bbutter%3AFJXMrvqXmOU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b5b6523f5ed417f4c899d005473ba16b5.jpeg'},\n", + " {'name': 'stir fry',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCXoECAEQPQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Astir%2Bfry%3Ao0twgEKDva0%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3337398b3fc538d59c1a2d960953452d.jpeg'},\n", + " {'name': 'plant based',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCnoECAEQPw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Aplant%2Bbased%3A6BEj1Wk084g%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3d37839120548e6228cc4e71e1b7c7af.jpeg'},\n", + " {'name': 'fried tofu',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoC3oECAEQQQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afried%2Btofu%3AEpVuI9_hNoU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2be19daee44662280115fa006abc2bf75b.jpeg'}],\n", + " 'images_results': [{'position': 1,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg',\n", + " 'related_content_id': 'aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/Easy-Vegan-Pad-Thai-SQUARE.jpg',\n", + " 'original_width': 1452,\n", + " 'original_height': 1453,\n", + " 'is_product': True},\n", + " {'position': 2,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg',\n", + " 'related_content_id': 'RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Thai-Recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 3,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg',\n", + " 'related_content_id': 'b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n", + " 'source': 'Lazy Cat Kitchen',\n", + " 'title': 'Healthier vegan pad thai - Lazy Cat Kitchen',\n", + " 'link': 'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2021/01/healthier-vegan-pad-thai-macro-1024x1536.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 4,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg',\n", + " 'related_content_id': 'akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'source': 'Full of Plants',\n", + " 'title': 'The Best Vegan Pad Thai - Full of Plants',\n", + " 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://fullofplants.com/wp-content/uploads/2022/03/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-thumb.jpg',\n", + " 'original_width': 1440,\n", + " 'original_height': 1440,\n", + " 'is_product': True},\n", + " {'position': 5,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg',\n", + " 'related_content_id': 'MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n", + " 'source': 'earthofmaria.com',\n", + " 'title': 'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria',\n", + " 'link': 'https://earthofmaria.com/easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://earthofmaria.com/wp-content/uploads/2019/04/Easy-Vegan-Pad-Thai-Gluten-free-6.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 6,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36f9a1c02c421efe07d8d147f542087ff245f0933ec60896cd.jpeg',\n", + " 'related_content_id': 'N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n", + " 'source': 'My Darling Vegan',\n", + " 'title': 'Easy Vegan Pad Thai - My Darling Vegan',\n", + " 'link': 'https://www.mydarlingvegan.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.mydarlingvegan.com/wp-content/uploads/2021/07/Vegan-Pad-Thai-2.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 7,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a75a0136dd1f95918c9bb1ded2f17e5c31f13d3708cc723f.jpeg',\n", + " 'related_content_id': 'NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n", + " 'source': 'Pinch Me Good',\n", + " 'title': 'Easy Vegetarian Pad Thai - Pinch Me Good',\n", + " 'link': 'https://pinchmegood.com/easy-vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://pinchmegood.com/wp-content/uploads/2019/03/Easy-Vegetarian-Pad-Thai.jpg',\n", + " 'original_width': 924,\n", + " 'original_height': 1386,\n", + " 'is_product': True},\n", + " {'position': 8,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36cdf1d570098da37da75a20a5a2ed59916c3cc1ac656f5b45.jpeg',\n", + " 'related_content_id': 'NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n", + " 'source': 'Vegan Huggs',\n", + " 'title': '30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs',\n", + " 'link': 'https://veganhuggs.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veganhuggs.com/wp-content/uploads/2019/03/vegan-pad-thai-3.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 1020,\n", + " 'is_product': True},\n", + " {'position': 9,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd364677ba205872944cc9932a27c40873a1e3f4424ca6219c9b.jpeg',\n", + " 'related_content_id': 'OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'source': 'Ministry of Curry',\n", + " 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n", + " 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-1.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 10,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3600f3b428f18999842a7c3ddc41991cd1d626950bd108397d.jpeg',\n", + " 'related_content_id': 'bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n", + " 'source': 'Lazy Cat Kitchen',\n", + " 'title': 'Vegan pad thai - Lazy Cat Kitchen',\n", + " 'link': 'https://www.lazycatkitchen.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2016/05/vegan-pad-thai-1000x1500.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1500,\n", + " 'is_product': True},\n", + " {'position': 11,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224470ef6b1b3462b418875bdedefa3d79.jpeg',\n", + " 'related_content_id': 'NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n", + " 'source': 'Well Plated by Erin',\n", + " 'title': 'Vegetarian Pad Thai {30-Minute Recipe} - WellPlated.com',\n", + " 'link': 'https://www.wellplated.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.wellplated.com/wp-content/uploads/2017/08/Healthy-Vegetarian-Pad-Thai.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1469,\n", + " 'is_product': True},\n", + " {'position': 12,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82276df3b8fda0d0c061010978e4b536cc1.jpeg',\n", + " 'related_content_id': 'WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n", + " 'source': 'The Spruce Eats',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.thespruceeats.com/vegetarian-pad-thai-3217746',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thespruceeats.com/thmb/wF19pUZKaKo66pofbpjI0eS1SLc=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/vegetarian-pad-thai-3217746-step-11-231a859fac40430583b044297aaf4a87.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 13,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82281ba3f6ced7a769ced6de3c3b0f1fe41.jpeg',\n", + " 'related_content_id': 'MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/Y6WvULetSWWIjzcQONSg9n8PFgg=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-2f0142cca68e4f9592381d281a391d59.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 14,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224df1973dd2dbff9bcbe3402164ae150c.jpeg',\n", + " 'related_content_id': 'bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n", + " 'source': 'Food Network',\n", + " 'title': 'Vegetarian Pad Thai Recipe | Food Network Kitchen | Food Network',\n", + " 'link': 'https://www.foodnetwork.com/recipes/food-network-kitchen/vegetarian-pad-thai-7183115',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2019/9/10/0/FNK_Vegetarian-Tofu-Pad-Thai_H2_s4x3.jpg.rend.hgtvcom.616.462.suffix/1568385716096.jpeg',\n", + " 'original_width': 616,\n", + " 'original_height': 462,\n", + " 'is_product': True},\n", + " {'position': 15,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822ed36be9df00a80e5203ab96f92fc31fd.jpeg',\n", + " 'related_content_id': 'RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'source': 'Bianca Zapatka',\n", + " 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n", + " 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/pad-thai-vegan-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-720x1008.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 1008,\n", + " 'is_product': True},\n", + " {'position': 16,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8223cb49bc3c204d16373a0a6e257d6e54f.jpeg',\n", + " 'related_content_id': 'UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n", + " 'source': 'EatPlant-Based.com',\n", + " 'title': 'Easy Vegan Pad Thai - EatPlant-Based',\n", + " 'link': 'https://eatplant-based.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://eatplant-based.com/wp-content/uploads/2022/03/Awakened-Pad-Thai-3.jpeg',\n", + " 'original_width': 668,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 17,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225dcace1e2fb2aebe208ed1bfde7e8775.jpeg',\n", + " 'related_content_id': 'UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n", + " 'source': 'Taste of Home',\n", + " 'title': 'Vegetarian Pad Thai Recipe: How to Make It',\n", + " 'link': 'https://www.tasteofhome.com/recipes/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://tmbidigitalassetsazure.blob.core.windows.net/rms3-prod/attachments/37/1200x1200/Vegetarian-Pad-Thai_EXPS_HCK18_197935_B04_014_4b.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 18,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82263e484cb2a264123c087cf8b9eb10c0d.jpeg',\n", + " 'related_content_id': 'djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n", + " 'source': 'Taste',\n", + " 'title': '10-minute vegetarian pad Thai recipe',\n", + " 'link': 'https://www.taste.com.au/recipes/10-minute-vegetarian-pad-thai-recipe/4bq39nic',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://img.taste.com.au/jgHrD_eG/w720-h480-cfill-q80/taste/2021/02/10-minute-vegetarian-pad-thai-168946-2.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 480,\n", + " 'is_product': True},\n", + " {'position': 19,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822f423edd39d8f9d0285cc270a8c00a7ee.jpeg',\n", + " 'related_content_id': 'ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n", + " 'source': 'YouTube',\n", + " 'title': 'Vegetarian Pad Thai Recipe TO MAKE TONIGHT (ผัดไทย)! - YouTube',\n", + " 'link': 'https://www.youtube.com/watch?v=zy_P70hXhdM',\n", + " 'tag': '8:44',\n", + " 'original': 'https://i.ytimg.com/vi/zy_P70hXhdM/maxresdefault.jpg',\n", + " 'original_width': 1280,\n", + " 'original_height': 720,\n", + " 'is_product': True},\n", + " {'position': 20,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225cd1fe40684d95943ec058d4b84eb560.jpeg',\n", + " 'related_content_id': 'UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'source': 'Vegan Recipes from Cassie Howard',\n", + " 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n", + " 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 903,\n", + " 'is_product': True},\n", + " {'position': 21,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvfVfg8ufhxGbAvq1idiNghBJ-fXS2MqelDQ&usqp=CAU',\n", + " 'related_content_id': 'NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'source': 'Spice Cravings',\n", + " 'title': 'Vegan Pad Thai | Spice Cravings',\n", + " 'link': 'https://spicecravings.com/vegan-pad-thai',\n", + " 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 22,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJ89CXPkap5RGkJHmeArqtTdY3pSO7w0DdNQ&usqp=CAU',\n", + " 'related_content_id': 'bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n", + " 'source': 'Pick Up Limes',\n", + " 'title': 'Vegan Pad Thai | Pick Up Limes',\n", + " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn.pickuplimes.com/cache/1d/72/1d7201d4341ab93affd3ecfec7a7d5a2.jpg',\n", + " 'original_width': 1280,\n", + " 'original_height': 1920,\n", + " 'is_product': True},\n", + " {'position': 23,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzjMINzFCCY2VU4QrzHkzBsVvtiJHsoF4Apw&usqp=CAU',\n", + " 'related_content_id': 'MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n", + " 'source': 'The Healthy Maven',\n", + " 'title': 'Veggie Pad Thai Recipe [20 Minutes] - The Healthy Maven',\n", + " 'link': 'https://www.thehealthymaven.com/pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thehealthymaven.com/wp-content/uploads/2020/03/veggie-pad-thai-4-1-e1583795458972.jpg',\n", + " 'original_width': 780,\n", + " 'original_height': 790,\n", + " 'is_product': True},\n", + " {'position': 24,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcv-xbBlo4x_uqyZY7fN4xVDtd0keRb9zt2Q&usqp=CAU',\n", + " 'related_content_id': 'aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'source': \"Del's cooking twist\",\n", + " 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n", + " 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3679.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1740,\n", + " 'is_product': True},\n", + " {'position': 25,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-3rXOoQrYAAnTPYimImLdkllhrvwGjtpzuQ&usqp=CAU',\n", + " 'related_content_id': 'cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n", + " 'source': \"Omnivore's Cookbook\",\n", + " 'title': \"Vegan Pad Thai - Omnivore's Cookbook\",\n", + " 'link': 'https://omnivorescookbook.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://omnivorescookbook.com/wp-content/uploads/2019/04/1401_Vegan-Pad-Thai_002.jpg',\n", + " 'original_width': 800,\n", + " 'original_height': 1198,\n", + " 'is_product': True},\n", + " {'position': 26,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRA6EbuGHJJ05llESu7R4DnXGJz0tLdAKHCag&usqp=CAU',\n", + " 'related_content_id': 'aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n", + " 'source': 'plantd',\n", + " 'title': 'Vegan Pad Thai with Peanut Sauce',\n", + " 'link': 'https://plantd.co/vegan-pad-thai-with-peanut-sauce/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://plantd.co/wp-content/uploads/2020/03/Vegan-Pad-Thai-with-Peanut-Sauce.png',\n", + " 'original_width': 1600,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 27,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-tJjj9tbpEaxSJtIxspo7uUdJEUzv9RvOIg&usqp=CAU',\n", + " 'related_content_id': 'dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'source': 'From My Bowl',\n", + " 'title': 'Vegan Pad Thai - From My Bowl',\n", + " 'link': 'https://frommybowl.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-19-1.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 28,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNiutaTkD8VXJuR7_mWK2pI6B7cPV98YJ1Yw&usqp=CAU',\n", + " 'related_content_id': 'NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n", + " 'source': 'The Foodie Takes Flight',\n", + " 'title': 'Vegan Pad Thai - The Foodie Takes Flight',\n", + " 'link': 'https://thefoodietakesflight.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://thefoodietakesflight.com/wp-content/uploads/2021/06/vegan-pad-thai-recipe-10.png',\n", + " 'original_width': 790,\n", + " 'original_height': 1150,\n", + " 'is_product': True},\n", + " {'position': 29,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtjaP5_LFHgeZL956hjrCANLq2zxN0VcNuDw&usqp=CAU',\n", + " 'related_content_id': 'S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n", + " 'source': 'One Ingredient Chef',\n", + " 'title': 'Vegetarian Pad Thai Recipe | One Ingredient Chef',\n", + " 'link': 'https://www.oneingredientchef.com/vegetarian-pad-thai/',\n", + " 'original': 'https://www.oneingredientchef.com/wp-content/uploads/2013/06/VegetarianPadThai.jpg',\n", + " 'original_width': 700,\n", + " 'original_height': 783,\n", + " 'is_product': False},\n", + " {'position': 30,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8a0V5sne-due2_0i_cLMG7mIDmIWWIlNdyg&usqp=CAU',\n", + " 'related_content_id': 'RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n", + " 'source': 'Love and Good Stuff',\n", + " 'title': 'Vegetable Pad Thai - Love & Good Stuff',\n", + " 'link': 'https://loveandgoodstuff.com/vegetable-pad-thai/',\n", + " 'original': 'https://loveandgoodstuff.com/wp-content/uploads/2018/04/vegetable-pad-thai-6.jpg',\n", + " 'original_width': 669,\n", + " 'original_height': 1000,\n", + " 'is_product': False},\n", + " {'position': 31,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq76Wud8JULmlFchKPTVnyslWUxpH0-tSocw&usqp=CAU',\n", + " 'related_content_id': 'YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n", + " 'source': 'Vibrant plate',\n", + " 'title': 'The Best Vegan Tofu Pad Thai - Vibrant plate',\n", + " 'link': 'https://www.vibrantplate.com/best-vegan-tofu-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.vibrantplate.com/wp-content/uploads/2021/01/Vegan-Tofu-Pad-Thai-05.jpg',\n", + " 'original_width': 800,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 32,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTMA_IXXqLXbDaKJStkocE79DhiNy3h1wNfyg&usqp=CAU',\n", + " 'related_content_id': 'X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'source': 'From My Bowl',\n", + " 'title': 'Vegan Pad Thai - From My Bowl',\n", + " 'link': 'https://frommybowl.com/vegan-pad-thai/',\n", + " 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-23.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1500,\n", + " 'is_product': False},\n", + " {'position': 33,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUQbieaco9iYa16jcjeZbf-gmoP7gSvJyl0Q&usqp=CAU',\n", + " 'related_content_id': 'd1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n", + " 'source': 'BBC',\n", + " 'title': 'Vegetable pad Thai recipe - BBC Food',\n", + " 'link': 'https://www.bbc.co.uk/food/recipes/stirfryvegetarianpha_70987',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://ichef.bbci.co.uk/food/ic/food_16x9_832/recipes/stirfryvegetarianpha_70987_16x9.jpg',\n", + " 'original_width': 832,\n", + " 'original_height': 468,\n", + " 'is_product': True},\n", + " {'position': 34,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT1WQnyJsXAny3gepgi_275uhe3V8VkQTMRtw&usqp=CAU',\n", + " 'related_content_id': 'U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n", + " 'source': 'Cilantro and Citronella',\n", + " 'title': 'Vegetarian Pad Thai',\n", + " 'link': 'https://www.cilantroandcitronella.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.cilantroandcitronella.com/wp-content/uploads/2015/03/pad-thai_1_04.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 1020,\n", + " 'is_product': True},\n", + " {'position': 35,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT9yCD2ZFN3V0txxVJK59VZKQw8dHdf52U_9w&usqp=CAU',\n", + " 'related_content_id': 'ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n", + " 'source': 'Eat With Clarity',\n", + " 'title': 'Best Vegan Pad Thai (Easy!) - Eat With Clarity',\n", + " 'link': 'https://eatwithclarity.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://eatwithclarity.com/wp-content/uploads/2020/06/vegan-pad-thai-9.jpg',\n", + " 'original_width': 1190,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 36,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-b-oobMM5KXLy32E-dTEmszExv0RTVq8OQQ&usqp=CAU',\n", + " 'related_content_id': 'VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n", + " 'source': 'Tesco Real Food',\n", + " 'title': 'Vegetarian pad Thai | Tesco Real Food',\n", + " 'link': 'https://realfood.tesco.com/recipes/vegetarian-pad-thai.html',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://realfood.tesco.com/media/images/Veg-Pad-Thai-LGH-069d45e9-fd6c-44d1-b747-83dbac2d921d-0-1400x919.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 919,\n", + " 'is_product': True},\n", + " {'position': 37,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtwz03hn90q7ot7m4-179UzOn7cQYaLBHrnA&usqp=CAU',\n", + " 'related_content_id': 'aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n", + " 'source': 'Klaraslife',\n", + " 'title': 'Vegan Pad Thai with cashew butter & broccoli - Klara`s Life',\n", + " 'link': 'https://klaraslife.com/en/vegan-pad-thai-with-cashew-butter-broccoli/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://klaraslife.com/wp-content/uploads/2019/11/IMG_0935.jpg',\n", + " 'original_width': 4000,\n", + " 'original_height': 5895,\n", + " 'is_product': True},\n", + " {'position': 38,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQDKEP2qkfB6nWHtF58pTBj7TJv2Jz63JYOw&usqp=CAU',\n", + " 'related_content_id': 'Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n", + " 'source': 'Fit Foodie Nutter',\n", + " 'title': '30 MINUTE EASY VEGAN PAD THAI –',\n", + " 'link': 'https://fitfoodienutter.com/recipe/30-minute-easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://fitfoodienutter.com/wp-content/uploads/2021/09/Vegan-Pad-Thai-12.jpg',\n", + " 'original_width': 870,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 39,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIadiylajWRN_JnkLntJZSunU8qi7S1wxGvQ&usqp=CAU',\n", + " 'related_content_id': 'SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n", + " 'source': 'Gimme Some Oven',\n", + " 'title': 'Pad Thai - Gimme Some Oven',\n", + " 'link': 'https://www.gimmesomeoven.com/pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.gimmesomeoven.com/wp-content/uploads/2019/01/Pad-Thai-Recipe-1.jpg',\n", + " 'original_width': 1392,\n", + " 'original_height': 2088,\n", + " 'is_product': True},\n", + " {'position': 40,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIpRVuMoifY2CKjWhZ_37sDaI5hp1tAw5T1Q&usqp=CAU',\n", + " 'related_content_id': 'SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n", + " 'source': 'The Kitchen Abroad',\n", + " 'title': 'Quick One Pan Vegan Pad Thai Recipe with Tofu',\n", + " 'link': 'https://www.thekitchenabroad.com/one-pan-vegan-pad-thai-recipe-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thekitchenabroad.com/wp-content/uploads/2020/06/Vegan-Pad-Thai-Recipe-with-Tofu-10.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1365,\n", + " 'is_product': True},\n", + " {'position': 41,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTkI3AiNwZau82RGak_znF-NEWDMatcRdQ_2Q&usqp=CAU',\n", + " 'related_content_id': 'SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n", + " 'source': 'Food Network',\n", + " 'title': 'Quick Veggie Pad Thai Recipe | Ree Drummond | Food Network',\n", + " 'link': 'https://www.foodnetwork.com/recipes/ree-drummond/quick-veggie-pad-thai-9422028',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2020/09/25/WU2503__vegetable-pad-thai_s4x3.jpg.rend.hgtvcom.616.462.suffix/1601058180561.jpeg',\n", + " 'original_width': 616,\n", + " 'original_height': 462,\n", + " 'is_product': True},\n", + " {'position': 42,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRJRZhgKxI1FzkCO0zB3RxLW1vAsi4WwL0Y7w&usqp=CAU',\n", + " 'related_content_id': 'aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'source': 'Delish Knowledge',\n", + " 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n", + " 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles5-copy-1.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 43,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSGA5db-ShQpar2dyZk0cAxA4-cdHYsisG3g&usqp=CAU',\n", + " 'related_content_id': 'Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'source': 'Six Hungry Feet',\n", + " 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n", + " 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n", + " 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-10.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1500,\n", + " 'is_product': False},\n", + " {'position': 44,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQolfY7XMQv1Q3zJr8XCj0pasBRTBn7MrJocA&usqp=CAU',\n", + " 'related_content_id': 'Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n", + " 'source': 'White On Rice Couple',\n", + " 'title': 'Vegetable Pad Thai Recipe w/ Cabbage EASY HEALTHY | White On Rice',\n", + " 'link': 'https://whiteonricecouple.com/cabbage-vegetable-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://whiteonricecouple.com/recipe/images/Cabbage-Vegetable-Pad-Thai-1.jpg',\n", + " 'original_width': 530,\n", + " 'original_height': 699,\n", + " 'is_product': True},\n", + " {'position': 45,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSium1YAIBcY-ty66CcxIZfjPydnxVlddWGwQ&usqp=CAU',\n", + " 'related_content_id': 'VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-14.jpg',\n", + " 'original_width': 1456,\n", + " 'original_height': 2184,\n", + " 'is_product': False},\n", + " {'position': 46,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_1bo3u0kxqiO87hkxwyR5bhvZtWff-OdRRA&usqp=CAU',\n", + " 'related_content_id': 'dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n", + " 'source': 'Make It Dairy Free',\n", + " 'title': 'Vegan Pad Thai - Make It Dairy Free',\n", + " 'link': 'https://makeitdairyfree.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://makeitdairyfree.com/wp-content/uploads/2022/12/vegan-pad-thai-2.jpg',\n", + " 'original_width': 736,\n", + " 'original_height': 1104,\n", + " 'is_product': True},\n", + " {'position': 47,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSW5-PJKenKvHTGKrhmzwyhhFUlvEkg25eRuQ&usqp=CAU',\n", + " 'related_content_id': 'WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'source': 'Bianca Zapatka',\n", + " 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n", + " 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/vegan-pad-thai-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-asian-food.jpg',\n", + " 'original_width': 1440,\n", + " 'original_height': 2016,\n", + " 'is_product': True},\n", + " {'position': 48,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRiWrdDbuV_CM0exB7yBqyoCOWaYqD6nTtJQ&usqp=CAU',\n", + " 'related_content_id': 'T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n", + " 'source': 'Running on Real Food',\n", + " 'title': 'Easy Vegan Tofu Pad Thai Recipe - Running on Real Food',\n", + " 'link': 'https://runningonrealfood.com/tofu-pad-thai/',\n", + " 'original': 'https://runningonrealfood.com/wp-content/uploads/2021/05/Best-Vegan-Tofu-Pad-Thai-Recipe-12.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 2100,\n", + " 'is_product': False},\n", + " {'position': 49,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtOw74y8VyL5dib33Rkr_Bu4Jo9K4Q3sJy1w&usqp=CAU',\n", + " 'related_content_id': 'Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/zH71oEuQnxw3B8536gZDM2_NkWI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-3-f47ff2bc806b4de9821e332a6126bcc1.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 2250,\n", + " 'is_product': True},\n", + " {'position': 50,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCaY87F2KeBqK2WQUNljTakrtO7Zlae5L4g&usqp=CAU',\n", + " 'related_content_id': 'M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n", + " 'source': 'Whitney Bond',\n", + " 'title': 'Vegetable Pad Thai Recipe - WhitneyBond.com',\n", + " 'link': 'https://whitneybond.com/whats-for-dinner-spicy-vegetable-pad-thai/',\n", + " 'original': 'https://whitneybond.com/wp-content/uploads/2013/01/Vegetable-Pad-Thai-4.jpg',\n", + " 'original_width': 1140,\n", + " 'original_height': 1280,\n", + " 'is_product': False},\n", + " {'position': 51,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSDWkQoMHapJVpYkNaQJbPyubSBwdP5is9eaw&usqp=CAU',\n", + " 'related_content_id': 'eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'source': 'Six Hungry Feet',\n", + " 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n", + " 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1500,\n", + " 'is_product': True},\n", + " {'position': 52,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQxAM2SH_lgbsUJZh0aljTp6OEQ0lNfSd2_BQ&usqp=CAU',\n", + " 'related_content_id': 'cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n", + " 'source': \"Mom's Dinner\",\n", + " 'title': \"The Best Vegetable Pad Thai - Mom's Dinner\",\n", + " 'link': 'https://momsdinner.net/vegetable-pad-thai/',\n", + " 'original': 'https://momsdinner.net/wp-content/uploads/2021/04/Vegetable-Pad-Thai-Recipe-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1680,\n", + " 'is_product': False},\n", + " {'position': 53,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwMUvtpa5kSIoAJ3kltgwtiuUYkvK9DJyg3w&usqp=CAU',\n", + " 'related_content_id': 'NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n", + " 'source': 'From The Comfort Of My Bowl',\n", + " 'title': 'Easy Vegan Pad Thai - From The Comfort Of My Bowl',\n", + " 'link': 'https://www.fromthecomfortofmybowl.com/vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.fromthecomfortofmybowl.com/wp-content/uploads/2021/03/best-vegan-pad-thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 900,\n", + " 'is_product': True},\n", + " {'position': 54,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPqWPCZyN1t4YbQNSYBWPLWSwzenu1C7a52A&usqp=CAU',\n", + " 'related_content_id': 'ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'source': 'Nora Cooks',\n", + " 'title': 'Vegan Pad Thai - Nora Cooks',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-5.jpg',\n", + " 'original_width': 1334,\n", + " 'original_height': 2001,\n", + " 'is_product': False},\n", + " {'position': 55,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREUFAdGtWRgMx9Qv45bdNbkRdlZnSFQZX7tQ&usqp=CAU',\n", + " 'related_content_id': 'bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n", + " 'source': 'Vegan Heaven',\n", + " 'title': 'Vegan Pad Thai - Vegan Heaven',\n", + " 'link': 'https://veganheaven.org/recipe/vegan-pad-thai/',\n", + " 'original': 'https://veganheaven.org/wp-content/uploads/2019/04/Vegan-Pad-Thai_.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 900,\n", + " 'is_product': False},\n", + " {'position': 56,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQW5Nh8vx1J5kcDtF7MZSnXljnKoalv8wq2RA&usqp=CAU',\n", + " 'related_content_id': 'cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-1-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 57,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRUtq_lbZ4d5Xfs2jW-qamRXEi-0T6rhsLjTg&usqp=CAU',\n", + " 'related_content_id': 'bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n", + " 'source': 'The Petite Cook',\n", + " 'title': 'The Easiest Vegan Pad Thai - The Petite Cook™',\n", + " 'link': 'https://www.thepetitecook.com/the-easiest-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thepetitecook.com/wp-content/uploads/2017/03/vegan-pad-thai-recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 58,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4uozc69jm3VWqxSKMG8hWocGvUtO4CXHPeA&usqp=CAU',\n", + " 'related_content_id': 'cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n", + " 'source': 'Food with Feeling',\n", + " 'title': 'Vegan Pad Thai - Food with Feeling',\n", + " 'link': 'https://foodwithfeeling.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://foodwithfeeling.com/wp-content/uploads/2021/02/Vegan-Pad-Thai-7.jpg',\n", + " 'original_width': 700,\n", + " 'original_height': 1050,\n", + " 'is_product': True},\n", + " {'position': 59,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcShtayJD_o-2NYDRaFdO7kc0IBDFrXsaLRAmw&usqp=CAU',\n", + " 'related_content_id': 'VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n", + " 'source': 'HealthyGirl Kitchen',\n", + " 'title': 'Vegan Pad Thai (easy!) - HealthyGirl Kitchen',\n", + " 'link': 'https://healthygirlkitchen.com/recipes/authentic-vegan-pad-thai/',\n", + " 'original': 'https://healthygirlkitchen.com/wp-content/uploads/2020/11/20201112-DSC_6273-2.jpeg',\n", + " 'original_width': 2500,\n", + " 'original_height': 1669,\n", + " 'is_product': False},\n", + " {'position': 60,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFnQxVF9fa3yOIanaxEOhaThezpWFnL4LdKw&usqp=CAU',\n", + " 'related_content_id': 'Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n", + " 'source': 'PETA',\n", + " 'title': 'Easy Vegan Pad Thai | PETA',\n", + " 'link': 'https://www.peta.org/recipes/easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.peta.org/wp-content/uploads/2014/03/vegan-pad-thai-e1429117378854-602x452-1444238253.jpg',\n", + " 'original_width': 602,\n", + " 'original_height': 452,\n", + " 'is_product': True},\n", + " {'position': 61,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJ2bEV_hnyoEftoYQQ2ivw6GAWsG3zvHcH2A&usqp=CAU',\n", + " 'related_content_id': 'NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'source': 'Ministry of Curry',\n", + " 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n", + " 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n", + " 'tag': 'Video',\n", + " 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-2.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 62,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0nCQUNnm-ZcLUpjYC487WehnBzJaNNAlVsA&usqp=CAU',\n", + " 'related_content_id': 'cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n", + " 'source': 'Crowded Kitchen',\n", + " 'title': 'Vegan Pad Thai with Tofu - Crowded Kitchen',\n", + " 'link': 'https://www.crowdedkitchen.com/vegan-pad-thai/',\n", + " 'original': 'https://www.crowdedkitchen.com/wp-content/uploads/2021/01/pad-thai-new-8.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 63,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT96UeZ4BgEN0Q2Xp0fwWYr8KuHmgbo64Lukw&usqp=CAU',\n", + " 'related_content_id': 'dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n", + " 'source': 'Healing Tomato',\n", + " 'title': 'Pad Thai Recipe (Vegan) - HealingTomato.com',\n", + " 'link': 'https://www.healingtomato.com/pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.healingtomato.com/wp-content/uploads/2016/01/pad-thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 593,\n", + " 'is_product': True},\n", + " {'position': 64,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQs0sHzHet343DWkhIN84nY2KeHE-mAR3zFTA&usqp=CAU',\n", + " 'related_content_id': 'QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'source': 'Detoxinista',\n", + " 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n", + " 'link': 'https://detoxinista.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1627,\n", + " 'is_product': True},\n", + " {'position': 65,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHQuNuSPWyl4_RjkFeElvxvkLOtuWWqW6GAQ&usqp=CAU',\n", + " 'related_content_id': 'emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n", + " 'source': 'Loving It Vegan',\n", + " 'title': 'Vegan Pad Thai - Loving It Vegan',\n", + " 'link': 'https://lovingitvegan.com/vegan-pad-thai/',\n", + " 'original': 'https://lovingitvegan.com/wp-content/uploads/2022/06/Vegan-Pad-Thai-22.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 66,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjWUg8dInH0c5rR8rRXl8EMKCxg1ccEhUekQ&usqp=CAU',\n", + " 'related_content_id': 'RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n", + " 'source': 'Hot For Food',\n", + " 'title': 'vegan pad thai - hot for food by Lauren Toyota',\n", + " 'link': 'https://www.hotforfoodblog.com/recipes/2015/02/02/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.hotforfoodblog.com/wp-content/uploads/2015/02/veganpadthai_hotforfoodblog_filtered1-500x375.jpg',\n", + " 'original_width': 500,\n", + " 'original_height': 375,\n", + " 'is_product': True},\n", + " {'position': 67,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSur4LsaevwvR_0eZ2F3Tf-YVx6-jDRus6E-w&usqp=CAU',\n", + " 'related_content_id': 'TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'source': 'Vegan Recipes from Cassie Howard',\n", + " 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n", + " 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai-Vegan.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 399,\n", + " 'is_product': True},\n", + " {'position': 68,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRTcDJm39S6nz4sTyLF-l6j6CeiVTVkPOXQ5g&usqp=CAU',\n", + " 'related_content_id': 'WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n", + " 'source': 'Gluten-Free, Allergy-Free, and Vegan Recipes',\n", + " 'title': 'Easy Vegan Pad Thai (Gluten-Free, Allergy-Free, Nut-Free, Soy-Free)',\n", + " 'link': 'https://strengthandsunshine.com/vegan-pad-thai-gluten-free/',\n", + " 'original': 'https://strengthandsunshine.com/wp-content/uploads/2019/05/Easy-Vegan-Pad-Thai-Gluten-Free-Allergy-Free-PM1.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': False},\n", + " {'position': 69,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQru1It4T3WzwaedAbLeetEsVNE6DkIrC4L4w&usqp=CAU',\n", + " 'related_content_id': 'dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n", + " 'source': \"Archana's Kitchen\",\n", + " 'title': \"Vegetarian Pad Thai Recipe by Archana's Kitchen\",\n", + " 'link': 'https://www.archanaskitchen.com/vegetarian-pad-thai',\n", + " 'original': 'https://www.archanaskitchen.com/images/archanaskitchen/0-Archanas-Kitchen-Recipes/2018/Vegetarian_Pad_Thai_Recipe-4-2.jpg',\n", + " 'original_width': 1600,\n", + " 'original_height': 1200,\n", + " 'is_product': False},\n", + " {'position': 70,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSTdgEdXp-bEPIX-4ssadcX6rzD4KQxGE5w&usqp=CAU',\n", + " 'related_content_id': 'ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-6.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 71,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTyPzitaptGw98mR0Oqbxxc2B8FtDlN7vpDDw&usqp=CAU',\n", + " 'related_content_id': 'RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n", + " 'source': 'Fooby',\n", + " 'title': 'Vegan Pad Thai - Recipes | fooby.ch',\n", + " 'link': 'https://fooby.ch/en/recipes/17187/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://recipecontent.fooby.ch/17187_3-2_480-320.jpg',\n", + " 'original_width': 480,\n", + " 'original_height': 321,\n", + " 'is_product': True},\n", + " {'position': 72,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9woGokoujYfjUge4wgpyswfCjstd_9uf1qw&usqp=CAU',\n", + " 'related_content_id': 'XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'source': 'Nora Cooks',\n", + " 'title': 'Vegan Pad Thai - Nora Cooks',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-7.jpg',\n", + " 'original_width': 1334,\n", + " 'original_height': 2001,\n", + " 'is_product': False},\n", + " {'position': 73,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSexYRHt5Ul2JMDLnWUdBxc6ELsg2E1iDL31w&usqp=CAU',\n", + " 'related_content_id': 'ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'source': \"Del's cooking twist\",\n", + " 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n", + " 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n", + " 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3702.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 822,\n", + " 'is_product': False},\n", + " {'position': 74,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnQTyIRwdSk4FpeGIc-MQnw9411wG2ENeCIg&usqp=CAU',\n", + " 'related_content_id': 'TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-13.jpg',\n", + " 'original_width': 1456,\n", + " 'original_height': 2184,\n", + " 'is_product': False},\n", + " {'position': 75,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREuE_KU8at0L9CjOGH_t4b-8Up9fL1WBIsUg&usqp=CAU',\n", + " 'related_content_id': 'RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n", + " 'source': 'Tasty',\n", + " 'title': 'Vegan Pad Thai Recipe by Tasty',\n", + " 'link': 'https://tasty.co/recipe/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://img.buzzfeed.com/thumbnailer-prod-us-east-1/video-api/assets/148610.jpg?resize=1200:*',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 76,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRqsk8XwnF_PLPcNqIatUj46HUH78xjZGBA5g&usqp=CAU',\n", + " 'related_content_id': 'X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n", + " 'source': 'Brand New Vegan',\n", + " 'title': 'Easy Vegan Pad Thai - Brand New Vegan',\n", + " 'link': 'https://www.brandnewvegan.com/recipes/easy-vegan-pad-thai',\n", + " 'original': 'https://www.brandnewvegan.com/wp-content/uploads/easy-vegan-pad-thai-h1-1024x682.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 682,\n", + " 'is_product': False},\n", + " {'position': 77,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTjlYvkOX8aA0iNS-32KeueAcXbjYMIcRkfnQ&usqp=CAU',\n", + " 'related_content_id': 'TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n", + " 'source': \"Kathy's Vegan Kitchen\",\n", + " 'title': \"Vegan Pad Thai Recipe | Kathy's Vegan Kitchen\",\n", + " 'link': 'https://www.kathysvegankitchen.com/vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.kathysvegankitchen.com/wp-content/uploads/2021/09/Pad-Thai-.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1277,\n", + " 'is_product': True},\n", + " {'position': 78,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEcvBpOj0RPCU23uRqHp6VJJrxfS3tQYnURw&usqp=CAU',\n", + " 'related_content_id': 'SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n", + " 'source': 'Real Thai Recipes',\n", + " 'title': 'Vegetarian Pad Thai » Real Thai Recipes » Authentic Thai recipes from Thailand',\n", + " 'link': 'https://www.realthairecipes.com/recipes/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.realthairecipes.com/wp-content/uploads/vegetarian-pad-thai1.jpg',\n", + " 'original_width': 440,\n", + " 'original_height': 261,\n", + " 'is_product': True},\n", + " {'position': 79,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJulkx7A2HLYWmkLlETfrNWofaQ6XllHyzeg&usqp=CAU',\n", + " 'related_content_id': 'ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n", + " 'source': 'Choosing Chia',\n", + " 'title': 'Raw Pad Thai - Choosing Chia',\n", + " 'link': 'https://choosingchia.com/raw-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://choosingchia.com/jessh-jessh/uploads/2021/06/raw-pad-thai-4.jpg',\n", + " 'original_width': 1360,\n", + " 'original_height': 2040,\n", + " 'is_product': True},\n", + " {'position': 80,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRf0Cju8qWUiOS3tuTGbs7-pXIIdVRzRLVJcQ&usqp=CAU',\n", + " 'related_content_id': 'TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n", + " 'source': \"Cook's Hideout\",\n", + " 'title': \"Vegan Pad Thai Noodles | Cook's Hideout\",\n", + " 'link': 'https://www.cookshideout.com/pad-thai-vegan-recipe',\n", + " 'tag': '0:51',\n", + " 'original': 'https://www.cookshideout.com/wp-content/uploads/2014/03/Vegan-Pad-Thai_4S.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1807,\n", + " 'is_product': True},\n", + " {'position': 81,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq0f_iTXyVwmnFhPzttm7_lJp8ajUCmufkNQ&usqp=CAU',\n", + " 'related_content_id': 'SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n", + " 'source': \"Chang's\",\n", + " 'title': \"Rainbow Vegetarian Pad Thai with Crispy Noodles - Chang's Authentic Asian Cooking\",\n", + " 'link': 'https://www.changs.com/recipes/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles/',\n", + " 'original': 'https://ik.imagekit.io/webtactics/changs/tr:w-750,h-1000/cgblog/id298/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles.jpg',\n", + " 'original_width': 750,\n", + " 'original_height': 1000,\n", + " 'is_product': False},\n", + " {'position': 82,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNxrIDPiE9qq8FTzKays6PAe4vKBNCSql2dw&usqp=CAU',\n", + " 'related_content_id': 'VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n", + " 'source': 'Connoisseurus Veg',\n", + " 'title': 'Vegan Pad Thai - Connoisseurus Veg',\n", + " 'link': 'https://www.connoisseurusveg.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.connoisseurusveg.com/wp-content/uploads/2021/04/vegan-pad-thai-r-8-of-10.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 83,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdkOE8fHkjIYt-VHnxHhCKT1Q4Ccu__Id64Q&usqp=CAU',\n", + " 'related_content_id': 'R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n", + " 'source': \"Madhu's Everyday Indian\",\n", + " 'title': \"Easy Vegan Pad Thai Recipe - Madhu's Everyday Indian\",\n", + " 'link': 'https://www.madhuseverydayindian.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.madhuseverydayindian.com/wp-content/uploads/2019/11/pad-thai-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 84,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRAqAWfnCA_xgZ33xmKJYH-GElMv8BR9SfEg&usqp=CAU',\n", + " 'related_content_id': 'YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/sNXRcU7H5YlFa9nto8PzROCcK6E=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-7-f2309902236d45f38dd937e894d7a95f.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 85,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvt5v5lIPiITlJSSh6yiG-k8NDEdEaAvrUZg&usqp=CAU',\n", + " 'related_content_id': 'M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n", + " 'source': 'Ve Eat Cook Bake',\n", + " 'title': 'Vegan Tofu Pad Thai Recipe (easy, oil free) - Ve Eat Cook Bake',\n", + " 'link': 'https://veeatcookbake.com/vegan-pad-thai-sauce/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veeatcookbake.com/wp-content/uploads/2020/01/vegan-tofu-pad-thai-3.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 1080,\n", + " 'is_product': True},\n", + " {'position': 86,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmmjnFxGBdd4XrLb3_NV9S6DqDsrm8gCArrQ&usqp=CAU',\n", + " 'related_content_id': 'd3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n", + " 'source': 'Pinterest',\n", + " 'title': 'Easy Vegan Pad Thai Recipe w/ Sauce - Choosing Chia | Recipe | Easy asian noodle recipes, Vegan pad thai, Easy asian noodles',\n", + " 'link': 'https://www.pinterest.com/pin/easy-vegan-pad-thai-recipe-w-sauce-choosing-chia--495044184044777788/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://i.pinimg.com/736x/20/05/d9/2005d9d549ea0aa25d2823c4bd47de66.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': True},\n", + " {'position': 87,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-brimcB4Yy8KjKGPRL_XwmcMsukorzxhh7w&usqp=CAU',\n", + " 'related_content_id': 'bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'source': 'Spice Cravings',\n", + " 'title': 'Vegan Pad Thai | Spice Cravings',\n", + " 'link': 'https://spicecravings.com/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-Featured.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 88,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmLLjuIxWgB0eAVv4CpMkufWKkwP0OLh95rw&usqp=CAU',\n", + " 'related_content_id': 'QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'source': 'Delish Knowledge',\n", + " 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n", + " 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n", + " 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles2.jpeg',\n", + " 'original_width': 981,\n", + " 'original_height': 1471,\n", + " 'is_product': False},\n", + " {'position': 89,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQBFHo9kgwduVWWgXYbjwx8oHmzkRq4eFx_w&usqp=CAU',\n", + " 'related_content_id': 'eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n", + " 'source': 'Nifty Recipes',\n", + " 'title': 'Easy Vegan Pad Thai from Tasty - recipe on Niftyrecipe.com',\n", + " 'link': 'https://niftyrecipe.com/video/1616/easy-vegan-pad-thai',\n", + " 'original': 'https://niftyrecipe.com/uploads/youtube/parse/gVXDvCI32N8.jpg',\n", + " 'original_width': 640,\n", + " 'original_height': 480,\n", + " 'is_product': False},\n", + " {'position': 90,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQDNoodvmhaxXBanZUWokpcjFLd1lBmPi6N9g&usqp=CAU',\n", + " 'related_content_id': 'UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'source': 'Detoxinista',\n", + " 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n", + " 'link': 'https://detoxinista.com/vegan-pad-thai/',\n", + " 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai-recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1513,\n", + " 'is_product': False},\n", + " {'position': 91,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTVHfWG0FG8Dlr4vAkRFB2CJEN1EUPWqp5dWQ&usqp=CAU',\n", + " 'related_content_id': 'S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n", + " 'source': 'Mom Always Finds Out',\n", + " 'title': 'Recipe} Vegetarian Pad Thai in Less than 15 Minutes - Mom Always Finds Out',\n", + " 'link': 'https://www.momalwaysfindsout.com/quick-pad-thai-recipe/',\n", + " 'original': 'http://momalwaysfindsout.com/wp-content/uploads/2013/08/easy-vegetarian-pad-thai-recipe.jpg',\n", + " 'original_width': 526,\n", + " 'original_height': 416,\n", + " 'is_product': False},\n", + " {'position': 92,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRhwBcrNUbTx9kzPKfcmWE0Ra7gapkAfRrcfw&usqp=CAU',\n", + " 'related_content_id': 'YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n", + " 'source': 'Nutriciously',\n", + " 'title': 'Colorful Raw Vegan Pad Thai Salad – Nutriciously',\n", + " 'link': 'https://nutriciously.com/raw-vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://nutriciously.com/wp-content/uploads/Raw-Vegan-Pad-Thai-by-Nutriciously-3-735x1102.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': True},\n", + " {'position': 93,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTE247S-7oA7iBXdWKaWSVW76NBNMj9G1zMMA&usqp=CAU',\n", + " 'related_content_id': 'YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n", + " 'source': 'Jessica in the Kitchen',\n", + " 'title': 'Easy Vegan Pad Thai | Jessica in the Kitchen',\n", + " 'link': 'https://jessicainthekitchen.com/vegan-pad-thai/',\n", + " 'original': 'https://jessicainthekitchen.com/wp-content/uploads/2022/08/Vegan-Pad-Thai0046.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 94,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEICg4TzsYnpMi-FDoDIIiTxIEYlkJotNZJw&usqp=CAU',\n", + " 'related_content_id': 'Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n", + " 'source': 'Feasting At Home',\n", + " 'title': 'Pad Thai (Video!) | Feasting at Home',\n", + " 'link': 'https://www.feastingathome.com/15-minute-pad-thai/',\n", + " 'original': 'https://www.feastingathome.com/wp-content/uploads/2016/04/easy-authentic-pad-thai-recipe-100-8.jpg',\n", + " 'original_width': 750,\n", + " 'original_height': 1125,\n", + " 'is_product': False},\n", + " {'position': 95,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRaL2_fWqKRkIvDq4dn5kZqexIjDD5rIpb-Q&usqp=CAU',\n", + " 'related_content_id': 'aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n", + " 'source': 'a Veg Taste from A to Z',\n", + " 'title': 'Vegan Pad Thai with Cashews -',\n", + " 'link': 'https://avegtastefromatoz.com/vegan-pad-thai-cashews/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://avegtastefromatoz.com/wp-content/uploads/2020/09/pad-thai-5.jpg',\n", + " 'original_width': 2048,\n", + " 'original_height': 2048,\n", + " 'is_product': True},\n", + " {'position': 96,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSQmbOr5bqa0rC0nX95VxH-6RasxkuymwUMg&usqp=CAU',\n", + " 'related_content_id': 'Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n", + " 'source': 'Plant-Based on a Budget',\n", + " 'title': 'Vegan Vegetable Pad Thai - Plant-Based on a Budget',\n", + " 'link': 'https://plantbasedonabudget.com/avocado-basil-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://plantbasedonabudget.com/wp-content/uploads/2014/05/Vegan-Avocado-Basil-Pad-Thai-Plant-Based-on-a-Budget-1-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 97,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQOF76mQo9LZPzWv_vzVAz-od1L271ioKWNVA&usqp=CAU',\n", + " 'related_content_id': 'Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'source': 'Full of Plants',\n", + " 'title': 'The Best Vegan Pad Thai - Full of Plants',\n", + " 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n", + " 'original': 'https://fullofplants.com/wp-content/uploads/2022/02/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-10-1400x2100.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 2100,\n", + " 'is_product': False},\n", + " {'position': 98,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-8yozAbc9Gpm97m_vt6sgcJ3mpTliabYGMQ&usqp=CAU',\n", + " 'related_content_id': 'bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n", + " 'source': \"It's All Good Vegan\",\n", + " 'title': \"Creamy Pad Thai Noodles - It's All Good Vegan\",\n", + " 'link': 'https://itsallgoodvegan.com/2020/02/19/creamy-pad-thai-noodles/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://itsallgoodvegan.com/wp-content/uploads/2020/02/img_2841.jpg',\n", + " 'original_width': 1638,\n", + " 'original_height': 2048,\n", + " 'is_product': True},\n", + " {'position': 99,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa2HSMw-ypurNqm48DPPpuKZOFbmDO65klnA&usqp=CAU',\n", + " 'related_content_id': 'Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n", + " 'source': 'Veggiekins',\n", + " 'title': 'Vegan Pad Thai with Tofu (gluten free) (Gluten-Free) - Veggiekins Blog',\n", + " 'link': 'https://veggiekinsblog.com/2021/03/24/vegan-pad-thai-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veggiekinsblog.com/wp-content/uploads/2021/03/Vegan-Pad-Thai-with-Tofu-4-scaled.jpg',\n", + " 'original_width': 1708,\n", + " 'original_height': 2560,\n", + " 'is_product': True},\n", + " {'position': 100,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEZmnz4duD3odLwVNqQ_OfHJ1zPNaofthtXw&usqp=CAU',\n", + " 'related_content_id': 'Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n", + " 'source': 'Zucker&Jagdwurst',\n", + " 'title': 'Vegan Pad Thai with “chicken“ - Zucker&Jagdwurst',\n", + " 'link': 'https://www.zuckerjagdwurst.com/en/recipes/vegan-pad-thai-with-chicken',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://assets.zuckerjagdwurst.com/q9pjl6288ajpcx8s994gccncy1i1/1110/740/65/true/center/R435+Veganes+Pad+Thai+mit+%E2%80%9EHu%CC%88hnchen%E2%80%9C39.jpg?animated=false',\n", + " 'original_width': 1110,\n", + " 'original_height': 740,\n", + " 'is_product': True}]}" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "params = {\n", + " \"engine\": \"google_images\",\n", + " \"q\": \"Vegan pad thai recipes\",\n", + " \"location\": \"United States\",\n", + " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", + "}\n", + "\n", + "search = GoogleSearch(params)\n", + "results = search.get_dict()\n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Healthier vegan pad thai - Lazy Cat Kitchen'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'The Best Vegan Pad Thai - Full of Plants'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegan Pad Thai - My Darling Vegan'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegetarian Pad Thai - Pinch Me Good'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Vegan pad thai - Lazy Cat Kitchen'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for r in results[\"images_results\"][0:10]:\n", + " display(r[\"title\"], Image(url=r[\"thumbnail\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "# You can create the tool to pass to an agent\n", + "serpapi_recipe_tool = Tool(\n", + " name=\"\",\n", + " description=\"A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\",\n", + " func=search.run,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This doc should be corrected [LangChain serpapi doc could be updated](https://python.langchain.com/en/latest/modules/agents/tools/examples/serpapi.html)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [ + "search = GoogleSerperAPIWrapper(type=\"search\")\n", + "results = search.results(\"Lion\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[edamam](https://www.edamam.com/)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_proc/03_edamam_api.ipynb b/_proc/03_edamam_api.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..d946f82a7fb5606b1a9b101c98631c6db43bff2d --- /dev/null +++ b/_proc/03_edamam_api.ipynb @@ -0,0 +1,86 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "description: Tinkering with the [](Edamam API)\n", + "output-file: edamam_api.html\n", + "title: edamam_api\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/edamam_api.py#L7){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### foo\n", + "\n", + "> foo ()" + ], + "text/plain": [ + "---\n", + "\n", + "[source](https://github.com/animalequality/lv-recipe-chatbot/blob/main/lv_recipe_chatbot/edamam_api.py#L7){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", + "\n", + "### foo\n", + "\n", + "> foo ()" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#| echo: false\n", + "#| output: asis\n", + "show_doc(foo)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_proc/_docs/app.html b/_proc/_docs/app.html new file mode 100644 index 0000000000000000000000000000000000000000..f8500423a17f9f51c79ba6ab348e2c37c9d55f5e --- /dev/null +++ b/_proc/_docs/app.html @@ -0,0 +1,483 @@ + + + + + + + + + + +lv-recipe-chatbot - app + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

app

+
+ +
+
+ Gradio app.py +
+
+ + +
+ + + + +
+ + +
+ + +
+

source

+
+

ConversationBot

+
+
 ConversationBot ()
+
+

Initialize self. See help(type(self)) for accurate signature.

+
+

source

+
+
+

launch_demo

+
+
 launch_demo ()
+
+

Load environment for the demo

+
+
from dotenv import load_dotenv
+
+
+
load_dotenv()
+launch_demo()
+
+
Running on local URL:  http://127.0.0.1:7862
+
+To create a public link, set `share=True` in `launch()`.
+
+
+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/_proc/_docs/edamam_api.html b/_proc/_docs/edamam_api.html new file mode 100644 index 0000000000000000000000000000000000000000..36a4ac8745afc670ac14b1869979b4f6754b195c --- /dev/null +++ b/_proc/_docs/edamam_api.html @@ -0,0 +1,426 @@ + + + + + + + + + + +lv-recipe-chatbot - edamam_api + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

edamam_api

+
+ +
+
+ Tinkering with the +
+
+ + +
+ + + + +
+ + +
+ + +
+

source

+
+

foo

+
+
 foo ()
+
+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/_proc/_docs/engineer_prompt.html b/_proc/_docs/engineer_prompt.html new file mode 100644 index 0000000000000000000000000000000000000000..91771e67165d86e2049cfad7bbaf5bb3b2778105 --- /dev/null +++ b/_proc/_docs/engineer_prompt.html @@ -0,0 +1,578 @@ + + + + + + + + + + +lv-recipe-chatbot - engineer_prompt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

engineer_prompt

+
+ +
+
+ Engineering prompts +
+
+ + +
+ + + + +
+ + +
+ + +

Setup env

+
+
from dotenv import load_dotenv
+
+
+
load_dotenv()
+
+
True
+
+
+

Evaluate chat backend

+
+
chat = PromptLayerChatOpenAI(temperature=1, pl_tags=["langchain"], return_pl_id=True)
+memory = ConversationBufferMemory(return_messages=True)
+chat_msgs = init_prompt.format_prompt(
+    ingredients="tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread",
+    allergies="",
+    recipe_freeform_input="The preparation time should be less than 30 minutes. I really love Thai food!",
+)
+
+chat_msgs = chat_msgs.to_messages()
+results = chat.generate([chat_msgs])
+chat_msgs.extend(
+    [
+        results.generations[0][0].message,
+        MessagesPlaceholder(variable_name="history"),
+        HumanMessagePromptTemplate.from_template("{input}"),
+    ]
+)
+open_prompt = ChatPromptTemplate.from_messages(chat_msgs)
+conversation = ConversationChain(
+    llm=chat, verbose=True, memory=memory, prompt=open_prompt
+)
+
+result = conversation.predict(input="Recommend a different recipe please.")
+print(result)
+
+
Anthropic module not found. Install with `pip install anthropic`.
+WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again
+WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again
+
+
+

+
+> Entering new ConversationChain chain...
+Prompt after formatting:
+System: The following is a conversation between a human and a friendly AI chef. 
+The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.
+
+Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey 
+
+Let's think step by step.
+If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.
+AI: What ingredients do you wish to cook with?
+Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread
+AI: Do you have any allergies I should be aware of?
+Human: Allergies: 
+AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?
+Human: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).
+Respect the human's allergies (if any).
+Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:
+
+###
+Preferences: The preparation time should be less than 30 minutes. I really love Thai food!
+###
+
+Output format:
+
+**Vegan recipe name**
+Preparation time (humanized)
+
+Ingredients (List of ingredients with quantities):
+- <quantity and unit> <ingredient>
+
+Steps (detailed):
+1.
+2.
+3.
+...
+AI: Sure! How about a vegan Thai tofu lettuce wraps recipe? It should take less than 30 minutes to prepare.
+
+**Vegan Thai Tofu Lettuce Wraps**
+Preparation time: 25 minutes
+
+Ingredients:
+- 1 package firm tofu
+- 1/4 cup vegan fish sauce (you can use soy sauce as a substitute)
+- 2 tablespoons maple syrup
+- 1 tablespoon lime juice
+- 1 teaspoon chili paste
+- 1 bell pepper, sliced
+- 2 carrots, julienned
+- 1/4 cup sliced pickles
+- 1/4 cup sliced olives
+- 6 large lettuce leaves
+- 1/4 cup chopped fresh cilantro
+
+Steps:
+1. Preheat a skillet over medium-high heat and add cubed tofu. Cook for about 5-7 minutes, flipping occasionally, until all the pieces are golden brown. Set aside.
+2. In a mixing bowl, whisk together the fish sauce (or soy sauce), maple syrup, lime juice, and chili paste until combined.
+3. In a large mixing bowl, add the bell pepper, carrots, pickles, olives, and cooked tofu. Pour the dressing over the ingredients, and toss until everything is evenly coated with the sauce.
+4. Assemble the lettuce wraps by separating the lettuce leaves and spooning the tofu mixture into each one. Top with fresh cilantro and serve immediately. Enjoy your delicious vegan Thai tofu lettuce wraps!
+Human: Recommend a different recipe please.
+
+> Finished chain.
+Of course! How about a Mediterranean-inspired sandwich that includes tofu, olives, and tomatoes?
+
+**Mediterranean Tofu Sandwich**
+Preparation time: 20 minutes
+
+Ingredients:
+- 1 package extra-firm tofu, drained and sliced into 1/2-inch slices
+- 2 tablespoons olive oil
+- 1 teaspoon dried oregano
+- Salt and pepper
+- 1/4 cup vegan mayo
+- 1 garlic clove, minced
+- 2 teaspoons lemon juice
+- 1 large tomato, sliced
+- 1/4 cup sliced kalamata olives
+- 1/4 cup chopped lettuce
+- 1/4 cup sliced pickles
+- Bread of your choice (I recommend ciabatta)
+
+Steps:
+1. Preheat a skillet over medium-high heat and add the olive oil.
+2. Season the tofu slices with oregano, salt, and pepper, then add them to the skillet. Cook for about 5-7 minutes on each side or until golden brown. Set aside.
+3. In a small bowl, mix the vegan mayo, minced garlic, and lemon juice. Spread the mixture onto the slices of bread.
+4. Layer the tomato slices, cooked tofu, olives, lettuce, and pickles onto the bread. Add salt and pepper to taste.
+5. Top with the other slice of bread, slice in half, and enjoy your delicious Mediterranean tofu sandwich!
+
+
+ + + +
+ +
+ + + + \ No newline at end of file diff --git a/_proc/_docs/index.html b/_proc/_docs/index.html new file mode 100644 index 0000000000000000000000000000000000000000..51292f753262f78943adbe3c917a14840f7a3fc9 --- /dev/null +++ b/_proc/_docs/index.html @@ -0,0 +1,526 @@ + + + + + + + + + + +lv-recipe-chatbot + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

lv-recipe-chatbot

+
+ +
+
+ An experimental Vegan recipe chatbot +
+
+ + +
+ + + + +
+ + +
+ + +

This file will become your README and also the index of your documentation.

+
+

Install

+
pip install lv_recipe_chatbot
+
+
+

How to use

+
+
from dotenv import load_dotenv
+
+load_dotenv()
+
+app.launch_demo()
+
+
Running on local URL:  http://127.0.0.1:7860
+
+To create a public link, set `share=True` in `launch()`.
+
+
+

or

+
python3 app.py
+
+
+

Dev quick-start

+

git clone the repo

+
cd lv-recipe-chatbot
+

Make sure to use the version of python specified in py_version.txt
+Create a virtual environment.

+
python3 -m venv env
+

Activate the env and install dependencies.

+
source env/bin/activate
+pip install -r requirements.txt
+pip install -r requirements/dev.txt
+

To make the Jupyter environment, git friendly: nbdev_install_hooks
+If you want to render documentation locally, you will want to install Quarto.

+

nbdev_install_quarto

+

Put API secrets in .env

+
cp .env.example .env
+

Edit .env with your secret key(s). Only OPEN_AI_KEY is required.

+

Then start the Gradio demo from within the virtual environment.

+
python3 app.py
+

Preview documentation

+
nbdev_preview
+
+
+

Dependencies

+

If a new dependency for development is helpful for developers, add it to dev.txt.
+If it is a dependency for the app that is imported in source code, add it to core.txt.
+Then run:

+
pipreqs --force
+

This will update our requirements.txt to include the dependency as it should be pinned in the environment.

+
+
+

Development

+

quick nbdev tutorial

+

Make changes in /nbs.
+Update the package files with nbdev_export then reimport with pip install -e '.[dev]'

+

Preview doc nbdev_preview
+Build docs, test and update README nbdev_prepare

+
+ + +
+ +
+ + + + \ No newline at end of file diff --git a/_proc/_docs/lchain_tool.html b/_proc/_docs/lchain_tool.html new file mode 100644 index 0000000000000000000000000000000000000000..e3a9b212ec2b2916d01f37d22e3c864a0cab5cee --- /dev/null +++ b/_proc/_docs/lchain_tool.html @@ -0,0 +1,2034 @@ + + + + + + + + + + +lv-recipe-chatbot - lchain_tool + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ +
+ + +
+ + + +
+ +
+
+

lchain_tool

+
+ +
+
+ Exploring Langchain Tool capabilities +
+
+ + +
+ + + + +
+ + +
+ + +
+
from dotenv import load_dotenv
+
+
+
load_dotenv()
+
+
True
+
+
+
+
llm = ChatOpenAI(temperature=0)
+
+
+
tools = load_tools(["llm-math"], llm=llm)
+agent = initialize_agent(
+    tools,
+    llm,
+    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
+    handle_parsing_errors=True,
+    verbose=True,
+)
+
+
+
agent("What is the 3% of of 300 * 30?")
+
+

+
+> Entering new AgentExecutor chain...
+We can calculate this using the Calculator tool.
+
+Action:
+```
+{
+  "action": "Calculator",
+  "action_input": "0.03 * 300 * 30"
+}
+```
+
+
+Observation: Answer: 270.0
+Thought:Could not parse LLM output: This is the correct answer to the question.
+Observation: Invalid or incomplete response
+Thought:Let me try the same action again.
+
+Action:
+```
+{
+  "action": "Calculator",
+  "action_input": "0.03 * 300 * 30"
+}
+```
+
+
+Observation: Answer: 270.0
+Thought:Could not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.
+
+Observation: Invalid or incomplete response
+Thought:There seems to be an issue with the LLM response. Let me try a different way to calculate the answer.
+
+Action:
+```
+{
+  "action": "Calculator",
+  "action_input": "300 * 30 * 0.03"
+}
+```
+
+
+Observation: Answer: 270.0
+Thought:I have successfully calculated the answer to the question using the calculator tool.
+
+Final Answer: 270.0
+
+> Finished chain.
+
+
+
{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}
+
+
+

SerpAPI Google Images

+
+
params = {
+    "q": "Vegan pad thai recipes",
+    "location": "United States",
+    "hl": "en",
+    "gl": "us",
+    "api_key": os.environ["SERPAPI_API_KEY"],
+}
+
+search = GoogleSearch(params)
+results = search.get_dict()
+recipes_results = results["recipes_results"]
+recipes_results
+
+
[{'title': 'Easy Tofu Pad Thai',
+  'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',
+  'source': 'Minimalist Baker',
+  'rating': 4.9,
+  'reviews': 117,
+  'total_time': '30 min',
+  'ingredients': ['Pad thai rice',
+   'peanut sauce',
+   'thai red',
+   'soy sauce',
+   'bean sprouts']},
+ {'title': 'Vegan Pad Thai',
+  'link': 'https://www.noracooks.com/vegan-pad-thai/',
+  'source': 'Nora Cooks',
+  'rating': 5.0,
+  'reviews': 53,
+  'total_time': '30 min',
+  'ingredients': ['Stir fry rice',
+   'mung bean sprouts',
+   'soy sauce',
+   'maple syrup',
+   'sriracha hot sauce']},
+ {'title': 'Vegan Pad Thai',
+  'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',
+  'source': 'Pick Up Limes',
+  'rating': 5.0,
+  'reviews': 34,
+  'total_time': '30 min',
+  'ingredients': ['Brown rice noodles',
+   'red hot',
+   'soy sauce',
+   'bean sprouts',
+   'sriracha hot sauce']}]
+
+
+
+
+

SerpAPIWrapper

+
+
 SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',
+                 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},
+                 serpapi_api_key:Optional[str]=None,
+                 aiosession:Optional[aiohttp.client.ClientSession]=None)
+
+

Wrapper around SerpAPI.

+

To use, you should have the google-search-results python package installed, and the environment variable SERPAPI_API_KEY set with your API key, or pass serpapi_api_key as a named parameter to the constructor.

+

Example: .. code-block:: python

+
    from langchain import SerpAPIWrapper
+    serpapi = SerpAPIWrapper()
+
+

source

+
+
+

RecipeSerpAPIWrapper

+
+
 RecipeSerpAPIWrapper (search_engine:Any=None, params:dict={'engine':
+                       'google', 'google_domain': 'google.com', 'gl':
+                       'us', 'hl': 'en'},
+                       serpapi_api_key:Optional[str]=None, aiosession:Opti
+                       onal[aiohttp.client.ClientSession]=None)
+
+

Wrapper around SerpAPI.

+

To use, you should have the google-search-results python package installed, and the environment variable SERPAPI_API_KEY set with your API key, or pass serpapi_api_key as a named parameter to the constructor.

+

Example: .. code-block:: python

+
    from langchain import SerpAPIWrapper
+    serpapi = SerpAPIWrapper()
+
+
params = {
+    "location": "United States",
+    "hl": "en",
+    "gl": "us",
+}
+search = RecipeSerpAPIWrapper(params=params)
+
+
+
vegan_recipes = search.run("Vegan fried rice recipes")
+vegan_recipes
+
+
[{'title': 'Easy Vegan Fried Rice',
+  'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',
+  'source': 'Minimalist Baker',
+  'rating': 4.8,
+  'reviews': 457,
+  'total_time': '1 hr 15 min',
+  'ingredients': ['Peanut butter',
+   'grain brown rice',
+   'soy sauce',
+   'maple syrup',
+   'chili garlic sauce']},
+ {'title': 'The Best Vegan Fried Rice',
+  'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',
+  'source': 'Short Girl Tall Order',
+  'rating': 4.8,
+  'reviews': 65,
+  'total_time': '28 min',
+  'ingredients': ['Soy sauce',
+   'white rice',
+   'rice wine vinegar',
+   'sugar',
+   'fresh peas']},
+ {'title': 'Vegan Fried Rice',
+  'link': 'https://www.noracooks.com/vegan-fried-rice/',
+  'source': 'Nora Cooks',
+  'rating': 5.0,
+  'reviews': 15,
+  'total_time': '20 min',
+  'ingredients': ['Gluten free',
+   'nutritional yeast',
+   'toasted sesame oil',
+   'carrots',
+   'olive oil']}]
+
+
+
+
params = {
+    "engine": "google_images",
+    "q": "Vegan pad thai recipes",
+    "location": "United States",
+    "api_key": os.environ["SERPAPI_API_KEY"],
+}
+
+search = GoogleSearch(params)
+results = search.get_dict()
+results
+
+
{'search_metadata': {'id': '647fff28b7b1ccd51d11a01d',
+  'status': 'Success',
+  'json_endpoint': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.json',
+  'created_at': '2023-06-07 03:53:12 UTC',
+  'processed_at': '2023-06-07 03:53:12 UTC',
+  'google_images_url': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&oq=Vegan+pad+thai+recipes&uule=w+CAIQICINVW5pdGVkIFN0YXRlcw&hl=en&gl=us&tbm=isch',
+  'raw_html_file': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.html',
+  'total_time_taken': 10.18},
+ 'search_parameters': {'engine': 'google_images',
+  'q': 'Vegan pad thai recipes',
+  'location_requested': 'United States',
+  'location_used': 'United States',
+  'google_domain': 'google.com',
+  'hl': 'en',
+  'gl': 'us',
+  'device': 'desktop'},
+ 'search_information': {'image_results_state': 'Results for exact spelling',
+  'menu_items': [{'position': 1,
+    'title': 'All',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEAI',
+    'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},
+   {'position': 2,
+    'title': 'Videos',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=vid&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEAQ',
+    'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_videos&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},
+   {'position': 3, 'title': 'Images'},
+   {'position': 4,
+    'title': 'Shopping',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=shop&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEAg',
+    'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_shopping&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},
+   {'position': 5,
+    'title': 'Maps',
+    'link': 'https://maps.google.com/maps?q=Vegan+pad+thai+recipes&source=lmns&entry=mc&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAR6BAgBEAo'},
+   {'position': 6,
+    'title': 'Books',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=bks&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEA0'},
+   {'position': 7,
+    'title': 'News',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=nws&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEA4',
+    'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes&tbm=nws'},
+   {'position': 8,
+    'title': 'Flights',
+    'link': 'https://www.google.com/travel/flights?q=Vegan+pad+thai+recipes&source=lmns&tbm=flm&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAJ6BAgBEA8'},
+   {'position': 9,
+    'title': 'Finance',
+    'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=fin&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEBA'}]},
+ 'suggested_searches': [{'name': 'rice noodles',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAHoECAEQKw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Arice%2Bnoodles%3Agk0lY1Ku8x8%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b7f361a9f8fb38098b46394cb9c659c83.jpeg'},
+  {'name': 'gluten free',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAXoECAEQLQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Agluten%2Bfree%3A_Jv5VE84jYQ%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba4acd7acf58a4e539824754bccf790f0.jpeg'},
+  {'name': 'tofu',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAnoECAEQLw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Atofu%3AEdnrGNBK_3E%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b57cb6349f17e3b4997748a7fb2213981.jpeg'},
+  {'name': 'thai peanut sauce',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoA3oECAEQMQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bpeanut%2Bsauce%3AAOyraWKuKIU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2bc44c0d5d0eef2c4dfefe036887628a3c.jpeg'},
+  {'name': 'vegan gluten',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBHoECAEQMw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Avegan%2Bgluten%3AYD_J3kTgidI%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b631482aae166e90902888b39f9df86d4.jpeg'},
+  {'name': 'thai food',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBXoECAEQNQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bfood%3A0nWr99Uxrwc%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3abb47a217c7337c6259316ffb3146b6.jpeg'},
+  {'name': 'thai tofu pad',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBnoECAEQNw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Btofu%2Bpad%3A-u5KMb62hFM%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba9dc874972edb8879d31906ca8d02d1e.jpeg'},
+  {'name': 'food network',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoB3oECAEQOQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afood%2Bnetwork%3A4fsBYIFuk6M%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3542cf3034c40352d8800de25efd446c.jpeg'},
+  {'name': 'peanut butter',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCHoECAEQOw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Apeanut%2Bbutter%3AFJXMrvqXmOU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b5b6523f5ed417f4c899d005473ba16b5.jpeg'},
+  {'name': 'stir fry',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCXoECAEQPQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Astir%2Bfry%3Ao0twgEKDva0%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3337398b3fc538d59c1a2d960953452d.jpeg'},
+  {'name': 'plant based',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCnoECAEQPw',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Aplant%2Bbased%3A6BEj1Wk084g%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3d37839120548e6228cc4e71e1b7c7af.jpeg'},
+  {'name': 'fried tofu',
+   'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoC3oECAEQQQ',
+   'chips': 'q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D',
+   'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afried%2Btofu%3AEpVuI9_hNoU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2be19daee44662280115fa006abc2bf75b.jpeg'}],
+ 'images_results': [{'position': 1,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg',
+   'related_content_id': 'aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'source': 'Minimalist Baker',
+   'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',
+   'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/Easy-Vegan-Pad-Thai-SQUARE.jpg',
+   'original_width': 1452,
+   'original_height': 1453,
+   'is_product': True},
+  {'position': 2,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg',
+   'related_content_id': 'RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',
+   'source': 'Pinch of Yum',
+   'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',
+   'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',
+   'tag': 'Recipe',
+   'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Thai-Recipe.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 3,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg',
+   'related_content_id': 'b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',
+   'source': 'Lazy Cat Kitchen',
+   'title': 'Healthier vegan pad thai - Lazy Cat Kitchen',
+   'link': 'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2021/01/healthier-vegan-pad-thai-macro-1024x1536.jpg',
+   'original_width': 1024,
+   'original_height': 1536,
+   'is_product': True},
+  {'position': 4,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg',
+   'related_content_id': 'akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',
+   'source': 'Full of Plants',
+   'title': 'The Best Vegan Pad Thai - Full of Plants',
+   'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://fullofplants.com/wp-content/uploads/2022/03/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-thumb.jpg',
+   'original_width': 1440,
+   'original_height': 1440,
+   'is_product': True},
+  {'position': 5,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg',
+   'related_content_id': 'MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',
+   'source': 'earthofmaria.com',
+   'title': 'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria',
+   'link': 'https://earthofmaria.com/easy-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://earthofmaria.com/wp-content/uploads/2019/04/Easy-Vegan-Pad-Thai-Gluten-free-6.jpg',
+   'original_width': 1024,
+   'original_height': 1536,
+   'is_product': True},
+  {'position': 6,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36f9a1c02c421efe07d8d147f542087ff245f0933ec60896cd.jpeg',
+   'related_content_id': 'N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',
+   'source': 'My Darling Vegan',
+   'title': 'Easy Vegan Pad Thai - My Darling Vegan',
+   'link': 'https://www.mydarlingvegan.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.mydarlingvegan.com/wp-content/uploads/2021/07/Vegan-Pad-Thai-2.jpg',
+   'original_width': 1024,
+   'original_height': 1536,
+   'is_product': True},
+  {'position': 7,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a75a0136dd1f95918c9bb1ded2f17e5c31f13d3708cc723f.jpeg',
+   'related_content_id': 'NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',
+   'source': 'Pinch Me Good',
+   'title': 'Easy Vegetarian Pad Thai - Pinch Me Good',
+   'link': 'https://pinchmegood.com/easy-vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://pinchmegood.com/wp-content/uploads/2019/03/Easy-Vegetarian-Pad-Thai.jpg',
+   'original_width': 924,
+   'original_height': 1386,
+   'is_product': True},
+  {'position': 8,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36cdf1d570098da37da75a20a5a2ed59916c3cc1ac656f5b45.jpeg',
+   'related_content_id': 'NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',
+   'source': 'Vegan Huggs',
+   'title': '30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs',
+   'link': 'https://veganhuggs.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://veganhuggs.com/wp-content/uploads/2019/03/vegan-pad-thai-3.jpg',
+   'original_width': 680,
+   'original_height': 1020,
+   'is_product': True},
+  {'position': 9,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd364677ba205872944cc9932a27c40873a1e3f4424ca6219c9b.jpeg',
+   'related_content_id': 'OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',
+   'source': 'Ministry of Curry',
+   'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',
+   'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-1.jpg',
+   'original_width': 1024,
+   'original_height': 1536,
+   'is_product': True},
+  {'position': 10,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3600f3b428f18999842a7c3ddc41991cd1d626950bd108397d.jpeg',
+   'related_content_id': 'bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',
+   'source': 'Lazy Cat Kitchen',
+   'title': 'Vegan pad thai - Lazy Cat Kitchen',
+   'link': 'https://www.lazycatkitchen.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2016/05/vegan-pad-thai-1000x1500.jpg',
+   'original_width': 1000,
+   'original_height': 1500,
+   'is_product': True},
+  {'position': 11,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224470ef6b1b3462b418875bdedefa3d79.jpeg',
+   'related_content_id': 'NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',
+   'source': 'Well Plated by Erin',
+   'title': 'Vegetarian Pad Thai {30-Minute Recipe} - WellPlated.com',
+   'link': 'https://www.wellplated.com/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.wellplated.com/wp-content/uploads/2017/08/Healthy-Vegetarian-Pad-Thai.jpg',
+   'original_width': 1200,
+   'original_height': 1469,
+   'is_product': True},
+  {'position': 12,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82276df3b8fda0d0c061010978e4b536cc1.jpeg',
+   'related_content_id': 'WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',
+   'source': 'The Spruce Eats',
+   'title': 'Vegetarian Pad Thai Recipe',
+   'link': 'https://www.thespruceeats.com/vegetarian-pad-thai-3217746',
+   'tag': 'Recipe',
+   'original': 'https://www.thespruceeats.com/thmb/wF19pUZKaKo66pofbpjI0eS1SLc=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/vegetarian-pad-thai-3217746-step-11-231a859fac40430583b044297aaf4a87.jpg',
+   'original_width': 1500,
+   'original_height': 1000,
+   'is_product': True},
+  {'position': 13,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82281ba3f6ced7a769ced6de3c3b0f1fe41.jpeg',
+   'related_content_id': 'MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',
+   'source': 'Simply Recipes',
+   'title': 'Vegetarian Pad Thai Recipe',
+   'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',
+   'tag': 'Recipe',
+   'original': 'https://www.simplyrecipes.com/thmb/Y6WvULetSWWIjzcQONSg9n8PFgg=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-2f0142cca68e4f9592381d281a391d59.jpg',
+   'original_width': 1500,
+   'original_height': 1000,
+   'is_product': True},
+  {'position': 14,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224df1973dd2dbff9bcbe3402164ae150c.jpeg',
+   'related_content_id': 'bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',
+   'source': 'Food Network',
+   'title': 'Vegetarian Pad Thai Recipe | Food Network Kitchen | Food Network',
+   'link': 'https://www.foodnetwork.com/recipes/food-network-kitchen/vegetarian-pad-thai-7183115',
+   'tag': 'Recipe',
+   'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2019/9/10/0/FNK_Vegetarian-Tofu-Pad-Thai_H2_s4x3.jpg.rend.hgtvcom.616.462.suffix/1568385716096.jpeg',
+   'original_width': 616,
+   'original_height': 462,
+   'is_product': True},
+  {'position': 15,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822ed36be9df00a80e5203ab96f92fc31fd.jpeg',
+   'related_content_id': 'RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',
+   'source': 'Bianca Zapatka',
+   'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',
+   'link': 'https://biancazapatka.com/en/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/pad-thai-vegan-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-720x1008.jpg',
+   'original_width': 720,
+   'original_height': 1008,
+   'is_product': True},
+  {'position': 16,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8223cb49bc3c204d16373a0a6e257d6e54f.jpeg',
+   'related_content_id': 'UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',
+   'source': 'EatPlant-Based.com',
+   'title': 'Easy Vegan Pad Thai - EatPlant-Based',
+   'link': 'https://eatplant-based.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://eatplant-based.com/wp-content/uploads/2022/03/Awakened-Pad-Thai-3.jpeg',
+   'original_width': 668,
+   'original_height': 1000,
+   'is_product': True},
+  {'position': 17,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225dcace1e2fb2aebe208ed1bfde7e8775.jpeg',
+   'related_content_id': 'UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',
+   'source': 'Taste of Home',
+   'title': 'Vegetarian Pad Thai Recipe: How to Make It',
+   'link': 'https://www.tasteofhome.com/recipes/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://tmbidigitalassetsazure.blob.core.windows.net/rms3-prod/attachments/37/1200x1200/Vegetarian-Pad-Thai_EXPS_HCK18_197935_B04_014_4b.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 18,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82263e484cb2a264123c087cf8b9eb10c0d.jpeg',
+   'related_content_id': 'djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',
+   'source': 'Taste',
+   'title': '10-minute vegetarian pad Thai recipe',
+   'link': 'https://www.taste.com.au/recipes/10-minute-vegetarian-pad-thai-recipe/4bq39nic',
+   'tag': 'Recipe',
+   'original': 'https://img.taste.com.au/jgHrD_eG/w720-h480-cfill-q80/taste/2021/02/10-minute-vegetarian-pad-thai-168946-2.jpg',
+   'original_width': 720,
+   'original_height': 480,
+   'is_product': True},
+  {'position': 19,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822f423edd39d8f9d0285cc270a8c00a7ee.jpeg',
+   'related_content_id': 'ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',
+   'source': 'YouTube',
+   'title': 'Vegetarian Pad Thai Recipe TO MAKE TONIGHT (ผัดไทย)! - YouTube',
+   'link': 'https://www.youtube.com/watch?v=zy_P70hXhdM',
+   'tag': '8:44',
+   'original': 'https://i.ytimg.com/vi/zy_P70hXhdM/maxresdefault.jpg',
+   'original_width': 1280,
+   'original_height': 720,
+   'is_product': True},
+  {'position': 20,
+   'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225cd1fe40684d95943ec058d4b84eb560.jpeg',
+   'related_content_id': 'UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',
+   'source': 'Vegan Recipes from Cassie Howard',
+   'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',
+   'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai.jpg',
+   'original_width': 600,
+   'original_height': 903,
+   'is_product': True},
+  {'position': 21,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvfVfg8ufhxGbAvq1idiNghBJ-fXS2MqelDQ&usqp=CAU',
+   'related_content_id': 'NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',
+   'source': 'Spice Cravings',
+   'title': 'Vegan Pad Thai | Spice Cravings',
+   'link': 'https://spicecravings.com/vegan-pad-thai',
+   'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-2.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 22,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJ89CXPkap5RGkJHmeArqtTdY3pSO7w0DdNQ&usqp=CAU',
+   'related_content_id': 'bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',
+   'source': 'Pick Up Limes',
+   'title': 'Vegan Pad Thai | Pick Up Limes',
+   'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',
+   'tag': 'Recipe',
+   'original': 'https://cdn.pickuplimes.com/cache/1d/72/1d7201d4341ab93affd3ecfec7a7d5a2.jpg',
+   'original_width': 1280,
+   'original_height': 1920,
+   'is_product': True},
+  {'position': 23,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzjMINzFCCY2VU4QrzHkzBsVvtiJHsoF4Apw&usqp=CAU',
+   'related_content_id': 'MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',
+   'source': 'The Healthy Maven',
+   'title': 'Veggie Pad Thai Recipe [20 Minutes] - The Healthy Maven',
+   'link': 'https://www.thehealthymaven.com/pad-thai-recipe/',
+   'tag': 'Recipe',
+   'original': 'https://www.thehealthymaven.com/wp-content/uploads/2020/03/veggie-pad-thai-4-1-e1583795458972.jpg',
+   'original_width': 780,
+   'original_height': 790,
+   'is_product': True},
+  {'position': 24,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcv-xbBlo4x_uqyZY7fN4xVDtd0keRb9zt2Q&usqp=CAU',
+   'related_content_id': 'aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',
+   'source': "Del's cooking twist",
+   'title': "Easy Pad Thai (vegan, gluten-free) - Del's cooking twist",
+   'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',
+   'tag': 'Recipe',
+   'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3679.jpg',
+   'original_width': 1200,
+   'original_height': 1740,
+   'is_product': True},
+  {'position': 25,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-3rXOoQrYAAnTPYimImLdkllhrvwGjtpzuQ&usqp=CAU',
+   'related_content_id': 'cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',
+   'source': "Omnivore's Cookbook",
+   'title': "Vegan Pad Thai - Omnivore's Cookbook",
+   'link': 'https://omnivorescookbook.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://omnivorescookbook.com/wp-content/uploads/2019/04/1401_Vegan-Pad-Thai_002.jpg',
+   'original_width': 800,
+   'original_height': 1198,
+   'is_product': True},
+  {'position': 26,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRA6EbuGHJJ05llESu7R4DnXGJz0tLdAKHCag&usqp=CAU',
+   'related_content_id': 'aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',
+   'source': 'plantd',
+   'title': 'Vegan Pad Thai with Peanut Sauce',
+   'link': 'https://plantd.co/vegan-pad-thai-with-peanut-sauce/',
+   'tag': 'Recipe',
+   'original': 'https://plantd.co/wp-content/uploads/2020/03/Vegan-Pad-Thai-with-Peanut-Sauce.png',
+   'original_width': 1600,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 27,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-tJjj9tbpEaxSJtIxspo7uUdJEUzv9RvOIg&usqp=CAU',
+   'related_content_id': 'dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',
+   'source': 'From My Bowl',
+   'title': 'Vegan Pad Thai - From My Bowl',
+   'link': 'https://frommybowl.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-19-1.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 28,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNiutaTkD8VXJuR7_mWK2pI6B7cPV98YJ1Yw&usqp=CAU',
+   'related_content_id': 'NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',
+   'source': 'The Foodie Takes Flight',
+   'title': 'Vegan Pad Thai - The Foodie Takes Flight',
+   'link': 'https://thefoodietakesflight.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://thefoodietakesflight.com/wp-content/uploads/2021/06/vegan-pad-thai-recipe-10.png',
+   'original_width': 790,
+   'original_height': 1150,
+   'is_product': True},
+  {'position': 29,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtjaP5_LFHgeZL956hjrCANLq2zxN0VcNuDw&usqp=CAU',
+   'related_content_id': 'S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',
+   'source': 'One Ingredient Chef',
+   'title': 'Vegetarian Pad Thai Recipe | One Ingredient Chef',
+   'link': 'https://www.oneingredientchef.com/vegetarian-pad-thai/',
+   'original': 'https://www.oneingredientchef.com/wp-content/uploads/2013/06/VegetarianPadThai.jpg',
+   'original_width': 700,
+   'original_height': 783,
+   'is_product': False},
+  {'position': 30,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8a0V5sne-due2_0i_cLMG7mIDmIWWIlNdyg&usqp=CAU',
+   'related_content_id': 'RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',
+   'source': 'Love and Good Stuff',
+   'title': 'Vegetable Pad Thai - Love & Good Stuff',
+   'link': 'https://loveandgoodstuff.com/vegetable-pad-thai/',
+   'original': 'https://loveandgoodstuff.com/wp-content/uploads/2018/04/vegetable-pad-thai-6.jpg',
+   'original_width': 669,
+   'original_height': 1000,
+   'is_product': False},
+  {'position': 31,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq76Wud8JULmlFchKPTVnyslWUxpH0-tSocw&usqp=CAU',
+   'related_content_id': 'YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',
+   'source': 'Vibrant plate',
+   'title': 'The Best Vegan Tofu Pad Thai - Vibrant plate',
+   'link': 'https://www.vibrantplate.com/best-vegan-tofu-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.vibrantplate.com/wp-content/uploads/2021/01/Vegan-Tofu-Pad-Thai-05.jpg',
+   'original_width': 800,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 32,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTMA_IXXqLXbDaKJStkocE79DhiNy3h1wNfyg&usqp=CAU',
+   'related_content_id': 'X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',
+   'source': 'From My Bowl',
+   'title': 'Vegan Pad Thai - From My Bowl',
+   'link': 'https://frommybowl.com/vegan-pad-thai/',
+   'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-23.jpg',
+   'original_width': 1000,
+   'original_height': 1500,
+   'is_product': False},
+  {'position': 33,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUQbieaco9iYa16jcjeZbf-gmoP7gSvJyl0Q&usqp=CAU',
+   'related_content_id': 'd1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',
+   'source': 'BBC',
+   'title': 'Vegetable pad Thai recipe - BBC Food',
+   'link': 'https://www.bbc.co.uk/food/recipes/stirfryvegetarianpha_70987',
+   'tag': 'Recipe',
+   'original': 'https://ichef.bbci.co.uk/food/ic/food_16x9_832/recipes/stirfryvegetarianpha_70987_16x9.jpg',
+   'original_width': 832,
+   'original_height': 468,
+   'is_product': True},
+  {'position': 34,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT1WQnyJsXAny3gepgi_275uhe3V8VkQTMRtw&usqp=CAU',
+   'related_content_id': 'U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',
+   'source': 'Cilantro and Citronella',
+   'title': 'Vegetarian Pad Thai',
+   'link': 'https://www.cilantroandcitronella.com/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.cilantroandcitronella.com/wp-content/uploads/2015/03/pad-thai_1_04.jpg',
+   'original_width': 680,
+   'original_height': 1020,
+   'is_product': True},
+  {'position': 35,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT9yCD2ZFN3V0txxVJK59VZKQw8dHdf52U_9w&usqp=CAU',
+   'related_content_id': 'ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',
+   'source': 'Eat With Clarity',
+   'title': 'Best Vegan Pad Thai (Easy!) - Eat With Clarity',
+   'link': 'https://eatwithclarity.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://eatwithclarity.com/wp-content/uploads/2020/06/vegan-pad-thai-9.jpg',
+   'original_width': 1190,
+   'original_height': 1800,
+   'is_product': True},
+  {'position': 36,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-b-oobMM5KXLy32E-dTEmszExv0RTVq8OQQ&usqp=CAU',
+   'related_content_id': 'VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',
+   'source': 'Tesco Real Food',
+   'title': 'Vegetarian pad Thai | Tesco Real Food',
+   'link': 'https://realfood.tesco.com/recipes/vegetarian-pad-thai.html',
+   'tag': 'Recipe',
+   'original': 'https://realfood.tesco.com/media/images/Veg-Pad-Thai-LGH-069d45e9-fd6c-44d1-b747-83dbac2d921d-0-1400x919.jpg',
+   'original_width': 1400,
+   'original_height': 919,
+   'is_product': True},
+  {'position': 37,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtwz03hn90q7ot7m4-179UzOn7cQYaLBHrnA&usqp=CAU',
+   'related_content_id': 'aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',
+   'source': 'Klaraslife',
+   'title': 'Vegan Pad Thai with cashew butter & broccoli - Klara`s Life',
+   'link': 'https://klaraslife.com/en/vegan-pad-thai-with-cashew-butter-broccoli/',
+   'tag': 'Recipe',
+   'original': 'https://klaraslife.com/wp-content/uploads/2019/11/IMG_0935.jpg',
+   'original_width': 4000,
+   'original_height': 5895,
+   'is_product': True},
+  {'position': 38,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQDKEP2qkfB6nWHtF58pTBj7TJv2Jz63JYOw&usqp=CAU',
+   'related_content_id': 'Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',
+   'source': 'Fit Foodie Nutter',
+   'title': '30 MINUTE EASY VEGAN PAD THAI –',
+   'link': 'https://fitfoodienutter.com/recipe/30-minute-easy-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://fitfoodienutter.com/wp-content/uploads/2021/09/Vegan-Pad-Thai-12.jpg',
+   'original_width': 870,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 39,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIadiylajWRN_JnkLntJZSunU8qi7S1wxGvQ&usqp=CAU',
+   'related_content_id': 'SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',
+   'source': 'Gimme Some Oven',
+   'title': 'Pad Thai - Gimme Some Oven',
+   'link': 'https://www.gimmesomeoven.com/pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.gimmesomeoven.com/wp-content/uploads/2019/01/Pad-Thai-Recipe-1.jpg',
+   'original_width': 1392,
+   'original_height': 2088,
+   'is_product': True},
+  {'position': 40,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIpRVuMoifY2CKjWhZ_37sDaI5hp1tAw5T1Q&usqp=CAU',
+   'related_content_id': 'SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',
+   'source': 'The Kitchen Abroad',
+   'title': 'Quick One Pan Vegan Pad Thai Recipe with Tofu',
+   'link': 'https://www.thekitchenabroad.com/one-pan-vegan-pad-thai-recipe-with-tofu/',
+   'tag': 'Recipe',
+   'original': 'https://www.thekitchenabroad.com/wp-content/uploads/2020/06/Vegan-Pad-Thai-Recipe-with-Tofu-10.jpg',
+   'original_width': 1024,
+   'original_height': 1365,
+   'is_product': True},
+  {'position': 41,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTkI3AiNwZau82RGak_znF-NEWDMatcRdQ_2Q&usqp=CAU',
+   'related_content_id': 'SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',
+   'source': 'Food Network',
+   'title': 'Quick Veggie Pad Thai Recipe | Ree Drummond | Food Network',
+   'link': 'https://www.foodnetwork.com/recipes/ree-drummond/quick-veggie-pad-thai-9422028',
+   'tag': 'Recipe',
+   'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2020/09/25/WU2503__vegetable-pad-thai_s4x3.jpg.rend.hgtvcom.616.462.suffix/1601058180561.jpeg',
+   'original_width': 616,
+   'original_height': 462,
+   'is_product': True},
+  {'position': 42,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRJRZhgKxI1FzkCO0zB3RxLW1vAsi4WwL0Y7w&usqp=CAU',
+   'related_content_id': 'aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',
+   'source': 'Delish Knowledge',
+   'title': '15-Minute Vegan Pad Thai - Delish Knowledge',
+   'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles5-copy-1.jpg',
+   'original_width': 1000,
+   'original_height': 1000,
+   'is_product': True},
+  {'position': 43,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSGA5db-ShQpar2dyZk0cAxA4-cdHYsisG3g&usqp=CAU',
+   'related_content_id': 'Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',
+   'source': 'Six Hungry Feet',
+   'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',
+   'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',
+   'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-10.jpg',
+   'original_width': 1200,
+   'original_height': 1500,
+   'is_product': False},
+  {'position': 44,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQolfY7XMQv1Q3zJr8XCj0pasBRTBn7MrJocA&usqp=CAU',
+   'related_content_id': 'Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',
+   'source': 'White On Rice Couple',
+   'title': 'Vegetable Pad Thai Recipe w/ Cabbage EASY HEALTHY | White On Rice',
+   'link': 'https://whiteonricecouple.com/cabbage-vegetable-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://whiteonricecouple.com/recipe/images/Cabbage-Vegetable-Pad-Thai-1.jpg',
+   'original_width': 530,
+   'original_height': 699,
+   'is_product': True},
+  {'position': 45,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSium1YAIBcY-ty66CcxIZfjPydnxVlddWGwQ&usqp=CAU',
+   'related_content_id': 'VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'source': 'Minimalist Baker',
+   'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',
+   'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',
+   'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-14.jpg',
+   'original_width': 1456,
+   'original_height': 2184,
+   'is_product': False},
+  {'position': 46,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_1bo3u0kxqiO87hkxwyR5bhvZtWff-OdRRA&usqp=CAU',
+   'related_content_id': 'dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',
+   'source': 'Make It Dairy Free',
+   'title': 'Vegan Pad Thai - Make It Dairy Free',
+   'link': 'https://makeitdairyfree.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://makeitdairyfree.com/wp-content/uploads/2022/12/vegan-pad-thai-2.jpg',
+   'original_width': 736,
+   'original_height': 1104,
+   'is_product': True},
+  {'position': 47,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSW5-PJKenKvHTGKrhmzwyhhFUlvEkg25eRuQ&usqp=CAU',
+   'related_content_id': 'WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',
+   'source': 'Bianca Zapatka',
+   'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',
+   'link': 'https://biancazapatka.com/en/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/vegan-pad-thai-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-asian-food.jpg',
+   'original_width': 1440,
+   'original_height': 2016,
+   'is_product': True},
+  {'position': 48,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRiWrdDbuV_CM0exB7yBqyoCOWaYqD6nTtJQ&usqp=CAU',
+   'related_content_id': 'T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',
+   'source': 'Running on Real Food',
+   'title': 'Easy Vegan Tofu Pad Thai Recipe - Running on Real Food',
+   'link': 'https://runningonrealfood.com/tofu-pad-thai/',
+   'original': 'https://runningonrealfood.com/wp-content/uploads/2021/05/Best-Vegan-Tofu-Pad-Thai-Recipe-12.jpg',
+   'original_width': 1400,
+   'original_height': 2100,
+   'is_product': False},
+  {'position': 49,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtOw74y8VyL5dib33Rkr_Bu4Jo9K4Q3sJy1w&usqp=CAU',
+   'related_content_id': 'Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',
+   'source': 'Simply Recipes',
+   'title': 'Vegetarian Pad Thai Recipe',
+   'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',
+   'tag': 'Recipe',
+   'original': 'https://www.simplyrecipes.com/thmb/zH71oEuQnxw3B8536gZDM2_NkWI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-3-f47ff2bc806b4de9821e332a6126bcc1.jpg',
+   'original_width': 1500,
+   'original_height': 2250,
+   'is_product': True},
+  {'position': 50,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCaY87F2KeBqK2WQUNljTakrtO7Zlae5L4g&usqp=CAU',
+   'related_content_id': 'M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',
+   'source': 'Whitney Bond',
+   'title': 'Vegetable Pad Thai Recipe - WhitneyBond.com',
+   'link': 'https://whitneybond.com/whats-for-dinner-spicy-vegetable-pad-thai/',
+   'original': 'https://whitneybond.com/wp-content/uploads/2013/01/Vegetable-Pad-Thai-4.jpg',
+   'original_width': 1140,
+   'original_height': 1280,
+   'is_product': False},
+  {'position': 51,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSDWkQoMHapJVpYkNaQJbPyubSBwdP5is9eaw&usqp=CAU',
+   'related_content_id': 'eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',
+   'source': 'Six Hungry Feet',
+   'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',
+   'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',
+   'tag': 'Recipe',
+   'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-3.jpg',
+   'original_width': 1200,
+   'original_height': 1500,
+   'is_product': True},
+  {'position': 52,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQxAM2SH_lgbsUJZh0aljTp6OEQ0lNfSd2_BQ&usqp=CAU',
+   'related_content_id': 'cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',
+   'source': "Mom's Dinner",
+   'title': "The Best Vegetable Pad Thai - Mom's Dinner",
+   'link': 'https://momsdinner.net/vegetable-pad-thai/',
+   'original': 'https://momsdinner.net/wp-content/uploads/2021/04/Vegetable-Pad-Thai-Recipe-3.jpg',
+   'original_width': 1200,
+   'original_height': 1680,
+   'is_product': False},
+  {'position': 53,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwMUvtpa5kSIoAJ3kltgwtiuUYkvK9DJyg3w&usqp=CAU',
+   'related_content_id': 'NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',
+   'source': 'From The Comfort Of My Bowl',
+   'title': 'Easy Vegan Pad Thai - From The Comfort Of My Bowl',
+   'link': 'https://www.fromthecomfortofmybowl.com/vegan-pad-thai-recipe/',
+   'tag': 'Recipe',
+   'original': 'https://www.fromthecomfortofmybowl.com/wp-content/uploads/2021/03/best-vegan-pad-thai.jpg',
+   'original_width': 600,
+   'original_height': 900,
+   'is_product': True},
+  {'position': 54,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPqWPCZyN1t4YbQNSYBWPLWSwzenu1C7a52A&usqp=CAU',
+   'related_content_id': 'ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',
+   'source': 'Nora Cooks',
+   'title': 'Vegan Pad Thai - Nora Cooks',
+   'link': 'https://www.noracooks.com/vegan-pad-thai/',
+   'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-5.jpg',
+   'original_width': 1334,
+   'original_height': 2001,
+   'is_product': False},
+  {'position': 55,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREUFAdGtWRgMx9Qv45bdNbkRdlZnSFQZX7tQ&usqp=CAU',
+   'related_content_id': 'bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',
+   'source': 'Vegan Heaven',
+   'title': 'Vegan Pad Thai - Vegan Heaven',
+   'link': 'https://veganheaven.org/recipe/vegan-pad-thai/',
+   'original': 'https://veganheaven.org/wp-content/uploads/2019/04/Vegan-Pad-Thai_.jpg',
+   'original_width': 680,
+   'original_height': 900,
+   'is_product': False},
+  {'position': 56,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQW5Nh8vx1J5kcDtF7MZSnXljnKoalv8wq2RA&usqp=CAU',
+   'related_content_id': 'cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',
+   'source': 'Pinch of Yum',
+   'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',
+   'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',
+   'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-1-2.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 57,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRUtq_lbZ4d5Xfs2jW-qamRXEi-0T6rhsLjTg&usqp=CAU',
+   'related_content_id': 'bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',
+   'source': 'The Petite Cook',
+   'title': 'The Easiest Vegan Pad Thai - The Petite Cookâ„¢',
+   'link': 'https://www.thepetitecook.com/the-easiest-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.thepetitecook.com/wp-content/uploads/2017/03/vegan-pad-thai-recipe.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 58,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4uozc69jm3VWqxSKMG8hWocGvUtO4CXHPeA&usqp=CAU',
+   'related_content_id': 'cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',
+   'source': 'Food with Feeling',
+   'title': 'Vegan Pad Thai - Food with Feeling',
+   'link': 'https://foodwithfeeling.com/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://foodwithfeeling.com/wp-content/uploads/2021/02/Vegan-Pad-Thai-7.jpg',
+   'original_width': 700,
+   'original_height': 1050,
+   'is_product': True},
+  {'position': 59,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcShtayJD_o-2NYDRaFdO7kc0IBDFrXsaLRAmw&usqp=CAU',
+   'related_content_id': 'VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',
+   'source': 'HealthyGirl Kitchen',
+   'title': 'Vegan Pad Thai (easy!) - HealthyGirl Kitchen',
+   'link': 'https://healthygirlkitchen.com/recipes/authentic-vegan-pad-thai/',
+   'original': 'https://healthygirlkitchen.com/wp-content/uploads/2020/11/20201112-DSC_6273-2.jpeg',
+   'original_width': 2500,
+   'original_height': 1669,
+   'is_product': False},
+  {'position': 60,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFnQxVF9fa3yOIanaxEOhaThezpWFnL4LdKw&usqp=CAU',
+   'related_content_id': 'Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',
+   'source': 'PETA',
+   'title': 'Easy Vegan Pad Thai | PETA',
+   'link': 'https://www.peta.org/recipes/easy-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.peta.org/wp-content/uploads/2014/03/vegan-pad-thai-e1429117378854-602x452-1444238253.jpg',
+   'original_width': 602,
+   'original_height': 452,
+   'is_product': True},
+  {'position': 61,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJ2bEV_hnyoEftoYQQ2ivw6GAWsG3zvHcH2A&usqp=CAU',
+   'related_content_id': 'NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',
+   'source': 'Ministry of Curry',
+   'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',
+   'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',
+   'tag': 'Video',
+   'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-2.jpg',
+   'original_width': 1024,
+   'original_height': 1536,
+   'is_product': True},
+  {'position': 62,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0nCQUNnm-ZcLUpjYC487WehnBzJaNNAlVsA&usqp=CAU',
+   'related_content_id': 'cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',
+   'source': 'Crowded Kitchen',
+   'title': 'Vegan Pad Thai with Tofu - Crowded Kitchen',
+   'link': 'https://www.crowdedkitchen.com/vegan-pad-thai/',
+   'original': 'https://www.crowdedkitchen.com/wp-content/uploads/2021/01/pad-thai-new-8.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 63,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT96UeZ4BgEN0Q2Xp0fwWYr8KuHmgbo64Lukw&usqp=CAU',
+   'related_content_id': 'dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',
+   'source': 'Healing Tomato',
+   'title': 'Pad Thai Recipe (Vegan) - HealingTomato.com',
+   'link': 'https://www.healingtomato.com/pad-thai-recipe/',
+   'tag': 'Recipe',
+   'original': 'https://www.healingtomato.com/wp-content/uploads/2016/01/pad-thai.jpg',
+   'original_width': 600,
+   'original_height': 593,
+   'is_product': True},
+  {'position': 64,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQs0sHzHet343DWkhIN84nY2KeHE-mAR3zFTA&usqp=CAU',
+   'related_content_id': 'QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',
+   'source': 'Detoxinista',
+   'title': 'Best Ever Vegan Pad Thai - Detoxinista',
+   'link': 'https://detoxinista.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai.jpg',
+   'original_width': 1200,
+   'original_height': 1627,
+   'is_product': True},
+  {'position': 65,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHQuNuSPWyl4_RjkFeElvxvkLOtuWWqW6GAQ&usqp=CAU',
+   'related_content_id': 'emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',
+   'source': 'Loving It Vegan',
+   'title': 'Vegan Pad Thai - Loving It Vegan',
+   'link': 'https://lovingitvegan.com/vegan-pad-thai/',
+   'original': 'https://lovingitvegan.com/wp-content/uploads/2022/06/Vegan-Pad-Thai-22.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 66,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjWUg8dInH0c5rR8rRXl8EMKCxg1ccEhUekQ&usqp=CAU',
+   'related_content_id': 'RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',
+   'source': 'Hot For Food',
+   'title': 'vegan pad thai - hot for food by Lauren Toyota',
+   'link': 'https://www.hotforfoodblog.com/recipes/2015/02/02/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.hotforfoodblog.com/wp-content/uploads/2015/02/veganpadthai_hotforfoodblog_filtered1-500x375.jpg',
+   'original_width': 500,
+   'original_height': 375,
+   'is_product': True},
+  {'position': 67,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSur4LsaevwvR_0eZ2F3Tf-YVx6-jDRus6E-w&usqp=CAU',
+   'related_content_id': 'TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',
+   'source': 'Vegan Recipes from Cassie Howard',
+   'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',
+   'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai-Vegan.jpg',
+   'original_width': 600,
+   'original_height': 399,
+   'is_product': True},
+  {'position': 68,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRTcDJm39S6nz4sTyLF-l6j6CeiVTVkPOXQ5g&usqp=CAU',
+   'related_content_id': 'WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',
+   'source': 'Gluten-Free, Allergy-Free, and Vegan Recipes',
+   'title': 'Easy Vegan Pad Thai (Gluten-Free, Allergy-Free, Nut-Free, Soy-Free)',
+   'link': 'https://strengthandsunshine.com/vegan-pad-thai-gluten-free/',
+   'original': 'https://strengthandsunshine.com/wp-content/uploads/2019/05/Easy-Vegan-Pad-Thai-Gluten-Free-Allergy-Free-PM1.jpg',
+   'original_width': 735,
+   'original_height': 1102,
+   'is_product': False},
+  {'position': 69,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQru1It4T3WzwaedAbLeetEsVNE6DkIrC4L4w&usqp=CAU',
+   'related_content_id': 'dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',
+   'source': "Archana's Kitchen",
+   'title': "Vegetarian Pad Thai Recipe by Archana's Kitchen",
+   'link': 'https://www.archanaskitchen.com/vegetarian-pad-thai',
+   'original': 'https://www.archanaskitchen.com/images/archanaskitchen/0-Archanas-Kitchen-Recipes/2018/Vegetarian_Pad_Thai_Recipe-4-2.jpg',
+   'original_width': 1600,
+   'original_height': 1200,
+   'is_product': False},
+  {'position': 70,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSTdgEdXp-bEPIX-4ssadcX6rzD4KQxGE5w&usqp=CAU',
+   'related_content_id': 'ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',
+   'source': 'Pinch of Yum',
+   'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',
+   'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',
+   'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-6.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 71,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTyPzitaptGw98mR0Oqbxxc2B8FtDlN7vpDDw&usqp=CAU',
+   'related_content_id': 'RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',
+   'source': 'Fooby',
+   'title': 'Vegan Pad Thai - Recipes | fooby.ch',
+   'link': 'https://fooby.ch/en/recipes/17187/vegan-pad-thai',
+   'tag': 'Recipe',
+   'original': 'https://recipecontent.fooby.ch/17187_3-2_480-320.jpg',
+   'original_width': 480,
+   'original_height': 321,
+   'is_product': True},
+  {'position': 72,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9woGokoujYfjUge4wgpyswfCjstd_9uf1qw&usqp=CAU',
+   'related_content_id': 'XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',
+   'source': 'Nora Cooks',
+   'title': 'Vegan Pad Thai - Nora Cooks',
+   'link': 'https://www.noracooks.com/vegan-pad-thai/',
+   'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-7.jpg',
+   'original_width': 1334,
+   'original_height': 2001,
+   'is_product': False},
+  {'position': 73,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSexYRHt5Ul2JMDLnWUdBxc6ELsg2E1iDL31w&usqp=CAU',
+   'related_content_id': 'ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',
+   'source': "Del's cooking twist",
+   'title': "Easy Pad Thai (vegan, gluten-free) - Del's cooking twist",
+   'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',
+   'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3702.jpg',
+   'original_width': 1200,
+   'original_height': 822,
+   'is_product': False},
+  {'position': 74,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnQTyIRwdSk4FpeGIc-MQnw9411wG2ENeCIg&usqp=CAU',
+   'related_content_id': 'TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',
+   'source': 'Minimalist Baker',
+   'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',
+   'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',
+   'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-13.jpg',
+   'original_width': 1456,
+   'original_height': 2184,
+   'is_product': False},
+  {'position': 75,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREuE_KU8at0L9CjOGH_t4b-8Up9fL1WBIsUg&usqp=CAU',
+   'related_content_id': 'RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',
+   'source': 'Tasty',
+   'title': 'Vegan Pad Thai Recipe by Tasty',
+   'link': 'https://tasty.co/recipe/vegan-pad-thai',
+   'tag': 'Recipe',
+   'original': 'https://img.buzzfeed.com/thumbnailer-prod-us-east-1/video-api/assets/148610.jpg?resize=1200:*',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 76,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRqsk8XwnF_PLPcNqIatUj46HUH78xjZGBA5g&usqp=CAU',
+   'related_content_id': 'X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',
+   'source': 'Brand New Vegan',
+   'title': 'Easy Vegan Pad Thai - Brand New Vegan',
+   'link': 'https://www.brandnewvegan.com/recipes/easy-vegan-pad-thai',
+   'original': 'https://www.brandnewvegan.com/wp-content/uploads/easy-vegan-pad-thai-h1-1024x682.jpg',
+   'original_width': 1024,
+   'original_height': 682,
+   'is_product': False},
+  {'position': 77,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTjlYvkOX8aA0iNS-32KeueAcXbjYMIcRkfnQ&usqp=CAU',
+   'related_content_id': 'TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',
+   'source': "Kathy's Vegan Kitchen",
+   'title': "Vegan Pad Thai Recipe | Kathy's Vegan Kitchen",
+   'link': 'https://www.kathysvegankitchen.com/vegan-pad-thai-recipe/',
+   'tag': 'Recipe',
+   'original': 'https://www.kathysvegankitchen.com/wp-content/uploads/2021/09/Pad-Thai-.jpg',
+   'original_width': 1200,
+   'original_height': 1277,
+   'is_product': True},
+  {'position': 78,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEcvBpOj0RPCU23uRqHp6VJJrxfS3tQYnURw&usqp=CAU',
+   'related_content_id': 'SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',
+   'source': 'Real Thai Recipes',
+   'title': 'Vegetarian Pad Thai » Real Thai Recipes » Authentic Thai recipes from  Thailand',
+   'link': 'https://www.realthairecipes.com/recipes/vegetarian-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.realthairecipes.com/wp-content/uploads/vegetarian-pad-thai1.jpg',
+   'original_width': 440,
+   'original_height': 261,
+   'is_product': True},
+  {'position': 79,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJulkx7A2HLYWmkLlETfrNWofaQ6XllHyzeg&usqp=CAU',
+   'related_content_id': 'ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',
+   'source': 'Choosing Chia',
+   'title': 'Raw Pad Thai - Choosing Chia',
+   'link': 'https://choosingchia.com/raw-vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://choosingchia.com/jessh-jessh/uploads/2021/06/raw-pad-thai-4.jpg',
+   'original_width': 1360,
+   'original_height': 2040,
+   'is_product': True},
+  {'position': 80,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRf0Cju8qWUiOS3tuTGbs7-pXIIdVRzRLVJcQ&usqp=CAU',
+   'related_content_id': 'TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',
+   'source': "Cook's Hideout",
+   'title': "Vegan Pad Thai Noodles | Cook's Hideout",
+   'link': 'https://www.cookshideout.com/pad-thai-vegan-recipe',
+   'tag': '0:51',
+   'original': 'https://www.cookshideout.com/wp-content/uploads/2014/03/Vegan-Pad-Thai_4S.jpg',
+   'original_width': 1200,
+   'original_height': 1807,
+   'is_product': True},
+  {'position': 81,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq0f_iTXyVwmnFhPzttm7_lJp8ajUCmufkNQ&usqp=CAU',
+   'related_content_id': 'SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',
+   'source': "Chang's",
+   'title': "Rainbow Vegetarian Pad Thai with Crispy Noodles - Chang's Authentic Asian  Cooking",
+   'link': 'https://www.changs.com/recipes/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles/',
+   'original': 'https://ik.imagekit.io/webtactics/changs/tr:w-750,h-1000/cgblog/id298/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles.jpg',
+   'original_width': 750,
+   'original_height': 1000,
+   'is_product': False},
+  {'position': 82,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNxrIDPiE9qq8FTzKays6PAe4vKBNCSql2dw&usqp=CAU',
+   'related_content_id': 'VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',
+   'source': 'Connoisseurus Veg',
+   'title': 'Vegan Pad Thai - Connoisseurus Veg',
+   'link': 'https://www.connoisseurusveg.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.connoisseurusveg.com/wp-content/uploads/2021/04/vegan-pad-thai-r-8-of-10.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': True},
+  {'position': 83,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdkOE8fHkjIYt-VHnxHhCKT1Q4Ccu__Id64Q&usqp=CAU',
+   'related_content_id': 'R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',
+   'source': "Madhu's Everyday Indian",
+   'title': "Easy Vegan Pad Thai Recipe - Madhu's Everyday Indian",
+   'link': 'https://www.madhuseverydayindian.com/vegan-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://www.madhuseverydayindian.com/wp-content/uploads/2019/11/pad-thai-3.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': True},
+  {'position': 84,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRAqAWfnCA_xgZ33xmKJYH-GElMv8BR9SfEg&usqp=CAU',
+   'related_content_id': 'YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',
+   'source': 'Simply Recipes',
+   'title': 'Vegetarian Pad Thai Recipe',
+   'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',
+   'tag': 'Recipe',
+   'original': 'https://www.simplyrecipes.com/thmb/sNXRcU7H5YlFa9nto8PzROCcK6E=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-7-f2309902236d45f38dd937e894d7a95f.jpg',
+   'original_width': 1500,
+   'original_height': 1000,
+   'is_product': True},
+  {'position': 85,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvt5v5lIPiITlJSSh6yiG-k8NDEdEaAvrUZg&usqp=CAU',
+   'related_content_id': 'M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',
+   'source': 'Ve Eat Cook Bake',
+   'title': 'Vegan Tofu Pad Thai Recipe (easy, oil free) - Ve Eat Cook Bake',
+   'link': 'https://veeatcookbake.com/vegan-pad-thai-sauce/',
+   'tag': 'Recipe',
+   'original': 'https://veeatcookbake.com/wp-content/uploads/2020/01/vegan-tofu-pad-thai-3.jpg',
+   'original_width': 720,
+   'original_height': 1080,
+   'is_product': True},
+  {'position': 86,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmmjnFxGBdd4XrLb3_NV9S6DqDsrm8gCArrQ&usqp=CAU',
+   'related_content_id': 'd3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',
+   'source': 'Pinterest',
+   'title': 'Easy Vegan Pad Thai Recipe w/ Sauce - Choosing Chia | Recipe | Easy asian  noodle recipes, Vegan pad thai, Easy asian noodles',
+   'link': 'https://www.pinterest.com/pin/easy-vegan-pad-thai-recipe-w-sauce-choosing-chia--495044184044777788/',
+   'tag': 'Recipe',
+   'original': 'https://i.pinimg.com/736x/20/05/d9/2005d9d549ea0aa25d2823c4bd47de66.jpg',
+   'original_width': 735,
+   'original_height': 1102,
+   'is_product': True},
+  {'position': 87,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-brimcB4Yy8KjKGPRL_XwmcMsukorzxhh7w&usqp=CAU',
+   'related_content_id': 'bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',
+   'source': 'Spice Cravings',
+   'title': 'Vegan Pad Thai | Spice Cravings',
+   'link': 'https://spicecravings.com/vegan-pad-thai',
+   'tag': 'Recipe',
+   'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-Featured.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 88,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmLLjuIxWgB0eAVv4CpMkufWKkwP0OLh95rw&usqp=CAU',
+   'related_content_id': 'QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',
+   'source': 'Delish Knowledge',
+   'title': '15-Minute Vegan Pad Thai - Delish Knowledge',
+   'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',
+   'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles2.jpeg',
+   'original_width': 981,
+   'original_height': 1471,
+   'is_product': False},
+  {'position': 89,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQBFHo9kgwduVWWgXYbjwx8oHmzkRq4eFx_w&usqp=CAU',
+   'related_content_id': 'eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',
+   'source': 'Nifty Recipes',
+   'title': 'Easy Vegan Pad Thai from Tasty - recipe on Niftyrecipe.com',
+   'link': 'https://niftyrecipe.com/video/1616/easy-vegan-pad-thai',
+   'original': 'https://niftyrecipe.com/uploads/youtube/parse/gVXDvCI32N8.jpg',
+   'original_width': 640,
+   'original_height': 480,
+   'is_product': False},
+  {'position': 90,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQDNoodvmhaxXBanZUWokpcjFLd1lBmPi6N9g&usqp=CAU',
+   'related_content_id': 'UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',
+   'source': 'Detoxinista',
+   'title': 'Best Ever Vegan Pad Thai - Detoxinista',
+   'link': 'https://detoxinista.com/vegan-pad-thai/',
+   'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai-recipe.jpg',
+   'original_width': 1200,
+   'original_height': 1513,
+   'is_product': False},
+  {'position': 91,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTVHfWG0FG8Dlr4vAkRFB2CJEN1EUPWqp5dWQ&usqp=CAU',
+   'related_content_id': 'S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',
+   'source': 'Mom Always Finds Out',
+   'title': 'Recipe} Vegetarian Pad Thai in Less than 15 Minutes - Mom Always Finds Out',
+   'link': 'https://www.momalwaysfindsout.com/quick-pad-thai-recipe/',
+   'original': 'http://momalwaysfindsout.com/wp-content/uploads/2013/08/easy-vegetarian-pad-thai-recipe.jpg',
+   'original_width': 526,
+   'original_height': 416,
+   'is_product': False},
+  {'position': 92,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRhwBcrNUbTx9kzPKfcmWE0Ra7gapkAfRrcfw&usqp=CAU',
+   'related_content_id': 'YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',
+   'source': 'Nutriciously',
+   'title': 'Colorful Raw Vegan Pad Thai Salad – Nutriciously',
+   'link': 'https://nutriciously.com/raw-vegan-pad-thai-recipe/',
+   'tag': 'Recipe',
+   'original': 'https://nutriciously.com/wp-content/uploads/Raw-Vegan-Pad-Thai-by-Nutriciously-3-735x1102.jpg',
+   'original_width': 735,
+   'original_height': 1102,
+   'is_product': True},
+  {'position': 93,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTE247S-7oA7iBXdWKaWSVW76NBNMj9G1zMMA&usqp=CAU',
+   'related_content_id': 'YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',
+   'source': 'Jessica in the Kitchen',
+   'title': 'Easy Vegan Pad Thai | Jessica in the Kitchen',
+   'link': 'https://jessicainthekitchen.com/vegan-pad-thai/',
+   'original': 'https://jessicainthekitchen.com/wp-content/uploads/2022/08/Vegan-Pad-Thai0046.jpg',
+   'original_width': 1200,
+   'original_height': 1800,
+   'is_product': False},
+  {'position': 94,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEICg4TzsYnpMi-FDoDIIiTxIEYlkJotNZJw&usqp=CAU',
+   'related_content_id': 'Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',
+   'source': 'Feasting At Home',
+   'title': 'Pad Thai (Video!) | Feasting at Home',
+   'link': 'https://www.feastingathome.com/15-minute-pad-thai/',
+   'original': 'https://www.feastingathome.com/wp-content/uploads/2016/04/easy-authentic-pad-thai-recipe-100-8.jpg',
+   'original_width': 750,
+   'original_height': 1125,
+   'is_product': False},
+  {'position': 95,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRaL2_fWqKRkIvDq4dn5kZqexIjDD5rIpb-Q&usqp=CAU',
+   'related_content_id': 'aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',
+   'source': 'a Veg Taste from A to Z',
+   'title': 'Vegan Pad Thai with Cashews -',
+   'link': 'https://avegtastefromatoz.com/vegan-pad-thai-cashews/',
+   'tag': 'Recipe',
+   'original': 'https://avegtastefromatoz.com/wp-content/uploads/2020/09/pad-thai-5.jpg',
+   'original_width': 2048,
+   'original_height': 2048,
+   'is_product': True},
+  {'position': 96,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSQmbOr5bqa0rC0nX95VxH-6RasxkuymwUMg&usqp=CAU',
+   'related_content_id': 'Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',
+   'source': 'Plant-Based on a Budget',
+   'title': 'Vegan Vegetable Pad Thai - Plant-Based on a Budget',
+   'link': 'https://plantbasedonabudget.com/avocado-basil-pad-thai/',
+   'tag': 'Recipe',
+   'original': 'https://plantbasedonabudget.com/wp-content/uploads/2014/05/Vegan-Avocado-Basil-Pad-Thai-Plant-Based-on-a-Budget-1-2.jpg',
+   'original_width': 1200,
+   'original_height': 1200,
+   'is_product': True},
+  {'position': 97,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQOF76mQo9LZPzWv_vzVAz-od1L271ioKWNVA&usqp=CAU',
+   'related_content_id': 'Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',
+   'source': 'Full of Plants',
+   'title': 'The Best Vegan Pad Thai - Full of Plants',
+   'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',
+   'original': 'https://fullofplants.com/wp-content/uploads/2022/02/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-10-1400x2100.jpg',
+   'original_width': 1400,
+   'original_height': 2100,
+   'is_product': False},
+  {'position': 98,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-8yozAbc9Gpm97m_vt6sgcJ3mpTliabYGMQ&usqp=CAU',
+   'related_content_id': 'bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',
+   'source': "It's All Good Vegan",
+   'title': "Creamy Pad Thai Noodles - It's All Good Vegan",
+   'link': 'https://itsallgoodvegan.com/2020/02/19/creamy-pad-thai-noodles/',
+   'tag': 'Recipe',
+   'original': 'https://itsallgoodvegan.com/wp-content/uploads/2020/02/img_2841.jpg',
+   'original_width': 1638,
+   'original_height': 2048,
+   'is_product': True},
+  {'position': 99,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa2HSMw-ypurNqm48DPPpuKZOFbmDO65klnA&usqp=CAU',
+   'related_content_id': 'Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',
+   'source': 'Veggiekins',
+   'title': 'Vegan Pad Thai with Tofu (gluten free) (Gluten-Free) - Veggiekins Blog',
+   'link': 'https://veggiekinsblog.com/2021/03/24/vegan-pad-thai-with-tofu/',
+   'tag': 'Recipe',
+   'original': 'https://veggiekinsblog.com/wp-content/uploads/2021/03/Vegan-Pad-Thai-with-Tofu-4-scaled.jpg',
+   'original_width': 1708,
+   'original_height': 2560,
+   'is_product': True},
+  {'position': 100,
+   'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEZmnz4duD3odLwVNqQ_OfHJ1zPNaofthtXw&usqp=CAU',
+   'related_content_id': 'Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',
+   'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',
+   'source': 'Zucker&Jagdwurst',
+   'title': 'Vegan Pad Thai with “chicken“ - Zucker&Jagdwurst',
+   'link': 'https://www.zuckerjagdwurst.com/en/recipes/vegan-pad-thai-with-chicken',
+   'tag': 'Recipe',
+   'original': 'https://assets.zuckerjagdwurst.com/q9pjl6288ajpcx8s994gccncy1i1/1110/740/65/true/center/R435+Veganes+Pad+Thai+mit+%E2%80%9EHu%CC%88hnchen%E2%80%9C39.jpg?animated=false',
+   'original_width': 1110,
+   'original_height': 740,
+   'is_product': True}]}
+
+
+
+
for r in results["images_results"][0:10]:
+    display(r["title"], Image(url=r["thumbnail"]))
+
+
'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'
+
+
+ +
+
+
'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum'
+
+
+ +
+
+
'Healthier vegan pad thai - Lazy Cat Kitchen'
+
+
+ +
+
+
'The Best Vegan Pad Thai - Full of Plants'
+
+
+ +
+
+
'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria'
+
+
+ +
+
+
'Easy Vegan Pad Thai - My Darling Vegan'
+
+
+ +
+
+
'Easy Vegetarian Pad Thai - Pinch Me Good'
+
+
+ +
+
+
'30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs'
+
+
+ +
+
+
'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry'
+
+
+ +
+
+
'Vegan pad thai - Lazy Cat Kitchen'
+
+
+ +
+
+
+
# You can create the tool to pass to an agent
+serpapi_recipe_tool = Tool(
+    name="",
+    description="A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.",
+    func=search.run,
+)
+
+

This doc should be corrected LangChain serpapi doc could be updated

+
+
search = GoogleSerperAPIWrapper(type="search")
+results = search.results("Lion")
+
+

edamam

+ + +
+ +
+ +
+ + + + \ No newline at end of file diff --git a/_proc/_docs/robots.txt b/_proc/_docs/robots.txt new file mode 100644 index 0000000000000000000000000000000000000000..52097efe9f6e1025cebc0dc2972b158890fcafa9 --- /dev/null +++ b/_proc/_docs/robots.txt @@ -0,0 +1 @@ +Sitemap: https://animalequality.github.io/lv-recipe-chatbot/sitemap.xml diff --git a/_proc/_docs/search.json b/_proc/_docs/search.json new file mode 100644 index 0000000000000000000000000000000000000000..4ad3fe6c2f3a3fad3342bfee7981d34d260afd2e --- /dev/null +++ b/_proc/_docs/search.json @@ -0,0 +1,79 @@ +[ + { + "objectID": "app.html", + "href": "app.html", + "title": "app", + "section": "", + "text": "source\n\nConversationBot\n\n ConversationBot ()\n\nInitialize self. See help(type(self)) for accurate signature.\n\nsource\n\n\nlaunch_demo\n\n launch_demo ()\n\nLoad environment for the demo\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\nlaunch_demo()\n\nRunning on local URL: http://127.0.0.1:7862\n\nTo create a public link, set `share=True` in `launch()`." + }, + { + "objectID": "index.html", + "href": "index.html", + "title": "lv-recipe-chatbot", + "section": "", + "text": "This file will become your README and also the index of your documentation." + }, + { + "objectID": "index.html#install", + "href": "index.html#install", + "title": "lv-recipe-chatbot", + "section": "Install", + "text": "Install\npip install lv_recipe_chatbot" + }, + { + "objectID": "index.html#how-to-use", + "href": "index.html#how-to-use", + "title": "lv-recipe-chatbot", + "section": "How to use", + "text": "How to use\n\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\napp.launch_demo()\n\nRunning on local URL: http://127.0.0.1:7860\n\nTo create a public link, set `share=True` in `launch()`.\n\n\nor\npython3 app.py" + }, + { + "objectID": "index.html#dev-quick-start", + "href": "index.html#dev-quick-start", + "title": "lv-recipe-chatbot", + "section": "Dev quick-start", + "text": "Dev quick-start\ngit clone the repo\ncd lv-recipe-chatbot\nMake sure to use the version of python specified in py_version.txt\nCreate a virtual environment.\npython3 -m venv env\nActivate the env and install dependencies.\nsource env/bin/activate\npip install -r requirements.txt\npip install -r requirements/dev.txt\nTo make the Jupyter environment, git friendly: nbdev_install_hooks\nIf you want to render documentation locally, you will want to install Quarto.\nnbdev_install_quarto\nPut API secrets in .env\ncp .env.example .env\nEdit .env with your secret key(s). Only OPEN_AI_KEY is required.\nThen start the Gradio demo from within the virtual environment.\npython3 app.py\nPreview documentation\nnbdev_preview" + }, + { + "objectID": "index.html#dependencies", + "href": "index.html#dependencies", + "title": "lv-recipe-chatbot", + "section": "Dependencies", + "text": "Dependencies\nIf a new dependency for development is helpful for developers, add it to dev.txt.\nIf it is a dependency for the app that is imported in source code, add it to core.txt.\nThen run:\npipreqs --force\nThis will update our requirements.txt to include the dependency as it should be pinned in the environment." + }, + { + "objectID": "index.html#development", + "href": "index.html#development", + "title": "lv-recipe-chatbot", + "section": "Development", + "text": "Development\nquick nbdev tutorial\nMake changes in /nbs.\nUpdate the package files with nbdev_export then reimport with pip install -e '.[dev]'\nPreview doc nbdev_preview\nBuild docs, test and update README nbdev_prepare" + }, + { + "objectID": "index.html#useful-links", + "href": "index.html#useful-links", + "title": "lv-recipe-chatbot", + "section": "Useful links", + "text": "Useful links\n\nTask Matrix (Formerly Visual ChatGPT)\nLangChain\nLLM Prompt Engineering\nOpenAI best practices for prompts" + }, + { + "objectID": "lchain_tool.html", + "href": "lchain_tool.html", + "title": "lchain_tool", + "section": "", + "text": "from dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\n\nllm = ChatOpenAI(temperature=0)\n\n\ntools = load_tools([\"llm-math\"], llm=llm)\nagent = initialize_agent(\n tools,\n llm,\n agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n handle_parsing_errors=True,\n verbose=True,\n)\n\n\nagent(\"What is the 3% of of 300 * 30?\")\n\n\n\n> Entering new AgentExecutor chain...\nWe can calculate this using the Calculator tool.\n\nAction:\n```\n{\n \"action\": \"Calculator\",\n \"action_input\": \"0.03 * 300 * 30\"\n}\n```\n\n\nObservation: Answer: 270.0\nThought:Could not parse LLM output: This is the correct answer to the question.\nObservation: Invalid or incomplete response\nThought:Let me try the same action again.\n\nAction:\n```\n{\n \"action\": \"Calculator\",\n \"action_input\": \"0.03 * 300 * 30\"\n}\n```\n\n\nObservation: Answer: 270.0\nThought:Could not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n\nObservation: Invalid or incomplete response\nThought:There seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n\nAction:\n```\n{\n \"action\": \"Calculator\",\n \"action_input\": \"300 * 30 * 0.03\"\n}\n```\n\n\nObservation: Answer: 270.0\nThought:I have successfully calculated the answer to the question using the calculator tool.\n\nFinal Answer: 270.0\n\n> Finished chain.\n\n\n{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}\n\n\nSerpAPI Google Images\n\nparams = {\n \"q\": \"Vegan pad thai recipes\",\n \"location\": \"United States\",\n \"hl\": \"en\",\n \"gl\": \"us\",\n \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n}\n\nsearch = GoogleSearch(params)\nresults = search.get_dict()\nrecipes_results = results[\"recipes_results\"]\nrecipes_results\n\n[{'title': 'Easy Tofu Pad Thai',\n 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n 'source': 'Minimalist Baker',\n 'rating': 4.9,\n 'reviews': 117,\n 'total_time': '30 min',\n 'ingredients': ['Pad thai rice',\n 'peanut sauce',\n 'thai red',\n 'soy sauce',\n 'bean sprouts']},\n {'title': 'Vegan Pad Thai',\n 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n 'source': 'Nora Cooks',\n 'rating': 5.0,\n 'reviews': 53,\n 'total_time': '30 min',\n 'ingredients': ['Stir fry rice',\n 'mung bean sprouts',\n 'soy sauce',\n 'maple syrup',\n 'sriracha hot sauce']},\n {'title': 'Vegan Pad Thai',\n 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n 'source': 'Pick Up Limes',\n 'rating': 5.0,\n 'reviews': 34,\n 'total_time': '30 min',\n 'ingredients': ['Brown rice noodles',\n 'red hot',\n 'soy sauce',\n 'bean sprouts',\n 'sriracha hot sauce']}]\n\n\n\n\nSerpAPIWrapper\n\n SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n serpapi_api_key:Optional[str]=None,\n aiosession:Optional[aiohttp.client.ClientSession]=None)\n\nWrapper around SerpAPI.\nTo use, you should have the google-search-results python package installed, and the environment variable SERPAPI_API_KEY set with your API key, or pass serpapi_api_key as a named parameter to the constructor.\nExample: .. code-block:: python\n from langchain import SerpAPIWrapper\n serpapi = SerpAPIWrapper()\n\nsource\n\n\nRecipeSerpAPIWrapper\n\n RecipeSerpAPIWrapper (search_engine:Any=None, params:dict={'engine':\n 'google', 'google_domain': 'google.com', 'gl':\n 'us', 'hl': 'en'},\n serpapi_api_key:Optional[str]=None, aiosession:Opti\n onal[aiohttp.client.ClientSession]=None)\n\nWrapper around SerpAPI.\nTo use, you should have the google-search-results python package installed, and the environment variable SERPAPI_API_KEY set with your API key, or pass serpapi_api_key as a named parameter to the constructor.\nExample: .. code-block:: python\n from langchain import SerpAPIWrapper\n serpapi = SerpAPIWrapper()\n\nparams = {\n \"location\": \"United States\",\n \"hl\": \"en\",\n \"gl\": \"us\",\n}\nsearch = RecipeSerpAPIWrapper(params=params)\n\n\nvegan_recipes = search.run(\"Vegan fried rice recipes\")\nvegan_recipes\n\n[{'title': 'Easy Vegan Fried Rice',\n 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n 'source': 'Minimalist Baker',\n 'rating': 4.8,\n 'reviews': 457,\n 'total_time': '1 hr 15 min',\n 'ingredients': ['Peanut butter',\n 'grain brown rice',\n 'soy sauce',\n 'maple syrup',\n 'chili garlic sauce']},\n {'title': 'The Best Vegan Fried Rice',\n 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n 'source': 'Short Girl Tall Order',\n 'rating': 4.8,\n 'reviews': 65,\n 'total_time': '28 min',\n 'ingredients': ['Soy sauce',\n 'white rice',\n 'rice wine vinegar',\n 'sugar',\n 'fresh peas']},\n {'title': 'Vegan Fried Rice',\n 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n 'source': 'Nora Cooks',\n 'rating': 5.0,\n 'reviews': 15,\n 'total_time': '20 min',\n 'ingredients': ['Gluten free',\n 'nutritional yeast',\n 'toasted sesame oil',\n 'carrots',\n 'olive oil']}]\n\n\n\nparams = {\n \"engine\": \"google_images\",\n \"q\": \"Vegan pad thai recipes\",\n \"location\": \"United States\",\n \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n}\n\nsearch = GoogleSearch(params)\nresults = search.get_dict()\nresults\n\n{'search_metadata': {'id': '647fff28b7b1ccd51d11a01d',\n 'status': 'Success',\n 'json_endpoint': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.json',\n 'created_at': '2023-06-07 03:53:12 UTC',\n 'processed_at': '2023-06-07 03:53:12 UTC',\n 'google_images_url': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&oq=Vegan+pad+thai+recipes&uule=w+CAIQICINVW5pdGVkIFN0YXRlcw&hl=en&gl=us&tbm=isch',\n 'raw_html_file': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.html',\n 'total_time_taken': 10.18},\n 'search_parameters': {'engine': 'google_images',\n 'q': 'Vegan pad thai recipes',\n 'location_requested': 'United States',\n 'location_used': 'United States',\n 'google_domain': 'google.com',\n 'hl': 'en',\n 'gl': 'us',\n 'device': 'desktop'},\n 'search_information': {'image_results_state': 'Results for exact spelling',\n 'menu_items': [{'position': 1,\n 'title': 'All',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEAI',\n 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n {'position': 2,\n 'title': 'Videos',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=vid&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEAQ',\n 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_videos&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n {'position': 3, 'title': 'Images'},\n {'position': 4,\n 'title': 'Shopping',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=shop&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEAg',\n 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_shopping&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n {'position': 5,\n 'title': 'Maps',\n 'link': 'https://maps.google.com/maps?q=Vegan+pad+thai+recipes&source=lmns&entry=mc&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAR6BAgBEAo'},\n {'position': 6,\n 'title': 'Books',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=bks&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEA0'},\n {'position': 7,\n 'title': 'News',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=nws&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEA4',\n 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes&tbm=nws'},\n {'position': 8,\n 'title': 'Flights',\n 'link': 'https://www.google.com/travel/flights?q=Vegan+pad+thai+recipes&source=lmns&tbm=flm&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAJ6BAgBEA8'},\n {'position': 9,\n 'title': 'Finance',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=fin&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEBA'}]},\n 'suggested_searches': [{'name': 'rice noodles',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAHoECAEQKw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Arice%2Bnoodles%3Agk0lY1Ku8x8%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b7f361a9f8fb38098b46394cb9c659c83.jpeg'},\n {'name': 'gluten free',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAXoECAEQLQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Agluten%2Bfree%3A_Jv5VE84jYQ%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba4acd7acf58a4e539824754bccf790f0.jpeg'},\n {'name': 'tofu',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAnoECAEQLw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Atofu%3AEdnrGNBK_3E%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b57cb6349f17e3b4997748a7fb2213981.jpeg'},\n {'name': 'thai peanut sauce',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoA3oECAEQMQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bpeanut%2Bsauce%3AAOyraWKuKIU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2bc44c0d5d0eef2c4dfefe036887628a3c.jpeg'},\n {'name': 'vegan gluten',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBHoECAEQMw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Avegan%2Bgluten%3AYD_J3kTgidI%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b631482aae166e90902888b39f9df86d4.jpeg'},\n {'name': 'thai food',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBXoECAEQNQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bfood%3A0nWr99Uxrwc%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3abb47a217c7337c6259316ffb3146b6.jpeg'},\n {'name': 'thai tofu pad',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBnoECAEQNw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Btofu%2Bpad%3A-u5KMb62hFM%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba9dc874972edb8879d31906ca8d02d1e.jpeg'},\n {'name': 'food network',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoB3oECAEQOQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afood%2Bnetwork%3A4fsBYIFuk6M%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3542cf3034c40352d8800de25efd446c.jpeg'},\n {'name': 'peanut butter',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCHoECAEQOw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Apeanut%2Bbutter%3AFJXMrvqXmOU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b5b6523f5ed417f4c899d005473ba16b5.jpeg'},\n {'name': 'stir fry',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCXoECAEQPQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Astir%2Bfry%3Ao0twgEKDva0%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3337398b3fc538d59c1a2d960953452d.jpeg'},\n {'name': 'plant based',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCnoECAEQPw',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Aplant%2Bbased%3A6BEj1Wk084g%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3d37839120548e6228cc4e71e1b7c7af.jpeg'},\n {'name': 'fried tofu',\n 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoC3oECAEQQQ',\n 'chips': 'q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D',\n 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afried%2Btofu%3AEpVuI9_hNoU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2be19daee44662280115fa006abc2bf75b.jpeg'}],\n 'images_results': [{'position': 1,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg',\n 'related_content_id': 'aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'source': 'Minimalist Baker',\n 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/Easy-Vegan-Pad-Thai-SQUARE.jpg',\n 'original_width': 1452,\n 'original_height': 1453,\n 'is_product': True},\n {'position': 2,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg',\n 'related_content_id': 'RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n 'source': 'Pinch of Yum',\n 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n 'tag': 'Recipe',\n 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Thai-Recipe.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 3,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg',\n 'related_content_id': 'b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n 'source': 'Lazy Cat Kitchen',\n 'title': 'Healthier vegan pad thai - Lazy Cat Kitchen',\n 'link': 'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2021/01/healthier-vegan-pad-thai-macro-1024x1536.jpg',\n 'original_width': 1024,\n 'original_height': 1536,\n 'is_product': True},\n {'position': 4,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg',\n 'related_content_id': 'akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n 'source': 'Full of Plants',\n 'title': 'The Best Vegan Pad Thai - Full of Plants',\n 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://fullofplants.com/wp-content/uploads/2022/03/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-thumb.jpg',\n 'original_width': 1440,\n 'original_height': 1440,\n 'is_product': True},\n {'position': 5,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg',\n 'related_content_id': 'MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n 'source': 'earthofmaria.com',\n 'title': 'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria',\n 'link': 'https://earthofmaria.com/easy-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://earthofmaria.com/wp-content/uploads/2019/04/Easy-Vegan-Pad-Thai-Gluten-free-6.jpg',\n 'original_width': 1024,\n 'original_height': 1536,\n 'is_product': True},\n {'position': 6,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36f9a1c02c421efe07d8d147f542087ff245f0933ec60896cd.jpeg',\n 'related_content_id': 'N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n 'source': 'My Darling Vegan',\n 'title': 'Easy Vegan Pad Thai - My Darling Vegan',\n 'link': 'https://www.mydarlingvegan.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.mydarlingvegan.com/wp-content/uploads/2021/07/Vegan-Pad-Thai-2.jpg',\n 'original_width': 1024,\n 'original_height': 1536,\n 'is_product': True},\n {'position': 7,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a75a0136dd1f95918c9bb1ded2f17e5c31f13d3708cc723f.jpeg',\n 'related_content_id': 'NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n 'source': 'Pinch Me Good',\n 'title': 'Easy Vegetarian Pad Thai - Pinch Me Good',\n 'link': 'https://pinchmegood.com/easy-vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://pinchmegood.com/wp-content/uploads/2019/03/Easy-Vegetarian-Pad-Thai.jpg',\n 'original_width': 924,\n 'original_height': 1386,\n 'is_product': True},\n {'position': 8,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36cdf1d570098da37da75a20a5a2ed59916c3cc1ac656f5b45.jpeg',\n 'related_content_id': 'NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n 'source': 'Vegan Huggs',\n 'title': '30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs',\n 'link': 'https://veganhuggs.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://veganhuggs.com/wp-content/uploads/2019/03/vegan-pad-thai-3.jpg',\n 'original_width': 680,\n 'original_height': 1020,\n 'is_product': True},\n {'position': 9,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd364677ba205872944cc9932a27c40873a1e3f4424ca6219c9b.jpeg',\n 'related_content_id': 'OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n 'source': 'Ministry of Curry',\n 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-1.jpg',\n 'original_width': 1024,\n 'original_height': 1536,\n 'is_product': True},\n {'position': 10,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3600f3b428f18999842a7c3ddc41991cd1d626950bd108397d.jpeg',\n 'related_content_id': 'bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n 'source': 'Lazy Cat Kitchen',\n 'title': 'Vegan pad thai - Lazy Cat Kitchen',\n 'link': 'https://www.lazycatkitchen.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2016/05/vegan-pad-thai-1000x1500.jpg',\n 'original_width': 1000,\n 'original_height': 1500,\n 'is_product': True},\n {'position': 11,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224470ef6b1b3462b418875bdedefa3d79.jpeg',\n 'related_content_id': 'NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n 'source': 'Well Plated by Erin',\n 'title': 'Vegetarian Pad Thai {30-Minute Recipe} - WellPlated.com',\n 'link': 'https://www.wellplated.com/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.wellplated.com/wp-content/uploads/2017/08/Healthy-Vegetarian-Pad-Thai.jpg',\n 'original_width': 1200,\n 'original_height': 1469,\n 'is_product': True},\n {'position': 12,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82276df3b8fda0d0c061010978e4b536cc1.jpeg',\n 'related_content_id': 'WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n 'source': 'The Spruce Eats',\n 'title': 'Vegetarian Pad Thai Recipe',\n 'link': 'https://www.thespruceeats.com/vegetarian-pad-thai-3217746',\n 'tag': 'Recipe',\n 'original': 'https://www.thespruceeats.com/thmb/wF19pUZKaKo66pofbpjI0eS1SLc=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/vegetarian-pad-thai-3217746-step-11-231a859fac40430583b044297aaf4a87.jpg',\n 'original_width': 1500,\n 'original_height': 1000,\n 'is_product': True},\n {'position': 13,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82281ba3f6ced7a769ced6de3c3b0f1fe41.jpeg',\n 'related_content_id': 'MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n 'source': 'Simply Recipes',\n 'title': 'Vegetarian Pad Thai Recipe',\n 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n 'tag': 'Recipe',\n 'original': 'https://www.simplyrecipes.com/thmb/Y6WvULetSWWIjzcQONSg9n8PFgg=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-2f0142cca68e4f9592381d281a391d59.jpg',\n 'original_width': 1500,\n 'original_height': 1000,\n 'is_product': True},\n {'position': 14,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224df1973dd2dbff9bcbe3402164ae150c.jpeg',\n 'related_content_id': 'bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n 'source': 'Food Network',\n 'title': 'Vegetarian Pad Thai Recipe | Food Network Kitchen | Food Network',\n 'link': 'https://www.foodnetwork.com/recipes/food-network-kitchen/vegetarian-pad-thai-7183115',\n 'tag': 'Recipe',\n 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2019/9/10/0/FNK_Vegetarian-Tofu-Pad-Thai_H2_s4x3.jpg.rend.hgtvcom.616.462.suffix/1568385716096.jpeg',\n 'original_width': 616,\n 'original_height': 462,\n 'is_product': True},\n {'position': 15,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822ed36be9df00a80e5203ab96f92fc31fd.jpeg',\n 'related_content_id': 'RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n 'source': 'Bianca Zapatka',\n 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/pad-thai-vegan-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-720x1008.jpg',\n 'original_width': 720,\n 'original_height': 1008,\n 'is_product': True},\n {'position': 16,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8223cb49bc3c204d16373a0a6e257d6e54f.jpeg',\n 'related_content_id': 'UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n 'source': 'EatPlant-Based.com',\n 'title': 'Easy Vegan Pad Thai - EatPlant-Based',\n 'link': 'https://eatplant-based.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://eatplant-based.com/wp-content/uploads/2022/03/Awakened-Pad-Thai-3.jpeg',\n 'original_width': 668,\n 'original_height': 1000,\n 'is_product': True},\n {'position': 17,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225dcace1e2fb2aebe208ed1bfde7e8775.jpeg',\n 'related_content_id': 'UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n 'source': 'Taste of Home',\n 'title': 'Vegetarian Pad Thai Recipe: How to Make It',\n 'link': 'https://www.tasteofhome.com/recipes/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://tmbidigitalassetsazure.blob.core.windows.net/rms3-prod/attachments/37/1200x1200/Vegetarian-Pad-Thai_EXPS_HCK18_197935_B04_014_4b.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 18,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82263e484cb2a264123c087cf8b9eb10c0d.jpeg',\n 'related_content_id': 'djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n 'source': 'Taste',\n 'title': '10-minute vegetarian pad Thai recipe',\n 'link': 'https://www.taste.com.au/recipes/10-minute-vegetarian-pad-thai-recipe/4bq39nic',\n 'tag': 'Recipe',\n 'original': 'https://img.taste.com.au/jgHrD_eG/w720-h480-cfill-q80/taste/2021/02/10-minute-vegetarian-pad-thai-168946-2.jpg',\n 'original_width': 720,\n 'original_height': 480,\n 'is_product': True},\n {'position': 19,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822f423edd39d8f9d0285cc270a8c00a7ee.jpeg',\n 'related_content_id': 'ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n 'source': 'YouTube',\n 'title': 'Vegetarian Pad Thai Recipe TO MAKE TONIGHT (ผัดไทย)! - YouTube',\n 'link': 'https://www.youtube.com/watch?v=zy_P70hXhdM',\n 'tag': '8:44',\n 'original': 'https://i.ytimg.com/vi/zy_P70hXhdM/maxresdefault.jpg',\n 'original_width': 1280,\n 'original_height': 720,\n 'is_product': True},\n {'position': 20,\n 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225cd1fe40684d95943ec058d4b84eb560.jpeg',\n 'related_content_id': 'UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n 'source': 'Vegan Recipes from Cassie Howard',\n 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai.jpg',\n 'original_width': 600,\n 'original_height': 903,\n 'is_product': True},\n {'position': 21,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvfVfg8ufhxGbAvq1idiNghBJ-fXS2MqelDQ&usqp=CAU',\n 'related_content_id': 'NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n 'source': 'Spice Cravings',\n 'title': 'Vegan Pad Thai | Spice Cravings',\n 'link': 'https://spicecravings.com/vegan-pad-thai',\n 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-2.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 22,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJ89CXPkap5RGkJHmeArqtTdY3pSO7w0DdNQ&usqp=CAU',\n 'related_content_id': 'bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n 'source': 'Pick Up Limes',\n 'title': 'Vegan Pad Thai | Pick Up Limes',\n 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n 'tag': 'Recipe',\n 'original': 'https://cdn.pickuplimes.com/cache/1d/72/1d7201d4341ab93affd3ecfec7a7d5a2.jpg',\n 'original_width': 1280,\n 'original_height': 1920,\n 'is_product': True},\n {'position': 23,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzjMINzFCCY2VU4QrzHkzBsVvtiJHsoF4Apw&usqp=CAU',\n 'related_content_id': 'MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n 'source': 'The Healthy Maven',\n 'title': 'Veggie Pad Thai Recipe [20 Minutes] - The Healthy Maven',\n 'link': 'https://www.thehealthymaven.com/pad-thai-recipe/',\n 'tag': 'Recipe',\n 'original': 'https://www.thehealthymaven.com/wp-content/uploads/2020/03/veggie-pad-thai-4-1-e1583795458972.jpg',\n 'original_width': 780,\n 'original_height': 790,\n 'is_product': True},\n {'position': 24,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcv-xbBlo4x_uqyZY7fN4xVDtd0keRb9zt2Q&usqp=CAU',\n 'related_content_id': 'aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n 'source': \"Del's cooking twist\",\n 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n 'tag': 'Recipe',\n 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3679.jpg',\n 'original_width': 1200,\n 'original_height': 1740,\n 'is_product': True},\n {'position': 25,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-3rXOoQrYAAnTPYimImLdkllhrvwGjtpzuQ&usqp=CAU',\n 'related_content_id': 'cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n 'source': \"Omnivore's Cookbook\",\n 'title': \"Vegan Pad Thai - Omnivore's Cookbook\",\n 'link': 'https://omnivorescookbook.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://omnivorescookbook.com/wp-content/uploads/2019/04/1401_Vegan-Pad-Thai_002.jpg',\n 'original_width': 800,\n 'original_height': 1198,\n 'is_product': True},\n {'position': 26,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRA6EbuGHJJ05llESu7R4DnXGJz0tLdAKHCag&usqp=CAU',\n 'related_content_id': 'aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n 'source': 'plantd',\n 'title': 'Vegan Pad Thai with Peanut Sauce',\n 'link': 'https://plantd.co/vegan-pad-thai-with-peanut-sauce/',\n 'tag': 'Recipe',\n 'original': 'https://plantd.co/wp-content/uploads/2020/03/Vegan-Pad-Thai-with-Peanut-Sauce.png',\n 'original_width': 1600,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 27,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-tJjj9tbpEaxSJtIxspo7uUdJEUzv9RvOIg&usqp=CAU',\n 'related_content_id': 'dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n 'source': 'From My Bowl',\n 'title': 'Vegan Pad Thai - From My Bowl',\n 'link': 'https://frommybowl.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-19-1.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 28,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNiutaTkD8VXJuR7_mWK2pI6B7cPV98YJ1Yw&usqp=CAU',\n 'related_content_id': 'NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n 'source': 'The Foodie Takes Flight',\n 'title': 'Vegan Pad Thai - The Foodie Takes Flight',\n 'link': 'https://thefoodietakesflight.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://thefoodietakesflight.com/wp-content/uploads/2021/06/vegan-pad-thai-recipe-10.png',\n 'original_width': 790,\n 'original_height': 1150,\n 'is_product': True},\n {'position': 29,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtjaP5_LFHgeZL956hjrCANLq2zxN0VcNuDw&usqp=CAU',\n 'related_content_id': 'S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n 'source': 'One Ingredient Chef',\n 'title': 'Vegetarian Pad Thai Recipe | One Ingredient Chef',\n 'link': 'https://www.oneingredientchef.com/vegetarian-pad-thai/',\n 'original': 'https://www.oneingredientchef.com/wp-content/uploads/2013/06/VegetarianPadThai.jpg',\n 'original_width': 700,\n 'original_height': 783,\n 'is_product': False},\n {'position': 30,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8a0V5sne-due2_0i_cLMG7mIDmIWWIlNdyg&usqp=CAU',\n 'related_content_id': 'RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n 'source': 'Love and Good Stuff',\n 'title': 'Vegetable Pad Thai - Love & Good Stuff',\n 'link': 'https://loveandgoodstuff.com/vegetable-pad-thai/',\n 'original': 'https://loveandgoodstuff.com/wp-content/uploads/2018/04/vegetable-pad-thai-6.jpg',\n 'original_width': 669,\n 'original_height': 1000,\n 'is_product': False},\n {'position': 31,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq76Wud8JULmlFchKPTVnyslWUxpH0-tSocw&usqp=CAU',\n 'related_content_id': 'YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n 'source': 'Vibrant plate',\n 'title': 'The Best Vegan Tofu Pad Thai - Vibrant plate',\n 'link': 'https://www.vibrantplate.com/best-vegan-tofu-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.vibrantplate.com/wp-content/uploads/2021/01/Vegan-Tofu-Pad-Thai-05.jpg',\n 'original_width': 800,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 32,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTMA_IXXqLXbDaKJStkocE79DhiNy3h1wNfyg&usqp=CAU',\n 'related_content_id': 'X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n 'source': 'From My Bowl',\n 'title': 'Vegan Pad Thai - From My Bowl',\n 'link': 'https://frommybowl.com/vegan-pad-thai/',\n 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-23.jpg',\n 'original_width': 1000,\n 'original_height': 1500,\n 'is_product': False},\n {'position': 33,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUQbieaco9iYa16jcjeZbf-gmoP7gSvJyl0Q&usqp=CAU',\n 'related_content_id': 'd1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n 'source': 'BBC',\n 'title': 'Vegetable pad Thai recipe - BBC Food',\n 'link': 'https://www.bbc.co.uk/food/recipes/stirfryvegetarianpha_70987',\n 'tag': 'Recipe',\n 'original': 'https://ichef.bbci.co.uk/food/ic/food_16x9_832/recipes/stirfryvegetarianpha_70987_16x9.jpg',\n 'original_width': 832,\n 'original_height': 468,\n 'is_product': True},\n {'position': 34,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT1WQnyJsXAny3gepgi_275uhe3V8VkQTMRtw&usqp=CAU',\n 'related_content_id': 'U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n 'source': 'Cilantro and Citronella',\n 'title': 'Vegetarian Pad Thai',\n 'link': 'https://www.cilantroandcitronella.com/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.cilantroandcitronella.com/wp-content/uploads/2015/03/pad-thai_1_04.jpg',\n 'original_width': 680,\n 'original_height': 1020,\n 'is_product': True},\n {'position': 35,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT9yCD2ZFN3V0txxVJK59VZKQw8dHdf52U_9w&usqp=CAU',\n 'related_content_id': 'ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n 'source': 'Eat With Clarity',\n 'title': 'Best Vegan Pad Thai (Easy!) - Eat With Clarity',\n 'link': 'https://eatwithclarity.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://eatwithclarity.com/wp-content/uploads/2020/06/vegan-pad-thai-9.jpg',\n 'original_width': 1190,\n 'original_height': 1800,\n 'is_product': True},\n {'position': 36,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-b-oobMM5KXLy32E-dTEmszExv0RTVq8OQQ&usqp=CAU',\n 'related_content_id': 'VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n 'source': 'Tesco Real Food',\n 'title': 'Vegetarian pad Thai | Tesco Real Food',\n 'link': 'https://realfood.tesco.com/recipes/vegetarian-pad-thai.html',\n 'tag': 'Recipe',\n 'original': 'https://realfood.tesco.com/media/images/Veg-Pad-Thai-LGH-069d45e9-fd6c-44d1-b747-83dbac2d921d-0-1400x919.jpg',\n 'original_width': 1400,\n 'original_height': 919,\n 'is_product': True},\n {'position': 37,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtwz03hn90q7ot7m4-179UzOn7cQYaLBHrnA&usqp=CAU',\n 'related_content_id': 'aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n 'source': 'Klaraslife',\n 'title': 'Vegan Pad Thai with cashew butter & broccoli - Klara`s Life',\n 'link': 'https://klaraslife.com/en/vegan-pad-thai-with-cashew-butter-broccoli/',\n 'tag': 'Recipe',\n 'original': 'https://klaraslife.com/wp-content/uploads/2019/11/IMG_0935.jpg',\n 'original_width': 4000,\n 'original_height': 5895,\n 'is_product': True},\n {'position': 38,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQDKEP2qkfB6nWHtF58pTBj7TJv2Jz63JYOw&usqp=CAU',\n 'related_content_id': 'Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n 'source': 'Fit Foodie Nutter',\n 'title': '30 MINUTE EASY VEGAN PAD THAI –',\n 'link': 'https://fitfoodienutter.com/recipe/30-minute-easy-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://fitfoodienutter.com/wp-content/uploads/2021/09/Vegan-Pad-Thai-12.jpg',\n 'original_width': 870,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 39,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIadiylajWRN_JnkLntJZSunU8qi7S1wxGvQ&usqp=CAU',\n 'related_content_id': 'SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n 'source': 'Gimme Some Oven',\n 'title': 'Pad Thai - Gimme Some Oven',\n 'link': 'https://www.gimmesomeoven.com/pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.gimmesomeoven.com/wp-content/uploads/2019/01/Pad-Thai-Recipe-1.jpg',\n 'original_width': 1392,\n 'original_height': 2088,\n 'is_product': True},\n {'position': 40,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIpRVuMoifY2CKjWhZ_37sDaI5hp1tAw5T1Q&usqp=CAU',\n 'related_content_id': 'SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n 'source': 'The Kitchen Abroad',\n 'title': 'Quick One Pan Vegan Pad Thai Recipe with Tofu',\n 'link': 'https://www.thekitchenabroad.com/one-pan-vegan-pad-thai-recipe-with-tofu/',\n 'tag': 'Recipe',\n 'original': 'https://www.thekitchenabroad.com/wp-content/uploads/2020/06/Vegan-Pad-Thai-Recipe-with-Tofu-10.jpg',\n 'original_width': 1024,\n 'original_height': 1365,\n 'is_product': True},\n {'position': 41,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTkI3AiNwZau82RGak_znF-NEWDMatcRdQ_2Q&usqp=CAU',\n 'related_content_id': 'SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n 'source': 'Food Network',\n 'title': 'Quick Veggie Pad Thai Recipe | Ree Drummond | Food Network',\n 'link': 'https://www.foodnetwork.com/recipes/ree-drummond/quick-veggie-pad-thai-9422028',\n 'tag': 'Recipe',\n 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2020/09/25/WU2503__vegetable-pad-thai_s4x3.jpg.rend.hgtvcom.616.462.suffix/1601058180561.jpeg',\n 'original_width': 616,\n 'original_height': 462,\n 'is_product': True},\n {'position': 42,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRJRZhgKxI1FzkCO0zB3RxLW1vAsi4WwL0Y7w&usqp=CAU',\n 'related_content_id': 'aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n 'source': 'Delish Knowledge',\n 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles5-copy-1.jpg',\n 'original_width': 1000,\n 'original_height': 1000,\n 'is_product': True},\n {'position': 43,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSGA5db-ShQpar2dyZk0cAxA4-cdHYsisG3g&usqp=CAU',\n 'related_content_id': 'Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n 'source': 'Six Hungry Feet',\n 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-10.jpg',\n 'original_width': 1200,\n 'original_height': 1500,\n 'is_product': False},\n {'position': 44,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQolfY7XMQv1Q3zJr8XCj0pasBRTBn7MrJocA&usqp=CAU',\n 'related_content_id': 'Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n 'source': 'White On Rice Couple',\n 'title': 'Vegetable Pad Thai Recipe w/ Cabbage EASY HEALTHY | White On Rice',\n 'link': 'https://whiteonricecouple.com/cabbage-vegetable-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://whiteonricecouple.com/recipe/images/Cabbage-Vegetable-Pad-Thai-1.jpg',\n 'original_width': 530,\n 'original_height': 699,\n 'is_product': True},\n {'position': 45,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSium1YAIBcY-ty66CcxIZfjPydnxVlddWGwQ&usqp=CAU',\n 'related_content_id': 'VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'source': 'Minimalist Baker',\n 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-14.jpg',\n 'original_width': 1456,\n 'original_height': 2184,\n 'is_product': False},\n {'position': 46,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_1bo3u0kxqiO87hkxwyR5bhvZtWff-OdRRA&usqp=CAU',\n 'related_content_id': 'dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n 'source': 'Make It Dairy Free',\n 'title': 'Vegan Pad Thai - Make It Dairy Free',\n 'link': 'https://makeitdairyfree.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://makeitdairyfree.com/wp-content/uploads/2022/12/vegan-pad-thai-2.jpg',\n 'original_width': 736,\n 'original_height': 1104,\n 'is_product': True},\n {'position': 47,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSW5-PJKenKvHTGKrhmzwyhhFUlvEkg25eRuQ&usqp=CAU',\n 'related_content_id': 'WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n 'source': 'Bianca Zapatka',\n 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/vegan-pad-thai-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-asian-food.jpg',\n 'original_width': 1440,\n 'original_height': 2016,\n 'is_product': True},\n {'position': 48,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRiWrdDbuV_CM0exB7yBqyoCOWaYqD6nTtJQ&usqp=CAU',\n 'related_content_id': 'T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n 'source': 'Running on Real Food',\n 'title': 'Easy Vegan Tofu Pad Thai Recipe - Running on Real Food',\n 'link': 'https://runningonrealfood.com/tofu-pad-thai/',\n 'original': 'https://runningonrealfood.com/wp-content/uploads/2021/05/Best-Vegan-Tofu-Pad-Thai-Recipe-12.jpg',\n 'original_width': 1400,\n 'original_height': 2100,\n 'is_product': False},\n {'position': 49,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtOw74y8VyL5dib33Rkr_Bu4Jo9K4Q3sJy1w&usqp=CAU',\n 'related_content_id': 'Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n 'source': 'Simply Recipes',\n 'title': 'Vegetarian Pad Thai Recipe',\n 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n 'tag': 'Recipe',\n 'original': 'https://www.simplyrecipes.com/thmb/zH71oEuQnxw3B8536gZDM2_NkWI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-3-f47ff2bc806b4de9821e332a6126bcc1.jpg',\n 'original_width': 1500,\n 'original_height': 2250,\n 'is_product': True},\n {'position': 50,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCaY87F2KeBqK2WQUNljTakrtO7Zlae5L4g&usqp=CAU',\n 'related_content_id': 'M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n 'source': 'Whitney Bond',\n 'title': 'Vegetable Pad Thai Recipe - WhitneyBond.com',\n 'link': 'https://whitneybond.com/whats-for-dinner-spicy-vegetable-pad-thai/',\n 'original': 'https://whitneybond.com/wp-content/uploads/2013/01/Vegetable-Pad-Thai-4.jpg',\n 'original_width': 1140,\n 'original_height': 1280,\n 'is_product': False},\n {'position': 51,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSDWkQoMHapJVpYkNaQJbPyubSBwdP5is9eaw&usqp=CAU',\n 'related_content_id': 'eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n 'source': 'Six Hungry Feet',\n 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n 'tag': 'Recipe',\n 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-3.jpg',\n 'original_width': 1200,\n 'original_height': 1500,\n 'is_product': True},\n {'position': 52,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQxAM2SH_lgbsUJZh0aljTp6OEQ0lNfSd2_BQ&usqp=CAU',\n 'related_content_id': 'cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n 'source': \"Mom's Dinner\",\n 'title': \"The Best Vegetable Pad Thai - Mom's Dinner\",\n 'link': 'https://momsdinner.net/vegetable-pad-thai/',\n 'original': 'https://momsdinner.net/wp-content/uploads/2021/04/Vegetable-Pad-Thai-Recipe-3.jpg',\n 'original_width': 1200,\n 'original_height': 1680,\n 'is_product': False},\n {'position': 53,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwMUvtpa5kSIoAJ3kltgwtiuUYkvK9DJyg3w&usqp=CAU',\n 'related_content_id': 'NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n 'source': 'From The Comfort Of My Bowl',\n 'title': 'Easy Vegan Pad Thai - From The Comfort Of My Bowl',\n 'link': 'https://www.fromthecomfortofmybowl.com/vegan-pad-thai-recipe/',\n 'tag': 'Recipe',\n 'original': 'https://www.fromthecomfortofmybowl.com/wp-content/uploads/2021/03/best-vegan-pad-thai.jpg',\n 'original_width': 600,\n 'original_height': 900,\n 'is_product': True},\n {'position': 54,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPqWPCZyN1t4YbQNSYBWPLWSwzenu1C7a52A&usqp=CAU',\n 'related_content_id': 'ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n 'source': 'Nora Cooks',\n 'title': 'Vegan Pad Thai - Nora Cooks',\n 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-5.jpg',\n 'original_width': 1334,\n 'original_height': 2001,\n 'is_product': False},\n {'position': 55,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREUFAdGtWRgMx9Qv45bdNbkRdlZnSFQZX7tQ&usqp=CAU',\n 'related_content_id': 'bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n 'source': 'Vegan Heaven',\n 'title': 'Vegan Pad Thai - Vegan Heaven',\n 'link': 'https://veganheaven.org/recipe/vegan-pad-thai/',\n 'original': 'https://veganheaven.org/wp-content/uploads/2019/04/Vegan-Pad-Thai_.jpg',\n 'original_width': 680,\n 'original_height': 900,\n 'is_product': False},\n {'position': 56,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQW5Nh8vx1J5kcDtF7MZSnXljnKoalv8wq2RA&usqp=CAU',\n 'related_content_id': 'cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n 'source': 'Pinch of Yum',\n 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-1-2.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 57,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRUtq_lbZ4d5Xfs2jW-qamRXEi-0T6rhsLjTg&usqp=CAU',\n 'related_content_id': 'bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n 'source': 'The Petite Cook',\n 'title': 'The Easiest Vegan Pad Thai - The Petite Cook™',\n 'link': 'https://www.thepetitecook.com/the-easiest-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.thepetitecook.com/wp-content/uploads/2017/03/vegan-pad-thai-recipe.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 58,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4uozc69jm3VWqxSKMG8hWocGvUtO4CXHPeA&usqp=CAU',\n 'related_content_id': 'cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n 'source': 'Food with Feeling',\n 'title': 'Vegan Pad Thai - Food with Feeling',\n 'link': 'https://foodwithfeeling.com/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://foodwithfeeling.com/wp-content/uploads/2021/02/Vegan-Pad-Thai-7.jpg',\n 'original_width': 700,\n 'original_height': 1050,\n 'is_product': True},\n {'position': 59,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcShtayJD_o-2NYDRaFdO7kc0IBDFrXsaLRAmw&usqp=CAU',\n 'related_content_id': 'VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n 'source': 'HealthyGirl Kitchen',\n 'title': 'Vegan Pad Thai (easy!) - HealthyGirl Kitchen',\n 'link': 'https://healthygirlkitchen.com/recipes/authentic-vegan-pad-thai/',\n 'original': 'https://healthygirlkitchen.com/wp-content/uploads/2020/11/20201112-DSC_6273-2.jpeg',\n 'original_width': 2500,\n 'original_height': 1669,\n 'is_product': False},\n {'position': 60,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFnQxVF9fa3yOIanaxEOhaThezpWFnL4LdKw&usqp=CAU',\n 'related_content_id': 'Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n 'source': 'PETA',\n 'title': 'Easy Vegan Pad Thai | PETA',\n 'link': 'https://www.peta.org/recipes/easy-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.peta.org/wp-content/uploads/2014/03/vegan-pad-thai-e1429117378854-602x452-1444238253.jpg',\n 'original_width': 602,\n 'original_height': 452,\n 'is_product': True},\n {'position': 61,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJ2bEV_hnyoEftoYQQ2ivw6GAWsG3zvHcH2A&usqp=CAU',\n 'related_content_id': 'NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n 'source': 'Ministry of Curry',\n 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n 'tag': 'Video',\n 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-2.jpg',\n 'original_width': 1024,\n 'original_height': 1536,\n 'is_product': True},\n {'position': 62,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0nCQUNnm-ZcLUpjYC487WehnBzJaNNAlVsA&usqp=CAU',\n 'related_content_id': 'cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n 'source': 'Crowded Kitchen',\n 'title': 'Vegan Pad Thai with Tofu - Crowded Kitchen',\n 'link': 'https://www.crowdedkitchen.com/vegan-pad-thai/',\n 'original': 'https://www.crowdedkitchen.com/wp-content/uploads/2021/01/pad-thai-new-8.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 63,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT96UeZ4BgEN0Q2Xp0fwWYr8KuHmgbo64Lukw&usqp=CAU',\n 'related_content_id': 'dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n 'source': 'Healing Tomato',\n 'title': 'Pad Thai Recipe (Vegan) - HealingTomato.com',\n 'link': 'https://www.healingtomato.com/pad-thai-recipe/',\n 'tag': 'Recipe',\n 'original': 'https://www.healingtomato.com/wp-content/uploads/2016/01/pad-thai.jpg',\n 'original_width': 600,\n 'original_height': 593,\n 'is_product': True},\n {'position': 64,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQs0sHzHet343DWkhIN84nY2KeHE-mAR3zFTA&usqp=CAU',\n 'related_content_id': 'QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n 'source': 'Detoxinista',\n 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n 'link': 'https://detoxinista.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai.jpg',\n 'original_width': 1200,\n 'original_height': 1627,\n 'is_product': True},\n {'position': 65,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHQuNuSPWyl4_RjkFeElvxvkLOtuWWqW6GAQ&usqp=CAU',\n 'related_content_id': 'emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n 'source': 'Loving It Vegan',\n 'title': 'Vegan Pad Thai - Loving It Vegan',\n 'link': 'https://lovingitvegan.com/vegan-pad-thai/',\n 'original': 'https://lovingitvegan.com/wp-content/uploads/2022/06/Vegan-Pad-Thai-22.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 66,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjWUg8dInH0c5rR8rRXl8EMKCxg1ccEhUekQ&usqp=CAU',\n 'related_content_id': 'RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n 'source': 'Hot For Food',\n 'title': 'vegan pad thai - hot for food by Lauren Toyota',\n 'link': 'https://www.hotforfoodblog.com/recipes/2015/02/02/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.hotforfoodblog.com/wp-content/uploads/2015/02/veganpadthai_hotforfoodblog_filtered1-500x375.jpg',\n 'original_width': 500,\n 'original_height': 375,\n 'is_product': True},\n {'position': 67,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSur4LsaevwvR_0eZ2F3Tf-YVx6-jDRus6E-w&usqp=CAU',\n 'related_content_id': 'TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n 'source': 'Vegan Recipes from Cassie Howard',\n 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai-Vegan.jpg',\n 'original_width': 600,\n 'original_height': 399,\n 'is_product': True},\n {'position': 68,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRTcDJm39S6nz4sTyLF-l6j6CeiVTVkPOXQ5g&usqp=CAU',\n 'related_content_id': 'WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n 'source': 'Gluten-Free, Allergy-Free, and Vegan Recipes',\n 'title': 'Easy Vegan Pad Thai (Gluten-Free, Allergy-Free, Nut-Free, Soy-Free)',\n 'link': 'https://strengthandsunshine.com/vegan-pad-thai-gluten-free/',\n 'original': 'https://strengthandsunshine.com/wp-content/uploads/2019/05/Easy-Vegan-Pad-Thai-Gluten-Free-Allergy-Free-PM1.jpg',\n 'original_width': 735,\n 'original_height': 1102,\n 'is_product': False},\n {'position': 69,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQru1It4T3WzwaedAbLeetEsVNE6DkIrC4L4w&usqp=CAU',\n 'related_content_id': 'dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n 'source': \"Archana's Kitchen\",\n 'title': \"Vegetarian Pad Thai Recipe by Archana's Kitchen\",\n 'link': 'https://www.archanaskitchen.com/vegetarian-pad-thai',\n 'original': 'https://www.archanaskitchen.com/images/archanaskitchen/0-Archanas-Kitchen-Recipes/2018/Vegetarian_Pad_Thai_Recipe-4-2.jpg',\n 'original_width': 1600,\n 'original_height': 1200,\n 'is_product': False},\n {'position': 70,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSTdgEdXp-bEPIX-4ssadcX6rzD4KQxGE5w&usqp=CAU',\n 'related_content_id': 'ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n 'source': 'Pinch of Yum',\n 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-6.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 71,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTyPzitaptGw98mR0Oqbxxc2B8FtDlN7vpDDw&usqp=CAU',\n 'related_content_id': 'RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n 'source': 'Fooby',\n 'title': 'Vegan Pad Thai - Recipes | fooby.ch',\n 'link': 'https://fooby.ch/en/recipes/17187/vegan-pad-thai',\n 'tag': 'Recipe',\n 'original': 'https://recipecontent.fooby.ch/17187_3-2_480-320.jpg',\n 'original_width': 480,\n 'original_height': 321,\n 'is_product': True},\n {'position': 72,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9woGokoujYfjUge4wgpyswfCjstd_9uf1qw&usqp=CAU',\n 'related_content_id': 'XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n 'source': 'Nora Cooks',\n 'title': 'Vegan Pad Thai - Nora Cooks',\n 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-7.jpg',\n 'original_width': 1334,\n 'original_height': 2001,\n 'is_product': False},\n {'position': 73,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSexYRHt5Ul2JMDLnWUdBxc6ELsg2E1iDL31w&usqp=CAU',\n 'related_content_id': 'ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n 'source': \"Del's cooking twist\",\n 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3702.jpg',\n 'original_width': 1200,\n 'original_height': 822,\n 'is_product': False},\n {'position': 74,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnQTyIRwdSk4FpeGIc-MQnw9411wG2ENeCIg&usqp=CAU',\n 'related_content_id': 'TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n 'source': 'Minimalist Baker',\n 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-13.jpg',\n 'original_width': 1456,\n 'original_height': 2184,\n 'is_product': False},\n {'position': 75,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREuE_KU8at0L9CjOGH_t4b-8Up9fL1WBIsUg&usqp=CAU',\n 'related_content_id': 'RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n 'source': 'Tasty',\n 'title': 'Vegan Pad Thai Recipe by Tasty',\n 'link': 'https://tasty.co/recipe/vegan-pad-thai',\n 'tag': 'Recipe',\n 'original': 'https://img.buzzfeed.com/thumbnailer-prod-us-east-1/video-api/assets/148610.jpg?resize=1200:*',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 76,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRqsk8XwnF_PLPcNqIatUj46HUH78xjZGBA5g&usqp=CAU',\n 'related_content_id': 'X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n 'source': 'Brand New Vegan',\n 'title': 'Easy Vegan Pad Thai - Brand New Vegan',\n 'link': 'https://www.brandnewvegan.com/recipes/easy-vegan-pad-thai',\n 'original': 'https://www.brandnewvegan.com/wp-content/uploads/easy-vegan-pad-thai-h1-1024x682.jpg',\n 'original_width': 1024,\n 'original_height': 682,\n 'is_product': False},\n {'position': 77,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTjlYvkOX8aA0iNS-32KeueAcXbjYMIcRkfnQ&usqp=CAU',\n 'related_content_id': 'TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n 'source': \"Kathy's Vegan Kitchen\",\n 'title': \"Vegan Pad Thai Recipe | Kathy's Vegan Kitchen\",\n 'link': 'https://www.kathysvegankitchen.com/vegan-pad-thai-recipe/',\n 'tag': 'Recipe',\n 'original': 'https://www.kathysvegankitchen.com/wp-content/uploads/2021/09/Pad-Thai-.jpg',\n 'original_width': 1200,\n 'original_height': 1277,\n 'is_product': True},\n {'position': 78,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEcvBpOj0RPCU23uRqHp6VJJrxfS3tQYnURw&usqp=CAU',\n 'related_content_id': 'SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n 'source': 'Real Thai Recipes',\n 'title': 'Vegetarian Pad Thai » Real Thai Recipes » Authentic Thai recipes from Thailand',\n 'link': 'https://www.realthairecipes.com/recipes/vegetarian-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.realthairecipes.com/wp-content/uploads/vegetarian-pad-thai1.jpg',\n 'original_width': 440,\n 'original_height': 261,\n 'is_product': True},\n {'position': 79,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJulkx7A2HLYWmkLlETfrNWofaQ6XllHyzeg&usqp=CAU',\n 'related_content_id': 'ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n 'source': 'Choosing Chia',\n 'title': 'Raw Pad Thai - Choosing Chia',\n 'link': 'https://choosingchia.com/raw-vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://choosingchia.com/jessh-jessh/uploads/2021/06/raw-pad-thai-4.jpg',\n 'original_width': 1360,\n 'original_height': 2040,\n 'is_product': True},\n {'position': 80,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRf0Cju8qWUiOS3tuTGbs7-pXIIdVRzRLVJcQ&usqp=CAU',\n 'related_content_id': 'TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n 'source': \"Cook's Hideout\",\n 'title': \"Vegan Pad Thai Noodles | Cook's Hideout\",\n 'link': 'https://www.cookshideout.com/pad-thai-vegan-recipe',\n 'tag': '0:51',\n 'original': 'https://www.cookshideout.com/wp-content/uploads/2014/03/Vegan-Pad-Thai_4S.jpg',\n 'original_width': 1200,\n 'original_height': 1807,\n 'is_product': True},\n {'position': 81,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq0f_iTXyVwmnFhPzttm7_lJp8ajUCmufkNQ&usqp=CAU',\n 'related_content_id': 'SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n 'source': \"Chang's\",\n 'title': \"Rainbow Vegetarian Pad Thai with Crispy Noodles - Chang's Authentic Asian Cooking\",\n 'link': 'https://www.changs.com/recipes/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles/',\n 'original': 'https://ik.imagekit.io/webtactics/changs/tr:w-750,h-1000/cgblog/id298/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles.jpg',\n 'original_width': 750,\n 'original_height': 1000,\n 'is_product': False},\n {'position': 82,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNxrIDPiE9qq8FTzKays6PAe4vKBNCSql2dw&usqp=CAU',\n 'related_content_id': 'VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n 'source': 'Connoisseurus Veg',\n 'title': 'Vegan Pad Thai - Connoisseurus Veg',\n 'link': 'https://www.connoisseurusveg.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.connoisseurusveg.com/wp-content/uploads/2021/04/vegan-pad-thai-r-8-of-10.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': True},\n {'position': 83,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdkOE8fHkjIYt-VHnxHhCKT1Q4Ccu__Id64Q&usqp=CAU',\n 'related_content_id': 'R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n 'source': \"Madhu's Everyday Indian\",\n 'title': \"Easy Vegan Pad Thai Recipe - Madhu's Everyday Indian\",\n 'link': 'https://www.madhuseverydayindian.com/vegan-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://www.madhuseverydayindian.com/wp-content/uploads/2019/11/pad-thai-3.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': True},\n {'position': 84,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRAqAWfnCA_xgZ33xmKJYH-GElMv8BR9SfEg&usqp=CAU',\n 'related_content_id': 'YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n 'source': 'Simply Recipes',\n 'title': 'Vegetarian Pad Thai Recipe',\n 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n 'tag': 'Recipe',\n 'original': 'https://www.simplyrecipes.com/thmb/sNXRcU7H5YlFa9nto8PzROCcK6E=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-7-f2309902236d45f38dd937e894d7a95f.jpg',\n 'original_width': 1500,\n 'original_height': 1000,\n 'is_product': True},\n {'position': 85,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvt5v5lIPiITlJSSh6yiG-k8NDEdEaAvrUZg&usqp=CAU',\n 'related_content_id': 'M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n 'source': 'Ve Eat Cook Bake',\n 'title': 'Vegan Tofu Pad Thai Recipe (easy, oil free) - Ve Eat Cook Bake',\n 'link': 'https://veeatcookbake.com/vegan-pad-thai-sauce/',\n 'tag': 'Recipe',\n 'original': 'https://veeatcookbake.com/wp-content/uploads/2020/01/vegan-tofu-pad-thai-3.jpg',\n 'original_width': 720,\n 'original_height': 1080,\n 'is_product': True},\n {'position': 86,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmmjnFxGBdd4XrLb3_NV9S6DqDsrm8gCArrQ&usqp=CAU',\n 'related_content_id': 'd3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n 'source': 'Pinterest',\n 'title': 'Easy Vegan Pad Thai Recipe w/ Sauce - Choosing Chia | Recipe | Easy asian noodle recipes, Vegan pad thai, Easy asian noodles',\n 'link': 'https://www.pinterest.com/pin/easy-vegan-pad-thai-recipe-w-sauce-choosing-chia--495044184044777788/',\n 'tag': 'Recipe',\n 'original': 'https://i.pinimg.com/736x/20/05/d9/2005d9d549ea0aa25d2823c4bd47de66.jpg',\n 'original_width': 735,\n 'original_height': 1102,\n 'is_product': True},\n {'position': 87,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-brimcB4Yy8KjKGPRL_XwmcMsukorzxhh7w&usqp=CAU',\n 'related_content_id': 'bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n 'source': 'Spice Cravings',\n 'title': 'Vegan Pad Thai | Spice Cravings',\n 'link': 'https://spicecravings.com/vegan-pad-thai',\n 'tag': 'Recipe',\n 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-Featured.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 88,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmLLjuIxWgB0eAVv4CpMkufWKkwP0OLh95rw&usqp=CAU',\n 'related_content_id': 'QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n 'source': 'Delish Knowledge',\n 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles2.jpeg',\n 'original_width': 981,\n 'original_height': 1471,\n 'is_product': False},\n {'position': 89,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQBFHo9kgwduVWWgXYbjwx8oHmzkRq4eFx_w&usqp=CAU',\n 'related_content_id': 'eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n 'source': 'Nifty Recipes',\n 'title': 'Easy Vegan Pad Thai from Tasty - recipe on Niftyrecipe.com',\n 'link': 'https://niftyrecipe.com/video/1616/easy-vegan-pad-thai',\n 'original': 'https://niftyrecipe.com/uploads/youtube/parse/gVXDvCI32N8.jpg',\n 'original_width': 640,\n 'original_height': 480,\n 'is_product': False},\n {'position': 90,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQDNoodvmhaxXBanZUWokpcjFLd1lBmPi6N9g&usqp=CAU',\n 'related_content_id': 'UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n 'source': 'Detoxinista',\n 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n 'link': 'https://detoxinista.com/vegan-pad-thai/',\n 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai-recipe.jpg',\n 'original_width': 1200,\n 'original_height': 1513,\n 'is_product': False},\n {'position': 91,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTVHfWG0FG8Dlr4vAkRFB2CJEN1EUPWqp5dWQ&usqp=CAU',\n 'related_content_id': 'S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n 'source': 'Mom Always Finds Out',\n 'title': 'Recipe} Vegetarian Pad Thai in Less than 15 Minutes - Mom Always Finds Out',\n 'link': 'https://www.momalwaysfindsout.com/quick-pad-thai-recipe/',\n 'original': 'http://momalwaysfindsout.com/wp-content/uploads/2013/08/easy-vegetarian-pad-thai-recipe.jpg',\n 'original_width': 526,\n 'original_height': 416,\n 'is_product': False},\n {'position': 92,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRhwBcrNUbTx9kzPKfcmWE0Ra7gapkAfRrcfw&usqp=CAU',\n 'related_content_id': 'YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n 'source': 'Nutriciously',\n 'title': 'Colorful Raw Vegan Pad Thai Salad – Nutriciously',\n 'link': 'https://nutriciously.com/raw-vegan-pad-thai-recipe/',\n 'tag': 'Recipe',\n 'original': 'https://nutriciously.com/wp-content/uploads/Raw-Vegan-Pad-Thai-by-Nutriciously-3-735x1102.jpg',\n 'original_width': 735,\n 'original_height': 1102,\n 'is_product': True},\n {'position': 93,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTE247S-7oA7iBXdWKaWSVW76NBNMj9G1zMMA&usqp=CAU',\n 'related_content_id': 'YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n 'source': 'Jessica in the Kitchen',\n 'title': 'Easy Vegan Pad Thai | Jessica in the Kitchen',\n 'link': 'https://jessicainthekitchen.com/vegan-pad-thai/',\n 'original': 'https://jessicainthekitchen.com/wp-content/uploads/2022/08/Vegan-Pad-Thai0046.jpg',\n 'original_width': 1200,\n 'original_height': 1800,\n 'is_product': False},\n {'position': 94,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEICg4TzsYnpMi-FDoDIIiTxIEYlkJotNZJw&usqp=CAU',\n 'related_content_id': 'Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n 'source': 'Feasting At Home',\n 'title': 'Pad Thai (Video!) | Feasting at Home',\n 'link': 'https://www.feastingathome.com/15-minute-pad-thai/',\n 'original': 'https://www.feastingathome.com/wp-content/uploads/2016/04/easy-authentic-pad-thai-recipe-100-8.jpg',\n 'original_width': 750,\n 'original_height': 1125,\n 'is_product': False},\n {'position': 95,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRaL2_fWqKRkIvDq4dn5kZqexIjDD5rIpb-Q&usqp=CAU',\n 'related_content_id': 'aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n 'source': 'a Veg Taste from A to Z',\n 'title': 'Vegan Pad Thai with Cashews -',\n 'link': 'https://avegtastefromatoz.com/vegan-pad-thai-cashews/',\n 'tag': 'Recipe',\n 'original': 'https://avegtastefromatoz.com/wp-content/uploads/2020/09/pad-thai-5.jpg',\n 'original_width': 2048,\n 'original_height': 2048,\n 'is_product': True},\n {'position': 96,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSQmbOr5bqa0rC0nX95VxH-6RasxkuymwUMg&usqp=CAU',\n 'related_content_id': 'Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n 'source': 'Plant-Based on a Budget',\n 'title': 'Vegan Vegetable Pad Thai - Plant-Based on a Budget',\n 'link': 'https://plantbasedonabudget.com/avocado-basil-pad-thai/',\n 'tag': 'Recipe',\n 'original': 'https://plantbasedonabudget.com/wp-content/uploads/2014/05/Vegan-Avocado-Basil-Pad-Thai-Plant-Based-on-a-Budget-1-2.jpg',\n 'original_width': 1200,\n 'original_height': 1200,\n 'is_product': True},\n {'position': 97,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQOF76mQo9LZPzWv_vzVAz-od1L271ioKWNVA&usqp=CAU',\n 'related_content_id': 'Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n 'source': 'Full of Plants',\n 'title': 'The Best Vegan Pad Thai - Full of Plants',\n 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n 'original': 'https://fullofplants.com/wp-content/uploads/2022/02/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-10-1400x2100.jpg',\n 'original_width': 1400,\n 'original_height': 2100,\n 'is_product': False},\n {'position': 98,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-8yozAbc9Gpm97m_vt6sgcJ3mpTliabYGMQ&usqp=CAU',\n 'related_content_id': 'bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n 'source': \"It's All Good Vegan\",\n 'title': \"Creamy Pad Thai Noodles - It's All Good Vegan\",\n 'link': 'https://itsallgoodvegan.com/2020/02/19/creamy-pad-thai-noodles/',\n 'tag': 'Recipe',\n 'original': 'https://itsallgoodvegan.com/wp-content/uploads/2020/02/img_2841.jpg',\n 'original_width': 1638,\n 'original_height': 2048,\n 'is_product': True},\n {'position': 99,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa2HSMw-ypurNqm48DPPpuKZOFbmDO65klnA&usqp=CAU',\n 'related_content_id': 'Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n 'source': 'Veggiekins',\n 'title': 'Vegan Pad Thai with Tofu (gluten free) (Gluten-Free) - Veggiekins Blog',\n 'link': 'https://veggiekinsblog.com/2021/03/24/vegan-pad-thai-with-tofu/',\n 'tag': 'Recipe',\n 'original': 'https://veggiekinsblog.com/wp-content/uploads/2021/03/Vegan-Pad-Thai-with-Tofu-4-scaled.jpg',\n 'original_width': 1708,\n 'original_height': 2560,\n 'is_product': True},\n {'position': 100,\n 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEZmnz4duD3odLwVNqQ_OfHJ1zPNaofthtXw&usqp=CAU',\n 'related_content_id': 'Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n 'source': 'Zucker&Jagdwurst',\n 'title': 'Vegan Pad Thai with “chicken“ - Zucker&Jagdwurst',\n 'link': 'https://www.zuckerjagdwurst.com/en/recipes/vegan-pad-thai-with-chicken',\n 'tag': 'Recipe',\n 'original': 'https://assets.zuckerjagdwurst.com/q9pjl6288ajpcx8s994gccncy1i1/1110/740/65/true/center/R435+Veganes+Pad+Thai+mit+%E2%80%9EHu%CC%88hnchen%E2%80%9C39.jpg?animated=false',\n 'original_width': 1110,\n 'original_height': 740,\n 'is_product': True}]}\n\n\n\nfor r in results[\"images_results\"][0:10]:\n display(r[\"title\"], Image(url=r[\"thumbnail\"]))\n\n'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'\n\n\n\n\n\n'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum'\n\n\n\n\n\n'Healthier vegan pad thai - Lazy Cat Kitchen'\n\n\n\n\n\n'The Best Vegan Pad Thai - Full of Plants'\n\n\n\n\n\n'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria'\n\n\n\n\n\n'Easy Vegan Pad Thai - My Darling Vegan'\n\n\n\n\n\n'Easy Vegetarian Pad Thai - Pinch Me Good'\n\n\n\n\n\n'30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs'\n\n\n\n\n\n'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry'\n\n\n\n\n\n'Vegan pad thai - Lazy Cat Kitchen'\n\n\n\n\n\n\n# You can create the tool to pass to an agent\nserpapi_recipe_tool = Tool(\n name=\"\",\n description=\"A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\",\n func=search.run,\n)\n\nThis doc should be corrected LangChain serpapi doc could be updated\n\nsearch = GoogleSerperAPIWrapper(type=\"search\")\nresults = search.results(\"Lion\")\n\nedamam" + }, + { + "objectID": "edamam_api.html", + "href": "edamam_api.html", + "title": "edamam_api", + "section": "", + "text": "source\n\nfoo\n\n foo ()" + }, + { + "objectID": "engineer_prompt.html", + "href": "engineer_prompt.html", + "title": "engineer_prompt", + "section": "", + "text": "Setup env\n\nfrom dotenv import load_dotenv\n\n\nload_dotenv()\n\nTrue\n\n\nEvaluate chat backend\n\nchat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\nmemory = ConversationBufferMemory(return_messages=True)\nchat_msgs = init_prompt.format_prompt(\n ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n allergies=\"\",\n recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n)\n\nchat_msgs = chat_msgs.to_messages()\nresults = chat.generate([chat_msgs])\nchat_msgs.extend(\n [\n results.generations[0][0].message,\n MessagesPlaceholder(variable_name=\"history\"),\n HumanMessagePromptTemplate.from_template(\"{input}\"),\n ]\n)\nopen_prompt = ChatPromptTemplate.from_messages(chat_msgs)\nconversation = ConversationChain(\n llm=chat, verbose=True, memory=memory, prompt=open_prompt\n)\n\nresult = conversation.predict(input=\"Recommend a different recipe please.\")\nprint(result)\n\nAnthropic module not found. Install with `pip install anthropic`.\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\nWARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n\n\n\n\n> Entering new ConversationChain chain...\nPrompt after formatting:\nSystem: The following is a conversation between a human and a friendly AI chef. \nThe AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n\nKnowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n\nLet's think step by step.\nIf the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\nAI: What ingredients do you wish to cook with?\nHuman: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\nAI: Do you have any allergies I should be aware of?\nHuman: Allergies: \nAI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\nHuman: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\nRespect the human's allergies (if any).\nFollow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n\n###\nPreferences: The preparation time should be less than 30 minutes. I really love Thai food!\n###\n\nOutput format:\n\n**Vegan recipe name**\nPreparation time (humanized)\n\nIngredients (List of ingredients with quantities):\n- <quantity and unit> <ingredient>\n\nSteps (detailed):\n1.\n2.\n3.\n...\nAI: Sure! How about a vegan Thai tofu lettuce wraps recipe? It should take less than 30 minutes to prepare.\n\n**Vegan Thai Tofu Lettuce Wraps**\nPreparation time: 25 minutes\n\nIngredients:\n- 1 package firm tofu\n- 1/4 cup vegan fish sauce (you can use soy sauce as a substitute)\n- 2 tablespoons maple syrup\n- 1 tablespoon lime juice\n- 1 teaspoon chili paste\n- 1 bell pepper, sliced\n- 2 carrots, julienned\n- 1/4 cup sliced pickles\n- 1/4 cup sliced olives\n- 6 large lettuce leaves\n- 1/4 cup chopped fresh cilantro\n\nSteps:\n1. Preheat a skillet over medium-high heat and add cubed tofu. Cook for about 5-7 minutes, flipping occasionally, until all the pieces are golden brown. Set aside.\n2. In a mixing bowl, whisk together the fish sauce (or soy sauce), maple syrup, lime juice, and chili paste until combined.\n3. In a large mixing bowl, add the bell pepper, carrots, pickles, olives, and cooked tofu. Pour the dressing over the ingredients, and toss until everything is evenly coated with the sauce.\n4. Assemble the lettuce wraps by separating the lettuce leaves and spooning the tofu mixture into each one. Top with fresh cilantro and serve immediately. Enjoy your delicious vegan Thai tofu lettuce wraps!\nHuman: Recommend a different recipe please.\n\n> Finished chain.\nOf course! How about a Mediterranean-inspired sandwich that includes tofu, olives, and tomatoes?\n\n**Mediterranean Tofu Sandwich**\nPreparation time: 20 minutes\n\nIngredients:\n- 1 package extra-firm tofu, drained and sliced into 1/2-inch slices\n- 2 tablespoons olive oil\n- 1 teaspoon dried oregano\n- Salt and pepper\n- 1/4 cup vegan mayo\n- 1 garlic clove, minced\n- 2 teaspoons lemon juice\n- 1 large tomato, sliced\n- 1/4 cup sliced kalamata olives\n- 1/4 cup chopped lettuce\n- 1/4 cup sliced pickles\n- Bread of your choice (I recommend ciabatta)\n\nSteps:\n1. Preheat a skillet over medium-high heat and add the olive oil.\n2. Season the tofu slices with oregano, salt, and pepper, then add them to the skillet. Cook for about 5-7 minutes on each side or until golden brown. Set aside.\n3. In a small bowl, mix the vegan mayo, minced garlic, and lemon juice. Spread the mixture onto the slices of bread.\n4. Layer the tomato slices, cooked tofu, olives, lettuce, and pickles onto the bread. Add salt and pepper to taste.\n5. Top with the other slice of bread, slice in half, and enjoy your delicious Mediterranean tofu sandwich!" + } +] \ No newline at end of file diff --git a/_proc/_docs/site_libs/bootstrap/bootstrap-icons.css b/_proc/_docs/site_libs/bootstrap/bootstrap-icons.css new file mode 100644 index 0000000000000000000000000000000000000000..94f1940448a6fa8d0a3dfca318638285c83a1f18 --- /dev/null +++ b/_proc/_docs/site_libs/bootstrap/bootstrap-icons.css @@ -0,0 +1,2018 @@ +@font-face { + font-display: block; + font-family: "bootstrap-icons"; + src: +url("./bootstrap-icons.woff?2ab2cbbe07fcebb53bdaa7313bb290f2") format("woff"); +} + +.bi::before, +[class^="bi-"]::before, +[class*=" bi-"]::before { + display: inline-block; + font-family: bootstrap-icons !important; + font-style: normal; + font-weight: normal !important; + font-variant: normal; + text-transform: none; + line-height: 1; + vertical-align: -.125em; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.bi-123::before { content: "\f67f"; } +.bi-alarm-fill::before { content: "\f101"; } +.bi-alarm::before { content: "\f102"; } +.bi-align-bottom::before { content: "\f103"; } +.bi-align-center::before { content: "\f104"; } +.bi-align-end::before { content: "\f105"; } +.bi-align-middle::before { content: "\f106"; } +.bi-align-start::before { content: "\f107"; } +.bi-align-top::before { content: "\f108"; } +.bi-alt::before { content: "\f109"; } +.bi-app-indicator::before { content: "\f10a"; } +.bi-app::before { content: "\f10b"; } +.bi-archive-fill::before { content: "\f10c"; } +.bi-archive::before { content: "\f10d"; } +.bi-arrow-90deg-down::before { content: "\f10e"; } +.bi-arrow-90deg-left::before { content: "\f10f"; } +.bi-arrow-90deg-right::before { content: "\f110"; } +.bi-arrow-90deg-up::before { content: "\f111"; } +.bi-arrow-bar-down::before { content: "\f112"; } +.bi-arrow-bar-left::before { content: "\f113"; } +.bi-arrow-bar-right::before { content: "\f114"; } +.bi-arrow-bar-up::before { content: "\f115"; } +.bi-arrow-clockwise::before { content: "\f116"; } +.bi-arrow-counterclockwise::before { content: "\f117"; } +.bi-arrow-down-circle-fill::before { content: "\f118"; } +.bi-arrow-down-circle::before { content: "\f119"; } +.bi-arrow-down-left-circle-fill::before { content: "\f11a"; } +.bi-arrow-down-left-circle::before { content: "\f11b"; } +.bi-arrow-down-left-square-fill::before { content: "\f11c"; } +.bi-arrow-down-left-square::before { content: "\f11d"; } +.bi-arrow-down-left::before { content: "\f11e"; } +.bi-arrow-down-right-circle-fill::before { content: "\f11f"; } +.bi-arrow-down-right-circle::before { content: "\f120"; } +.bi-arrow-down-right-square-fill::before { content: "\f121"; } +.bi-arrow-down-right-square::before { content: "\f122"; } +.bi-arrow-down-right::before { content: "\f123"; } +.bi-arrow-down-short::before { content: "\f124"; } +.bi-arrow-down-square-fill::before { content: "\f125"; } +.bi-arrow-down-square::before { content: "\f126"; } +.bi-arrow-down-up::before { content: "\f127"; } +.bi-arrow-down::before { content: "\f128"; } +.bi-arrow-left-circle-fill::before { content: "\f129"; } +.bi-arrow-left-circle::before { content: "\f12a"; } +.bi-arrow-left-right::before { content: "\f12b"; } +.bi-arrow-left-short::before { content: "\f12c"; } +.bi-arrow-left-square-fill::before { content: "\f12d"; } +.bi-arrow-left-square::before { content: "\f12e"; } +.bi-arrow-left::before { content: "\f12f"; } +.bi-arrow-repeat::before { content: "\f130"; } +.bi-arrow-return-left::before { content: "\f131"; } +.bi-arrow-return-right::before { content: "\f132"; } +.bi-arrow-right-circle-fill::before { content: "\f133"; } +.bi-arrow-right-circle::before { content: "\f134"; } +.bi-arrow-right-short::before { content: "\f135"; } +.bi-arrow-right-square-fill::before { content: "\f136"; } +.bi-arrow-right-square::before { content: "\f137"; } +.bi-arrow-right::before { content: "\f138"; } +.bi-arrow-up-circle-fill::before { content: "\f139"; } +.bi-arrow-up-circle::before { content: "\f13a"; } +.bi-arrow-up-left-circle-fill::before { content: "\f13b"; } +.bi-arrow-up-left-circle::before { content: "\f13c"; } +.bi-arrow-up-left-square-fill::before { content: "\f13d"; } +.bi-arrow-up-left-square::before { content: "\f13e"; } +.bi-arrow-up-left::before { content: "\f13f"; } +.bi-arrow-up-right-circle-fill::before { content: "\f140"; } +.bi-arrow-up-right-circle::before { content: "\f141"; } +.bi-arrow-up-right-square-fill::before { content: "\f142"; } +.bi-arrow-up-right-square::before { content: "\f143"; } +.bi-arrow-up-right::before { content: "\f144"; } +.bi-arrow-up-short::before { content: "\f145"; } +.bi-arrow-up-square-fill::before { content: "\f146"; } +.bi-arrow-up-square::before { content: "\f147"; } +.bi-arrow-up::before { content: "\f148"; } +.bi-arrows-angle-contract::before { content: "\f149"; } +.bi-arrows-angle-expand::before { content: "\f14a"; } +.bi-arrows-collapse::before { content: "\f14b"; } +.bi-arrows-expand::before { content: "\f14c"; } +.bi-arrows-fullscreen::before { content: "\f14d"; } +.bi-arrows-move::before { content: "\f14e"; } +.bi-aspect-ratio-fill::before { content: "\f14f"; } +.bi-aspect-ratio::before { content: "\f150"; } +.bi-asterisk::before { content: "\f151"; } +.bi-at::before { content: "\f152"; } +.bi-award-fill::before { content: "\f153"; } +.bi-award::before { content: "\f154"; } +.bi-back::before { content: "\f155"; } +.bi-backspace-fill::before { content: "\f156"; } +.bi-backspace-reverse-fill::before { content: "\f157"; } +.bi-backspace-reverse::before { content: "\f158"; } +.bi-backspace::before { content: "\f159"; } +.bi-badge-3d-fill::before { content: "\f15a"; } +.bi-badge-3d::before { content: "\f15b"; } +.bi-badge-4k-fill::before { content: "\f15c"; } +.bi-badge-4k::before { content: "\f15d"; } +.bi-badge-8k-fill::before { content: "\f15e"; } +.bi-badge-8k::before { content: "\f15f"; } +.bi-badge-ad-fill::before { content: "\f160"; } +.bi-badge-ad::before { content: "\f161"; } +.bi-badge-ar-fill::before { content: "\f162"; } +.bi-badge-ar::before { content: "\f163"; } +.bi-badge-cc-fill::before { content: "\f164"; } +.bi-badge-cc::before { content: "\f165"; } +.bi-badge-hd-fill::before { content: "\f166"; } +.bi-badge-hd::before { content: "\f167"; } +.bi-badge-tm-fill::before { content: "\f168"; } +.bi-badge-tm::before { content: "\f169"; } +.bi-badge-vo-fill::before { content: "\f16a"; } +.bi-badge-vo::before { content: "\f16b"; } +.bi-badge-vr-fill::before { content: "\f16c"; } +.bi-badge-vr::before { content: "\f16d"; } +.bi-badge-wc-fill::before { content: "\f16e"; } +.bi-badge-wc::before { content: "\f16f"; } +.bi-bag-check-fill::before { content: "\f170"; } +.bi-bag-check::before { content: "\f171"; } +.bi-bag-dash-fill::before { content: "\f172"; } +.bi-bag-dash::before { content: "\f173"; } +.bi-bag-fill::before { content: "\f174"; } +.bi-bag-plus-fill::before { content: "\f175"; } +.bi-bag-plus::before { content: "\f176"; } +.bi-bag-x-fill::before { content: "\f177"; } +.bi-bag-x::before { content: "\f178"; } +.bi-bag::before { content: "\f179"; } +.bi-bar-chart-fill::before { content: "\f17a"; } +.bi-bar-chart-line-fill::before { content: "\f17b"; } +.bi-bar-chart-line::before { content: "\f17c"; } +.bi-bar-chart-steps::before { content: "\f17d"; } +.bi-bar-chart::before { content: "\f17e"; } +.bi-basket-fill::before { content: "\f17f"; } +.bi-basket::before { content: "\f180"; } +.bi-basket2-fill::before { content: "\f181"; } +.bi-basket2::before { content: "\f182"; } +.bi-basket3-fill::before { content: "\f183"; } +.bi-basket3::before { content: "\f184"; } +.bi-battery-charging::before { content: "\f185"; } +.bi-battery-full::before { content: "\f186"; } +.bi-battery-half::before { content: "\f187"; } +.bi-battery::before { content: "\f188"; } +.bi-bell-fill::before { content: "\f189"; } +.bi-bell::before { content: "\f18a"; } +.bi-bezier::before { content: "\f18b"; } +.bi-bezier2::before { content: "\f18c"; } +.bi-bicycle::before { content: "\f18d"; } +.bi-binoculars-fill::before { content: "\f18e"; } +.bi-binoculars::before { content: "\f18f"; } +.bi-blockquote-left::before { content: "\f190"; } +.bi-blockquote-right::before { content: "\f191"; } +.bi-book-fill::before { content: "\f192"; } +.bi-book-half::before { content: "\f193"; } +.bi-book::before { content: "\f194"; } +.bi-bookmark-check-fill::before { content: "\f195"; } +.bi-bookmark-check::before { content: "\f196"; } +.bi-bookmark-dash-fill::before { content: "\f197"; } +.bi-bookmark-dash::before { content: "\f198"; } +.bi-bookmark-fill::before { content: "\f199"; } +.bi-bookmark-heart-fill::before { content: "\f19a"; } +.bi-bookmark-heart::before { content: "\f19b"; } +.bi-bookmark-plus-fill::before { content: "\f19c"; } +.bi-bookmark-plus::before { content: "\f19d"; } +.bi-bookmark-star-fill::before { content: "\f19e"; } +.bi-bookmark-star::before { content: "\f19f"; } +.bi-bookmark-x-fill::before { content: "\f1a0"; } +.bi-bookmark-x::before { content: "\f1a1"; } +.bi-bookmark::before { content: "\f1a2"; } +.bi-bookmarks-fill::before { content: "\f1a3"; } +.bi-bookmarks::before { content: "\f1a4"; } +.bi-bookshelf::before { content: "\f1a5"; } +.bi-bootstrap-fill::before { content: "\f1a6"; } +.bi-bootstrap-reboot::before { content: "\f1a7"; } +.bi-bootstrap::before { content: "\f1a8"; } +.bi-border-all::before { content: "\f1a9"; } +.bi-border-bottom::before { content: "\f1aa"; } +.bi-border-center::before { content: "\f1ab"; } +.bi-border-inner::before { content: "\f1ac"; } +.bi-border-left::before { content: "\f1ad"; } +.bi-border-middle::before { content: "\f1ae"; } +.bi-border-outer::before { content: "\f1af"; } +.bi-border-right::before { content: "\f1b0"; } +.bi-border-style::before { content: "\f1b1"; } +.bi-border-top::before { content: "\f1b2"; } +.bi-border-width::before { content: "\f1b3"; } +.bi-border::before { content: "\f1b4"; } +.bi-bounding-box-circles::before { content: "\f1b5"; } +.bi-bounding-box::before { content: "\f1b6"; } +.bi-box-arrow-down-left::before { content: "\f1b7"; } +.bi-box-arrow-down-right::before { content: "\f1b8"; } +.bi-box-arrow-down::before { content: "\f1b9"; } +.bi-box-arrow-in-down-left::before { content: "\f1ba"; } +.bi-box-arrow-in-down-right::before { content: "\f1bb"; } +.bi-box-arrow-in-down::before { content: "\f1bc"; } +.bi-box-arrow-in-left::before { content: "\f1bd"; } +.bi-box-arrow-in-right::before { content: "\f1be"; } +.bi-box-arrow-in-up-left::before { content: "\f1bf"; } +.bi-box-arrow-in-up-right::before { content: "\f1c0"; } +.bi-box-arrow-in-up::before { content: "\f1c1"; } +.bi-box-arrow-left::before { content: "\f1c2"; } +.bi-box-arrow-right::before { content: "\f1c3"; } +.bi-box-arrow-up-left::before { content: "\f1c4"; } +.bi-box-arrow-up-right::before { content: "\f1c5"; } +.bi-box-arrow-up::before { content: "\f1c6"; } +.bi-box-seam::before { content: "\f1c7"; } +.bi-box::before { content: "\f1c8"; } +.bi-braces::before { content: "\f1c9"; } +.bi-bricks::before { content: "\f1ca"; } +.bi-briefcase-fill::before { content: "\f1cb"; } +.bi-briefcase::before { content: "\f1cc"; } +.bi-brightness-alt-high-fill::before { content: "\f1cd"; } +.bi-brightness-alt-high::before { content: "\f1ce"; } +.bi-brightness-alt-low-fill::before { content: "\f1cf"; } +.bi-brightness-alt-low::before { content: "\f1d0"; } +.bi-brightness-high-fill::before { content: "\f1d1"; } +.bi-brightness-high::before { content: "\f1d2"; } +.bi-brightness-low-fill::before { content: "\f1d3"; } +.bi-brightness-low::before { content: "\f1d4"; } +.bi-broadcast-pin::before { content: "\f1d5"; } +.bi-broadcast::before { content: "\f1d6"; } +.bi-brush-fill::before { content: "\f1d7"; } +.bi-brush::before { content: "\f1d8"; } +.bi-bucket-fill::before { content: "\f1d9"; } +.bi-bucket::before { content: "\f1da"; } +.bi-bug-fill::before { content: "\f1db"; } +.bi-bug::before { content: "\f1dc"; } +.bi-building::before { content: "\f1dd"; } +.bi-bullseye::before { content: "\f1de"; } +.bi-calculator-fill::before { content: "\f1df"; } +.bi-calculator::before { content: "\f1e0"; } +.bi-calendar-check-fill::before { content: "\f1e1"; } +.bi-calendar-check::before { content: "\f1e2"; } +.bi-calendar-date-fill::before { content: "\f1e3"; } +.bi-calendar-date::before { content: "\f1e4"; } +.bi-calendar-day-fill::before { content: "\f1e5"; } +.bi-calendar-day::before { content: "\f1e6"; } +.bi-calendar-event-fill::before { content: "\f1e7"; } +.bi-calendar-event::before { content: "\f1e8"; } +.bi-calendar-fill::before { content: "\f1e9"; } +.bi-calendar-minus-fill::before { content: "\f1ea"; } +.bi-calendar-minus::before { content: "\f1eb"; } +.bi-calendar-month-fill::before { content: "\f1ec"; } +.bi-calendar-month::before { content: "\f1ed"; } +.bi-calendar-plus-fill::before { content: "\f1ee"; } +.bi-calendar-plus::before { content: "\f1ef"; } +.bi-calendar-range-fill::before { content: "\f1f0"; } +.bi-calendar-range::before { content: "\f1f1"; } +.bi-calendar-week-fill::before { content: "\f1f2"; } +.bi-calendar-week::before { content: "\f1f3"; } +.bi-calendar-x-fill::before { content: "\f1f4"; } +.bi-calendar-x::before { content: "\f1f5"; } +.bi-calendar::before { content: "\f1f6"; } +.bi-calendar2-check-fill::before { content: "\f1f7"; } +.bi-calendar2-check::before { content: "\f1f8"; } +.bi-calendar2-date-fill::before { content: "\f1f9"; } +.bi-calendar2-date::before { content: "\f1fa"; } +.bi-calendar2-day-fill::before { content: "\f1fb"; } +.bi-calendar2-day::before { content: "\f1fc"; } +.bi-calendar2-event-fill::before { content: "\f1fd"; } +.bi-calendar2-event::before { content: "\f1fe"; } +.bi-calendar2-fill::before { content: "\f1ff"; } +.bi-calendar2-minus-fill::before { content: "\f200"; } +.bi-calendar2-minus::before { content: "\f201"; } +.bi-calendar2-month-fill::before { content: "\f202"; } +.bi-calendar2-month::before { content: "\f203"; } +.bi-calendar2-plus-fill::before { content: "\f204"; } +.bi-calendar2-plus::before { content: "\f205"; } +.bi-calendar2-range-fill::before { content: "\f206"; } +.bi-calendar2-range::before { content: "\f207"; } +.bi-calendar2-week-fill::before { content: "\f208"; } +.bi-calendar2-week::before { content: "\f209"; } +.bi-calendar2-x-fill::before { content: "\f20a"; } +.bi-calendar2-x::before { content: "\f20b"; } +.bi-calendar2::before { content: "\f20c"; } +.bi-calendar3-event-fill::before { content: "\f20d"; } +.bi-calendar3-event::before { content: "\f20e"; } +.bi-calendar3-fill::before { content: "\f20f"; } +.bi-calendar3-range-fill::before { content: "\f210"; } +.bi-calendar3-range::before { content: "\f211"; } +.bi-calendar3-week-fill::before { content: "\f212"; } +.bi-calendar3-week::before { content: "\f213"; } +.bi-calendar3::before { content: "\f214"; } +.bi-calendar4-event::before { content: "\f215"; } +.bi-calendar4-range::before { content: "\f216"; } +.bi-calendar4-week::before { content: "\f217"; } +.bi-calendar4::before { content: "\f218"; } +.bi-camera-fill::before { content: "\f219"; } +.bi-camera-reels-fill::before { content: "\f21a"; } +.bi-camera-reels::before { content: "\f21b"; } +.bi-camera-video-fill::before { content: "\f21c"; } +.bi-camera-video-off-fill::before { content: "\f21d"; } +.bi-camera-video-off::before { content: "\f21e"; } +.bi-camera-video::before { content: "\f21f"; } +.bi-camera::before { content: "\f220"; } +.bi-camera2::before { content: "\f221"; } +.bi-capslock-fill::before { content: "\f222"; } +.bi-capslock::before { content: "\f223"; } +.bi-card-checklist::before { content: "\f224"; } +.bi-card-heading::before { content: "\f225"; } +.bi-card-image::before { content: "\f226"; } +.bi-card-list::before { content: "\f227"; } +.bi-card-text::before { content: "\f228"; } +.bi-caret-down-fill::before { content: "\f229"; } +.bi-caret-down-square-fill::before { content: "\f22a"; } +.bi-caret-down-square::before { content: "\f22b"; } +.bi-caret-down::before { content: "\f22c"; } +.bi-caret-left-fill::before { content: "\f22d"; } +.bi-caret-left-square-fill::before { content: "\f22e"; } +.bi-caret-left-square::before { content: "\f22f"; } +.bi-caret-left::before { content: "\f230"; } +.bi-caret-right-fill::before { content: "\f231"; } +.bi-caret-right-square-fill::before { content: "\f232"; } +.bi-caret-right-square::before { content: "\f233"; } +.bi-caret-right::before { content: "\f234"; } +.bi-caret-up-fill::before { content: "\f235"; } +.bi-caret-up-square-fill::before { content: "\f236"; } +.bi-caret-up-square::before { content: "\f237"; } +.bi-caret-up::before { content: "\f238"; } +.bi-cart-check-fill::before { content: "\f239"; } +.bi-cart-check::before { content: "\f23a"; } +.bi-cart-dash-fill::before { content: "\f23b"; } +.bi-cart-dash::before { content: "\f23c"; } +.bi-cart-fill::before { content: "\f23d"; } +.bi-cart-plus-fill::before { content: "\f23e"; } +.bi-cart-plus::before { content: "\f23f"; } +.bi-cart-x-fill::before { content: "\f240"; } +.bi-cart-x::before { content: "\f241"; } +.bi-cart::before { content: "\f242"; } +.bi-cart2::before { content: "\f243"; } +.bi-cart3::before { content: "\f244"; } +.bi-cart4::before { content: "\f245"; } +.bi-cash-stack::before { content: "\f246"; } +.bi-cash::before { content: "\f247"; } +.bi-cast::before { content: "\f248"; } +.bi-chat-dots-fill::before { content: "\f249"; } +.bi-chat-dots::before { content: "\f24a"; } +.bi-chat-fill::before { content: "\f24b"; } +.bi-chat-left-dots-fill::before { content: "\f24c"; } +.bi-chat-left-dots::before { content: "\f24d"; } +.bi-chat-left-fill::before { content: "\f24e"; } +.bi-chat-left-quote-fill::before { content: "\f24f"; } +.bi-chat-left-quote::before { content: "\f250"; } +.bi-chat-left-text-fill::before { content: "\f251"; } +.bi-chat-left-text::before { content: "\f252"; } +.bi-chat-left::before { content: "\f253"; } +.bi-chat-quote-fill::before { content: "\f254"; } +.bi-chat-quote::before { content: "\f255"; } +.bi-chat-right-dots-fill::before { content: "\f256"; } +.bi-chat-right-dots::before { content: "\f257"; } +.bi-chat-right-fill::before { content: "\f258"; } +.bi-chat-right-quote-fill::before { content: "\f259"; } +.bi-chat-right-quote::before { content: "\f25a"; } +.bi-chat-right-text-fill::before { content: "\f25b"; } +.bi-chat-right-text::before { content: "\f25c"; } +.bi-chat-right::before { content: "\f25d"; } +.bi-chat-square-dots-fill::before { content: "\f25e"; } +.bi-chat-square-dots::before { content: "\f25f"; } +.bi-chat-square-fill::before { content: "\f260"; } +.bi-chat-square-quote-fill::before { content: "\f261"; } +.bi-chat-square-quote::before { content: "\f262"; } +.bi-chat-square-text-fill::before { content: "\f263"; } +.bi-chat-square-text::before { content: "\f264"; } +.bi-chat-square::before { content: "\f265"; } +.bi-chat-text-fill::before { content: "\f266"; } +.bi-chat-text::before { content: "\f267"; } +.bi-chat::before { content: "\f268"; } +.bi-check-all::before { content: "\f269"; } +.bi-check-circle-fill::before { content: "\f26a"; } +.bi-check-circle::before { content: "\f26b"; } +.bi-check-square-fill::before { content: "\f26c"; } +.bi-check-square::before { content: "\f26d"; } +.bi-check::before { content: "\f26e"; } +.bi-check2-all::before { content: "\f26f"; } +.bi-check2-circle::before { content: "\f270"; } +.bi-check2-square::before { content: "\f271"; } +.bi-check2::before { content: "\f272"; } +.bi-chevron-bar-contract::before { content: "\f273"; } +.bi-chevron-bar-down::before { content: "\f274"; } +.bi-chevron-bar-expand::before { content: "\f275"; } +.bi-chevron-bar-left::before { content: "\f276"; } +.bi-chevron-bar-right::before { content: "\f277"; } +.bi-chevron-bar-up::before { content: "\f278"; } +.bi-chevron-compact-down::before { content: "\f279"; } +.bi-chevron-compact-left::before { content: "\f27a"; } +.bi-chevron-compact-right::before { content: "\f27b"; } +.bi-chevron-compact-up::before { content: "\f27c"; } +.bi-chevron-contract::before { content: "\f27d"; } +.bi-chevron-double-down::before { content: "\f27e"; } +.bi-chevron-double-left::before { content: "\f27f"; } +.bi-chevron-double-right::before { content: "\f280"; } +.bi-chevron-double-up::before { content: "\f281"; } +.bi-chevron-down::before { content: "\f282"; } +.bi-chevron-expand::before { content: "\f283"; } +.bi-chevron-left::before { content: "\f284"; } +.bi-chevron-right::before { content: "\f285"; } +.bi-chevron-up::before { content: "\f286"; } +.bi-circle-fill::before { content: "\f287"; } +.bi-circle-half::before { content: "\f288"; } +.bi-circle-square::before { content: "\f289"; } +.bi-circle::before { content: "\f28a"; } +.bi-clipboard-check::before { content: "\f28b"; } +.bi-clipboard-data::before { content: "\f28c"; } +.bi-clipboard-minus::before { content: "\f28d"; } +.bi-clipboard-plus::before { content: "\f28e"; } +.bi-clipboard-x::before { content: "\f28f"; } +.bi-clipboard::before { content: "\f290"; } +.bi-clock-fill::before { content: "\f291"; } +.bi-clock-history::before { content: "\f292"; } +.bi-clock::before { content: "\f293"; } +.bi-cloud-arrow-down-fill::before { content: "\f294"; } +.bi-cloud-arrow-down::before { content: "\f295"; } +.bi-cloud-arrow-up-fill::before { content: "\f296"; } +.bi-cloud-arrow-up::before { content: "\f297"; } +.bi-cloud-check-fill::before { content: "\f298"; } +.bi-cloud-check::before { content: "\f299"; } +.bi-cloud-download-fill::before { content: "\f29a"; } +.bi-cloud-download::before { content: "\f29b"; } +.bi-cloud-drizzle-fill::before { content: "\f29c"; } +.bi-cloud-drizzle::before { content: "\f29d"; } +.bi-cloud-fill::before { content: "\f29e"; } +.bi-cloud-fog-fill::before { content: "\f29f"; } +.bi-cloud-fog::before { content: "\f2a0"; } +.bi-cloud-fog2-fill::before { content: "\f2a1"; } +.bi-cloud-fog2::before { content: "\f2a2"; } +.bi-cloud-hail-fill::before { content: "\f2a3"; } +.bi-cloud-hail::before { content: "\f2a4"; } +.bi-cloud-haze-1::before { content: "\f2a5"; } +.bi-cloud-haze-fill::before { content: "\f2a6"; } +.bi-cloud-haze::before { content: "\f2a7"; } +.bi-cloud-haze2-fill::before { content: "\f2a8"; } +.bi-cloud-lightning-fill::before { content: "\f2a9"; } +.bi-cloud-lightning-rain-fill::before { content: "\f2aa"; } +.bi-cloud-lightning-rain::before { content: "\f2ab"; } +.bi-cloud-lightning::before { content: "\f2ac"; } +.bi-cloud-minus-fill::before { content: "\f2ad"; } +.bi-cloud-minus::before { content: "\f2ae"; } +.bi-cloud-moon-fill::before { content: "\f2af"; } +.bi-cloud-moon::before { content: "\f2b0"; } +.bi-cloud-plus-fill::before { content: "\f2b1"; } +.bi-cloud-plus::before { content: "\f2b2"; } +.bi-cloud-rain-fill::before { content: "\f2b3"; } +.bi-cloud-rain-heavy-fill::before { content: "\f2b4"; } +.bi-cloud-rain-heavy::before { content: "\f2b5"; } +.bi-cloud-rain::before { content: "\f2b6"; } +.bi-cloud-slash-fill::before { content: "\f2b7"; } +.bi-cloud-slash::before { content: "\f2b8"; } +.bi-cloud-sleet-fill::before { content: "\f2b9"; } +.bi-cloud-sleet::before { content: "\f2ba"; } +.bi-cloud-snow-fill::before { content: "\f2bb"; } +.bi-cloud-snow::before { content: "\f2bc"; } +.bi-cloud-sun-fill::before { content: "\f2bd"; } +.bi-cloud-sun::before { content: "\f2be"; } +.bi-cloud-upload-fill::before { content: "\f2bf"; } +.bi-cloud-upload::before { content: "\f2c0"; } +.bi-cloud::before { content: "\f2c1"; } +.bi-clouds-fill::before { content: "\f2c2"; } +.bi-clouds::before { content: "\f2c3"; } +.bi-cloudy-fill::before { content: "\f2c4"; } +.bi-cloudy::before { content: "\f2c5"; } +.bi-code-slash::before { content: "\f2c6"; } +.bi-code-square::before { content: "\f2c7"; } +.bi-code::before { content: "\f2c8"; } +.bi-collection-fill::before { content: "\f2c9"; } +.bi-collection-play-fill::before { content: "\f2ca"; } +.bi-collection-play::before { content: "\f2cb"; } +.bi-collection::before { content: "\f2cc"; } +.bi-columns-gap::before { content: "\f2cd"; } +.bi-columns::before { content: "\f2ce"; } +.bi-command::before { content: "\f2cf"; } +.bi-compass-fill::before { content: "\f2d0"; } +.bi-compass::before { content: "\f2d1"; } +.bi-cone-striped::before { content: "\f2d2"; } +.bi-cone::before { content: "\f2d3"; } +.bi-controller::before { content: "\f2d4"; } +.bi-cpu-fill::before { content: "\f2d5"; } +.bi-cpu::before { content: "\f2d6"; } +.bi-credit-card-2-back-fill::before { content: "\f2d7"; } +.bi-credit-card-2-back::before { content: "\f2d8"; } +.bi-credit-card-2-front-fill::before { content: "\f2d9"; } +.bi-credit-card-2-front::before { content: "\f2da"; } +.bi-credit-card-fill::before { content: "\f2db"; } +.bi-credit-card::before { content: "\f2dc"; } +.bi-crop::before { content: "\f2dd"; } +.bi-cup-fill::before { content: "\f2de"; } +.bi-cup-straw::before { content: "\f2df"; } +.bi-cup::before { content: "\f2e0"; } +.bi-cursor-fill::before { content: "\f2e1"; } +.bi-cursor-text::before { content: "\f2e2"; } +.bi-cursor::before { content: "\f2e3"; } +.bi-dash-circle-dotted::before { content: "\f2e4"; } +.bi-dash-circle-fill::before { content: "\f2e5"; } +.bi-dash-circle::before { content: "\f2e6"; } +.bi-dash-square-dotted::before { content: "\f2e7"; } +.bi-dash-square-fill::before { content: "\f2e8"; } +.bi-dash-square::before { content: "\f2e9"; } +.bi-dash::before { content: "\f2ea"; } +.bi-diagram-2-fill::before { content: "\f2eb"; } +.bi-diagram-2::before { content: "\f2ec"; } +.bi-diagram-3-fill::before { content: "\f2ed"; } +.bi-diagram-3::before { content: "\f2ee"; } +.bi-diamond-fill::before { content: "\f2ef"; } +.bi-diamond-half::before { content: "\f2f0"; } +.bi-diamond::before { content: "\f2f1"; } +.bi-dice-1-fill::before { content: "\f2f2"; } +.bi-dice-1::before { content: "\f2f3"; } +.bi-dice-2-fill::before { content: "\f2f4"; } +.bi-dice-2::before { content: "\f2f5"; } +.bi-dice-3-fill::before { content: "\f2f6"; } +.bi-dice-3::before { content: "\f2f7"; } +.bi-dice-4-fill::before { content: "\f2f8"; } +.bi-dice-4::before { content: "\f2f9"; } +.bi-dice-5-fill::before { content: "\f2fa"; } +.bi-dice-5::before { content: "\f2fb"; } +.bi-dice-6-fill::before { content: "\f2fc"; } +.bi-dice-6::before { content: "\f2fd"; } +.bi-disc-fill::before { content: "\f2fe"; } +.bi-disc::before { content: "\f2ff"; } +.bi-discord::before { content: "\f300"; } +.bi-display-fill::before { content: "\f301"; } +.bi-display::before { content: "\f302"; } +.bi-distribute-horizontal::before { content: "\f303"; } +.bi-distribute-vertical::before { content: "\f304"; } +.bi-door-closed-fill::before { content: "\f305"; } +.bi-door-closed::before { content: "\f306"; } +.bi-door-open-fill::before { content: "\f307"; } +.bi-door-open::before { content: "\f308"; } +.bi-dot::before { content: "\f309"; } +.bi-download::before { content: "\f30a"; } +.bi-droplet-fill::before { content: "\f30b"; } +.bi-droplet-half::before { content: "\f30c"; } +.bi-droplet::before { content: "\f30d"; } +.bi-earbuds::before { content: "\f30e"; } +.bi-easel-fill::before { content: "\f30f"; } +.bi-easel::before { content: "\f310"; } +.bi-egg-fill::before { content: "\f311"; } +.bi-egg-fried::before { content: "\f312"; } +.bi-egg::before { content: "\f313"; } +.bi-eject-fill::before { content: "\f314"; } +.bi-eject::before { content: "\f315"; } +.bi-emoji-angry-fill::before { content: "\f316"; } +.bi-emoji-angry::before { content: "\f317"; } +.bi-emoji-dizzy-fill::before { content: "\f318"; } +.bi-emoji-dizzy::before { content: "\f319"; } +.bi-emoji-expressionless-fill::before { content: "\f31a"; } +.bi-emoji-expressionless::before { content: "\f31b"; } +.bi-emoji-frown-fill::before { content: "\f31c"; } +.bi-emoji-frown::before { content: "\f31d"; } +.bi-emoji-heart-eyes-fill::before { content: "\f31e"; } +.bi-emoji-heart-eyes::before { content: "\f31f"; } +.bi-emoji-laughing-fill::before { content: "\f320"; } +.bi-emoji-laughing::before { content: "\f321"; } +.bi-emoji-neutral-fill::before { content: "\f322"; } +.bi-emoji-neutral::before { content: "\f323"; } +.bi-emoji-smile-fill::before { content: "\f324"; } +.bi-emoji-smile-upside-down-fill::before { content: "\f325"; } +.bi-emoji-smile-upside-down::before { content: "\f326"; } +.bi-emoji-smile::before { content: "\f327"; } +.bi-emoji-sunglasses-fill::before { content: "\f328"; } +.bi-emoji-sunglasses::before { content: "\f329"; } +.bi-emoji-wink-fill::before { content: "\f32a"; } +.bi-emoji-wink::before { content: "\f32b"; } +.bi-envelope-fill::before { content: "\f32c"; } +.bi-envelope-open-fill::before { content: "\f32d"; } +.bi-envelope-open::before { content: "\f32e"; } +.bi-envelope::before { content: "\f32f"; } +.bi-eraser-fill::before { content: "\f330"; } +.bi-eraser::before { content: "\f331"; } +.bi-exclamation-circle-fill::before { content: "\f332"; } +.bi-exclamation-circle::before { content: "\f333"; } +.bi-exclamation-diamond-fill::before { content: "\f334"; } +.bi-exclamation-diamond::before { content: "\f335"; } +.bi-exclamation-octagon-fill::before { content: "\f336"; } +.bi-exclamation-octagon::before { content: "\f337"; } +.bi-exclamation-square-fill::before { content: "\f338"; } +.bi-exclamation-square::before { content: "\f339"; } +.bi-exclamation-triangle-fill::before { content: "\f33a"; } +.bi-exclamation-triangle::before { content: "\f33b"; } +.bi-exclamation::before { content: "\f33c"; } +.bi-exclude::before { content: "\f33d"; } +.bi-eye-fill::before { content: "\f33e"; } +.bi-eye-slash-fill::before { content: "\f33f"; } +.bi-eye-slash::before { content: "\f340"; } +.bi-eye::before { content: "\f341"; } +.bi-eyedropper::before { content: "\f342"; } +.bi-eyeglasses::before { content: "\f343"; } +.bi-facebook::before { content: "\f344"; } +.bi-file-arrow-down-fill::before { content: "\f345"; } +.bi-file-arrow-down::before { content: "\f346"; } +.bi-file-arrow-up-fill::before { content: "\f347"; } +.bi-file-arrow-up::before { content: "\f348"; } +.bi-file-bar-graph-fill::before { content: "\f349"; } +.bi-file-bar-graph::before { content: "\f34a"; } +.bi-file-binary-fill::before { content: "\f34b"; } +.bi-file-binary::before { content: "\f34c"; } +.bi-file-break-fill::before { content: "\f34d"; } +.bi-file-break::before { content: "\f34e"; } +.bi-file-check-fill::before { content: "\f34f"; } +.bi-file-check::before { content: "\f350"; } +.bi-file-code-fill::before { content: "\f351"; } +.bi-file-code::before { content: "\f352"; } +.bi-file-diff-fill::before { content: "\f353"; } +.bi-file-diff::before { content: "\f354"; } +.bi-file-earmark-arrow-down-fill::before { content: "\f355"; } +.bi-file-earmark-arrow-down::before { content: "\f356"; } +.bi-file-earmark-arrow-up-fill::before { content: "\f357"; } +.bi-file-earmark-arrow-up::before { content: "\f358"; } +.bi-file-earmark-bar-graph-fill::before { content: "\f359"; } +.bi-file-earmark-bar-graph::before { content: "\f35a"; } +.bi-file-earmark-binary-fill::before { content: "\f35b"; } +.bi-file-earmark-binary::before { content: "\f35c"; } +.bi-file-earmark-break-fill::before { content: "\f35d"; } +.bi-file-earmark-break::before { content: "\f35e"; } +.bi-file-earmark-check-fill::before { content: "\f35f"; } +.bi-file-earmark-check::before { content: "\f360"; } +.bi-file-earmark-code-fill::before { content: "\f361"; } +.bi-file-earmark-code::before { content: "\f362"; } +.bi-file-earmark-diff-fill::before { content: "\f363"; } +.bi-file-earmark-diff::before { content: "\f364"; } +.bi-file-earmark-easel-fill::before { content: "\f365"; } +.bi-file-earmark-easel::before { content: "\f366"; } +.bi-file-earmark-excel-fill::before { content: "\f367"; } +.bi-file-earmark-excel::before { content: "\f368"; } +.bi-file-earmark-fill::before { content: "\f369"; } +.bi-file-earmark-font-fill::before { content: "\f36a"; } +.bi-file-earmark-font::before { content: "\f36b"; } +.bi-file-earmark-image-fill::before { content: "\f36c"; } +.bi-file-earmark-image::before { content: "\f36d"; } +.bi-file-earmark-lock-fill::before { content: "\f36e"; } +.bi-file-earmark-lock::before { content: "\f36f"; } +.bi-file-earmark-lock2-fill::before { content: "\f370"; } +.bi-file-earmark-lock2::before { content: "\f371"; } +.bi-file-earmark-medical-fill::before { content: "\f372"; } +.bi-file-earmark-medical::before { content: "\f373"; } +.bi-file-earmark-minus-fill::before { content: "\f374"; } +.bi-file-earmark-minus::before { content: "\f375"; } +.bi-file-earmark-music-fill::before { content: "\f376"; } +.bi-file-earmark-music::before { content: "\f377"; } +.bi-file-earmark-person-fill::before { content: "\f378"; } +.bi-file-earmark-person::before { content: "\f379"; } +.bi-file-earmark-play-fill::before { content: "\f37a"; } +.bi-file-earmark-play::before { content: "\f37b"; } +.bi-file-earmark-plus-fill::before { content: "\f37c"; } +.bi-file-earmark-plus::before { content: "\f37d"; } +.bi-file-earmark-post-fill::before { content: "\f37e"; } +.bi-file-earmark-post::before { content: "\f37f"; } +.bi-file-earmark-ppt-fill::before { content: "\f380"; } +.bi-file-earmark-ppt::before { content: "\f381"; } +.bi-file-earmark-richtext-fill::before { content: "\f382"; } +.bi-file-earmark-richtext::before { content: "\f383"; } +.bi-file-earmark-ruled-fill::before { content: "\f384"; } +.bi-file-earmark-ruled::before { content: "\f385"; } +.bi-file-earmark-slides-fill::before { content: "\f386"; } +.bi-file-earmark-slides::before { content: "\f387"; } +.bi-file-earmark-spreadsheet-fill::before { content: "\f388"; } +.bi-file-earmark-spreadsheet::before { content: "\f389"; } +.bi-file-earmark-text-fill::before { content: "\f38a"; } +.bi-file-earmark-text::before { content: "\f38b"; } +.bi-file-earmark-word-fill::before { content: "\f38c"; } +.bi-file-earmark-word::before { content: "\f38d"; } +.bi-file-earmark-x-fill::before { content: "\f38e"; } +.bi-file-earmark-x::before { content: "\f38f"; } +.bi-file-earmark-zip-fill::before { content: "\f390"; } +.bi-file-earmark-zip::before { content: "\f391"; } +.bi-file-earmark::before { content: "\f392"; } +.bi-file-easel-fill::before { content: "\f393"; } +.bi-file-easel::before { content: "\f394"; } +.bi-file-excel-fill::before { content: "\f395"; } +.bi-file-excel::before { content: "\f396"; } +.bi-file-fill::before { content: "\f397"; } +.bi-file-font-fill::before { content: "\f398"; } +.bi-file-font::before { content: "\f399"; } +.bi-file-image-fill::before { content: "\f39a"; } +.bi-file-image::before { content: "\f39b"; } +.bi-file-lock-fill::before { content: "\f39c"; } +.bi-file-lock::before { content: "\f39d"; } +.bi-file-lock2-fill::before { content: "\f39e"; } +.bi-file-lock2::before { content: "\f39f"; } +.bi-file-medical-fill::before { content: "\f3a0"; } +.bi-file-medical::before { content: "\f3a1"; } +.bi-file-minus-fill::before { content: "\f3a2"; } +.bi-file-minus::before { content: "\f3a3"; } +.bi-file-music-fill::before { content: "\f3a4"; } +.bi-file-music::before { content: "\f3a5"; } +.bi-file-person-fill::before { content: "\f3a6"; } +.bi-file-person::before { content: "\f3a7"; } +.bi-file-play-fill::before { content: "\f3a8"; } +.bi-file-play::before { content: "\f3a9"; } +.bi-file-plus-fill::before { content: "\f3aa"; } +.bi-file-plus::before { content: "\f3ab"; } +.bi-file-post-fill::before { content: "\f3ac"; } +.bi-file-post::before { content: "\f3ad"; } +.bi-file-ppt-fill::before { content: "\f3ae"; } +.bi-file-ppt::before { content: "\f3af"; } +.bi-file-richtext-fill::before { content: "\f3b0"; } +.bi-file-richtext::before { content: "\f3b1"; } +.bi-file-ruled-fill::before { content: "\f3b2"; } +.bi-file-ruled::before { content: "\f3b3"; } +.bi-file-slides-fill::before { content: "\f3b4"; } +.bi-file-slides::before { content: "\f3b5"; } +.bi-file-spreadsheet-fill::before { content: "\f3b6"; } +.bi-file-spreadsheet::before { content: "\f3b7"; } +.bi-file-text-fill::before { content: "\f3b8"; } +.bi-file-text::before { content: "\f3b9"; } +.bi-file-word-fill::before { content: "\f3ba"; } +.bi-file-word::before { content: "\f3bb"; } +.bi-file-x-fill::before { content: "\f3bc"; } +.bi-file-x::before { content: "\f3bd"; } +.bi-file-zip-fill::before { content: "\f3be"; } +.bi-file-zip::before { content: "\f3bf"; } +.bi-file::before { content: "\f3c0"; } +.bi-files-alt::before { content: "\f3c1"; } +.bi-files::before { content: "\f3c2"; } +.bi-film::before { content: "\f3c3"; } +.bi-filter-circle-fill::before { content: "\f3c4"; } +.bi-filter-circle::before { content: "\f3c5"; } +.bi-filter-left::before { content: "\f3c6"; } +.bi-filter-right::before { content: "\f3c7"; } +.bi-filter-square-fill::before { content: "\f3c8"; } +.bi-filter-square::before { content: "\f3c9"; } +.bi-filter::before { content: "\f3ca"; } +.bi-flag-fill::before { content: "\f3cb"; } +.bi-flag::before { content: "\f3cc"; } +.bi-flower1::before { content: "\f3cd"; } +.bi-flower2::before { content: "\f3ce"; } +.bi-flower3::before { content: "\f3cf"; } +.bi-folder-check::before { content: "\f3d0"; } +.bi-folder-fill::before { content: "\f3d1"; } +.bi-folder-minus::before { content: "\f3d2"; } +.bi-folder-plus::before { content: "\f3d3"; } +.bi-folder-symlink-fill::before { content: "\f3d4"; } +.bi-folder-symlink::before { content: "\f3d5"; } +.bi-folder-x::before { content: "\f3d6"; } +.bi-folder::before { content: "\f3d7"; } +.bi-folder2-open::before { content: "\f3d8"; } +.bi-folder2::before { content: "\f3d9"; } +.bi-fonts::before { content: "\f3da"; } +.bi-forward-fill::before { content: "\f3db"; } +.bi-forward::before { content: "\f3dc"; } +.bi-front::before { content: "\f3dd"; } +.bi-fullscreen-exit::before { content: "\f3de"; } +.bi-fullscreen::before { content: "\f3df"; } +.bi-funnel-fill::before { content: "\f3e0"; } +.bi-funnel::before { content: "\f3e1"; } +.bi-gear-fill::before { content: "\f3e2"; } +.bi-gear-wide-connected::before { content: "\f3e3"; } +.bi-gear-wide::before { content: "\f3e4"; } +.bi-gear::before { content: "\f3e5"; } +.bi-gem::before { content: "\f3e6"; } +.bi-geo-alt-fill::before { content: "\f3e7"; } +.bi-geo-alt::before { content: "\f3e8"; } +.bi-geo-fill::before { content: "\f3e9"; } +.bi-geo::before { content: "\f3ea"; } +.bi-gift-fill::before { content: "\f3eb"; } +.bi-gift::before { content: "\f3ec"; } +.bi-github::before { content: "\f3ed"; } +.bi-globe::before { content: "\f3ee"; } +.bi-globe2::before { content: "\f3ef"; } +.bi-google::before { content: "\f3f0"; } +.bi-graph-down::before { content: "\f3f1"; } +.bi-graph-up::before { content: "\f3f2"; } +.bi-grid-1x2-fill::before { content: "\f3f3"; } +.bi-grid-1x2::before { content: "\f3f4"; } +.bi-grid-3x2-gap-fill::before { content: "\f3f5"; } +.bi-grid-3x2-gap::before { content: "\f3f6"; } +.bi-grid-3x2::before { content: "\f3f7"; } +.bi-grid-3x3-gap-fill::before { content: "\f3f8"; } +.bi-grid-3x3-gap::before { content: "\f3f9"; } +.bi-grid-3x3::before { content: "\f3fa"; } +.bi-grid-fill::before { content: "\f3fb"; } +.bi-grid::before { content: "\f3fc"; } +.bi-grip-horizontal::before { content: "\f3fd"; } +.bi-grip-vertical::before { content: "\f3fe"; } +.bi-hammer::before { content: "\f3ff"; } +.bi-hand-index-fill::before { content: "\f400"; } +.bi-hand-index-thumb-fill::before { content: "\f401"; } +.bi-hand-index-thumb::before { content: "\f402"; } +.bi-hand-index::before { content: "\f403"; } +.bi-hand-thumbs-down-fill::before { content: "\f404"; } +.bi-hand-thumbs-down::before { content: "\f405"; } +.bi-hand-thumbs-up-fill::before { content: "\f406"; } +.bi-hand-thumbs-up::before { content: "\f407"; } +.bi-handbag-fill::before { content: "\f408"; } +.bi-handbag::before { content: "\f409"; } +.bi-hash::before { content: "\f40a"; } +.bi-hdd-fill::before { content: "\f40b"; } +.bi-hdd-network-fill::before { content: "\f40c"; } +.bi-hdd-network::before { content: "\f40d"; } +.bi-hdd-rack-fill::before { content: "\f40e"; } +.bi-hdd-rack::before { content: "\f40f"; } +.bi-hdd-stack-fill::before { content: "\f410"; } +.bi-hdd-stack::before { content: "\f411"; } +.bi-hdd::before { content: "\f412"; } +.bi-headphones::before { content: "\f413"; } +.bi-headset::before { content: "\f414"; } +.bi-heart-fill::before { content: "\f415"; } +.bi-heart-half::before { content: "\f416"; } +.bi-heart::before { content: "\f417"; } +.bi-heptagon-fill::before { content: "\f418"; } +.bi-heptagon-half::before { content: "\f419"; } +.bi-heptagon::before { content: "\f41a"; } +.bi-hexagon-fill::before { content: "\f41b"; } +.bi-hexagon-half::before { content: "\f41c"; } +.bi-hexagon::before { content: "\f41d"; } +.bi-hourglass-bottom::before { content: "\f41e"; } +.bi-hourglass-split::before { content: "\f41f"; } +.bi-hourglass-top::before { content: "\f420"; } +.bi-hourglass::before { content: "\f421"; } +.bi-house-door-fill::before { content: "\f422"; } +.bi-house-door::before { content: "\f423"; } +.bi-house-fill::before { content: "\f424"; } +.bi-house::before { content: "\f425"; } +.bi-hr::before { content: "\f426"; } +.bi-hurricane::before { content: "\f427"; } +.bi-image-alt::before { content: "\f428"; } +.bi-image-fill::before { content: "\f429"; } +.bi-image::before { content: "\f42a"; } +.bi-images::before { content: "\f42b"; } +.bi-inbox-fill::before { content: "\f42c"; } +.bi-inbox::before { content: "\f42d"; } +.bi-inboxes-fill::before { content: "\f42e"; } +.bi-inboxes::before { content: "\f42f"; } +.bi-info-circle-fill::before { content: "\f430"; } +.bi-info-circle::before { content: "\f431"; } +.bi-info-square-fill::before { content: "\f432"; } +.bi-info-square::before { content: "\f433"; } +.bi-info::before { content: "\f434"; } +.bi-input-cursor-text::before { content: "\f435"; } +.bi-input-cursor::before { content: "\f436"; } +.bi-instagram::before { content: "\f437"; } +.bi-intersect::before { content: "\f438"; } +.bi-journal-album::before { content: "\f439"; } +.bi-journal-arrow-down::before { content: "\f43a"; } +.bi-journal-arrow-up::before { content: "\f43b"; } +.bi-journal-bookmark-fill::before { content: "\f43c"; } +.bi-journal-bookmark::before { content: "\f43d"; } +.bi-journal-check::before { content: "\f43e"; } +.bi-journal-code::before { content: "\f43f"; } +.bi-journal-medical::before { content: "\f440"; } +.bi-journal-minus::before { content: "\f441"; } +.bi-journal-plus::before { content: "\f442"; } +.bi-journal-richtext::before { content: "\f443"; } +.bi-journal-text::before { content: "\f444"; } +.bi-journal-x::before { content: "\f445"; } +.bi-journal::before { content: "\f446"; } +.bi-journals::before { content: "\f447"; } +.bi-joystick::before { content: "\f448"; } +.bi-justify-left::before { content: "\f449"; } +.bi-justify-right::before { content: "\f44a"; } +.bi-justify::before { content: "\f44b"; } +.bi-kanban-fill::before { content: "\f44c"; } +.bi-kanban::before { content: "\f44d"; } +.bi-key-fill::before { content: "\f44e"; } +.bi-key::before { content: "\f44f"; } +.bi-keyboard-fill::before { content: "\f450"; } +.bi-keyboard::before { content: "\f451"; } +.bi-ladder::before { content: "\f452"; } +.bi-lamp-fill::before { content: "\f453"; } +.bi-lamp::before { content: "\f454"; } +.bi-laptop-fill::before { content: "\f455"; } +.bi-laptop::before { content: "\f456"; } +.bi-layer-backward::before { content: "\f457"; } +.bi-layer-forward::before { content: "\f458"; } +.bi-layers-fill::before { content: "\f459"; } +.bi-layers-half::before { content: "\f45a"; } +.bi-layers::before { content: "\f45b"; } +.bi-layout-sidebar-inset-reverse::before { content: "\f45c"; } +.bi-layout-sidebar-inset::before { content: "\f45d"; } +.bi-layout-sidebar-reverse::before { content: "\f45e"; } +.bi-layout-sidebar::before { content: "\f45f"; } +.bi-layout-split::before { content: "\f460"; } +.bi-layout-text-sidebar-reverse::before { content: "\f461"; } +.bi-layout-text-sidebar::before { content: "\f462"; } +.bi-layout-text-window-reverse::before { content: "\f463"; } +.bi-layout-text-window::before { content: "\f464"; } +.bi-layout-three-columns::before { content: "\f465"; } +.bi-layout-wtf::before { content: "\f466"; } +.bi-life-preserver::before { content: "\f467"; } +.bi-lightbulb-fill::before { content: "\f468"; } +.bi-lightbulb-off-fill::before { content: "\f469"; } +.bi-lightbulb-off::before { content: "\f46a"; } +.bi-lightbulb::before { content: "\f46b"; } +.bi-lightning-charge-fill::before { content: "\f46c"; } +.bi-lightning-charge::before { content: "\f46d"; } +.bi-lightning-fill::before { content: "\f46e"; } +.bi-lightning::before { content: "\f46f"; } +.bi-link-45deg::before { content: "\f470"; } +.bi-link::before { content: "\f471"; } +.bi-linkedin::before { content: "\f472"; } +.bi-list-check::before { content: "\f473"; } +.bi-list-nested::before { content: "\f474"; } +.bi-list-ol::before { content: "\f475"; } +.bi-list-stars::before { content: "\f476"; } +.bi-list-task::before { content: "\f477"; } +.bi-list-ul::before { content: "\f478"; } +.bi-list::before { content: "\f479"; } +.bi-lock-fill::before { content: "\f47a"; } +.bi-lock::before { content: "\f47b"; } +.bi-mailbox::before { content: "\f47c"; } +.bi-mailbox2::before { content: "\f47d"; } +.bi-map-fill::before { content: "\f47e"; } +.bi-map::before { content: "\f47f"; } +.bi-markdown-fill::before { content: "\f480"; } +.bi-markdown::before { content: "\f481"; } +.bi-mask::before { content: "\f482"; } +.bi-megaphone-fill::before { content: "\f483"; } +.bi-megaphone::before { content: "\f484"; } +.bi-menu-app-fill::before { content: "\f485"; } +.bi-menu-app::before { content: "\f486"; } +.bi-menu-button-fill::before { content: "\f487"; } +.bi-menu-button-wide-fill::before { content: "\f488"; } +.bi-menu-button-wide::before { content: "\f489"; } +.bi-menu-button::before { content: "\f48a"; } +.bi-menu-down::before { content: "\f48b"; } +.bi-menu-up::before { content: "\f48c"; } +.bi-mic-fill::before { content: "\f48d"; } +.bi-mic-mute-fill::before { content: "\f48e"; } +.bi-mic-mute::before { content: "\f48f"; } +.bi-mic::before { content: "\f490"; } +.bi-minecart-loaded::before { content: "\f491"; } +.bi-minecart::before { content: "\f492"; } +.bi-moisture::before { content: "\f493"; } +.bi-moon-fill::before { content: "\f494"; } +.bi-moon-stars-fill::before { content: "\f495"; } +.bi-moon-stars::before { content: "\f496"; } +.bi-moon::before { content: "\f497"; } +.bi-mouse-fill::before { content: "\f498"; } +.bi-mouse::before { content: "\f499"; } +.bi-mouse2-fill::before { content: "\f49a"; } +.bi-mouse2::before { content: "\f49b"; } +.bi-mouse3-fill::before { content: "\f49c"; } +.bi-mouse3::before { content: "\f49d"; } +.bi-music-note-beamed::before { content: "\f49e"; } +.bi-music-note-list::before { content: "\f49f"; } +.bi-music-note::before { content: "\f4a0"; } +.bi-music-player-fill::before { content: "\f4a1"; } +.bi-music-player::before { content: "\f4a2"; } +.bi-newspaper::before { content: "\f4a3"; } +.bi-node-minus-fill::before { content: "\f4a4"; } +.bi-node-minus::before { content: "\f4a5"; } +.bi-node-plus-fill::before { content: "\f4a6"; } +.bi-node-plus::before { content: "\f4a7"; } +.bi-nut-fill::before { content: "\f4a8"; } +.bi-nut::before { content: "\f4a9"; } +.bi-octagon-fill::before { content: "\f4aa"; } +.bi-octagon-half::before { content: "\f4ab"; } +.bi-octagon::before { content: "\f4ac"; } +.bi-option::before { content: "\f4ad"; } +.bi-outlet::before { content: "\f4ae"; } +.bi-paint-bucket::before { content: "\f4af"; } +.bi-palette-fill::before { content: "\f4b0"; } +.bi-palette::before { content: "\f4b1"; } +.bi-palette2::before { content: "\f4b2"; } +.bi-paperclip::before { content: "\f4b3"; } +.bi-paragraph::before { content: "\f4b4"; } +.bi-patch-check-fill::before { content: "\f4b5"; } +.bi-patch-check::before { content: "\f4b6"; } +.bi-patch-exclamation-fill::before { content: "\f4b7"; } +.bi-patch-exclamation::before { content: "\f4b8"; } +.bi-patch-minus-fill::before { content: "\f4b9"; } +.bi-patch-minus::before { content: "\f4ba"; } +.bi-patch-plus-fill::before { content: "\f4bb"; } +.bi-patch-plus::before { content: "\f4bc"; } +.bi-patch-question-fill::before { content: "\f4bd"; } +.bi-patch-question::before { content: "\f4be"; } +.bi-pause-btn-fill::before { content: "\f4bf"; } +.bi-pause-btn::before { content: "\f4c0"; } +.bi-pause-circle-fill::before { content: "\f4c1"; } +.bi-pause-circle::before { content: "\f4c2"; } +.bi-pause-fill::before { content: "\f4c3"; } +.bi-pause::before { content: "\f4c4"; } +.bi-peace-fill::before { content: "\f4c5"; } +.bi-peace::before { content: "\f4c6"; } +.bi-pen-fill::before { content: "\f4c7"; } +.bi-pen::before { content: "\f4c8"; } +.bi-pencil-fill::before { content: "\f4c9"; } +.bi-pencil-square::before { content: "\f4ca"; } +.bi-pencil::before { content: "\f4cb"; } +.bi-pentagon-fill::before { content: "\f4cc"; } +.bi-pentagon-half::before { content: "\f4cd"; } +.bi-pentagon::before { content: "\f4ce"; } +.bi-people-fill::before { content: "\f4cf"; } +.bi-people::before { content: "\f4d0"; } +.bi-percent::before { content: "\f4d1"; } +.bi-person-badge-fill::before { content: "\f4d2"; } +.bi-person-badge::before { content: "\f4d3"; } +.bi-person-bounding-box::before { content: "\f4d4"; } +.bi-person-check-fill::before { content: "\f4d5"; } +.bi-person-check::before { content: "\f4d6"; } +.bi-person-circle::before { content: "\f4d7"; } +.bi-person-dash-fill::before { content: "\f4d8"; } +.bi-person-dash::before { content: "\f4d9"; } +.bi-person-fill::before { content: "\f4da"; } +.bi-person-lines-fill::before { content: "\f4db"; } +.bi-person-plus-fill::before { content: "\f4dc"; } +.bi-person-plus::before { content: "\f4dd"; } +.bi-person-square::before { content: "\f4de"; } +.bi-person-x-fill::before { content: "\f4df"; } +.bi-person-x::before { content: "\f4e0"; } +.bi-person::before { content: "\f4e1"; } +.bi-phone-fill::before { content: "\f4e2"; } +.bi-phone-landscape-fill::before { content: "\f4e3"; } +.bi-phone-landscape::before { content: "\f4e4"; } +.bi-phone-vibrate-fill::before { content: "\f4e5"; } +.bi-phone-vibrate::before { content: "\f4e6"; } +.bi-phone::before { content: "\f4e7"; } +.bi-pie-chart-fill::before { content: "\f4e8"; } +.bi-pie-chart::before { content: "\f4e9"; } +.bi-pin-angle-fill::before { content: "\f4ea"; } +.bi-pin-angle::before { content: "\f4eb"; } +.bi-pin-fill::before { content: "\f4ec"; } +.bi-pin::before { content: "\f4ed"; } +.bi-pip-fill::before { content: "\f4ee"; } +.bi-pip::before { content: "\f4ef"; } +.bi-play-btn-fill::before { content: "\f4f0"; } +.bi-play-btn::before { content: "\f4f1"; } +.bi-play-circle-fill::before { content: "\f4f2"; } +.bi-play-circle::before { content: "\f4f3"; } +.bi-play-fill::before { content: "\f4f4"; } +.bi-play::before { content: "\f4f5"; } +.bi-plug-fill::before { content: "\f4f6"; } +.bi-plug::before { content: "\f4f7"; } +.bi-plus-circle-dotted::before { content: "\f4f8"; } +.bi-plus-circle-fill::before { content: "\f4f9"; } +.bi-plus-circle::before { content: "\f4fa"; } +.bi-plus-square-dotted::before { content: "\f4fb"; } +.bi-plus-square-fill::before { content: "\f4fc"; } +.bi-plus-square::before { content: "\f4fd"; } +.bi-plus::before { content: "\f4fe"; } +.bi-power::before { content: "\f4ff"; } +.bi-printer-fill::before { content: "\f500"; } +.bi-printer::before { content: "\f501"; } +.bi-puzzle-fill::before { content: "\f502"; } +.bi-puzzle::before { content: "\f503"; } +.bi-question-circle-fill::before { content: "\f504"; } +.bi-question-circle::before { content: "\f505"; } +.bi-question-diamond-fill::before { content: "\f506"; } +.bi-question-diamond::before { content: "\f507"; } +.bi-question-octagon-fill::before { content: "\f508"; } +.bi-question-octagon::before { content: "\f509"; } +.bi-question-square-fill::before { content: "\f50a"; } +.bi-question-square::before { content: "\f50b"; } +.bi-question::before { content: "\f50c"; } +.bi-rainbow::before { content: "\f50d"; } +.bi-receipt-cutoff::before { content: "\f50e"; } +.bi-receipt::before { content: "\f50f"; } +.bi-reception-0::before { content: "\f510"; } +.bi-reception-1::before { content: "\f511"; } +.bi-reception-2::before { content: "\f512"; } +.bi-reception-3::before { content: "\f513"; } +.bi-reception-4::before { content: "\f514"; } +.bi-record-btn-fill::before { content: "\f515"; } +.bi-record-btn::before { content: "\f516"; } +.bi-record-circle-fill::before { content: "\f517"; } +.bi-record-circle::before { content: "\f518"; } +.bi-record-fill::before { content: "\f519"; } +.bi-record::before { content: "\f51a"; } +.bi-record2-fill::before { content: "\f51b"; } +.bi-record2::before { content: "\f51c"; } +.bi-reply-all-fill::before { content: "\f51d"; } +.bi-reply-all::before { content: "\f51e"; } +.bi-reply-fill::before { content: "\f51f"; } +.bi-reply::before { content: "\f520"; } +.bi-rss-fill::before { content: "\f521"; } +.bi-rss::before { content: "\f522"; } +.bi-rulers::before { content: "\f523"; } +.bi-save-fill::before { content: "\f524"; } +.bi-save::before { content: "\f525"; } +.bi-save2-fill::before { content: "\f526"; } +.bi-save2::before { content: "\f527"; } +.bi-scissors::before { content: "\f528"; } +.bi-screwdriver::before { content: "\f529"; } +.bi-search::before { content: "\f52a"; } +.bi-segmented-nav::before { content: "\f52b"; } +.bi-server::before { content: "\f52c"; } +.bi-share-fill::before { content: "\f52d"; } +.bi-share::before { content: "\f52e"; } +.bi-shield-check::before { content: "\f52f"; } +.bi-shield-exclamation::before { content: "\f530"; } +.bi-shield-fill-check::before { content: "\f531"; } +.bi-shield-fill-exclamation::before { content: "\f532"; } +.bi-shield-fill-minus::before { content: "\f533"; } +.bi-shield-fill-plus::before { content: "\f534"; } +.bi-shield-fill-x::before { content: "\f535"; } +.bi-shield-fill::before { content: "\f536"; } +.bi-shield-lock-fill::before { content: "\f537"; } +.bi-shield-lock::before { content: "\f538"; } +.bi-shield-minus::before { content: "\f539"; } +.bi-shield-plus::before { content: "\f53a"; } +.bi-shield-shaded::before { content: "\f53b"; } +.bi-shield-slash-fill::before { content: "\f53c"; } +.bi-shield-slash::before { content: "\f53d"; } +.bi-shield-x::before { content: "\f53e"; } +.bi-shield::before { content: "\f53f"; } +.bi-shift-fill::before { content: "\f540"; } +.bi-shift::before { content: "\f541"; } +.bi-shop-window::before { content: "\f542"; } +.bi-shop::before { content: "\f543"; } +.bi-shuffle::before { content: "\f544"; } +.bi-signpost-2-fill::before { content: "\f545"; } +.bi-signpost-2::before { content: "\f546"; } +.bi-signpost-fill::before { content: "\f547"; } +.bi-signpost-split-fill::before { content: "\f548"; } +.bi-signpost-split::before { content: "\f549"; } +.bi-signpost::before { content: "\f54a"; } +.bi-sim-fill::before { content: "\f54b"; } +.bi-sim::before { content: "\f54c"; } +.bi-skip-backward-btn-fill::before { content: "\f54d"; } +.bi-skip-backward-btn::before { content: "\f54e"; } +.bi-skip-backward-circle-fill::before { content: "\f54f"; } +.bi-skip-backward-circle::before { content: "\f550"; } +.bi-skip-backward-fill::before { content: "\f551"; } +.bi-skip-backward::before { content: "\f552"; } +.bi-skip-end-btn-fill::before { content: "\f553"; } +.bi-skip-end-btn::before { content: "\f554"; } +.bi-skip-end-circle-fill::before { content: "\f555"; } +.bi-skip-end-circle::before { content: "\f556"; } +.bi-skip-end-fill::before { content: "\f557"; } +.bi-skip-end::before { content: "\f558"; } +.bi-skip-forward-btn-fill::before { content: "\f559"; } +.bi-skip-forward-btn::before { content: "\f55a"; } +.bi-skip-forward-circle-fill::before { content: "\f55b"; } +.bi-skip-forward-circle::before { content: "\f55c"; } +.bi-skip-forward-fill::before { content: "\f55d"; } +.bi-skip-forward::before { content: "\f55e"; } +.bi-skip-start-btn-fill::before { content: "\f55f"; } +.bi-skip-start-btn::before { content: "\f560"; } +.bi-skip-start-circle-fill::before { content: "\f561"; } +.bi-skip-start-circle::before { content: "\f562"; } +.bi-skip-start-fill::before { content: "\f563"; } +.bi-skip-start::before { content: "\f564"; } +.bi-slack::before { content: "\f565"; } +.bi-slash-circle-fill::before { content: "\f566"; } +.bi-slash-circle::before { content: "\f567"; } +.bi-slash-square-fill::before { content: "\f568"; } +.bi-slash-square::before { content: "\f569"; } +.bi-slash::before { content: "\f56a"; } +.bi-sliders::before { content: "\f56b"; } +.bi-smartwatch::before { content: "\f56c"; } +.bi-snow::before { content: "\f56d"; } +.bi-snow2::before { content: "\f56e"; } +.bi-snow3::before { content: "\f56f"; } +.bi-sort-alpha-down-alt::before { content: "\f570"; } +.bi-sort-alpha-down::before { content: "\f571"; } +.bi-sort-alpha-up-alt::before { content: "\f572"; } +.bi-sort-alpha-up::before { content: "\f573"; } +.bi-sort-down-alt::before { content: "\f574"; } +.bi-sort-down::before { content: "\f575"; } +.bi-sort-numeric-down-alt::before { content: "\f576"; } +.bi-sort-numeric-down::before { content: "\f577"; } +.bi-sort-numeric-up-alt::before { content: "\f578"; } +.bi-sort-numeric-up::before { content: "\f579"; } +.bi-sort-up-alt::before { content: "\f57a"; } +.bi-sort-up::before { content: "\f57b"; } +.bi-soundwave::before { content: "\f57c"; } +.bi-speaker-fill::before { content: "\f57d"; } +.bi-speaker::before { content: "\f57e"; } +.bi-speedometer::before { content: "\f57f"; } +.bi-speedometer2::before { content: "\f580"; } +.bi-spellcheck::before { content: "\f581"; } +.bi-square-fill::before { content: "\f582"; } +.bi-square-half::before { content: "\f583"; } +.bi-square::before { content: "\f584"; } +.bi-stack::before { content: "\f585"; } +.bi-star-fill::before { content: "\f586"; } +.bi-star-half::before { content: "\f587"; } +.bi-star::before { content: "\f588"; } +.bi-stars::before { content: "\f589"; } +.bi-stickies-fill::before { content: "\f58a"; } +.bi-stickies::before { content: "\f58b"; } +.bi-sticky-fill::before { content: "\f58c"; } +.bi-sticky::before { content: "\f58d"; } +.bi-stop-btn-fill::before { content: "\f58e"; } +.bi-stop-btn::before { content: "\f58f"; } +.bi-stop-circle-fill::before { content: "\f590"; } +.bi-stop-circle::before { content: "\f591"; } +.bi-stop-fill::before { content: "\f592"; } +.bi-stop::before { content: "\f593"; } +.bi-stoplights-fill::before { content: "\f594"; } +.bi-stoplights::before { content: "\f595"; } +.bi-stopwatch-fill::before { content: "\f596"; } +.bi-stopwatch::before { content: "\f597"; } +.bi-subtract::before { content: "\f598"; } +.bi-suit-club-fill::before { content: "\f599"; } +.bi-suit-club::before { content: "\f59a"; } +.bi-suit-diamond-fill::before { content: "\f59b"; } +.bi-suit-diamond::before { content: "\f59c"; } +.bi-suit-heart-fill::before { content: "\f59d"; } +.bi-suit-heart::before { content: "\f59e"; } +.bi-suit-spade-fill::before { content: "\f59f"; } +.bi-suit-spade::before { content: "\f5a0"; } +.bi-sun-fill::before { content: "\f5a1"; } +.bi-sun::before { content: "\f5a2"; } +.bi-sunglasses::before { content: "\f5a3"; } +.bi-sunrise-fill::before { content: "\f5a4"; } +.bi-sunrise::before { content: "\f5a5"; } +.bi-sunset-fill::before { content: "\f5a6"; } +.bi-sunset::before { content: "\f5a7"; } +.bi-symmetry-horizontal::before { content: "\f5a8"; } +.bi-symmetry-vertical::before { content: "\f5a9"; } +.bi-table::before { content: "\f5aa"; } +.bi-tablet-fill::before { content: "\f5ab"; } +.bi-tablet-landscape-fill::before { content: "\f5ac"; } +.bi-tablet-landscape::before { content: "\f5ad"; } +.bi-tablet::before { content: "\f5ae"; } +.bi-tag-fill::before { content: "\f5af"; } +.bi-tag::before { content: "\f5b0"; } +.bi-tags-fill::before { content: "\f5b1"; } +.bi-tags::before { content: "\f5b2"; } +.bi-telegram::before { content: "\f5b3"; } +.bi-telephone-fill::before { content: "\f5b4"; } +.bi-telephone-forward-fill::before { content: "\f5b5"; } +.bi-telephone-forward::before { content: "\f5b6"; } +.bi-telephone-inbound-fill::before { content: "\f5b7"; } +.bi-telephone-inbound::before { content: "\f5b8"; } +.bi-telephone-minus-fill::before { content: "\f5b9"; } +.bi-telephone-minus::before { content: "\f5ba"; } +.bi-telephone-outbound-fill::before { content: "\f5bb"; } +.bi-telephone-outbound::before { content: "\f5bc"; } +.bi-telephone-plus-fill::before { content: "\f5bd"; } +.bi-telephone-plus::before { content: "\f5be"; } +.bi-telephone-x-fill::before { content: "\f5bf"; } +.bi-telephone-x::before { content: "\f5c0"; } +.bi-telephone::before { content: "\f5c1"; } +.bi-terminal-fill::before { content: "\f5c2"; } +.bi-terminal::before { content: "\f5c3"; } +.bi-text-center::before { content: "\f5c4"; } +.bi-text-indent-left::before { content: "\f5c5"; } +.bi-text-indent-right::before { content: "\f5c6"; } +.bi-text-left::before { content: "\f5c7"; } +.bi-text-paragraph::before { content: "\f5c8"; } +.bi-text-right::before { content: "\f5c9"; } +.bi-textarea-resize::before { content: "\f5ca"; } +.bi-textarea-t::before { content: "\f5cb"; } +.bi-textarea::before { content: "\f5cc"; } +.bi-thermometer-half::before { content: "\f5cd"; } +.bi-thermometer-high::before { content: "\f5ce"; } +.bi-thermometer-low::before { content: "\f5cf"; } +.bi-thermometer-snow::before { content: "\f5d0"; } +.bi-thermometer-sun::before { content: "\f5d1"; } +.bi-thermometer::before { content: "\f5d2"; } +.bi-three-dots-vertical::before { content: "\f5d3"; } +.bi-three-dots::before { content: "\f5d4"; } +.bi-toggle-off::before { content: "\f5d5"; } +.bi-toggle-on::before { content: "\f5d6"; } +.bi-toggle2-off::before { content: "\f5d7"; } +.bi-toggle2-on::before { content: "\f5d8"; } +.bi-toggles::before { content: "\f5d9"; } +.bi-toggles2::before { content: "\f5da"; } +.bi-tools::before { content: "\f5db"; } +.bi-tornado::before { content: "\f5dc"; } +.bi-trash-fill::before { content: "\f5dd"; } +.bi-trash::before { content: "\f5de"; } +.bi-trash2-fill::before { content: "\f5df"; } +.bi-trash2::before { content: "\f5e0"; } +.bi-tree-fill::before { content: "\f5e1"; } +.bi-tree::before { content: "\f5e2"; } +.bi-triangle-fill::before { content: "\f5e3"; } +.bi-triangle-half::before { content: "\f5e4"; } +.bi-triangle::before { content: "\f5e5"; } +.bi-trophy-fill::before { content: "\f5e6"; } +.bi-trophy::before { content: "\f5e7"; } +.bi-tropical-storm::before { content: "\f5e8"; } +.bi-truck-flatbed::before { content: "\f5e9"; } +.bi-truck::before { content: "\f5ea"; } +.bi-tsunami::before { content: "\f5eb"; } +.bi-tv-fill::before { content: "\f5ec"; } +.bi-tv::before { content: "\f5ed"; } +.bi-twitch::before { content: "\f5ee"; } +.bi-twitter::before { content: "\f5ef"; } +.bi-type-bold::before { content: "\f5f0"; } +.bi-type-h1::before { content: "\f5f1"; } +.bi-type-h2::before { content: "\f5f2"; } +.bi-type-h3::before { content: "\f5f3"; } +.bi-type-italic::before { content: "\f5f4"; } +.bi-type-strikethrough::before { content: "\f5f5"; } +.bi-type-underline::before { content: "\f5f6"; } +.bi-type::before { content: "\f5f7"; } +.bi-ui-checks-grid::before { content: "\f5f8"; } +.bi-ui-checks::before { content: "\f5f9"; } +.bi-ui-radios-grid::before { content: "\f5fa"; } +.bi-ui-radios::before { content: "\f5fb"; } +.bi-umbrella-fill::before { content: "\f5fc"; } +.bi-umbrella::before { content: "\f5fd"; } +.bi-union::before { content: "\f5fe"; } +.bi-unlock-fill::before { content: "\f5ff"; } +.bi-unlock::before { content: "\f600"; } +.bi-upc-scan::before { content: "\f601"; } +.bi-upc::before { content: "\f602"; } +.bi-upload::before { content: "\f603"; } +.bi-vector-pen::before { content: "\f604"; } +.bi-view-list::before { content: "\f605"; } +.bi-view-stacked::before { content: "\f606"; } +.bi-vinyl-fill::before { content: "\f607"; } +.bi-vinyl::before { content: "\f608"; } +.bi-voicemail::before { content: "\f609"; } +.bi-volume-down-fill::before { content: "\f60a"; } +.bi-volume-down::before { content: "\f60b"; } +.bi-volume-mute-fill::before { content: "\f60c"; } +.bi-volume-mute::before { content: "\f60d"; } +.bi-volume-off-fill::before { content: "\f60e"; } +.bi-volume-off::before { content: "\f60f"; } +.bi-volume-up-fill::before { content: "\f610"; } +.bi-volume-up::before { content: "\f611"; } +.bi-vr::before { content: "\f612"; } +.bi-wallet-fill::before { content: "\f613"; } +.bi-wallet::before { content: "\f614"; } +.bi-wallet2::before { content: "\f615"; } +.bi-watch::before { content: "\f616"; } +.bi-water::before { content: "\f617"; } +.bi-whatsapp::before { content: "\f618"; } +.bi-wifi-1::before { content: "\f619"; } +.bi-wifi-2::before { content: "\f61a"; } +.bi-wifi-off::before { content: "\f61b"; } +.bi-wifi::before { content: "\f61c"; } +.bi-wind::before { content: "\f61d"; } +.bi-window-dock::before { content: "\f61e"; } +.bi-window-sidebar::before { content: "\f61f"; } +.bi-window::before { content: "\f620"; } +.bi-wrench::before { content: "\f621"; } +.bi-x-circle-fill::before { content: "\f622"; } +.bi-x-circle::before { content: "\f623"; } +.bi-x-diamond-fill::before { content: "\f624"; } +.bi-x-diamond::before { content: "\f625"; } +.bi-x-octagon-fill::before { content: "\f626"; } +.bi-x-octagon::before { content: "\f627"; } +.bi-x-square-fill::before { content: "\f628"; } +.bi-x-square::before { content: "\f629"; } +.bi-x::before { content: "\f62a"; } +.bi-youtube::before { content: "\f62b"; } +.bi-zoom-in::before { content: "\f62c"; } +.bi-zoom-out::before { content: "\f62d"; } +.bi-bank::before { content: "\f62e"; } +.bi-bank2::before { content: "\f62f"; } +.bi-bell-slash-fill::before { content: "\f630"; } +.bi-bell-slash::before { content: "\f631"; } +.bi-cash-coin::before { content: "\f632"; } +.bi-check-lg::before { content: "\f633"; } +.bi-coin::before { content: "\f634"; } +.bi-currency-bitcoin::before { content: "\f635"; } +.bi-currency-dollar::before { content: "\f636"; } +.bi-currency-euro::before { content: "\f637"; } +.bi-currency-exchange::before { content: "\f638"; } +.bi-currency-pound::before { content: "\f639"; } +.bi-currency-yen::before { content: "\f63a"; } +.bi-dash-lg::before { content: "\f63b"; } +.bi-exclamation-lg::before { content: "\f63c"; } +.bi-file-earmark-pdf-fill::before { content: "\f63d"; } +.bi-file-earmark-pdf::before { content: "\f63e"; } +.bi-file-pdf-fill::before { content: "\f63f"; } +.bi-file-pdf::before { content: "\f640"; } +.bi-gender-ambiguous::before { content: "\f641"; } +.bi-gender-female::before { content: "\f642"; } +.bi-gender-male::before { content: "\f643"; } +.bi-gender-trans::before { content: "\f644"; } +.bi-headset-vr::before { content: "\f645"; } +.bi-info-lg::before { content: "\f646"; } +.bi-mastodon::before { content: "\f647"; } +.bi-messenger::before { content: "\f648"; } +.bi-piggy-bank-fill::before { content: "\f649"; } +.bi-piggy-bank::before { content: "\f64a"; } +.bi-pin-map-fill::before { content: "\f64b"; } +.bi-pin-map::before { content: "\f64c"; } +.bi-plus-lg::before { content: "\f64d"; } +.bi-question-lg::before { content: "\f64e"; } +.bi-recycle::before { content: "\f64f"; } +.bi-reddit::before { content: "\f650"; } +.bi-safe-fill::before { content: "\f651"; } +.bi-safe2-fill::before { content: "\f652"; } +.bi-safe2::before { content: "\f653"; } +.bi-sd-card-fill::before { content: "\f654"; } +.bi-sd-card::before { content: "\f655"; } +.bi-skype::before { content: "\f656"; } +.bi-slash-lg::before { content: "\f657"; } +.bi-translate::before { content: "\f658"; } +.bi-x-lg::before { content: "\f659"; } +.bi-safe::before { content: "\f65a"; } +.bi-apple::before { content: "\f65b"; } +.bi-microsoft::before { content: "\f65d"; } +.bi-windows::before { content: "\f65e"; } +.bi-behance::before { content: "\f65c"; } +.bi-dribbble::before { content: "\f65f"; } +.bi-line::before { content: "\f660"; } +.bi-medium::before { content: "\f661"; } +.bi-paypal::before { content: "\f662"; } +.bi-pinterest::before { content: "\f663"; } +.bi-signal::before { content: "\f664"; } +.bi-snapchat::before { content: "\f665"; } +.bi-spotify::before { content: "\f666"; } +.bi-stack-overflow::before { content: "\f667"; } +.bi-strava::before { content: "\f668"; } +.bi-wordpress::before { content: "\f669"; } +.bi-vimeo::before { content: "\f66a"; } +.bi-activity::before { content: "\f66b"; } +.bi-easel2-fill::before { content: "\f66c"; } +.bi-easel2::before { content: "\f66d"; } +.bi-easel3-fill::before { content: "\f66e"; } +.bi-easel3::before { content: "\f66f"; } +.bi-fan::before { content: "\f670"; } +.bi-fingerprint::before { content: "\f671"; } +.bi-graph-down-arrow::before { content: "\f672"; } +.bi-graph-up-arrow::before { content: "\f673"; } +.bi-hypnotize::before { content: "\f674"; } +.bi-magic::before { content: "\f675"; } +.bi-person-rolodex::before { content: "\f676"; } +.bi-person-video::before { content: "\f677"; } +.bi-person-video2::before { content: "\f678"; } +.bi-person-video3::before { content: "\f679"; } +.bi-person-workspace::before { content: "\f67a"; } +.bi-radioactive::before { content: "\f67b"; } +.bi-webcam-fill::before { content: "\f67c"; } +.bi-webcam::before { content: "\f67d"; } +.bi-yin-yang::before { content: "\f67e"; } +.bi-bandaid-fill::before { content: "\f680"; } +.bi-bandaid::before { content: "\f681"; } +.bi-bluetooth::before { content: "\f682"; } +.bi-body-text::before { content: "\f683"; } +.bi-boombox::before { content: "\f684"; } +.bi-boxes::before { content: "\f685"; } +.bi-dpad-fill::before { content: "\f686"; } +.bi-dpad::before { content: "\f687"; } +.bi-ear-fill::before { content: "\f688"; } +.bi-ear::before { content: "\f689"; } +.bi-envelope-check-1::before { content: "\f68a"; } +.bi-envelope-check-fill::before { content: "\f68b"; } +.bi-envelope-check::before { content: "\f68c"; } +.bi-envelope-dash-1::before { content: "\f68d"; } +.bi-envelope-dash-fill::before { content: "\f68e"; } +.bi-envelope-dash::before { content: "\f68f"; } +.bi-envelope-exclamation-1::before { content: "\f690"; } +.bi-envelope-exclamation-fill::before { content: "\f691"; } +.bi-envelope-exclamation::before { content: "\f692"; } +.bi-envelope-plus-fill::before { content: "\f693"; } +.bi-envelope-plus::before { content: "\f694"; } +.bi-envelope-slash-1::before { content: "\f695"; } +.bi-envelope-slash-fill::before { content: "\f696"; } +.bi-envelope-slash::before { content: "\f697"; } +.bi-envelope-x-1::before { content: "\f698"; } +.bi-envelope-x-fill::before { content: "\f699"; } +.bi-envelope-x::before { content: "\f69a"; } +.bi-explicit-fill::before { content: "\f69b"; } +.bi-explicit::before { content: "\f69c"; } +.bi-git::before { content: "\f69d"; } +.bi-infinity::before { content: "\f69e"; } +.bi-list-columns-reverse::before { content: "\f69f"; } +.bi-list-columns::before { content: "\f6a0"; } +.bi-meta::before { content: "\f6a1"; } +.bi-mortorboard-fill::before { content: "\f6a2"; } +.bi-mortorboard::before { content: "\f6a3"; } +.bi-nintendo-switch::before { content: "\f6a4"; } +.bi-pc-display-horizontal::before { content: "\f6a5"; } +.bi-pc-display::before { content: "\f6a6"; } +.bi-pc-horizontal::before { content: "\f6a7"; } +.bi-pc::before { content: "\f6a8"; } +.bi-playstation::before { content: "\f6a9"; } +.bi-plus-slash-minus::before { content: "\f6aa"; } +.bi-projector-fill::before { content: "\f6ab"; } +.bi-projector::before { content: "\f6ac"; } +.bi-qr-code-scan::before { content: "\f6ad"; } +.bi-qr-code::before { content: "\f6ae"; } +.bi-quora::before { content: "\f6af"; } +.bi-quote::before { content: "\f6b0"; } +.bi-robot::before { content: "\f6b1"; } +.bi-send-check-fill::before { content: "\f6b2"; } +.bi-send-check::before { content: "\f6b3"; } +.bi-send-dash-fill::before { content: "\f6b4"; } +.bi-send-dash::before { content: "\f6b5"; } +.bi-send-exclamation-1::before { content: "\f6b6"; } +.bi-send-exclamation-fill::before { content: "\f6b7"; } +.bi-send-exclamation::before { content: "\f6b8"; } +.bi-send-fill::before { content: "\f6b9"; } +.bi-send-plus-fill::before { content: "\f6ba"; } +.bi-send-plus::before { content: "\f6bb"; } +.bi-send-slash-fill::before { content: "\f6bc"; } +.bi-send-slash::before { content: "\f6bd"; } +.bi-send-x-fill::before { content: "\f6be"; } +.bi-send-x::before { content: "\f6bf"; } +.bi-send::before { content: "\f6c0"; } +.bi-steam::before { content: "\f6c1"; } +.bi-terminal-dash-1::before { content: "\f6c2"; } +.bi-terminal-dash::before { content: "\f6c3"; } +.bi-terminal-plus::before { content: "\f6c4"; } +.bi-terminal-split::before { content: "\f6c5"; } +.bi-ticket-detailed-fill::before { content: "\f6c6"; } +.bi-ticket-detailed::before { content: "\f6c7"; } +.bi-ticket-fill::before { content: "\f6c8"; } +.bi-ticket-perforated-fill::before { content: "\f6c9"; } +.bi-ticket-perforated::before { content: "\f6ca"; } +.bi-ticket::before { content: "\f6cb"; } +.bi-tiktok::before { content: "\f6cc"; } +.bi-window-dash::before { content: "\f6cd"; } +.bi-window-desktop::before { content: "\f6ce"; } +.bi-window-fullscreen::before { content: "\f6cf"; } +.bi-window-plus::before { content: "\f6d0"; } +.bi-window-split::before { content: "\f6d1"; } +.bi-window-stack::before { content: "\f6d2"; } +.bi-window-x::before { content: "\f6d3"; } +.bi-xbox::before { content: "\f6d4"; } +.bi-ethernet::before { content: "\f6d5"; } +.bi-hdmi-fill::before { content: "\f6d6"; } +.bi-hdmi::before { content: "\f6d7"; } +.bi-usb-c-fill::before { content: "\f6d8"; } +.bi-usb-c::before { content: "\f6d9"; } +.bi-usb-fill::before { content: "\f6da"; } +.bi-usb-plug-fill::before { content: "\f6db"; } +.bi-usb-plug::before { content: "\f6dc"; } +.bi-usb-symbol::before { content: "\f6dd"; } +.bi-usb::before { content: "\f6de"; } +.bi-boombox-fill::before { content: "\f6df"; } +.bi-displayport-1::before { content: "\f6e0"; } +.bi-displayport::before { content: "\f6e1"; } +.bi-gpu-card::before { content: "\f6e2"; } +.bi-memory::before { content: "\f6e3"; } +.bi-modem-fill::before { content: "\f6e4"; } +.bi-modem::before { content: "\f6e5"; } +.bi-motherboard-fill::before { content: "\f6e6"; } +.bi-motherboard::before { content: "\f6e7"; } +.bi-optical-audio-fill::before { content: "\f6e8"; } +.bi-optical-audio::before { content: "\f6e9"; } +.bi-pci-card::before { content: "\f6ea"; } +.bi-router-fill::before { content: "\f6eb"; } +.bi-router::before { content: "\f6ec"; } +.bi-ssd-fill::before { content: "\f6ed"; } +.bi-ssd::before { content: "\f6ee"; } +.bi-thunderbolt-fill::before { content: "\f6ef"; } +.bi-thunderbolt::before { content: "\f6f0"; } +.bi-usb-drive-fill::before { content: "\f6f1"; } +.bi-usb-drive::before { content: "\f6f2"; } +.bi-usb-micro-fill::before { content: "\f6f3"; } +.bi-usb-micro::before { content: "\f6f4"; } +.bi-usb-mini-fill::before { content: "\f6f5"; } +.bi-usb-mini::before { content: "\f6f6"; } +.bi-cloud-haze2::before { content: "\f6f7"; } +.bi-device-hdd-fill::before { content: "\f6f8"; } +.bi-device-hdd::before { content: "\f6f9"; } +.bi-device-ssd-fill::before { content: "\f6fa"; } +.bi-device-ssd::before { content: "\f6fb"; } +.bi-displayport-fill::before { content: "\f6fc"; } +.bi-mortarboard-fill::before { content: "\f6fd"; } +.bi-mortarboard::before { content: "\f6fe"; } +.bi-terminal-x::before { content: "\f6ff"; } +.bi-arrow-through-heart-fill::before { content: "\f700"; } +.bi-arrow-through-heart::before { content: "\f701"; } +.bi-badge-sd-fill::before { content: "\f702"; } +.bi-badge-sd::before { content: "\f703"; } +.bi-bag-heart-fill::before { content: "\f704"; } +.bi-bag-heart::before { content: "\f705"; } +.bi-balloon-fill::before { content: "\f706"; } +.bi-balloon-heart-fill::before { content: "\f707"; } +.bi-balloon-heart::before { content: "\f708"; } +.bi-balloon::before { content: "\f709"; } +.bi-box2-fill::before { content: "\f70a"; } +.bi-box2-heart-fill::before { content: "\f70b"; } +.bi-box2-heart::before { content: "\f70c"; } +.bi-box2::before { content: "\f70d"; } +.bi-braces-asterisk::before { content: "\f70e"; } +.bi-calendar-heart-fill::before { content: "\f70f"; } +.bi-calendar-heart::before { content: "\f710"; } +.bi-calendar2-heart-fill::before { content: "\f711"; } +.bi-calendar2-heart::before { content: "\f712"; } +.bi-chat-heart-fill::before { content: "\f713"; } +.bi-chat-heart::before { content: "\f714"; } +.bi-chat-left-heart-fill::before { content: "\f715"; } +.bi-chat-left-heart::before { content: "\f716"; } +.bi-chat-right-heart-fill::before { content: "\f717"; } +.bi-chat-right-heart::before { content: "\f718"; } +.bi-chat-square-heart-fill::before { content: "\f719"; } +.bi-chat-square-heart::before { content: "\f71a"; } +.bi-clipboard-check-fill::before { content: "\f71b"; } +.bi-clipboard-data-fill::before { content: "\f71c"; } +.bi-clipboard-fill::before { content: "\f71d"; } +.bi-clipboard-heart-fill::before { content: "\f71e"; } +.bi-clipboard-heart::before { content: "\f71f"; } +.bi-clipboard-minus-fill::before { content: "\f720"; } +.bi-clipboard-plus-fill::before { content: "\f721"; } +.bi-clipboard-pulse::before { content: "\f722"; } +.bi-clipboard-x-fill::before { content: "\f723"; } +.bi-clipboard2-check-fill::before { content: "\f724"; } +.bi-clipboard2-check::before { content: "\f725"; } +.bi-clipboard2-data-fill::before { content: "\f726"; } +.bi-clipboard2-data::before { content: "\f727"; } +.bi-clipboard2-fill::before { content: "\f728"; } +.bi-clipboard2-heart-fill::before { content: "\f729"; } +.bi-clipboard2-heart::before { content: "\f72a"; } +.bi-clipboard2-minus-fill::before { content: "\f72b"; } +.bi-clipboard2-minus::before { content: "\f72c"; } +.bi-clipboard2-plus-fill::before { content: "\f72d"; } +.bi-clipboard2-plus::before { content: "\f72e"; } +.bi-clipboard2-pulse-fill::before { content: "\f72f"; } +.bi-clipboard2-pulse::before { content: "\f730"; } +.bi-clipboard2-x-fill::before { content: "\f731"; } +.bi-clipboard2-x::before { content: "\f732"; } +.bi-clipboard2::before { content: "\f733"; } +.bi-emoji-kiss-fill::before { content: "\f734"; } +.bi-emoji-kiss::before { content: "\f735"; } +.bi-envelope-heart-fill::before { content: "\f736"; } +.bi-envelope-heart::before { content: "\f737"; } +.bi-envelope-open-heart-fill::before { content: "\f738"; } +.bi-envelope-open-heart::before { content: "\f739"; } +.bi-envelope-paper-fill::before { content: "\f73a"; } +.bi-envelope-paper-heart-fill::before { content: "\f73b"; } +.bi-envelope-paper-heart::before { content: "\f73c"; } +.bi-envelope-paper::before { content: "\f73d"; } +.bi-filetype-aac::before { content: "\f73e"; } +.bi-filetype-ai::before { content: "\f73f"; } +.bi-filetype-bmp::before { content: "\f740"; } +.bi-filetype-cs::before { content: "\f741"; } +.bi-filetype-css::before { content: "\f742"; } +.bi-filetype-csv::before { content: "\f743"; } +.bi-filetype-doc::before { content: "\f744"; } +.bi-filetype-docx::before { content: "\f745"; } +.bi-filetype-exe::before { content: "\f746"; } +.bi-filetype-gif::before { content: "\f747"; } +.bi-filetype-heic::before { content: "\f748"; } +.bi-filetype-html::before { content: "\f749"; } +.bi-filetype-java::before { content: "\f74a"; } +.bi-filetype-jpg::before { content: "\f74b"; } +.bi-filetype-js::before { content: "\f74c"; } +.bi-filetype-jsx::before { content: "\f74d"; } +.bi-filetype-key::before { content: "\f74e"; } +.bi-filetype-m4p::before { content: "\f74f"; } +.bi-filetype-md::before { content: "\f750"; } +.bi-filetype-mdx::before { content: "\f751"; } +.bi-filetype-mov::before { content: "\f752"; } +.bi-filetype-mp3::before { content: "\f753"; } +.bi-filetype-mp4::before { content: "\f754"; } +.bi-filetype-otf::before { content: "\f755"; } +.bi-filetype-pdf::before { content: "\f756"; } +.bi-filetype-php::before { content: "\f757"; } +.bi-filetype-png::before { content: "\f758"; } +.bi-filetype-ppt-1::before { content: "\f759"; } +.bi-filetype-ppt::before { content: "\f75a"; } +.bi-filetype-psd::before { content: "\f75b"; } +.bi-filetype-py::before { content: "\f75c"; } +.bi-filetype-raw::before { content: "\f75d"; } +.bi-filetype-rb::before { content: "\f75e"; } +.bi-filetype-sass::before { content: "\f75f"; } +.bi-filetype-scss::before { content: "\f760"; } +.bi-filetype-sh::before { content: "\f761"; } +.bi-filetype-svg::before { content: "\f762"; } +.bi-filetype-tiff::before { content: "\f763"; } +.bi-filetype-tsx::before { content: "\f764"; } +.bi-filetype-ttf::before { content: "\f765"; } +.bi-filetype-txt::before { content: "\f766"; } +.bi-filetype-wav::before { content: "\f767"; } +.bi-filetype-woff::before { content: "\f768"; } +.bi-filetype-xls-1::before { content: "\f769"; } +.bi-filetype-xls::before { content: "\f76a"; } +.bi-filetype-xml::before { content: "\f76b"; } +.bi-filetype-yml::before { content: "\f76c"; } +.bi-heart-arrow::before { content: "\f76d"; } +.bi-heart-pulse-fill::before { content: "\f76e"; } +.bi-heart-pulse::before { content: "\f76f"; } +.bi-heartbreak-fill::before { content: "\f770"; } +.bi-heartbreak::before { content: "\f771"; } +.bi-hearts::before { content: "\f772"; } +.bi-hospital-fill::before { content: "\f773"; } +.bi-hospital::before { content: "\f774"; } +.bi-house-heart-fill::before { content: "\f775"; } +.bi-house-heart::before { content: "\f776"; } +.bi-incognito::before { content: "\f777"; } +.bi-magnet-fill::before { content: "\f778"; } +.bi-magnet::before { content: "\f779"; } +.bi-person-heart::before { content: "\f77a"; } +.bi-person-hearts::before { content: "\f77b"; } +.bi-phone-flip::before { content: "\f77c"; } +.bi-plugin::before { content: "\f77d"; } +.bi-postage-fill::before { content: "\f77e"; } +.bi-postage-heart-fill::before { content: "\f77f"; } +.bi-postage-heart::before { content: "\f780"; } +.bi-postage::before { content: "\f781"; } +.bi-postcard-fill::before { content: "\f782"; } +.bi-postcard-heart-fill::before { content: "\f783"; } +.bi-postcard-heart::before { content: "\f784"; } +.bi-postcard::before { content: "\f785"; } +.bi-search-heart-fill::before { content: "\f786"; } +.bi-search-heart::before { content: "\f787"; } +.bi-sliders2-vertical::before { content: "\f788"; } +.bi-sliders2::before { content: "\f789"; } +.bi-trash3-fill::before { content: "\f78a"; } +.bi-trash3::before { content: "\f78b"; } +.bi-valentine::before { content: "\f78c"; } +.bi-valentine2::before { content: "\f78d"; } +.bi-wrench-adjustable-circle-fill::before { content: "\f78e"; } +.bi-wrench-adjustable-circle::before { content: "\f78f"; } +.bi-wrench-adjustable::before { content: "\f790"; } +.bi-filetype-json::before { content: "\f791"; } +.bi-filetype-pptx::before { content: "\f792"; } +.bi-filetype-xlsx::before { content: "\f793"; } +.bi-1-circle-1::before { content: "\f794"; } +.bi-1-circle-fill-1::before { content: "\f795"; } +.bi-1-circle-fill::before { content: "\f796"; } +.bi-1-circle::before { content: "\f797"; } +.bi-1-square-fill::before { content: "\f798"; } +.bi-1-square::before { content: "\f799"; } +.bi-2-circle-1::before { content: "\f79a"; } +.bi-2-circle-fill-1::before { content: "\f79b"; } +.bi-2-circle-fill::before { content: "\f79c"; } +.bi-2-circle::before { content: "\f79d"; } +.bi-2-square-fill::before { content: "\f79e"; } +.bi-2-square::before { content: "\f79f"; } +.bi-3-circle-1::before { content: "\f7a0"; } +.bi-3-circle-fill-1::before { content: "\f7a1"; } +.bi-3-circle-fill::before { content: "\f7a2"; } +.bi-3-circle::before { content: "\f7a3"; } +.bi-3-square-fill::before { content: "\f7a4"; } +.bi-3-square::before { content: "\f7a5"; } +.bi-4-circle-1::before { content: "\f7a6"; } +.bi-4-circle-fill-1::before { content: "\f7a7"; } +.bi-4-circle-fill::before { content: "\f7a8"; } +.bi-4-circle::before { content: "\f7a9"; } +.bi-4-square-fill::before { content: "\f7aa"; } +.bi-4-square::before { content: "\f7ab"; } +.bi-5-circle-1::before { content: "\f7ac"; } +.bi-5-circle-fill-1::before { content: "\f7ad"; } +.bi-5-circle-fill::before { content: "\f7ae"; } +.bi-5-circle::before { content: "\f7af"; } +.bi-5-square-fill::before { content: "\f7b0"; } +.bi-5-square::before { content: "\f7b1"; } +.bi-6-circle-1::before { content: "\f7b2"; } +.bi-6-circle-fill-1::before { content: "\f7b3"; } +.bi-6-circle-fill::before { content: "\f7b4"; } +.bi-6-circle::before { content: "\f7b5"; } +.bi-6-square-fill::before { content: "\f7b6"; } +.bi-6-square::before { content: "\f7b7"; } +.bi-7-circle-1::before { content: "\f7b8"; } +.bi-7-circle-fill-1::before { content: "\f7b9"; } +.bi-7-circle-fill::before { content: "\f7ba"; } +.bi-7-circle::before { content: "\f7bb"; } +.bi-7-square-fill::before { content: "\f7bc"; } +.bi-7-square::before { content: "\f7bd"; } +.bi-8-circle-1::before { content: "\f7be"; } +.bi-8-circle-fill-1::before { content: "\f7bf"; } +.bi-8-circle-fill::before { content: "\f7c0"; } +.bi-8-circle::before { content: "\f7c1"; } +.bi-8-square-fill::before { content: "\f7c2"; } +.bi-8-square::before { content: "\f7c3"; } +.bi-9-circle-1::before { content: "\f7c4"; } +.bi-9-circle-fill-1::before { content: "\f7c5"; } +.bi-9-circle-fill::before { content: "\f7c6"; } +.bi-9-circle::before { content: "\f7c7"; } +.bi-9-square-fill::before { content: "\f7c8"; } +.bi-9-square::before { content: "\f7c9"; } +.bi-airplane-engines-fill::before { content: "\f7ca"; } +.bi-airplane-engines::before { content: "\f7cb"; } +.bi-airplane-fill::before { content: "\f7cc"; } +.bi-airplane::before { content: "\f7cd"; } +.bi-alexa::before { content: "\f7ce"; } +.bi-alipay::before { content: "\f7cf"; } +.bi-android::before { content: "\f7d0"; } +.bi-android2::before { content: "\f7d1"; } +.bi-box-fill::before { content: "\f7d2"; } +.bi-box-seam-fill::before { content: "\f7d3"; } +.bi-browser-chrome::before { content: "\f7d4"; } +.bi-browser-edge::before { content: "\f7d5"; } +.bi-browser-firefox::before { content: "\f7d6"; } +.bi-browser-safari::before { content: "\f7d7"; } +.bi-c-circle-1::before { content: "\f7d8"; } +.bi-c-circle-fill-1::before { content: "\f7d9"; } +.bi-c-circle-fill::before { content: "\f7da"; } +.bi-c-circle::before { content: "\f7db"; } +.bi-c-square-fill::before { content: "\f7dc"; } +.bi-c-square::before { content: "\f7dd"; } +.bi-capsule-pill::before { content: "\f7de"; } +.bi-capsule::before { content: "\f7df"; } +.bi-car-front-fill::before { content: "\f7e0"; } +.bi-car-front::before { content: "\f7e1"; } +.bi-cassette-fill::before { content: "\f7e2"; } +.bi-cassette::before { content: "\f7e3"; } +.bi-cc-circle-1::before { content: "\f7e4"; } +.bi-cc-circle-fill-1::before { content: "\f7e5"; } +.bi-cc-circle-fill::before { content: "\f7e6"; } +.bi-cc-circle::before { content: "\f7e7"; } +.bi-cc-square-fill::before { content: "\f7e8"; } +.bi-cc-square::before { content: "\f7e9"; } +.bi-cup-hot-fill::before { content: "\f7ea"; } +.bi-cup-hot::before { content: "\f7eb"; } +.bi-currency-rupee::before { content: "\f7ec"; } +.bi-dropbox::before { content: "\f7ed"; } +.bi-escape::before { content: "\f7ee"; } +.bi-fast-forward-btn-fill::before { content: "\f7ef"; } +.bi-fast-forward-btn::before { content: "\f7f0"; } +.bi-fast-forward-circle-fill::before { content: "\f7f1"; } +.bi-fast-forward-circle::before { content: "\f7f2"; } +.bi-fast-forward-fill::before { content: "\f7f3"; } +.bi-fast-forward::before { content: "\f7f4"; } +.bi-filetype-sql::before { content: "\f7f5"; } +.bi-fire::before { content: "\f7f6"; } +.bi-google-play::before { content: "\f7f7"; } +.bi-h-circle-1::before { content: "\f7f8"; } +.bi-h-circle-fill-1::before { content: "\f7f9"; } +.bi-h-circle-fill::before { content: "\f7fa"; } +.bi-h-circle::before { content: "\f7fb"; } +.bi-h-square-fill::before { content: "\f7fc"; } +.bi-h-square::before { content: "\f7fd"; } +.bi-indent::before { content: "\f7fe"; } +.bi-lungs-fill::before { content: "\f7ff"; } +.bi-lungs::before { content: "\f800"; } +.bi-microsoft-teams::before { content: "\f801"; } +.bi-p-circle-1::before { content: "\f802"; } +.bi-p-circle-fill-1::before { content: "\f803"; } +.bi-p-circle-fill::before { content: "\f804"; } +.bi-p-circle::before { content: "\f805"; } +.bi-p-square-fill::before { content: "\f806"; } +.bi-p-square::before { content: "\f807"; } +.bi-pass-fill::before { content: "\f808"; } +.bi-pass::before { content: "\f809"; } +.bi-prescription::before { content: "\f80a"; } +.bi-prescription2::before { content: "\f80b"; } +.bi-r-circle-1::before { content: "\f80c"; } +.bi-r-circle-fill-1::before { content: "\f80d"; } +.bi-r-circle-fill::before { content: "\f80e"; } +.bi-r-circle::before { content: "\f80f"; } +.bi-r-square-fill::before { content: "\f810"; } +.bi-r-square::before { content: "\f811"; } +.bi-repeat-1::before { content: "\f812"; } +.bi-repeat::before { content: "\f813"; } +.bi-rewind-btn-fill::before { content: "\f814"; } +.bi-rewind-btn::before { content: "\f815"; } +.bi-rewind-circle-fill::before { content: "\f816"; } +.bi-rewind-circle::before { content: "\f817"; } +.bi-rewind-fill::before { content: "\f818"; } +.bi-rewind::before { content: "\f819"; } +.bi-train-freight-front-fill::before { content: "\f81a"; } +.bi-train-freight-front::before { content: "\f81b"; } +.bi-train-front-fill::before { content: "\f81c"; } +.bi-train-front::before { content: "\f81d"; } +.bi-train-lightrail-front-fill::before { content: "\f81e"; } +.bi-train-lightrail-front::before { content: "\f81f"; } +.bi-truck-front-fill::before { content: "\f820"; } +.bi-truck-front::before { content: "\f821"; } +.bi-ubuntu::before { content: "\f822"; } +.bi-unindent::before { content: "\f823"; } +.bi-unity::before { content: "\f824"; } +.bi-universal-access-circle::before { content: "\f825"; } +.bi-universal-access::before { content: "\f826"; } +.bi-virus::before { content: "\f827"; } +.bi-virus2::before { content: "\f828"; } +.bi-wechat::before { content: "\f829"; } +.bi-yelp::before { content: "\f82a"; } +.bi-sign-stop-fill::before { content: "\f82b"; } +.bi-sign-stop-lights-fill::before { content: "\f82c"; } +.bi-sign-stop-lights::before { content: "\f82d"; } +.bi-sign-stop::before { content: "\f82e"; } +.bi-sign-turn-left-fill::before { content: "\f82f"; } +.bi-sign-turn-left::before { content: "\f830"; } +.bi-sign-turn-right-fill::before { content: "\f831"; } +.bi-sign-turn-right::before { content: "\f832"; } +.bi-sign-turn-slight-left-fill::before { content: "\f833"; } +.bi-sign-turn-slight-left::before { content: "\f834"; } +.bi-sign-turn-slight-right-fill::before { content: "\f835"; } +.bi-sign-turn-slight-right::before { content: "\f836"; } +.bi-sign-yield-fill::before { content: "\f837"; } +.bi-sign-yield::before { content: "\f838"; } +.bi-ev-station-fill::before { content: "\f839"; } +.bi-ev-station::before { content: "\f83a"; } +.bi-fuel-pump-diesel-fill::before { content: "\f83b"; } +.bi-fuel-pump-diesel::before { content: "\f83c"; } +.bi-fuel-pump-fill::before { content: "\f83d"; } +.bi-fuel-pump::before { content: "\f83e"; } +.bi-0-circle-fill::before { content: "\f83f"; } +.bi-0-circle::before { content: "\f840"; } +.bi-0-square-fill::before { content: "\f841"; } +.bi-0-square::before { content: "\f842"; } +.bi-rocket-fill::before { content: "\f843"; } +.bi-rocket-takeoff-fill::before { content: "\f844"; } +.bi-rocket-takeoff::before { content: "\f845"; } +.bi-rocket::before { content: "\f846"; } +.bi-stripe::before { content: "\f847"; } +.bi-subscript::before { content: "\f848"; } +.bi-superscript::before { content: "\f849"; } +.bi-trello::before { content: "\f84a"; } +.bi-envelope-at-fill::before { content: "\f84b"; } +.bi-envelope-at::before { content: "\f84c"; } +.bi-regex::before { content: "\f84d"; } +.bi-text-wrap::before { content: "\f84e"; } +.bi-sign-dead-end-fill::before { content: "\f84f"; } +.bi-sign-dead-end::before { content: "\f850"; } +.bi-sign-do-not-enter-fill::before { content: "\f851"; } +.bi-sign-do-not-enter::before { content: "\f852"; } +.bi-sign-intersection-fill::before { content: "\f853"; } +.bi-sign-intersection-side-fill::before { content: "\f854"; } +.bi-sign-intersection-side::before { content: "\f855"; } +.bi-sign-intersection-t-fill::before { content: "\f856"; } +.bi-sign-intersection-t::before { content: "\f857"; } +.bi-sign-intersection-y-fill::before { content: "\f858"; } +.bi-sign-intersection-y::before { content: "\f859"; } +.bi-sign-intersection::before { content: "\f85a"; } +.bi-sign-merge-left-fill::before { content: "\f85b"; } +.bi-sign-merge-left::before { content: "\f85c"; } +.bi-sign-merge-right-fill::before { content: "\f85d"; } +.bi-sign-merge-right::before { content: "\f85e"; } +.bi-sign-no-left-turn-fill::before { content: "\f85f"; } +.bi-sign-no-left-turn::before { content: "\f860"; } +.bi-sign-no-parking-fill::before { content: "\f861"; } +.bi-sign-no-parking::before { content: "\f862"; } +.bi-sign-no-right-turn-fill::before { content: "\f863"; } +.bi-sign-no-right-turn::before { content: "\f864"; } +.bi-sign-railroad-fill::before { content: "\f865"; } +.bi-sign-railroad::before { content: "\f866"; } +.bi-building-add::before { content: "\f867"; } +.bi-building-check::before { content: "\f868"; } +.bi-building-dash::before { content: "\f869"; } +.bi-building-down::before { content: "\f86a"; } +.bi-building-exclamation::before { content: "\f86b"; } +.bi-building-fill-add::before { content: "\f86c"; } +.bi-building-fill-check::before { content: "\f86d"; } +.bi-building-fill-dash::before { content: "\f86e"; } +.bi-building-fill-down::before { content: "\f86f"; } +.bi-building-fill-exclamation::before { content: "\f870"; } +.bi-building-fill-gear::before { content: "\f871"; } +.bi-building-fill-lock::before { content: "\f872"; } +.bi-building-fill-slash::before { content: "\f873"; } +.bi-building-fill-up::before { content: "\f874"; } +.bi-building-fill-x::before { content: "\f875"; } +.bi-building-fill::before { content: "\f876"; } +.bi-building-gear::before { content: "\f877"; } +.bi-building-lock::before { content: "\f878"; } +.bi-building-slash::before { content: "\f879"; } +.bi-building-up::before { content: "\f87a"; } +.bi-building-x::before { content: "\f87b"; } +.bi-buildings-fill::before { content: "\f87c"; } +.bi-buildings::before { content: "\f87d"; } +.bi-bus-front-fill::before { content: "\f87e"; } +.bi-bus-front::before { content: "\f87f"; } +.bi-ev-front-fill::before { content: "\f880"; } +.bi-ev-front::before { content: "\f881"; } +.bi-globe-americas::before { content: "\f882"; } +.bi-globe-asia-australia::before { content: "\f883"; } +.bi-globe-central-south-asia::before { content: "\f884"; } +.bi-globe-europe-africa::before { content: "\f885"; } +.bi-house-add-fill::before { content: "\f886"; } +.bi-house-add::before { content: "\f887"; } +.bi-house-check-fill::before { content: "\f888"; } +.bi-house-check::before { content: "\f889"; } +.bi-house-dash-fill::before { content: "\f88a"; } +.bi-house-dash::before { content: "\f88b"; } +.bi-house-down-fill::before { content: "\f88c"; } +.bi-house-down::before { content: "\f88d"; } +.bi-house-exclamation-fill::before { content: "\f88e"; } +.bi-house-exclamation::before { content: "\f88f"; } +.bi-house-gear-fill::before { content: "\f890"; } +.bi-house-gear::before { content: "\f891"; } +.bi-house-lock-fill::before { content: "\f892"; } +.bi-house-lock::before { content: "\f893"; } +.bi-house-slash-fill::before { content: "\f894"; } +.bi-house-slash::before { content: "\f895"; } +.bi-house-up-fill::before { content: "\f896"; } +.bi-house-up::before { content: "\f897"; } +.bi-house-x-fill::before { content: "\f898"; } +.bi-house-x::before { content: "\f899"; } +.bi-person-add::before { content: "\f89a"; } +.bi-person-down::before { content: "\f89b"; } +.bi-person-exclamation::before { content: "\f89c"; } +.bi-person-fill-add::before { content: "\f89d"; } +.bi-person-fill-check::before { content: "\f89e"; } +.bi-person-fill-dash::before { content: "\f89f"; } +.bi-person-fill-down::before { content: "\f8a0"; } +.bi-person-fill-exclamation::before { content: "\f8a1"; } +.bi-person-fill-gear::before { content: "\f8a2"; } +.bi-person-fill-lock::before { content: "\f8a3"; } +.bi-person-fill-slash::before { content: "\f8a4"; } +.bi-person-fill-up::before { content: "\f8a5"; } +.bi-person-fill-x::before { content: "\f8a6"; } +.bi-person-gear::before { content: "\f8a7"; } +.bi-person-lock::before { content: "\f8a8"; } +.bi-person-slash::before { content: "\f8a9"; } +.bi-person-up::before { content: "\f8aa"; } +.bi-scooter::before { content: "\f8ab"; } +.bi-taxi-front-fill::before { content: "\f8ac"; } +.bi-taxi-front::before { content: "\f8ad"; } +.bi-amd::before { content: "\f8ae"; } +.bi-database-add::before { content: "\f8af"; } +.bi-database-check::before { content: "\f8b0"; } +.bi-database-dash::before { content: "\f8b1"; } +.bi-database-down::before { content: "\f8b2"; } +.bi-database-exclamation::before { content: "\f8b3"; } +.bi-database-fill-add::before { content: "\f8b4"; } +.bi-database-fill-check::before { content: "\f8b5"; } +.bi-database-fill-dash::before { content: "\f8b6"; } +.bi-database-fill-down::before { content: "\f8b7"; } +.bi-database-fill-exclamation::before { content: "\f8b8"; } +.bi-database-fill-gear::before { content: "\f8b9"; } +.bi-database-fill-lock::before { content: "\f8ba"; } +.bi-database-fill-slash::before { content: "\f8bb"; } +.bi-database-fill-up::before { content: "\f8bc"; } +.bi-database-fill-x::before { content: "\f8bd"; } +.bi-database-fill::before { content: "\f8be"; } +.bi-database-gear::before { content: "\f8bf"; } +.bi-database-lock::before { content: "\f8c0"; } +.bi-database-slash::before { content: "\f8c1"; } +.bi-database-up::before { content: "\f8c2"; } +.bi-database-x::before { content: "\f8c3"; } +.bi-database::before { content: "\f8c4"; } +.bi-houses-fill::before { content: "\f8c5"; } +.bi-houses::before { content: "\f8c6"; } +.bi-nvidia::before { content: "\f8c7"; } +.bi-person-vcard-fill::before { content: "\f8c8"; } +.bi-person-vcard::before { content: "\f8c9"; } +.bi-sina-weibo::before { content: "\f8ca"; } +.bi-tencent-qq::before { content: "\f8cb"; } +.bi-wikipedia::before { content: "\f8cc"; } diff --git a/_proc/_docs/site_libs/bootstrap/bootstrap-icons.woff b/_proc/_docs/site_libs/bootstrap/bootstrap-icons.woff new file mode 100644 index 0000000000000000000000000000000000000000..18d21d457558d4dc2e231a8f6ee585fada9c6bab Binary files /dev/null and b/_proc/_docs/site_libs/bootstrap/bootstrap-icons.woff differ diff --git a/_proc/_docs/site_libs/bootstrap/bootstrap.min.css b/_proc/_docs/site_libs/bootstrap/bootstrap.min.css new file mode 100644 index 0000000000000000000000000000000000000000..30038d1d9e3a773f499d6e8d97212cc3dd53850f --- /dev/null +++ b/_proc/_docs/site_libs/bootstrap/bootstrap.min.css @@ -0,0 +1,10 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors + * Copyright 2011-2021 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */@import"https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@300;400;700&display=swap";:root{--bs-blue: #2780e3;--bs-indigo: #6610f2;--bs-purple: #613d7c;--bs-pink: #e83e8c;--bs-red: #ff0039;--bs-orange: #f0ad4e;--bs-yellow: #ff7518;--bs-green: #3fb618;--bs-teal: #20c997;--bs-cyan: #9954bb;--bs-white: #fff;--bs-gray: #6c757d;--bs-gray-dark: #373a3c;--bs-gray-100: #f8f9fa;--bs-gray-200: #e9ecef;--bs-gray-300: #dee2e6;--bs-gray-400: #ced4da;--bs-gray-500: #adb5bd;--bs-gray-600: #6c757d;--bs-gray-700: #495057;--bs-gray-800: #373a3c;--bs-gray-900: #212529;--bs-default: #373a3c;--bs-primary: #2780e3;--bs-secondary: #373a3c;--bs-success: #3fb618;--bs-info: #9954bb;--bs-warning: #ff7518;--bs-danger: #ff0039;--bs-light: #f8f9fa;--bs-dark: #373a3c;--bs-default-rgb: 55, 58, 60;--bs-primary-rgb: 39, 128, 227;--bs-secondary-rgb: 55, 58, 60;--bs-success-rgb: 63, 182, 24;--bs-info-rgb: 153, 84, 187;--bs-warning-rgb: 255, 117, 24;--bs-danger-rgb: 255, 0, 57;--bs-light-rgb: 248, 249, 250;--bs-dark-rgb: 55, 58, 60;--bs-white-rgb: 255, 255, 255;--bs-black-rgb: 0, 0, 0;--bs-body-color-rgb: 55, 58, 60;--bs-body-bg-rgb: 255, 255, 255;--bs-font-sans-serif: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));--bs-root-font-size: 17px;--bs-body-font-family: var(--bs-font-sans-serif);--bs-body-font-size: 1rem;--bs-body-font-weight: 400;--bs-body-line-height: 1.5;--bs-body-color: #373a3c;--bs-body-bg: #fff}*,*::before,*::after{box-sizing:border-box}:root{font-size:var(--bs-root-font-size)}body{margin:0;font-family:var(--bs-body-font-family);font-size:var(--bs-body-font-size);font-weight:var(--bs-body-font-weight);line-height:var(--bs-body-line-height);color:var(--bs-body-color);text-align:var(--bs-body-text-align);background-color:var(--bs-body-bg);-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}h6,.h6,h5,.h5,h4,.h4,h3,.h3,h2,.h2,h1,.h1{margin-top:0;margin-bottom:.5rem;font-weight:400;line-height:1.2}h1,.h1{font-size:calc(1.325rem + 0.9vw)}@media(min-width: 1200px){h1,.h1{font-size:2rem}}h2,.h2{font-size:calc(1.29rem + 0.48vw)}@media(min-width: 1200px){h2,.h2{font-size:1.65rem}}h3,.h3{font-size:calc(1.27rem + 0.24vw)}@media(min-width: 1200px){h3,.h3{font-size:1.45rem}}h4,.h4{font-size:1.25rem}h5,.h5{font-size:1.1rem}h6,.h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[title],abbr[data-bs-original-title]{text-decoration:underline dotted;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;-ms-text-decoration:underline dotted;-o-text-decoration:underline dotted;cursor:help;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}ol,ul,dl{margin-top:0;margin-bottom:1rem}ol ol,ul ul,ol ul,ul ol{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem;padding:.625rem 1.25rem;border-left:.25rem solid #e9ecef}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}b,strong{font-weight:bolder}small,.small{font-size:0.875em}mark,.mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:0.75em;line-height:0;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}a{color:#2780e3;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}a:hover{color:#1f66b6}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}pre,code,kbd,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr /* rtl:ignore */;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:0.875em;color:#000;background-color:#f7f7f7;padding:.5rem;border:1px solid #dee2e6}pre code{background-color:rgba(0,0,0,0);font-size:inherit;color:inherit;word-break:normal}code{font-size:0.875em;color:#9753b8;background-color:#f7f7f7;padding:.125rem .25rem;word-wrap:break-word}a>code{color:inherit}kbd{padding:.4rem .4rem;font-size:0.875em;color:#fff;background-color:#212529}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}thead,tbody,tfoot,tr,td,th{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}input,button,select,optgroup,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button:not(:disabled),[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + 0.3vw);line-height:inherit}@media(min-width: 1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-text,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none !important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media(min-width: 1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:0.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:0.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:0.875em;color:#6c757d}.grid{display:grid;grid-template-rows:repeat(var(--bs-rows, 1), 1fr);grid-template-columns:repeat(var(--bs-columns, 12), 1fr);gap:var(--bs-gap, 1.5rem)}.grid .g-col-1{grid-column:auto/span 1}.grid .g-col-2{grid-column:auto/span 2}.grid .g-col-3{grid-column:auto/span 3}.grid .g-col-4{grid-column:auto/span 4}.grid .g-col-5{grid-column:auto/span 5}.grid .g-col-6{grid-column:auto/span 6}.grid .g-col-7{grid-column:auto/span 7}.grid .g-col-8{grid-column:auto/span 8}.grid .g-col-9{grid-column:auto/span 9}.grid .g-col-10{grid-column:auto/span 10}.grid .g-col-11{grid-column:auto/span 11}.grid .g-col-12{grid-column:auto/span 12}.grid .g-start-1{grid-column-start:1}.grid .g-start-2{grid-column-start:2}.grid .g-start-3{grid-column-start:3}.grid .g-start-4{grid-column-start:4}.grid .g-start-5{grid-column-start:5}.grid .g-start-6{grid-column-start:6}.grid .g-start-7{grid-column-start:7}.grid .g-start-8{grid-column-start:8}.grid .g-start-9{grid-column-start:9}.grid .g-start-10{grid-column-start:10}.grid .g-start-11{grid-column-start:11}@media(min-width: 576px){.grid .g-col-sm-1{grid-column:auto/span 1}.grid .g-col-sm-2{grid-column:auto/span 2}.grid .g-col-sm-3{grid-column:auto/span 3}.grid .g-col-sm-4{grid-column:auto/span 4}.grid .g-col-sm-5{grid-column:auto/span 5}.grid .g-col-sm-6{grid-column:auto/span 6}.grid .g-col-sm-7{grid-column:auto/span 7}.grid .g-col-sm-8{grid-column:auto/span 8}.grid .g-col-sm-9{grid-column:auto/span 9}.grid .g-col-sm-10{grid-column:auto/span 10}.grid .g-col-sm-11{grid-column:auto/span 11}.grid .g-col-sm-12{grid-column:auto/span 12}.grid .g-start-sm-1{grid-column-start:1}.grid .g-start-sm-2{grid-column-start:2}.grid .g-start-sm-3{grid-column-start:3}.grid .g-start-sm-4{grid-column-start:4}.grid .g-start-sm-5{grid-column-start:5}.grid .g-start-sm-6{grid-column-start:6}.grid .g-start-sm-7{grid-column-start:7}.grid .g-start-sm-8{grid-column-start:8}.grid .g-start-sm-9{grid-column-start:9}.grid .g-start-sm-10{grid-column-start:10}.grid .g-start-sm-11{grid-column-start:11}}@media(min-width: 768px){.grid .g-col-md-1{grid-column:auto/span 1}.grid .g-col-md-2{grid-column:auto/span 2}.grid .g-col-md-3{grid-column:auto/span 3}.grid .g-col-md-4{grid-column:auto/span 4}.grid .g-col-md-5{grid-column:auto/span 5}.grid .g-col-md-6{grid-column:auto/span 6}.grid .g-col-md-7{grid-column:auto/span 7}.grid .g-col-md-8{grid-column:auto/span 8}.grid .g-col-md-9{grid-column:auto/span 9}.grid .g-col-md-10{grid-column:auto/span 10}.grid .g-col-md-11{grid-column:auto/span 11}.grid .g-col-md-12{grid-column:auto/span 12}.grid .g-start-md-1{grid-column-start:1}.grid .g-start-md-2{grid-column-start:2}.grid .g-start-md-3{grid-column-start:3}.grid .g-start-md-4{grid-column-start:4}.grid .g-start-md-5{grid-column-start:5}.grid .g-start-md-6{grid-column-start:6}.grid .g-start-md-7{grid-column-start:7}.grid .g-start-md-8{grid-column-start:8}.grid .g-start-md-9{grid-column-start:9}.grid .g-start-md-10{grid-column-start:10}.grid .g-start-md-11{grid-column-start:11}}@media(min-width: 992px){.grid .g-col-lg-1{grid-column:auto/span 1}.grid .g-col-lg-2{grid-column:auto/span 2}.grid .g-col-lg-3{grid-column:auto/span 3}.grid .g-col-lg-4{grid-column:auto/span 4}.grid .g-col-lg-5{grid-column:auto/span 5}.grid .g-col-lg-6{grid-column:auto/span 6}.grid .g-col-lg-7{grid-column:auto/span 7}.grid .g-col-lg-8{grid-column:auto/span 8}.grid .g-col-lg-9{grid-column:auto/span 9}.grid .g-col-lg-10{grid-column:auto/span 10}.grid .g-col-lg-11{grid-column:auto/span 11}.grid .g-col-lg-12{grid-column:auto/span 12}.grid .g-start-lg-1{grid-column-start:1}.grid .g-start-lg-2{grid-column-start:2}.grid .g-start-lg-3{grid-column-start:3}.grid .g-start-lg-4{grid-column-start:4}.grid .g-start-lg-5{grid-column-start:5}.grid .g-start-lg-6{grid-column-start:6}.grid .g-start-lg-7{grid-column-start:7}.grid .g-start-lg-8{grid-column-start:8}.grid .g-start-lg-9{grid-column-start:9}.grid .g-start-lg-10{grid-column-start:10}.grid .g-start-lg-11{grid-column-start:11}}@media(min-width: 1200px){.grid .g-col-xl-1{grid-column:auto/span 1}.grid .g-col-xl-2{grid-column:auto/span 2}.grid .g-col-xl-3{grid-column:auto/span 3}.grid .g-col-xl-4{grid-column:auto/span 4}.grid .g-col-xl-5{grid-column:auto/span 5}.grid .g-col-xl-6{grid-column:auto/span 6}.grid .g-col-xl-7{grid-column:auto/span 7}.grid .g-col-xl-8{grid-column:auto/span 8}.grid .g-col-xl-9{grid-column:auto/span 9}.grid .g-col-xl-10{grid-column:auto/span 10}.grid .g-col-xl-11{grid-column:auto/span 11}.grid .g-col-xl-12{grid-column:auto/span 12}.grid .g-start-xl-1{grid-column-start:1}.grid .g-start-xl-2{grid-column-start:2}.grid .g-start-xl-3{grid-column-start:3}.grid .g-start-xl-4{grid-column-start:4}.grid .g-start-xl-5{grid-column-start:5}.grid .g-start-xl-6{grid-column-start:6}.grid .g-start-xl-7{grid-column-start:7}.grid .g-start-xl-8{grid-column-start:8}.grid .g-start-xl-9{grid-column-start:9}.grid .g-start-xl-10{grid-column-start:10}.grid .g-start-xl-11{grid-column-start:11}}@media(min-width: 1400px){.grid .g-col-xxl-1{grid-column:auto/span 1}.grid .g-col-xxl-2{grid-column:auto/span 2}.grid .g-col-xxl-3{grid-column:auto/span 3}.grid .g-col-xxl-4{grid-column:auto/span 4}.grid .g-col-xxl-5{grid-column:auto/span 5}.grid .g-col-xxl-6{grid-column:auto/span 6}.grid .g-col-xxl-7{grid-column:auto/span 7}.grid .g-col-xxl-8{grid-column:auto/span 8}.grid .g-col-xxl-9{grid-column:auto/span 9}.grid .g-col-xxl-10{grid-column:auto/span 10}.grid .g-col-xxl-11{grid-column:auto/span 11}.grid .g-col-xxl-12{grid-column:auto/span 12}.grid .g-start-xxl-1{grid-column-start:1}.grid .g-start-xxl-2{grid-column-start:2}.grid .g-start-xxl-3{grid-column-start:3}.grid .g-start-xxl-4{grid-column-start:4}.grid .g-start-xxl-5{grid-column-start:5}.grid .g-start-xxl-6{grid-column-start:6}.grid .g-start-xxl-7{grid-column-start:7}.grid .g-start-xxl-8{grid-column-start:8}.grid .g-start-xxl-9{grid-column-start:9}.grid .g-start-xxl-10{grid-column-start:10}.grid .g-start-xxl-11{grid-column-start:11}}.table{--bs-table-bg: transparent;--bs-table-accent-bg: transparent;--bs-table-striped-color: #373a3c;--bs-table-striped-bg: rgba(0, 0, 0, 0.05);--bs-table-active-color: #373a3c;--bs-table-active-bg: rgba(0, 0, 0, 0.1);--bs-table-hover-color: #373a3c;--bs-table-hover-bg: rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#373a3c;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:first-child){border-top:2px solid #b6babc}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-borderless>:not(:first-child){border-top-width:0}.table-striped>tbody>tr:nth-of-type(odd)>*{--bs-table-accent-bg: var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg: var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover>*{--bs-table-accent-bg: var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg: #d4e6f9;--bs-table-striped-bg: #c9dbed;--bs-table-striped-color: #000;--bs-table-active-bg: #bfcfe0;--bs-table-active-color: #000;--bs-table-hover-bg: #c4d5e6;--bs-table-hover-color: #000;color:#000;border-color:#bfcfe0}.table-secondary{--bs-table-bg: #d7d8d8;--bs-table-striped-bg: #cccdcd;--bs-table-striped-color: #000;--bs-table-active-bg: #c2c2c2;--bs-table-active-color: #000;--bs-table-hover-bg: #c7c8c8;--bs-table-hover-color: #000;color:#000;border-color:#c2c2c2}.table-success{--bs-table-bg: #d9f0d1;--bs-table-striped-bg: #cee4c7;--bs-table-striped-color: #000;--bs-table-active-bg: #c3d8bc;--bs-table-active-color: #000;--bs-table-hover-bg: #c9dec1;--bs-table-hover-color: #000;color:#000;border-color:#c3d8bc}.table-info{--bs-table-bg: #ebddf1;--bs-table-striped-bg: #dfd2e5;--bs-table-striped-color: #000;--bs-table-active-bg: #d4c7d9;--bs-table-active-color: #000;--bs-table-hover-bg: #d9ccdf;--bs-table-hover-color: #000;color:#000;border-color:#d4c7d9}.table-warning{--bs-table-bg: #ffe3d1;--bs-table-striped-bg: #f2d8c7;--bs-table-striped-color: #000;--bs-table-active-bg: #e6ccbc;--bs-table-active-color: #000;--bs-table-hover-bg: #ecd2c1;--bs-table-hover-color: #000;color:#000;border-color:#e6ccbc}.table-danger{--bs-table-bg: #ffccd7;--bs-table-striped-bg: #f2c2cc;--bs-table-striped-color: #000;--bs-table-active-bg: #e6b8c2;--bs-table-active-color: #000;--bs-table-hover-bg: #ecbdc7;--bs-table-hover-color: #000;color:#000;border-color:#e6b8c2}.table-light{--bs-table-bg: #f8f9fa;--bs-table-striped-bg: #ecedee;--bs-table-striped-color: #000;--bs-table-active-bg: #dfe0e1;--bs-table-active-color: #000;--bs-table-hover-bg: #e5e6e7;--bs-table-hover-color: #000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg: #373a3c;--bs-table-striped-bg: #414446;--bs-table-striped-color: #fff;--bs-table-active-bg: #4b4e50;--bs-table-active-color: #fff;--bs-table-hover-bg: #46494b;--bs-table-hover-color: #fff;color:#fff;border-color:#4b4e50}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media(max-width: 575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media(max-width: 1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label,.shiny-input-container .control-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(0.375rem + 1px);padding-bottom:calc(0.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(0.5rem + 1px);padding-bottom:calc(0.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(0.25rem + 1px);padding-bottom:calc(0.25rem + 1px);font-size:0.875rem}.form-text{margin-top:.25rem;font-size:0.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#373a3c;background-color:#fff;border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#373a3c;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-0.375rem -0.75rem;margin-inline-end:.75rem;color:#373a3c;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-control::-webkit-file-upload-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#373a3c;background-color:rgba(0,0,0,0);border:solid rgba(0,0,0,0);border-width:1px 0}.form-control-plaintext.form-control-sm,.form-control-plaintext.form-control-lg{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px);padding:.25rem .5rem;font-size:0.875rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-0.25rem -0.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-0.5rem -1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + 0.75rem + 2px)}textarea.form-control-sm{min-height:calc(1.5em + 0.5rem + 2px)}textarea.form-control-lg{min-height:calc(1.5em + 1rem + 2px)}.form-control-color{width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em}.form-control-color::-webkit-color-swatch{height:1.5em}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:0;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-select{transition:none}}.form-select:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:rgba(0,0,0,0);text-shadow:0 0 0 #373a3c}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:0.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check,.shiny-input-container .checkbox,.shiny-input-container .radio{display:block;min-height:1.5rem;padding-left:0;margin-bottom:.125rem}.form-check .form-check-input,.form-check .shiny-input-container .checkbox input,.form-check .shiny-input-container .radio input,.shiny-input-container .checkbox .form-check-input,.shiny-input-container .checkbox .shiny-input-container .checkbox input,.shiny-input-container .checkbox .shiny-input-container .radio input,.shiny-input-container .radio .form-check-input,.shiny-input-container .radio .shiny-input-container .checkbox input,.shiny-input-container .radio .shiny-input-container .radio input{float:left;margin-left:0}.form-check-input,.shiny-input-container .checkbox input,.shiny-input-container .checkbox-inline input,.shiny-input-container .radio input,.shiny-input-container .radio-inline input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;color-adjust:exact;-webkit-print-color-adjust:exact}.form-check-input[type=radio],.shiny-input-container .checkbox input[type=radio],.shiny-input-container .checkbox-inline input[type=radio],.shiny-input-container .radio input[type=radio],.shiny-input-container .radio-inline input[type=radio]{border-radius:50%}.form-check-input:active,.shiny-input-container .checkbox input:active,.shiny-input-container .checkbox-inline input:active,.shiny-input-container .radio input:active,.shiny-input-container .radio-inline input:active{filter:brightness(90%)}.form-check-input:focus,.shiny-input-container .checkbox input:focus,.shiny-input-container .checkbox-inline input:focus,.shiny-input-container .radio input:focus,.shiny-input-container .radio-inline input:focus{border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.form-check-input:checked,.shiny-input-container .checkbox input:checked,.shiny-input-container .checkbox-inline input:checked,.shiny-input-container .radio input:checked,.shiny-input-container .radio-inline input:checked{background-color:#2780e3;border-color:#2780e3}.form-check-input:checked[type=checkbox],.shiny-input-container .checkbox input:checked[type=checkbox],.shiny-input-container .checkbox-inline input:checked[type=checkbox],.shiny-input-container .radio input:checked[type=checkbox],.shiny-input-container .radio-inline input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio],.shiny-input-container .checkbox input:checked[type=radio],.shiny-input-container .checkbox-inline input:checked[type=radio],.shiny-input-container .radio input:checked[type=radio],.shiny-input-container .radio-inline input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate,.shiny-input-container .checkbox input[type=checkbox]:indeterminate,.shiny-input-container .checkbox-inline input[type=checkbox]:indeterminate,.shiny-input-container .radio input[type=checkbox]:indeterminate,.shiny-input-container .radio-inline input[type=checkbox]:indeterminate{background-color:#2780e3;border-color:#2780e3;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled,.shiny-input-container .checkbox input:disabled,.shiny-input-container .checkbox-inline input:disabled,.shiny-input-container .radio input:disabled,.shiny-input-container .radio-inline input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input[disabled]~.form-check-label,.form-check-input[disabled]~span,.form-check-input:disabled~.form-check-label,.form-check-input:disabled~span,.shiny-input-container .checkbox input[disabled]~.form-check-label,.shiny-input-container .checkbox input[disabled]~span,.shiny-input-container .checkbox input:disabled~.form-check-label,.shiny-input-container .checkbox input:disabled~span,.shiny-input-container .checkbox-inline input[disabled]~.form-check-label,.shiny-input-container .checkbox-inline input[disabled]~span,.shiny-input-container .checkbox-inline input:disabled~.form-check-label,.shiny-input-container .checkbox-inline input:disabled~span,.shiny-input-container .radio input[disabled]~.form-check-label,.shiny-input-container .radio input[disabled]~span,.shiny-input-container .radio input:disabled~.form-check-label,.shiny-input-container .radio input:disabled~span,.shiny-input-container .radio-inline input[disabled]~.form-check-label,.shiny-input-container .radio-inline input[disabled]~span,.shiny-input-container .radio-inline input:disabled~.form-check-label,.shiny-input-container .radio-inline input:disabled~span{opacity:.5}.form-check-label,.shiny-input-container .checkbox label,.shiny-input-container .checkbox-inline label,.shiny-input-container .radio label,.shiny-input-container .radio-inline label{cursor:pointer}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;transition:background-position .15s ease-in-out}@media(prefers-reduced-motion: reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2393c0f1'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline,.shiny-input-container .checkbox-inline,.shiny-input-container .radio-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.btn-check[disabled]+.btn,.btn-check:disabled+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:rgba(0,0,0,0);appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(39,128,227,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-0.25rem;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-webkit-slider-thumb{transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#bed9f7}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0)}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#2780e3;border:0;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none}@media(prefers-reduced-motion: reduce){.form-range::-moz-range-thumb{transition:none}}.form-range::-moz-range-thumb:active{background-color:#bed9f7}.form-range::-moz-range-track{width:100%;height:.5rem;color:rgba(0,0,0,0);cursor:pointer;background-color:#dee2e6;border-color:rgba(0,0,0,0)}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid rgba(0,0,0,0);transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media(prefers-reduced-motion: reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::placeholder{color:rgba(0,0,0,0)}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(0.85) translateY(-0.5rem) translateX(0.15rem)}.input-group{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:stretch;-webkit-align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#373a3c;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da}.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text,.input-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem}.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text,.input-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#3fb618}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(63,182,24,.9)}.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip,.is-valid~.valid-feedback,.is-valid~.valid-tooltip{display:block}.was-validated .form-control:valid,.form-control.is-valid{border-color:#3fb618;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:valid:focus,.form-control.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:valid,.form-select.is-valid{border-color:#3fb618}.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"],.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%233fb618' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:valid:focus,.form-select.is-valid:focus{border-color:#3fb618;box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-check-input:valid,.form-check-input.is-valid{border-color:#3fb618}.was-validated .form-check-input:valid:checked,.form-check-input.is-valid:checked{background-color:#3fb618}.was-validated .form-check-input:valid:focus,.form-check-input.is-valid:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.25)}.was-validated .form-check-input:valid~.form-check-label,.form-check-input.is-valid~.form-check-label{color:#3fb618}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.was-validated .input-group .form-control:valid,.input-group .form-control.is-valid,.was-validated .input-group .form-select:valid,.input-group .form-select.is-valid{z-index:1}.was-validated .input-group .form-control:valid:focus,.input-group .form-control.is-valid:focus,.was-validated .input-group .form-select:valid:focus,.input-group .form-select.is-valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:0.875em;color:#ff0039}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:0.875rem;color:#fff;background-color:rgba(255,0,57,.9)}.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip,.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip{display:block}.was-validated .form-control:invalid,.form-control.is-invalid{border-color:#ff0039;padding-right:calc(1.5em + 0.75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(0.375em + 0.1875rem) center;background-size:calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-control:invalid:focus,.form-control.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + 0.75rem);background-position:top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem)}.was-validated .form-select:invalid,.form-select.is-invalid{border-color:#ff0039}.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"],.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23373a3c' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23ff0039'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23ff0039' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(0.75em + 0.375rem) calc(0.75em + 0.375rem)}.was-validated .form-select:invalid:focus,.form-select.is-invalid:focus{border-color:#ff0039;box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-check-input:invalid,.form-check-input.is-invalid{border-color:#ff0039}.was-validated .form-check-input:invalid:checked,.form-check-input.is-invalid:checked{background-color:#ff0039}.was-validated .form-check-input:invalid:focus,.form-check-input.is-invalid:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.25)}.was-validated .form-check-input:invalid~.form-check-label,.form-check-input.is-invalid~.form-check-label{color:#ff0039}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.was-validated .input-group .form-control:invalid,.input-group .form-control.is-invalid,.was-validated .input-group .form-select:invalid,.input-group .form-select.is-invalid{z-index:2}.was-validated .input-group .form-control:invalid:focus,.input-group .form-control.is-invalid:focus,.was-validated .input-group .form-select:invalid:focus,.input-group .form-select.is-invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#373a3c;text-align:center;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);padding:.375rem .75rem;font-size:1rem;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.btn{transition:none}}.btn:hover{color:#373a3c}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.btn:disabled,.btn.disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-default{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-default:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-default,.btn-default:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-default,.btn-check:active+.btn-default,.btn-default:active,.btn-default.active,.show>.btn-default.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-default:focus,.btn-check:active+.btn-default:focus,.btn-default:active:focus,.btn-default.active:focus,.show>.btn-default.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-default:disabled,.btn-default.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-primary{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-primary:hover{color:#fff;background-color:#216dc1;border-color:#1f66b6}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#216dc1;border-color:#1f66b6;box-shadow:0 0 0 .25rem rgba(71,147,231,.5)}.btn-check:checked+.btn-primary,.btn-check:active+.btn-primary,.btn-primary:active,.btn-primary.active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#1f66b6;border-color:#1d60aa}.btn-check:checked+.btn-primary:focus,.btn-check:active+.btn-primary:focus,.btn-primary:active:focus,.btn-primary.active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(71,147,231,.5)}.btn-primary:disabled,.btn-primary.disabled{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-secondary{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-secondary:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-secondary,.btn-check:active+.btn-secondary,.btn-secondary:active,.btn-secondary.active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-secondary:focus,.btn-check:active+.btn-secondary:focus,.btn-secondary:active:focus,.btn-secondary.active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-secondary:disabled,.btn-secondary.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-success{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-success:hover{color:#fff;background-color:#369b14;border-color:#329213}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#369b14;border-color:#329213;box-shadow:0 0 0 .25rem rgba(92,193,59,.5)}.btn-check:checked+.btn-success,.btn-check:active+.btn-success,.btn-success:active,.btn-success.active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#329213;border-color:#2f8912}.btn-check:checked+.btn-success:focus,.btn-check:active+.btn-success:focus,.btn-success:active:focus,.btn-success.active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(92,193,59,.5)}.btn-success:disabled,.btn-success.disabled{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-info{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-info:hover{color:#fff;background-color:#82479f;border-color:#7a4396}.btn-check:focus+.btn-info,.btn-info:focus{color:#fff;background-color:#82479f;border-color:#7a4396;box-shadow:0 0 0 .25rem rgba(168,110,197,.5)}.btn-check:checked+.btn-info,.btn-check:active+.btn-info,.btn-info:active,.btn-info.active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#7a4396;border-color:#733f8c}.btn-check:checked+.btn-info:focus,.btn-check:active+.btn-info:focus,.btn-info:active:focus,.btn-info.active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(168,110,197,.5)}.btn-info:disabled,.btn-info.disabled{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-warning{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-warning:hover{color:#fff;background-color:#d96314;border-color:#cc5e13}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#fff;background-color:#d96314;border-color:#cc5e13;box-shadow:0 0 0 .25rem rgba(255,138,59,.5)}.btn-check:checked+.btn-warning,.btn-check:active+.btn-warning,.btn-warning:active,.btn-warning.active,.show>.btn-warning.dropdown-toggle{color:#fff;background-color:#cc5e13;border-color:#bf5812}.btn-check:checked+.btn-warning:focus,.btn-check:active+.btn-warning:focus,.btn-warning:active:focus,.btn-warning.active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(255,138,59,.5)}.btn-warning:disabled,.btn-warning.disabled{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-danger{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-danger:hover{color:#fff;background-color:#d90030;border-color:#cc002e}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#d90030;border-color:#cc002e;box-shadow:0 0 0 .25rem rgba(255,38,87,.5)}.btn-check:checked+.btn-danger,.btn-check:active+.btn-danger,.btn-danger:active,.btn-danger.active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#cc002e;border-color:#bf002b}.btn-check:checked+.btn-danger:focus,.btn-check:active+.btn-danger:focus,.btn-danger:active:focus,.btn-danger.active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(255,38,87,.5)}.btn-danger:disabled,.btn-danger.disabled{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:checked+.btn-light,.btn-check:active+.btn-light,.btn-light:active,.btn-light.active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:checked+.btn-light:focus,.btn-check:active+.btn-light:focus,.btn-light:active:focus,.btn-light.active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light:disabled,.btn-light.disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-dark:hover{color:#fff;background-color:#2f3133;border-color:#2c2e30}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#2f3133;border-color:#2c2e30;box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-check:checked+.btn-dark,.btn-check:active+.btn-dark,.btn-dark:active,.btn-dark.active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#2c2e30;border-color:#292c2d}.btn-check:checked+.btn-dark:focus,.btn-check:active+.btn-dark:focus,.btn-dark:active:focus,.btn-dark.active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(85,88,89,.5)}.btn-dark:disabled,.btn-dark.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-outline-default{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-default:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-default,.btn-outline-default:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-default,.btn-check:active+.btn-outline-default,.btn-outline-default:active,.btn-outline-default.active,.btn-outline-default.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-default:focus,.btn-check:active+.btn-outline-default:focus,.btn-outline-default:active:focus,.btn-outline-default.active:focus,.btn-outline-default.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-default:disabled,.btn-outline-default.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-primary{color:#2780e3;border-color:#2780e3;background-color:rgba(0,0,0,0)}.btn-outline-primary:hover{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(39,128,227,.5)}.btn-check:checked+.btn-outline-primary,.btn-check:active+.btn-outline-primary,.btn-outline-primary:active,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show{color:#fff;background-color:#2780e3;border-color:#2780e3}.btn-check:checked+.btn-outline-primary:focus,.btn-check:active+.btn-outline-primary:focus,.btn-outline-primary:active:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(39,128,227,.5)}.btn-outline-primary:disabled,.btn-outline-primary.disabled{color:#2780e3;background-color:rgba(0,0,0,0)}.btn-outline-secondary{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-secondary:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-secondary,.btn-check:active+.btn-outline-secondary,.btn-outline-secondary:active,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-secondary:focus,.btn-check:active+.btn-outline-secondary:focus,.btn-outline-secondary:active:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-secondary:disabled,.btn-outline-secondary.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-success{color:#3fb618;border-color:#3fb618;background-color:rgba(0,0,0,0)}.btn-outline-success:hover{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.5)}.btn-check:checked+.btn-outline-success,.btn-check:active+.btn-outline-success,.btn-outline-success:active,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show{color:#fff;background-color:#3fb618;border-color:#3fb618}.btn-check:checked+.btn-outline-success:focus,.btn-check:active+.btn-outline-success:focus,.btn-outline-success:active:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(63,182,24,.5)}.btn-outline-success:disabled,.btn-outline-success.disabled{color:#3fb618;background-color:rgba(0,0,0,0)}.btn-outline-info{color:#9954bb;border-color:#9954bb;background-color:rgba(0,0,0,0)}.btn-outline-info:hover{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(153,84,187,.5)}.btn-check:checked+.btn-outline-info,.btn-check:active+.btn-outline-info,.btn-outline-info:active,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show{color:#fff;background-color:#9954bb;border-color:#9954bb}.btn-check:checked+.btn-outline-info:focus,.btn-check:active+.btn-outline-info:focus,.btn-outline-info:active:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(153,84,187,.5)}.btn-outline-info:disabled,.btn-outline-info.disabled{color:#9954bb;background-color:rgba(0,0,0,0)}.btn-outline-warning{color:#ff7518;border-color:#ff7518;background-color:rgba(0,0,0,0)}.btn-outline-warning:hover{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,117,24,.5)}.btn-check:checked+.btn-outline-warning,.btn-check:active+.btn-outline-warning,.btn-outline-warning:active,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show{color:#fff;background-color:#ff7518;border-color:#ff7518}.btn-check:checked+.btn-outline-warning:focus,.btn-check:active+.btn-outline-warning:focus,.btn-outline-warning:active:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(255,117,24,.5)}.btn-outline-warning:disabled,.btn-outline-warning.disabled{color:#ff7518;background-color:rgba(0,0,0,0)}.btn-outline-danger{color:#ff0039;border-color:#ff0039;background-color:rgba(0,0,0,0)}.btn-outline-danger:hover{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.5)}.btn-check:checked+.btn-outline-danger,.btn-check:active+.btn-outline-danger,.btn-outline-danger:active,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show{color:#fff;background-color:#ff0039;border-color:#ff0039}.btn-check:checked+.btn-outline-danger:focus,.btn-check:active+.btn-outline-danger:focus,.btn-outline-danger:active:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(255,0,57,.5)}.btn-outline-danger:disabled,.btn-outline-danger.disabled{color:#ff0039;background-color:rgba(0,0,0,0)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa;background-color:rgba(0,0,0,0)}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:checked+.btn-outline-light,.btn-check:active+.btn-outline-light,.btn-outline-light:active,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:checked+.btn-outline-light:focus,.btn-check:active+.btn-outline-light:focus,.btn-outline-light:active:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light:disabled,.btn-outline-light.disabled{color:#f8f9fa;background-color:rgba(0,0,0,0)}.btn-outline-dark{color:#373a3c;border-color:#373a3c;background-color:rgba(0,0,0,0)}.btn-outline-dark:hover{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-check:checked+.btn-outline-dark,.btn-check:active+.btn-outline-dark,.btn-outline-dark:active,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show{color:#fff;background-color:#373a3c;border-color:#373a3c}.btn-check:checked+.btn-outline-dark:focus,.btn-check:active+.btn-outline-dark:focus,.btn-outline-dark:active:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus{box-shadow:0 0 0 .25rem rgba(55,58,60,.5)}.btn-outline-dark:disabled,.btn-outline-dark.disabled{color:#373a3c;background-color:rgba(0,0,0,0)}.btn-link{font-weight:400;color:#2780e3;text-decoration:underline;-webkit-text-decoration:underline;-moz-text-decoration:underline;-ms-text-decoration:underline;-o-text-decoration:underline}.btn-link:hover{color:#1f66b6}.btn-link:disabled,.btn-link.disabled{color:#6c757d}.btn-lg,.btn-group-lg>.btn{padding:.5rem 1rem;font-size:1.25rem;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:.25rem .5rem;font-size:0.875rem;border-radius:0}.fade{transition:opacity .15s linear}@media(prefers-reduced-motion: reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .2s ease}@media(prefers-reduced-motion: reduce){.collapsing{transition:none}}.collapsing.collapse-horizontal{width:0;height:auto;transition:width .35s ease}@media(prefers-reduced-motion: reduce){.collapsing.collapse-horizontal{transition:none}}.dropup,.dropend,.dropdown,.dropstart{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid rgba(0,0,0,0);border-bottom:0;border-left:.3em solid rgba(0,0,0,0)}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#373a3c;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15)}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position: start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position: end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media(min-width: 576px){.dropdown-menu-sm-start{--bs-position: start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position: end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 768px){.dropdown-menu-md-start{--bs-position: start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position: end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 992px){.dropdown-menu-lg-start{--bs-position: start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position: end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1200px){.dropdown-menu-xl-start{--bs-position: start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position: end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media(min-width: 1400px){.dropdown-menu-xxl-start{--bs-position: start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position: end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid rgba(0,0,0,0);border-bottom:.3em solid;border-left:.3em solid rgba(0,0,0,0)}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:0;border-bottom:.3em solid rgba(0,0,0,0);border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid rgba(0,0,0,0);border-right:.3em solid;border-bottom:.3em solid rgba(0,0,0,0)}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap;background-color:rgba(0,0,0,0);border:0}.dropdown-item:hover,.dropdown-item:focus{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#2780e3}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:rgba(0,0,0,0)}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:0.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#373a3c;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:hover,.dropdown-menu-dark .dropdown-item:focus{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#2780e3}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto}.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn:hover,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn.active{z-index:1}.btn-toolbar{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;justify-content:flex-start;-webkit-justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:not(:first-child),.btn-group>.btn-group:not(:first-child){margin-left:-1px}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-sm+.dropdown-toggle-split,.btn-group-sm>.btn+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-lg+.dropdown-toggle-split,.btn-group-lg>.btn+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;-webkit-flex-direction:column;align-items:flex-start;-webkit-align-items:flex-start;justify-content:center;-webkit-justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn:not(:first-child),.btn-group-vertical>.btn-group:not(:first-child){margin-top:-1px}.nav{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#2780e3;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media(prefers-reduced-motion: reduce){.nav-link{transition:none}}.nav-link:hover,.nav-link:focus{color:#1f66b6}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:none;border:1px solid rgba(0,0,0,0)}.nav-tabs .nav-link:hover,.nav-tabs .nav-link:focus{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:rgba(0,0,0,0);border-color:rgba(0,0,0,0)}.nav-tabs .nav-link.active,.nav-tabs .nav-item.show .nav-link{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px}.nav-pills .nav-link{background:none;border:0}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#2780e3}.nav-fill>.nav-link,.nav-fill .nav-item{flex:1 1 auto;-webkit-flex:1 1 auto;text-align:center}.nav-justified>.nav-link,.nav-justified .nav-item{flex-basis:0;-webkit-flex-basis:0;flex-grow:1;-webkit-flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container-xxl,.navbar>.container-xl,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container,.navbar>.container-fluid{display:flex;display:-webkit-flex;flex-wrap:inherit;-webkit-flex-wrap:inherit;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;-webkit-flex-basis:100%;flex-grow:1;-webkit-flex-grow:1;align-items:center;-webkit-align-items:center}.navbar-toggler{padding:.25 0;font-size:1.25rem;line-height:1;background-color:rgba(0,0,0,0);border:1px solid rgba(0,0,0,0);transition:box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height, 75vh);overflow-y:auto}@media(min-width: 576px){.navbar-expand-sm{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .offcanvas-header{display:none}.navbar-expand-sm .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-sm .offcanvas-top,.navbar-expand-sm .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-sm .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 768px){.navbar-expand-md{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .offcanvas-header{display:none}.navbar-expand-md .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-md .offcanvas-top,.navbar-expand-md .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-md .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 992px){.navbar-expand-lg{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .offcanvas-header{display:none}.navbar-expand-lg .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-lg .offcanvas-top,.navbar-expand-lg .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-lg .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1200px){.navbar-expand-xl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .offcanvas-header{display:none}.navbar-expand-xl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xl .offcanvas-top,.navbar-expand-xl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}@media(min-width: 1400px){.navbar-expand-xxl{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}.navbar-expand-xxl .offcanvas-header{display:none}.navbar-expand-xxl .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand-xxl .offcanvas-top,.navbar-expand-xxl .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand-xxl .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}}.navbar-expand{flex-wrap:nowrap;-webkit-flex-wrap:nowrap;justify-content:flex-start;-webkit-justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row;-webkit-flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex !important;display:-webkit-flex !important;flex-basis:auto;-webkit-flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .offcanvas-header{display:none}.navbar-expand .offcanvas{position:inherit;bottom:0;z-index:1000;flex-grow:1;-webkit-flex-grow:1;visibility:visible !important;background-color:rgba(0,0,0,0);border-right:0;border-left:0;transition:none;transform:none}.navbar-expand .offcanvas-top,.navbar-expand .offcanvas-bottom{height:auto;border-top:0;border-bottom:0}.navbar-expand .offcanvas-body{display:flex;display:-webkit-flex;flex-grow:0;-webkit-flex-grow:0;padding:0;overflow-y:visible}.navbar-light{background-color:#2780e3}.navbar-light .navbar-brand{color:#fdfeff}.navbar-light .navbar-brand:hover,.navbar-light .navbar-brand:focus{color:#fdfeff}.navbar-light .navbar-nav .nav-link{color:#fdfeff}.navbar-light .navbar-nav .nav-link:hover,.navbar-light .navbar-nav .nav-link:focus{color:rgba(253,254,255,.8)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(253,254,255,.75)}.navbar-light .navbar-nav .show>.nav-link,.navbar-light .navbar-nav .nav-link.active{color:#fdfeff}.navbar-light .navbar-toggler{color:#fdfeff;border-color:rgba(253,254,255,0)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfeff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:#fdfeff}.navbar-light .navbar-text a,.navbar-light .navbar-text a:hover,.navbar-light .navbar-text a:focus{color:#fdfeff}.navbar-dark{background-color:#2780e3}.navbar-dark .navbar-brand{color:#fdfeff}.navbar-dark .navbar-brand:hover,.navbar-dark .navbar-brand:focus{color:#fdfeff}.navbar-dark .navbar-nav .nav-link{color:#fdfeff}.navbar-dark .navbar-nav .nav-link:hover,.navbar-dark .navbar-nav .nav-link:focus{color:rgba(253,254,255,.8)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(253,254,255,.75)}.navbar-dark .navbar-nav .show>.nav-link,.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active{color:#fdfeff}.navbar-dark .navbar-toggler{color:#fdfeff;border-color:rgba(253,254,255,0)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%23fdfeff' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:#fdfeff}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:hover,.navbar-dark .navbar-text a:focus{color:#fdfeff}.card{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125)}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0}.card>.list-group:last-child{border-bottom-width:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-0.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:#adb5bd;border-bottom:1px solid rgba(0,0,0,.125)}.card-footer{padding:.5rem 1rem;background-color:#adb5bd;border-top:1px solid rgba(0,0,0,.125)}.card-header-tabs{margin-right:-0.5rem;margin-bottom:-0.5rem;margin-left:-0.5rem;border-bottom:0}.card-header-pills{margin-right:-0.5rem;margin-left:-0.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem}.card-img,.card-img-top,.card-img-bottom{width:100%}.card-group>.card{margin-bottom:.75rem}@media(min-width: 576px){.card-group{display:flex;display:-webkit-flex;flex-flow:row wrap;-webkit-flex-flow:row wrap}.card-group>.card{flex:1 0 0%;-webkit-flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}}.accordion-button{position:relative;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#373a3c;text-align:left;background-color:#fff;border:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media(prefers-reduced-motion: reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#2373cc;background-color:#e9f2fc;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%232373cc'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;-webkit-flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23373a3c'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media(prefers-reduced-motion: reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#93c0f1;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:not(:first-of-type){border-top:0}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.breadcrumb{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, ">") /* rtl: var(--bs-breadcrumb-divider, ">") */}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;display:-webkit-flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#2780e3;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media(prefers-reduced-motion: reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#1f66b6;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#1f66b6;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#2780e3;border-color:#2780e3}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:0.875rem}.badge{display:inline-block;padding:.35em .65em;font-size:0.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:0 solid rgba(0,0,0,0)}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-default{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-default .alert-link{color:#1a1c1d}.alert-primary{color:#174d88;background-color:#d4e6f9;border-color:#bed9f7}.alert-primary .alert-link{color:#123e6d}.alert-secondary{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-secondary .alert-link{color:#1a1c1d}.alert-success{color:#266d0e;background-color:#d9f0d1;border-color:#c5e9ba}.alert-success .alert-link{color:#1e570b}.alert-info{color:#5c3270;background-color:#ebddf1;border-color:#e0cceb}.alert-info .alert-link{color:#4a285a}.alert-warning{color:#99460e;background-color:#ffe3d1;border-color:#ffd6ba}.alert-warning .alert-link{color:#7a380b}.alert-danger{color:#902;background-color:#ffccd7;border-color:#ffb3c4}.alert-danger .alert-link{color:#7a001b}.alert-light{color:#959596;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#777778}.alert-dark{color:#212324;background-color:#d7d8d8;border-color:#c3c4c5}.alert-dark .alert-link{color:#1a1c1d}@keyframes progress-bar-stripes{0%{background-position-x:.5rem}}.progress{display:flex;display:-webkit-flex;height:.5rem;overflow:hidden;font-size:0.75rem;background-color:#e9ecef}.progress-bar{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;justify-content:center;-webkit-justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#2780e3;transition:width .6s ease}@media(prefers-reduced-motion: reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:.5rem .5rem}.progress-bar-animated{animation:1s linear infinite progress-bar-stripes}@media(prefers-reduced-motion: reduce){.progress-bar-animated{animation:none}}.list-group{display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;padding-left:0;margin-bottom:0}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:hover,.list-group-item-action:focus{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#373a3c;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;-webkit-text-decoration:none;-moz-text-decoration:none;-ms-text-decoration:none;-o-text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#2780e3;border-color:#2780e3}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media(min-width: 576px){.list-group-horizontal-sm{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 768px){.list-group-horizontal-md{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 992px){.list-group-horizontal-lg{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1200px){.list-group-horizontal-xl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media(min-width: 1400px){.list-group-horizontal-xxl{flex-direction:row;-webkit-flex-direction:row}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-default{color:#212324;background-color:#d7d8d8}.list-group-item-default.list-group-item-action:hover,.list-group-item-default.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-default.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.list-group-item-primary{color:#174d88;background-color:#d4e6f9}.list-group-item-primary.list-group-item-action:hover,.list-group-item-primary.list-group-item-action:focus{color:#174d88;background-color:#bfcfe0}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#174d88;border-color:#174d88}.list-group-item-secondary{color:#212324;background-color:#d7d8d8}.list-group-item-secondary.list-group-item-action:hover,.list-group-item-secondary.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.list-group-item-success{color:#266d0e;background-color:#d9f0d1}.list-group-item-success.list-group-item-action:hover,.list-group-item-success.list-group-item-action:focus{color:#266d0e;background-color:#c3d8bc}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#266d0e;border-color:#266d0e}.list-group-item-info{color:#5c3270;background-color:#ebddf1}.list-group-item-info.list-group-item-action:hover,.list-group-item-info.list-group-item-action:focus{color:#5c3270;background-color:#d4c7d9}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#5c3270;border-color:#5c3270}.list-group-item-warning{color:#99460e;background-color:#ffe3d1}.list-group-item-warning.list-group-item-action:hover,.list-group-item-warning.list-group-item-action:focus{color:#99460e;background-color:#e6ccbc}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#99460e;border-color:#99460e}.list-group-item-danger{color:#902;background-color:#ffccd7}.list-group-item-danger.list-group-item-action:hover,.list-group-item-danger.list-group-item-action:focus{color:#902;background-color:#e6b8c2}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#902;border-color:#902}.list-group-item-light{color:#959596;background-color:#fefefe}.list-group-item-light.list-group-item-action:hover,.list-group-item-light.list-group-item-action:focus{color:#959596;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#959596;border-color:#959596}.list-group-item-dark{color:#212324;background-color:#d7d8d8}.list-group-item-dark.list-group-item-action:hover,.list-group-item-dark.list-group-item-action:focus{color:#212324;background-color:#c2c2c2}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#212324;border-color:#212324}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:rgba(0,0,0,0) url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(39,128,227,.25);opacity:1}.btn-close:disabled,.btn-close.disabled{pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:0.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15)}.toast.showing{opacity:0}.toast:not(.show){display:none}.toast-container{width:max-content;width:-webkit-max-content;width:-moz-max-content;width:-ms-max-content;width:-o-max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-header .btn-close{margin-right:-0.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1055;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0, -50px)}@media(prefers-reduced-motion: reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1050;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;display:-webkit-flex;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6}.modal-header .btn-close{padding:.5rem .5rem;margin:-0.5rem -0.5rem -0.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;-webkit-flex:1 1 auto;padding:1rem}.modal-footer{display:flex;display:-webkit-flex;flex-wrap:wrap;-webkit-flex-wrap:wrap;flex-shrink:0;-webkit-flex-shrink:0;align-items:center;-webkit-align-items:center;justify-content:flex-end;-webkit-justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6}.modal-footer>*{margin:.25rem}@media(min-width: 576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media(min-width: 992px){.modal-lg,.modal-xl{max-width:800px}}@media(min-width: 1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0}.modal-fullscreen .modal-body{overflow-y:auto}@media(max-width: 575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}}@media(max-width: 767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}}@media(max-width: 991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}}@media(max-width: 1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}}@media(max-width: 1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-tooltip-top,.bs-tooltip-auto[data-popper-placement^=top]{padding:.4rem 0}.bs-tooltip-top .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow{bottom:0}.bs-tooltip-top .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-end,.bs-tooltip-auto[data-popper-placement^=right]{padding:0 .4rem}.bs-tooltip-end .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-end .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-bottom,.bs-tooltip-auto[data-popper-placement^=bottom]{padding:.4rem 0}.bs-tooltip-bottom .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow{top:0}.bs-tooltip-bottom .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-start,.bs-tooltip-auto[data-popper-placement^=left]{padding:0 .4rem}.bs-tooltip-start .tooltip-arrow,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-start .tooltip-arrow::before,.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000}.popover{position:absolute;top:0;left:0 /* rtl:ignore */;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:0.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2)}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::before,.popover .popover-arrow::after{position:absolute;display:block;content:"";border-color:rgba(0,0,0,0);border-style:solid}.bs-popover-top>.popover-arrow,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow{bottom:calc(-0.5rem - 1px)}.bs-popover-top>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-top>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-end>.popover-arrow,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow{left:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-end>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-end>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-bottom>.popover-arrow,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow{top:calc(-0.5rem - 1px)}.bs-popover-bottom>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-bottom>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-bottom .popover-header::before,.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-0.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-start>.popover-arrow,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow{right:calc(-0.5rem - 1px);width:.5rem;height:1rem}.bs-popover-start>.popover-arrow::before,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-start>.popover-arrow::after,.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#373a3c}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y;-webkit-touch-action:pan-y;-moz-touch-action:pan-y;-ms-touch-action:pan-y;-o-touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;backface-visibility:hidden;-webkit-backface-visibility:hidden;-moz-backface-visibility:hidden;-ms-backface-visibility:hidden;-o-backface-visibility:hidden;transition:transform .6s ease-in-out}@media(prefers-reduced-motion: reduce){.carousel-item{transition:none}}.carousel-item.active,.carousel-item-next,.carousel-item-prev{display:block}.carousel-item-next:not(.carousel-item-start),.active.carousel-item-end{transform:translateX(100%)}.carousel-item-prev:not(.carousel-item-end),.active.carousel-item-start{transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item.active,.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end{z-index:1;opacity:1}.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{z-index:0;opacity:0;transition:opacity 0s .6s}@media(prefers-reduced-motion: reduce){.carousel-fade .active.carousel-item-start,.carousel-fade .active.carousel-item-end{transition:none}}.carousel-control-prev,.carousel-control-next{position:absolute;top:0;bottom:0;z-index:1;display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:center;-webkit-justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:none;border:0;opacity:.5;transition:opacity .15s ease}@media(prefers-reduced-motion: reduce){.carousel-control-prev,.carousel-control-next{transition:none}}.carousel-control-prev:hover,.carousel-control-prev:focus,.carousel-control-next:hover,.carousel-control-next:focus{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-prev-icon,.carousel-control-next-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;display:-webkit-flex;justify-content:center;-webkit-justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;-webkit-flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid rgba(0,0,0,0);border-bottom:10px solid rgba(0,0,0,0);opacity:.5;transition:opacity .6s ease}@media(prefers-reduced-motion: reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-prev-icon,.carousel-dark .carousel-control-next-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@keyframes spinner-border{to{transform:rotate(360deg) /* rtl:ignore */}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;border:.25em solid currentColor;border-right-color:rgba(0,0,0,0);border-radius:50%;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-0.125em;background-color:currentColor;border-radius:50%;opacity:0;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media(prefers-reduced-motion: reduce){.spinner-border,.spinner-grow{animation-duration:1.5s;-webkit-animation-duration:1.5s;-moz-animation-duration:1.5s;-ms-animation-duration:1.5s;-o-animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1045;display:flex;display:-webkit-flex;flex-direction:column;-webkit-flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media(prefers-reduced-motion: reduce){.offcanvas{transition:none}}.offcanvas-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.offcanvas-backdrop.fade{opacity:0}.offcanvas-backdrop.show{opacity:.5}.offcanvas-header{display:flex;display:-webkit-flex;align-items:center;-webkit-align-items:center;justify-content:space-between;-webkit-justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-0.5rem;margin-right:-0.5rem;margin-bottom:-0.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;-webkit-flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.placeholder{display:inline-block;min-height:1em;vertical-align:middle;cursor:wait;background-color:currentColor;opacity:.5}.placeholder.btn::before{display:inline-block;content:""}.placeholder-xs{min-height:.6em}.placeholder-sm{min-height:.8em}.placeholder-lg{min-height:1.2em}.placeholder-glow .placeholder{animation:placeholder-glow 2s ease-in-out infinite}@keyframes placeholder-glow{50%{opacity:.2}}.placeholder-wave{mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);-webkit-mask-image:linear-gradient(130deg, #000 55%, rgba(0, 0, 0, 0.8) 75%, #000 95%);mask-size:200% 100%;-webkit-mask-size:200% 100%;animation:placeholder-wave 2s linear infinite}@keyframes placeholder-wave{100%{mask-position:-200% 0%;-webkit-mask-position:-200% 0%}}.clearfix::after{display:block;clear:both;content:""}.link-default{color:#373a3c}.link-default:hover,.link-default:focus{color:#2c2e30}.link-primary{color:#2780e3}.link-primary:hover,.link-primary:focus{color:#1f66b6}.link-secondary{color:#373a3c}.link-secondary:hover,.link-secondary:focus{color:#2c2e30}.link-success{color:#3fb618}.link-success:hover,.link-success:focus{color:#329213}.link-info{color:#9954bb}.link-info:hover,.link-info:focus{color:#7a4396}.link-warning{color:#ff7518}.link-warning:hover,.link-warning:focus{color:#cc5e13}.link-danger{color:#ff0039}.link-danger:hover,.link-danger:focus{color:#cc002e}.link-light{color:#f8f9fa}.link-light:hover,.link-light:focus{color:#f9fafb}.link-dark{color:#373a3c}.link-dark:hover,.link-dark:focus{color:#2c2e30}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio: 100%}.ratio-4x3{--bs-aspect-ratio: 75%}.ratio-16x9{--bs-aspect-ratio: 56.25%}.ratio-21x9{--bs-aspect-ratio: 42.8571428571%}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:sticky;top:0;z-index:1020}@media(min-width: 576px){.sticky-sm-top{position:sticky;top:0;z-index:1020}}@media(min-width: 768px){.sticky-md-top{position:sticky;top:0;z-index:1020}}@media(min-width: 992px){.sticky-lg-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1200px){.sticky-xl-top{position:sticky;top:0;z-index:1020}}@media(min-width: 1400px){.sticky-xxl-top{position:sticky;top:0;z-index:1020}}.hstack{display:flex;display:-webkit-flex;flex-direction:row;-webkit-flex-direction:row;align-items:center;-webkit-align-items:center;align-self:stretch;-webkit-align-self:stretch}.vstack{display:flex;display:-webkit-flex;flex:1 1 auto;-webkit-flex:1 1 auto;flex-direction:column;-webkit-flex-direction:column;align-self:stretch;-webkit-align-self:stretch}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0, 0, 0, 0) !important;white-space:nowrap !important;border:0 !important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.vr{display:inline-block;align-self:stretch;-webkit-align-self:stretch;width:1px;min-height:1em;background-color:currentColor;opacity:.25}.align-baseline{vertical-align:baseline !important}.align-top{vertical-align:top !important}.align-middle{vertical-align:middle !important}.align-bottom{vertical-align:bottom !important}.align-text-bottom{vertical-align:text-bottom !important}.align-text-top{vertical-align:text-top !important}.float-start{float:left !important}.float-end{float:right !important}.float-none{float:none !important}.opacity-0{opacity:0 !important}.opacity-25{opacity:.25 !important}.opacity-50{opacity:.5 !important}.opacity-75{opacity:.75 !important}.opacity-100{opacity:1 !important}.overflow-auto{overflow:auto !important}.overflow-hidden{overflow:hidden !important}.overflow-visible{overflow:visible !important}.overflow-scroll{overflow:scroll !important}.d-inline{display:inline !important}.d-inline-block{display:inline-block !important}.d-block{display:block !important}.d-grid{display:grid !important}.d-table{display:table !important}.d-table-row{display:table-row !important}.d-table-cell{display:table-cell !important}.d-flex{display:flex !important}.d-inline-flex{display:inline-flex !important}.d-none{display:none !important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15) !important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075) !important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175) !important}.shadow-none{box-shadow:none !important}.position-static{position:static !important}.position-relative{position:relative !important}.position-absolute{position:absolute !important}.position-fixed{position:fixed !important}.position-sticky{position:sticky !important}.top-0{top:0 !important}.top-50{top:50% !important}.top-100{top:100% !important}.bottom-0{bottom:0 !important}.bottom-50{bottom:50% !important}.bottom-100{bottom:100% !important}.start-0{left:0 !important}.start-50{left:50% !important}.start-100{left:100% !important}.end-0{right:0 !important}.end-50{right:50% !important}.end-100{right:100% !important}.translate-middle{transform:translate(-50%, -50%) !important}.translate-middle-x{transform:translateX(-50%) !important}.translate-middle-y{transform:translateY(-50%) !important}.border{border:1px solid #dee2e6 !important}.border-0{border:0 !important}.border-top{border-top:1px solid #dee2e6 !important}.border-top-0{border-top:0 !important}.border-end{border-right:1px solid #dee2e6 !important}.border-end-0{border-right:0 !important}.border-bottom{border-bottom:1px solid #dee2e6 !important}.border-bottom-0{border-bottom:0 !important}.border-start{border-left:1px solid #dee2e6 !important}.border-start-0{border-left:0 !important}.border-default{border-color:#373a3c !important}.border-primary{border-color:#2780e3 !important}.border-secondary{border-color:#373a3c !important}.border-success{border-color:#3fb618 !important}.border-info{border-color:#9954bb !important}.border-warning{border-color:#ff7518 !important}.border-danger{border-color:#ff0039 !important}.border-light{border-color:#f8f9fa !important}.border-dark{border-color:#373a3c !important}.border-white{border-color:#fff !important}.border-1{border-width:1px !important}.border-2{border-width:2px !important}.border-3{border-width:3px !important}.border-4{border-width:4px !important}.border-5{border-width:5px !important}.w-25{width:25% !important}.w-50{width:50% !important}.w-75{width:75% !important}.w-100{width:100% !important}.w-auto{width:auto !important}.mw-100{max-width:100% !important}.vw-100{width:100vw !important}.min-vw-100{min-width:100vw !important}.h-25{height:25% !important}.h-50{height:50% !important}.h-75{height:75% !important}.h-100{height:100% !important}.h-auto{height:auto !important}.mh-100{max-height:100% !important}.vh-100{height:100vh !important}.min-vh-100{min-height:100vh !important}.flex-fill{flex:1 1 auto !important}.flex-row{flex-direction:row !important}.flex-column{flex-direction:column !important}.flex-row-reverse{flex-direction:row-reverse !important}.flex-column-reverse{flex-direction:column-reverse !important}.flex-grow-0{flex-grow:0 !important}.flex-grow-1{flex-grow:1 !important}.flex-shrink-0{flex-shrink:0 !important}.flex-shrink-1{flex-shrink:1 !important}.flex-wrap{flex-wrap:wrap !important}.flex-nowrap{flex-wrap:nowrap !important}.flex-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-0{gap:0 !important}.gap-1{gap:.25rem !important}.gap-2{gap:.5rem !important}.gap-3{gap:1rem !important}.gap-4{gap:1.5rem !important}.gap-5{gap:3rem !important}.justify-content-start{justify-content:flex-start !important}.justify-content-end{justify-content:flex-end !important}.justify-content-center{justify-content:center !important}.justify-content-between{justify-content:space-between !important}.justify-content-around{justify-content:space-around !important}.justify-content-evenly{justify-content:space-evenly !important}.align-items-start{align-items:flex-start !important}.align-items-end{align-items:flex-end !important}.align-items-center{align-items:center !important}.align-items-baseline{align-items:baseline !important}.align-items-stretch{align-items:stretch !important}.align-content-start{align-content:flex-start !important}.align-content-end{align-content:flex-end !important}.align-content-center{align-content:center !important}.align-content-between{align-content:space-between !important}.align-content-around{align-content:space-around !important}.align-content-stretch{align-content:stretch !important}.align-self-auto{align-self:auto !important}.align-self-start{align-self:flex-start !important}.align-self-end{align-self:flex-end !important}.align-self-center{align-self:center !important}.align-self-baseline{align-self:baseline !important}.align-self-stretch{align-self:stretch !important}.order-first{order:-1 !important}.order-0{order:0 !important}.order-1{order:1 !important}.order-2{order:2 !important}.order-3{order:3 !important}.order-4{order:4 !important}.order-5{order:5 !important}.order-last{order:6 !important}.m-0{margin:0 !important}.m-1{margin:.25rem !important}.m-2{margin:.5rem !important}.m-3{margin:1rem !important}.m-4{margin:1.5rem !important}.m-5{margin:3rem !important}.m-auto{margin:auto !important}.mx-0{margin-right:0 !important;margin-left:0 !important}.mx-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-3{margin-right:1rem !important;margin-left:1rem !important}.mx-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-5{margin-right:3rem !important;margin-left:3rem !important}.mx-auto{margin-right:auto !important;margin-left:auto !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-0{margin-top:0 !important}.mt-1{margin-top:.25rem !important}.mt-2{margin-top:.5rem !important}.mt-3{margin-top:1rem !important}.mt-4{margin-top:1.5rem !important}.mt-5{margin-top:3rem !important}.mt-auto{margin-top:auto !important}.me-0{margin-right:0 !important}.me-1{margin-right:.25rem !important}.me-2{margin-right:.5rem !important}.me-3{margin-right:1rem !important}.me-4{margin-right:1.5rem !important}.me-5{margin-right:3rem !important}.me-auto{margin-right:auto !important}.mb-0{margin-bottom:0 !important}.mb-1{margin-bottom:.25rem !important}.mb-2{margin-bottom:.5rem !important}.mb-3{margin-bottom:1rem !important}.mb-4{margin-bottom:1.5rem !important}.mb-5{margin-bottom:3rem !important}.mb-auto{margin-bottom:auto !important}.ms-0{margin-left:0 !important}.ms-1{margin-left:.25rem !important}.ms-2{margin-left:.5rem !important}.ms-3{margin-left:1rem !important}.ms-4{margin-left:1.5rem !important}.ms-5{margin-left:3rem !important}.ms-auto{margin-left:auto !important}.p-0{padding:0 !important}.p-1{padding:.25rem !important}.p-2{padding:.5rem !important}.p-3{padding:1rem !important}.p-4{padding:1.5rem !important}.p-5{padding:3rem !important}.px-0{padding-right:0 !important;padding-left:0 !important}.px-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-3{padding-right:1rem !important;padding-left:1rem !important}.px-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-5{padding-right:3rem !important;padding-left:3rem !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-0{padding-top:0 !important}.pt-1{padding-top:.25rem !important}.pt-2{padding-top:.5rem !important}.pt-3{padding-top:1rem !important}.pt-4{padding-top:1.5rem !important}.pt-5{padding-top:3rem !important}.pe-0{padding-right:0 !important}.pe-1{padding-right:.25rem !important}.pe-2{padding-right:.5rem !important}.pe-3{padding-right:1rem !important}.pe-4{padding-right:1.5rem !important}.pe-5{padding-right:3rem !important}.pb-0{padding-bottom:0 !important}.pb-1{padding-bottom:.25rem !important}.pb-2{padding-bottom:.5rem !important}.pb-3{padding-bottom:1rem !important}.pb-4{padding-bottom:1.5rem !important}.pb-5{padding-bottom:3rem !important}.ps-0{padding-left:0 !important}.ps-1{padding-left:.25rem !important}.ps-2{padding-left:.5rem !important}.ps-3{padding-left:1rem !important}.ps-4{padding-left:1.5rem !important}.ps-5{padding-left:3rem !important}.font-monospace{font-family:var(--bs-font-monospace) !important}.fs-1{font-size:calc(1.325rem + 0.9vw) !important}.fs-2{font-size:calc(1.29rem + 0.48vw) !important}.fs-3{font-size:calc(1.27rem + 0.24vw) !important}.fs-4{font-size:1.25rem !important}.fs-5{font-size:1.1rem !important}.fs-6{font-size:1rem !important}.fst-italic{font-style:italic !important}.fst-normal{font-style:normal !important}.fw-light{font-weight:300 !important}.fw-lighter{font-weight:lighter !important}.fw-normal{font-weight:400 !important}.fw-bold{font-weight:700 !important}.fw-bolder{font-weight:bolder !important}.lh-1{line-height:1 !important}.lh-sm{line-height:1.25 !important}.lh-base{line-height:1.5 !important}.lh-lg{line-height:2 !important}.text-start{text-align:left !important}.text-end{text-align:right !important}.text-center{text-align:center !important}.text-decoration-none{text-decoration:none !important}.text-decoration-underline{text-decoration:underline !important}.text-decoration-line-through{text-decoration:line-through !important}.text-lowercase{text-transform:lowercase !important}.text-uppercase{text-transform:uppercase !important}.text-capitalize{text-transform:capitalize !important}.text-wrap{white-space:normal !important}.text-nowrap{white-space:nowrap !important}.text-break{word-wrap:break-word !important;word-break:break-word !important}.text-default{--bs-text-opacity: 1;color:rgba(var(--bs-default-rgb), var(--bs-text-opacity)) !important}.text-primary{--bs-text-opacity: 1;color:rgba(var(--bs-primary-rgb), var(--bs-text-opacity)) !important}.text-secondary{--bs-text-opacity: 1;color:rgba(var(--bs-secondary-rgb), var(--bs-text-opacity)) !important}.text-success{--bs-text-opacity: 1;color:rgba(var(--bs-success-rgb), var(--bs-text-opacity)) !important}.text-info{--bs-text-opacity: 1;color:rgba(var(--bs-info-rgb), var(--bs-text-opacity)) !important}.text-warning{--bs-text-opacity: 1;color:rgba(var(--bs-warning-rgb), var(--bs-text-opacity)) !important}.text-danger{--bs-text-opacity: 1;color:rgba(var(--bs-danger-rgb), var(--bs-text-opacity)) !important}.text-light{--bs-text-opacity: 1;color:rgba(var(--bs-light-rgb), var(--bs-text-opacity)) !important}.text-dark{--bs-text-opacity: 1;color:rgba(var(--bs-dark-rgb), var(--bs-text-opacity)) !important}.text-black{--bs-text-opacity: 1;color:rgba(var(--bs-black-rgb), var(--bs-text-opacity)) !important}.text-white{--bs-text-opacity: 1;color:rgba(var(--bs-white-rgb), var(--bs-text-opacity)) !important}.text-body{--bs-text-opacity: 1;color:rgba(var(--bs-body-color-rgb), var(--bs-text-opacity)) !important}.text-muted{--bs-text-opacity: 1;color:#6c757d !important}.text-black-50{--bs-text-opacity: 1;color:rgba(0,0,0,.5) !important}.text-white-50{--bs-text-opacity: 1;color:rgba(255,255,255,.5) !important}.text-reset{--bs-text-opacity: 1;color:inherit !important}.text-opacity-25{--bs-text-opacity: 0.25}.text-opacity-50{--bs-text-opacity: 0.5}.text-opacity-75{--bs-text-opacity: 0.75}.text-opacity-100{--bs-text-opacity: 1}.bg-default{--bs-bg-opacity: 1;background-color:rgba(var(--bs-default-rgb), var(--bs-bg-opacity)) !important}.bg-primary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-primary-rgb), var(--bs-bg-opacity)) !important}.bg-secondary{--bs-bg-opacity: 1;background-color:rgba(var(--bs-secondary-rgb), var(--bs-bg-opacity)) !important}.bg-success{--bs-bg-opacity: 1;background-color:rgba(var(--bs-success-rgb), var(--bs-bg-opacity)) !important}.bg-info{--bs-bg-opacity: 1;background-color:rgba(var(--bs-info-rgb), var(--bs-bg-opacity)) !important}.bg-warning{--bs-bg-opacity: 1;background-color:rgba(var(--bs-warning-rgb), var(--bs-bg-opacity)) !important}.bg-danger{--bs-bg-opacity: 1;background-color:rgba(var(--bs-danger-rgb), var(--bs-bg-opacity)) !important}.bg-light{--bs-bg-opacity: 1;background-color:rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important}.bg-dark{--bs-bg-opacity: 1;background-color:rgba(var(--bs-dark-rgb), var(--bs-bg-opacity)) !important}.bg-black{--bs-bg-opacity: 1;background-color:rgba(var(--bs-black-rgb), var(--bs-bg-opacity)) !important}.bg-white{--bs-bg-opacity: 1;background-color:rgba(var(--bs-white-rgb), var(--bs-bg-opacity)) !important}.bg-body{--bs-bg-opacity: 1;background-color:rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important}.bg-transparent{--bs-bg-opacity: 1;background-color:rgba(0,0,0,0) !important}.bg-opacity-10{--bs-bg-opacity: 0.1}.bg-opacity-25{--bs-bg-opacity: 0.25}.bg-opacity-50{--bs-bg-opacity: 0.5}.bg-opacity-75{--bs-bg-opacity: 0.75}.bg-opacity-100{--bs-bg-opacity: 1}.bg-gradient{background-image:var(--bs-gradient) !important}.user-select-all{user-select:all !important}.user-select-auto{user-select:auto !important}.user-select-none{user-select:none !important}.pe-none{pointer-events:none !important}.pe-auto{pointer-events:auto !important}.rounded{border-radius:.25rem !important}.rounded-0{border-radius:0 !important}.rounded-1{border-radius:.2em !important}.rounded-2{border-radius:.25rem !important}.rounded-3{border-radius:.3rem !important}.rounded-circle{border-radius:50% !important}.rounded-pill{border-radius:50rem !important}.rounded-top{border-top-left-radius:.25rem !important;border-top-right-radius:.25rem !important}.rounded-end{border-top-right-radius:.25rem !important;border-bottom-right-radius:.25rem !important}.rounded-bottom{border-bottom-right-radius:.25rem !important;border-bottom-left-radius:.25rem !important}.rounded-start{border-bottom-left-radius:.25rem !important;border-top-left-radius:.25rem !important}.visible{visibility:visible !important}.invisible{visibility:hidden !important}@media(min-width: 576px){.float-sm-start{float:left !important}.float-sm-end{float:right !important}.float-sm-none{float:none !important}.d-sm-inline{display:inline !important}.d-sm-inline-block{display:inline-block !important}.d-sm-block{display:block !important}.d-sm-grid{display:grid !important}.d-sm-table{display:table !important}.d-sm-table-row{display:table-row !important}.d-sm-table-cell{display:table-cell !important}.d-sm-flex{display:flex !important}.d-sm-inline-flex{display:inline-flex !important}.d-sm-none{display:none !important}.flex-sm-fill{flex:1 1 auto !important}.flex-sm-row{flex-direction:row !important}.flex-sm-column{flex-direction:column !important}.flex-sm-row-reverse{flex-direction:row-reverse !important}.flex-sm-column-reverse{flex-direction:column-reverse !important}.flex-sm-grow-0{flex-grow:0 !important}.flex-sm-grow-1{flex-grow:1 !important}.flex-sm-shrink-0{flex-shrink:0 !important}.flex-sm-shrink-1{flex-shrink:1 !important}.flex-sm-wrap{flex-wrap:wrap !important}.flex-sm-nowrap{flex-wrap:nowrap !important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-sm-0{gap:0 !important}.gap-sm-1{gap:.25rem !important}.gap-sm-2{gap:.5rem !important}.gap-sm-3{gap:1rem !important}.gap-sm-4{gap:1.5rem !important}.gap-sm-5{gap:3rem !important}.justify-content-sm-start{justify-content:flex-start !important}.justify-content-sm-end{justify-content:flex-end !important}.justify-content-sm-center{justify-content:center !important}.justify-content-sm-between{justify-content:space-between !important}.justify-content-sm-around{justify-content:space-around !important}.justify-content-sm-evenly{justify-content:space-evenly !important}.align-items-sm-start{align-items:flex-start !important}.align-items-sm-end{align-items:flex-end !important}.align-items-sm-center{align-items:center !important}.align-items-sm-baseline{align-items:baseline !important}.align-items-sm-stretch{align-items:stretch !important}.align-content-sm-start{align-content:flex-start !important}.align-content-sm-end{align-content:flex-end !important}.align-content-sm-center{align-content:center !important}.align-content-sm-between{align-content:space-between !important}.align-content-sm-around{align-content:space-around !important}.align-content-sm-stretch{align-content:stretch !important}.align-self-sm-auto{align-self:auto !important}.align-self-sm-start{align-self:flex-start !important}.align-self-sm-end{align-self:flex-end !important}.align-self-sm-center{align-self:center !important}.align-self-sm-baseline{align-self:baseline !important}.align-self-sm-stretch{align-self:stretch !important}.order-sm-first{order:-1 !important}.order-sm-0{order:0 !important}.order-sm-1{order:1 !important}.order-sm-2{order:2 !important}.order-sm-3{order:3 !important}.order-sm-4{order:4 !important}.order-sm-5{order:5 !important}.order-sm-last{order:6 !important}.m-sm-0{margin:0 !important}.m-sm-1{margin:.25rem !important}.m-sm-2{margin:.5rem !important}.m-sm-3{margin:1rem !important}.m-sm-4{margin:1.5rem !important}.m-sm-5{margin:3rem !important}.m-sm-auto{margin:auto !important}.mx-sm-0{margin-right:0 !important;margin-left:0 !important}.mx-sm-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-sm-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-sm-3{margin-right:1rem !important;margin-left:1rem !important}.mx-sm-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-sm-5{margin-right:3rem !important;margin-left:3rem !important}.mx-sm-auto{margin-right:auto !important;margin-left:auto !important}.my-sm-0{margin-top:0 !important;margin-bottom:0 !important}.my-sm-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-sm-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-sm-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-sm-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-sm-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-sm-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-sm-0{margin-top:0 !important}.mt-sm-1{margin-top:.25rem !important}.mt-sm-2{margin-top:.5rem !important}.mt-sm-3{margin-top:1rem !important}.mt-sm-4{margin-top:1.5rem !important}.mt-sm-5{margin-top:3rem !important}.mt-sm-auto{margin-top:auto !important}.me-sm-0{margin-right:0 !important}.me-sm-1{margin-right:.25rem !important}.me-sm-2{margin-right:.5rem !important}.me-sm-3{margin-right:1rem !important}.me-sm-4{margin-right:1.5rem !important}.me-sm-5{margin-right:3rem !important}.me-sm-auto{margin-right:auto !important}.mb-sm-0{margin-bottom:0 !important}.mb-sm-1{margin-bottom:.25rem !important}.mb-sm-2{margin-bottom:.5rem !important}.mb-sm-3{margin-bottom:1rem !important}.mb-sm-4{margin-bottom:1.5rem !important}.mb-sm-5{margin-bottom:3rem !important}.mb-sm-auto{margin-bottom:auto !important}.ms-sm-0{margin-left:0 !important}.ms-sm-1{margin-left:.25rem !important}.ms-sm-2{margin-left:.5rem !important}.ms-sm-3{margin-left:1rem !important}.ms-sm-4{margin-left:1.5rem !important}.ms-sm-5{margin-left:3rem !important}.ms-sm-auto{margin-left:auto !important}.p-sm-0{padding:0 !important}.p-sm-1{padding:.25rem !important}.p-sm-2{padding:.5rem !important}.p-sm-3{padding:1rem !important}.p-sm-4{padding:1.5rem !important}.p-sm-5{padding:3rem !important}.px-sm-0{padding-right:0 !important;padding-left:0 !important}.px-sm-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-sm-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-sm-3{padding-right:1rem !important;padding-left:1rem !important}.px-sm-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-sm-5{padding-right:3rem !important;padding-left:3rem !important}.py-sm-0{padding-top:0 !important;padding-bottom:0 !important}.py-sm-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-sm-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-sm-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-sm-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-sm-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-sm-0{padding-top:0 !important}.pt-sm-1{padding-top:.25rem !important}.pt-sm-2{padding-top:.5rem !important}.pt-sm-3{padding-top:1rem !important}.pt-sm-4{padding-top:1.5rem !important}.pt-sm-5{padding-top:3rem !important}.pe-sm-0{padding-right:0 !important}.pe-sm-1{padding-right:.25rem !important}.pe-sm-2{padding-right:.5rem !important}.pe-sm-3{padding-right:1rem !important}.pe-sm-4{padding-right:1.5rem !important}.pe-sm-5{padding-right:3rem !important}.pb-sm-0{padding-bottom:0 !important}.pb-sm-1{padding-bottom:.25rem !important}.pb-sm-2{padding-bottom:.5rem !important}.pb-sm-3{padding-bottom:1rem !important}.pb-sm-4{padding-bottom:1.5rem !important}.pb-sm-5{padding-bottom:3rem !important}.ps-sm-0{padding-left:0 !important}.ps-sm-1{padding-left:.25rem !important}.ps-sm-2{padding-left:.5rem !important}.ps-sm-3{padding-left:1rem !important}.ps-sm-4{padding-left:1.5rem !important}.ps-sm-5{padding-left:3rem !important}.text-sm-start{text-align:left !important}.text-sm-end{text-align:right !important}.text-sm-center{text-align:center !important}}@media(min-width: 768px){.float-md-start{float:left !important}.float-md-end{float:right !important}.float-md-none{float:none !important}.d-md-inline{display:inline !important}.d-md-inline-block{display:inline-block !important}.d-md-block{display:block !important}.d-md-grid{display:grid !important}.d-md-table{display:table !important}.d-md-table-row{display:table-row !important}.d-md-table-cell{display:table-cell !important}.d-md-flex{display:flex !important}.d-md-inline-flex{display:inline-flex !important}.d-md-none{display:none !important}.flex-md-fill{flex:1 1 auto !important}.flex-md-row{flex-direction:row !important}.flex-md-column{flex-direction:column !important}.flex-md-row-reverse{flex-direction:row-reverse !important}.flex-md-column-reverse{flex-direction:column-reverse !important}.flex-md-grow-0{flex-grow:0 !important}.flex-md-grow-1{flex-grow:1 !important}.flex-md-shrink-0{flex-shrink:0 !important}.flex-md-shrink-1{flex-shrink:1 !important}.flex-md-wrap{flex-wrap:wrap !important}.flex-md-nowrap{flex-wrap:nowrap !important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-md-0{gap:0 !important}.gap-md-1{gap:.25rem !important}.gap-md-2{gap:.5rem !important}.gap-md-3{gap:1rem !important}.gap-md-4{gap:1.5rem !important}.gap-md-5{gap:3rem !important}.justify-content-md-start{justify-content:flex-start !important}.justify-content-md-end{justify-content:flex-end !important}.justify-content-md-center{justify-content:center !important}.justify-content-md-between{justify-content:space-between !important}.justify-content-md-around{justify-content:space-around !important}.justify-content-md-evenly{justify-content:space-evenly !important}.align-items-md-start{align-items:flex-start !important}.align-items-md-end{align-items:flex-end !important}.align-items-md-center{align-items:center !important}.align-items-md-baseline{align-items:baseline !important}.align-items-md-stretch{align-items:stretch !important}.align-content-md-start{align-content:flex-start !important}.align-content-md-end{align-content:flex-end !important}.align-content-md-center{align-content:center !important}.align-content-md-between{align-content:space-between !important}.align-content-md-around{align-content:space-around !important}.align-content-md-stretch{align-content:stretch !important}.align-self-md-auto{align-self:auto !important}.align-self-md-start{align-self:flex-start !important}.align-self-md-end{align-self:flex-end !important}.align-self-md-center{align-self:center !important}.align-self-md-baseline{align-self:baseline !important}.align-self-md-stretch{align-self:stretch !important}.order-md-first{order:-1 !important}.order-md-0{order:0 !important}.order-md-1{order:1 !important}.order-md-2{order:2 !important}.order-md-3{order:3 !important}.order-md-4{order:4 !important}.order-md-5{order:5 !important}.order-md-last{order:6 !important}.m-md-0{margin:0 !important}.m-md-1{margin:.25rem !important}.m-md-2{margin:.5rem !important}.m-md-3{margin:1rem !important}.m-md-4{margin:1.5rem !important}.m-md-5{margin:3rem !important}.m-md-auto{margin:auto !important}.mx-md-0{margin-right:0 !important;margin-left:0 !important}.mx-md-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-md-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-md-3{margin-right:1rem !important;margin-left:1rem !important}.mx-md-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-md-5{margin-right:3rem !important;margin-left:3rem !important}.mx-md-auto{margin-right:auto !important;margin-left:auto !important}.my-md-0{margin-top:0 !important;margin-bottom:0 !important}.my-md-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-md-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-md-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-md-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-md-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-md-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-md-0{margin-top:0 !important}.mt-md-1{margin-top:.25rem !important}.mt-md-2{margin-top:.5rem !important}.mt-md-3{margin-top:1rem !important}.mt-md-4{margin-top:1.5rem !important}.mt-md-5{margin-top:3rem !important}.mt-md-auto{margin-top:auto !important}.me-md-0{margin-right:0 !important}.me-md-1{margin-right:.25rem !important}.me-md-2{margin-right:.5rem !important}.me-md-3{margin-right:1rem !important}.me-md-4{margin-right:1.5rem !important}.me-md-5{margin-right:3rem !important}.me-md-auto{margin-right:auto !important}.mb-md-0{margin-bottom:0 !important}.mb-md-1{margin-bottom:.25rem !important}.mb-md-2{margin-bottom:.5rem !important}.mb-md-3{margin-bottom:1rem !important}.mb-md-4{margin-bottom:1.5rem !important}.mb-md-5{margin-bottom:3rem !important}.mb-md-auto{margin-bottom:auto !important}.ms-md-0{margin-left:0 !important}.ms-md-1{margin-left:.25rem !important}.ms-md-2{margin-left:.5rem !important}.ms-md-3{margin-left:1rem !important}.ms-md-4{margin-left:1.5rem !important}.ms-md-5{margin-left:3rem !important}.ms-md-auto{margin-left:auto !important}.p-md-0{padding:0 !important}.p-md-1{padding:.25rem !important}.p-md-2{padding:.5rem !important}.p-md-3{padding:1rem !important}.p-md-4{padding:1.5rem !important}.p-md-5{padding:3rem !important}.px-md-0{padding-right:0 !important;padding-left:0 !important}.px-md-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-md-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-md-3{padding-right:1rem !important;padding-left:1rem !important}.px-md-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-md-5{padding-right:3rem !important;padding-left:3rem !important}.py-md-0{padding-top:0 !important;padding-bottom:0 !important}.py-md-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-md-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-md-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-md-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-md-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-md-0{padding-top:0 !important}.pt-md-1{padding-top:.25rem !important}.pt-md-2{padding-top:.5rem !important}.pt-md-3{padding-top:1rem !important}.pt-md-4{padding-top:1.5rem !important}.pt-md-5{padding-top:3rem !important}.pe-md-0{padding-right:0 !important}.pe-md-1{padding-right:.25rem !important}.pe-md-2{padding-right:.5rem !important}.pe-md-3{padding-right:1rem !important}.pe-md-4{padding-right:1.5rem !important}.pe-md-5{padding-right:3rem !important}.pb-md-0{padding-bottom:0 !important}.pb-md-1{padding-bottom:.25rem !important}.pb-md-2{padding-bottom:.5rem !important}.pb-md-3{padding-bottom:1rem !important}.pb-md-4{padding-bottom:1.5rem !important}.pb-md-5{padding-bottom:3rem !important}.ps-md-0{padding-left:0 !important}.ps-md-1{padding-left:.25rem !important}.ps-md-2{padding-left:.5rem !important}.ps-md-3{padding-left:1rem !important}.ps-md-4{padding-left:1.5rem !important}.ps-md-5{padding-left:3rem !important}.text-md-start{text-align:left !important}.text-md-end{text-align:right !important}.text-md-center{text-align:center !important}}@media(min-width: 992px){.float-lg-start{float:left !important}.float-lg-end{float:right !important}.float-lg-none{float:none !important}.d-lg-inline{display:inline !important}.d-lg-inline-block{display:inline-block !important}.d-lg-block{display:block !important}.d-lg-grid{display:grid !important}.d-lg-table{display:table !important}.d-lg-table-row{display:table-row !important}.d-lg-table-cell{display:table-cell !important}.d-lg-flex{display:flex !important}.d-lg-inline-flex{display:inline-flex !important}.d-lg-none{display:none !important}.flex-lg-fill{flex:1 1 auto !important}.flex-lg-row{flex-direction:row !important}.flex-lg-column{flex-direction:column !important}.flex-lg-row-reverse{flex-direction:row-reverse !important}.flex-lg-column-reverse{flex-direction:column-reverse !important}.flex-lg-grow-0{flex-grow:0 !important}.flex-lg-grow-1{flex-grow:1 !important}.flex-lg-shrink-0{flex-shrink:0 !important}.flex-lg-shrink-1{flex-shrink:1 !important}.flex-lg-wrap{flex-wrap:wrap !important}.flex-lg-nowrap{flex-wrap:nowrap !important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-lg-0{gap:0 !important}.gap-lg-1{gap:.25rem !important}.gap-lg-2{gap:.5rem !important}.gap-lg-3{gap:1rem !important}.gap-lg-4{gap:1.5rem !important}.gap-lg-5{gap:3rem !important}.justify-content-lg-start{justify-content:flex-start !important}.justify-content-lg-end{justify-content:flex-end !important}.justify-content-lg-center{justify-content:center !important}.justify-content-lg-between{justify-content:space-between !important}.justify-content-lg-around{justify-content:space-around !important}.justify-content-lg-evenly{justify-content:space-evenly !important}.align-items-lg-start{align-items:flex-start !important}.align-items-lg-end{align-items:flex-end !important}.align-items-lg-center{align-items:center !important}.align-items-lg-baseline{align-items:baseline !important}.align-items-lg-stretch{align-items:stretch !important}.align-content-lg-start{align-content:flex-start !important}.align-content-lg-end{align-content:flex-end !important}.align-content-lg-center{align-content:center !important}.align-content-lg-between{align-content:space-between !important}.align-content-lg-around{align-content:space-around !important}.align-content-lg-stretch{align-content:stretch !important}.align-self-lg-auto{align-self:auto !important}.align-self-lg-start{align-self:flex-start !important}.align-self-lg-end{align-self:flex-end !important}.align-self-lg-center{align-self:center !important}.align-self-lg-baseline{align-self:baseline !important}.align-self-lg-stretch{align-self:stretch !important}.order-lg-first{order:-1 !important}.order-lg-0{order:0 !important}.order-lg-1{order:1 !important}.order-lg-2{order:2 !important}.order-lg-3{order:3 !important}.order-lg-4{order:4 !important}.order-lg-5{order:5 !important}.order-lg-last{order:6 !important}.m-lg-0{margin:0 !important}.m-lg-1{margin:.25rem !important}.m-lg-2{margin:.5rem !important}.m-lg-3{margin:1rem !important}.m-lg-4{margin:1.5rem !important}.m-lg-5{margin:3rem !important}.m-lg-auto{margin:auto !important}.mx-lg-0{margin-right:0 !important;margin-left:0 !important}.mx-lg-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-lg-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-lg-3{margin-right:1rem !important;margin-left:1rem !important}.mx-lg-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-lg-5{margin-right:3rem !important;margin-left:3rem !important}.mx-lg-auto{margin-right:auto !important;margin-left:auto !important}.my-lg-0{margin-top:0 !important;margin-bottom:0 !important}.my-lg-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-lg-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-lg-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-lg-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-lg-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-lg-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-lg-0{margin-top:0 !important}.mt-lg-1{margin-top:.25rem !important}.mt-lg-2{margin-top:.5rem !important}.mt-lg-3{margin-top:1rem !important}.mt-lg-4{margin-top:1.5rem !important}.mt-lg-5{margin-top:3rem !important}.mt-lg-auto{margin-top:auto !important}.me-lg-0{margin-right:0 !important}.me-lg-1{margin-right:.25rem !important}.me-lg-2{margin-right:.5rem !important}.me-lg-3{margin-right:1rem !important}.me-lg-4{margin-right:1.5rem !important}.me-lg-5{margin-right:3rem !important}.me-lg-auto{margin-right:auto !important}.mb-lg-0{margin-bottom:0 !important}.mb-lg-1{margin-bottom:.25rem !important}.mb-lg-2{margin-bottom:.5rem !important}.mb-lg-3{margin-bottom:1rem !important}.mb-lg-4{margin-bottom:1.5rem !important}.mb-lg-5{margin-bottom:3rem !important}.mb-lg-auto{margin-bottom:auto !important}.ms-lg-0{margin-left:0 !important}.ms-lg-1{margin-left:.25rem !important}.ms-lg-2{margin-left:.5rem !important}.ms-lg-3{margin-left:1rem !important}.ms-lg-4{margin-left:1.5rem !important}.ms-lg-5{margin-left:3rem !important}.ms-lg-auto{margin-left:auto !important}.p-lg-0{padding:0 !important}.p-lg-1{padding:.25rem !important}.p-lg-2{padding:.5rem !important}.p-lg-3{padding:1rem !important}.p-lg-4{padding:1.5rem !important}.p-lg-5{padding:3rem !important}.px-lg-0{padding-right:0 !important;padding-left:0 !important}.px-lg-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-lg-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-lg-3{padding-right:1rem !important;padding-left:1rem !important}.px-lg-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-lg-5{padding-right:3rem !important;padding-left:3rem !important}.py-lg-0{padding-top:0 !important;padding-bottom:0 !important}.py-lg-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-lg-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-lg-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-lg-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-lg-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-lg-0{padding-top:0 !important}.pt-lg-1{padding-top:.25rem !important}.pt-lg-2{padding-top:.5rem !important}.pt-lg-3{padding-top:1rem !important}.pt-lg-4{padding-top:1.5rem !important}.pt-lg-5{padding-top:3rem !important}.pe-lg-0{padding-right:0 !important}.pe-lg-1{padding-right:.25rem !important}.pe-lg-2{padding-right:.5rem !important}.pe-lg-3{padding-right:1rem !important}.pe-lg-4{padding-right:1.5rem !important}.pe-lg-5{padding-right:3rem !important}.pb-lg-0{padding-bottom:0 !important}.pb-lg-1{padding-bottom:.25rem !important}.pb-lg-2{padding-bottom:.5rem !important}.pb-lg-3{padding-bottom:1rem !important}.pb-lg-4{padding-bottom:1.5rem !important}.pb-lg-5{padding-bottom:3rem !important}.ps-lg-0{padding-left:0 !important}.ps-lg-1{padding-left:.25rem !important}.ps-lg-2{padding-left:.5rem !important}.ps-lg-3{padding-left:1rem !important}.ps-lg-4{padding-left:1.5rem !important}.ps-lg-5{padding-left:3rem !important}.text-lg-start{text-align:left !important}.text-lg-end{text-align:right !important}.text-lg-center{text-align:center !important}}@media(min-width: 1200px){.float-xl-start{float:left !important}.float-xl-end{float:right !important}.float-xl-none{float:none !important}.d-xl-inline{display:inline !important}.d-xl-inline-block{display:inline-block !important}.d-xl-block{display:block !important}.d-xl-grid{display:grid !important}.d-xl-table{display:table !important}.d-xl-table-row{display:table-row !important}.d-xl-table-cell{display:table-cell !important}.d-xl-flex{display:flex !important}.d-xl-inline-flex{display:inline-flex !important}.d-xl-none{display:none !important}.flex-xl-fill{flex:1 1 auto !important}.flex-xl-row{flex-direction:row !important}.flex-xl-column{flex-direction:column !important}.flex-xl-row-reverse{flex-direction:row-reverse !important}.flex-xl-column-reverse{flex-direction:column-reverse !important}.flex-xl-grow-0{flex-grow:0 !important}.flex-xl-grow-1{flex-grow:1 !important}.flex-xl-shrink-0{flex-shrink:0 !important}.flex-xl-shrink-1{flex-shrink:1 !important}.flex-xl-wrap{flex-wrap:wrap !important}.flex-xl-nowrap{flex-wrap:nowrap !important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xl-0{gap:0 !important}.gap-xl-1{gap:.25rem !important}.gap-xl-2{gap:.5rem !important}.gap-xl-3{gap:1rem !important}.gap-xl-4{gap:1.5rem !important}.gap-xl-5{gap:3rem !important}.justify-content-xl-start{justify-content:flex-start !important}.justify-content-xl-end{justify-content:flex-end !important}.justify-content-xl-center{justify-content:center !important}.justify-content-xl-between{justify-content:space-between !important}.justify-content-xl-around{justify-content:space-around !important}.justify-content-xl-evenly{justify-content:space-evenly !important}.align-items-xl-start{align-items:flex-start !important}.align-items-xl-end{align-items:flex-end !important}.align-items-xl-center{align-items:center !important}.align-items-xl-baseline{align-items:baseline !important}.align-items-xl-stretch{align-items:stretch !important}.align-content-xl-start{align-content:flex-start !important}.align-content-xl-end{align-content:flex-end !important}.align-content-xl-center{align-content:center !important}.align-content-xl-between{align-content:space-between !important}.align-content-xl-around{align-content:space-around !important}.align-content-xl-stretch{align-content:stretch !important}.align-self-xl-auto{align-self:auto !important}.align-self-xl-start{align-self:flex-start !important}.align-self-xl-end{align-self:flex-end !important}.align-self-xl-center{align-self:center !important}.align-self-xl-baseline{align-self:baseline !important}.align-self-xl-stretch{align-self:stretch !important}.order-xl-first{order:-1 !important}.order-xl-0{order:0 !important}.order-xl-1{order:1 !important}.order-xl-2{order:2 !important}.order-xl-3{order:3 !important}.order-xl-4{order:4 !important}.order-xl-5{order:5 !important}.order-xl-last{order:6 !important}.m-xl-0{margin:0 !important}.m-xl-1{margin:.25rem !important}.m-xl-2{margin:.5rem !important}.m-xl-3{margin:1rem !important}.m-xl-4{margin:1.5rem !important}.m-xl-5{margin:3rem !important}.m-xl-auto{margin:auto !important}.mx-xl-0{margin-right:0 !important;margin-left:0 !important}.mx-xl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xl-auto{margin-right:auto !important;margin-left:auto !important}.my-xl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xl-0{margin-top:0 !important}.mt-xl-1{margin-top:.25rem !important}.mt-xl-2{margin-top:.5rem !important}.mt-xl-3{margin-top:1rem !important}.mt-xl-4{margin-top:1.5rem !important}.mt-xl-5{margin-top:3rem !important}.mt-xl-auto{margin-top:auto !important}.me-xl-0{margin-right:0 !important}.me-xl-1{margin-right:.25rem !important}.me-xl-2{margin-right:.5rem !important}.me-xl-3{margin-right:1rem !important}.me-xl-4{margin-right:1.5rem !important}.me-xl-5{margin-right:3rem !important}.me-xl-auto{margin-right:auto !important}.mb-xl-0{margin-bottom:0 !important}.mb-xl-1{margin-bottom:.25rem !important}.mb-xl-2{margin-bottom:.5rem !important}.mb-xl-3{margin-bottom:1rem !important}.mb-xl-4{margin-bottom:1.5rem !important}.mb-xl-5{margin-bottom:3rem !important}.mb-xl-auto{margin-bottom:auto !important}.ms-xl-0{margin-left:0 !important}.ms-xl-1{margin-left:.25rem !important}.ms-xl-2{margin-left:.5rem !important}.ms-xl-3{margin-left:1rem !important}.ms-xl-4{margin-left:1.5rem !important}.ms-xl-5{margin-left:3rem !important}.ms-xl-auto{margin-left:auto !important}.p-xl-0{padding:0 !important}.p-xl-1{padding:.25rem !important}.p-xl-2{padding:.5rem !important}.p-xl-3{padding:1rem !important}.p-xl-4{padding:1.5rem !important}.p-xl-5{padding:3rem !important}.px-xl-0{padding-right:0 !important;padding-left:0 !important}.px-xl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xl-0{padding-top:0 !important}.pt-xl-1{padding-top:.25rem !important}.pt-xl-2{padding-top:.5rem !important}.pt-xl-3{padding-top:1rem !important}.pt-xl-4{padding-top:1.5rem !important}.pt-xl-5{padding-top:3rem !important}.pe-xl-0{padding-right:0 !important}.pe-xl-1{padding-right:.25rem !important}.pe-xl-2{padding-right:.5rem !important}.pe-xl-3{padding-right:1rem !important}.pe-xl-4{padding-right:1.5rem !important}.pe-xl-5{padding-right:3rem !important}.pb-xl-0{padding-bottom:0 !important}.pb-xl-1{padding-bottom:.25rem !important}.pb-xl-2{padding-bottom:.5rem !important}.pb-xl-3{padding-bottom:1rem !important}.pb-xl-4{padding-bottom:1.5rem !important}.pb-xl-5{padding-bottom:3rem !important}.ps-xl-0{padding-left:0 !important}.ps-xl-1{padding-left:.25rem !important}.ps-xl-2{padding-left:.5rem !important}.ps-xl-3{padding-left:1rem !important}.ps-xl-4{padding-left:1.5rem !important}.ps-xl-5{padding-left:3rem !important}.text-xl-start{text-align:left !important}.text-xl-end{text-align:right !important}.text-xl-center{text-align:center !important}}@media(min-width: 1400px){.float-xxl-start{float:left !important}.float-xxl-end{float:right !important}.float-xxl-none{float:none !important}.d-xxl-inline{display:inline !important}.d-xxl-inline-block{display:inline-block !important}.d-xxl-block{display:block !important}.d-xxl-grid{display:grid !important}.d-xxl-table{display:table !important}.d-xxl-table-row{display:table-row !important}.d-xxl-table-cell{display:table-cell !important}.d-xxl-flex{display:flex !important}.d-xxl-inline-flex{display:inline-flex !important}.d-xxl-none{display:none !important}.flex-xxl-fill{flex:1 1 auto !important}.flex-xxl-row{flex-direction:row !important}.flex-xxl-column{flex-direction:column !important}.flex-xxl-row-reverse{flex-direction:row-reverse !important}.flex-xxl-column-reverse{flex-direction:column-reverse !important}.flex-xxl-grow-0{flex-grow:0 !important}.flex-xxl-grow-1{flex-grow:1 !important}.flex-xxl-shrink-0{flex-shrink:0 !important}.flex-xxl-shrink-1{flex-shrink:1 !important}.flex-xxl-wrap{flex-wrap:wrap !important}.flex-xxl-nowrap{flex-wrap:nowrap !important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse !important}.gap-xxl-0{gap:0 !important}.gap-xxl-1{gap:.25rem !important}.gap-xxl-2{gap:.5rem !important}.gap-xxl-3{gap:1rem !important}.gap-xxl-4{gap:1.5rem !important}.gap-xxl-5{gap:3rem !important}.justify-content-xxl-start{justify-content:flex-start !important}.justify-content-xxl-end{justify-content:flex-end !important}.justify-content-xxl-center{justify-content:center !important}.justify-content-xxl-between{justify-content:space-between !important}.justify-content-xxl-around{justify-content:space-around !important}.justify-content-xxl-evenly{justify-content:space-evenly !important}.align-items-xxl-start{align-items:flex-start !important}.align-items-xxl-end{align-items:flex-end !important}.align-items-xxl-center{align-items:center !important}.align-items-xxl-baseline{align-items:baseline !important}.align-items-xxl-stretch{align-items:stretch !important}.align-content-xxl-start{align-content:flex-start !important}.align-content-xxl-end{align-content:flex-end !important}.align-content-xxl-center{align-content:center !important}.align-content-xxl-between{align-content:space-between !important}.align-content-xxl-around{align-content:space-around !important}.align-content-xxl-stretch{align-content:stretch !important}.align-self-xxl-auto{align-self:auto !important}.align-self-xxl-start{align-self:flex-start !important}.align-self-xxl-end{align-self:flex-end !important}.align-self-xxl-center{align-self:center !important}.align-self-xxl-baseline{align-self:baseline !important}.align-self-xxl-stretch{align-self:stretch !important}.order-xxl-first{order:-1 !important}.order-xxl-0{order:0 !important}.order-xxl-1{order:1 !important}.order-xxl-2{order:2 !important}.order-xxl-3{order:3 !important}.order-xxl-4{order:4 !important}.order-xxl-5{order:5 !important}.order-xxl-last{order:6 !important}.m-xxl-0{margin:0 !important}.m-xxl-1{margin:.25rem !important}.m-xxl-2{margin:.5rem !important}.m-xxl-3{margin:1rem !important}.m-xxl-4{margin:1.5rem !important}.m-xxl-5{margin:3rem !important}.m-xxl-auto{margin:auto !important}.mx-xxl-0{margin-right:0 !important;margin-left:0 !important}.mx-xxl-1{margin-right:.25rem !important;margin-left:.25rem !important}.mx-xxl-2{margin-right:.5rem !important;margin-left:.5rem !important}.mx-xxl-3{margin-right:1rem !important;margin-left:1rem !important}.mx-xxl-4{margin-right:1.5rem !important;margin-left:1.5rem !important}.mx-xxl-5{margin-right:3rem !important;margin-left:3rem !important}.mx-xxl-auto{margin-right:auto !important;margin-left:auto !important}.my-xxl-0{margin-top:0 !important;margin-bottom:0 !important}.my-xxl-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.my-xxl-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.my-xxl-3{margin-top:1rem !important;margin-bottom:1rem !important}.my-xxl-4{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.my-xxl-5{margin-top:3rem !important;margin-bottom:3rem !important}.my-xxl-auto{margin-top:auto !important;margin-bottom:auto !important}.mt-xxl-0{margin-top:0 !important}.mt-xxl-1{margin-top:.25rem !important}.mt-xxl-2{margin-top:.5rem !important}.mt-xxl-3{margin-top:1rem !important}.mt-xxl-4{margin-top:1.5rem !important}.mt-xxl-5{margin-top:3rem !important}.mt-xxl-auto{margin-top:auto !important}.me-xxl-0{margin-right:0 !important}.me-xxl-1{margin-right:.25rem !important}.me-xxl-2{margin-right:.5rem !important}.me-xxl-3{margin-right:1rem !important}.me-xxl-4{margin-right:1.5rem !important}.me-xxl-5{margin-right:3rem !important}.me-xxl-auto{margin-right:auto !important}.mb-xxl-0{margin-bottom:0 !important}.mb-xxl-1{margin-bottom:.25rem !important}.mb-xxl-2{margin-bottom:.5rem !important}.mb-xxl-3{margin-bottom:1rem !important}.mb-xxl-4{margin-bottom:1.5rem !important}.mb-xxl-5{margin-bottom:3rem !important}.mb-xxl-auto{margin-bottom:auto !important}.ms-xxl-0{margin-left:0 !important}.ms-xxl-1{margin-left:.25rem !important}.ms-xxl-2{margin-left:.5rem !important}.ms-xxl-3{margin-left:1rem !important}.ms-xxl-4{margin-left:1.5rem !important}.ms-xxl-5{margin-left:3rem !important}.ms-xxl-auto{margin-left:auto !important}.p-xxl-0{padding:0 !important}.p-xxl-1{padding:.25rem !important}.p-xxl-2{padding:.5rem !important}.p-xxl-3{padding:1rem !important}.p-xxl-4{padding:1.5rem !important}.p-xxl-5{padding:3rem !important}.px-xxl-0{padding-right:0 !important;padding-left:0 !important}.px-xxl-1{padding-right:.25rem !important;padding-left:.25rem !important}.px-xxl-2{padding-right:.5rem !important;padding-left:.5rem !important}.px-xxl-3{padding-right:1rem !important;padding-left:1rem !important}.px-xxl-4{padding-right:1.5rem !important;padding-left:1.5rem !important}.px-xxl-5{padding-right:3rem !important;padding-left:3rem !important}.py-xxl-0{padding-top:0 !important;padding-bottom:0 !important}.py-xxl-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.py-xxl-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.py-xxl-3{padding-top:1rem !important;padding-bottom:1rem !important}.py-xxl-4{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.py-xxl-5{padding-top:3rem !important;padding-bottom:3rem !important}.pt-xxl-0{padding-top:0 !important}.pt-xxl-1{padding-top:.25rem !important}.pt-xxl-2{padding-top:.5rem !important}.pt-xxl-3{padding-top:1rem !important}.pt-xxl-4{padding-top:1.5rem !important}.pt-xxl-5{padding-top:3rem !important}.pe-xxl-0{padding-right:0 !important}.pe-xxl-1{padding-right:.25rem !important}.pe-xxl-2{padding-right:.5rem !important}.pe-xxl-3{padding-right:1rem !important}.pe-xxl-4{padding-right:1.5rem !important}.pe-xxl-5{padding-right:3rem !important}.pb-xxl-0{padding-bottom:0 !important}.pb-xxl-1{padding-bottom:.25rem !important}.pb-xxl-2{padding-bottom:.5rem !important}.pb-xxl-3{padding-bottom:1rem !important}.pb-xxl-4{padding-bottom:1.5rem !important}.pb-xxl-5{padding-bottom:3rem !important}.ps-xxl-0{padding-left:0 !important}.ps-xxl-1{padding-left:.25rem !important}.ps-xxl-2{padding-left:.5rem !important}.ps-xxl-3{padding-left:1rem !important}.ps-xxl-4{padding-left:1.5rem !important}.ps-xxl-5{padding-left:3rem !important}.text-xxl-start{text-align:left !important}.text-xxl-end{text-align:right !important}.text-xxl-center{text-align:center !important}}.bg-default{color:#fff}.bg-primary{color:#fff}.bg-secondary{color:#fff}.bg-success{color:#fff}.bg-info{color:#fff}.bg-warning{color:#fff}.bg-danger{color:#fff}.bg-light{color:#000}.bg-dark{color:#fff}@media(min-width: 1200px){.fs-1{font-size:2rem !important}.fs-2{font-size:1.65rem !important}.fs-3{font-size:1.45rem !important}}@media print{.d-print-inline{display:inline !important}.d-print-inline-block{display:inline-block !important}.d-print-block{display:block !important}.d-print-grid{display:grid !important}.d-print-table{display:table !important}.d-print-table-row{display:table-row !important}.d-print-table-cell{display:table-cell !important}.d-print-flex{display:flex !important}.d-print-inline-flex{display:inline-flex !important}.d-print-none{display:none !important}}.quarto-container{min-height:calc(100vh - 132px)}footer.footer .nav-footer,#quarto-header>nav{padding-left:1em;padding-right:1em}nav[role=doc-toc]{padding-left:.5em}#quarto-content>*{padding-top:14px}@media(max-width: 991.98px){#quarto-content>*{padding-top:0}#quarto-content .subtitle{padding-top:14px}#quarto-content section:first-of-type h2:first-of-type,#quarto-content section:first-of-type .h2:first-of-type{margin-top:1rem}}.headroom-target,header.headroom{will-change:transform;transition:position 200ms linear;transition:all 200ms linear}header.headroom--pinned{transform:translateY(0%)}header.headroom--unpinned{transform:translateY(-100%)}.navbar-container{width:100%}.navbar-brand{overflow:hidden;text-overflow:ellipsis}.navbar-brand-container{max-width:calc(100% - 115px);min-width:0;display:flex;align-items:center}@media(min-width: 992px){.navbar-brand-container{margin-right:1em}}.navbar-brand.navbar-brand-logo{margin-right:4px;display:inline-flex}.navbar-toggler{flex-basis:content;flex-shrink:0}.navbar .navbar-toggler{order:-1;margin-right:.5em}.navbar-logo{max-height:24px;width:auto;padding-right:4px}nav .nav-item:not(.compact){padding-top:1px}nav .nav-link i,nav .dropdown-item i{padding-right:1px}.navbar-expand-lg .navbar-nav .nav-link{padding-left:.6rem;padding-right:.6rem}nav .nav-item.compact .nav-link{padding-left:.5rem;padding-right:.5rem;font-size:1.1rem}.navbar .quarto-navbar-tools div.dropdown{display:inline-block}.navbar .quarto-navbar-tools .quarto-navigation-tool{color:#fdfeff}.navbar .quarto-navbar-tools .quarto-navigation-tool:hover{color:#fdfeff}@media(max-width: 991.98px){.navbar .quarto-navbar-tools{margin-top:.25em;padding-top:.75em;display:block;color:solid #007ffd 1px;text-align:center;vertical-align:middle;margin-right:auto}}.navbar-nav .dropdown-menu{min-width:220px;font-size:.9rem}.navbar .navbar-nav .nav-link.dropdown-toggle::after{opacity:.75;vertical-align:.175em}.navbar ul.dropdown-menu{padding-top:0;padding-bottom:0}.navbar .dropdown-header{text-transform:uppercase;font-size:.8rem;padding:0 .5rem}.navbar .dropdown-item{padding:.4rem .5rem}.navbar .dropdown-item>i.bi{margin-left:.1rem;margin-right:.25em}.sidebar #quarto-search{margin-top:-1px}.sidebar #quarto-search svg.aa-SubmitIcon{width:16px;height:16px}.sidebar-navigation a{color:inherit}.sidebar-title{margin-top:.25rem;padding-bottom:.5rem;font-size:1.3rem;line-height:1.6rem;visibility:visible}.sidebar-title>a{font-size:inherit;text-decoration:none}.sidebar-title .sidebar-tools-main{margin-top:-6px}@media(max-width: 991.98px){#quarto-sidebar div.sidebar-header{padding-top:.2em}}.sidebar-header-stacked .sidebar-title{margin-top:.6rem}.sidebar-logo{max-width:90%;padding-bottom:.5rem}.sidebar-logo-link{text-decoration:none}.sidebar-navigation li a{text-decoration:none}.sidebar-navigation .quarto-navigation-tool{opacity:.7;font-size:.875rem}#quarto-sidebar>nav>.sidebar-tools-main{margin-left:14px}.sidebar-tools-main{display:inline-flex;margin-left:0px;order:2}.sidebar-tools-main:not(.tools-wide){vertical-align:middle}.sidebar-navigation .quarto-navigation-tool.dropdown-toggle::after{display:none}.sidebar.sidebar-navigation>*{padding-top:1em}.sidebar-item{margin-bottom:.2em}.sidebar-section{margin-top:.2em;padding-left:.5em;padding-bottom:.2em}.sidebar-item .sidebar-item-container{display:flex;justify-content:space-between}.sidebar-item-toggle:hover{cursor:pointer}.sidebar-item .sidebar-item-toggle .bi{font-size:.7rem;text-align:center}.sidebar-item .sidebar-item-toggle .bi-chevron-right::before{transition:transform 200ms ease}.sidebar-item .sidebar-item-toggle[aria-expanded=false] .bi-chevron-right::before{transform:none}.sidebar-item .sidebar-item-toggle[aria-expanded=true] .bi-chevron-right::before{transform:rotate(90deg)}.sidebar-navigation .sidebar-divider{margin-left:0;margin-right:0;margin-top:.5rem;margin-bottom:.5rem}@media(max-width: 991.98px){.quarto-secondary-nav{display:block}.quarto-secondary-nav button.quarto-search-button{padding-right:0em;padding-left:2em}.quarto-secondary-nav button.quarto-btn-toggle{margin-left:-0.75rem;margin-right:.15rem}.quarto-secondary-nav nav.quarto-page-breadcrumbs{display:flex;align-items:center;padding-right:1em;margin-left:-0.25em}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{text-decoration:none}.quarto-secondary-nav nav.quarto-page-breadcrumbs ol.breadcrumb{margin-bottom:0}}@media(min-width: 992px){.quarto-secondary-nav{display:none}}.quarto-secondary-nav .quarto-btn-toggle{color:#595959}.quarto-secondary-nav[aria-expanded=false] .quarto-btn-toggle .bi-chevron-right::before{transform:none}.quarto-secondary-nav[aria-expanded=true] .quarto-btn-toggle .bi-chevron-right::before{transform:rotate(90deg)}.quarto-secondary-nav .quarto-btn-toggle .bi-chevron-right::before{transition:transform 200ms ease}.quarto-secondary-nav{cursor:pointer}.quarto-secondary-nav-title{margin-top:.3em;color:#595959;padding-top:4px}.quarto-secondary-nav nav.quarto-page-breadcrumbs{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a{color:#595959}.quarto-secondary-nav nav.quarto-page-breadcrumbs a:hover{color:rgba(27,88,157,.8)}.quarto-secondary-nav nav.quarto-page-breadcrumbs .breadcrumb-item::before{color:#8c8c8c}div.sidebar-item-container{color:#595959}div.sidebar-item-container:hover,div.sidebar-item-container:focus{color:rgba(27,88,157,.8)}div.sidebar-item-container.disabled{color:rgba(89,89,89,.75)}div.sidebar-item-container .active,div.sidebar-item-container .show>.nav-link,div.sidebar-item-container .sidebar-link>code{color:#1b589d}div.sidebar.sidebar-navigation.rollup.quarto-sidebar-toggle-contents,nav.sidebar.sidebar-navigation:not(.rollup){background-color:#fff}@media(max-width: 991.98px){.sidebar-navigation .sidebar-item a,.nav-page .nav-page-text,.sidebar-navigation{font-size:1rem}.sidebar-navigation ul.sidebar-section.depth1 .sidebar-section-item{font-size:1.1rem}.sidebar-logo{display:none}.sidebar.sidebar-navigation{position:static;border-bottom:1px solid #dee2e6}.sidebar.sidebar-navigation.collapsing{position:fixed;z-index:1000}.sidebar.sidebar-navigation.show{position:fixed;z-index:1000}.sidebar.sidebar-navigation{min-height:100%}nav.quarto-secondary-nav{background-color:#fff;border-bottom:1px solid #dee2e6}.sidebar .sidebar-footer{visibility:visible;padding-top:1rem;position:inherit}.sidebar-tools-collapse{display:block}}#quarto-sidebar{transition:width .15s ease-in}#quarto-sidebar>*{padding-right:1em}@media(max-width: 991.98px){#quarto-sidebar .sidebar-menu-container{white-space:nowrap;min-width:225px}#quarto-sidebar.show{transition:width .15s ease-out}}@media(min-width: 992px){#quarto-sidebar{display:flex;flex-direction:column}.nav-page .nav-page-text,.sidebar-navigation .sidebar-section .sidebar-item{font-size:.875rem}.sidebar-navigation .sidebar-item{font-size:.925rem}.sidebar.sidebar-navigation{display:block;position:sticky}.sidebar-search{width:100%}.sidebar .sidebar-footer{visibility:visible}}@media(max-width: 991.98px){#quarto-sidebar-glass{position:fixed;top:0;bottom:0;left:0;right:0;background-color:rgba(255,255,255,0);transition:background-color .15s ease-in;z-index:-1}#quarto-sidebar-glass.collapsing{z-index:1000}#quarto-sidebar-glass.show{transition:background-color .15s ease-out;background-color:rgba(102,102,102,.4);z-index:1000}}.sidebar .sidebar-footer{padding:.5rem 1rem;align-self:flex-end;color:#6c757d;width:100%}.quarto-page-breadcrumbs .breadcrumb-item+.breadcrumb-item,.quarto-page-breadcrumbs .breadcrumb-item{padding-right:.33em;padding-left:0}.quarto-page-breadcrumbs .breadcrumb-item::before{padding-right:.33em}.quarto-sidebar-footer{font-size:.875em}.sidebar-section .bi-chevron-right{vertical-align:middle}.sidebar-section .bi-chevron-right::before{font-size:.9em}.notransition{-webkit-transition:none !important;-moz-transition:none !important;-o-transition:none !important;transition:none !important}.btn:focus:not(:focus-visible){box-shadow:none}.page-navigation{display:flex;justify-content:space-between}.nav-page{padding-bottom:.75em}.nav-page .bi{font-size:1.8rem;vertical-align:middle}.nav-page .nav-page-text{padding-left:.25em;padding-right:.25em}.nav-page a{color:#6c757d;text-decoration:none;display:flex;align-items:center}.nav-page a:hover{color:#1f66b6}.toc-actions{display:flex}.toc-actions p{margin-block-start:0;margin-block-end:0}.toc-actions a{text-decoration:none;color:inherit;font-weight:400}.toc-actions a:hover{color:#1f66b6}.toc-actions .action-links{margin-left:4px}.sidebar nav[role=doc-toc] .toc-actions .bi{margin-left:-4px;font-size:.7rem;color:#6c757d}.sidebar nav[role=doc-toc] .toc-actions .bi:before{padding-top:3px}#quarto-margin-sidebar .toc-actions .bi:before{margin-top:.3rem;font-size:.7rem;color:#6c757d;vertical-align:top}.sidebar nav[role=doc-toc] .toc-actions>div:first-of-type{margin-top:-3px}#quarto-margin-sidebar .toc-actions p,.sidebar nav[role=doc-toc] .toc-actions p{font-size:.875rem}.nav-footer .toc-actions{padding-bottom:.5em;padding-top:.5em}.nav-footer .toc-actions :first-child{margin-left:auto}.nav-footer .toc-actions :last-child{margin-right:auto}.nav-footer .toc-actions .action-links{display:flex}.nav-footer .toc-actions .action-links p{padding-right:1.5em}.nav-footer .toc-actions .action-links p:last-of-type{padding-right:0}.nav-footer{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:space-between;align-items:baseline;text-align:center;padding-top:.5rem;padding-bottom:.5rem;background-color:#fff}body.nav-fixed{padding-top:64px}.nav-footer-contents{color:#6c757d;margin-top:.25rem}.nav-footer{min-height:3.5em;color:#757575}.nav-footer a{color:#757575}.nav-footer .nav-footer-left{font-size:.825em}.nav-footer .nav-footer-center{font-size:.825em}.nav-footer .nav-footer-right{font-size:.825em}.nav-footer-left .footer-items,.nav-footer-center .footer-items,.nav-footer-right .footer-items{display:inline-flex;padding-top:.3em;padding-bottom:.3em;margin-bottom:0em}.nav-footer-left .footer-items .nav-link,.nav-footer-center .footer-items .nav-link,.nav-footer-right .footer-items .nav-link{padding-left:.6em;padding-right:.6em}.nav-footer-left{flex:1 1 0px;text-align:left}.nav-footer-right{flex:1 1 0px;text-align:right}.nav-footer-center{flex:1 1 0px;min-height:3em;text-align:center}.nav-footer-center .footer-items{justify-content:center}@media(max-width: 767.98px){.nav-footer-center{margin-top:3em}}.navbar .quarto-reader-toggle.reader .quarto-reader-toggle-btn{background-color:#fdfeff;border-radius:3px}.quarto-reader-toggle.reader.quarto-navigation-tool .quarto-reader-toggle-btn{background-color:#595959;border-radius:3px}.quarto-reader-toggle .quarto-reader-toggle-btn{display:inline-flex;padding-left:.2em;padding-right:.2em;margin-left:-0.2em;margin-right:-0.2em;text-align:center}.navbar .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle:not(.reader) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-reader-toggle.reader .bi::before{background-image:url('data:image/svg+xml,')}#quarto-back-to-top{display:none;position:fixed;bottom:50px;background-color:#fff;border-radius:.25rem;box-shadow:0 .2rem .5rem #6c757d,0 0 .05rem #6c757d;color:#6c757d;text-decoration:none;font-size:.9em;text-align:center;left:50%;padding:.4rem .8rem;transform:translate(-50%, 0)}.aa-DetachedOverlay ul.aa-List,#quarto-search-results ul.aa-List{list-style:none;padding-left:0}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{background-color:#fff;position:absolute;z-index:2000}#quarto-search-results .aa-Panel{max-width:400px}#quarto-search input{font-size:.925rem}@media(min-width: 992px){.navbar #quarto-search{margin-left:.25rem;order:999}}@media(max-width: 991.98px){#quarto-sidebar .sidebar-search{display:none}}#quarto-sidebar .sidebar-search .aa-Autocomplete{width:100%}.navbar .aa-Autocomplete .aa-Form{width:180px}.navbar #quarto-search.type-overlay .aa-Autocomplete{width:40px}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form{background-color:inherit;border:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form:focus-within{box-shadow:none;outline:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper{display:none}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-InputWrapper:focus-within{display:inherit}.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-Label svg,.navbar #quarto-search.type-overlay .aa-Autocomplete .aa-Form .aa-LoadingIndicator svg{width:26px;height:26px;color:#fdfeff;opacity:1}.navbar #quarto-search.type-overlay .aa-Autocomplete svg.aa-SubmitIcon{width:26px;height:26px;color:#fdfeff;opacity:1}.aa-Autocomplete .aa-Form,.aa-DetachedFormContainer .aa-Form{align-items:center;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;color:#373a3c;display:flex;line-height:1em;margin:0;position:relative;width:100%}.aa-Autocomplete .aa-Form:focus-within,.aa-DetachedFormContainer .aa-Form:focus-within{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;order:1}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{cursor:initial;flex-shrink:0;padding:0;text-align:left}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-Label svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator svg{color:#373a3c;opacity:.5}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-SubmitButton{appearance:none;background:none;border:0;margin:0}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-Autocomplete .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperPrefix .aa-LoadingIndicator[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapper,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper{order:3;position:relative;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input{appearance:none;background:none;border:0;color:#373a3c;font:inherit;height:calc(1.5em + .1rem + 2px);padding:0;width:100%}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::placeholder,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::placeholder{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input:focus{border-color:none;box-shadow:none;outline:none}.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-Autocomplete .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-decoration,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-cancel-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-button,.aa-DetachedFormContainer .aa-Form .aa-InputWrapper .aa-Input::-webkit-search-results-decoration{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix{align-items:center;display:flex;order:4}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton{align-items:center;background:none;border:0;color:#373a3c;opacity:.8;cursor:pointer;display:flex;margin:0;width:calc(1.5em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton:focus{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton[hidden]{display:none}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-ClearButton svg{width:calc(1.5em + 0.75rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton{border:none;align-items:center;background:none;color:#373a3c;opacity:.4;font-size:.7rem;cursor:pointer;display:none;margin:0;width:calc(1em + .1rem + 2px)}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:hover,.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton:focus{color:#373a3c;opacity:.8}.aa-Autocomplete .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden],.aa-DetachedFormContainer .aa-Form .aa-InputWrapperSuffix .aa-CopyButton[hidden]{display:none}.aa-PanelLayout:empty{display:none}.quarto-search-no-results.no-query{display:none}.aa-Source:has(.no-query){display:none}#quarto-search-results .aa-Panel{border:solid #ced4da 1px}#quarto-search-results .aa-SourceNoResults{width:398px}.aa-DetachedOverlay .aa-Panel,#quarto-search-results .aa-Panel{max-height:65vh;overflow-y:auto;font-size:.925rem}.aa-DetachedOverlay .aa-SourceNoResults,#quarto-search-results .aa-SourceNoResults{height:60px;display:flex;justify-content:center;align-items:center}.aa-DetachedOverlay .search-error,#quarto-search-results .search-error{padding-top:10px;padding-left:20px;padding-right:20px;cursor:default}.aa-DetachedOverlay .search-error .search-error-title,#quarto-search-results .search-error .search-error-title{font-size:1.1rem;margin-bottom:.5rem}.aa-DetachedOverlay .search-error .search-error-title .search-error-icon,#quarto-search-results .search-error .search-error-title .search-error-icon{margin-right:8px}.aa-DetachedOverlay .search-error .search-error-text,#quarto-search-results .search-error .search-error-text{font-weight:300}.aa-DetachedOverlay .search-result-text,#quarto-search-results .search-result-text{font-weight:300;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.2rem;max-height:2.4rem}.aa-DetachedOverlay .aa-SourceHeader .search-result-header,#quarto-search-results .aa-SourceHeader .search-result-header{font-size:.875rem;background-color:#f2f2f2;padding-left:14px;padding-bottom:4px;padding-top:4px}.aa-DetachedOverlay .aa-SourceHeader .search-result-header-no-results,#quarto-search-results .aa-SourceHeader .search-result-header-no-results{display:none}.aa-DetachedOverlay .aa-SourceFooter .algolia-search-logo,#quarto-search-results .aa-SourceFooter .algolia-search-logo{width:110px;opacity:.85;margin:8px;float:right}.aa-DetachedOverlay .search-result-section,#quarto-search-results .search-result-section{font-size:.925em}.aa-DetachedOverlay a.search-result-link,#quarto-search-results a.search-result-link{color:inherit;text-decoration:none}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item,#quarto-search-results li.aa-Item[aria-selected=true] .search-item{background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-result-text-container{color:#fff;background-color:#2780e3}.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=true] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=true] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=true] .search-item .search-match.mark{color:#fff;background-color:#4b95e8}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item,#quarto-search-results li.aa-Item[aria-selected=false] .search-item{background-color:#fff}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item.search-result-more,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-section,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-title-container,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-result-text-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item.search-result-more,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-section,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-title-container,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-result-text-container{color:#373a3c}.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item mark.search-match,.aa-DetachedOverlay li.aa-Item[aria-selected=false] .search-item .search-match.mark,#quarto-search-results li.aa-Item[aria-selected=false] .search-item mark.search-match,#quarto-search-results li.aa-Item[aria-selected=false] .search-item .search-match.mark{color:inherit;background-color:#e5effc}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-title-container{background-color:#fff;color:#373a3c}.aa-DetachedOverlay .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container,#quarto-search-results .aa-Item .search-result-doc:not(.document-selectable) .search-result-text-container{padding-top:0px}.aa-DetachedOverlay li.aa-Item .search-result-doc.document-selectable .search-result-text-container,#quarto-search-results li.aa-Item .search-result-doc.document-selectable .search-result-text-container{margin-top:-4px}.aa-DetachedOverlay .aa-Item,#quarto-search-results .aa-Item{cursor:pointer}.aa-DetachedOverlay .aa-Item .search-item,#quarto-search-results .aa-Item .search-item{border-left:none;border-right:none;border-top:none;background-color:#fff;border-color:#ced4da;color:#373a3c}.aa-DetachedOverlay .aa-Item .search-item p,#quarto-search-results .aa-Item .search-item p{margin-top:0;margin-bottom:0}.aa-DetachedOverlay .aa-Item .search-item i.bi,#quarto-search-results .aa-Item .search-item i.bi{padding-left:8px;padding-right:8px;font-size:1.3em}.aa-DetachedOverlay .aa-Item .search-item .search-result-title,#quarto-search-results .aa-Item .search-item .search-result-title{margin-top:.3em;margin-bottom:.1rem}.aa-DetachedOverlay .aa-Item .search-result-title-container,#quarto-search-results .aa-Item .search-result-title-container{font-size:1em;display:flex;padding:6px 4px 6px 4px}.aa-DetachedOverlay .aa-Item .search-result-text-container,#quarto-search-results .aa-Item .search-result-text-container{padding-bottom:8px;padding-right:8px;margin-left:44px}.aa-DetachedOverlay .aa-Item .search-result-doc-section,.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-doc-section,#quarto-search-results .aa-Item .search-result-more{padding-top:8px;padding-bottom:8px;padding-left:44px}.aa-DetachedOverlay .aa-Item .search-result-more,#quarto-search-results .aa-Item .search-result-more{font-size:.8em;font-weight:400}.aa-DetachedOverlay .aa-Item .search-result-doc,#quarto-search-results .aa-Item .search-result-doc{border-top:1px solid #ced4da}.aa-DetachedSearchButton{background:none;border:none}.aa-DetachedSearchButton .aa-DetachedSearchButtonPlaceholder{display:none}.navbar .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#fdfeff}.sidebar-tools-collapse #quarto-search,.sidebar-tools-main #quarto-search{display:inline}.sidebar-tools-collapse #quarto-search .aa-Autocomplete,.sidebar-tools-main #quarto-search .aa-Autocomplete{display:inline}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton{padding-left:4px;padding-right:4px}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon{color:#595959}.sidebar-tools-collapse #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon,.sidebar-tools-main #quarto-search .aa-DetachedSearchButton .aa-DetachedSearchButtonIcon .aa-SubmitIcon{margin-top:-3px}.aa-DetachedContainer{background:rgba(255,255,255,.65);width:90%;bottom:0;box-shadow:rgba(206,212,218,.6) 0 0 0 1px;outline:currentColor none medium;display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:1101}.aa-DetachedContainer::after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{background-color:#fff;border-bottom:1px solid #ced4da;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:.5em}.aa-DetachedCancelButton{background:none;font-size:.8em;border:0;border-radius:3px;color:#373a3c;cursor:pointer;margin:0 0 0 .5em;padding:0 .5em}.aa-DetachedCancelButton:hover,.aa-DetachedCancelButton:focus{box-shadow:rgba(39,128,227,.6) 0 0 0 1px;outline:currentColor none medium}.aa-DetachedContainer--modal{bottom:inherit;height:auto;margin:0 auto;position:absolute;top:100px;border-radius:6px;max-width:850px}@media(max-width: 575.98px){.aa-DetachedContainer--modal{width:100%;top:0px;border-radius:0px;border:none}}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:var(--aa-detached-modal-max-height);padding-bottom:var(--aa-spacing-half);position:static}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:rgba(55,58,60,.4);position:fixed;left:0;right:0;top:0;margin:0;padding:0;height:100vh;z-index:1100}.quarto-listing{padding-bottom:1em}.listing-pagination{padding-top:.5em}ul.pagination{float:right;padding-left:8px;padding-top:.5em}ul.pagination li{padding-right:.75em}ul.pagination li.disabled a,ul.pagination li.active a{color:#373a3c;text-decoration:none}ul.pagination li:last-of-type{padding-right:0}.listing-actions-group{display:flex}.quarto-listing-filter{margin-bottom:1em;width:200px;margin-left:auto}.quarto-listing-sort{margin-bottom:1em;margin-right:auto;width:auto}.quarto-listing-sort .input-group-text{font-size:.8em}.input-group-text{border-right:none}.quarto-listing-sort select.form-select{font-size:.8em}.listing-no-matching{text-align:center;padding-top:2em;padding-bottom:3em;font-size:1em}#quarto-margin-sidebar .quarto-listing-category{padding-top:0;font-size:1rem}#quarto-margin-sidebar .quarto-listing-category-title{cursor:pointer;font-weight:600;font-size:1rem}.quarto-listing-category .category{cursor:pointer}.quarto-listing-category .category.active{font-weight:600}.quarto-listing-category.category-cloud{display:flex;flex-wrap:wrap;align-items:baseline}.quarto-listing-category.category-cloud .category{padding-right:5px}.quarto-listing-category.category-cloud .category-cloud-1{font-size:.75em}.quarto-listing-category.category-cloud .category-cloud-2{font-size:.95em}.quarto-listing-category.category-cloud .category-cloud-3{font-size:1.15em}.quarto-listing-category.category-cloud .category-cloud-4{font-size:1.35em}.quarto-listing-category.category-cloud .category-cloud-5{font-size:1.55em}.quarto-listing-category.category-cloud .category-cloud-6{font-size:1.75em}.quarto-listing-category.category-cloud .category-cloud-7{font-size:1.95em}.quarto-listing-category.category-cloud .category-cloud-8{font-size:2.15em}.quarto-listing-category.category-cloud .category-cloud-9{font-size:2.35em}.quarto-listing-category.category-cloud .category-cloud-10{font-size:2.55em}.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-1{grid-template-columns:repeat(1, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-1{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-2{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-2{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-3{grid-template-columns:repeat(3, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-3{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-3{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-4{grid-template-columns:repeat(4, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-4{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-4{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-5{grid-template-columns:repeat(5, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-5{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-5{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-6{grid-template-columns:repeat(6, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-6{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-6{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-7{grid-template-columns:repeat(7, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-7{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-7{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-8{grid-template-columns:repeat(8, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-8{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-8{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-9{grid-template-columns:repeat(9, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-9{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-9{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-10{grid-template-columns:repeat(10, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-10{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-10{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-11{grid-template-columns:repeat(11, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-11{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-11{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-cols-12{grid-template-columns:repeat(12, minmax(0, 1fr));gap:1.5em}@media(max-width: 767.98px){.quarto-listing-cols-12{grid-template-columns:repeat(2, minmax(0, 1fr));gap:1.5em}}@media(max-width: 575.98px){.quarto-listing-cols-12{grid-template-columns:minmax(0, 1fr);gap:1.5em}}.quarto-listing-grid{gap:1.5em}.quarto-grid-item.borderless{border:none}.quarto-grid-item.borderless .listing-categories .listing-category:last-of-type,.quarto-grid-item.borderless .listing-categories .listing-category:first-of-type{padding-left:0}.quarto-grid-item.borderless .listing-categories .listing-category{border:0}.quarto-grid-link{text-decoration:none;color:inherit}.quarto-grid-link:hover{text-decoration:none;color:inherit}.quarto-grid-item h5.title,.quarto-grid-item .title.h5{margin-top:0;margin-bottom:0}.quarto-grid-item .card-footer{display:flex;justify-content:space-between;font-size:.8em}.quarto-grid-item .card-footer p{margin-bottom:0}.quarto-grid-item p.card-img-top{margin-bottom:0}.quarto-grid-item p.card-img-top>img{object-fit:cover}.quarto-grid-item .card-other-values{margin-top:.5em;font-size:.8em}.quarto-grid-item .card-other-values tr{margin-bottom:.5em}.quarto-grid-item .card-other-values tr>td:first-of-type{font-weight:600;padding-right:1em;padding-left:1em;vertical-align:top}.quarto-grid-item div.post-contents{display:flex;flex-direction:column;text-decoration:none;height:100%}.quarto-grid-item .listing-item-img-placeholder{background-color:#adb5bd;flex-shrink:0}.quarto-grid-item .card-attribution{padding-top:1em;display:flex;gap:1em;text-transform:uppercase;color:#6c757d;font-weight:500;flex-grow:10;align-items:flex-end}.quarto-grid-item .description{padding-bottom:1em}.quarto-grid-item .card-attribution .date{align-self:flex-end}.quarto-grid-item .card-attribution.justify{justify-content:space-between}.quarto-grid-item .card-attribution.start{justify-content:flex-start}.quarto-grid-item .card-attribution.end{justify-content:flex-end}.quarto-grid-item .card-title{margin-bottom:.1em}.quarto-grid-item .card-subtitle{padding-top:.25em}.quarto-grid-item .card-text{font-size:.9em}.quarto-grid-item .listing-reading-time{padding-bottom:.25em}.quarto-grid-item .card-text-small{font-size:.8em}.quarto-grid-item .card-subtitle.subtitle{font-size:.9em;font-weight:600;padding-bottom:.5em}.quarto-grid-item .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}.quarto-grid-item .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}.quarto-grid-item.card-right{text-align:right}.quarto-grid-item.card-right .listing-categories{justify-content:flex-end}.quarto-grid-item.card-left{text-align:left}.quarto-grid-item.card-center{text-align:center}.quarto-grid-item.card-center .listing-description{text-align:justify}.quarto-grid-item.card-center .listing-categories{justify-content:center}table.quarto-listing-table td.image{padding:0px}table.quarto-listing-table td.image img{width:100%;max-width:50px;object-fit:contain}table.quarto-listing-table a{text-decoration:none}table.quarto-listing-table th a{color:inherit}table.quarto-listing-table th a.asc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table th a.desc:after{margin-bottom:-2px;margin-left:5px;display:inline-block;height:1rem;width:1rem;background-repeat:no-repeat;background-size:1rem 1rem;background-image:url('data:image/svg+xml,');content:""}table.quarto-listing-table.table-hover td{cursor:pointer}.quarto-post.image-left{flex-direction:row}.quarto-post.image-right{flex-direction:row-reverse}@media(max-width: 767.98px){.quarto-post.image-right,.quarto-post.image-left{gap:0em;flex-direction:column}.quarto-post .metadata{padding-bottom:1em;order:2}.quarto-post .body{order:1}.quarto-post .thumbnail{order:3}}.list.quarto-listing-default div:last-of-type{border-bottom:none}@media(min-width: 992px){.quarto-listing-container-default{margin-right:2em}}div.quarto-post{display:flex;gap:2em;margin-bottom:1.5em;border-bottom:1px solid #dee2e6}@media(max-width: 767.98px){div.quarto-post{padding-bottom:1em}}div.quarto-post .metadata{flex-basis:20%;flex-grow:0;margin-top:.2em;flex-shrink:10}div.quarto-post .thumbnail{flex-basis:30%;flex-grow:0;flex-shrink:0}div.quarto-post .thumbnail img{margin-top:.4em;width:100%;object-fit:cover}div.quarto-post .body{flex-basis:45%;flex-grow:1;flex-shrink:0}div.quarto-post .body h3.listing-title,div.quarto-post .body .listing-title.h3{margin-top:0px;margin-bottom:0px;border-bottom:none}div.quarto-post .body .listing-subtitle{font-size:.875em;margin-bottom:.5em;margin-top:.2em}div.quarto-post .body .description{font-size:.9em}div.quarto-post a{color:#373a3c;display:flex;flex-direction:column;text-decoration:none}div.quarto-post a div.description{flex-shrink:0}div.quarto-post .metadata{display:flex;flex-direction:column;font-size:.8em;font-family:var(--bs-font-sans-serif);flex-basis:33%}div.quarto-post .listing-categories{display:flex;flex-wrap:wrap;padding-bottom:5px}div.quarto-post .listing-categories .listing-category{color:#6c757d;border:solid 1px #dee2e6;border-radius:.25rem;text-transform:uppercase;font-size:.65em;padding-left:.5em;padding-right:.5em;padding-top:.15em;padding-bottom:.15em;cursor:pointer;margin-right:4px;margin-bottom:4px}div.quarto-post .listing-description{margin-bottom:.5em}div.quarto-about-jolla{display:flex !important;flex-direction:column;align-items:center;margin-top:10%;padding-bottom:1em}div.quarto-about-jolla .about-image{object-fit:cover;margin-left:auto;margin-right:auto;margin-bottom:1.5em}div.quarto-about-jolla img.round{border-radius:50%}div.quarto-about-jolla img.rounded{border-radius:10px}div.quarto-about-jolla .quarto-title h1.title,div.quarto-about-jolla .quarto-title .title.h1{text-align:center}div.quarto-about-jolla .quarto-title .description{text-align:center}div.quarto-about-jolla h2,div.quarto-about-jolla .h2{border-bottom:none}div.quarto-about-jolla .about-sep{width:60%}div.quarto-about-jolla main{text-align:center}div.quarto-about-jolla .about-links{display:flex}@media(min-width: 992px){div.quarto-about-jolla .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-jolla .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-jolla .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-jolla .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-jolla .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-jolla .about-link:hover{color:#2780e3}div.quarto-about-jolla .about-link i.bi{margin-right:.15em}div.quarto-about-solana{display:flex !important;flex-direction:column;padding-top:3em !important;padding-bottom:1em}div.quarto-about-solana .about-entity{display:flex !important;align-items:start;justify-content:space-between}@media(min-width: 992px){div.quarto-about-solana .about-entity{flex-direction:row}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity{flex-direction:column-reverse;align-items:center;text-align:center}}div.quarto-about-solana .about-entity .entity-contents{display:flex;flex-direction:column}@media(max-width: 767.98px){div.quarto-about-solana .about-entity .entity-contents{width:100%}}div.quarto-about-solana .about-entity .about-image{object-fit:cover}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-image{margin-bottom:1.5em}}div.quarto-about-solana .about-entity img.round{border-radius:50%}div.quarto-about-solana .about-entity img.rounded{border-radius:10px}div.quarto-about-solana .about-entity .about-links{display:flex;justify-content:left;padding-bottom:1.2em}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-solana .about-entity .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-solana .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-solana .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-solana .about-entity .about-link:hover{color:#2780e3}div.quarto-about-solana .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-solana .about-contents{padding-right:1.5em;flex-basis:0;flex-grow:1}div.quarto-about-solana .about-contents main.content{margin-top:0}div.quarto-about-solana .about-contents h2,div.quarto-about-solana .about-contents .h2{border-bottom:none}div.quarto-about-trestles{display:flex !important;flex-direction:row;padding-top:3em !important;padding-bottom:1em}@media(max-width: 991.98px){div.quarto-about-trestles{flex-direction:column;padding-top:0em !important}}div.quarto-about-trestles .about-entity{display:flex !important;flex-direction:column;align-items:center;text-align:center;padding-right:1em}@media(min-width: 992px){div.quarto-about-trestles .about-entity{flex:0 0 42%}}div.quarto-about-trestles .about-entity .about-image{object-fit:cover;margin-bottom:1.5em}div.quarto-about-trestles .about-entity img.round{border-radius:50%}div.quarto-about-trestles .about-entity img.rounded{border-radius:10px}div.quarto-about-trestles .about-entity .about-links{display:flex;justify-content:center}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-trestles .about-entity .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-trestles .about-entity .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-trestles .about-entity .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-trestles .about-entity .about-link:hover{color:#2780e3}div.quarto-about-trestles .about-entity .about-link i.bi{margin-right:.15em}div.quarto-about-trestles .about-contents{flex-basis:0;flex-grow:1}div.quarto-about-trestles .about-contents h2,div.quarto-about-trestles .about-contents .h2{border-bottom:none}@media(min-width: 992px){div.quarto-about-trestles .about-contents{border-left:solid 1px #dee2e6;padding-left:1.5em}}div.quarto-about-trestles .about-contents main.content{margin-top:0}div.quarto-about-marquee{padding-bottom:1em}div.quarto-about-marquee .about-contents{display:flex;flex-direction:column}div.quarto-about-marquee .about-image{max-height:550px;margin-bottom:1.5em;object-fit:cover}div.quarto-about-marquee img.round{border-radius:50%}div.quarto-about-marquee img.rounded{border-radius:10px}div.quarto-about-marquee h2,div.quarto-about-marquee .h2{border-bottom:none}div.quarto-about-marquee .about-links{display:flex;justify-content:center;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-marquee .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-marquee .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-marquee .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-marquee .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-marquee .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-marquee .about-link:hover{color:#2780e3}div.quarto-about-marquee .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-marquee .about-link{border:none}}div.quarto-about-broadside{display:flex;flex-direction:column;padding-bottom:1em}div.quarto-about-broadside .about-main{display:flex !important;padding-top:0 !important}@media(min-width: 992px){div.quarto-about-broadside .about-main{flex-direction:row;align-items:flex-start}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main{flex-direction:column}}@media(max-width: 991.98px){div.quarto-about-broadside .about-main .about-entity{flex-shrink:0;width:100%;height:450px;margin-bottom:1.5em;background-size:cover;background-repeat:no-repeat}}@media(min-width: 992px){div.quarto-about-broadside .about-main .about-entity{flex:0 10 50%;margin-right:1.5em;width:100%;height:100%;background-size:100%;background-repeat:no-repeat}}div.quarto-about-broadside .about-main .about-contents{padding-top:14px;flex:0 0 50%}div.quarto-about-broadside h2,div.quarto-about-broadside .h2{border-bottom:none}div.quarto-about-broadside .about-sep{margin-top:1.5em;width:60%;align-self:center}div.quarto-about-broadside .about-links{display:flex;justify-content:center;column-gap:20px;padding-top:1.5em}@media(min-width: 992px){div.quarto-about-broadside .about-links{flex-direction:row;column-gap:.8em;row-gap:15px;flex-wrap:wrap}}@media(max-width: 991.98px){div.quarto-about-broadside .about-links{flex-direction:column;row-gap:1em;width:100%;padding-bottom:1.5em}}div.quarto-about-broadside .about-link{color:#686d71;text-decoration:none;border:solid 1px}@media(min-width: 992px){div.quarto-about-broadside .about-link{font-size:.8em;padding:.25em .5em;border-radius:4px}}@media(max-width: 991.98px){div.quarto-about-broadside .about-link{font-size:1.1em;padding:.5em .5em;text-align:center;border-radius:6px}}div.quarto-about-broadside .about-link:hover{color:#2780e3}div.quarto-about-broadside .about-link i.bi{margin-right:.15em}@media(min-width: 992px){div.quarto-about-broadside .about-link{border:none}}.tippy-box[data-theme~=quarto]{background-color:#fff;border:solid 1px #dee2e6;border-radius:.25rem;color:#373a3c;font-size:.875rem}.tippy-box[data-theme~=quarto]>.tippy-backdrop{background-color:#fff}.tippy-box[data-theme~=quarto]>.tippy-arrow:after,.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{content:"";position:absolute;z-index:-1}.tippy-box[data-theme~=quarto]>.tippy-arrow:after{border-color:rgba(0,0,0,0);border-style:solid}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-6px}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-6px}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-6px}.tippy-box[data-placement^=left]>.tippy-arrow:before{right:-6px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:before{border-top-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-arrow:after{border-top-color:#dee2e6;border-width:7px 7px 0;top:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow>svg{top:16px}.tippy-box[data-theme~=quarto][data-placement^=top]>.tippy-svg-arrow:after{top:17px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:before{border-bottom-color:#fff;bottom:16px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-arrow:after{border-bottom-color:#dee2e6;border-width:0 7px 7px;bottom:17px;left:1px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow>svg{bottom:15px}.tippy-box[data-theme~=quarto][data-placement^=bottom]>.tippy-svg-arrow:after{bottom:17px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:before{border-left-color:#fff}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-arrow:after{border-left-color:#dee2e6;border-width:7px 0 7px 7px;left:17px;top:1px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow>svg{left:11px}.tippy-box[data-theme~=quarto][data-placement^=left]>.tippy-svg-arrow:after{left:12px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:before{border-right-color:#fff;right:16px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-arrow:after{border-width:7px 7px 7px 0;right:17px;top:1px;border-right-color:#dee2e6}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow>svg{right:11px}.tippy-box[data-theme~=quarto][data-placement^=right]>.tippy-svg-arrow:after{right:12px}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow{fill:#373a3c}.tippy-box[data-theme~=quarto]>.tippy-svg-arrow:after{background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iNiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMCA2czEuNzk2LS4wMTMgNC42Ny0zLjYxNUM1Ljg1MS45IDYuOTMuMDA2IDggMGMxLjA3LS4wMDYgMi4xNDguODg3IDMuMzQzIDIuMzg1QzE0LjIzMyA2LjAwNSAxNiA2IDE2IDZIMHoiIGZpbGw9InJnYmEoMCwgOCwgMTYsIDAuMikiLz48L3N2Zz4=);background-size:16px 6px;width:16px;height:6px}.top-right{position:absolute;top:1em;right:1em}.hidden{display:none !important}.zindex-bottom{z-index:-1 !important}.quarto-layout-panel{margin-bottom:1em}.quarto-layout-panel>figure{width:100%}.quarto-layout-panel>figure>figcaption,.quarto-layout-panel>.panel-caption{margin-top:10pt}.quarto-layout-panel>.table-caption{margin-top:0px}.table-caption p{margin-bottom:.5em}.quarto-layout-row{display:flex;flex-direction:row;align-items:flex-start}.quarto-layout-valign-top{align-items:flex-start}.quarto-layout-valign-bottom{align-items:flex-end}.quarto-layout-valign-center{align-items:center}.quarto-layout-cell{position:relative;margin-right:20px}.quarto-layout-cell:last-child{margin-right:0}.quarto-layout-cell figure,.quarto-layout-cell>p{margin:.2em}.quarto-layout-cell img{max-width:100%}.quarto-layout-cell .html-widget{width:100% !important}.quarto-layout-cell div figure p{margin:0}.quarto-layout-cell figure{display:inline-block;margin-inline-start:0;margin-inline-end:0}.quarto-layout-cell table{display:inline-table}.quarto-layout-cell-subref figcaption,figure .quarto-layout-row figure figcaption{text-align:center;font-style:italic}.quarto-figure{position:relative;margin-bottom:1em}.quarto-figure>figure{width:100%;margin-bottom:0}.quarto-figure-left>figure>p,.quarto-figure-left>figure>div{text-align:left}.quarto-figure-center>figure>p,.quarto-figure-center>figure>div{text-align:center}.quarto-figure-right>figure>p,.quarto-figure-right>figure>div{text-align:right}figure>p:empty{display:none}figure>p:first-child{margin-top:0;margin-bottom:0}figure>figcaption{margin-top:.5em}div[id^=tbl-]{position:relative}.quarto-figure>.anchorjs-link{position:absolute;top:.6em;right:.5em}div[id^=tbl-]>.anchorjs-link{position:absolute;top:.7em;right:.3em}.quarto-figure:hover>.anchorjs-link,div[id^=tbl-]:hover>.anchorjs-link,h2:hover>.anchorjs-link,.h2:hover>.anchorjs-link,h3:hover>.anchorjs-link,.h3:hover>.anchorjs-link,h4:hover>.anchorjs-link,.h4:hover>.anchorjs-link,h5:hover>.anchorjs-link,.h5:hover>.anchorjs-link,h6:hover>.anchorjs-link,.h6:hover>.anchorjs-link,.reveal-anchorjs-link>.anchorjs-link{opacity:1}#title-block-header{margin-block-end:1rem;position:relative;margin-top:-1px}#title-block-header .abstract{margin-block-start:1rem}#title-block-header .abstract .abstract-title{font-weight:600}#title-block-header a{text-decoration:none}#title-block-header .author,#title-block-header .date,#title-block-header .doi{margin-block-end:.2rem}#title-block-header .quarto-title-block>div{display:flex}#title-block-header .quarto-title-block>div>h1,#title-block-header .quarto-title-block>div>.h1{flex-grow:1}#title-block-header .quarto-title-block>div>button{flex-shrink:0;height:2.25rem;margin-top:0}@media(min-width: 992px){#title-block-header .quarto-title-block>div>button{margin-top:5px}}tr.header>th>p:last-of-type{margin-bottom:0px}table,.table{caption-side:top;margin-bottom:1.5rem}caption,.table-caption{padding-top:.5rem;padding-bottom:.5rem;text-align:center}.utterances{max-width:none;margin-left:-8px}iframe{margin-bottom:1em}details{margin-bottom:1em}details[show]{margin-bottom:0}details>summary{color:#6c757d}details>summary>p:only-child{display:inline}pre.sourceCode,code.sourceCode{position:relative}p code:not(.sourceCode){white-space:pre-wrap}code{white-space:pre}@media print{code{white-space:pre-wrap}}pre>code{display:block}pre>code.sourceCode{white-space:pre}pre>code.sourceCode>span>a:first-child::before{text-decoration:none}pre.code-overflow-wrap>code.sourceCode{white-space:pre-wrap}pre.code-overflow-scroll>code.sourceCode{white-space:pre}code a:any-link{color:inherit;text-decoration:none}code a:hover{color:inherit;text-decoration:underline}ul.task-list{padding-left:1em}[data-tippy-root]{display:inline-block}.tippy-content .footnote-back{display:none}.quarto-embedded-source-code{display:none}.quarto-unresolved-ref{font-weight:600}.quarto-cover-image{max-width:35%;float:right;margin-left:30px}.cell-output-display .widget-subarea{margin-bottom:1em}.cell-output-display:not(.no-overflow-x),.knitsql-table:not(.no-overflow-x){overflow-x:auto}.panel-input{margin-bottom:1em}.panel-input>div,.panel-input>div>div{display:inline-block;vertical-align:top;padding-right:12px}.panel-input>p:last-child{margin-bottom:0}.layout-sidebar{margin-bottom:1em}.layout-sidebar .tab-content{border:none}.tab-content>.page-columns.active{display:grid}div.sourceCode>iframe{width:100%;height:300px;margin-bottom:-0.5em}div.ansi-escaped-output{font-family:monospace;display:block}/*! +* +* ansi colors from IPython notebook's +* +*/.ansi-black-fg{color:#3e424d}.ansi-black-bg{background-color:#3e424d}.ansi-black-intense-fg{color:#282c36}.ansi-black-intense-bg{background-color:#282c36}.ansi-red-fg{color:#e75c58}.ansi-red-bg{background-color:#e75c58}.ansi-red-intense-fg{color:#b22b31}.ansi-red-intense-bg{background-color:#b22b31}.ansi-green-fg{color:#00a250}.ansi-green-bg{background-color:#00a250}.ansi-green-intense-fg{color:#007427}.ansi-green-intense-bg{background-color:#007427}.ansi-yellow-fg{color:#ddb62b}.ansi-yellow-bg{background-color:#ddb62b}.ansi-yellow-intense-fg{color:#b27d12}.ansi-yellow-intense-bg{background-color:#b27d12}.ansi-blue-fg{color:#208ffb}.ansi-blue-bg{background-color:#208ffb}.ansi-blue-intense-fg{color:#0065ca}.ansi-blue-intense-bg{background-color:#0065ca}.ansi-magenta-fg{color:#d160c4}.ansi-magenta-bg{background-color:#d160c4}.ansi-magenta-intense-fg{color:#a03196}.ansi-magenta-intense-bg{background-color:#a03196}.ansi-cyan-fg{color:#60c6c8}.ansi-cyan-bg{background-color:#60c6c8}.ansi-cyan-intense-fg{color:#258f8f}.ansi-cyan-intense-bg{background-color:#258f8f}.ansi-white-fg{color:#c5c1b4}.ansi-white-bg{background-color:#c5c1b4}.ansi-white-intense-fg{color:#a1a6b2}.ansi-white-intense-bg{background-color:#a1a6b2}.ansi-default-inverse-fg{color:#fff}.ansi-default-inverse-bg{background-color:#000}.ansi-bold{font-weight:bold}.ansi-underline{text-decoration:underline}:root{--quarto-body-bg: #fff;--quarto-body-color: #373a3c;--quarto-text-muted: #6c757d;--quarto-border-color: #dee2e6;--quarto-border-width: 1px;--quarto-border-radius: 0.25rem}table.gt_table{color:var(--quarto-body-color);font-size:1em;width:100%;background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_column_spanner_outer{color:var(--quarto-body-color);background-color:rgba(0,0,0,0);border-top-width:inherit;border-bottom-width:inherit;border-color:var(--quarto-border-color)}table.gt_table th.gt_col_heading{color:var(--quarto-body-color);font-weight:bold;background-color:rgba(0,0,0,0)}table.gt_table thead.gt_col_headings{border-bottom:1px solid currentColor;border-top-width:inherit;border-top-color:var(--quarto-border-color)}table.gt_table thead.gt_col_headings:not(:first-child){border-top-width:1px;border-top-color:var(--quarto-border-color)}table.gt_table td.gt_row{border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-width:0px}table.gt_table tbody.gt_table_body{border-top-width:1px;border-bottom-width:1px;border-bottom-color:var(--quarto-border-color);border-top-color:currentColor}div.columns{display:initial;gap:initial}div.column{display:inline-block;overflow-x:initial;vertical-align:top;width:50%}.code-annotation-tip-content{word-wrap:break-word}.code-annotation-container-hidden{display:none !important}dl.code-annotation-container-grid{display:grid;grid-template-columns:min-content auto}dl.code-annotation-container-grid dt{grid-column:1}dl.code-annotation-container-grid dd{grid-column:2}pre.sourceCode.code-annotation-code{padding-right:0}code.sourceCode .code-annotation-anchor{z-index:100;position:absolute;right:.5em;left:inherit;background-color:rgba(0,0,0,0)}:root{--mermaid-bg-color: #fff;--mermaid-edge-color: #373a3c;--mermaid-node-fg-color: #373a3c;--mermaid-fg-color: #373a3c;--mermaid-fg-color--lighter: #4f5457;--mermaid-fg-color--lightest: #686d71;--mermaid-font-family: Source Sans Pro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;--mermaid-label-bg-color: #fff;--mermaid-label-fg-color: #2780e3;--mermaid-node-bg-color: rgba(39, 128, 227, 0.1);--mermaid-node-fg-color: #373a3c}@media print{:root{font-size:11pt}#quarto-sidebar,#TOC,.nav-page{display:none}.page-columns .content{grid-column-start:page-start}.fixed-top{position:relative}.panel-caption,.figure-caption,figcaption{color:#666}}.code-copy-button{position:absolute;top:0;right:0;border:0;margin-top:5px;margin-right:5px;background-color:rgba(0,0,0,0);z-index:3}.code-copy-button:focus{outline:none}.code-copy-button-tooltip{font-size:.75em}pre.sourceCode:hover>.code-copy-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}pre.sourceCode:hover>.code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}pre.sourceCode:hover>.code-copy-button-checked:hover>.bi::before{background-image:url('data:image/svg+xml,')}main ol ol,main ul ul,main ol ul,main ul ol{margin-bottom:1em}ul>li:not(:has(>p))>ul,ol>li:not(:has(>p))>ul,ul>li:not(:has(>p))>ol,ol>li:not(:has(>p))>ol{margin-bottom:0}ul>li:not(:has(>p))>ul>li:has(>p),ol>li:not(:has(>p))>ul>li:has(>p),ul>li:not(:has(>p))>ol>li:has(>p),ol>li:not(:has(>p))>ol>li:has(>p){margin-top:1rem}body{margin:0}main.page-columns>header>h1.title,main.page-columns>header>.title.h1{margin-bottom:0}@media(min-width: 992px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] 35px [page-end-inset page-end] 5fr [screen-end-inset] 1.5em}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset] 35px [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 850px - 3em )) [body-content-end] 3em [body-end] 50px [body-end-outset] minmax(0px, 250px) [page-end-inset] minmax(50px, 100px) [page-end] 1fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 175px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 100px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start] minmax(50px, 100px) [page-start-inset] 50px [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(0px, 200px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 50px [page-start-inset] minmax(50px, 150px) [body-start-outset] 50px [body-start] 1.5em [body-content-start] minmax(450px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(50px, 150px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] minmax(25px, 50px) [page-start-inset] minmax(50px, 150px) [body-start-outset] minmax(25px, 50px) [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] minmax(25px, 50px) [body-end-outset] minmax(50px, 150px) [page-end-inset] minmax(25px, 50px) [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 991.98px){body .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.fullcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.slimcontent:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.listing:not(.floating):not(.docked) .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset] 5fr [body-start] 1.5em [body-content-start] minmax(500px, calc( 1250px - 3em )) [body-content-end body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start] 35px [page-start-inset] minmax(0px, 145px) [body-start-outset] 35px [body-start] 1.5em [body-content-start] minmax(450px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1.5em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 1000px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 800px - 3em )) [body-content-end] 1.5em [body-end body-end-outset page-end-inset page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.docked.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.docked.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(25px, 50px) [page-end-inset] 50px [page-end] 5fr [screen-end-inset] 1.5em [screen-end]}body.floating.slimcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 35px [body-end-outset] minmax(75px, 145px) [page-end-inset] 35px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}body.floating.listing .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset] 5fr [page-start page-start-inset body-start-outset body-start] 1em [body-content-start] minmax(500px, calc( 750px - 3em )) [body-content-end] 1.5em [body-end] 50px [body-end-outset] minmax(75px, 150px) [page-end-inset] 25px [page-end] 4fr [screen-end-inset] 1.5em [screen-end]}}@media(max-width: 767.98px){body .page-columns,body.fullcontent:not(.floating):not(.docked) .page-columns,body.slimcontent:not(.floating):not(.docked) .page-columns,body.docked .page-columns,body.docked.slimcontent .page-columns,body.docked.fullcontent .page-columns,body.floating .page-columns,body.floating.slimcontent .page-columns,body.floating.fullcontent .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}body:not(.floating):not(.docked) .page-columns.toc-left .page-columns{display:grid;gap:0;grid-template-columns:[screen-start] 1.5em [screen-start-inset page-start page-start-inset body-start-outset body-start body-content-start] minmax(0px, 1fr) [body-content-end body-end body-end-outset page-end-inset page-end screen-end-inset] 1.5em [screen-end]}nav[role=doc-toc]{display:none}}body,.page-row-navigation{grid-template-rows:[page-top] max-content [contents-top] max-content [contents-bottom] max-content [page-bottom]}.page-rows-contents{grid-template-rows:[content-top] minmax(max-content, 1fr) [content-bottom] minmax(60px, max-content) [page-bottom]}.page-full{grid-column:screen-start/screen-end !important}.page-columns>*{grid-column:body-content-start/body-content-end}.page-columns.column-page>*{grid-column:page-start/page-end}.page-columns.column-page-left>*{grid-column:page-start/body-content-end}.page-columns.column-page-right>*{grid-column:body-content-start/page-end}.page-rows{grid-auto-rows:auto}.header{grid-column:screen-start/screen-end;grid-row:page-top/contents-top}#quarto-content{padding:0;grid-column:screen-start/screen-end;grid-row:contents-top/contents-bottom}body.floating .sidebar.sidebar-navigation{grid-column:page-start/body-start;grid-row:content-top/page-bottom}body.docked .sidebar.sidebar-navigation{grid-column:screen-start/body-start;grid-row:content-top/page-bottom}.sidebar.toc-left{grid-column:page-start/body-start;grid-row:content-top/page-bottom}.sidebar.margin-sidebar{grid-column:body-end/page-end;grid-row:content-top/page-bottom}.page-columns .content{grid-column:body-content-start/body-content-end;grid-row:content-top/content-bottom;align-content:flex-start}.page-columns .page-navigation{grid-column:body-content-start/body-content-end;grid-row:content-bottom/page-bottom}.page-columns .footer{grid-column:screen-start/screen-end;grid-row:contents-bottom/page-bottom}.page-columns .column-body{grid-column:body-content-start/body-content-end}.page-columns .column-body-fullbleed{grid-column:body-start/body-end}.page-columns .column-body-outset{grid-column:body-start-outset/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset table{background:#fff}.page-columns .column-body-outset-left{grid-column:body-start-outset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-left table{background:#fff}.page-columns .column-body-outset-right{grid-column:body-content-start/body-end-outset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-body-outset-right table{background:#fff}.page-columns .column-page{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page table{background:#fff}.page-columns .column-page-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset table{background:#fff}.page-columns .column-page-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-left table{background:#fff}.page-columns .column-page-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-inset-right figcaption table{background:#fff}.page-columns .column-page-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-left table{background:#fff}.page-columns .column-page-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-page-right figcaption table{background:#fff}#quarto-content.page-columns #quarto-margin-sidebar,#quarto-content.page-columns #quarto-sidebar{z-index:1}@media(max-width: 991.98px){#quarto-content.page-columns #quarto-margin-sidebar.collapse,#quarto-content.page-columns #quarto-sidebar.collapse,#quarto-content.page-columns #quarto-margin-sidebar.collapsing,#quarto-content.page-columns #quarto-sidebar.collapsing{z-index:1055}}#quarto-content.page-columns main.column-page,#quarto-content.page-columns main.column-page-right,#quarto-content.page-columns main.column-page-left{z-index:0}.page-columns .column-screen-inset{grid-column:screen-start-inset/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:screen-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/screen-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:screen-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:screen-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/screen-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:screen-start/screen-end;padding:1em;background:#f8f9fa;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}.zindex-content{z-index:998;transform:translate3d(0, 0, 0)}.zindex-modal{z-index:1055;transform:translate3d(0, 0, 0)}.zindex-over-content{z-index:999;transform:translate3d(0, 0, 0)}img.img-fluid.column-screen,img.img-fluid.column-screen-inset-shaded,img.img-fluid.column-screen-inset,img.img-fluid.column-screen-inset-left,img.img-fluid.column-screen-inset-right,img.img-fluid.column-screen-left,img.img-fluid.column-screen-right{width:100%}@media(min-width: 992px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.column-sidebar{grid-column:page-start/body-start !important;z-index:998}.column-leftmargin{grid-column:screen-start-inset/body-start !important;z-index:998}.no-row-height{height:1em;overflow:visible}}@media(max-width: 991.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-end/page-end !important;z-index:998}.no-row-height{height:1em;overflow:visible}.page-columns.page-full{overflow:visible}.page-columns.toc-left .margin-caption,.page-columns.toc-left div.aside,.page-columns.toc-left aside,.page-columns.toc-left .column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.page-columns.toc-left .no-row-height{height:initial;overflow:initial}}@media(max-width: 767.98px){.margin-caption,div.aside,aside,.column-margin{grid-column:body-content-start/body-content-end !important;z-index:998;transform:translate3d(0, 0, 0)}.no-row-height{height:initial;overflow:initial}#quarto-margin-sidebar{display:none}#quarto-sidebar-toc-left{display:none}.hidden-sm{display:none}}.panel-grid{display:grid;grid-template-rows:repeat(1, 1fr);grid-template-columns:repeat(24, 1fr);gap:1em}.panel-grid .g-col-1{grid-column:auto/span 1}.panel-grid .g-col-2{grid-column:auto/span 2}.panel-grid .g-col-3{grid-column:auto/span 3}.panel-grid .g-col-4{grid-column:auto/span 4}.panel-grid .g-col-5{grid-column:auto/span 5}.panel-grid .g-col-6{grid-column:auto/span 6}.panel-grid .g-col-7{grid-column:auto/span 7}.panel-grid .g-col-8{grid-column:auto/span 8}.panel-grid .g-col-9{grid-column:auto/span 9}.panel-grid .g-col-10{grid-column:auto/span 10}.panel-grid .g-col-11{grid-column:auto/span 11}.panel-grid .g-col-12{grid-column:auto/span 12}.panel-grid .g-col-13{grid-column:auto/span 13}.panel-grid .g-col-14{grid-column:auto/span 14}.panel-grid .g-col-15{grid-column:auto/span 15}.panel-grid .g-col-16{grid-column:auto/span 16}.panel-grid .g-col-17{grid-column:auto/span 17}.panel-grid .g-col-18{grid-column:auto/span 18}.panel-grid .g-col-19{grid-column:auto/span 19}.panel-grid .g-col-20{grid-column:auto/span 20}.panel-grid .g-col-21{grid-column:auto/span 21}.panel-grid .g-col-22{grid-column:auto/span 22}.panel-grid .g-col-23{grid-column:auto/span 23}.panel-grid .g-col-24{grid-column:auto/span 24}.panel-grid .g-start-1{grid-column-start:1}.panel-grid .g-start-2{grid-column-start:2}.panel-grid .g-start-3{grid-column-start:3}.panel-grid .g-start-4{grid-column-start:4}.panel-grid .g-start-5{grid-column-start:5}.panel-grid .g-start-6{grid-column-start:6}.panel-grid .g-start-7{grid-column-start:7}.panel-grid .g-start-8{grid-column-start:8}.panel-grid .g-start-9{grid-column-start:9}.panel-grid .g-start-10{grid-column-start:10}.panel-grid .g-start-11{grid-column-start:11}.panel-grid .g-start-12{grid-column-start:12}.panel-grid .g-start-13{grid-column-start:13}.panel-grid .g-start-14{grid-column-start:14}.panel-grid .g-start-15{grid-column-start:15}.panel-grid .g-start-16{grid-column-start:16}.panel-grid .g-start-17{grid-column-start:17}.panel-grid .g-start-18{grid-column-start:18}.panel-grid .g-start-19{grid-column-start:19}.panel-grid .g-start-20{grid-column-start:20}.panel-grid .g-start-21{grid-column-start:21}.panel-grid .g-start-22{grid-column-start:22}.panel-grid .g-start-23{grid-column-start:23}@media(min-width: 576px){.panel-grid .g-col-sm-1{grid-column:auto/span 1}.panel-grid .g-col-sm-2{grid-column:auto/span 2}.panel-grid .g-col-sm-3{grid-column:auto/span 3}.panel-grid .g-col-sm-4{grid-column:auto/span 4}.panel-grid .g-col-sm-5{grid-column:auto/span 5}.panel-grid .g-col-sm-6{grid-column:auto/span 6}.panel-grid .g-col-sm-7{grid-column:auto/span 7}.panel-grid .g-col-sm-8{grid-column:auto/span 8}.panel-grid .g-col-sm-9{grid-column:auto/span 9}.panel-grid .g-col-sm-10{grid-column:auto/span 10}.panel-grid .g-col-sm-11{grid-column:auto/span 11}.panel-grid .g-col-sm-12{grid-column:auto/span 12}.panel-grid .g-col-sm-13{grid-column:auto/span 13}.panel-grid .g-col-sm-14{grid-column:auto/span 14}.panel-grid .g-col-sm-15{grid-column:auto/span 15}.panel-grid .g-col-sm-16{grid-column:auto/span 16}.panel-grid .g-col-sm-17{grid-column:auto/span 17}.panel-grid .g-col-sm-18{grid-column:auto/span 18}.panel-grid .g-col-sm-19{grid-column:auto/span 19}.panel-grid .g-col-sm-20{grid-column:auto/span 20}.panel-grid .g-col-sm-21{grid-column:auto/span 21}.panel-grid .g-col-sm-22{grid-column:auto/span 22}.panel-grid .g-col-sm-23{grid-column:auto/span 23}.panel-grid .g-col-sm-24{grid-column:auto/span 24}.panel-grid .g-start-sm-1{grid-column-start:1}.panel-grid .g-start-sm-2{grid-column-start:2}.panel-grid .g-start-sm-3{grid-column-start:3}.panel-grid .g-start-sm-4{grid-column-start:4}.panel-grid .g-start-sm-5{grid-column-start:5}.panel-grid .g-start-sm-6{grid-column-start:6}.panel-grid .g-start-sm-7{grid-column-start:7}.panel-grid .g-start-sm-8{grid-column-start:8}.panel-grid .g-start-sm-9{grid-column-start:9}.panel-grid .g-start-sm-10{grid-column-start:10}.panel-grid .g-start-sm-11{grid-column-start:11}.panel-grid .g-start-sm-12{grid-column-start:12}.panel-grid .g-start-sm-13{grid-column-start:13}.panel-grid .g-start-sm-14{grid-column-start:14}.panel-grid .g-start-sm-15{grid-column-start:15}.panel-grid .g-start-sm-16{grid-column-start:16}.panel-grid .g-start-sm-17{grid-column-start:17}.panel-grid .g-start-sm-18{grid-column-start:18}.panel-grid .g-start-sm-19{grid-column-start:19}.panel-grid .g-start-sm-20{grid-column-start:20}.panel-grid .g-start-sm-21{grid-column-start:21}.panel-grid .g-start-sm-22{grid-column-start:22}.panel-grid .g-start-sm-23{grid-column-start:23}}@media(min-width: 768px){.panel-grid .g-col-md-1{grid-column:auto/span 1}.panel-grid .g-col-md-2{grid-column:auto/span 2}.panel-grid .g-col-md-3{grid-column:auto/span 3}.panel-grid .g-col-md-4{grid-column:auto/span 4}.panel-grid .g-col-md-5{grid-column:auto/span 5}.panel-grid .g-col-md-6{grid-column:auto/span 6}.panel-grid .g-col-md-7{grid-column:auto/span 7}.panel-grid .g-col-md-8{grid-column:auto/span 8}.panel-grid .g-col-md-9{grid-column:auto/span 9}.panel-grid .g-col-md-10{grid-column:auto/span 10}.panel-grid .g-col-md-11{grid-column:auto/span 11}.panel-grid .g-col-md-12{grid-column:auto/span 12}.panel-grid .g-col-md-13{grid-column:auto/span 13}.panel-grid .g-col-md-14{grid-column:auto/span 14}.panel-grid .g-col-md-15{grid-column:auto/span 15}.panel-grid .g-col-md-16{grid-column:auto/span 16}.panel-grid .g-col-md-17{grid-column:auto/span 17}.panel-grid .g-col-md-18{grid-column:auto/span 18}.panel-grid .g-col-md-19{grid-column:auto/span 19}.panel-grid .g-col-md-20{grid-column:auto/span 20}.panel-grid .g-col-md-21{grid-column:auto/span 21}.panel-grid .g-col-md-22{grid-column:auto/span 22}.panel-grid .g-col-md-23{grid-column:auto/span 23}.panel-grid .g-col-md-24{grid-column:auto/span 24}.panel-grid .g-start-md-1{grid-column-start:1}.panel-grid .g-start-md-2{grid-column-start:2}.panel-grid .g-start-md-3{grid-column-start:3}.panel-grid .g-start-md-4{grid-column-start:4}.panel-grid .g-start-md-5{grid-column-start:5}.panel-grid .g-start-md-6{grid-column-start:6}.panel-grid .g-start-md-7{grid-column-start:7}.panel-grid .g-start-md-8{grid-column-start:8}.panel-grid .g-start-md-9{grid-column-start:9}.panel-grid .g-start-md-10{grid-column-start:10}.panel-grid .g-start-md-11{grid-column-start:11}.panel-grid .g-start-md-12{grid-column-start:12}.panel-grid .g-start-md-13{grid-column-start:13}.panel-grid .g-start-md-14{grid-column-start:14}.panel-grid .g-start-md-15{grid-column-start:15}.panel-grid .g-start-md-16{grid-column-start:16}.panel-grid .g-start-md-17{grid-column-start:17}.panel-grid .g-start-md-18{grid-column-start:18}.panel-grid .g-start-md-19{grid-column-start:19}.panel-grid .g-start-md-20{grid-column-start:20}.panel-grid .g-start-md-21{grid-column-start:21}.panel-grid .g-start-md-22{grid-column-start:22}.panel-grid .g-start-md-23{grid-column-start:23}}@media(min-width: 992px){.panel-grid .g-col-lg-1{grid-column:auto/span 1}.panel-grid .g-col-lg-2{grid-column:auto/span 2}.panel-grid .g-col-lg-3{grid-column:auto/span 3}.panel-grid .g-col-lg-4{grid-column:auto/span 4}.panel-grid .g-col-lg-5{grid-column:auto/span 5}.panel-grid .g-col-lg-6{grid-column:auto/span 6}.panel-grid .g-col-lg-7{grid-column:auto/span 7}.panel-grid .g-col-lg-8{grid-column:auto/span 8}.panel-grid .g-col-lg-9{grid-column:auto/span 9}.panel-grid .g-col-lg-10{grid-column:auto/span 10}.panel-grid .g-col-lg-11{grid-column:auto/span 11}.panel-grid .g-col-lg-12{grid-column:auto/span 12}.panel-grid .g-col-lg-13{grid-column:auto/span 13}.panel-grid .g-col-lg-14{grid-column:auto/span 14}.panel-grid .g-col-lg-15{grid-column:auto/span 15}.panel-grid .g-col-lg-16{grid-column:auto/span 16}.panel-grid .g-col-lg-17{grid-column:auto/span 17}.panel-grid .g-col-lg-18{grid-column:auto/span 18}.panel-grid .g-col-lg-19{grid-column:auto/span 19}.panel-grid .g-col-lg-20{grid-column:auto/span 20}.panel-grid .g-col-lg-21{grid-column:auto/span 21}.panel-grid .g-col-lg-22{grid-column:auto/span 22}.panel-grid .g-col-lg-23{grid-column:auto/span 23}.panel-grid .g-col-lg-24{grid-column:auto/span 24}.panel-grid .g-start-lg-1{grid-column-start:1}.panel-grid .g-start-lg-2{grid-column-start:2}.panel-grid .g-start-lg-3{grid-column-start:3}.panel-grid .g-start-lg-4{grid-column-start:4}.panel-grid .g-start-lg-5{grid-column-start:5}.panel-grid .g-start-lg-6{grid-column-start:6}.panel-grid .g-start-lg-7{grid-column-start:7}.panel-grid .g-start-lg-8{grid-column-start:8}.panel-grid .g-start-lg-9{grid-column-start:9}.panel-grid .g-start-lg-10{grid-column-start:10}.panel-grid .g-start-lg-11{grid-column-start:11}.panel-grid .g-start-lg-12{grid-column-start:12}.panel-grid .g-start-lg-13{grid-column-start:13}.panel-grid .g-start-lg-14{grid-column-start:14}.panel-grid .g-start-lg-15{grid-column-start:15}.panel-grid .g-start-lg-16{grid-column-start:16}.panel-grid .g-start-lg-17{grid-column-start:17}.panel-grid .g-start-lg-18{grid-column-start:18}.panel-grid .g-start-lg-19{grid-column-start:19}.panel-grid .g-start-lg-20{grid-column-start:20}.panel-grid .g-start-lg-21{grid-column-start:21}.panel-grid .g-start-lg-22{grid-column-start:22}.panel-grid .g-start-lg-23{grid-column-start:23}}@media(min-width: 1200px){.panel-grid .g-col-xl-1{grid-column:auto/span 1}.panel-grid .g-col-xl-2{grid-column:auto/span 2}.panel-grid .g-col-xl-3{grid-column:auto/span 3}.panel-grid .g-col-xl-4{grid-column:auto/span 4}.panel-grid .g-col-xl-5{grid-column:auto/span 5}.panel-grid .g-col-xl-6{grid-column:auto/span 6}.panel-grid .g-col-xl-7{grid-column:auto/span 7}.panel-grid .g-col-xl-8{grid-column:auto/span 8}.panel-grid .g-col-xl-9{grid-column:auto/span 9}.panel-grid .g-col-xl-10{grid-column:auto/span 10}.panel-grid .g-col-xl-11{grid-column:auto/span 11}.panel-grid .g-col-xl-12{grid-column:auto/span 12}.panel-grid .g-col-xl-13{grid-column:auto/span 13}.panel-grid .g-col-xl-14{grid-column:auto/span 14}.panel-grid .g-col-xl-15{grid-column:auto/span 15}.panel-grid .g-col-xl-16{grid-column:auto/span 16}.panel-grid .g-col-xl-17{grid-column:auto/span 17}.panel-grid .g-col-xl-18{grid-column:auto/span 18}.panel-grid .g-col-xl-19{grid-column:auto/span 19}.panel-grid .g-col-xl-20{grid-column:auto/span 20}.panel-grid .g-col-xl-21{grid-column:auto/span 21}.panel-grid .g-col-xl-22{grid-column:auto/span 22}.panel-grid .g-col-xl-23{grid-column:auto/span 23}.panel-grid .g-col-xl-24{grid-column:auto/span 24}.panel-grid .g-start-xl-1{grid-column-start:1}.panel-grid .g-start-xl-2{grid-column-start:2}.panel-grid .g-start-xl-3{grid-column-start:3}.panel-grid .g-start-xl-4{grid-column-start:4}.panel-grid .g-start-xl-5{grid-column-start:5}.panel-grid .g-start-xl-6{grid-column-start:6}.panel-grid .g-start-xl-7{grid-column-start:7}.panel-grid .g-start-xl-8{grid-column-start:8}.panel-grid .g-start-xl-9{grid-column-start:9}.panel-grid .g-start-xl-10{grid-column-start:10}.panel-grid .g-start-xl-11{grid-column-start:11}.panel-grid .g-start-xl-12{grid-column-start:12}.panel-grid .g-start-xl-13{grid-column-start:13}.panel-grid .g-start-xl-14{grid-column-start:14}.panel-grid .g-start-xl-15{grid-column-start:15}.panel-grid .g-start-xl-16{grid-column-start:16}.panel-grid .g-start-xl-17{grid-column-start:17}.panel-grid .g-start-xl-18{grid-column-start:18}.panel-grid .g-start-xl-19{grid-column-start:19}.panel-grid .g-start-xl-20{grid-column-start:20}.panel-grid .g-start-xl-21{grid-column-start:21}.panel-grid .g-start-xl-22{grid-column-start:22}.panel-grid .g-start-xl-23{grid-column-start:23}}@media(min-width: 1400px){.panel-grid .g-col-xxl-1{grid-column:auto/span 1}.panel-grid .g-col-xxl-2{grid-column:auto/span 2}.panel-grid .g-col-xxl-3{grid-column:auto/span 3}.panel-grid .g-col-xxl-4{grid-column:auto/span 4}.panel-grid .g-col-xxl-5{grid-column:auto/span 5}.panel-grid .g-col-xxl-6{grid-column:auto/span 6}.panel-grid .g-col-xxl-7{grid-column:auto/span 7}.panel-grid .g-col-xxl-8{grid-column:auto/span 8}.panel-grid .g-col-xxl-9{grid-column:auto/span 9}.panel-grid .g-col-xxl-10{grid-column:auto/span 10}.panel-grid .g-col-xxl-11{grid-column:auto/span 11}.panel-grid .g-col-xxl-12{grid-column:auto/span 12}.panel-grid .g-col-xxl-13{grid-column:auto/span 13}.panel-grid .g-col-xxl-14{grid-column:auto/span 14}.panel-grid .g-col-xxl-15{grid-column:auto/span 15}.panel-grid .g-col-xxl-16{grid-column:auto/span 16}.panel-grid .g-col-xxl-17{grid-column:auto/span 17}.panel-grid .g-col-xxl-18{grid-column:auto/span 18}.panel-grid .g-col-xxl-19{grid-column:auto/span 19}.panel-grid .g-col-xxl-20{grid-column:auto/span 20}.panel-grid .g-col-xxl-21{grid-column:auto/span 21}.panel-grid .g-col-xxl-22{grid-column:auto/span 22}.panel-grid .g-col-xxl-23{grid-column:auto/span 23}.panel-grid .g-col-xxl-24{grid-column:auto/span 24}.panel-grid .g-start-xxl-1{grid-column-start:1}.panel-grid .g-start-xxl-2{grid-column-start:2}.panel-grid .g-start-xxl-3{grid-column-start:3}.panel-grid .g-start-xxl-4{grid-column-start:4}.panel-grid .g-start-xxl-5{grid-column-start:5}.panel-grid .g-start-xxl-6{grid-column-start:6}.panel-grid .g-start-xxl-7{grid-column-start:7}.panel-grid .g-start-xxl-8{grid-column-start:8}.panel-grid .g-start-xxl-9{grid-column-start:9}.panel-grid .g-start-xxl-10{grid-column-start:10}.panel-grid .g-start-xxl-11{grid-column-start:11}.panel-grid .g-start-xxl-12{grid-column-start:12}.panel-grid .g-start-xxl-13{grid-column-start:13}.panel-grid .g-start-xxl-14{grid-column-start:14}.panel-grid .g-start-xxl-15{grid-column-start:15}.panel-grid .g-start-xxl-16{grid-column-start:16}.panel-grid .g-start-xxl-17{grid-column-start:17}.panel-grid .g-start-xxl-18{grid-column-start:18}.panel-grid .g-start-xxl-19{grid-column-start:19}.panel-grid .g-start-xxl-20{grid-column-start:20}.panel-grid .g-start-xxl-21{grid-column-start:21}.panel-grid .g-start-xxl-22{grid-column-start:22}.panel-grid .g-start-xxl-23{grid-column-start:23}}main{margin-top:1em;margin-bottom:1em}h1,.h1,h2,.h2{opacity:.9;margin-top:2rem;margin-bottom:1rem;font-weight:600}h1.title,.title.h1{margin-top:0}h2,.h2{border-bottom:1px solid #dee2e6;padding-bottom:.5rem}h3,.h3{font-weight:600}h3,.h3,h4,.h4{opacity:.9;margin-top:1.5rem}h5,.h5,h6,.h6{opacity:.9}.header-section-number{color:#747a7f}.nav-link.active .header-section-number{color:inherit}mark,.mark{padding:0em}.panel-caption,caption,.figure-caption{font-size:.9rem}.panel-caption,.figure-caption,figcaption{color:#747a7f}.table-caption,caption{color:#373a3c}.quarto-layout-cell[data-ref-parent] caption{color:#747a7f}.column-margin figcaption,.margin-caption,div.aside,aside,.column-margin{color:#747a7f;font-size:.825rem}.panel-caption.margin-caption{text-align:inherit}.column-margin.column-container p{margin-bottom:0}.column-margin.column-container>*:not(.collapse){padding-top:.5em;padding-bottom:.5em;display:block}.column-margin.column-container>*.collapse:not(.show){display:none}@media(min-width: 768px){.column-margin.column-container .callout-margin-content:first-child{margin-top:4.5em}.column-margin.column-container .callout-margin-content-simple:first-child{margin-top:3.5em}}.margin-caption>*{padding-top:.5em;padding-bottom:.5em}@media(max-width: 767.98px){.quarto-layout-row{flex-direction:column}}.nav-tabs .nav-item{margin-top:1px;cursor:pointer}.tab-content{margin-top:0px;border-left:#dee2e6 1px solid;border-right:#dee2e6 1px solid;border-bottom:#dee2e6 1px solid;margin-left:0;padding:1em;margin-bottom:1em}@media(max-width: 767.98px){.layout-sidebar{margin-left:0;margin-right:0}}.panel-sidebar,.panel-sidebar .form-control,.panel-input,.panel-input .form-control,.selectize-dropdown{font-size:.9rem}.panel-sidebar .form-control,.panel-input .form-control{padding-top:.1rem}.tab-pane div.sourceCode{margin-top:0px}.tab-pane>p{padding-top:1em}.tab-content>.tab-pane:not(.active){display:none !important}div.sourceCode{background-color:rgba(233,236,239,.65);border:1px solid rgba(233,236,239,.65);border-radius:.25rem}pre.sourceCode{background-color:rgba(0,0,0,0)}pre.sourceCode{border:none;font-size:.875em;overflow:visible !important;padding:.4em}.callout pre.sourceCode{padding-left:0}div.sourceCode{overflow-y:hidden}.callout div.sourceCode{margin-left:initial}.blockquote{font-size:inherit;padding-left:1rem;padding-right:1.5rem;color:#747a7f}.blockquote h1:first-child,.blockquote .h1:first-child,.blockquote h2:first-child,.blockquote .h2:first-child,.blockquote h3:first-child,.blockquote .h3:first-child,.blockquote h4:first-child,.blockquote .h4:first-child,.blockquote h5:first-child,.blockquote .h5:first-child{margin-top:0}pre{background-color:initial;padding:initial;border:initial}p code:not(.sourceCode),li code:not(.sourceCode),td code:not(.sourceCode){background-color:#f7f7f7;padding:.2em}nav p code:not(.sourceCode),nav li code:not(.sourceCode),nav td code:not(.sourceCode){background-color:rgba(0,0,0,0);padding:0}td code:not(.sourceCode){white-space:pre-wrap}#quarto-embedded-source-code-modal>.modal-dialog{max-width:1000px;padding-left:1.75rem;padding-right:1.75rem}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body{padding:0}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-body div.sourceCode{margin:0;padding:.2rem .2rem;border-radius:0px;border:none}#quarto-embedded-source-code-modal>.modal-dialog>.modal-content>.modal-header{padding:.7rem}.code-tools-button{font-size:1rem;padding:.15rem .15rem;margin-left:5px;color:#6c757d;background-color:rgba(0,0,0,0);transition:initial;cursor:pointer}.code-tools-button>.bi::before{display:inline-block;height:1rem;width:1rem;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:1rem 1rem}.code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button>.bi::before{background-image:url('data:image/svg+xml,')}#quarto-embedded-source-code-modal .code-copy-button-checked>.bi::before{background-image:url('data:image/svg+xml,')}.sidebar{will-change:top;transition:top 200ms linear;position:sticky;overflow-y:auto;padding-top:1.2em;max-height:100vh}.sidebar.toc-left,.sidebar.margin-sidebar{top:0px;padding-top:1em}.sidebar.toc-left>*,.sidebar.margin-sidebar>*{padding-top:.5em}.sidebar.quarto-banner-title-block-sidebar>*{padding-top:1.65em}figure .quarto-notebook-link{margin-top:.5em}.quarto-notebook-link{font-size:.75em;color:#6c757d;margin-bottom:1em;text-decoration:none;display:block}.quarto-notebook-link:hover{text-decoration:underline;color:#2780e3}.quarto-notebook-link::before{display:inline-block;height:.75rem;width:.75rem;margin-bottom:0em;margin-right:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}.quarto-alternate-notebooks i.bi,.quarto-alternate-formats i.bi{margin-right:.4em}.quarto-notebook .cell-container{display:flex}.quarto-notebook .cell-container .cell{flex-grow:4}.quarto-notebook .cell-container .cell-decorator{padding-top:1.5em;padding-right:1em;text-align:right}.quarto-notebook h2,.quarto-notebook .h2{border-bottom:none}.sidebar .quarto-alternate-formats a,.sidebar .quarto-alternate-notebooks a{text-decoration:none}.sidebar .quarto-alternate-formats a:hover,.sidebar .quarto-alternate-notebooks a:hover{color:#2780e3}.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2,.sidebar nav[role=doc-toc]>h2,.sidebar nav[role=doc-toc]>.h2{font-size:.875rem;font-weight:400;margin-bottom:.5rem;margin-top:.3rem;font-family:inherit;border-bottom:0;padding-bottom:0;padding-top:0px}.sidebar .quarto-alternate-notebooks h2,.sidebar .quarto-alternate-notebooks .h2,.sidebar .quarto-alternate-formats h2,.sidebar .quarto-alternate-formats .h2{margin-top:1rem}.sidebar nav[role=doc-toc]>ul a{border-left:1px solid #e9ecef;padding-left:.6rem}.sidebar .quarto-alternate-notebooks h2>ul a,.sidebar .quarto-alternate-notebooks .h2>ul a,.sidebar .quarto-alternate-formats h2>ul a,.sidebar .quarto-alternate-formats .h2>ul a{border-left:none;padding-left:.6rem}.sidebar .quarto-alternate-notebooks ul a:empty,.sidebar .quarto-alternate-formats ul a:empty,.sidebar nav[role=doc-toc]>ul a:empty{display:none}.sidebar .quarto-alternate-notebooks ul,.sidebar .quarto-alternate-formats ul,.sidebar nav[role=doc-toc] ul{padding-left:0;list-style:none;font-size:.875rem;font-weight:300}.sidebar .quarto-alternate-notebooks ul li a,.sidebar .quarto-alternate-formats ul li a,.sidebar nav[role=doc-toc]>ul li a{line-height:1.1rem;padding-bottom:.2rem;padding-top:.2rem;color:inherit}.sidebar nav[role=doc-toc] ul>li>ul>li>a{padding-left:1.2em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>a{padding-left:2.4em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>a{padding-left:3.6em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:4.8em}.sidebar nav[role=doc-toc] ul>li>ul>li>ul>li>ul>li>ul>li>ul>li>a{padding-left:6em}.sidebar nav[role=doc-toc] ul>li>a.active,.sidebar nav[role=doc-toc] ul>li>ul>li>a.active{border-left:1px solid #2780e3;color:#2780e3 !important}.sidebar nav[role=doc-toc] ul>li>a:hover,.sidebar nav[role=doc-toc] ul>li>ul>li>a:hover{color:#2780e3 !important}kbd,.kbd{color:#373a3c;background-color:#f8f9fa;border:1px solid;border-radius:5px;border-color:#dee2e6}div.hanging-indent{margin-left:1em;text-indent:-1em}.citation a,.footnote-ref{text-decoration:none}.footnotes ol{padding-left:1em}.tippy-content>*{margin-bottom:.7em}.tippy-content>*:last-child{margin-bottom:0}.table a{word-break:break-word}.table>thead{border-top-width:1px;border-top-color:#dee2e6;border-bottom:1px solid #b6babc}.callout{margin-top:1.25rem;margin-bottom:1.25rem;border-radius:.25rem;overflow-wrap:break-word}.callout .callout-title-container{overflow-wrap:anywhere}.callout.callout-style-simple{padding:.4em .7em;border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout.callout-style-default{border-left:5px solid;border-right:1px solid #dee2e6;border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.callout .callout-body-container{flex-grow:1}.callout.callout-style-simple .callout-body{font-size:.9rem;font-weight:400}.callout.callout-style-default .callout-body{font-size:.9rem;font-weight:400}.callout.callout-titled .callout-body{margin-top:.2em}.callout:not(.no-icon).callout-titled.callout-style-simple .callout-body{padding-left:1.6em}.callout.callout-titled>.callout-header{padding-top:.2em;margin-bottom:-0.2em}.callout.callout-style-simple>div.callout-header{border-bottom:none;font-size:.9rem;font-weight:600;opacity:75%}.callout.callout-style-default>div.callout-header{border-bottom:none;font-weight:600;opacity:85%;font-size:.9rem;padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body{padding-left:.5em;padding-right:.5em}.callout.callout-style-default div.callout-body>:first-child{margin-top:.5em}.callout>div.callout-header[data-bs-toggle=collapse]{cursor:pointer}.callout.callout-style-default .callout-header[aria-expanded=false],.callout.callout-style-default .callout-header[aria-expanded=true]{padding-top:0px;margin-bottom:0px;align-items:center}.callout.callout-titled .callout-body>:last-child:not(.sourceCode),.callout.callout-titled .callout-body>div>:last-child:not(.sourceCode){margin-bottom:.5rem}.callout:not(.callout-titled) .callout-body>:first-child,.callout:not(.callout-titled) .callout-body>div>:first-child{margin-top:.25rem}.callout:not(.callout-titled) .callout-body>:last-child,.callout:not(.callout-titled) .callout-body>div>:last-child{margin-bottom:.2rem}.callout.callout-style-simple .callout-icon::before,.callout.callout-style-simple .callout-toggle::before{height:1rem;width:1rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.callout.callout-style-default .callout-icon::before,.callout.callout-style-default .callout-toggle::before{height:.9rem;width:.9rem;display:inline-block;content:"";background-repeat:no-repeat;background-size:.9rem .9rem}.callout.callout-style-default .callout-toggle::before{margin-top:5px}.callout .callout-btn-toggle .callout-toggle::before{transition:transform .2s linear}.callout .callout-header[aria-expanded=false] .callout-toggle::before{transform:rotate(-90deg)}.callout .callout-header[aria-expanded=true] .callout-toggle::before{transform:none}.callout.callout-style-simple:not(.no-icon) div.callout-icon-container{padding-top:.2em;padding-right:.55em}.callout.callout-style-default:not(.no-icon) div.callout-icon-container{padding-top:.1em;padding-right:.35em}.callout.callout-style-default:not(.no-icon) div.callout-title-container{margin-top:-1px}.callout.callout-style-default.callout-caution:not(.no-icon) div.callout-icon-container{padding-top:.3em;padding-right:.35em}.callout>.callout-body>.callout-icon-container>.no-icon,.callout>.callout-header>.callout-icon-container>.no-icon{display:none}div.callout.callout{border-left-color:#6c757d}div.callout.callout-style-default>.callout-header{background-color:#6c757d}div.callout-note.callout{border-left-color:#2780e3}div.callout-note.callout-style-default>.callout-header{background-color:#e9f2fc}div.callout-note:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-note .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-tip.callout{border-left-color:#3fb618}div.callout-tip.callout-style-default>.callout-header{background-color:#ecf8e8}div.callout-tip:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-tip .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-warning.callout{border-left-color:#ff7518}div.callout-warning.callout-style-default>.callout-header{background-color:#fff1e8}div.callout-warning:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-warning .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-caution.callout{border-left-color:#f0ad4e}div.callout-caution.callout-style-default>.callout-header{background-color:#fef7ed}div.callout-caution:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-caution .callout-toggle::before{background-image:url('data:image/svg+xml,')}div.callout-important.callout{border-left-color:#ff0039}div.callout-important.callout-style-default>.callout-header{background-color:#ffe6eb}div.callout-important:not(.callout-titled) .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important.callout-titled .callout-icon::before{background-image:url('data:image/svg+xml,');}div.callout-important .callout-toggle::before{background-image:url('data:image/svg+xml,')}.quarto-toggle-container{display:flex;align-items:center}.quarto-reader-toggle .bi::before,.quarto-color-scheme-toggle .bi::before{display:inline-block;height:1rem;width:1rem;content:"";background-repeat:no-repeat;background-size:1rem 1rem}.sidebar-navigation{padding-left:20px}.navbar .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.navbar .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle:not(.alternate) .bi::before{background-image:url('data:image/svg+xml,')}.sidebar-navigation .quarto-color-scheme-toggle.alternate .bi::before{background-image:url('data:image/svg+xml,')}.quarto-sidebar-toggle{border-color:#dee2e6;border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem;border-style:solid;border-width:1px;overflow:hidden;border-top-width:0px;padding-top:0px !important}.quarto-sidebar-toggle-title{cursor:pointer;padding-bottom:2px;margin-left:.25em;text-align:center;font-weight:400;font-size:.775em}#quarto-content .quarto-sidebar-toggle{background:#fafafa}#quarto-content .quarto-sidebar-toggle-title{color:#373a3c}.quarto-sidebar-toggle-icon{color:#dee2e6;margin-right:.5em;float:right;transition:transform .2s ease}.quarto-sidebar-toggle-icon::before{padding-top:5px}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-icon{transform:rotate(-180deg)}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-title{border-bottom:solid #dee2e6 1px}.quarto-sidebar-toggle-contents{background-color:#fff;padding-right:10px;padding-left:10px;margin-top:0px !important;transition:max-height .5s ease}.quarto-sidebar-toggle.expanded .quarto-sidebar-toggle-contents{padding-top:1em;padding-bottom:10px}.quarto-sidebar-toggle:not(.expanded) .quarto-sidebar-toggle-contents{padding-top:0px !important;padding-bottom:0px}nav[role=doc-toc]{z-index:1020}#quarto-sidebar>*,nav[role=doc-toc]>*{transition:opacity .1s ease,border .1s ease}#quarto-sidebar.slow>*,nav[role=doc-toc].slow>*{transition:opacity .4s ease,border .4s ease}.quarto-color-scheme-toggle:not(.alternate).top-right .bi::before{background-image:url('data:image/svg+xml,')}.quarto-color-scheme-toggle.alternate.top-right .bi::before{background-image:url('data:image/svg+xml,')}#quarto-appendix.default{border-top:1px solid #dee2e6}#quarto-appendix.default{background-color:#fff;padding-top:1.5em;margin-top:2em;z-index:998}#quarto-appendix.default .quarto-appendix-heading{margin-top:0;line-height:1.4em;font-weight:600;opacity:.9;border-bottom:none;margin-bottom:0}#quarto-appendix.default .footnotes ol,#quarto-appendix.default .footnotes ol li>p:last-of-type,#quarto-appendix.default .quarto-appendix-contents>p:last-of-type{margin-bottom:0}#quarto-appendix.default .quarto-appendix-secondary-label{margin-bottom:.4em}#quarto-appendix.default .quarto-appendix-bibtex{font-size:.7em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-bibtex code.sourceCode{white-space:pre-wrap}#quarto-appendix.default .quarto-appendix-citeas{font-size:.9em;padding:1em;border:solid 1px #dee2e6;margin-bottom:1em}#quarto-appendix.default .quarto-appendix-heading{font-size:1em !important}#quarto-appendix.default *[role=doc-endnotes]>ol,#quarto-appendix.default .quarto-appendix-contents>*:not(h2):not(.h2){font-size:.9em}#quarto-appendix.default section{padding-bottom:1.5em}#quarto-appendix.default section *[role=doc-endnotes],#quarto-appendix.default section>*:not(a){opacity:.9;word-wrap:break-word}.btn.btn-quarto,div.cell-output-display .btn-quarto{color:#cbcccc;background-color:#373a3c;border-color:#373a3c}.btn.btn-quarto:hover,div.cell-output-display .btn-quarto:hover{color:#cbcccc;background-color:#555859;border-color:#4b4e50}.btn-check:focus+.btn.btn-quarto,.btn.btn-quarto:focus,.btn-check:focus+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:focus{color:#cbcccc;background-color:#555859;border-color:#4b4e50;box-shadow:0 0 0 .25rem rgba(77,80,82,.5)}.btn-check:checked+.btn.btn-quarto,.btn-check:active+.btn.btn-quarto,.btn.btn-quarto:active,.btn.btn-quarto.active,.show>.btn.btn-quarto.dropdown-toggle,.btn-check:checked+div.cell-output-display .btn-quarto,.btn-check:active+div.cell-output-display .btn-quarto,div.cell-output-display .btn-quarto:active,div.cell-output-display .btn-quarto.active,.show>div.cell-output-display .btn-quarto.dropdown-toggle{color:#fff;background-color:#5f6163;border-color:#4b4e50}.btn-check:checked+.btn.btn-quarto:focus,.btn-check:active+.btn.btn-quarto:focus,.btn.btn-quarto:active:focus,.btn.btn-quarto.active:focus,.show>.btn.btn-quarto.dropdown-toggle:focus,.btn-check:checked+div.cell-output-display .btn-quarto:focus,.btn-check:active+div.cell-output-display .btn-quarto:focus,div.cell-output-display .btn-quarto:active:focus,div.cell-output-display .btn-quarto.active:focus,.show>div.cell-output-display .btn-quarto.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(77,80,82,.5)}.btn.btn-quarto:disabled,.btn.btn-quarto.disabled,div.cell-output-display .btn-quarto:disabled,div.cell-output-display .btn-quarto.disabled{color:#fff;background-color:#373a3c;border-color:#373a3c}nav.quarto-secondary-nav.color-navbar{background-color:#2780e3;color:#fdfeff}nav.quarto-secondary-nav.color-navbar h1,nav.quarto-secondary-nav.color-navbar .h1,nav.quarto-secondary-nav.color-navbar .quarto-btn-toggle{color:#fdfeff}@media(max-width: 991.98px){body.nav-sidebar .quarto-title-banner{margin-bottom:0;padding-bottom:0}body.nav-sidebar #title-block-header{margin-block-end:0}}p.subtitle{margin-top:.25em;margin-bottom:.5em}code a:any-link{color:inherit;text-decoration-color:#6c757d}/*! light */div.observablehq table thead tr th{background-color:var(--bs-body-bg)}input,button,select,optgroup,textarea{background-color:var(--bs-body-bg)}.code-annotated .code-copy-button{margin-right:1.25em;margin-top:0;padding-bottom:0;padding-top:3px}.code-annotation-gutter-bg{background-color:#fff}.code-annotation-gutter{background-color:rgba(233,236,239,.65)}.code-annotation-gutter,.code-annotation-gutter-bg{height:100%;width:calc(20px + .5em);position:absolute;top:0;right:0}dl.code-annotation-container-grid dt{margin-right:1em;margin-top:.25rem}dl.code-annotation-container-grid dt{font-family:var(--bs-font-monospace);color:#4f5457;border:solid #4f5457 1px;border-radius:50%;height:22px;width:22px;line-height:22px;font-size:11px;text-align:center;vertical-align:middle;text-decoration:none}dl.code-annotation-container-grid dt[data-target-cell]{cursor:pointer}dl.code-annotation-container-grid dt[data-target-cell].code-annotation-active{color:#fff;border:solid #aaa 1px;background-color:#aaa}pre.code-annotation-code{padding-top:0;padding-bottom:0}pre.code-annotation-code code{z-index:3}#code-annotation-line-highlight-gutter{width:100%;border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}#code-annotation-line-highlight{margin-left:-4em;width:calc(100% + 4em);border-top:solid rgba(170,170,170,.2666666667) 1px;border-bottom:solid rgba(170,170,170,.2666666667) 1px;z-index:2;background-color:rgba(170,170,170,.1333333333)}code.sourceCode .code-annotation-anchor.code-annotation-active{background-color:var(--quarto-hl-normal-color, #aaaaaa);border:solid var(--quarto-hl-normal-color, #aaaaaa) 1px;color:#e9ecef;font-weight:bolder}code.sourceCode .code-annotation-anchor{font-family:var(--bs-font-monospace);color:var(--quarto-hl-co-color);border:solid var(--quarto-hl-co-color) 1px;border-radius:50%;height:18px;width:18px;font-size:9px;margin-top:2px}code.sourceCode button.code-annotation-anchor{padding:2px}code.sourceCode a.code-annotation-anchor{line-height:18px;text-align:center;vertical-align:middle;cursor:default;text-decoration:none}@media print{.page-columns .column-screen-inset{grid-column:page-start-inset/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset table{background:#fff}.page-columns .column-screen-inset-left{grid-column:page-start-inset/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-left table{background:#fff}.page-columns .column-screen-inset-right{grid-column:body-content-start/page-end-inset;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-inset-right table{background:#fff}.page-columns .column-screen{grid-column:page-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen table{background:#fff}.page-columns .column-screen-left{grid-column:page-start/body-content-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-left table{background:#fff}.page-columns .column-screen-right{grid-column:body-content-start/page-end;z-index:998;transform:translate3d(0, 0, 0)}.page-columns .column-screen-right table{background:#fff}.page-columns .column-screen-inset-shaded{grid-column:page-start-inset/page-end-inset;padding:1em;background:#f8f9fa;z-index:998;transform:translate3d(0, 0, 0);margin-bottom:1em}}.quarto-video{margin-bottom:1em}.table>thead{border-top-width:0}.table>:not(caption)>*:not(:last-child)>*{border-bottom-color:#ebeced;border-bottom-style:solid;border-bottom-width:1px}.table>:not(:first-child){border-top:1px solid #b6babc;border-bottom:1px solid inherit}.table tbody{border-bottom-color:#b6babc}a.external:after{display:inline-block;height:.75rem;width:.75rem;margin-bottom:.15em;margin-left:.25em;content:"";vertical-align:-0.125em;background-image:url('data:image/svg+xml,');background-repeat:no-repeat;background-size:.75rem .75rem}div.sourceCode code a.external:after{content:none}a.external:after:hover{cursor:pointer}.quarto-ext-icon{display:inline-block;font-size:.75em;padding-left:.3em}.code-with-filename .code-with-filename-file{margin-bottom:0;padding-bottom:2px;padding-top:2px;padding-left:.7em;border:var(--quarto-border-width) solid var(--quarto-border-color);border-radius:var(--quarto-border-radius);border-bottom:0;border-bottom-left-radius:0%;border-bottom-right-radius:0%}.code-with-filename div.sourceCode,.reveal .code-with-filename div.sourceCode{margin-top:0;border-top-left-radius:0%;border-top-right-radius:0%}.code-with-filename .code-with-filename-file pre{margin-bottom:0}.code-with-filename .code-with-filename-file,.code-with-filename .code-with-filename-file pre{background-color:rgba(219,219,219,.8)}.quarto-dark .code-with-filename .code-with-filename-file,.quarto-dark .code-with-filename .code-with-filename-file pre{background-color:#555}.code-with-filename .code-with-filename-file strong{font-weight:400}.quarto-title-banner{margin-bottom:1em;color:#fdfeff;background:#2780e3}.quarto-title-banner .code-tools-button{color:#97cbff}.quarto-title-banner .code-tools-button:hover{color:#fdfeff}.quarto-title-banner .code-tools-button>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .code-tools-button:hover>.bi::before{background-image:url('data:image/svg+xml,')}.quarto-title-banner .quarto-title .title{font-weight:600}.quarto-title-banner .quarto-categories{margin-top:.75em}@media(min-width: 992px){.quarto-title-banner{padding-top:2.5em;padding-bottom:2.5em}}@media(max-width: 991.98px){.quarto-title-banner{padding-top:1em;padding-bottom:1em}}main.quarto-banner-title-block>section:first-child>h2,main.quarto-banner-title-block>section:first-child>.h2,main.quarto-banner-title-block>section:first-child>h3,main.quarto-banner-title-block>section:first-child>.h3,main.quarto-banner-title-block>section:first-child>h4,main.quarto-banner-title-block>section:first-child>.h4{margin-top:0}.quarto-title .quarto-categories{display:flex;flex-wrap:wrap;row-gap:.5em;column-gap:.4em;padding-bottom:.5em;margin-top:.75em}.quarto-title .quarto-categories .quarto-category{padding:.25em .75em;font-size:.65em;text-transform:uppercase;border:solid 1px;border-radius:.25rem;opacity:.6}.quarto-title .quarto-categories .quarto-category a{color:inherit}#title-block-header.quarto-title-block.default .quarto-title-meta{display:grid;grid-template-columns:repeat(2, 1fr)}#title-block-header.quarto-title-block.default .quarto-title .title{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-author-orcid img{margin-top:-5px}#title-block-header.quarto-title-block.default .quarto-description p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p,#title-block-header.quarto-title-block.default .quarto-title-authors p,#title-block-header.quarto-title-block.default .quarto-title-affiliations p{margin-bottom:.1em}#title-block-header.quarto-title-block.default .quarto-title-meta-heading{text-transform:uppercase;margin-top:1em;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-contents{font-size:.9em}#title-block-header.quarto-title-block.default .quarto-title-meta-contents a{color:#373a3c}#title-block-header.quarto-title-block.default .quarto-title-meta-contents p.affiliation:last-of-type{margin-bottom:.7em}#title-block-header.quarto-title-block.default p.affiliation{margin-bottom:.1em}#title-block-header.quarto-title-block.default .description,#title-block-header.quarto-title-block.default .abstract{margin-top:0}#title-block-header.quarto-title-block.default .description>p,#title-block-header.quarto-title-block.default .abstract>p{font-size:.9em}#title-block-header.quarto-title-block.default .description>p:last-of-type,#title-block-header.quarto-title-block.default .abstract>p:last-of-type{margin-bottom:0}#title-block-header.quarto-title-block.default .description .abstract-title,#title-block-header.quarto-title-block.default .abstract .abstract-title{margin-top:1em;text-transform:uppercase;font-size:.8em;opacity:.8;font-weight:400}#title-block-header.quarto-title-block.default .quarto-title-meta-author{display:grid;grid-template-columns:1fr 1fr}.quarto-title-tools-only{display:flex;justify-content:right}body{-webkit-font-smoothing:antialiased}.badge.bg-light{color:#373a3c}.progress .progress-bar{font-size:8px;line-height:8px}/*# sourceMappingURL=9161419e6f82ea4435380a70856fa72b.css.map */ diff --git a/_proc/_docs/site_libs/bootstrap/bootstrap.min.js b/_proc/_docs/site_libs/bootstrap/bootstrap.min.js new file mode 100644 index 0000000000000000000000000000000000000000..cc0a25561dfb616832227c9e2b2c1b1bbe69bc05 --- /dev/null +++ b/_proc/_docs/site_libs/bootstrap/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v5.1.3 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e()}(this,(function(){"use strict";const t="transitionend",e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i=`#${i.split("#")[1]}`),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},n=t=>{const i=e(t);return i?document.querySelector(i):null},s=e=>{e.dispatchEvent(new Event(t))},o=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),r=t=>o(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(t):null,a=(t,e,i)=>{Object.keys(i).forEach((n=>{const s=i[n],r=e[n],a=r&&o(r)?"element":null==(l=r)?`${l}`:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(s).test(a))throw new TypeError(`${t.toUpperCase()}: Option "${n}" provided type "${a}" but expected type "${s}".`)}))},l=t=>!(!o(t)||0===t.getClientRects().length)&&"visible"===getComputedStyle(t).getPropertyValue("visibility"),c=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},d=()=>{},u=t=>{t.offsetHeight},f=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},p=[],m=()=>"rtl"===document.documentElement.dir,g=t=>{var e;e=()=>{const e=f();if(e){const i=t.NAME,n=e.fn[i];e.fn[i]=t.jQueryInterface,e.fn[i].Constructor=t,e.fn[i].noConflict=()=>(e.fn[i]=n,t.jQueryInterface)}},"loading"===document.readyState?(p.length||document.addEventListener("DOMContentLoaded",(()=>{p.forEach((t=>t()))})),p.push(e)):e()},_=t=>{"function"==typeof t&&t()},b=(e,i,n=!0)=>{if(!n)return void _(e);const o=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const n=Number.parseFloat(e),s=Number.parseFloat(i);return n||s?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0})(i)+5;let r=!1;const a=({target:n})=>{n===i&&(r=!0,i.removeEventListener(t,a),_(e))};i.addEventListener(t,a),setTimeout((()=>{r||s(i)}),o)},v=(t,e,i,n)=>{let s=t.indexOf(e);if(-1===s)return t[!i&&n?t.length-1:0];const o=t.length;return s+=i?1:-1,n&&(s=(s+o)%o),t[Math.max(0,Math.min(s,o-1))]},y=/[^.]*(?=\..*)\.|.*/,w=/\..*/,E=/::\d+$/,A={};let T=1;const O={mouseenter:"mouseover",mouseleave:"mouseout"},C=/^(mouseenter|mouseleave)/i,k=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function L(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function x(t){const e=L(t);return t.uidEvent=e,A[e]=A[e]||{},A[e]}function D(t,e,i=null){const n=Object.keys(t);for(let s=0,o=n.length;sfunction(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};n?n=t(n):i=t(i)}const[o,r,a]=S(e,i,n),l=x(t),c=l[a]||(l[a]={}),h=D(c,r,o?i:null);if(h)return void(h.oneOff=h.oneOff&&s);const d=L(r,e.replace(y,"")),u=o?function(t,e,i){return function n(s){const o=t.querySelectorAll(e);for(let{target:r}=s;r&&r!==this;r=r.parentNode)for(let a=o.length;a--;)if(o[a]===r)return s.delegateTarget=r,n.oneOff&&j.off(t,s.type,e,i),i.apply(r,[s]);return null}}(t,i,n):function(t,e){return function i(n){return n.delegateTarget=t,i.oneOff&&j.off(t,n.type,e),e.apply(t,[n])}}(t,i);u.delegationSelector=o?i:null,u.originalHandler=r,u.oneOff=s,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function I(t,e,i,n,s){const o=D(e[i],n,s);o&&(t.removeEventListener(i,o,Boolean(s)),delete e[i][o.uidEvent])}function P(t){return t=t.replace(w,""),O[t]||t}const j={on(t,e,i,n){N(t,e,i,n,!1)},one(t,e,i,n){N(t,e,i,n,!0)},off(t,e,i,n){if("string"!=typeof e||!t)return;const[s,o,r]=S(e,i,n),a=r!==e,l=x(t),c=e.startsWith(".");if(void 0!==o){if(!l||!l[r])return;return void I(t,l,r,o,s?i:null)}c&&Object.keys(l).forEach((i=>{!function(t,e,i,n){const s=e[i]||{};Object.keys(s).forEach((o=>{if(o.includes(n)){const n=s[o];I(t,e,i,n.originalHandler,n.delegationSelector)}}))}(t,l,i,e.slice(1))}));const h=l[r]||{};Object.keys(h).forEach((i=>{const n=i.replace(E,"");if(!a||e.includes(n)){const e=h[i];I(t,l,r,e.originalHandler,e.delegationSelector)}}))},trigger(t,e,i){if("string"!=typeof e||!t)return null;const n=f(),s=P(e),o=e!==s,r=k.has(s);let a,l=!0,c=!0,h=!1,d=null;return o&&n&&(a=n.Event(e,i),n(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),h=a.isDefaultPrevented()),r?(d=document.createEvent("HTMLEvents"),d.initEvent(s,l,!0)):d=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach((t=>{Object.defineProperty(d,t,{get:()=>i[t]})})),h&&d.preventDefault(),c&&t.dispatchEvent(d),d.defaultPrevented&&void 0!==a&&a.preventDefault(),d}},M=new Map,H={set(t,e,i){M.has(t)||M.set(t,new Map);const n=M.get(t);n.has(e)||0===n.size?n.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>M.has(t)&&M.get(t).get(e)||null,remove(t,e){if(!M.has(t))return;const i=M.get(t);i.delete(e),0===i.size&&M.delete(t)}};class B{constructor(t){(t=r(t))&&(this._element=t,H.set(this._element,this.constructor.DATA_KEY,this))}dispose(){H.remove(this._element,this.constructor.DATA_KEY),j.off(this._element,this.constructor.EVENT_KEY),Object.getOwnPropertyNames(this).forEach((t=>{this[t]=null}))}_queueCallback(t,e,i=!0){b(t,e,i)}static getInstance(t){return H.get(r(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.1.3"}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}}const R=(t,e="hide")=>{const i=`click.dismiss${t.EVENT_KEY}`,s=t.NAME;j.on(document,i,`[data-bs-dismiss="${s}"]`,(function(i){if(["A","AREA"].includes(this.tagName)&&i.preventDefault(),c(this))return;const o=n(this)||this.closest(`.${s}`);t.getOrCreateInstance(o)[e]()}))};class W extends B{static get NAME(){return"alert"}close(){if(j.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),j.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=W.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}R(W,"close"),g(W);const $='[data-bs-toggle="button"]';class z extends B{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=z.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}function q(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function F(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}j.on(document,"click.bs.button.data-api",$,(t=>{t.preventDefault();const e=t.target.closest($);z.getOrCreateInstance(e).toggle()})),g(z);const U={setDataAttribute(t,e,i){t.setAttribute(`data-bs-${F(e)}`,i)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${F(e)}`)},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter((t=>t.startsWith("bs"))).forEach((i=>{let n=i.replace(/^bs/,"");n=n.charAt(0).toLowerCase()+n.slice(1,n.length),e[n]=q(t.dataset[i])})),e},getDataAttribute:(t,e)=>q(t.getAttribute(`data-bs-${F(e)}`)),offset(t){const e=t.getBoundingClientRect();return{top:e.top+window.pageYOffset,left:e.left+window.pageXOffset}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const i=[];let n=t.parentNode;for(;n&&n.nodeType===Node.ELEMENT_NODE&&3!==n.nodeType;)n.matches(e)&&i.push(n),n=n.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(", ");return this.find(e,t).filter((t=>!c(t)&&l(t)))}},K="carousel",X={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},Y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},Q="next",G="prev",Z="left",J="right",tt={ArrowLeft:J,ArrowRight:Z},et="slid.bs.carousel",it="active",nt=".active.carousel-item";class st extends B{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return X}static get NAME(){return K}next(){this._slide(Q)}nextWhenVisible(){!document.hidden&&l(this._element)&&this.next()}prev(){this._slide(G)}pause(t){t||(this._isPaused=!0),V.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(s(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=V.findOne(nt,this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void j.one(this._element,et,(()=>this.to(t)));if(e===t)return this.pause(),void this.cycle();const i=t>e?Q:G;this._slide(i,this._items[t])}_getConfig(t){return t={...X,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(K,t,Y),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?J:Z)}_addEventListeners(){this._config.keyboard&&j.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(j.on(this._element,"mouseenter.bs.carousel",(t=>this.pause(t))),j.on(this._element,"mouseleave.bs.carousel",(t=>this.cycle(t)))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>this._pointerEvent&&("pen"===t.pointerType||"touch"===t.pointerType),e=e=>{t(e)?this.touchStartX=e.clientX:this._pointerEvent||(this.touchStartX=e.touches[0].clientX)},i=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},n=e=>{t(e)&&(this.touchDeltaX=e.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((t=>this.cycle(t)),500+this._config.interval))};V.find(".carousel-item img",this._element).forEach((t=>{j.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()))})),this._pointerEvent?(j.on(this._element,"pointerdown.bs.carousel",(t=>e(t))),j.on(this._element,"pointerup.bs.carousel",(t=>n(t))),this._element.classList.add("pointer-event")):(j.on(this._element,"touchstart.bs.carousel",(t=>e(t))),j.on(this._element,"touchmove.bs.carousel",(t=>i(t))),j.on(this._element,"touchend.bs.carousel",(t=>n(t))))}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=tt[t.key];e&&(t.preventDefault(),this._slide(e))}_getItemIndex(t){return this._items=t&&t.parentNode?V.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===Q;return v(this._items,e,i,this._config.wrap)}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),n=this._getItemIndex(V.findOne(nt,this._element));return j.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:n,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(it),e.removeAttribute("aria-current");const i=V.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{j.trigger(this._element,et,{relatedTarget:o,direction:d,from:s,to:r})};if(this._element.classList.contains("slide")){o.classList.add(h),u(o),n.classList.add(c),o.classList.add(c);const t=()=>{o.classList.remove(c,h),o.classList.add(it),n.classList.remove(it,h,c),this._isSliding=!1,setTimeout(f,0)};this._queueCallback(t,n,!0)}else n.classList.remove(it),o.classList.add(it),this._isSliding=!1,f();a&&this.cycle()}_directionToOrder(t){return[J,Z].includes(t)?m()?t===Z?G:Q:t===Z?Q:G:t}_orderToDirection(t){return[Q,G].includes(t)?m()?t===G?Z:J:t===G?J:Z:t}static carouselInterface(t,e){const i=st.getOrCreateInstance(t,e);let{_config:n}=i;"object"==typeof e&&(n={...n,...e});const s="string"==typeof e?e:n.slide;if("number"==typeof e)i.to(e);else if("string"==typeof s){if(void 0===i[s])throw new TypeError(`No method named "${s}"`);i[s]()}else n.interval&&n.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){st.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=n(this);if(!e||!e.classList.contains("carousel"))return;const i={...U.getDataAttributes(e),...U.getDataAttributes(this)},s=this.getAttribute("data-bs-slide-to");s&&(i.interval=!1),st.carouselInterface(e,i),s&&st.getInstance(e).to(s),t.preventDefault()}}j.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",st.dataApiClickHandler),j.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element));null!==s&&o.length&&(this._selector=s,this._triggerArray.push(e))}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return rt}static get NAME(){return ot}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t,e=[];if(this._config.parent){const t=V.find(ut,this._config.parent);e=V.find(".collapse.show, .collapse.collapsing",this._config.parent).filter((e=>!t.includes(e)))}const i=V.findOne(this._selector);if(e.length){const n=e.find((t=>i!==t));if(t=n?pt.getInstance(n):null,t&&t._isTransitioning)return}if(j.trigger(this._element,"show.bs.collapse").defaultPrevented)return;e.forEach((e=>{i!==e&&pt.getOrCreateInstance(e,{toggle:!1}).hide(),t||H.set(e,"bs.collapse",null)}));const n=this._getDimension();this._element.classList.remove(ct),this._element.classList.add(ht),this._element.style[n]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${n[0].toUpperCase()+n.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct,lt),this._element.style[n]="",j.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[n]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(j.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,u(this._element),this._element.classList.add(ht),this._element.classList.remove(ct,lt);const e=this._triggerArray.length;for(let t=0;t{this._isTransitioning=!1,this._element.classList.remove(ht),this._element.classList.add(ct),j.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(lt)}_getConfig(t){return(t={...rt,...U.getDataAttributes(this._element),...t}).toggle=Boolean(t.toggle),t.parent=r(t.parent),a(ot,t,at),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=V.find(ut,this._config.parent);V.find(ft,this._config.parent).filter((e=>!t.includes(e))).forEach((t=>{const e=n(t);e&&this._addAriaAndCollapsedClass([t],this._isShown(e))}))}_addAriaAndCollapsedClass(t,e){t.length&&t.forEach((t=>{e?t.classList.remove(dt):t.classList.add(dt),t.setAttribute("aria-expanded",e)}))}static jQueryInterface(t){return this.each((function(){const e={};"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1);const i=pt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t]()}}))}}j.on(document,"click.bs.collapse.data-api",ft,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=i(this);V.find(e).forEach((t=>{pt.getOrCreateInstance(t,{toggle:!1}).toggle()}))})),g(pt);var mt="top",gt="bottom",_t="right",bt="left",vt="auto",yt=[mt,gt,_t,bt],wt="start",Et="end",At="clippingParents",Tt="viewport",Ot="popper",Ct="reference",kt=yt.reduce((function(t,e){return t.concat([e+"-"+wt,e+"-"+Et])}),[]),Lt=[].concat(yt,[vt]).reduce((function(t,e){return t.concat([e,e+"-"+wt,e+"-"+Et])}),[]),xt="beforeRead",Dt="read",St="afterRead",Nt="beforeMain",It="main",Pt="afterMain",jt="beforeWrite",Mt="write",Ht="afterWrite",Bt=[xt,Dt,St,Nt,It,Pt,jt,Mt,Ht];function Rt(t){return t?(t.nodeName||"").toLowerCase():null}function Wt(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function $t(t){return t instanceof Wt(t).Element||t instanceof Element}function zt(t){return t instanceof Wt(t).HTMLElement||t instanceof HTMLElement}function qt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof Wt(t).ShadowRoot||t instanceof ShadowRoot)}const Ft={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},n=e.attributes[t]||{},s=e.elements[t];zt(s)&&Rt(s)&&(Object.assign(s.style,i),Object.keys(n).forEach((function(t){var e=n[t];!1===e?s.removeAttribute(t):s.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var n=e.elements[t],s=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});zt(n)&&Rt(n)&&(Object.assign(n.style,o),Object.keys(s).forEach((function(t){n.removeAttribute(t)})))}))}},requires:["computeStyles"]};function Ut(t){return t.split("-")[0]}function Vt(t,e){var i=t.getBoundingClientRect();return{width:i.width/1,height:i.height/1,top:i.top/1,right:i.right/1,bottom:i.bottom/1,left:i.left/1,x:i.left/1,y:i.top/1}}function Kt(t){var e=Vt(t),i=t.offsetWidth,n=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-n)<=1&&(n=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:n}}function Xt(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&&qt(i)){var n=e;do{if(n&&t.isSameNode(n))return!0;n=n.parentNode||n.host}while(n)}return!1}function Yt(t){return Wt(t).getComputedStyle(t)}function Qt(t){return["table","td","th"].indexOf(Rt(t))>=0}function Gt(t){return(($t(t)?t.ownerDocument:t.document)||window.document).documentElement}function Zt(t){return"html"===Rt(t)?t:t.assignedSlot||t.parentNode||(qt(t)?t.host:null)||Gt(t)}function Jt(t){return zt(t)&&"fixed"!==Yt(t).position?t.offsetParent:null}function te(t){for(var e=Wt(t),i=Jt(t);i&&Qt(i)&&"static"===Yt(i).position;)i=Jt(i);return i&&("html"===Rt(i)||"body"===Rt(i)&&"static"===Yt(i).position)?e:i||function(t){var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&zt(t)&&"fixed"===Yt(t).position)return null;for(var i=Zt(t);zt(i)&&["html","body"].indexOf(Rt(i))<0;){var n=Yt(i);if("none"!==n.transform||"none"!==n.perspective||"paint"===n.contain||-1!==["transform","perspective"].indexOf(n.willChange)||e&&"filter"===n.willChange||e&&n.filter&&"none"!==n.filter)return i;i=i.parentNode}return null}(t)||e}function ee(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var ie=Math.max,ne=Math.min,se=Math.round;function oe(t,e,i){return ie(t,ne(e,i))}function re(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function ae(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}const le={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,n=t.name,s=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=Ut(i.placement),l=ee(a),c=[bt,_t].indexOf(a)>=0?"height":"width";if(o&&r){var h=function(t,e){return re("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:ae(t,yt))}(s.padding,i),d=Kt(o),u="y"===l?mt:bt,f="y"===l?gt:_t,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],m=r[l]-i.rects.reference[l],g=te(o),_=g?"y"===l?g.clientHeight||0:g.clientWidth||0:0,b=p/2-m/2,v=h[u],y=_-d[c]-h[f],w=_/2-d[c]/2+b,E=oe(v,w,y),A=l;i.modifiersData[n]=((e={})[A]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,n=void 0===i?"[data-popper-arrow]":i;null!=n&&("string"!=typeof n||(n=e.elements.popper.querySelector(n)))&&Xt(e.elements.popper,n)&&(e.elements.arrow=n)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function ce(t){return t.split("-")[1]}var he={top:"auto",right:"auto",bottom:"auto",left:"auto"};function de(t){var e,i=t.popper,n=t.popperRect,s=t.placement,o=t.variation,r=t.offsets,a=t.position,l=t.gpuAcceleration,c=t.adaptive,h=t.roundOffsets,d=!0===h?function(t){var e=t.x,i=t.y,n=window.devicePixelRatio||1;return{x:se(se(e*n)/n)||0,y:se(se(i*n)/n)||0}}(r):"function"==typeof h?h(r):r,u=d.x,f=void 0===u?0:u,p=d.y,m=void 0===p?0:p,g=r.hasOwnProperty("x"),_=r.hasOwnProperty("y"),b=bt,v=mt,y=window;if(c){var w=te(i),E="clientHeight",A="clientWidth";w===Wt(i)&&"static"!==Yt(w=Gt(i)).position&&"absolute"===a&&(E="scrollHeight",A="scrollWidth"),w=w,s!==mt&&(s!==bt&&s!==_t||o!==Et)||(v=gt,m-=w[E]-n.height,m*=l?1:-1),s!==bt&&(s!==mt&&s!==gt||o!==Et)||(b=_t,f-=w[A]-n.width,f*=l?1:-1)}var T,O=Object.assign({position:a},c&&he);return l?Object.assign({},O,((T={})[v]=_?"0":"",T[b]=g?"0":"",T.transform=(y.devicePixelRatio||1)<=1?"translate("+f+"px, "+m+"px)":"translate3d("+f+"px, "+m+"px, 0)",T)):Object.assign({},O,((e={})[v]=_?m+"px":"",e[b]=g?f+"px":"",e.transform="",e))}const ue={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,n=i.gpuAcceleration,s=void 0===n||n,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:Ut(e.placement),variation:ce(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:s};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,de(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,de(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}};var fe={passive:!0};const pe={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,n=t.options,s=n.scroll,o=void 0===s||s,r=n.resize,a=void 0===r||r,l=Wt(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,fe)})),a&&l.addEventListener("resize",i.update,fe),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,fe)})),a&&l.removeEventListener("resize",i.update,fe)}},data:{}};var me={left:"right",right:"left",bottom:"top",top:"bottom"};function ge(t){return t.replace(/left|right|bottom|top/g,(function(t){return me[t]}))}var _e={start:"end",end:"start"};function be(t){return t.replace(/start|end/g,(function(t){return _e[t]}))}function ve(t){var e=Wt(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function ye(t){return Vt(Gt(t)).left+ve(t).scrollLeft}function we(t){var e=Yt(t),i=e.overflow,n=e.overflowX,s=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+s+n)}function Ee(t){return["html","body","#document"].indexOf(Rt(t))>=0?t.ownerDocument.body:zt(t)&&we(t)?t:Ee(Zt(t))}function Ae(t,e){var i;void 0===e&&(e=[]);var n=Ee(t),s=n===(null==(i=t.ownerDocument)?void 0:i.body),o=Wt(n),r=s?[o].concat(o.visualViewport||[],we(n)?n:[]):n,a=e.concat(r);return s?a:a.concat(Ae(Zt(r)))}function Te(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function Oe(t,e){return e===Tt?Te(function(t){var e=Wt(t),i=Gt(t),n=e.visualViewport,s=i.clientWidth,o=i.clientHeight,r=0,a=0;return n&&(s=n.width,o=n.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=n.offsetLeft,a=n.offsetTop)),{width:s,height:o,x:r+ye(t),y:a}}(t)):zt(e)?function(t){var e=Vt(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Te(function(t){var e,i=Gt(t),n=ve(t),s=null==(e=t.ownerDocument)?void 0:e.body,o=ie(i.scrollWidth,i.clientWidth,s?s.scrollWidth:0,s?s.clientWidth:0),r=ie(i.scrollHeight,i.clientHeight,s?s.scrollHeight:0,s?s.clientHeight:0),a=-n.scrollLeft+ye(t),l=-n.scrollTop;return"rtl"===Yt(s||i).direction&&(a+=ie(i.clientWidth,s?s.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(Gt(t)))}function Ce(t){var e,i=t.reference,n=t.element,s=t.placement,o=s?Ut(s):null,r=s?ce(s):null,a=i.x+i.width/2-n.width/2,l=i.y+i.height/2-n.height/2;switch(o){case mt:e={x:a,y:i.y-n.height};break;case gt:e={x:a,y:i.y+i.height};break;case _t:e={x:i.x+i.width,y:l};break;case bt:e={x:i.x-n.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?ee(o):null;if(null!=c){var h="y"===c?"height":"width";switch(r){case wt:e[c]=e[c]-(i[h]/2-n[h]/2);break;case Et:e[c]=e[c]+(i[h]/2-n[h]/2)}}return e}function ke(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=void 0===n?t.placement:n,o=i.boundary,r=void 0===o?At:o,a=i.rootBoundary,l=void 0===a?Tt:a,c=i.elementContext,h=void 0===c?Ot:c,d=i.altBoundary,u=void 0!==d&&d,f=i.padding,p=void 0===f?0:f,m=re("number"!=typeof p?p:ae(p,yt)),g=h===Ot?Ct:Ot,_=t.rects.popper,b=t.elements[u?g:h],v=function(t,e,i){var n="clippingParents"===e?function(t){var e=Ae(Zt(t)),i=["absolute","fixed"].indexOf(Yt(t).position)>=0&&zt(t)?te(t):t;return $t(i)?e.filter((function(t){return $t(t)&&Xt(t,i)&&"body"!==Rt(t)})):[]}(t):[].concat(e),s=[].concat(n,[i]),o=s[0],r=s.reduce((function(e,i){var n=Oe(t,i);return e.top=ie(n.top,e.top),e.right=ne(n.right,e.right),e.bottom=ne(n.bottom,e.bottom),e.left=ie(n.left,e.left),e}),Oe(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}($t(b)?b:b.contextElement||Gt(t.elements.popper),r,l),y=Vt(t.elements.reference),w=Ce({reference:y,element:_,strategy:"absolute",placement:s}),E=Te(Object.assign({},_,w)),A=h===Ot?E:y,T={top:v.top-A.top+m.top,bottom:A.bottom-v.bottom+m.bottom,left:v.left-A.left+m.left,right:A.right-v.right+m.right},O=t.modifiersData.offset;if(h===Ot&&O){var C=O[s];Object.keys(T).forEach((function(t){var e=[_t,gt].indexOf(t)>=0?1:-1,i=[mt,gt].indexOf(t)>=0?"y":"x";T[t]+=C[i]*e}))}return T}function Le(t,e){void 0===e&&(e={});var i=e,n=i.placement,s=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?Lt:l,h=ce(n),d=h?a?kt:kt.filter((function(t){return ce(t)===h})):yt,u=d.filter((function(t){return c.indexOf(t)>=0}));0===u.length&&(u=d);var f=u.reduce((function(e,i){return e[i]=ke(t,{placement:i,boundary:s,rootBoundary:o,padding:r})[Ut(i)],e}),{});return Object.keys(f).sort((function(t,e){return f[t]-f[e]}))}const xe={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name;if(!e.modifiersData[n]._skip){for(var s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,h=i.boundary,d=i.rootBoundary,u=i.altBoundary,f=i.flipVariations,p=void 0===f||f,m=i.allowedAutoPlacements,g=e.options.placement,_=Ut(g),b=l||(_!==g&&p?function(t){if(Ut(t)===vt)return[];var e=ge(t);return[be(t),e,be(e)]}(g):[ge(g)]),v=[g].concat(b).reduce((function(t,i){return t.concat(Ut(i)===vt?Le(e,{placement:i,boundary:h,rootBoundary:d,padding:c,flipVariations:p,allowedAutoPlacements:m}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,A=!0,T=v[0],O=0;O=0,D=x?"width":"height",S=ke(e,{placement:C,boundary:h,rootBoundary:d,altBoundary:u,padding:c}),N=x?L?_t:bt:L?gt:mt;y[D]>w[D]&&(N=ge(N));var I=ge(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[I]<=0),P.every((function(t){return t}))){T=C,A=!1;break}E.set(C,P)}if(A)for(var j=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return T=e,"break"},M=p?3:1;M>0&&"break"!==j(M);M--);e.placement!==T&&(e.modifiersData[n]._skip=!0,e.placement=T,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function De(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Se(t){return[mt,_t,gt,bt].some((function(e){return t[e]>=0}))}const Ne={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,n=e.rects.reference,s=e.rects.popper,o=e.modifiersData.preventOverflow,r=ke(e,{elementContext:"reference"}),a=ke(e,{altBoundary:!0}),l=De(r,n),c=De(a,s,o),h=Se(l),d=Se(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:h,hasPopperEscaped:d},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":h,"data-popper-escaped":d})}},Ie={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.offset,o=void 0===s?[0,0]:s,r=Lt.reduce((function(t,i){return t[i]=function(t,e,i){var n=Ut(t),s=[bt,mt].indexOf(n)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*s,[bt,_t].indexOf(n)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[n]=r}},Pe={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=Ce({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},je={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,n=t.name,s=i.mainAxis,o=void 0===s||s,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,h=i.altBoundary,d=i.padding,u=i.tether,f=void 0===u||u,p=i.tetherOffset,m=void 0===p?0:p,g=ke(e,{boundary:l,rootBoundary:c,padding:d,altBoundary:h}),_=Ut(e.placement),b=ce(e.placement),v=!b,y=ee(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,A=e.rects.reference,T=e.rects.popper,O="function"==typeof m?m(Object.assign({},e.rects,{placement:e.placement})):m,C={x:0,y:0};if(E){if(o||a){var k="y"===y?mt:bt,L="y"===y?gt:_t,x="y"===y?"height":"width",D=E[y],S=E[y]+g[k],N=E[y]-g[L],I=f?-T[x]/2:0,P=b===wt?A[x]:T[x],j=b===wt?-T[x]:-A[x],M=e.elements.arrow,H=f&&M?Kt(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},R=B[k],W=B[L],$=oe(0,A[x],H[x]),z=v?A[x]/2-I-$-R-O:P-$-R-O,q=v?-A[x]/2+I+$+W+O:j+$+W+O,F=e.elements.arrow&&te(e.elements.arrow),U=F?"y"===y?F.clientTop||0:F.clientLeft||0:0,V=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,K=E[y]+z-V-U,X=E[y]+q-V;if(o){var Y=oe(f?ne(S,K):S,D,f?ie(N,X):N);E[y]=Y,C[y]=Y-D}if(a){var Q="x"===y?mt:bt,G="x"===y?gt:_t,Z=E[w],J=Z+g[Q],tt=Z-g[G],et=oe(f?ne(J,K):J,Z,f?ie(tt,X):tt);E[w]=et,C[w]=et-Z}}e.modifiersData[n]=C}},requiresIfExists:["offset"]};function Me(t,e,i){void 0===i&&(i=!1);var n=zt(e);zt(e)&&function(t){var e=t.getBoundingClientRect();e.width,t.offsetWidth,e.height,t.offsetHeight}(e);var s,o,r=Gt(e),a=Vt(t),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(n||!n&&!i)&&(("body"!==Rt(e)||we(r))&&(l=(s=e)!==Wt(s)&&zt(s)?{scrollLeft:(o=s).scrollLeft,scrollTop:o.scrollTop}:ve(s)),zt(e)?((c=Vt(e)).x+=e.clientLeft,c.y+=e.clientTop):r&&(c.x=ye(r))),{x:a.left+l.scrollLeft-c.x,y:a.top+l.scrollTop-c.y,width:a.width,height:a.height}}function He(t){var e=new Map,i=new Set,n=[];function s(t){i.add(t.name),[].concat(t.requires||[],t.requiresIfExists||[]).forEach((function(t){if(!i.has(t)){var n=e.get(t);n&&s(n)}})),n.push(t)}return t.forEach((function(t){e.set(t.name,t)})),t.forEach((function(t){i.has(t.name)||s(t)})),n}var Be={placement:"bottom",modifiers:[],strategy:"absolute"};function Re(){for(var t=arguments.length,e=new Array(t),i=0;ij.on(t,"mouseover",d))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(Je),this._element.classList.add(Je),j.trigger(this._element,"shown.bs.dropdown",t)}hide(){if(c(this._element)||!this._isShown(this._menu))return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){j.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._popper&&this._popper.destroy(),this._menu.classList.remove(Je),this._element.classList.remove(Je),this._element.setAttribute("aria-expanded","false"),U.removeDataAttribute(this._menu,"popper"),j.trigger(this._element,"hidden.bs.dropdown",t))}_getConfig(t){if(t={...this.constructor.Default,...U.getDataAttributes(this._element),...t},a(Ue,t,this.constructor.DefaultType),"object"==typeof t.reference&&!o(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${Ue.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(t){if(void 0===Fe)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let e=this._element;"parent"===this._config.reference?e=t:o(this._config.reference)?e=r(this._config.reference):"object"==typeof this._config.reference&&(e=this._config.reference);const i=this._getPopperConfig(),n=i.modifiers.find((t=>"applyStyles"===t.name&&!1===t.enabled));this._popper=qe(e,this._menu,i),n&&U.setDataAttribute(this._menu,"popper","static")}_isShown(t=this._element){return t.classList.contains(Je)}_getMenuElement(){return V.next(this._element,ei)[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ri;if(t.classList.contains("dropstart"))return ai;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?ni:ii:e?oi:si}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}_selectMenuItem({key:t,target:e}){const i=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter(l);i.length&&v(i,e,t===Ye,!i.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(t&&(2===t.button||"keyup"===t.type&&"Tab"!==t.key))return;const e=V.find(ti);for(let i=0,n=e.length;ie+t)),this._setElementAttributes(di,"paddingRight",(e=>e+t)),this._setElementAttributes(ui,"marginRight",(e=>e-t))}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,i){const n=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+n)return;this._saveInitialAttribute(t,e);const s=window.getComputedStyle(t)[e];t.style[e]=`${i(Number.parseFloat(s))}px`}))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,"paddingRight"),this._resetElementAttributes(di,"paddingRight"),this._resetElementAttributes(ui,"marginRight")}_saveInitialAttribute(t,e){const i=t.style[e];i&&U.setDataAttribute(t,e,i)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const i=U.getDataAttribute(t,e);void 0===i?t.style.removeProperty(e):(U.removeDataAttribute(t,e),t.style[e]=i)}))}_applyManipulationCallback(t,e){o(t)?e(t):V.find(t,this._element).forEach(e)}isOverflowing(){return this.getWidth()>0}}const pi={className:"modal-backdrop",isVisible:!0,isAnimated:!1,rootElement:"body",clickCallback:null},mi={className:"string",isVisible:"boolean",isAnimated:"boolean",rootElement:"(element|string)",clickCallback:"(function|null)"},gi="show",_i="mousedown.bs.backdrop";class bi{constructor(t){this._config=this._getConfig(t),this._isAppended=!1,this._element=null}show(t){this._config.isVisible?(this._append(),this._config.isAnimated&&u(this._getElement()),this._getElement().classList.add(gi),this._emulateAnimation((()=>{_(t)}))):_(t)}hide(t){this._config.isVisible?(this._getElement().classList.remove(gi),this._emulateAnimation((()=>{this.dispose(),_(t)}))):_(t)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_getConfig(t){return(t={...pi,..."object"==typeof t?t:{}}).rootElement=r(t.rootElement),a("backdrop",t,mi),t}_append(){this._isAppended||(this._config.rootElement.append(this._getElement()),j.on(this._getElement(),_i,(()=>{_(this._config.clickCallback)})),this._isAppended=!0)}dispose(){this._isAppended&&(j.off(this._element,_i),this._element.remove(),this._isAppended=!1)}_emulateAnimation(t){b(t,this._getElement(),this._config.isAnimated)}}const vi={trapElement:null,autofocus:!0},yi={trapElement:"element",autofocus:"boolean"},wi=".bs.focustrap",Ei="backward";class Ai{constructor(t){this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}activate(){const{trapElement:t,autofocus:e}=this._config;this._isActive||(e&&t.focus(),j.off(document,wi),j.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),j.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,j.off(document,wi))}_handleFocusin(t){const{target:e}=t,{trapElement:i}=this._config;if(e===document||e===i||i.contains(e))return;const n=V.focusableChildren(i);0===n.length?i.focus():this._lastTabNavDirection===Ei?n[n.length-1].focus():n[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Ei:"forward")}_getConfig(t){return t={...vi,..."object"==typeof t?t:{}},a("focustrap",t,yi),t}}const Ti="modal",Oi="Escape",Ci={backdrop:!0,keyboard:!0,focus:!0},ki={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean"},Li="hidden.bs.modal",xi="show.bs.modal",Di="resize.bs.modal",Si="click.dismiss.bs.modal",Ni="keydown.dismiss.bs.modal",Ii="mousedown.dismiss.bs.modal",Pi="modal-open",ji="show",Mi="modal-static";class Hi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollBar=new fi}static get Default(){return Ci}static get NAME(){return Ti}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||j.trigger(this._element,xi,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isAnimated()&&(this._isTransitioning=!0),this._scrollBar.hide(),document.body.classList.add(Pi),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),j.on(this._dialog,Ii,(()=>{j.one(this._element,"mouseup.dismiss.bs.modal",(t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)}))})),this._showBackdrop((()=>this._showElement(t))))}hide(){if(!this._isShown||this._isTransitioning)return;if(j.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const t=this._isAnimated();t&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),this._focustrap.deactivate(),this._element.classList.remove(ji),j.off(this._element,Si),j.off(this._dialog,Ii),this._queueCallback((()=>this._hideModal()),this._element,t)}dispose(){[window,this._dialog].forEach((t=>j.off(t,".bs.modal"))),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new bi({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_getConfig(t){return t={...Ci,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Ti,t,ki),t}_showElement(t){const e=this._isAnimated(),i=V.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add(ji),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,j.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,e)}_setEscapeEvent(){this._isShown?j.on(this._element,Ni,(t=>{this._config.keyboard&&t.key===Oi?(t.preventDefault(),this.hide()):this._config.keyboard||t.key!==Oi||this._triggerBackdropTransition()})):j.off(this._element,Ni)}_setResizeEvent(){this._isShown?j.on(window,Di,(()=>this._adjustDialog())):j.off(window,Di)}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Pi),this._resetAdjustments(),this._scrollBar.reset(),j.trigger(this._element,Li)}))}_showBackdrop(t){j.on(this._element,Si,(t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&(!0===this._config.backdrop?this.hide():"static"===this._config.backdrop&&this._triggerBackdropTransition())})),this._backdrop.show(t)}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(j.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const{classList:t,scrollHeight:e,style:i}=this._element,n=e>document.documentElement.clientHeight;!n&&"hidden"===i.overflowY||t.contains(Mi)||(n||(i.overflowY="hidden"),t.add(Mi),this._queueCallback((()=>{t.remove(Mi),n||this._queueCallback((()=>{i.overflowY=""}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),i=e>0;(!i&&t&&!m()||i&&!t&&m())&&(this._element.style.paddingLeft=`${e}px`),(i&&!t&&!m()||!i&&t&&m())&&(this._element.style.paddingRight=`${e}px`)}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const i=Hi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}j.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=n(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),j.one(e,xi,(t=>{t.defaultPrevented||j.one(e,Li,(()=>{l(this)&&this.focus()}))}));const i=V.findOne(".modal.show");i&&Hi.getInstance(i).hide(),Hi.getOrCreateInstance(e).toggle(this)})),R(Hi),g(Hi);const Bi="offcanvas",Ri={backdrop:!0,keyboard:!0,scroll:!1},Wi={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"},$i="show",zi=".offcanvas.show",qi="hidden.bs.offcanvas";class Fi extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get NAME(){return Bi}static get Default(){return Ri}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||j.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._backdrop.show(),this._config.scroll||(new fi).hide(),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add($i),this._queueCallback((()=>{this._config.scroll||this._focustrap.activate(),j.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(j.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.remove($i),this._backdrop.hide(),this._queueCallback((()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.scroll||(new fi).reset(),j.trigger(this._element,qi)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_getConfig(t){return t={...Ri,...U.getDataAttributes(this._element),..."object"==typeof t?t:{}},a(Bi,t,Wi),t}_initializeBackDrop(){return new bi({className:"offcanvas-backdrop",isVisible:this._config.backdrop,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:()=>this.hide()})}_initializeFocusTrap(){return new Ai({trapElement:this._element})}_addEventListeners(){j.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}))}static jQueryInterface(t){return this.each((function(){const e=Fi.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}j.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=n(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this))return;j.one(e,qi,(()=>{l(this)&&this.focus()}));const i=V.findOne(zi);i&&i!==e&&Fi.getInstance(i).hide(),Fi.getOrCreateInstance(e).toggle(this)})),j.on(window,"load.bs.offcanvas.data-api",(()=>V.find(zi).forEach((t=>Fi.getOrCreateInstance(t).show())))),R(Fi),g(Fi);const Ui=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),Vi=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,Ki=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Xi=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!Ui.has(i)||Boolean(Vi.test(t.nodeValue)||Ki.test(t.nodeValue));const n=e.filter((t=>t instanceof RegExp));for(let t=0,e=n.length;t{Xi(t,r)||i.removeAttribute(t.nodeName)}))}return n.body.innerHTML}const Qi="tooltip",Gi=new Set(["sanitize","allowList","sanitizeFn"]),Zi={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ji={AUTO:"auto",TOP:"top",RIGHT:m()?"left":"right",BOTTOM:"bottom",LEFT:m()?"right":"left"},tn={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},en={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},nn="fade",sn="show",on="show",rn="out",an=".tooltip-inner",ln=".modal",cn="hide.bs.modal",hn="hover",dn="focus";class un extends B{constructor(t,e){if(void 0===Fe)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this._config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return tn}static get NAME(){return Qi}static get Event(){return en}static get DefaultType(){return Zi}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains(sn))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),j.off(this._element.closest(ln),cn,this._hideModalHandler),this.tip&&this.tip.remove(),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const t=j.trigger(this._element,this.constructor.Event.SHOW),e=h(this._element),i=null===e?this._element.ownerDocument.documentElement.contains(this._element):e.contains(this._element);if(t.defaultPrevented||!i)return;"tooltip"===this.constructor.NAME&&this.tip&&this.getTitle()!==this.tip.querySelector(an).innerHTML&&(this._disposePopper(),this.tip.remove(),this.tip=null);const n=this.getTipElement(),s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME);n.setAttribute("id",s),this._element.setAttribute("aria-describedby",s),this._config.animation&&n.classList.add(nn);const o="function"==typeof this._config.placement?this._config.placement.call(this,n,this._element):this._config.placement,r=this._getAttachment(o);this._addAttachmentClass(r);const{container:a}=this._config;H.set(n,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(a.append(n),j.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=qe(this._element,n,this._getPopperConfig(r)),n.classList.add(sn);const l=this._resolvePossibleFunction(this._config.customClass);l&&n.classList.add(...l.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>{j.on(t,"mouseover",d)}));const c=this.tip.classList.contains(nn);this._queueCallback((()=>{const t=this._hoverState;this._hoverState=null,j.trigger(this._element,this.constructor.Event.SHOWN),t===rn&&this._leave(null,this)}),this.tip,c)}hide(){if(!this._popper)return;const t=this.getTipElement();if(j.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented)return;t.classList.remove(sn),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach((t=>j.off(t,"mouseover",d))),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1;const e=this.tip.classList.contains(nn);this._queueCallback((()=>{this._isWithActiveTrigger()||(this._hoverState!==on&&t.remove(),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),j.trigger(this._element,this.constructor.Event.HIDDEN),this._disposePopper())}),this.tip,e),this._hoverState=""}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");t.innerHTML=this._config.template;const e=t.children[0];return this.setContent(e),e.classList.remove(nn,sn),this.tip=e,this.tip}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),an)}_sanitizeAndSetContent(t,e,i){const n=V.findOne(i,t);e||!n?this.setElementContent(n,e):n.remove()}setElementContent(t,e){if(null!==t)return o(e)?(e=r(e),void(this._config.html?e.parentNode!==t&&(t.innerHTML="",t.append(e)):t.textContent=e.textContent)):void(this._config.html?(this._config.sanitize&&(e=Yi(e,this._config.allowList,this._config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){const t=this._element.getAttribute("data-bs-original-title")||this._config.title;return this._resolvePossibleFunction(t)}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){return e||this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return"function"==typeof t?t.call(this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this._config.popperConfig?this._config.popperConfig(e):this._config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add(`${this._getBasicClassPrefix()}-${this.updateAttachment(t)}`)}_getAttachment(t){return Ji[t.toUpperCase()]}_setListeners(){this._config.trigger.split(" ").forEach((t=>{if("click"===t)j.on(this._element,this.constructor.Event.CLICK,this._config.selector,(t=>this.toggle(t)));else if("manual"!==t){const e=t===hn?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i=t===hn?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;j.on(this._element,e,this._config.selector,(t=>this._enter(t))),j.on(this._element,i,this._config.selector,(t=>this._leave(t)))}})),this._hideModalHandler=()=>{this._element&&this.hide()},j.on(this._element.closest(ln),cn,this._hideModalHandler),this._config.selector?this._config={...this._config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?dn:hn]=!0),e.getTipElement().classList.contains(sn)||e._hoverState===on?e._hoverState=on:(clearTimeout(e._timeout),e._hoverState=on,e._config.delay&&e._config.delay.show?e._timeout=setTimeout((()=>{e._hoverState===on&&e.show()}),e._config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?dn:hn]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=rn,e._config.delay&&e._config.delay.hide?e._timeout=setTimeout((()=>{e._hoverState===rn&&e.hide()}),e._config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=U.getDataAttributes(this._element);return Object.keys(e).forEach((t=>{Gi.has(t)&&delete e[t]})),(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).container=!1===t.container?document.body:r(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a(Qi,t,this.constructor.DefaultType),t.sanitize&&(t.template=Yi(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};for(const e in this._config)this.constructor.Default[e]!==this._config[e]&&(t[e]=this._config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=new RegExp(`(^|\\s)${this._getBasicClassPrefix()}\\S+`,"g"),i=t.getAttribute("class").match(e);null!==i&&i.length>0&&i.map((t=>t.trim())).forEach((e=>t.classList.remove(e)))}_getBasicClassPrefix(){return"bs-tooltip"}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null)}static jQueryInterface(t){return this.each((function(){const e=un.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(un);const fn={...un.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},pn={...un.DefaultType,content:"(string|element|function)"},mn={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class gn extends un{static get Default(){return fn}static get NAME(){return"popover"}static get Event(){return mn}static get DefaultType(){return pn}isWithContent(){return this.getTitle()||this._getContent()}setContent(t){this._sanitizeAndSetContent(t,this.getTitle(),".popover-header"),this._sanitizeAndSetContent(t,this._getContent(),".popover-body")}_getContent(){return this._resolvePossibleFunction(this._config.content)}_getBasicClassPrefix(){return"bs-popover"}static jQueryInterface(t){return this.each((function(){const e=gn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}g(gn);const _n="scrollspy",bn={offset:10,method:"auto",target:""},vn={offset:"number",method:"string",target:"(string|element)"},yn="active",wn=".nav-link, .list-group-item, .dropdown-item",En="position";class An extends B{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,j.on(this._scrollElement,"scroll.bs.scrollspy",(()=>this._process())),this.refresh(),this._process()}static get Default(){return bn}static get NAME(){return _n}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":En,e="auto"===this._config.method?t:this._config.method,n=e===En?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),V.find(wn,this._config.target).map((t=>{const s=i(t),o=s?V.findOne(s):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[U[e](o).top+n,s]}return null})).filter((t=>t)).sort(((t,e)=>t[0]-e[0])).forEach((t=>{this._offsets.push(t[0]),this._targets.push(t[1])}))}dispose(){j.off(this._scrollElement,".bs.scrollspy"),super.dispose()}_getConfig(t){return(t={...bn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}}).target=r(t.target)||document.documentElement,a(_n,t,vn),t}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`)),i=V.findOne(e.join(","),this._config.target);i.classList.add(yn),i.classList.contains("dropdown-item")?V.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add(yn):V.parents(i,".nav, .list-group").forEach((t=>{V.prev(t,".nav-link, .list-group-item").forEach((t=>t.classList.add(yn))),V.prev(t,".nav-item").forEach((t=>{V.children(t,".nav-link").forEach((t=>t.classList.add(yn)))}))})),j.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){V.find(wn,this._config.target).filter((t=>t.classList.contains(yn))).forEach((t=>t.classList.remove(yn)))}static jQueryInterface(t){return this.each((function(){const e=An.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(window,"load.bs.scrollspy.data-api",(()=>{V.find('[data-bs-spy="scroll"]').forEach((t=>new An(t)))})),g(An);const Tn="active",On="fade",Cn="show",kn=".active",Ln=":scope > li > .active";class xn extends B{static get NAME(){return"tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains(Tn))return;let t;const e=n(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?Ln:kn;t=V.find(e,i),t=t[t.length-1]}const s=t?j.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(j.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==s&&s.defaultPrevented)return;this._activate(this._element,i);const o=()=>{j.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),j.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const n=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?V.children(e,kn):V.find(Ln,e))[0],s=i&&n&&n.classList.contains(On),o=()=>this._transitionComplete(t,n,i);n&&s?(n.classList.remove(Cn),this._queueCallback(o,t,!0)):o()}_transitionComplete(t,e,i){if(e){e.classList.remove(Tn);const t=V.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove(Tn),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add(Tn),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains(On)&&t.classList.add(Cn);let n=t.parentNode;if(n&&"LI"===n.nodeName&&(n=n.parentNode),n&&n.classList.contains("dropdown-menu")){const e=t.closest(".dropdown");e&&V.find(".dropdown-toggle",e).forEach((t=>t.classList.add(Tn))),t.setAttribute("aria-expanded",!0)}i&&i()}static jQueryInterface(t){return this.each((function(){const e=xn.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}j.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),c(this)||xn.getOrCreateInstance(this).show()})),g(xn);const Dn="toast",Sn="hide",Nn="show",In="showing",Pn={animation:"boolean",autohide:"boolean",delay:"number"},jn={animation:!0,autohide:!0,delay:5e3};class Mn extends B{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get DefaultType(){return Pn}static get Default(){return jn}static get NAME(){return Dn}show(){j.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Sn),u(this._element),this._element.classList.add(Nn),this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.remove(In),j.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this._element.classList.contains(Nn)&&(j.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(In),this._queueCallback((()=>{this._element.classList.add(Sn),this._element.classList.remove(In),this._element.classList.remove(Nn),j.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this._element.classList.contains(Nn)&&this._element.classList.remove(Nn),super.dispose()}_getConfig(t){return t={...jn,...U.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},a(Dn,t,this.constructor.DefaultType),t}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const i=t.relatedTarget;this._element===i||this._element.contains(i)||this._maybeScheduleHide()}_setListeners(){j.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),j.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),j.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=Mn.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return R(Mn),g(Mn),{Alert:W,Button:z,Carousel:st,Collapse:pt,Dropdown:hi,Modal:Hi,Offcanvas:Fi,Popover:gn,ScrollSpy:An,Tab:xn,Toast:Mn,Tooltip:un}})); +//# sourceMappingURL=bootstrap.bundle.min.js.map \ No newline at end of file diff --git a/_proc/_docs/site_libs/clipboard/clipboard.min.js b/_proc/_docs/site_libs/clipboard/clipboard.min.js new file mode 100644 index 0000000000000000000000000000000000000000..1103f811ed80f17985ecf61e0d50e3359484244f --- /dev/null +++ b/_proc/_docs/site_libs/clipboard/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return b}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),r=n.n(e);function c(t){try{return document.execCommand(t)}catch(t){return}}var a=function(t){t=r()(t);return c("cut"),t};function o(t,e){var n,o,t=(n=t,o="rtl"===document.documentElement.getAttribute("dir"),(t=document.createElement("textarea")).style.fontSize="12pt",t.style.border="0",t.style.padding="0",t.style.margin="0",t.style.position="absolute",t.style[o?"right":"left"]="-9999px",o=window.pageYOffset||document.documentElement.scrollTop,t.style.top="".concat(o,"px"),t.setAttribute("readonly",""),t.value=n,t);return e.container.appendChild(t),e=r()(t),c("copy"),t.remove(),e}var f=function(t){var e=1.anchorjs-link,.anchorjs-link:focus{opacity:1}",u.sheet.cssRules.length),u.sheet.insertRule("[data-anchorjs-icon]::after{content:attr(data-anchorjs-icon)}",u.sheet.cssRules.length),u.sheet.insertRule('@font-face{font-family:anchorjs-icons;src:url(data:n/a;base64,AAEAAAALAIAAAwAwT1MvMg8yG2cAAAE4AAAAYGNtYXDp3gC3AAABpAAAAExnYXNwAAAAEAAAA9wAAAAIZ2x5ZlQCcfwAAAH4AAABCGhlYWQHFvHyAAAAvAAAADZoaGVhBnACFwAAAPQAAAAkaG10eASAADEAAAGYAAAADGxvY2EACACEAAAB8AAAAAhtYXhwAAYAVwAAARgAAAAgbmFtZQGOH9cAAAMAAAAAunBvc3QAAwAAAAADvAAAACAAAQAAAAEAAHzE2p9fDzz1AAkEAAAAAADRecUWAAAAANQA6R8AAAAAAoACwAAAAAgAAgAAAAAAAAABAAADwP/AAAACgAAA/9MCrQABAAAAAAAAAAAAAAAAAAAAAwABAAAAAwBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAMCQAGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAg//0DwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAAIAAAACgAAxAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEADAAAAAIAAgAAgAAACDpy//9//8AAAAg6cv//f///+EWNwADAAEAAAAAAAAAAAAAAAAACACEAAEAAAAAAAAAAAAAAAAxAAACAAQARAKAAsAAKwBUAAABIiYnJjQ3NzY2MzIWFxYUBwcGIicmNDc3NjQnJiYjIgYHBwYUFxYUBwYGIwciJicmNDc3NjIXFhQHBwYUFxYWMzI2Nzc2NCcmNDc2MhcWFAcHBgYjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAAADACWAAEAAAAAAAEACAAAAAEAAAAAAAIAAwAIAAEAAAAAAAMACAAAAAEAAAAAAAQACAAAAAEAAAAAAAUAAQALAAEAAAAAAAYACAAAAAMAAQQJAAEAEAAMAAMAAQQJAAIABgAcAAMAAQQJAAMAEAAMAAMAAQQJAAQAEAAMAAMAAQQJAAUAAgAiAAMAAQQJAAYAEAAMYW5jaG9yanM0MDBAAGEAbgBjAGgAbwByAGoAcwA0ADAAMABAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAP) format("truetype")}',u.sheet.cssRules.length)),u=document.querySelectorAll("[id]"),t=[].map.call(u,function(A){return A.id}),i=0;i\]./()*\\\n\t\b\v\u00A0]/g,"-").replace(/-{2,}/g,"-").substring(0,this.options.truncate).replace(/^-+|-+$/gm,"").toLowerCase()},this.hasAnchorJSLink=function(A){var e=A.firstChild&&-1<(" "+A.firstChild.className+" ").indexOf(" anchorjs-link "),A=A.lastChild&&-1<(" "+A.lastChild.className+" ").indexOf(" anchorjs-link ");return e||A||!1}}}); +// @license-end \ No newline at end of file diff --git a/_proc/_docs/site_libs/quarto-html/popper.min.js b/_proc/_docs/site_libs/quarto-html/popper.min.js new file mode 100644 index 0000000000000000000000000000000000000000..2269d66967635e9bde6edb948cd93b0ae1978dfc --- /dev/null +++ b/_proc/_docs/site_libs/quarto-html/popper.min.js @@ -0,0 +1,6 @@ +/** + * @popperjs/core v2.11.4 - MIT License + */ + +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Popper={})}(this,(function(e){"use strict";function t(e){if(null==e)return window;if("[object Window]"!==e.toString()){var t=e.ownerDocument;return t&&t.defaultView||window}return e}function n(e){return e instanceof t(e).Element||e instanceof Element}function r(e){return e instanceof t(e).HTMLElement||e instanceof HTMLElement}function o(e){return"undefined"!=typeof ShadowRoot&&(e instanceof t(e).ShadowRoot||e instanceof ShadowRoot)}var i=Math.max,a=Math.min,s=Math.round;function f(e,t){void 0===t&&(t=!1);var n=e.getBoundingClientRect(),o=1,i=1;if(r(e)&&t){var a=e.offsetHeight,f=e.offsetWidth;f>0&&(o=s(n.width)/f||1),a>0&&(i=s(n.height)/a||1)}return{width:n.width/o,height:n.height/i,top:n.top/i,right:n.right/o,bottom:n.bottom/i,left:n.left/o,x:n.left/o,y:n.top/i}}function c(e){var n=t(e);return{scrollLeft:n.pageXOffset,scrollTop:n.pageYOffset}}function p(e){return e?(e.nodeName||"").toLowerCase():null}function u(e){return((n(e)?e.ownerDocument:e.document)||window.document).documentElement}function l(e){return f(u(e)).left+c(e).scrollLeft}function d(e){return t(e).getComputedStyle(e)}function h(e){var t=d(e),n=t.overflow,r=t.overflowX,o=t.overflowY;return/auto|scroll|overlay|hidden/.test(n+o+r)}function m(e,n,o){void 0===o&&(o=!1);var i,a,d=r(n),m=r(n)&&function(e){var t=e.getBoundingClientRect(),n=s(t.width)/e.offsetWidth||1,r=s(t.height)/e.offsetHeight||1;return 1!==n||1!==r}(n),v=u(n),g=f(e,m),y={scrollLeft:0,scrollTop:0},b={x:0,y:0};return(d||!d&&!o)&&(("body"!==p(n)||h(v))&&(y=(i=n)!==t(i)&&r(i)?{scrollLeft:(a=i).scrollLeft,scrollTop:a.scrollTop}:c(i)),r(n)?((b=f(n,!0)).x+=n.clientLeft,b.y+=n.clientTop):v&&(b.x=l(v))),{x:g.left+y.scrollLeft-b.x,y:g.top+y.scrollTop-b.y,width:g.width,height:g.height}}function v(e){var t=f(e),n=e.offsetWidth,r=e.offsetHeight;return Math.abs(t.width-n)<=1&&(n=t.width),Math.abs(t.height-r)<=1&&(r=t.height),{x:e.offsetLeft,y:e.offsetTop,width:n,height:r}}function g(e){return"html"===p(e)?e:e.assignedSlot||e.parentNode||(o(e)?e.host:null)||u(e)}function y(e){return["html","body","#document"].indexOf(p(e))>=0?e.ownerDocument.body:r(e)&&h(e)?e:y(g(e))}function b(e,n){var r;void 0===n&&(n=[]);var o=y(e),i=o===(null==(r=e.ownerDocument)?void 0:r.body),a=t(o),s=i?[a].concat(a.visualViewport||[],h(o)?o:[]):o,f=n.concat(s);return i?f:f.concat(b(g(s)))}function x(e){return["table","td","th"].indexOf(p(e))>=0}function w(e){return r(e)&&"fixed"!==d(e).position?e.offsetParent:null}function O(e){for(var n=t(e),i=w(e);i&&x(i)&&"static"===d(i).position;)i=w(i);return i&&("html"===p(i)||"body"===p(i)&&"static"===d(i).position)?n:i||function(e){var t=-1!==navigator.userAgent.toLowerCase().indexOf("firefox");if(-1!==navigator.userAgent.indexOf("Trident")&&r(e)&&"fixed"===d(e).position)return null;var n=g(e);for(o(n)&&(n=n.host);r(n)&&["html","body"].indexOf(p(n))<0;){var i=d(n);if("none"!==i.transform||"none"!==i.perspective||"paint"===i.contain||-1!==["transform","perspective"].indexOf(i.willChange)||t&&"filter"===i.willChange||t&&i.filter&&"none"!==i.filter)return n;n=n.parentNode}return null}(e)||n}var j="top",E="bottom",D="right",A="left",L="auto",P=[j,E,D,A],M="start",k="end",W="viewport",B="popper",H=P.reduce((function(e,t){return e.concat([t+"-"+M,t+"-"+k])}),[]),T=[].concat(P,[L]).reduce((function(e,t){return e.concat([t,t+"-"+M,t+"-"+k])}),[]),R=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function S(e){var t=new Map,n=new Set,r=[];function o(e){n.add(e.name),[].concat(e.requires||[],e.requiresIfExists||[]).forEach((function(e){if(!n.has(e)){var r=t.get(e);r&&o(r)}})),r.push(e)}return e.forEach((function(e){t.set(e.name,e)})),e.forEach((function(e){n.has(e.name)||o(e)})),r}function C(e){return e.split("-")[0]}function q(e,t){var n=t.getRootNode&&t.getRootNode();if(e.contains(t))return!0;if(n&&o(n)){var r=t;do{if(r&&e.isSameNode(r))return!0;r=r.parentNode||r.host}while(r)}return!1}function V(e){return Object.assign({},e,{left:e.x,top:e.y,right:e.x+e.width,bottom:e.y+e.height})}function N(e,r){return r===W?V(function(e){var n=t(e),r=u(e),o=n.visualViewport,i=r.clientWidth,a=r.clientHeight,s=0,f=0;return o&&(i=o.width,a=o.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(s=o.offsetLeft,f=o.offsetTop)),{width:i,height:a,x:s+l(e),y:f}}(e)):n(r)?function(e){var t=f(e);return t.top=t.top+e.clientTop,t.left=t.left+e.clientLeft,t.bottom=t.top+e.clientHeight,t.right=t.left+e.clientWidth,t.width=e.clientWidth,t.height=e.clientHeight,t.x=t.left,t.y=t.top,t}(r):V(function(e){var t,n=u(e),r=c(e),o=null==(t=e.ownerDocument)?void 0:t.body,a=i(n.scrollWidth,n.clientWidth,o?o.scrollWidth:0,o?o.clientWidth:0),s=i(n.scrollHeight,n.clientHeight,o?o.scrollHeight:0,o?o.clientHeight:0),f=-r.scrollLeft+l(e),p=-r.scrollTop;return"rtl"===d(o||n).direction&&(f+=i(n.clientWidth,o?o.clientWidth:0)-a),{width:a,height:s,x:f,y:p}}(u(e)))}function I(e,t,o){var s="clippingParents"===t?function(e){var t=b(g(e)),o=["absolute","fixed"].indexOf(d(e).position)>=0&&r(e)?O(e):e;return n(o)?t.filter((function(e){return n(e)&&q(e,o)&&"body"!==p(e)})):[]}(e):[].concat(t),f=[].concat(s,[o]),c=f[0],u=f.reduce((function(t,n){var r=N(e,n);return t.top=i(r.top,t.top),t.right=a(r.right,t.right),t.bottom=a(r.bottom,t.bottom),t.left=i(r.left,t.left),t}),N(e,c));return u.width=u.right-u.left,u.height=u.bottom-u.top,u.x=u.left,u.y=u.top,u}function _(e){return e.split("-")[1]}function F(e){return["top","bottom"].indexOf(e)>=0?"x":"y"}function U(e){var t,n=e.reference,r=e.element,o=e.placement,i=o?C(o):null,a=o?_(o):null,s=n.x+n.width/2-r.width/2,f=n.y+n.height/2-r.height/2;switch(i){case j:t={x:s,y:n.y-r.height};break;case E:t={x:s,y:n.y+n.height};break;case D:t={x:n.x+n.width,y:f};break;case A:t={x:n.x-r.width,y:f};break;default:t={x:n.x,y:n.y}}var c=i?F(i):null;if(null!=c){var p="y"===c?"height":"width";switch(a){case M:t[c]=t[c]-(n[p]/2-r[p]/2);break;case k:t[c]=t[c]+(n[p]/2-r[p]/2)}}return t}function z(e){return Object.assign({},{top:0,right:0,bottom:0,left:0},e)}function X(e,t){return t.reduce((function(t,n){return t[n]=e,t}),{})}function Y(e,t){void 0===t&&(t={});var r=t,o=r.placement,i=void 0===o?e.placement:o,a=r.boundary,s=void 0===a?"clippingParents":a,c=r.rootBoundary,p=void 0===c?W:c,l=r.elementContext,d=void 0===l?B:l,h=r.altBoundary,m=void 0!==h&&h,v=r.padding,g=void 0===v?0:v,y=z("number"!=typeof g?g:X(g,P)),b=d===B?"reference":B,x=e.rects.popper,w=e.elements[m?b:d],O=I(n(w)?w:w.contextElement||u(e.elements.popper),s,p),A=f(e.elements.reference),L=U({reference:A,element:x,strategy:"absolute",placement:i}),M=V(Object.assign({},x,L)),k=d===B?M:A,H={top:O.top-k.top+y.top,bottom:k.bottom-O.bottom+y.bottom,left:O.left-k.left+y.left,right:k.right-O.right+y.right},T=e.modifiersData.offset;if(d===B&&T){var R=T[i];Object.keys(H).forEach((function(e){var t=[D,E].indexOf(e)>=0?1:-1,n=[j,E].indexOf(e)>=0?"y":"x";H[e]+=R[n]*t}))}return H}var G={placement:"bottom",modifiers:[],strategy:"absolute"};function J(){for(var e=arguments.length,t=new Array(e),n=0;n=0?-1:1,i="function"==typeof n?n(Object.assign({},t,{placement:e})):n,a=i[0],s=i[1];return a=a||0,s=(s||0)*o,[A,D].indexOf(r)>=0?{x:s,y:a}:{x:a,y:s}}(n,t.rects,i),e}),{}),s=a[t.placement],f=s.x,c=s.y;null!=t.modifiersData.popperOffsets&&(t.modifiersData.popperOffsets.x+=f,t.modifiersData.popperOffsets.y+=c),t.modifiersData[r]=a}},ie={left:"right",right:"left",bottom:"top",top:"bottom"};function ae(e){return e.replace(/left|right|bottom|top/g,(function(e){return ie[e]}))}var se={start:"end",end:"start"};function fe(e){return e.replace(/start|end/g,(function(e){return se[e]}))}function ce(e,t){void 0===t&&(t={});var n=t,r=n.placement,o=n.boundary,i=n.rootBoundary,a=n.padding,s=n.flipVariations,f=n.allowedAutoPlacements,c=void 0===f?T:f,p=_(r),u=p?s?H:H.filter((function(e){return _(e)===p})):P,l=u.filter((function(e){return c.indexOf(e)>=0}));0===l.length&&(l=u);var d=l.reduce((function(t,n){return t[n]=Y(e,{placement:n,boundary:o,rootBoundary:i,padding:a})[C(n)],t}),{});return Object.keys(d).sort((function(e,t){return d[e]-d[t]}))}var pe={name:"flip",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name;if(!t.modifiersData[r]._skip){for(var o=n.mainAxis,i=void 0===o||o,a=n.altAxis,s=void 0===a||a,f=n.fallbackPlacements,c=n.padding,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.flipVariations,h=void 0===d||d,m=n.allowedAutoPlacements,v=t.options.placement,g=C(v),y=f||(g===v||!h?[ae(v)]:function(e){if(C(e)===L)return[];var t=ae(e);return[fe(e),t,fe(t)]}(v)),b=[v].concat(y).reduce((function(e,n){return e.concat(C(n)===L?ce(t,{placement:n,boundary:p,rootBoundary:u,padding:c,flipVariations:h,allowedAutoPlacements:m}):n)}),[]),x=t.rects.reference,w=t.rects.popper,O=new Map,P=!0,k=b[0],W=0;W=0,S=R?"width":"height",q=Y(t,{placement:B,boundary:p,rootBoundary:u,altBoundary:l,padding:c}),V=R?T?D:A:T?E:j;x[S]>w[S]&&(V=ae(V));var N=ae(V),I=[];if(i&&I.push(q[H]<=0),s&&I.push(q[V]<=0,q[N]<=0),I.every((function(e){return e}))){k=B,P=!1;break}O.set(B,I)}if(P)for(var F=function(e){var t=b.find((function(t){var n=O.get(t);if(n)return n.slice(0,e).every((function(e){return e}))}));if(t)return k=t,"break"},U=h?3:1;U>0;U--){if("break"===F(U))break}t.placement!==k&&(t.modifiersData[r]._skip=!0,t.placement=k,t.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function ue(e,t,n){return i(e,a(t,n))}var le={name:"preventOverflow",enabled:!0,phase:"main",fn:function(e){var t=e.state,n=e.options,r=e.name,o=n.mainAxis,s=void 0===o||o,f=n.altAxis,c=void 0!==f&&f,p=n.boundary,u=n.rootBoundary,l=n.altBoundary,d=n.padding,h=n.tether,m=void 0===h||h,g=n.tetherOffset,y=void 0===g?0:g,b=Y(t,{boundary:p,rootBoundary:u,padding:d,altBoundary:l}),x=C(t.placement),w=_(t.placement),L=!w,P=F(x),k="x"===P?"y":"x",W=t.modifiersData.popperOffsets,B=t.rects.reference,H=t.rects.popper,T="function"==typeof y?y(Object.assign({},t.rects,{placement:t.placement})):y,R="number"==typeof T?{mainAxis:T,altAxis:T}:Object.assign({mainAxis:0,altAxis:0},T),S=t.modifiersData.offset?t.modifiersData.offset[t.placement]:null,q={x:0,y:0};if(W){if(s){var V,N="y"===P?j:A,I="y"===P?E:D,U="y"===P?"height":"width",z=W[P],X=z+b[N],G=z-b[I],J=m?-H[U]/2:0,K=w===M?B[U]:H[U],Q=w===M?-H[U]:-B[U],Z=t.elements.arrow,$=m&&Z?v(Z):{width:0,height:0},ee=t.modifiersData["arrow#persistent"]?t.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},te=ee[N],ne=ee[I],re=ue(0,B[U],$[U]),oe=L?B[U]/2-J-re-te-R.mainAxis:K-re-te-R.mainAxis,ie=L?-B[U]/2+J+re+ne+R.mainAxis:Q+re+ne+R.mainAxis,ae=t.elements.arrow&&O(t.elements.arrow),se=ae?"y"===P?ae.clientTop||0:ae.clientLeft||0:0,fe=null!=(V=null==S?void 0:S[P])?V:0,ce=z+ie-fe,pe=ue(m?a(X,z+oe-fe-se):X,z,m?i(G,ce):G);W[P]=pe,q[P]=pe-z}if(c){var le,de="x"===P?j:A,he="x"===P?E:D,me=W[k],ve="y"===k?"height":"width",ge=me+b[de],ye=me-b[he],be=-1!==[j,A].indexOf(x),xe=null!=(le=null==S?void 0:S[k])?le:0,we=be?ge:me-B[ve]-H[ve]-xe+R.altAxis,Oe=be?me+B[ve]+H[ve]-xe-R.altAxis:ye,je=m&&be?function(e,t,n){var r=ue(e,t,n);return r>n?n:r}(we,me,Oe):ue(m?we:ge,me,m?Oe:ye);W[k]=je,q[k]=je-me}t.modifiersData[r]=q}},requiresIfExists:["offset"]};var de={name:"arrow",enabled:!0,phase:"main",fn:function(e){var t,n=e.state,r=e.name,o=e.options,i=n.elements.arrow,a=n.modifiersData.popperOffsets,s=C(n.placement),f=F(s),c=[A,D].indexOf(s)>=0?"height":"width";if(i&&a){var p=function(e,t){return z("number"!=typeof(e="function"==typeof e?e(Object.assign({},t.rects,{placement:t.placement})):e)?e:X(e,P))}(o.padding,n),u=v(i),l="y"===f?j:A,d="y"===f?E:D,h=n.rects.reference[c]+n.rects.reference[f]-a[f]-n.rects.popper[c],m=a[f]-n.rects.reference[f],g=O(i),y=g?"y"===f?g.clientHeight||0:g.clientWidth||0:0,b=h/2-m/2,x=p[l],w=y-u[c]-p[d],L=y/2-u[c]/2+b,M=ue(x,L,w),k=f;n.modifiersData[r]=((t={})[k]=M,t.centerOffset=M-L,t)}},effect:function(e){var t=e.state,n=e.options.element,r=void 0===n?"[data-popper-arrow]":n;null!=r&&("string"!=typeof r||(r=t.elements.popper.querySelector(r)))&&q(t.elements.popper,r)&&(t.elements.arrow=r)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]};function he(e,t,n){return void 0===n&&(n={x:0,y:0}),{top:e.top-t.height-n.y,right:e.right-t.width+n.x,bottom:e.bottom-t.height+n.y,left:e.left-t.width-n.x}}function me(e){return[j,D,E,A].some((function(t){return e[t]>=0}))}var ve={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(e){var t=e.state,n=e.name,r=t.rects.reference,o=t.rects.popper,i=t.modifiersData.preventOverflow,a=Y(t,{elementContext:"reference"}),s=Y(t,{altBoundary:!0}),f=he(a,r),c=he(s,o,i),p=me(f),u=me(c);t.modifiersData[n]={referenceClippingOffsets:f,popperEscapeOffsets:c,isReferenceHidden:p,hasPopperEscaped:u},t.attributes.popper=Object.assign({},t.attributes.popper,{"data-popper-reference-hidden":p,"data-popper-escaped":u})}},ge=K({defaultModifiers:[Z,$,ne,re]}),ye=[Z,$,ne,re,oe,pe,le,de,ve],be=K({defaultModifiers:ye});e.applyStyles=re,e.arrow=de,e.computeStyles=ne,e.createPopper=be,e.createPopperLite=ge,e.defaultModifiers=ye,e.detectOverflow=Y,e.eventListeners=Z,e.flip=pe,e.hide=ve,e.offset=oe,e.popperGenerator=K,e.popperOffsets=$,e.preventOverflow=le,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/_proc/_docs/site_libs/quarto-html/quarto-syntax-highlighting.css b/_proc/_docs/site_libs/quarto-html/quarto-syntax-highlighting.css new file mode 100644 index 0000000000000000000000000000000000000000..d9fd98f040973821b431026876f51351960f58e0 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-html/quarto-syntax-highlighting.css @@ -0,0 +1,203 @@ +/* quarto syntax highlight colors */ +:root { + --quarto-hl-ot-color: #003B4F; + --quarto-hl-at-color: #657422; + --quarto-hl-ss-color: #20794D; + --quarto-hl-an-color: #5E5E5E; + --quarto-hl-fu-color: #4758AB; + --quarto-hl-st-color: #20794D; + --quarto-hl-cf-color: #003B4F; + --quarto-hl-op-color: #5E5E5E; + --quarto-hl-er-color: #AD0000; + --quarto-hl-bn-color: #AD0000; + --quarto-hl-al-color: #AD0000; + --quarto-hl-va-color: #111111; + --quarto-hl-bu-color: inherit; + --quarto-hl-ex-color: inherit; + --quarto-hl-pp-color: #AD0000; + --quarto-hl-in-color: #5E5E5E; + --quarto-hl-vs-color: #20794D; + --quarto-hl-wa-color: #5E5E5E; + --quarto-hl-do-color: #5E5E5E; + --quarto-hl-im-color: #00769E; + --quarto-hl-ch-color: #20794D; + --quarto-hl-dt-color: #AD0000; + --quarto-hl-fl-color: #AD0000; + --quarto-hl-co-color: #5E5E5E; + --quarto-hl-cv-color: #5E5E5E; + --quarto-hl-cn-color: #8f5902; + --quarto-hl-sc-color: #5E5E5E; + --quarto-hl-dv-color: #AD0000; + --quarto-hl-kw-color: #003B4F; +} + +/* other quarto variables */ +:root { + --quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +pre > code.sourceCode > span { + color: #003B4F; +} + +code span { + color: #003B4F; +} + +code.sourceCode > span { + color: #003B4F; +} + +div.sourceCode, +div.sourceCode pre.sourceCode { + color: #003B4F; +} + +code span.ot { + color: #003B4F; + font-style: inherit; +} + +code span.at { + color: #657422; + font-style: inherit; +} + +code span.ss { + color: #20794D; + font-style: inherit; +} + +code span.an { + color: #5E5E5E; + font-style: inherit; +} + +code span.fu { + color: #4758AB; + font-style: inherit; +} + +code span.st { + color: #20794D; + font-style: inherit; +} + +code span.cf { + color: #003B4F; + font-style: inherit; +} + +code span.op { + color: #5E5E5E; + font-style: inherit; +} + +code span.er { + color: #AD0000; + font-style: inherit; +} + +code span.bn { + color: #AD0000; + font-style: inherit; +} + +code span.al { + color: #AD0000; + font-style: inherit; +} + +code span.va { + color: #111111; + font-style: inherit; +} + +code span.bu { + font-style: inherit; +} + +code span.ex { + font-style: inherit; +} + +code span.pp { + color: #AD0000; + font-style: inherit; +} + +code span.in { + color: #5E5E5E; + font-style: inherit; +} + +code span.vs { + color: #20794D; + font-style: inherit; +} + +code span.wa { + color: #5E5E5E; + font-style: italic; +} + +code span.do { + color: #5E5E5E; + font-style: italic; +} + +code span.im { + color: #00769E; + font-style: inherit; +} + +code span.ch { + color: #20794D; + font-style: inherit; +} + +code span.dt { + color: #AD0000; + font-style: inherit; +} + +code span.fl { + color: #AD0000; + font-style: inherit; +} + +code span.co { + color: #5E5E5E; + font-style: inherit; +} + +code span.cv { + color: #5E5E5E; + font-style: italic; +} + +code span.cn { + color: #8f5902; + font-style: inherit; +} + +code span.sc { + color: #5E5E5E; + font-style: inherit; +} + +code span.dv { + color: #AD0000; + font-style: inherit; +} + +code span.kw { + color: #003B4F; + font-style: inherit; +} + +.prevent-inlining { + content: " { + // Find any conflicting margin elements and add margins to the + // top to prevent overlap + const marginChildren = window.document.querySelectorAll( + ".column-margin.column-container > * " + ); + + let lastBottom = 0; + for (const marginChild of marginChildren) { + if (marginChild.offsetParent !== null) { + // clear the top margin so we recompute it + marginChild.style.marginTop = null; + const top = marginChild.getBoundingClientRect().top + window.scrollY; + console.log({ + childtop: marginChild.getBoundingClientRect().top, + scroll: window.scrollY, + top, + lastBottom, + }); + if (top < lastBottom) { + const margin = lastBottom - top; + marginChild.style.marginTop = `${margin}px`; + } + const styles = window.getComputedStyle(marginChild); + const marginTop = parseFloat(styles["marginTop"]); + + console.log({ + top, + height: marginChild.getBoundingClientRect().height, + marginTop, + total: top + marginChild.getBoundingClientRect().height + marginTop, + }); + lastBottom = top + marginChild.getBoundingClientRect().height + marginTop; + } + } +}; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Recompute the position of margin elements anytime the body size changes + if (window.ResizeObserver) { + const resizeObserver = new window.ResizeObserver( + throttle(layoutMarginEls, 50) + ); + resizeObserver.observe(window.document.body); + } + + const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]'); + const sidebarEl = window.document.getElementById("quarto-sidebar"); + const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left"); + const marginSidebarEl = window.document.getElementById( + "quarto-margin-sidebar" + ); + // function to determine whether the element has a previous sibling that is active + const prevSiblingIsActiveLink = (el) => { + const sibling = el.previousElementSibling; + if (sibling && sibling.tagName === "A") { + return sibling.classList.contains("active"); + } else { + return false; + } + }; + + // fire slideEnter for bootstrap tab activations (for htmlwidget resize behavior) + function fireSlideEnter(e) { + const event = window.document.createEvent("Event"); + event.initEvent("slideenter", true, true); + window.document.dispatchEvent(event); + } + const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]'); + tabs.forEach((tab) => { + tab.addEventListener("shown.bs.tab", fireSlideEnter); + }); + + // fire slideEnter for tabby tab activations (for htmlwidget resize behavior) + document.addEventListener("tabby", fireSlideEnter, false); + + // Track scrolling and mark TOC links as active + // get table of contents and sidebar (bail if we don't have at least one) + const tocLinks = tocEl + ? [...tocEl.querySelectorAll("a[data-scroll-target]")] + : []; + const makeActive = (link) => tocLinks[link].classList.add("active"); + const removeActive = (link) => tocLinks[link].classList.remove("active"); + const removeAllActive = () => + [...Array(tocLinks.length).keys()].forEach((link) => removeActive(link)); + + // activate the anchor for a section associated with this TOC entry + tocLinks.forEach((link) => { + link.addEventListener("click", () => { + if (link.href.indexOf("#") !== -1) { + const anchor = link.href.split("#")[1]; + const heading = window.document.querySelector( + `[data-anchor-id=${anchor}]` + ); + if (heading) { + // Add the class + heading.classList.add("reveal-anchorjs-link"); + + // function to show the anchor + const handleMouseout = () => { + heading.classList.remove("reveal-anchorjs-link"); + heading.removeEventListener("mouseout", handleMouseout); + }; + + // add a function to clear the anchor when the user mouses out of it + heading.addEventListener("mouseout", handleMouseout); + } + } + }); + }); + + const sections = tocLinks.map((link) => { + const target = link.getAttribute("data-scroll-target"); + if (target.startsWith("#")) { + return window.document.getElementById(decodeURI(`${target.slice(1)}`)); + } else { + return window.document.querySelector(decodeURI(`${target}`)); + } + }); + + const sectionMargin = 200; + let currentActive = 0; + // track whether we've initialized state the first time + let init = false; + + const updateActiveLink = () => { + // The index from bottom to top (e.g. reversed list) + let sectionIndex = -1; + if ( + window.innerHeight + window.pageYOffset >= + window.document.body.offsetHeight + ) { + sectionIndex = 0; + } else { + sectionIndex = [...sections].reverse().findIndex((section) => { + if (section) { + return window.pageYOffset >= section.offsetTop - sectionMargin; + } else { + return false; + } + }); + } + if (sectionIndex > -1) { + const current = sections.length - sectionIndex - 1; + if (current !== currentActive) { + removeAllActive(); + currentActive = current; + makeActive(current); + if (init) { + window.dispatchEvent(sectionChanged); + } + init = true; + } + } + }; + + const inHiddenRegion = (top, bottom, hiddenRegions) => { + for (const region of hiddenRegions) { + if (top <= region.bottom && bottom >= region.top) { + return true; + } + } + return false; + }; + + const categorySelector = "header.quarto-title-block .quarto-category"; + const activateCategories = (href) => { + // Find any categories + // Surround them with a link pointing back to: + // #category=Authoring + try { + const categoryEls = window.document.querySelectorAll(categorySelector); + for (const categoryEl of categoryEls) { + const categoryText = categoryEl.textContent; + if (categoryText) { + const link = `${href}#category=${encodeURIComponent(categoryText)}`; + const linkEl = window.document.createElement("a"); + linkEl.setAttribute("href", link); + for (const child of categoryEl.childNodes) { + linkEl.append(child); + } + categoryEl.appendChild(linkEl); + } + } + } catch { + // Ignore errors + } + }; + function hasTitleCategories() { + return window.document.querySelector(categorySelector) !== null; + } + + function offsetRelativeUrl(url) { + const offset = getMeta("quarto:offset"); + return offset ? offset + url : url; + } + + function offsetAbsoluteUrl(url) { + const offset = getMeta("quarto:offset"); + const baseUrl = new URL(offset, window.location); + + const projRelativeUrl = url.replace(baseUrl, ""); + if (projRelativeUrl.startsWith("/")) { + return projRelativeUrl; + } else { + return "/" + projRelativeUrl; + } + } + + // read a meta tag value + function getMeta(metaName) { + const metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; + } + + async function findAndActivateCategories() { + const currentPagePath = offsetAbsoluteUrl(window.location.href); + const response = await fetch(offsetRelativeUrl("listings.json")); + if (response.status == 200) { + return response.json().then(function (listingPaths) { + const listingHrefs = []; + for (const listingPath of listingPaths) { + const pathWithoutLeadingSlash = listingPath.listing.substring(1); + for (const item of listingPath.items) { + if ( + item === currentPagePath || + item === currentPagePath + "index.html" + ) { + // Resolve this path against the offset to be sure + // we already are using the correct path to the listing + // (this adjusts the listing urls to be rooted against + // whatever root the page is actually running against) + const relative = offsetRelativeUrl(pathWithoutLeadingSlash); + const baseUrl = window.location; + const resolvedPath = new URL(relative, baseUrl); + listingHrefs.push(resolvedPath.pathname); + break; + } + } + } + + // Look up the tree for a nearby linting and use that if we find one + const nearestListing = findNearestParentListing( + offsetAbsoluteUrl(window.location.pathname), + listingHrefs + ); + if (nearestListing) { + activateCategories(nearestListing); + } else { + // See if the referrer is a listing page for this item + const referredRelativePath = offsetAbsoluteUrl(document.referrer); + const referrerListing = listingHrefs.find((listingHref) => { + const isListingReferrer = + listingHref === referredRelativePath || + listingHref === referredRelativePath + "index.html"; + return isListingReferrer; + }); + + if (referrerListing) { + // Try to use the referrer if possible + activateCategories(referrerListing); + } else if (listingHrefs.length > 0) { + // Otherwise, just fall back to the first listing + activateCategories(listingHrefs[0]); + } + } + }); + } + } + if (hasTitleCategories()) { + findAndActivateCategories(); + } + + const findNearestParentListing = (href, listingHrefs) => { + if (!href || !listingHrefs) { + return undefined; + } + // Look up the tree for a nearby linting and use that if we find one + const relativeParts = href.substring(1).split("/"); + while (relativeParts.length > 0) { + const path = relativeParts.join("/"); + for (const listingHref of listingHrefs) { + if (listingHref.startsWith(path)) { + return listingHref; + } + } + relativeParts.pop(); + } + + return undefined; + }; + + const manageSidebarVisiblity = (el, placeholderDescriptor) => { + let isVisible = true; + let elRect; + + return (hiddenRegions) => { + if (el === null) { + return; + } + + // Find the last element of the TOC + const lastChildEl = el.lastElementChild; + + if (lastChildEl) { + // Converts the sidebar to a menu + const convertToMenu = () => { + for (const child of el.children) { + child.style.opacity = 0; + child.style.overflow = "hidden"; + } + + nexttick(() => { + const toggleContainer = window.document.createElement("div"); + toggleContainer.style.width = "100%"; + toggleContainer.classList.add("zindex-over-content"); + toggleContainer.classList.add("quarto-sidebar-toggle"); + toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom + toggleContainer.id = placeholderDescriptor.id; + toggleContainer.style.position = "fixed"; + + const toggleIcon = window.document.createElement("i"); + toggleIcon.classList.add("quarto-sidebar-toggle-icon"); + toggleIcon.classList.add("bi"); + toggleIcon.classList.add("bi-caret-down-fill"); + + const toggleTitle = window.document.createElement("div"); + const titleEl = window.document.body.querySelector( + placeholderDescriptor.titleSelector + ); + if (titleEl) { + toggleTitle.append( + titleEl.textContent || titleEl.innerText, + toggleIcon + ); + } + toggleTitle.classList.add("zindex-over-content"); + toggleTitle.classList.add("quarto-sidebar-toggle-title"); + toggleContainer.append(toggleTitle); + + const toggleContents = window.document.createElement("div"); + toggleContents.classList = el.classList; + toggleContents.classList.add("zindex-over-content"); + toggleContents.classList.add("quarto-sidebar-toggle-contents"); + for (const child of el.children) { + if (child.id === "toc-title") { + continue; + } + + const clone = child.cloneNode(true); + clone.style.opacity = 1; + clone.style.display = null; + toggleContents.append(clone); + } + toggleContents.style.height = "0px"; + const positionToggle = () => { + // position the element (top left of parent, same width as parent) + if (!elRect) { + elRect = el.getBoundingClientRect(); + } + toggleContainer.style.left = `${elRect.left}px`; + toggleContainer.style.top = `${elRect.top}px`; + toggleContainer.style.width = `${elRect.width}px`; + }; + positionToggle(); + + toggleContainer.append(toggleContents); + el.parentElement.prepend(toggleContainer); + + // Process clicks + let tocShowing = false; + // Allow the caller to control whether this is dismissed + // when it is clicked (e.g. sidebar navigation supports + // opening and closing the nav tree, so don't dismiss on click) + const clickEl = placeholderDescriptor.dismissOnClick + ? toggleContainer + : toggleTitle; + + const closeToggle = () => { + if (tocShowing) { + toggleContainer.classList.remove("expanded"); + toggleContents.style.height = "0px"; + tocShowing = false; + } + }; + + // Get rid of any expanded toggle if the user scrolls + window.document.addEventListener( + "scroll", + throttle(() => { + closeToggle(); + }, 50) + ); + + // Handle positioning of the toggle + window.addEventListener( + "resize", + throttle(() => { + elRect = undefined; + positionToggle(); + }, 50) + ); + + window.addEventListener("quarto-hrChanged", () => { + elRect = undefined; + }); + + // Process the click + clickEl.onclick = () => { + if (!tocShowing) { + toggleContainer.classList.add("expanded"); + toggleContents.style.height = null; + tocShowing = true; + } else { + closeToggle(); + } + }; + }); + }; + + // Converts a sidebar from a menu back to a sidebar + const convertToSidebar = () => { + for (const child of el.children) { + child.style.opacity = 1; + child.style.overflow = null; + } + + const placeholderEl = window.document.getElementById( + placeholderDescriptor.id + ); + if (placeholderEl) { + placeholderEl.remove(); + } + + el.classList.remove("rollup"); + }; + + if (isReaderMode()) { + convertToMenu(); + isVisible = false; + } else { + // Find the top and bottom o the element that is being managed + const elTop = el.offsetTop; + const elBottom = + elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight; + + if (!isVisible) { + // If the element is current not visible reveal if there are + // no conflicts with overlay regions + if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToSidebar(); + isVisible = true; + } + } else { + // If the element is visible, hide it if it conflicts with overlay regions + // and insert a placeholder toggle (or if we're in reader mode) + if (inHiddenRegion(elTop, elBottom, hiddenRegions)) { + convertToMenu(); + isVisible = false; + } + } + } + } + }; + }; + + const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]'); + for (const tabEl of tabEls) { + const id = tabEl.getAttribute("data-bs-target"); + if (id) { + const columnEl = document.querySelector( + `${id} .column-margin, .tabset-margin-content` + ); + if (columnEl) + tabEl.addEventListener("shown.bs.tab", function (event) { + const el = event.srcElement; + if (el) { + const visibleCls = `${el.id}-margin-content`; + // walk up until we find a parent tabset + let panelTabsetEl = el.parentElement; + while (panelTabsetEl) { + if (panelTabsetEl.classList.contains("panel-tabset")) { + break; + } + panelTabsetEl = panelTabsetEl.parentElement; + } + + if (panelTabsetEl) { + const prevSib = panelTabsetEl.previousElementSibling; + if ( + prevSib && + prevSib.classList.contains("tabset-margin-container") + ) { + const childNodes = prevSib.querySelectorAll( + ".tabset-margin-content" + ); + for (const childEl of childNodes) { + if (childEl.classList.contains(visibleCls)) { + childEl.classList.remove("collapse"); + } else { + childEl.classList.add("collapse"); + } + } + } + } + } + + layoutMarginEls(); + }); + } + } + + // Manage the visibility of the toc and the sidebar + const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, { + id: "quarto-toc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, { + id: "quarto-sidebarnav-toggle", + titleSelector: ".title", + dismissOnClick: false, + }); + let tocLeftScrollVisibility; + if (leftTocEl) { + tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, { + id: "quarto-lefttoc-toggle", + titleSelector: "#toc-title", + dismissOnClick: true, + }); + } + + // Find the first element that uses formatting in special columns + const conflictingEls = window.document.body.querySelectorAll( + '[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]' + ); + + // Filter all the possibly conflicting elements into ones + // the do conflict on the left or ride side + const arrConflictingEls = Array.from(conflictingEls); + const leftSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return false; + } + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + className.startsWith("column-") && + !className.endsWith("right") && + !className.endsWith("container") && + className !== "column-margin" + ); + }); + }); + const rightSideConflictEls = arrConflictingEls.filter((el) => { + if (el.tagName === "ASIDE") { + return true; + } + + const hasMarginCaption = Array.from(el.classList).find((className) => { + return className == "margin-caption"; + }); + if (hasMarginCaption) { + return true; + } + + return Array.from(el.classList).find((className) => { + return ( + className !== "column-body" && + !className.endsWith("container") && + className.startsWith("column-") && + !className.endsWith("left") + ); + }); + }); + + const kOverlapPaddingSize = 10; + function toRegions(els) { + return els.map((el) => { + const boundRect = el.getBoundingClientRect(); + const top = + boundRect.top + + document.documentElement.scrollTop - + kOverlapPaddingSize; + return { + top, + bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize, + }; + }); + } + + let hasObserved = false; + const visibleItemObserver = (els) => { + let visibleElements = [...els]; + const intersectionObserver = new IntersectionObserver( + (entries, _observer) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + if (visibleElements.indexOf(entry.target) === -1) { + visibleElements.push(entry.target); + } + } else { + visibleElements = visibleElements.filter((visibleEntry) => { + return visibleEntry !== entry; + }); + } + }); + + if (!hasObserved) { + hideOverlappedSidebars(); + } + hasObserved = true; + }, + {} + ); + els.forEach((el) => { + intersectionObserver.observe(el); + }); + + return { + getVisibleEntries: () => { + return visibleElements; + }, + }; + }; + + const rightElementObserver = visibleItemObserver(rightSideConflictEls); + const leftElementObserver = visibleItemObserver(leftSideConflictEls); + + const hideOverlappedSidebars = () => { + marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries())); + sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries())); + if (tocLeftScrollVisibility) { + tocLeftScrollVisibility( + toRegions(leftElementObserver.getVisibleEntries()) + ); + } + }; + + window.quartoToggleReader = () => { + // Applies a slow class (or removes it) + // to update the transition speed + const slowTransition = (slow) => { + const manageTransition = (id, slow) => { + const el = document.getElementById(id); + if (el) { + if (slow) { + el.classList.add("slow"); + } else { + el.classList.remove("slow"); + } + } + }; + + manageTransition("TOC", slow); + manageTransition("quarto-sidebar", slow); + }; + const readerMode = !isReaderMode(); + setReaderModeValue(readerMode); + + // If we're entering reader mode, slow the transition + if (readerMode) { + slowTransition(readerMode); + } + highlightReaderToggle(readerMode); + hideOverlappedSidebars(); + + // If we're exiting reader mode, restore the non-slow transition + if (!readerMode) { + slowTransition(!readerMode); + } + }; + + const highlightReaderToggle = (readerMode) => { + const els = document.querySelectorAll(".quarto-reader-toggle"); + if (els) { + els.forEach((el) => { + if (readerMode) { + el.classList.add("reader"); + } else { + el.classList.remove("reader"); + } + }); + } + }; + + const setReaderModeValue = (val) => { + if (window.location.protocol !== "file:") { + window.localStorage.setItem("quarto-reader-mode", val); + } else { + localReaderMode = val; + } + }; + + const isReaderMode = () => { + if (window.location.protocol !== "file:") { + return window.localStorage.getItem("quarto-reader-mode") === "true"; + } else { + return localReaderMode; + } + }; + let localReaderMode = null; + + const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded"); + const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1; + + // Walk the TOC and collapse/expand nodes + // Nodes are expanded if: + // - they are top level + // - they have children that are 'active' links + // - they are directly below an link that is 'active' + const walk = (el, depth) => { + // Tick depth when we enter a UL + if (el.tagName === "UL") { + depth = depth + 1; + } + + // It this is active link + let isActiveNode = false; + if (el.tagName === "A" && el.classList.contains("active")) { + isActiveNode = true; + } + + // See if there is an active child to this element + let hasActiveChild = false; + for (child of el.children) { + hasActiveChild = walk(child, depth) || hasActiveChild; + } + + // Process the collapse state if this is an UL + if (el.tagName === "UL") { + if (tocOpenDepth === -1 && depth > 1) { + el.classList.add("collapse"); + } else if ( + depth <= tocOpenDepth || + hasActiveChild || + prevSiblingIsActiveLink(el) + ) { + el.classList.remove("collapse"); + } else { + el.classList.add("collapse"); + } + + // untick depth when we leave a UL + depth = depth - 1; + } + return hasActiveChild || isActiveNode; + }; + + // walk the TOC and expand / collapse any items that should be shown + + if (tocEl) { + walk(tocEl, 0); + updateActiveLink(); + } + + // Throttle the scroll event and walk peridiocally + window.document.addEventListener( + "scroll", + throttle(() => { + if (tocEl) { + updateActiveLink(); + walk(tocEl, 0); + } + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 5) + ); + window.addEventListener( + "resize", + throttle(() => { + if (!isReaderMode()) { + hideOverlappedSidebars(); + } + }, 10) + ); + hideOverlappedSidebars(); + highlightReaderToggle(isReaderMode()); +}); + +// grouped tabsets +window.addEventListener("pageshow", (_event) => { + function getTabSettings() { + const data = localStorage.getItem("quarto-persistent-tabsets-data"); + if (!data) { + localStorage.setItem("quarto-persistent-tabsets-data", "{}"); + return {}; + } + if (data) { + return JSON.parse(data); + } + } + + function setTabSettings(data) { + localStorage.setItem( + "quarto-persistent-tabsets-data", + JSON.stringify(data) + ); + } + + function setTabState(groupName, groupValue) { + const data = getTabSettings(); + data[groupName] = groupValue; + setTabSettings(data); + } + + function toggleTab(tab, active) { + const tabPanelId = tab.getAttribute("aria-controls"); + const tabPanel = document.getElementById(tabPanelId); + if (active) { + tab.classList.add("active"); + tabPanel.classList.add("active"); + } else { + tab.classList.remove("active"); + tabPanel.classList.remove("active"); + } + } + + function toggleAll(selectedGroup, selectorsToSync) { + for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) { + const active = selectedGroup === thisGroup; + for (const tab of tabs) { + toggleTab(tab, active); + } + } + } + + function findSelectorsToSyncByLanguage() { + const result = {}; + const tabs = Array.from( + document.querySelectorAll(`div[data-group] a[id^='tabset-']`) + ); + for (const item of tabs) { + const div = item.parentElement.parentElement.parentElement; + const group = div.getAttribute("data-group"); + if (!result[group]) { + result[group] = {}; + } + const selectorsToSync = result[group]; + const value = item.innerHTML; + if (!selectorsToSync[value]) { + selectorsToSync[value] = []; + } + selectorsToSync[value].push(item); + } + return result; + } + + function setupSelectorSync() { + const selectorsToSync = findSelectorsToSyncByLanguage(); + Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => { + Object.entries(tabSetsByValue).forEach(([value, items]) => { + items.forEach((item) => { + item.addEventListener("click", (_event) => { + setTabState(group, value); + toggleAll(value, selectorsToSync[group]); + }); + }); + }); + }); + return selectorsToSync; + } + + const selectorsToSync = setupSelectorSync(); + for (const [group, selectedName] of Object.entries(getTabSettings())) { + const selectors = selectorsToSync[group]; + // it's possible that stale state gives us empty selections, so we explicitly check here. + if (selectors) { + toggleAll(selectedName, selectors); + } + } +}); + +function throttle(func, wait) { + let waiting = false; + return function () { + if (!waiting) { + func.apply(this, arguments); + waiting = true; + setTimeout(function () { + waiting = false; + }, wait); + } + }; +} + +function nexttick(func) { + return setTimeout(func, 0); +} diff --git a/_proc/_docs/site_libs/quarto-html/tippy.css b/_proc/_docs/site_libs/quarto-html/tippy.css new file mode 100644 index 0000000000000000000000000000000000000000..e6ae635cb1f82b176c18afa80dfa029c7a536e70 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-html/tippy.css @@ -0,0 +1 @@ +.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1} \ No newline at end of file diff --git a/_proc/_docs/site_libs/quarto-html/tippy.umd.min.js b/_proc/_docs/site_libs/quarto-html/tippy.umd.min.js new file mode 100644 index 0000000000000000000000000000000000000000..ca292be32b252f9a40e231f3a3e696b2506f7c96 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-html/tippy.umd.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],t):(e=e||self).tippy=t(e.Popper)}(this,(function(e){"use strict";var t={passive:!0,capture:!0},n=function(){return document.body};function r(e,t,n){if(Array.isArray(e)){var r=e[t];return null==r?Array.isArray(n)?n[t]:n:r}return e}function o(e,t){var n={}.toString.call(e);return 0===n.indexOf("[object")&&n.indexOf(t+"]")>-1}function i(e,t){return"function"==typeof e?e.apply(void 0,t):e}function a(e,t){return 0===t?e:function(r){clearTimeout(n),n=setTimeout((function(){e(r)}),t)};var n}function s(e,t){var n=Object.assign({},e);return t.forEach((function(e){delete n[e]})),n}function u(e){return[].concat(e)}function c(e,t){-1===e.indexOf(t)&&e.push(t)}function p(e){return e.split("-")[0]}function f(e){return[].slice.call(e)}function l(e){return Object.keys(e).reduce((function(t,n){return void 0!==e[n]&&(t[n]=e[n]),t}),{})}function d(){return document.createElement("div")}function v(e){return["Element","Fragment"].some((function(t){return o(e,t)}))}function m(e){return o(e,"MouseEvent")}function g(e){return!(!e||!e._tippy||e._tippy.reference!==e)}function h(e){return v(e)?[e]:function(e){return o(e,"NodeList")}(e)?f(e):Array.isArray(e)?e:f(document.querySelectorAll(e))}function b(e,t){e.forEach((function(e){e&&(e.style.transitionDuration=t+"ms")}))}function y(e,t){e.forEach((function(e){e&&e.setAttribute("data-state",t)}))}function w(e){var t,n=u(e)[0];return null!=n&&null!=(t=n.ownerDocument)&&t.body?n.ownerDocument:document}function E(e,t,n){var r=t+"EventListener";["transitionend","webkitTransitionEnd"].forEach((function(t){e[r](t,n)}))}function O(e,t){for(var n=t;n;){var r;if(e.contains(n))return!0;n=null==n.getRootNode||null==(r=n.getRootNode())?void 0:r.host}return!1}var x={isTouch:!1},C=0;function T(){x.isTouch||(x.isTouch=!0,window.performance&&document.addEventListener("mousemove",A))}function A(){var e=performance.now();e-C<20&&(x.isTouch=!1,document.removeEventListener("mousemove",A)),C=e}function L(){var e=document.activeElement;if(g(e)){var t=e._tippy;e.blur&&!t.state.isVisible&&e.blur()}}var D=!!("undefined"!=typeof window&&"undefined"!=typeof document)&&!!window.msCrypto,R=Object.assign({appendTo:n,aria:{content:"auto",expanded:"auto"},delay:0,duration:[300,250],getReferenceClientRect:null,hideOnClick:!0,ignoreAttributes:!1,interactive:!1,interactiveBorder:2,interactiveDebounce:0,moveTransition:"",offset:[0,10],onAfterUpdate:function(){},onBeforeUpdate:function(){},onCreate:function(){},onDestroy:function(){},onHidden:function(){},onHide:function(){},onMount:function(){},onShow:function(){},onShown:function(){},onTrigger:function(){},onUntrigger:function(){},onClickOutside:function(){},placement:"top",plugins:[],popperOptions:{},render:null,showOnCreate:!1,touch:!0,trigger:"mouseenter focus",triggerTarget:null},{animateFill:!1,followCursor:!1,inlinePositioning:!1,sticky:!1},{allowHTML:!1,animation:"fade",arrow:!0,content:"",inertia:!1,maxWidth:350,role:"tooltip",theme:"",zIndex:9999}),k=Object.keys(R);function P(e){var t=(e.plugins||[]).reduce((function(t,n){var r,o=n.name,i=n.defaultValue;o&&(t[o]=void 0!==e[o]?e[o]:null!=(r=R[o])?r:i);return t}),{});return Object.assign({},e,t)}function j(e,t){var n=Object.assign({},t,{content:i(t.content,[e])},t.ignoreAttributes?{}:function(e,t){return(t?Object.keys(P(Object.assign({},R,{plugins:t}))):k).reduce((function(t,n){var r=(e.getAttribute("data-tippy-"+n)||"").trim();if(!r)return t;if("content"===n)t[n]=r;else try{t[n]=JSON.parse(r)}catch(e){t[n]=r}return t}),{})}(e,t.plugins));return n.aria=Object.assign({},R.aria,n.aria),n.aria={expanded:"auto"===n.aria.expanded?t.interactive:n.aria.expanded,content:"auto"===n.aria.content?t.interactive?null:"describedby":n.aria.content},n}function M(e,t){e.innerHTML=t}function V(e){var t=d();return!0===e?t.className="tippy-arrow":(t.className="tippy-svg-arrow",v(e)?t.appendChild(e):M(t,e)),t}function I(e,t){v(t.content)?(M(e,""),e.appendChild(t.content)):"function"!=typeof t.content&&(t.allowHTML?M(e,t.content):e.textContent=t.content)}function S(e){var t=e.firstElementChild,n=f(t.children);return{box:t,content:n.find((function(e){return e.classList.contains("tippy-content")})),arrow:n.find((function(e){return e.classList.contains("tippy-arrow")||e.classList.contains("tippy-svg-arrow")})),backdrop:n.find((function(e){return e.classList.contains("tippy-backdrop")}))}}function N(e){var t=d(),n=d();n.className="tippy-box",n.setAttribute("data-state","hidden"),n.setAttribute("tabindex","-1");var r=d();function o(n,r){var o=S(t),i=o.box,a=o.content,s=o.arrow;r.theme?i.setAttribute("data-theme",r.theme):i.removeAttribute("data-theme"),"string"==typeof r.animation?i.setAttribute("data-animation",r.animation):i.removeAttribute("data-animation"),r.inertia?i.setAttribute("data-inertia",""):i.removeAttribute("data-inertia"),i.style.maxWidth="number"==typeof r.maxWidth?r.maxWidth+"px":r.maxWidth,r.role?i.setAttribute("role",r.role):i.removeAttribute("role"),n.content===r.content&&n.allowHTML===r.allowHTML||I(a,e.props),r.arrow?s?n.arrow!==r.arrow&&(i.removeChild(s),i.appendChild(V(r.arrow))):i.appendChild(V(r.arrow)):s&&i.removeChild(s)}return r.className="tippy-content",r.setAttribute("data-state","hidden"),I(r,e.props),t.appendChild(n),n.appendChild(r),o(e.props,e.props),{popper:t,onUpdate:o}}N.$$tippy=!0;var B=1,H=[],U=[];function _(o,s){var v,g,h,C,T,A,L,k,M=j(o,Object.assign({},R,P(l(s)))),V=!1,I=!1,N=!1,_=!1,F=[],W=a(we,M.interactiveDebounce),X=B++,Y=(k=M.plugins).filter((function(e,t){return k.indexOf(e)===t})),$={id:X,reference:o,popper:d(),popperInstance:null,props:M,state:{isEnabled:!0,isVisible:!1,isDestroyed:!1,isMounted:!1,isShown:!1},plugins:Y,clearDelayTimeouts:function(){clearTimeout(v),clearTimeout(g),cancelAnimationFrame(h)},setProps:function(e){if($.state.isDestroyed)return;ae("onBeforeUpdate",[$,e]),be();var t=$.props,n=j(o,Object.assign({},t,l(e),{ignoreAttributes:!0}));$.props=n,he(),t.interactiveDebounce!==n.interactiveDebounce&&(ce(),W=a(we,n.interactiveDebounce));t.triggerTarget&&!n.triggerTarget?u(t.triggerTarget).forEach((function(e){e.removeAttribute("aria-expanded")})):n.triggerTarget&&o.removeAttribute("aria-expanded");ue(),ie(),J&&J(t,n);$.popperInstance&&(Ce(),Ae().forEach((function(e){requestAnimationFrame(e._tippy.popperInstance.forceUpdate)})));ae("onAfterUpdate",[$,e])},setContent:function(e){$.setProps({content:e})},show:function(){var e=$.state.isVisible,t=$.state.isDestroyed,o=!$.state.isEnabled,a=x.isTouch&&!$.props.touch,s=r($.props.duration,0,R.duration);if(e||t||o||a)return;if(te().hasAttribute("disabled"))return;if(ae("onShow",[$],!1),!1===$.props.onShow($))return;$.state.isVisible=!0,ee()&&(z.style.visibility="visible");ie(),de(),$.state.isMounted||(z.style.transition="none");if(ee()){var u=re(),p=u.box,f=u.content;b([p,f],0)}A=function(){var e;if($.state.isVisible&&!_){if(_=!0,z.offsetHeight,z.style.transition=$.props.moveTransition,ee()&&$.props.animation){var t=re(),n=t.box,r=t.content;b([n,r],s),y([n,r],"visible")}se(),ue(),c(U,$),null==(e=$.popperInstance)||e.forceUpdate(),ae("onMount",[$]),$.props.animation&&ee()&&function(e,t){me(e,t)}(s,(function(){$.state.isShown=!0,ae("onShown",[$])}))}},function(){var e,t=$.props.appendTo,r=te();e=$.props.interactive&&t===n||"parent"===t?r.parentNode:i(t,[r]);e.contains(z)||e.appendChild(z);$.state.isMounted=!0,Ce()}()},hide:function(){var e=!$.state.isVisible,t=$.state.isDestroyed,n=!$.state.isEnabled,o=r($.props.duration,1,R.duration);if(e||t||n)return;if(ae("onHide",[$],!1),!1===$.props.onHide($))return;$.state.isVisible=!1,$.state.isShown=!1,_=!1,V=!1,ee()&&(z.style.visibility="hidden");if(ce(),ve(),ie(!0),ee()){var i=re(),a=i.box,s=i.content;$.props.animation&&(b([a,s],o),y([a,s],"hidden"))}se(),ue(),$.props.animation?ee()&&function(e,t){me(e,(function(){!$.state.isVisible&&z.parentNode&&z.parentNode.contains(z)&&t()}))}(o,$.unmount):$.unmount()},hideWithInteractivity:function(e){ne().addEventListener("mousemove",W),c(H,W),W(e)},enable:function(){$.state.isEnabled=!0},disable:function(){$.hide(),$.state.isEnabled=!1},unmount:function(){$.state.isVisible&&$.hide();if(!$.state.isMounted)return;Te(),Ae().forEach((function(e){e._tippy.unmount()})),z.parentNode&&z.parentNode.removeChild(z);U=U.filter((function(e){return e!==$})),$.state.isMounted=!1,ae("onHidden",[$])},destroy:function(){if($.state.isDestroyed)return;$.clearDelayTimeouts(),$.unmount(),be(),delete o._tippy,$.state.isDestroyed=!0,ae("onDestroy",[$])}};if(!M.render)return $;var q=M.render($),z=q.popper,J=q.onUpdate;z.setAttribute("data-tippy-root",""),z.id="tippy-"+$.id,$.popper=z,o._tippy=$,z._tippy=$;var G=Y.map((function(e){return e.fn($)})),K=o.hasAttribute("aria-expanded");return he(),ue(),ie(),ae("onCreate",[$]),M.showOnCreate&&Le(),z.addEventListener("mouseenter",(function(){$.props.interactive&&$.state.isVisible&&$.clearDelayTimeouts()})),z.addEventListener("mouseleave",(function(){$.props.interactive&&$.props.trigger.indexOf("mouseenter")>=0&&ne().addEventListener("mousemove",W)})),$;function Q(){var e=$.props.touch;return Array.isArray(e)?e:[e,0]}function Z(){return"hold"===Q()[0]}function ee(){var e;return!(null==(e=$.props.render)||!e.$$tippy)}function te(){return L||o}function ne(){var e=te().parentNode;return e?w(e):document}function re(){return S(z)}function oe(e){return $.state.isMounted&&!$.state.isVisible||x.isTouch||C&&"focus"===C.type?0:r($.props.delay,e?0:1,R.delay)}function ie(e){void 0===e&&(e=!1),z.style.pointerEvents=$.props.interactive&&!e?"":"none",z.style.zIndex=""+$.props.zIndex}function ae(e,t,n){var r;(void 0===n&&(n=!0),G.forEach((function(n){n[e]&&n[e].apply(n,t)})),n)&&(r=$.props)[e].apply(r,t)}function se(){var e=$.props.aria;if(e.content){var t="aria-"+e.content,n=z.id;u($.props.triggerTarget||o).forEach((function(e){var r=e.getAttribute(t);if($.state.isVisible)e.setAttribute(t,r?r+" "+n:n);else{var o=r&&r.replace(n,"").trim();o?e.setAttribute(t,o):e.removeAttribute(t)}}))}}function ue(){!K&&$.props.aria.expanded&&u($.props.triggerTarget||o).forEach((function(e){$.props.interactive?e.setAttribute("aria-expanded",$.state.isVisible&&e===te()?"true":"false"):e.removeAttribute("aria-expanded")}))}function ce(){ne().removeEventListener("mousemove",W),H=H.filter((function(e){return e!==W}))}function pe(e){if(!x.isTouch||!N&&"mousedown"!==e.type){var t=e.composedPath&&e.composedPath()[0]||e.target;if(!$.props.interactive||!O(z,t)){if(u($.props.triggerTarget||o).some((function(e){return O(e,t)}))){if(x.isTouch)return;if($.state.isVisible&&$.props.trigger.indexOf("click")>=0)return}else ae("onClickOutside",[$,e]);!0===$.props.hideOnClick&&($.clearDelayTimeouts(),$.hide(),I=!0,setTimeout((function(){I=!1})),$.state.isMounted||ve())}}}function fe(){N=!0}function le(){N=!1}function de(){var e=ne();e.addEventListener("mousedown",pe,!0),e.addEventListener("touchend",pe,t),e.addEventListener("touchstart",le,t),e.addEventListener("touchmove",fe,t)}function ve(){var e=ne();e.removeEventListener("mousedown",pe,!0),e.removeEventListener("touchend",pe,t),e.removeEventListener("touchstart",le,t),e.removeEventListener("touchmove",fe,t)}function me(e,t){var n=re().box;function r(e){e.target===n&&(E(n,"remove",r),t())}if(0===e)return t();E(n,"remove",T),E(n,"add",r),T=r}function ge(e,t,n){void 0===n&&(n=!1),u($.props.triggerTarget||o).forEach((function(r){r.addEventListener(e,t,n),F.push({node:r,eventType:e,handler:t,options:n})}))}function he(){var e;Z()&&(ge("touchstart",ye,{passive:!0}),ge("touchend",Ee,{passive:!0})),(e=$.props.trigger,e.split(/\s+/).filter(Boolean)).forEach((function(e){if("manual"!==e)switch(ge(e,ye),e){case"mouseenter":ge("mouseleave",Ee);break;case"focus":ge(D?"focusout":"blur",Oe);break;case"focusin":ge("focusout",Oe)}}))}function be(){F.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),F=[]}function ye(e){var t,n=!1;if($.state.isEnabled&&!xe(e)&&!I){var r="focus"===(null==(t=C)?void 0:t.type);C=e,L=e.currentTarget,ue(),!$.state.isVisible&&m(e)&&H.forEach((function(t){return t(e)})),"click"===e.type&&($.props.trigger.indexOf("mouseenter")<0||V)&&!1!==$.props.hideOnClick&&$.state.isVisible?n=!0:Le(e),"click"===e.type&&(V=!n),n&&!r&&De(e)}}function we(e){var t=e.target,n=te().contains(t)||z.contains(t);"mousemove"===e.type&&n||function(e,t){var n=t.clientX,r=t.clientY;return e.every((function(e){var t=e.popperRect,o=e.popperState,i=e.props.interactiveBorder,a=p(o.placement),s=o.modifiersData.offset;if(!s)return!0;var u="bottom"===a?s.top.y:0,c="top"===a?s.bottom.y:0,f="right"===a?s.left.x:0,l="left"===a?s.right.x:0,d=t.top-r+u>i,v=r-t.bottom-c>i,m=t.left-n+f>i,g=n-t.right-l>i;return d||v||m||g}))}(Ae().concat(z).map((function(e){var t,n=null==(t=e._tippy.popperInstance)?void 0:t.state;return n?{popperRect:e.getBoundingClientRect(),popperState:n,props:M}:null})).filter(Boolean),e)&&(ce(),De(e))}function Ee(e){xe(e)||$.props.trigger.indexOf("click")>=0&&V||($.props.interactive?$.hideWithInteractivity(e):De(e))}function Oe(e){$.props.trigger.indexOf("focusin")<0&&e.target!==te()||$.props.interactive&&e.relatedTarget&&z.contains(e.relatedTarget)||De(e)}function xe(e){return!!x.isTouch&&Z()!==e.type.indexOf("touch")>=0}function Ce(){Te();var t=$.props,n=t.popperOptions,r=t.placement,i=t.offset,a=t.getReferenceClientRect,s=t.moveTransition,u=ee()?S(z).arrow:null,c=a?{getBoundingClientRect:a,contextElement:a.contextElement||te()}:o,p=[{name:"offset",options:{offset:i}},{name:"preventOverflow",options:{padding:{top:2,bottom:2,left:5,right:5}}},{name:"flip",options:{padding:5}},{name:"computeStyles",options:{adaptive:!s}},{name:"$$tippy",enabled:!0,phase:"beforeWrite",requires:["computeStyles"],fn:function(e){var t=e.state;if(ee()){var n=re().box;["placement","reference-hidden","escaped"].forEach((function(e){"placement"===e?n.setAttribute("data-placement",t.placement):t.attributes.popper["data-popper-"+e]?n.setAttribute("data-"+e,""):n.removeAttribute("data-"+e)})),t.attributes.popper={}}}}];ee()&&u&&p.push({name:"arrow",options:{element:u,padding:3}}),p.push.apply(p,(null==n?void 0:n.modifiers)||[]),$.popperInstance=e.createPopper(c,z,Object.assign({},n,{placement:r,onFirstUpdate:A,modifiers:p}))}function Te(){$.popperInstance&&($.popperInstance.destroy(),$.popperInstance=null)}function Ae(){return f(z.querySelectorAll("[data-tippy-root]"))}function Le(e){$.clearDelayTimeouts(),e&&ae("onTrigger",[$,e]),de();var t=oe(!0),n=Q(),r=n[0],o=n[1];x.isTouch&&"hold"===r&&o&&(t=o),t?v=setTimeout((function(){$.show()}),t):$.show()}function De(e){if($.clearDelayTimeouts(),ae("onUntrigger",[$,e]),$.state.isVisible){if(!($.props.trigger.indexOf("mouseenter")>=0&&$.props.trigger.indexOf("click")>=0&&["mouseleave","mousemove"].indexOf(e.type)>=0&&V)){var t=oe(!1);t?g=setTimeout((function(){$.state.isVisible&&$.hide()}),t):h=requestAnimationFrame((function(){$.hide()}))}}else ve()}}function F(e,n){void 0===n&&(n={});var r=R.plugins.concat(n.plugins||[]);document.addEventListener("touchstart",T,t),window.addEventListener("blur",L);var o=Object.assign({},n,{plugins:r}),i=h(e).reduce((function(e,t){var n=t&&_(t,o);return n&&e.push(n),e}),[]);return v(e)?i[0]:i}F.defaultProps=R,F.setDefaultProps=function(e){Object.keys(e).forEach((function(t){R[t]=e[t]}))},F.currentInput=x;var W=Object.assign({},e.applyStyles,{effect:function(e){var t=e.state,n={popper:{position:t.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};Object.assign(t.elements.popper.style,n.popper),t.styles=n,t.elements.arrow&&Object.assign(t.elements.arrow.style,n.arrow)}}),X={mouseover:"mouseenter",focusin:"focus",click:"click"};var Y={name:"animateFill",defaultValue:!1,fn:function(e){var t;if(null==(t=e.props.render)||!t.$$tippy)return{};var n=S(e.popper),r=n.box,o=n.content,i=e.props.animateFill?function(){var e=d();return e.className="tippy-backdrop",y([e],"hidden"),e}():null;return{onCreate:function(){i&&(r.insertBefore(i,r.firstElementChild),r.setAttribute("data-animatefill",""),r.style.overflow="hidden",e.setProps({arrow:!1,animation:"shift-away"}))},onMount:function(){if(i){var e=r.style.transitionDuration,t=Number(e.replace("ms",""));o.style.transitionDelay=Math.round(t/10)+"ms",i.style.transitionDuration=e,y([i],"visible")}},onShow:function(){i&&(i.style.transitionDuration="0ms")},onHide:function(){i&&y([i],"hidden")}}}};var $={clientX:0,clientY:0},q=[];function z(e){var t=e.clientX,n=e.clientY;$={clientX:t,clientY:n}}var J={name:"followCursor",defaultValue:!1,fn:function(e){var t=e.reference,n=w(e.props.triggerTarget||t),r=!1,o=!1,i=!0,a=e.props;function s(){return"initial"===e.props.followCursor&&e.state.isVisible}function u(){n.addEventListener("mousemove",f)}function c(){n.removeEventListener("mousemove",f)}function p(){r=!0,e.setProps({getReferenceClientRect:null}),r=!1}function f(n){var r=!n.target||t.contains(n.target),o=e.props.followCursor,i=n.clientX,a=n.clientY,s=t.getBoundingClientRect(),u=i-s.left,c=a-s.top;!r&&e.props.interactive||e.setProps({getReferenceClientRect:function(){var e=t.getBoundingClientRect(),n=i,r=a;"initial"===o&&(n=e.left+u,r=e.top+c);var s="horizontal"===o?e.top:r,p="vertical"===o?e.right:n,f="horizontal"===o?e.bottom:r,l="vertical"===o?e.left:n;return{width:p-l,height:f-s,top:s,right:p,bottom:f,left:l}}})}function l(){e.props.followCursor&&(q.push({instance:e,doc:n}),function(e){e.addEventListener("mousemove",z)}(n))}function d(){0===(q=q.filter((function(t){return t.instance!==e}))).filter((function(e){return e.doc===n})).length&&function(e){e.removeEventListener("mousemove",z)}(n)}return{onCreate:l,onDestroy:d,onBeforeUpdate:function(){a=e.props},onAfterUpdate:function(t,n){var i=n.followCursor;r||void 0!==i&&a.followCursor!==i&&(d(),i?(l(),!e.state.isMounted||o||s()||u()):(c(),p()))},onMount:function(){e.props.followCursor&&!o&&(i&&(f($),i=!1),s()||u())},onTrigger:function(e,t){m(t)&&($={clientX:t.clientX,clientY:t.clientY}),o="focus"===t.type},onHidden:function(){e.props.followCursor&&(p(),c(),i=!0)}}}};var G={name:"inlinePositioning",defaultValue:!1,fn:function(e){var t,n=e.reference;var r=-1,o=!1,i=[],a={name:"tippyInlinePositioning",enabled:!0,phase:"afterWrite",fn:function(o){var a=o.state;e.props.inlinePositioning&&(-1!==i.indexOf(a.placement)&&(i=[]),t!==a.placement&&-1===i.indexOf(a.placement)&&(i.push(a.placement),e.setProps({getReferenceClientRect:function(){return function(e){return function(e,t,n,r){if(n.length<2||null===e)return t;if(2===n.length&&r>=0&&n[0].left>n[1].right)return n[r]||t;switch(e){case"top":case"bottom":var o=n[0],i=n[n.length-1],a="top"===e,s=o.top,u=i.bottom,c=a?o.left:i.left,p=a?o.right:i.right;return{top:s,bottom:u,left:c,right:p,width:p-c,height:u-s};case"left":case"right":var f=Math.min.apply(Math,n.map((function(e){return e.left}))),l=Math.max.apply(Math,n.map((function(e){return e.right}))),d=n.filter((function(t){return"left"===e?t.left===f:t.right===l})),v=d[0].top,m=d[d.length-1].bottom;return{top:v,bottom:m,left:f,right:l,width:l-f,height:m-v};default:return t}}(p(e),n.getBoundingClientRect(),f(n.getClientRects()),r)}(a.placement)}})),t=a.placement)}};function s(){var t;o||(t=function(e,t){var n;return{popperOptions:Object.assign({},e.popperOptions,{modifiers:[].concat(((null==(n=e.popperOptions)?void 0:n.modifiers)||[]).filter((function(e){return e.name!==t.name})),[t])})}}(e.props,a),o=!0,e.setProps(t),o=!1)}return{onCreate:s,onAfterUpdate:s,onTrigger:function(t,n){if(m(n)){var o=f(e.reference.getClientRects()),i=o.find((function(e){return e.left-2<=n.clientX&&e.right+2>=n.clientX&&e.top-2<=n.clientY&&e.bottom+2>=n.clientY})),a=o.indexOf(i);r=a>-1?a:r}},onHidden:function(){r=-1}}}};var K={name:"sticky",defaultValue:!1,fn:function(e){var t=e.reference,n=e.popper;function r(t){return!0===e.props.sticky||e.props.sticky===t}var o=null,i=null;function a(){var s=r("reference")?(e.popperInstance?e.popperInstance.state.elements.reference:t).getBoundingClientRect():null,u=r("popper")?n.getBoundingClientRect():null;(s&&Q(o,s)||u&&Q(i,u))&&e.popperInstance&&e.popperInstance.update(),o=s,i=u,e.state.isMounted&&requestAnimationFrame(a)}return{onMount:function(){e.props.sticky&&a()}}}};function Q(e,t){return!e||!t||(e.top!==t.top||e.right!==t.right||e.bottom!==t.bottom||e.left!==t.left)}return F.setDefaultProps({plugins:[Y,J,G,K],render:N}),F.createSingleton=function(e,t){var n;void 0===t&&(t={});var r,o=e,i=[],a=[],c=t.overrides,p=[],f=!1;function l(){a=o.map((function(e){return u(e.props.triggerTarget||e.reference)})).reduce((function(e,t){return e.concat(t)}),[])}function v(){i=o.map((function(e){return e.reference}))}function m(e){o.forEach((function(t){e?t.enable():t.disable()}))}function g(e){return o.map((function(t){var n=t.setProps;return t.setProps=function(o){n(o),t.reference===r&&e.setProps(o)},function(){t.setProps=n}}))}function h(e,t){var n=a.indexOf(t);if(t!==r){r=t;var s=(c||[]).concat("content").reduce((function(e,t){return e[t]=o[n].props[t],e}),{});e.setProps(Object.assign({},s,{getReferenceClientRect:"function"==typeof s.getReferenceClientRect?s.getReferenceClientRect:function(){var e;return null==(e=i[n])?void 0:e.getBoundingClientRect()}}))}}m(!1),v(),l();var b={fn:function(){return{onDestroy:function(){m(!0)},onHidden:function(){r=null},onClickOutside:function(e){e.props.showOnCreate&&!f&&(f=!0,r=null)},onShow:function(e){e.props.showOnCreate&&!f&&(f=!0,h(e,i[0]))},onTrigger:function(e,t){h(e,t.currentTarget)}}}},y=F(d(),Object.assign({},s(t,["overrides"]),{plugins:[b].concat(t.plugins||[]),triggerTarget:a,popperOptions:Object.assign({},t.popperOptions,{modifiers:[].concat((null==(n=t.popperOptions)?void 0:n.modifiers)||[],[W])})})),w=y.show;y.show=function(e){if(w(),!r&&null==e)return h(y,i[0]);if(!r||null!=e){if("number"==typeof e)return i[e]&&h(y,i[e]);if(o.indexOf(e)>=0){var t=e.reference;return h(y,t)}return i.indexOf(e)>=0?h(y,e):void 0}},y.showNext=function(){var e=i[0];if(!r)return y.show(0);var t=i.indexOf(r);y.show(i[t+1]||e)},y.showPrevious=function(){var e=i[i.length-1];if(!r)return y.show(e);var t=i.indexOf(r),n=i[t-1]||e;y.show(n)};var E=y.setProps;return y.setProps=function(e){c=e.overrides||c,E(e)},y.setInstances=function(e){m(!0),p.forEach((function(e){return e()})),o=e,m(!1),v(),l(),p=g(y),y.setProps({triggerTarget:a})},p=g(y),y},F.delegate=function(e,n){var r=[],o=[],i=!1,a=n.target,c=s(n,["target"]),p=Object.assign({},c,{trigger:"manual",touch:!1}),f=Object.assign({touch:R.touch},c,{showOnCreate:!0}),l=F(e,p);function d(e){if(e.target&&!i){var t=e.target.closest(a);if(t){var r=t.getAttribute("data-tippy-trigger")||n.trigger||R.trigger;if(!t._tippy&&!("touchstart"===e.type&&"boolean"==typeof f.touch||"touchstart"!==e.type&&r.indexOf(X[e.type])<0)){var s=F(t,f);s&&(o=o.concat(s))}}}}function v(e,t,n,o){void 0===o&&(o=!1),e.addEventListener(t,n,o),r.push({node:e,eventType:t,handler:n,options:o})}return u(l).forEach((function(e){var n=e.destroy,a=e.enable,s=e.disable;e.destroy=function(e){void 0===e&&(e=!0),e&&o.forEach((function(e){e.destroy()})),o=[],r.forEach((function(e){var t=e.node,n=e.eventType,r=e.handler,o=e.options;t.removeEventListener(n,r,o)})),r=[],n()},e.enable=function(){a(),o.forEach((function(e){return e.enable()})),i=!1},e.disable=function(){s(),o.forEach((function(e){return e.disable()})),i=!0},function(e){var n=e.reference;v(n,"touchstart",d,t),v(n,"mouseover",d),v(n,"focusin",d),v(n,"click",d)}(e)})),l},F.hideAll=function(e){var t=void 0===e?{}:e,n=t.exclude,r=t.duration;U.forEach((function(e){var t=!1;if(n&&(t=g(n)?e.reference===n:e.popper===n.popper),!t){var o=e.props.duration;e.setProps({duration:r}),e.hide(),e.state.isDestroyed||e.setProps({duration:o})}}))},F.roundArrow='',F})); + diff --git a/_proc/_docs/site_libs/quarto-nav/headroom.min.js b/_proc/_docs/site_libs/quarto-nav/headroom.min.js new file mode 100644 index 0000000000000000000000000000000000000000..b08f1dffbbdae0ace4eb2510b43666c8491546d3 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-nav/headroom.min.js @@ -0,0 +1,7 @@ +/*! + * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it + * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js + * License: MIT + */ + +!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(t=t||self).Headroom=n()}(this,function(){"use strict";function t(){return"undefined"!=typeof window}function d(t){return function(t){return t&&t.document&&function(t){return 9===t.nodeType}(t.document)}(t)?function(t){var n=t.document,o=n.body,s=n.documentElement;return{scrollHeight:function(){return Math.max(o.scrollHeight,s.scrollHeight,o.offsetHeight,s.offsetHeight,o.clientHeight,s.clientHeight)},height:function(){return t.innerHeight||s.clientHeight||o.clientHeight},scrollY:function(){return void 0!==t.pageYOffset?t.pageYOffset:(s||o.parentNode||o).scrollTop}}}(t):function(t){return{scrollHeight:function(){return Math.max(t.scrollHeight,t.offsetHeight,t.clientHeight)},height:function(){return Math.max(t.offsetHeight,t.clientHeight)},scrollY:function(){return t.scrollTop}}}(t)}function n(t,s,e){var n,o=function(){var n=!1;try{var t={get passive(){n=!0}};window.addEventListener("test",t,t),window.removeEventListener("test",t,t)}catch(t){n=!1}return n}(),i=!1,r=d(t),l=r.scrollY(),a={};function c(){var t=Math.round(r.scrollY()),n=r.height(),o=r.scrollHeight();a.scrollY=t,a.lastScrollY=l,a.direction=ls.tolerance[a.direction],e(a),l=t,i=!1}function h(){i||(i=!0,n=requestAnimationFrame(c))}var u=!!o&&{passive:!0,capture:!1};return t.addEventListener("scroll",h,u),c(),{destroy:function(){cancelAnimationFrame(n),t.removeEventListener("scroll",h,u)}}}function o(t){return t===Object(t)?t:{down:t,up:t}}function s(t,n){n=n||{},Object.assign(this,s.options,n),this.classes=Object.assign({},s.options.classes,n.classes),this.elem=t,this.tolerance=o(this.tolerance),this.offset=o(this.offset),this.initialised=!1,this.frozen=!1}return s.prototype={constructor:s,init:function(){return s.cutsTheMustard&&!this.initialised&&(this.addClass("initial"),this.initialised=!0,setTimeout(function(t){t.scrollTracker=n(t.scroller,{offset:t.offset,tolerance:t.tolerance},t.update.bind(t))},100,this)),this},destroy:function(){this.initialised=!1,Object.keys(this.classes).forEach(this.removeClass,this),this.scrollTracker.destroy()},unpin:function(){!this.hasClass("pinned")&&this.hasClass("unpinned")||(this.addClass("unpinned"),this.removeClass("pinned"),this.onUnpin&&this.onUnpin.call(this))},pin:function(){this.hasClass("unpinned")&&(this.addClass("pinned"),this.removeClass("unpinned"),this.onPin&&this.onPin.call(this))},freeze:function(){this.frozen=!0,this.addClass("frozen")},unfreeze:function(){this.frozen=!1,this.removeClass("frozen")},top:function(){this.hasClass("top")||(this.addClass("top"),this.removeClass("notTop"),this.onTop&&this.onTop.call(this))},notTop:function(){this.hasClass("notTop")||(this.addClass("notTop"),this.removeClass("top"),this.onNotTop&&this.onNotTop.call(this))},bottom:function(){this.hasClass("bottom")||(this.addClass("bottom"),this.removeClass("notBottom"),this.onBottom&&this.onBottom.call(this))},notBottom:function(){this.hasClass("notBottom")||(this.addClass("notBottom"),this.removeClass("bottom"),this.onNotBottom&&this.onNotBottom.call(this))},shouldUnpin:function(t){return"down"===t.direction&&!t.top&&t.toleranceExceeded},shouldPin:function(t){return"up"===t.direction&&t.toleranceExceeded||t.top},addClass:function(t){this.elem.classList.add.apply(this.elem.classList,this.classes[t].split(" "))},removeClass:function(t){this.elem.classList.remove.apply(this.elem.classList,this.classes[t].split(" "))},hasClass:function(t){return this.classes[t].split(" ").every(function(t){return this.classList.contains(t)},this.elem)},update:function(t){t.isOutOfBounds||!0!==this.frozen&&(t.top?this.top():this.notTop(),t.bottom?this.bottom():this.notBottom(),this.shouldUnpin(t)?this.unpin():this.shouldPin(t)&&this.pin())}},s.options={tolerance:{up:0,down:0},offset:0,scroller:t()?window:null,classes:{frozen:"headroom--frozen",pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",bottom:"headroom--bottom",notBottom:"headroom--not-bottom",initial:"headroom"}},s.cutsTheMustard=!!(t()&&function(){}.bind&&"classList"in document.documentElement&&Object.assign&&Object.keys&&requestAnimationFrame),s}); diff --git a/_proc/_docs/site_libs/quarto-nav/quarto-nav.js b/_proc/_docs/site_libs/quarto-nav/quarto-nav.js new file mode 100644 index 0000000000000000000000000000000000000000..3b21201f9537ba017353711b4a310936d9569945 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-nav/quarto-nav.js @@ -0,0 +1,277 @@ +const headroomChanged = new CustomEvent("quarto-hrChanged", { + detail: {}, + bubbles: true, + cancelable: false, + composed: false, +}); + +window.document.addEventListener("DOMContentLoaded", function () { + let init = false; + + // Manage the back to top button, if one is present. + let lastScrollTop = window.pageYOffset || document.documentElement.scrollTop; + const scrollDownBuffer = 5; + const scrollUpBuffer = 35; + const btn = document.getElementById("quarto-back-to-top"); + const hideBackToTop = () => { + btn.style.display = "none"; + }; + const showBackToTop = () => { + btn.style.display = "inline-block"; + }; + if (btn) { + window.document.addEventListener( + "scroll", + function () { + const currentScrollTop = + window.pageYOffset || document.documentElement.scrollTop; + + // Shows and hides the button 'intelligently' as the user scrolls + if (currentScrollTop - scrollDownBuffer > lastScrollTop) { + hideBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } else if (currentScrollTop < lastScrollTop - scrollUpBuffer) { + showBackToTop(); + lastScrollTop = currentScrollTop <= 0 ? 0 : currentScrollTop; + } + + // Show the button at the bottom, hides it at the top + if (currentScrollTop <= 0) { + hideBackToTop(); + } else if ( + window.innerHeight + currentScrollTop >= + document.body.offsetHeight + ) { + showBackToTop(); + } + }, + false + ); + } + + function throttle(func, wait) { + var timeout; + return function () { + const context = this; + const args = arguments; + const later = function () { + clearTimeout(timeout); + timeout = null; + func.apply(context, args); + }; + + if (!timeout) { + timeout = setTimeout(later, wait); + } + }; + } + + function headerOffset() { + // Set an offset if there is are fixed top navbar + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl) { + return headerEl.clientHeight; + } else { + return 0; + } + } + + function footerOffset() { + const footerEl = window.document.querySelector("footer.footer"); + if (footerEl) { + return footerEl.clientHeight; + } else { + return 0; + } + } + + function updateDocumentOffsetWithoutAnimation() { + updateDocumentOffset(false); + } + + function updateDocumentOffset(animated) { + // set body offset + const topOffset = headerOffset(); + const bodyOffset = topOffset + footerOffset(); + const bodyEl = window.document.body; + bodyEl.setAttribute("data-bs-offset", topOffset); + bodyEl.style.paddingTop = topOffset + "px"; + + // deal with sidebar offsets + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + if (!animated) { + sidebar.classList.add("notransition"); + // Remove the no transition class after the animation has time to complete + setTimeout(function () { + sidebar.classList.remove("notransition"); + }, 201); + } + + if (window.Headroom && sidebar.classList.contains("sidebar-unpinned")) { + sidebar.style.top = "0"; + sidebar.style.maxHeight = "100vh"; + } else { + sidebar.style.top = topOffset + "px"; + sidebar.style.maxHeight = "calc(100vh - " + topOffset + "px)"; + } + }); + + // allow space for footer + const mainContainer = window.document.querySelector(".quarto-container"); + if (mainContainer) { + mainContainer.style.minHeight = "calc(100vh - " + bodyOffset + "px)"; + } + + // link offset + let linkStyle = window.document.querySelector("#quarto-target-style"); + if (!linkStyle) { + linkStyle = window.document.createElement("style"); + linkStyle.setAttribute("id", "quarto-target-style"); + window.document.head.appendChild(linkStyle); + } + while (linkStyle.firstChild) { + linkStyle.removeChild(linkStyle.firstChild); + } + if (topOffset > 0) { + linkStyle.appendChild( + window.document.createTextNode(` + section:target::before { + content: ""; + display: block; + height: ${topOffset}px; + margin: -${topOffset}px 0 0; + }`) + ); + } + if (init) { + window.dispatchEvent(headroomChanged); + } + init = true; + } + + // initialize headroom + var header = window.document.querySelector("#quarto-header"); + if (header && window.Headroom) { + const headroom = new window.Headroom(header, { + tolerance: 5, + onPin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.remove("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + onUnpin: function () { + const sidebars = window.document.querySelectorAll( + ".sidebar, .headroom-target" + ); + sidebars.forEach((sidebar) => { + sidebar.classList.add("sidebar-unpinned"); + }); + updateDocumentOffset(); + }, + }); + headroom.init(); + + let frozen = false; + window.quartoToggleHeadroom = function () { + if (frozen) { + headroom.unfreeze(); + frozen = false; + } else { + headroom.freeze(); + frozen = true; + } + }; + } + + window.addEventListener( + "hashchange", + function (e) { + if ( + getComputedStyle(document.documentElement).scrollBehavior !== "smooth" + ) { + window.scrollTo(0, window.pageYOffset - headerOffset()); + } + }, + false + ); + + // Observe size changed for the header + const headerEl = window.document.querySelector("header.fixed-top"); + if (headerEl && window.ResizeObserver) { + const observer = new window.ResizeObserver( + updateDocumentOffsetWithoutAnimation + ); + observer.observe(headerEl, { + attributes: true, + childList: true, + characterData: true, + }); + } else { + window.addEventListener( + "resize", + throttle(updateDocumentOffsetWithoutAnimation, 50) + ); + } + setTimeout(updateDocumentOffsetWithoutAnimation, 250); + + // fixup index.html links if we aren't on the filesystem + if (window.location.protocol !== "file:") { + const links = window.document.querySelectorAll("a"); + for (let i = 0; i < links.length; i++) { + if (links[i].href) { + links[i].href = links[i].href.replace(/\/index\.html/, "/"); + } + } + + // Fixup any sharing links that require urls + // Append url to any sharing urls + const sharingLinks = window.document.querySelectorAll( + "a.sidebar-tools-main-item" + ); + for (let i = 0; i < sharingLinks.length; i++) { + const sharingLink = sharingLinks[i]; + const href = sharingLink.getAttribute("href"); + if (href) { + sharingLink.setAttribute( + "href", + href.replace("|url|", window.location.href) + ); + } + } + + // Scroll the active navigation item into view, if necessary + const navSidebar = window.document.querySelector("nav#quarto-sidebar"); + if (navSidebar) { + // Find the active item + const activeItem = navSidebar.querySelector("li.sidebar-item a.active"); + if (activeItem) { + // Wait for the scroll height and height to resolve by observing size changes on the + // nav element that is scrollable + const resizeObserver = new ResizeObserver((_entries) => { + // The bottom of the element + const elBottom = activeItem.offsetTop; + const viewBottom = navSidebar.scrollTop + navSidebar.clientHeight; + + // The element height and scroll height are the same, then we are still loading + if (viewBottom !== navSidebar.scrollHeight) { + // Determine if the item isn't visible and scroll to it + if (elBottom >= viewBottom) { + navSidebar.scrollTop = elBottom; + } + + // stop observing now since we've completed the scroll + resizeObserver.unobserve(navSidebar); + } + }); + resizeObserver.observe(navSidebar); + } + } + } +}); diff --git a/_proc/_docs/site_libs/quarto-search/autocomplete.umd.js b/_proc/_docs/site_libs/quarto-search/autocomplete.umd.js new file mode 100644 index 0000000000000000000000000000000000000000..619c57cc5c8b59d94aa0f39f8f70639f0d9ac691 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-search/autocomplete.umd.js @@ -0,0 +1,3 @@ +/*! @algolia/autocomplete-js 1.7.3 | MIT License | © Algolia, Inc. and contributors | https://github.com/algolia/autocomplete */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self)["@algolia/autocomplete-js"]={})}(this,(function(e){"use strict";function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(e){for(var n=1;n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function a(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,o,i=[],u=!0,a=!1;try{for(n=n.call(e);!(u=(r=n.next()).done)&&(i.push(r.value),!t||i.length!==t);u=!0);}catch(e){a=!0,o=e}finally{try{u||null==n.return||n.return()}finally{if(a)throw o}}return i}(e,t)||l(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function c(e){return function(e){if(Array.isArray(e))return s(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||l(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(e,t){if(e){if("string"==typeof e)return s(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?s(e,t):void 0}}function s(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=n?null===r?null:0:o}function S(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function I(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function E(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t=function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var ae,ce,le,se=null,pe=(ae=-1,ce=-1,le=void 0,function(e){var t=++ae;return Promise.resolve(e).then((function(e){return le&&t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var ye=["props","refresh","store"],be=["inputElement","formElement","panelElement"],Oe=["inputElement"],_e=["inputElement","maxLength"],Pe=["item","source"];function je(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function we(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function Ee(e){var t=e.props,n=e.refresh,r=e.store,o=Ie(e,ye);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,i=e.panelElement;function u(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,i].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return we({onTouchStart:u,onMouseDown:u,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},Ie(e,be))},getRootProps:function(e){return we({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label")},e)},getFormProps:function(e){return e.inputElement,we({action:"",noValidate:!0,role:"search",onSubmit:function(i){var u;i.preventDefault(),t.onSubmit(we({event:i,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(u=e.inputElement)||void 0===u||u.blur()},onReset:function(i){var u;i.preventDefault(),t.onReset(we({event:i,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(u=e.inputElement)||void 0===u||u.focus()}},Ie(e,Oe))},getLabelProps:function(e){return we({htmlFor:"".concat(t.id,"-input"),id:"".concat(t.id,"-label")},e)},getInputProps:function(e){var i;function u(e){(t.openOnFocus||Boolean(r.getState().query))&&fe(we({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var a=e||{};a.inputElement;var c=a.maxLength,l=void 0===c?512:c,s=Ie(a,_e),p=A(r.getState()),f=function(e){return Boolean(e&&e.match(C))}((null===(i=t.environment.navigator)||void 0===i?void 0:i.userAgent)||""),d=null!=p&&p.itemUrl&&!f?"go":"search";return we({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?"".concat(t.id,"-item-").concat(r.getState().activeItemId):void 0,"aria-controls":r.getState().isOpen?"".concat(t.id,"-list"):void 0,"aria-labelledby":"".concat(t.id,"-label"),value:r.getState().completion||r.getState().query,id:"".concat(t.id,"-input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:d,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:l,type:"search",onChange:function(e){fe(we({event:e,props:t,query:e.currentTarget.value.slice(0,l),refresh:n,store:r},o))},onKeyDown:function(e){!function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,i=ge(e,de);if("ArrowUp"===t.key||"ArrowDown"===t.key){var u=function(){var e=n.environment.document.getElementById("".concat(n.id,"-item-").concat(o.getState().activeItemId));e&&(e.scrollIntoViewIfNeeded?e.scrollIntoViewIfNeeded(!1):e.scrollIntoView(!1))},a=function(){var e=A(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,u=e.itemInputValue,a=e.itemUrl,c=e.source;c.onActive(ve({event:t,item:n,itemInputValue:u,itemUrl:a,refresh:r,source:c,state:o.getState()},i))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?fe(ve({event:t,props:n,query:o.getState().query,refresh:r,store:o},i)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),a(),setTimeout(u,0)})):(o.dispatch(t.key,{}),a(),u())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var c=A(o.getState()),l=c.item,s=c.itemInputValue,p=c.itemUrl,f=c.source;if(t.metaKey||t.ctrlKey)void 0!==p&&(f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewTab({itemUrl:p,item:l,state:o.getState()}));else if(t.shiftKey)void 0!==p&&(f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),n.navigator.navigateNewWindow({itemUrl:p,item:l,state:o.getState()}));else if(t.altKey);else{if(void 0!==p)return f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i)),void n.navigator.navigate({itemUrl:p,item:l,state:o.getState()});fe(ve({event:t,nextState:{isOpen:!1},props:n,query:s,refresh:r,store:o},i)).then((function(){f.onSelect(ve({event:t,item:l,itemInputValue:s,itemUrl:p,refresh:r,source:f,state:o.getState()},i))}))}}}(we({event:e,props:t,refresh:n,store:r},o))},onFocus:u,onBlur:y,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||u(n)}},s)},getPanelProps:function(e){return we({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){return we({role:"listbox","aria-labelledby":"".concat(t.id,"-label"),id:"".concat(t.id,"-list")},e)},getItemProps:function(e){var i=e.item,u=e.source,a=Ie(e,Pe);return we({id:"".concat(t.id,"-item-").concat(i.__autocomplete_id),role:"option","aria-selected":r.getState().activeItemId===i.__autocomplete_id,onMouseMove:function(e){if(i.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",i.__autocomplete_id);var t=A(r.getState());if(null!==r.getState().activeItemId&&t){var u=t.item,a=t.itemInputValue,c=t.itemUrl,l=t.source;l.onActive(we({event:e,item:u,itemInputValue:a,itemUrl:c,refresh:n,source:l,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var a=u.getItemInputValue({item:i,state:r.getState()}),c=u.getItemUrl({item:i,state:r.getState()});(c?Promise.resolve():fe(we({event:e,nextState:{isOpen:!1},props:t,query:a,refresh:n,store:r},o))).then((function(){u.onSelect(we({event:e,item:i,itemInputValue:a,itemUrl:c,refresh:n,source:u,state:r.getState()},o))}))}},a)}}}function Ae(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ce(e){for(var t=1;t0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:v(),plugins:o,initialState:H({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(F(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return E(e,n)}))).then((function(e){return d(e)})).then((function(e){return e.map((function(e){return H(H({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:H({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}(e,t),r=R(Te,n,(function(e){var t=e.prevState,r=e.state;n.onStateChange(Be({prevState:t,state:r,refresh:u},o))})),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var n=0,r=e.map((function(e){return L(L({},e),{},{items:d(e.items).map((function(e){return L(L({},e),{},{__autocomplete_id:n++})}))})}));t.dispatch("setCollections",r)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:r}),i=Ee(Be({props:n,refresh:u,store:r},o));function u(){return fe(Be({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,query:r.getState().query,refresh:u,store:r},o))}return n.plugins.forEach((function(e){var n;return null===(n=e.subscribe)||void 0===n?void 0:n.call(e,Be(Be({},o),{},{refresh:u,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})}}))})),function(e){var t,n,r=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(n=t.userAgent)||void 0===n?void 0:n.includes("Algolia Crawler")){var i=o.document.createElement("meta"),u=o.document.querySelector("head");i.name="algolia:metadata",setTimeout((function(){i.content=JSON.stringify(r),u.appendChild(i)}),0)}}({metadata:ke({plugins:n.plugins,options:e}),environment:n.environment}),Be(Be({refresh:u},i),o)}var Ue=function(e,t,n,r){var o;t[0]=0;for(var i=1;i=5&&((o||!e&&5===r)&&(u.push(r,0,o,n),r=6),e&&(u.push(r,e,0,n),r=6)),o=""},c=0;c"===t?(r=1,o=""):o=t+o[0]:i?t===i?i="":o+=t:'"'===t||"'"===t?i=t:">"===t?(a(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[c][l+1])?(a(),3===r&&(u=u[0]),r=u,(u=u[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(a(),r=2):o+=t),3===r&&"!--"===o&&(r=4,u=u[0])}return a(),u}(e)),t),arguments,[])).length>1?t:t[0]}var We=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n};function Qe(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function $e(){for(var e=arguments.length,t=new Array(e),n=0;n2&&(u.children=arguments.length>3?lt.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(i in e.defaultProps)void 0===u[i]&&(u[i]=e.defaultProps[i]);return _t(e,u,r,o,null)}function _t(e,t,n,r,o){var i={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==o?++pt:o};return null==o&&null!=st.vnode&&st.vnode(i),i}function Pt(e){return e.children}function jt(e,t){this.props=e,this.context=t}function wt(e,t){if(null==t)return e.__?wt(e.__,e.__.__k.indexOf(e)+1):null;for(var n;t0?_t(d.type,d.props,d.key,null,d.__v):d)){if(d.__=n,d.__b=n.__b+1,null===(f=g[s])||f&&d.key==f.key&&d.type===f.type)g[s]=void 0;else for(p=0;p0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(Ht);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function Wt(e){return function(e){if(Array.isArray(e))return Qt(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Qt(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Qt(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Qt(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n",""":'"',"'":"'"},Gt=new RegExp(/\w/i),Kt=/&(amp|quot|lt|gt|#39);/g,Jt=RegExp(Kt.source);function Yt(e,t){var n,r,o,i=e[t],u=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,a=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return Gt.test((o=i.value)&&Jt.test(o)?o.replace(Kt,(function(e){return zt[e]})):o)||a!==u?i.isHighlighted:a}function Xt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Zt(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function mn(e){return function(e){if(Array.isArray(e))return vn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return vn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return vn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function vn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n0;if(!O.value.core.openOnFocus&&!t.query)return n;var r=Boolean(h.current||O.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:Sn,options:e}}))})),j=p(n({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},O.value.core.initialState)),w={getEnvironmentProps:O.value.renderer.getEnvironmentProps,getFormProps:O.value.renderer.getFormProps,getInputProps:O.value.renderer.getInputProps,getItemProps:O.value.renderer.getItemProps,getLabelProps:O.value.renderer.getLabelProps,getListProps:O.value.renderer.getListProps,getPanelProps:O.value.renderer.getPanelProps,getRootProps:O.value.renderer.getRootProps},S={setActiveItemId:P.value.setActiveItemId,setQuery:P.value.setQuery,setCollections:P.value.setCollections,setIsOpen:P.value.setIsOpen,setStatus:P.value.setStatus,setContext:P.value.setContext,refresh:P.value.refresh},I=d((function(){return Ve.bind(O.value.renderer.renderer.createElement)})),E=d((function(){return ct({autocomplete:P.value,autocompleteScopeApi:S,classNames:O.value.renderer.classNames,environment:O.value.core.environment,isDetached:_.value,placeholder:O.value.core.placeholder,propGetters:w,setIsModalOpen:k,state:j.current,translations:O.value.renderer.translations})}));function A(){tt(E.value.panel,{style:_.value?{}:wn({panelPlacement:O.value.renderer.panelPlacement,container:E.value.root,form:E.value.form,environment:O.value.core.environment})})}function C(e){j.current=e;var t={autocomplete:P.value,autocompleteScopeApi:S,classNames:O.value.renderer.classNames,components:O.value.renderer.components,container:O.value.renderer.container,html:I.value,dom:E.value,panelContainer:_.value?E.value.detachedContainer:O.value.renderer.panelContainer,propGetters:w,state:j.current,renderer:O.value.renderer.renderer},r=!g(e)&&!h.current&&O.value.renderer.renderNoResults||O.value.renderer.render;!function(e){var t=e.autocomplete,r=e.autocompleteScopeApi,o=e.dom,i=e.propGetters,u=e.state;nt(o.root,i.getRootProps(n({state:u,props:t.getRootProps({})},r))),nt(o.input,i.getInputProps(n({state:u,props:t.getInputProps({inputElement:o.input}),inputElement:o.input},r))),tt(o.label,{hidden:"stalled"===u.status}),tt(o.loadingIndicator,{hidden:"stalled"!==u.status}),tt(o.clearButton,{hidden:!u.query})}(t),function(e,t){var r=t.autocomplete,o=t.autocompleteScopeApi,u=t.classNames,a=t.html,c=t.dom,l=t.panelContainer,s=t.propGetters,p=t.state,f=t.components,d=t.renderer;if(p.isOpen){l.contains(c.panel)||"loading"===p.status||l.appendChild(c.panel),c.panel.classList.toggle("aa-Panel--stalled","stalled"===p.status);var m=p.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var c=e.source,l=e.items;return d.createElement("section",{key:t,className:u.source,"data-autocomplete-source-id":c.sourceId},c.templates.header&&d.createElement("div",{className:u.sourceHeader},c.templates.header({components:f,createElement:d.createElement,Fragment:d.Fragment,items:l,source:c,state:p,html:a})),c.templates.noResults&&0===l.length?d.createElement("div",{className:u.sourceNoResults},c.templates.noResults({components:f,createElement:d.createElement,Fragment:d.Fragment,source:c,state:p,html:a})):d.createElement("ul",i({className:u.list},s.getListProps(n({state:p,props:r.getListProps({})},o))),l.map((function(e){var t=r.getItemProps({item:e,source:c});return d.createElement("li",i({key:t.id,className:u.item},s.getItemProps(n({state:p,props:t},o))),c.templates.item({components:f,createElement:d.createElement,Fragment:d.Fragment,item:e,state:p,html:a}))}))),c.templates.footer&&d.createElement("div",{className:u.sourceFooter},c.templates.footer({components:f,createElement:d.createElement,Fragment:d.Fragment,items:l,source:c,state:p,html:a})))})),v=d.createElement(d.Fragment,null,d.createElement("div",{className:u.panelLayout},m),d.createElement("div",{className:"aa-GradientBottom"})),h=m.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(n(n({children:v,state:p,sections:m,elements:h},d),{},{components:f,html:a},o),c.panel)}else l.contains(c.panel)&&l.removeChild(c.panel)}(r,t)}function D(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};c();var t=O.value.renderer,n=t.components,r=u(t,In);y.current=Ge(r,O.value.core,{components:Ke(n,(function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")})),initialState:j.current},e),m(),l(),P.value.refresh().then((function(){C(j.current)}))}function k(e){requestAnimationFrame((function(){var t=O.value.core.environment.document.body.contains(E.value.detachedOverlay);e!==t&&(e?(O.value.core.environment.document.body.appendChild(E.value.detachedOverlay),O.value.core.environment.document.body.classList.add("aa-Detached"),E.value.input.focus()):(O.value.core.environment.document.body.removeChild(E.value.detachedOverlay),O.value.core.environment.document.body.classList.remove("aa-Detached"),P.value.setQuery(""),P.value.refresh()))}))}return a((function(){var e=P.value.getEnvironmentProps({formElement:E.value.form,panelElement:E.value.panel,inputElement:E.value.input});return tt(O.value.core.environment,e),function(){tt(O.value.core.environment,Object.keys(e).reduce((function(e,t){return n(n({},e),{},o({},t,void 0))}),{}))}})),a((function(){var e=_.value?O.value.core.environment.document.body:O.value.renderer.panelContainer,t=_.value?E.value.detachedOverlay:E.value.panel;return _.value&&j.current.isOpen&&k(!0),C(j.current),function(){e.contains(t)&&e.removeChild(t)}})),a((function(){var e=O.value.renderer.container;return e.appendChild(E.value.root),function(){e.removeChild(E.value.root)}})),a((function(){var e=f((function(e){C(e.state)}),0);return b.current=function(t){var n=t.state,r=t.prevState;(_.value&&r.isOpen!==n.isOpen&&k(n.isOpen),_.value||!n.isOpen||r.isOpen||A(),n.query!==r.query)&&O.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){b.current=void 0}})),a((function(){var e=f((function(){var e=_.value;_.value=O.value.core.environment.matchMedia(O.value.renderer.detachedMediaQuery).matches,e!==_.value?D({}):requestAnimationFrame(A)}),20);return O.value.core.environment.addEventListener("resize",e),function(){O.value.core.environment.removeEventListener("resize",e)}})),a((function(){if(!_.value)return function(){};function e(e){E.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=O.value.core.environment.matchMedia(getComputedStyle(O.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),a((function(){return requestAnimationFrame(A),function(){}})),n(n({},S),{},{update:D,destroy:function(){c()}})},e.getAlgoliaFacets=function(e){var t=En({transformResponse:function(e){return e.facetHits}}),r=e.queries.map((function(e){return n(n({},e),{},{type:"facet"})}));return t(n(n({},e),{},{queries:r}))},e.getAlgoliaResults=An,Object.defineProperty(e,"__esModule",{value:!0})})); + diff --git a/_proc/_docs/site_libs/quarto-search/fuse.min.js b/_proc/_docs/site_libs/quarto-search/fuse.min.js new file mode 100644 index 0000000000000000000000000000000000000000..adc28356e2f591038d4e691cb5b418d7a490bfb1 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-search/fuse.min.js @@ -0,0 +1,9 @@ +/** + * Fuse.js v6.6.2 - Lightweight fuzzy-search (http://fusejs.io) + * + * Copyright (c) 2022 Kiro Risk (http://kiro.me) + * All Rights Reserved. Apache Software License 2.0 + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var e,t;e=this,t=function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var n=1;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n0&&void 0!==arguments[0]?arguments[0]:1,t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:3,n=new Map,r=Math.pow(10,t);return{get:function(t){var i=t.match(C).length;if(n.has(i))return n.get(i);var o=1/Math.pow(i,.5*e),c=parseFloat(Math.round(o*r)/r);return n.set(i,c),c},clear:function(){n.clear()}}}var $=function(){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.getFn,i=void 0===n?I.getFn:n,o=t.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o;r(this,e),this.norm=E(c,3),this.getFn=i,this.isCreated=!1,this.setIndexRecords()}return o(e,[{key:"setSources",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.docs=e}},{key:"setIndexRecords",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.records=e}},{key:"setKeys",value:function(){var e=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.keys=t,this._keysMap={},t.forEach((function(t,n){e._keysMap[t.id]=n}))}},{key:"create",value:function(){var e=this;!this.isCreated&&this.docs.length&&(this.isCreated=!0,g(this.docs[0])?this.docs.forEach((function(t,n){e._addString(t,n)})):this.docs.forEach((function(t,n){e._addObject(t,n)})),this.norm.clear())}},{key:"add",value:function(e){var t=this.size();g(e)?this._addString(e,t):this._addObject(e,t)}},{key:"removeAt",value:function(e){this.records.splice(e,1);for(var t=e,n=this.size();t2&&void 0!==arguments[2]?arguments[2]:{},r=n.getFn,i=void 0===r?I.getFn:r,o=n.fieldNormWeight,c=void 0===o?I.fieldNormWeight:o,a=new $({getFn:i,fieldNormWeight:c});return a.setKeys(e.map(_)),a.setSources(t),a.create(),a}function R(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.errors,r=void 0===n?0:n,i=t.currentLocation,o=void 0===i?0:i,c=t.expectedLocation,a=void 0===c?0:c,s=t.distance,u=void 0===s?I.distance:s,h=t.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=r/e.length;if(l)return f;var d=Math.abs(a-o);return u?f+d/u:d?1:f}function N(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:I.minMatchCharLength,n=[],r=-1,i=-1,o=0,c=e.length;o=t&&n.push([r,i]),r=-1)}return e[o-1]&&o-r>=t&&n.push([r,o-1]),n}var P=32;function W(e){for(var t={},n=0,r=e.length;n1&&void 0!==arguments[1]?arguments[1]:{},o=i.location,c=void 0===o?I.location:o,a=i.threshold,s=void 0===a?I.threshold:a,u=i.distance,h=void 0===u?I.distance:u,l=i.includeMatches,f=void 0===l?I.includeMatches:l,d=i.findAllMatches,v=void 0===d?I.findAllMatches:d,g=i.minMatchCharLength,y=void 0===g?I.minMatchCharLength:g,p=i.isCaseSensitive,m=void 0===p?I.isCaseSensitive:p,k=i.ignoreLocation,M=void 0===k?I.ignoreLocation:k;if(r(this,e),this.options={location:c,threshold:s,distance:h,includeMatches:f,findAllMatches:v,minMatchCharLength:y,isCaseSensitive:m,ignoreLocation:M},this.pattern=m?t:t.toLowerCase(),this.chunks=[],this.pattern.length){var b=function(e,t){n.chunks.push({pattern:e,alphabet:W(e),startIndex:t})},x=this.pattern.length;if(x>P){for(var w=0,L=x%P,S=x-L;w3&&void 0!==arguments[3]?arguments[3]:{},i=r.location,o=void 0===i?I.location:i,c=r.distance,a=void 0===c?I.distance:c,s=r.threshold,u=void 0===s?I.threshold:s,h=r.findAllMatches,l=void 0===h?I.findAllMatches:h,f=r.minMatchCharLength,d=void 0===f?I.minMatchCharLength:f,v=r.includeMatches,g=void 0===v?I.includeMatches:v,y=r.ignoreLocation,p=void 0===y?I.ignoreLocation:y;if(t.length>P)throw new Error(w(P));for(var m,k=t.length,M=e.length,b=Math.max(0,Math.min(o,M)),x=u,L=b,S=d>1||g,_=S?Array(M):[];(m=e.indexOf(t,L))>-1;){var O=R(t,{currentLocation:m,expectedLocation:b,distance:a,ignoreLocation:p});if(x=Math.min(O,x),L=m+k,S)for(var j=0;j=z;q-=1){var B=q-1,J=n[e.charAt(B)];if(S&&(_[B]=+!!J),K[q]=(K[q+1]<<1|1)&J,F&&(K[q]|=(A[q+1]|A[q])<<1|1|A[q+1]),K[q]&$&&(C=R(t,{errors:F,currentLocation:B,expectedLocation:b,distance:a,ignoreLocation:p}))<=x){if(x=C,(L=B)<=b)break;z=Math.max(1,2*b-L)}}if(R(t,{errors:F+1,currentLocation:b,expectedLocation:b,distance:a,ignoreLocation:p})>x)break;A=K}var U={isMatch:L>=0,score:Math.max(.001,C)};if(S){var V=N(_,d);V.length?g&&(U.indices=V):U.isMatch=!1}return U}(e,n,i,{location:c+o,distance:a,threshold:s,findAllMatches:u,minMatchCharLength:h,includeMatches:r,ignoreLocation:l}),p=y.isMatch,m=y.score,k=y.indices;p&&(g=!0),v+=m,p&&k&&(d=[].concat(f(d),f(k)))}));var y={isMatch:g,score:g?v/this.chunks.length:1};return g&&r&&(y.indices=d),y}}]),e}(),z=function(){function e(t){r(this,e),this.pattern=t}return o(e,[{key:"search",value:function(){}}],[{key:"isMultiMatch",value:function(e){return D(e,this.multiRegex)}},{key:"isSingleMatch",value:function(e){return D(e,this.singleRegex)}}]),e}();function D(e,t){var n=e.match(t);return n?n[1]:null}var K=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e===this.pattern;return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"exact"}},{key:"multiRegex",get:function(){return/^="(.*)"$/}},{key:"singleRegex",get:function(){return/^=(.*)$/}}]),n}(z),q=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=-1===e.indexOf(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"$/}},{key:"singleRegex",get:function(){return/^!(.*)$/}}]),n}(z),B=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,this.pattern.length-1]}}}],[{key:"type",get:function(){return"prefix-exact"}},{key:"multiRegex",get:function(){return/^\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^\^(.*)$/}}]),n}(z),J=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.startsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-prefix-exact"}},{key:"multiRegex",get:function(){return/^!\^"(.*)"$/}},{key:"singleRegex",get:function(){return/^!\^(.*)$/}}]),n}(z),U=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[e.length-this.pattern.length,e.length-1]}}}],[{key:"type",get:function(){return"suffix-exact"}},{key:"multiRegex",get:function(){return/^"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^(.*)\$$/}}]),n}(z),V=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){var t=!e.endsWith(this.pattern);return{isMatch:t,score:t?0:1,indices:[0,e.length-1]}}}],[{key:"type",get:function(){return"inverse-suffix-exact"}},{key:"multiRegex",get:function(){return/^!"(.*)"\$$/}},{key:"singleRegex",get:function(){return/^!(.*)\$$/}}]),n}(z),G=function(e){a(n,e);var t=l(n);function n(e){var i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},c=o.location,a=void 0===c?I.location:c,s=o.threshold,u=void 0===s?I.threshold:s,h=o.distance,l=void 0===h?I.distance:h,f=o.includeMatches,d=void 0===f?I.includeMatches:f,v=o.findAllMatches,g=void 0===v?I.findAllMatches:v,y=o.minMatchCharLength,p=void 0===y?I.minMatchCharLength:y,m=o.isCaseSensitive,k=void 0===m?I.isCaseSensitive:m,M=o.ignoreLocation,b=void 0===M?I.ignoreLocation:M;return r(this,n),(i=t.call(this,e))._bitapSearch=new T(e,{location:a,threshold:u,distance:l,includeMatches:d,findAllMatches:g,minMatchCharLength:p,isCaseSensitive:k,ignoreLocation:b}),i}return o(n,[{key:"search",value:function(e){return this._bitapSearch.searchIn(e)}}],[{key:"type",get:function(){return"fuzzy"}},{key:"multiRegex",get:function(){return/^"(.*)"$/}},{key:"singleRegex",get:function(){return/^(.*)$/}}]),n}(z),H=function(e){a(n,e);var t=l(n);function n(e){return r(this,n),t.call(this,e)}return o(n,[{key:"search",value:function(e){for(var t,n=0,r=[],i=this.pattern.length;(t=e.indexOf(this.pattern,n))>-1;)n=t+i,r.push([t,n-1]);var o=!!r.length;return{isMatch:o,score:o?0:1,indices:r}}}],[{key:"type",get:function(){return"include"}},{key:"multiRegex",get:function(){return/^'"(.*)"$/}},{key:"singleRegex",get:function(){return/^'(.*)$/}}]),n}(z),Q=[K,H,B,J,V,U,q,G],X=Q.length,Y=/ +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/;function Z(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return e.split("|").map((function(e){for(var n=e.trim().split(Y).filter((function(e){return e&&!!e.trim()})),r=[],i=0,o=n.length;i1&&void 0!==arguments[1]?arguments[1]:{},i=n.isCaseSensitive,o=void 0===i?I.isCaseSensitive:i,c=n.includeMatches,a=void 0===c?I.includeMatches:c,s=n.minMatchCharLength,u=void 0===s?I.minMatchCharLength:s,h=n.ignoreLocation,l=void 0===h?I.ignoreLocation:h,f=n.findAllMatches,d=void 0===f?I.findAllMatches:f,v=n.location,g=void 0===v?I.location:v,y=n.threshold,p=void 0===y?I.threshold:y,m=n.distance,k=void 0===m?I.distance:m;r(this,e),this.query=null,this.options={isCaseSensitive:o,includeMatches:a,minMatchCharLength:u,findAllMatches:d,ignoreLocation:l,location:g,threshold:p,distance:k},this.pattern=o?t:t.toLowerCase(),this.query=Z(this.pattern,this.options)}return o(e,[{key:"searchIn",value:function(e){var t=this.query;if(!t)return{isMatch:!1,score:1};var n=this.options,r=n.includeMatches;e=n.isCaseSensitive?e:e.toLowerCase();for(var i=0,o=[],c=0,a=0,s=t.length;a-1&&(n.refIndex=e.idx),t.matches.push(n)}}))}function ve(e,t){t.score=e.score}function ge(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.includeMatches,i=void 0===r?I.includeMatches:r,o=n.includeScore,c=void 0===o?I.includeScore:o,a=[];return i&&a.push(de),c&&a.push(ve),e.map((function(e){var n=e.idx,r={item:t[n],refIndex:n};return a.length&&a.forEach((function(t){t(e,r)})),r}))}var ye=function(){function e(n){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},o=arguments.length>2?arguments[2]:void 0;r(this,e),this.options=t(t({},I),i),this.options.useExtendedSearch,this._keyStore=new S(this.options.keys),this.setCollection(n,o)}return o(e,[{key:"setCollection",value:function(e,t){if(this._docs=e,t&&!(t instanceof $))throw new Error("Incorrect 'index' type");this._myIndex=t||F(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight})}},{key:"add",value:function(e){k(e)&&(this._docs.push(e),this._myIndex.add(e))}},{key:"remove",value:function(){for(var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!1},t=[],n=0,r=this._docs.length;n1&&void 0!==arguments[1]?arguments[1]:{},n=t.limit,r=void 0===n?-1:n,i=this.options,o=i.includeMatches,c=i.includeScore,a=i.shouldSort,s=i.sortFn,u=i.ignoreFieldNorm,h=g(e)?g(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e);return fe(h,{ignoreFieldNorm:u}),a&&h.sort(s),y(r)&&r>-1&&(h=h.slice(0,r)),ge(h,this._docs,{includeMatches:o,includeScore:c})}},{key:"_searchStringList",value:function(e){var t=re(e,this.options),n=this._myIndex.records,r=[];return n.forEach((function(e){var n=e.v,i=e.i,o=e.n;if(k(n)){var c=t.searchIn(n),a=c.isMatch,s=c.score,u=c.indices;a&&r.push({item:n,idx:i,matches:[{score:s,value:n,norm:o,indices:u}]})}})),r}},{key:"_searchLogical",value:function(e){var t=this,n=function(e,t){var n=(arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}).auto,r=void 0===n||n,i=function e(n){var i=Object.keys(n),o=ue(n);if(!o&&i.length>1&&!se(n))return e(le(n));if(he(n)){var c=o?n[ce]:i[0],a=o?n[ae]:n[c];if(!g(a))throw new Error(x(c));var s={keyId:j(c),pattern:a};return r&&(s.searcher=re(a,t)),s}var u={children:[],operator:i[0]};return i.forEach((function(t){var r=n[t];v(r)&&r.forEach((function(t){u.children.push(e(t))}))})),u};return se(e)||(e=le(e)),i(e)}(e,this.options),r=function e(n,r,i){if(!n.children){var o=n.keyId,c=n.searcher,a=t._findMatches({key:t._keyStore.get(o),value:t._myIndex.getValueForItemAtKeyId(r,o),searcher:c});return a&&a.length?[{idx:i,item:r,matches:a}]:[]}for(var s=[],u=0,h=n.children.length;u1&&void 0!==arguments[1]?arguments[1]:{},n=t.getFn,r=void 0===n?I.getFn:n,i=t.fieldNormWeight,o=void 0===i?I.fieldNormWeight:i,c=e.keys,a=e.records,s=new $({getFn:r,fieldNormWeight:o});return s.setKeys(c),s.setIndexRecords(a),s},ye.config=I,function(){ne.push.apply(ne,arguments)}(te),ye},"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Fuse=t(); \ No newline at end of file diff --git a/_proc/_docs/site_libs/quarto-search/quarto-search.js b/_proc/_docs/site_libs/quarto-search/quarto-search.js new file mode 100644 index 0000000000000000000000000000000000000000..f5d852d137a766374e35adadfccde8e6e9482ce1 --- /dev/null +++ b/_proc/_docs/site_libs/quarto-search/quarto-search.js @@ -0,0 +1,1140 @@ +const kQueryArg = "q"; +const kResultsArg = "show-results"; + +// If items don't provide a URL, then both the navigator and the onSelect +// function aren't called (and therefore, the default implementation is used) +// +// We're using this sentinel URL to signal to those handlers that this +// item is a more item (along with the type) and can be handled appropriately +const kItemTypeMoreHref = "0767FDFD-0422-4E5A-BC8A-3BE11E5BBA05"; + +window.document.addEventListener("DOMContentLoaded", function (_event) { + // Ensure that search is available on this page. If it isn't, + // should return early and not do anything + var searchEl = window.document.getElementById("quarto-search"); + if (!searchEl) return; + + const { autocomplete } = window["@algolia/autocomplete-js"]; + + let quartoSearchOptions = {}; + let language = {}; + const searchOptionEl = window.document.getElementById( + "quarto-search-options" + ); + if (searchOptionEl) { + const jsonStr = searchOptionEl.textContent; + quartoSearchOptions = JSON.parse(jsonStr); + language = quartoSearchOptions.language; + } + + // note the search mode + if (quartoSearchOptions.type === "overlay") { + searchEl.classList.add("type-overlay"); + } else { + searchEl.classList.add("type-textbox"); + } + + // Used to determine highlighting behavior for this page + // A `q` query param is expected when the user follows a search + // to this page + const currentUrl = new URL(window.location); + const query = currentUrl.searchParams.get(kQueryArg); + const showSearchResults = currentUrl.searchParams.get(kResultsArg); + const mainEl = window.document.querySelector("main"); + + // highlight matches on the page + if (query !== null && mainEl) { + // perform any highlighting + highlight(escapeRegExp(query), mainEl); + + // fix up the URL to remove the q query param + const replacementUrl = new URL(window.location); + replacementUrl.searchParams.delete(kQueryArg); + window.history.replaceState({}, "", replacementUrl); + } + + // function to clear highlighting on the page when the search query changes + // (e.g. if the user edits the query or clears it) + let highlighting = true; + const resetHighlighting = (searchTerm) => { + if (mainEl && highlighting && query !== null && searchTerm !== query) { + clearHighlight(query, mainEl); + highlighting = false; + } + }; + + // Clear search highlighting when the user scrolls sufficiently + const resetFn = () => { + resetHighlighting(""); + window.removeEventListener("quarto-hrChanged", resetFn); + window.removeEventListener("quarto-sectionChanged", resetFn); + }; + + // Register this event after the initial scrolling and settling of events + // on the page + window.addEventListener("quarto-hrChanged", resetFn); + window.addEventListener("quarto-sectionChanged", resetFn); + + // Responsively switch to overlay mode if the search is present on the navbar + // Note that switching the sidebar to overlay mode requires more coordinate (not just + // the media query since we generate different HTML for sidebar overlays than we do + // for sidebar input UI) + const detachedMediaQuery = + quartoSearchOptions.type === "overlay" ? "all" : "(max-width: 991px)"; + + // If configured, include the analytics client to send insights + const plugins = configurePlugins(quartoSearchOptions); + + let lastState = null; + const { setIsOpen, setQuery, setCollections } = autocomplete({ + container: searchEl, + detachedMediaQuery: detachedMediaQuery, + defaultActiveItemId: 0, + panelContainer: "#quarto-search-results", + panelPlacement: quartoSearchOptions["panel-placement"], + debug: false, + openOnFocus: true, + plugins, + classNames: { + form: "d-flex", + }, + translations: { + clearButtonTitle: language["search-clear-button-title"], + detachedCancelButtonText: language["search-detached-cancel-button-title"], + submitButtonTitle: language["search-submit-button-title"], + }, + initialState: { + query, + }, + getItemUrl({ item }) { + return item.href; + }, + onStateChange({ state }) { + // Perhaps reset highlighting + resetHighlighting(state.query); + + // If the panel just opened, ensure the panel is positioned properly + if (state.isOpen) { + if (lastState && !lastState.isOpen) { + setTimeout(() => { + positionPanel(quartoSearchOptions["panel-placement"]); + }, 150); + } + } + + // Perhaps show the copy link + showCopyLink(state.query, quartoSearchOptions); + + lastState = state; + }, + reshape({ sources, state }) { + return sources.map((source) => { + try { + const items = source.getItems(); + + // Validate the items + validateItems(items); + + // group the items by document + const groupedItems = new Map(); + items.forEach((item) => { + const hrefParts = item.href.split("#"); + const baseHref = hrefParts[0]; + const isDocumentItem = hrefParts.length === 1; + + const items = groupedItems.get(baseHref); + if (!items) { + groupedItems.set(baseHref, [item]); + } else { + // If the href for this item matches the document + // exactly, place this item first as it is the item that represents + // the document itself + if (isDocumentItem) { + items.unshift(item); + } else { + items.push(item); + } + groupedItems.set(baseHref, items); + } + }); + + const reshapedItems = []; + let count = 1; + for (const [_key, value] of groupedItems) { + const firstItem = value[0]; + reshapedItems.push({ + ...firstItem, + type: kItemTypeDoc, + }); + + const collapseMatches = quartoSearchOptions["collapse-after"]; + const collapseCount = + typeof collapseMatches === "number" ? collapseMatches : 1; + + if (value.length > 1) { + const target = `search-more-${count}`; + const isExpanded = + state.context.expanded && + state.context.expanded.includes(target); + + const remainingCount = value.length - collapseCount; + + for (let i = 1; i < value.length; i++) { + if (collapseMatches && i === collapseCount) { + reshapedItems.push({ + target, + title: isExpanded + ? language["search-hide-matches-text"] + : remainingCount === 1 + ? `${remainingCount} ${language["search-more-match-text"]}` + : `${remainingCount} ${language["search-more-matches-text"]}`, + type: kItemTypeMore, + href: kItemTypeMoreHref, + }); + } + + if (isExpanded || !collapseMatches || i < collapseCount) { + reshapedItems.push({ + ...value[i], + type: kItemTypeItem, + target, + }); + } + } + } + count += 1; + } + + return { + ...source, + getItems() { + return reshapedItems; + }, + }; + } catch (error) { + // Some form of error occurred + return { + ...source, + getItems() { + return [ + { + title: error.name || "An Error Occurred While Searching", + text: + error.message || + "An unknown error occurred while attempting to perform the requested search.", + type: kItemTypeError, + }, + ]; + }, + }; + } + }); + }, + navigator: { + navigate({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.location.assign(itemUrl); + } + }, + navigateNewTab({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + const windowReference = window.open(itemUrl, "_blank", "noopener"); + if (windowReference) { + windowReference.focus(); + } + } + }, + navigateNewWindow({ itemUrl }) { + if (itemUrl !== offsetURL(kItemTypeMoreHref)) { + window.open(itemUrl, "_blank", "noopener"); + } + }, + }, + getSources({ state, setContext, setActiveItemId, refresh }) { + return [ + { + sourceId: "documents", + getItemUrl({ item }) { + if (item.href) { + return offsetURL(item.href); + } else { + return undefined; + } + }, + onSelect({ + item, + state, + setContext, + setIsOpen, + setActiveItemId, + refresh, + }) { + if (item.type === kItemTypeMore) { + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + + // Toggle more + setIsOpen(true); + } + }, + getItems({ query }) { + if (query === null || query === "") { + return []; + } + + const limit = quartoSearchOptions.limit; + if (quartoSearchOptions.algolia) { + return algoliaSearch(query, limit, quartoSearchOptions.algolia); + } else { + // Fuse search options + const fuseSearchOptions = { + isCaseSensitive: false, + shouldSort: true, + minMatchCharLength: 2, + limit: limit, + }; + + return readSearchData().then(function (fuse) { + return fuseSearch(query, fuse, fuseSearchOptions); + }); + } + }, + templates: { + noResults({ createElement }) { + const hasQuery = lastState.query; + + return createElement( + "div", + { + class: `quarto-search-no-results${ + hasQuery ? "" : " no-query" + }`, + }, + language["search-no-results-text"] + ); + }, + header({ items, createElement }) { + // count the documents + const count = items.filter((item) => { + return item.type === kItemTypeDoc; + }).length; + + if (count > 0) { + return createElement( + "div", + { class: "search-result-header" }, + `${count} ${language["search-matching-documents-text"]}` + ); + } else { + return createElement( + "div", + { class: "search-result-header-no-results" }, + `` + ); + } + }, + footer({ _items, createElement }) { + if ( + quartoSearchOptions.algolia && + quartoSearchOptions.algolia["show-logo"] + ) { + const libDir = quartoSearchOptions.algolia["libDir"]; + const logo = createElement("img", { + src: offsetURL( + `${libDir}/quarto-search/search-by-algolia.svg` + ), + class: "algolia-search-logo", + }); + return createElement( + "a", + { href: "http://www.algolia.com/" }, + logo + ); + } + }, + + item({ item, createElement }) { + return renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh + ); + }, + }, + }, + ]; + }, + }); + + window.quartoOpenSearch = () => { + setIsOpen(false); + setIsOpen(true); + focusSearchInput(); + }; + + // Remove the labeleledby attribute since it is pointing + // to a non-existent label + if (quartoSearchOptions.type === "overlay") { + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + if (inputEl) { + inputEl.removeAttribute("aria-labelledby"); + } + } + + // If the main document scrolls dismiss the search results + // (otherwise, since they're floating in the document they can scroll with the document) + window.document.body.onscroll = () => { + setIsOpen(false); + }; + + if (showSearchResults) { + setIsOpen(true); + focusSearchInput(); + } +}); + +function configurePlugins(quartoSearchOptions) { + const autocompletePlugins = []; + const algoliaOptions = quartoSearchOptions.algolia; + if ( + algoliaOptions && + algoliaOptions["analytics-events"] && + algoliaOptions["search-only-api-key"] && + algoliaOptions["application-id"] + ) { + const apiKey = algoliaOptions["search-only-api-key"]; + const appId = algoliaOptions["application-id"]; + + // Aloglia insights may not be loaded because they require cookie consent + // Use deferred loading so events will start being recorded when/if consent + // is granted. + const algoliaInsightsDeferredPlugin = deferredLoadPlugin(() => { + if ( + window.aa && + window["@algolia/autocomplete-plugin-algolia-insights"] + ) { + window.aa("init", { + appId, + apiKey, + useCookie: true, + }); + + const { createAlgoliaInsightsPlugin } = + window["@algolia/autocomplete-plugin-algolia-insights"]; + // Register the insights client + const algoliaInsightsPlugin = createAlgoliaInsightsPlugin({ + insightsClient: window.aa, + onItemsChange({ insights, insightsEvents }) { + const events = insightsEvents.map((event) => { + const maxEvents = event.objectIDs.slice(0, 20); + return { + ...event, + objectIDs: maxEvents, + }; + }); + + insights.viewedObjectIDs(...events); + }, + }); + return algoliaInsightsPlugin; + } + }); + + // Add the plugin + autocompletePlugins.push(algoliaInsightsDeferredPlugin); + return autocompletePlugins; + } +} + +// For plugins that may not load immediately, create a wrapper +// plugin and forward events and plugin data once the plugin +// is initialized. This is useful for cases like cookie consent +// which may prevent the analytics insights event plugin from initializing +// immediately. +function deferredLoadPlugin(createPlugin) { + let plugin = undefined; + let subscribeObj = undefined; + const wrappedPlugin = () => { + if (!plugin && subscribeObj) { + plugin = createPlugin(); + if (plugin && plugin.subscribe) { + plugin.subscribe(subscribeObj); + } + } + return plugin; + }; + + return { + subscribe: (obj) => { + subscribeObj = obj; + }, + onStateChange: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onStateChange) { + plugin.onStateChange(obj); + } + }, + onSubmit: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onSubmit) { + plugin.onSubmit(obj); + } + }, + onReset: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.onReset) { + plugin.onReset(obj); + } + }, + getSources: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.getSources) { + return plugin.getSources(obj); + } else { + return Promise.resolve([]); + } + }, + data: (obj) => { + const plugin = wrappedPlugin(); + if (plugin && plugin.data) { + plugin.data(obj); + } + }, + }; +} + +function validateItems(items) { + // Validate the first item + if (items.length > 0) { + const item = items[0]; + const missingFields = []; + if (item.href == undefined) { + missingFields.push("href"); + } + if (!item.title == undefined) { + missingFields.push("title"); + } + if (!item.text == undefined) { + missingFields.push("text"); + } + + if (missingFields.length === 1) { + throw { + name: `Error: Search index is missing the ${missingFields[0]} field.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items include the ${missingFields[0]} field or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } else if (missingFields.length > 1) { + const missingFieldList = missingFields + .map((field) => { + return `${field}`; + }) + .join(", "); + + throw { + name: `Error: Search index is missing the following fields: ${missingFieldList}.`, + message: `The items being returned for this search do not include all the required fields. Please ensure that your index items includes the following fields: ${missingFieldList}, or use index-fields in your _quarto.yml file to specify the field names.`, + }; + } + } +} + +let lastQuery = null; +function showCopyLink(query, options) { + const language = options.language; + lastQuery = query; + // Insert share icon + const inputSuffixEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix" + ); + + if (inputSuffixEl) { + let copyButtonEl = window.document.body.querySelector( + ".aa-Form .aa-InputWrapperSuffix .aa-CopyButton" + ); + + if (copyButtonEl === null) { + copyButtonEl = window.document.createElement("button"); + copyButtonEl.setAttribute("class", "aa-CopyButton"); + copyButtonEl.setAttribute("type", "button"); + copyButtonEl.setAttribute("title", language["search-copy-link-title"]); + copyButtonEl.onmousedown = (e) => { + e.preventDefault(); + e.stopPropagation(); + }; + + const linkIcon = "bi-clipboard"; + const checkIcon = "bi-check2"; + + const shareIconEl = window.document.createElement("i"); + shareIconEl.setAttribute("class", `bi ${linkIcon}`); + copyButtonEl.appendChild(shareIconEl); + inputSuffixEl.prepend(copyButtonEl); + + const clipboard = new window.ClipboardJS(".aa-CopyButton", { + text: function (_trigger) { + const copyUrl = new URL(window.location); + copyUrl.searchParams.set(kQueryArg, lastQuery); + copyUrl.searchParams.set(kResultsArg, "1"); + return copyUrl.toString(); + }, + }); + clipboard.on("success", function (e) { + // Focus the input + + // button target + const button = e.trigger; + const icon = button.querySelector("i.bi"); + + // flash "checked" + icon.classList.add(checkIcon); + icon.classList.remove(linkIcon); + setTimeout(function () { + icon.classList.remove(checkIcon); + icon.classList.add(linkIcon); + }, 1000); + }); + } + + // If there is a query, show the link icon + if (copyButtonEl) { + if (lastQuery && options["copy-button"]) { + copyButtonEl.style.display = "flex"; + } else { + copyButtonEl.style.display = "none"; + } + } + } +} + +/* Search Index Handling */ +// create the index +var fuseIndex = undefined; +async function readSearchData() { + // Initialize the search index on demand + if (fuseIndex === undefined) { + // create fuse index + const options = { + keys: [ + { name: "title", weight: 20 }, + { name: "section", weight: 20 }, + { name: "text", weight: 10 }, + ], + ignoreLocation: true, + threshold: 0.1, + }; + const fuse = new window.Fuse([], options); + + // fetch the main search.json + const response = await fetch(offsetURL("search.json")); + if (response.status == 200) { + return response.json().then(function (searchDocs) { + searchDocs.forEach(function (searchDoc) { + fuse.add(searchDoc); + }); + fuseIndex = fuse; + return fuseIndex; + }); + } else { + return Promise.reject( + new Error( + "Unexpected status from search index request: " + response.status + ) + ); + } + } + return fuseIndex; +} + +function inputElement() { + return window.document.body.querySelector(".aa-Form .aa-Input"); +} + +function focusSearchInput() { + setTimeout(() => { + const inputEl = inputElement(); + if (inputEl) { + inputEl.focus(); + } + }, 50); +} + +/* Panels */ +const kItemTypeDoc = "document"; +const kItemTypeMore = "document-more"; +const kItemTypeItem = "document-item"; +const kItemTypeError = "error"; + +function renderItem( + item, + createElement, + state, + setActiveItemId, + setContext, + refresh +) { + switch (item.type) { + case kItemTypeDoc: + return createDocumentCard( + createElement, + "file-richtext", + item.title, + item.section, + item.text, + item.href + ); + case kItemTypeMore: + return createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh + ); + case kItemTypeItem: + return createSectionCard( + createElement, + item.section, + item.text, + item.href + ); + case kItemTypeError: + return createErrorCard(createElement, item.title, item.text); + default: + return undefined; + } +} + +function createDocumentCard(createElement, icon, title, section, text, href) { + const iconEl = createElement("i", { + class: `bi bi-${icon} search-result-icon`, + }); + const titleEl = createElement("p", { class: "search-result-title" }, title); + const titleContainerEl = createElement( + "div", + { class: "search-result-title-container" }, + [iconEl, titleEl] + ); + + const textEls = []; + if (section) { + const sectionEl = createElement( + "p", + { class: "search-result-section" }, + section + ); + textEls.push(sectionEl); + } + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + textEls.push(descEl); + + const textContainerEl = createElement( + "div", + { class: "search-result-text-container" }, + textEls + ); + + const containerEl = createElement( + "div", + { + class: "search-result-container", + }, + [titleContainerEl, textContainerEl] + ); + + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + containerEl + ); + + const classes = ["search-result-doc", "search-item"]; + if (!section) { + classes.push("document-selectable"); + } + + return createElement( + "div", + { + class: classes.join(" "), + }, + linkEl + ); +} + +function createMoreCard( + createElement, + item, + state, + setActiveItemId, + setContext, + refresh +) { + const moreCardEl = createElement( + "div", + { + class: "search-result-more search-item", + onClick: (e) => { + // Handle expanding the sections by adding the expanded + // section to the list of expanded sections + toggleExpanded(item, state, setContext, setActiveItemId, refresh); + e.stopPropagation(); + }, + }, + item.title + ); + + return moreCardEl; +} + +function toggleExpanded(item, state, setContext, setActiveItemId, refresh) { + const expanded = state.context.expanded || []; + if (expanded.includes(item.target)) { + setContext({ + expanded: expanded.filter((target) => target !== item.target), + }); + } else { + setContext({ expanded: [...expanded, item.target] }); + } + + refresh(); + setActiveItemId(item.__autocomplete_id); +} + +function createSectionCard(createElement, section, text, href) { + const sectionEl = createSection(createElement, section, text, href); + return createElement( + "div", + { + class: "search-result-doc-section search-item", + }, + sectionEl + ); +} + +function createSection(createElement, title, text, href) { + const descEl = createElement("p", { + class: "search-result-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { class: "search-result-section" }, title); + const linkEl = createElement( + "a", + { + href: offsetURL(href), + class: "search-result-link", + }, + [titleEl, descEl] + ); + return linkEl; +} + +function createErrorCard(createElement, title, text) { + const descEl = createElement("p", { + class: "search-error-text", + dangerouslySetInnerHTML: { + __html: text, + }, + }); + + const titleEl = createElement("p", { + class: "search-error-title", + dangerouslySetInnerHTML: { + __html: ` ${title}`, + }, + }); + const errorEl = createElement("div", { class: "search-error" }, [ + titleEl, + descEl, + ]); + return errorEl; +} + +function positionPanel(pos) { + const panelEl = window.document.querySelector( + "#quarto-search-results .aa-Panel" + ); + const inputEl = window.document.querySelector( + "#quarto-search .aa-Autocomplete" + ); + + if (panelEl && inputEl) { + panelEl.style.top = `${Math.round(panelEl.offsetTop)}px`; + if (pos === "start") { + panelEl.style.left = `${Math.round(inputEl.left)}px`; + } else { + panelEl.style.right = `${Math.round(inputEl.offsetRight)}px`; + } + } +} + +/* Highlighting */ +// highlighting functions +function highlightMatch(query, text) { + if (text) { + const start = text.toLowerCase().indexOf(query.toLowerCase()); + if (start !== -1) { + const startMark = ""; + const endMark = ""; + + const end = start + query.length; + text = + text.slice(0, start) + + startMark + + text.slice(start, end) + + endMark + + text.slice(end); + const startInfo = clipStart(text, start); + const endInfo = clipEnd( + text, + startInfo.position + startMark.length + endMark.length + ); + text = + startInfo.prefix + + text.slice(startInfo.position, endInfo.position) + + endInfo.suffix; + + return text; + } else { + return text; + } + } else { + return text; + } +} + +function clipStart(text, pos) { + const clipStart = pos - 50; + if (clipStart < 0) { + // This will just return the start of the string + return { + position: 0, + prefix: "", + }; + } else { + // We're clipping before the start of the string, walk backwards to the first space. + const spacePos = findSpace(text, pos, -1); + return { + position: spacePos.position, + prefix: "", + }; + } +} + +function clipEnd(text, pos) { + const clipEnd = pos + 200; + if (clipEnd > text.length) { + return { + position: text.length, + suffix: "", + }; + } else { + const spacePos = findSpace(text, clipEnd, 1); + return { + position: spacePos.position, + suffix: spacePos.clipped ? "…" : "", + }; + } +} + +function findSpace(text, start, step) { + let stepPos = start; + while (stepPos > -1 && stepPos < text.length) { + const char = text[stepPos]; + if (char === " " || char === "," || char === ":") { + return { + position: step === 1 ? stepPos : stepPos - step, + clipped: stepPos > 1 && stepPos < text.length, + }; + } + stepPos = stepPos + step; + } + + return { + position: stepPos - step, + clipped: false, + }; +} + +// removes highlighting as implemented by the mark tag +function clearHighlight(searchterm, el) { + const childNodes = el.childNodes; + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + if (node.nodeType === Node.ELEMENT_NODE) { + if ( + node.tagName === "MARK" && + node.innerText.toLowerCase() === searchterm.toLowerCase() + ) { + el.replaceChild(document.createTextNode(node.innerText), node); + } else { + clearHighlight(searchterm, node); + } + } + } +} + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string +} + +// highlight matches +function highlight(term, el) { + const termRegex = new RegExp(term, "ig"); + const childNodes = el.childNodes; + + // walk back to front avoid mutating elements in front of us + for (let i = childNodes.length - 1; i >= 0; i--) { + const node = childNodes[i]; + + if (node.nodeType === Node.TEXT_NODE) { + // Search text nodes for text to highlight + const text = node.nodeValue; + + let startIndex = 0; + let matchIndex = text.search(termRegex); + if (matchIndex > -1) { + const markFragment = document.createDocumentFragment(); + while (matchIndex > -1) { + const prefix = text.slice(startIndex, matchIndex); + markFragment.appendChild(document.createTextNode(prefix)); + + const mark = document.createElement("mark"); + mark.appendChild( + document.createTextNode( + text.slice(matchIndex, matchIndex + term.length) + ) + ); + markFragment.appendChild(mark); + + startIndex = matchIndex + term.length; + matchIndex = text.slice(startIndex).search(new RegExp(term, "ig")); + if (matchIndex > -1) { + matchIndex = startIndex + matchIndex; + } + } + if (startIndex < text.length) { + markFragment.appendChild( + document.createTextNode(text.slice(startIndex, text.length)) + ); + } + + el.replaceChild(markFragment, node); + } + } else if (node.nodeType === Node.ELEMENT_NODE) { + // recurse through elements + highlight(term, node); + } + } +} + +/* Link Handling */ +// get the offset from this page for a given site root relative url +function offsetURL(url) { + var offset = getMeta("quarto:offset"); + return offset ? offset + url : url; +} + +// read a meta tag value +function getMeta(metaName) { + var metas = window.document.getElementsByTagName("meta"); + for (let i = 0; i < metas.length; i++) { + if (metas[i].getAttribute("name") === metaName) { + return metas[i].getAttribute("content"); + } + } + return ""; +} + +function algoliaSearch(query, limit, algoliaOptions) { + const { getAlgoliaResults } = window["@algolia/autocomplete-preset-algolia"]; + + const applicationId = algoliaOptions["application-id"]; + const searchOnlyApiKey = algoliaOptions["search-only-api-key"]; + const indexName = algoliaOptions["index-name"]; + const indexFields = algoliaOptions["index-fields"]; + const searchClient = window.algoliasearch(applicationId, searchOnlyApiKey); + const searchParams = algoliaOptions["params"]; + const searchAnalytics = !!algoliaOptions["analytics-events"]; + + return getAlgoliaResults({ + searchClient, + queries: [ + { + indexName: indexName, + query, + params: { + hitsPerPage: limit, + clickAnalytics: searchAnalytics, + ...searchParams, + }, + }, + ], + transformResponse: (response) => { + if (!indexFields) { + return response.hits.map((hit) => { + return hit.map((item) => { + return { + ...item, + text: highlightMatch(query, item.text), + }; + }); + }); + } else { + const remappedHits = response.hits.map((hit) => { + return hit.map((item) => { + const newItem = { ...item }; + ["href", "section", "title", "text"].forEach((keyName) => { + const mappedName = indexFields[keyName]; + if ( + mappedName && + item[mappedName] !== undefined && + mappedName !== keyName + ) { + newItem[keyName] = item[mappedName]; + delete newItem[mappedName]; + } + }); + newItem.text = highlightMatch(query, newItem.text); + return newItem; + }); + }); + return remappedHits; + } + }, + }); +} + +function fuseSearch(query, fuse, fuseOptions) { + return fuse.search(query, fuseOptions).map((result) => { + const addParam = (url, name, value) => { + const anchorParts = url.split("#"); + const baseUrl = anchorParts[0]; + const sep = baseUrl.search("\\?") > 0 ? "&" : "?"; + anchorParts[0] = baseUrl + sep + name + "=" + value; + return anchorParts.join("#"); + }; + + return { + title: result.item.title, + section: result.item.section, + href: addParam(result.item.href, kQueryArg, query), + text: highlightMatch(query, result.item.text), + }; + }); +} diff --git a/_proc/_docs/sitemap.xml b/_proc/_docs/sitemap.xml new file mode 100644 index 0000000000000000000000000000000000000000..41640005220c0ee5b94ebea4196a8db112e42128 --- /dev/null +++ b/_proc/_docs/sitemap.xml @@ -0,0 +1,23 @@ + + + + https://animalequality.github.io/lv-recipe-chatbot/app.html + 2023-06-07T04:08:48.274Z + + + https://animalequality.github.io/lv-recipe-chatbot/index.html + 2023-06-07T04:10:36.549Z + + + https://animalequality.github.io/lv-recipe-chatbot/lchain_tool.html + 2023-06-07T04:08:31.310Z + + + https://animalequality.github.io/lv-recipe-chatbot/edamam_api.html + 2023-06-07T04:08:31.486Z + + + https://animalequality.github.io/lv-recipe-chatbot/engineer_prompt.html + 2023-06-06T21:27:32.002Z + + diff --git a/_proc/_docs/styles.css b/_proc/_docs/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..66ccc49ee8f0e73901dac02dc4e9224b7d1b2c78 --- /dev/null +++ b/_proc/_docs/styles.css @@ -0,0 +1,37 @@ +.cell { + margin-bottom: 1rem; +} + +.cell > .sourceCode { + margin-bottom: 0; +} + +.cell-output > pre { + margin-bottom: 0; +} + +.cell-output > pre, .cell-output > .sourceCode > pre, .cell-output-stdout > pre { + margin-left: 0.8rem; + margin-top: 0; + background: none; + border-left: 2px solid lightsalmon; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.cell-output > .sourceCode { + border: none; +} + +.cell-output > .sourceCode { + background: none; + margin-top: 0; +} + +div.description { + padding-left: 2px; + padding-top: 5px; + font-style: italic; + font-size: 135%; + opacity: 70%; +} diff --git a/_proc/_quarto.yml b/_proc/_quarto.yml new file mode 100644 index 0000000000000000000000000000000000000000..0a6dfcb2f20aeeb3b9b36e44d534c646114dc302 --- /dev/null +++ b/_proc/_quarto.yml @@ -0,0 +1,20 @@ +project: + type: website + +format: + html: + theme: cosmo + css: styles.css + toc: true + +website: + twitter-card: true + open-graph: true + repo-actions: [issue] + navbar: + background: primary + search: true + sidebar: + style: floating + +metadata-files: [nbdev.yml, sidebar.yml] \ No newline at end of file diff --git a/_proc/index.ipynb b/_proc/index.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..39e1be4a01d80597bdca222740c26d3a38c778cb --- /dev/null +++ b/_proc/index.ipynb @@ -0,0 +1,199 @@ +{ + "cells": [ + { + "cell_type": "raw", + "metadata": {}, + "source": [ + "---\n", + "description: An experimental Vegan recipe chatbot\n", + "output-file: index.html\n", + "title: lv-recipe-chatbot\n", + "\n", + "---\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This file will become your README and also the index of your documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Install" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```sh\n", + "pip install lv_recipe_chatbot\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How to use" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running on local URL: http://127.0.0.1:7860\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + } + ], + "source": [ + "from dotenv import load_dotenv\n", + "\n", + "load_dotenv()\n", + "\n", + "app.launch_demo()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or \n", + "```sh\n", + "python3 app.py\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dev quick-start\n", + "\n", + "`git clone` the repo \n", + "\n", + "```sh\n", + "cd lv-recipe-chatbot\n", + "``` \n", + "\n", + "Make sure to use the version of python specified in `py_version.txt` \n", + "Create a virtual environment.\n", + "\n", + "```sh\n", + "python3 -m venv env\n", + "```\n", + "\n", + "Activate the env and install dependencies.\n", + "\n", + "```sh\n", + "source env/bin/activate\n", + "pip install -r requirements.txt\n", + "pip install -r requirements/dev.txt\n", + "```\n", + "\n", + "To make the Jupyter environment, git friendly: `nbdev_install_hooks` \n", + "If you want to render documentation locally, you will want to [install Quarto](https://nbdev.fast.ai/tutorials/tutorial.html#install-quarto).\n", + "\n", + "`nbdev_install_quarto` \n", + "\n", + "Put API secrets in .env\n", + "\n", + "```sh\n", + "cp .env.example .env\n", + "```\n", + "\n", + "Edit .env with your secret key(s). Only `OPEN_AI_KEY` is required.\n", + "\n", + "Then start the Gradio demo from within the virtual environment. \n", + "\n", + "```sh\n", + "python3 app.py\n", + "```\n", + "\n", + "Preview documentation\n", + "\n", + "```sh\n", + "nbdev_preview\n", + "```\n", + "\n", + "## Dependencies\n", + "\n", + "If a new dependency for development is helpful for developers, add it to `dev.txt`. \n", + "If it is a dependency for the app that is imported in source code, add it to `core.txt`. \n", + "Then run:\n", + "\n", + "```sh\n", + "pipreqs --force\n", + "```\n", + "\n", + "This will update our `requirements.txt` to include the dependency as it should be pinned in the environment. \n", + "\n", + "\n", + "## Development\n", + "\n", + "[quick nbdev tutorial](https://nbdev.fast.ai/tutorials)\n", + "\n", + "Make changes in `/nbs`. \n", + "Update the package files with `nbdev_export` then reimport with `pip install -e '.[dev]'`\n", + "\n", + "Preview doc `nbdev_preview` \n", + "Build docs, test and update README `nbdev_prepare`\n", + "\n", + "\n", + "\n", + "## Useful links\n", + "\n", + "* [Task Matrix (Formerly Visual ChatGPT)](https://github.com/microsoft/TaskMatrix)\n", + "* [LangChain](https://python.langchain.com/en/latest/index.html)\n", + "* [LLM Prompt Engineering](https://www.promptingguide.ai)\n", + "* [OpenAI best practices for prompts](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "language": "python" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "state": {}, + "version_major": 2, + "version_minor": 0 + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_proc/nbdev.yml b/_proc/nbdev.yml new file mode 100644 index 0000000000000000000000000000000000000000..7314ea6b69efe5a314f9d3814242161eb07a72d1 --- /dev/null +++ b/_proc/nbdev.yml @@ -0,0 +1,9 @@ +project: + output-dir: _docs + +website: + title: "lv-recipe-chatbot" + site-url: "https://animalequality.github.io/lv-recipe-chatbot" + description: "An experimental Vegan recipe chatbot" + repo-branch: main + repo-url: "https://github.com/animalequality/lv-recipe-chatbot" diff --git a/_proc/sidebar.yml b/_proc/sidebar.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc9c7b717fea0dee0ce3403ad5d6db5c4c5432e9 --- /dev/null +++ b/_proc/sidebar.yml @@ -0,0 +1,8 @@ +website: + sidebar: + contents: + - index.ipynb + - 00_engineer_prompt.ipynb + - 01_app.ipynb + - 02_lchain_tool.ipynb + - 03_edamam_api.ipynb diff --git a/_proc/sidebar.yml.bak b/_proc/sidebar.yml.bak new file mode 100644 index 0000000000000000000000000000000000000000..fc9c7b717fea0dee0ce3403ad5d6db5c4c5432e9 --- /dev/null +++ b/_proc/sidebar.yml.bak @@ -0,0 +1,8 @@ +website: + sidebar: + contents: + - index.ipynb + - 00_engineer_prompt.ipynb + - 01_app.ipynb + - 02_lchain_tool.ipynb + - 03_edamam_api.ipynb diff --git a/_proc/styles.css b/_proc/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..66ccc49ee8f0e73901dac02dc4e9224b7d1b2c78 --- /dev/null +++ b/_proc/styles.css @@ -0,0 +1,37 @@ +.cell { + margin-bottom: 1rem; +} + +.cell > .sourceCode { + margin-bottom: 0; +} + +.cell-output > pre { + margin-bottom: 0; +} + +.cell-output > pre, .cell-output > .sourceCode > pre, .cell-output-stdout > pre { + margin-left: 0.8rem; + margin-top: 0; + background: none; + border-left: 2px solid lightsalmon; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.cell-output > .sourceCode { + border: none; +} + +.cell-output > .sourceCode { + background: none; + margin-top: 0; +} + +div.description { + padding-left: 2px; + padding-top: 5px; + font-style: italic; + font-size: 135%; + opacity: 70%; +} diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..92c2979708a942106b17d40ca533f164a1188c30 --- /dev/null +++ b/app.py @@ -0,0 +1,5 @@ +from lv_recipe_chatbot.app import launch_demo +# for Hugging Face + +if __name__ == "__main__": + launch_demo() \ No newline at end of file diff --git a/chatbot/__init__.py b/chatbot/__init__.py deleted file mode 100644 index bf6bd6c59fca6cd6c02255f1ed871a69802b53bb..0000000000000000000000000000000000000000 --- a/chatbot/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from dotenv import load_dotenv - -load_dotenv() diff --git a/env.example b/env.example new file mode 100644 index 0000000000000000000000000000000000000000..c5d66a3ebc8077721692fd189a59ee6cefec4ecf --- /dev/null +++ b/env.example @@ -0,0 +1,5 @@ +OPENAI_API_KEY = "" +PROMPTLAYER_API_KEY = "" +GRADIO_DEMO_USERNAME = "" +GRADIO_DEMO_PASSWORD = "" +SERPAPI_API_KEY = "" \ No newline at end of file diff --git a/hface.yaml b/hface.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e3cfad82a7ad1cc37b5bd8844854541a63819ba4 --- /dev/null +++ b/hface.yaml @@ -0,0 +1,11 @@ +--- +title: lv-recipe-chatbot +emoji: 🫑 +colorFrom: green +colorTo: indigo +sdk: gradio +sdk_version: 3.23.0 +app_file: app.py +pinned: false +license: unknown +--- \ No newline at end of file diff --git a/lv_recipe_chatbot/__init__.py b/lv_recipe_chatbot/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..f102a9cadfa89ce554b3b26d2b90bfba2e05273c --- /dev/null +++ b/lv_recipe_chatbot/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.1" diff --git a/lv_recipe_chatbot/_modidx.py b/lv_recipe_chatbot/_modidx.py new file mode 100644 index 0000000000000000000000000000000000000000..0461dca20afd86dbae2dfc3132a48089bddf52f2 --- /dev/null +++ b/lv_recipe_chatbot/_modidx.py @@ -0,0 +1,26 @@ +# Autogenerated by nbdev + +d = { 'settings': { 'branch': 'main', + 'doc_baseurl': '/lv-recipe-chatbot', + 'doc_host': 'https://animalequality.github.io', + 'git_url': 'https://github.com/animalequality/lv-recipe-chatbot', + 'lib_path': 'lv_recipe_chatbot'}, + 'syms': { 'lv_recipe_chatbot.app': { 'lv_recipe_chatbot.app.ConversationBot': ('app.html#conversationbot', 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.ConversationBot.__init__': ( 'app.html#conversationbot.__init__', + 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.ConversationBot._get_bot_response': ( 'app.html#conversationbot._get_bot_response', + 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.ConversationBot.init_conversation': ( 'app.html#conversationbot.init_conversation', + 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.ConversationBot.reset': ( 'app.html#conversationbot.reset', + 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.ConversationBot.respond': ( 'app.html#conversationbot.respond', + 'lv_recipe_chatbot/app.py'), + 'lv_recipe_chatbot.app.launch_demo': ('app.html#launch_demo', 'lv_recipe_chatbot/app.py')}, + 'lv_recipe_chatbot.edamam_api': { 'lv_recipe_chatbot.edamam_api.foo': ( 'edamam_api.html#foo', + 'lv_recipe_chatbot/edamam_api.py')}, + 'lv_recipe_chatbot.engineer_prompt': {}, + 'lv_recipe_chatbot.lchain_tool': { 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper': ( 'lchain_tool.html#recipeserpapiwrapper', + 'lv_recipe_chatbot/lchain_tool.py'), + 'lv_recipe_chatbot.lchain_tool.RecipeSerpAPIWrapper._process_response': ( 'lchain_tool.html#recipeserpapiwrapper._process_response', + 'lv_recipe_chatbot/lchain_tool.py')}}} diff --git a/chatbot/app.py b/lv_recipe_chatbot/app.py similarity index 54% rename from chatbot/app.py rename to lv_recipe_chatbot/app.py index 48fb53ea0dd0421cec229024679240b6bd30c787..b06e6d31c59f04b9fa2a5b313fc69663ecf2acec 100644 --- a/chatbot/app.py +++ b/lv_recipe_chatbot/app.py @@ -1,15 +1,25 @@ +# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/01_app.ipynb. + +# %% auto 0 +__all__ = ['ConversationBot', 'launch_demo'] + +# %% ../nbs/01_app.ipynb 3 +import os + import gradio as gr -from langchain.chat_models import ChatOpenAI +from fastcore.utils import in_jupyter from langchain.chains import ConversationChain +from langchain.chat_models import ChatOpenAI from langchain.memory import ConversationBufferMemory - from langchain.prompts.chat import ( + ChatPromptTemplate, HumanMessagePromptTemplate, MessagesPlaceholder, - ChatPromptTemplate, ) -from chatbot.engineer_prompt import init_prompt +from .engineer_prompt import init_prompt + +# %% ../nbs/01_app.ipynb 4 class ConversationBot: def __init__( self, @@ -72,46 +82,24 @@ class ConversationBot: response = self.conversation.predict(input=user_msg) return response - # def run_image(self, image, state, txt, lang): - # image_filename = os.path.join("image", f"{str(uuid.uuid4())[:8]}.png") - # print("======>Auto Resize Image...") - # img = Image.open(image.name) - # width, height = img.size - # ratio = min(512 / width, 512 / height) - # width_new, height_new = (round(width * ratio), round(height * ratio)) - # width_new = int(np.round(width_new / 64.0)) * 64 - # height_new = int(np.round(height_new / 64.0)) * 64 - # img = img.resize((width_new, height_new)) - # img = img.convert("RGB") - # img.save(image_filename, "PNG") - # print(f"Resize image form {width}x{height} to {width_new}x{height_new}") - # description = self.models["ImageCaptioning"].inference(image_filename) - # Human_prompt = f'\nHuman: provide a figure named {image_filename}. The description is: {description}. This information helps you to understand this image, but you should use tools to finish following tasks, rather than directly imagine from my description. If you understand, say "Received". \n' - # self.memory.buffer = ( - # self.agent.memory.buffer + Human_prompt + "AI: " + AI_prompt - # ) - # state = state + [(f"![](file={image_filename})*{image_filename}*", AI_prompt)] - # print( - # f"\nProcessed run_image, Input image: {image_filename}\nCurrent state: {state}\n" - # f"Current Memory: {self.agent.memory.buffer}" - # ) - # return state, state, f"{txt} {image_filename} " - - -with gr.Blocks() as demo: - bot = ConversationBot() - chatbot = gr.Chatbot( - value=[(None, bot.ai_prompt_questions["ingredients"].prompt.template)] - ) - - msg = gr.Textbox() - clear = gr.Button("Clear") +# %% ../nbs/01_app.ipynb 5 +def launch_demo(): + with gr.Blocks() as demo: + bot = ConversationBot() + chatbot = gr.Chatbot( + value=[(None, bot.ai_prompt_questions["ingredients"].prompt.template)] + ) - msg.submit( - fn=bot.respond, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False - ) - clear.click(lambda: None, None, chatbot, queue=False).then(bot.reset) + msg = gr.Textbox() + clear = gr.Button("Clear") -if __name__ == "__main__": - import os - demo.launch(auth=(os.environ["GRADIO_DEMO_USERNAME"], os.environ["GRADIO_DEMO_PASSWORD"])) + msg.submit( + fn=bot.respond, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False + ) + clear.click(lambda: None, None, chatbot, queue=False).then(bot.reset) + demo.launch( + auth=( + os.environ["GRADIO_DEMO_USERNAME"], + os.environ["GRADIO_DEMO_PASSWORD"], + ) + ) diff --git a/lv_recipe_chatbot/edamam_api.py b/lv_recipe_chatbot/edamam_api.py new file mode 100644 index 0000000000000000000000000000000000000000..4c7b900ca92d8f64380855d4b15d9547d5dc987c --- /dev/null +++ b/lv_recipe_chatbot/edamam_api.py @@ -0,0 +1,8 @@ +# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/03_edamam_api.ipynb. + +# %% auto 0 +__all__ = ['foo'] + +# %% ../nbs/03_edamam_api.ipynb 3 +def foo(): + pass diff --git a/chatbot/engineer_prompt.py b/lv_recipe_chatbot/engineer_prompt.py similarity index 53% rename from chatbot/engineer_prompt.py rename to lv_recipe_chatbot/engineer_prompt.py index c7c18608bc1c6f66aa0450bbbe2dcadc3d6893a8..6c691d9ced85f0887ec571a526391ea28935a9d0 100644 --- a/chatbot/engineer_prompt.py +++ b/lv_recipe_chatbot/engineer_prompt.py @@ -1,19 +1,22 @@ -from langchain.chat_models import PromptLayerChatOpenAI -from langchain.schema import HumanMessage, AIMessage, SystemMessage +# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_engineer_prompt.ipynb. + +# %% auto 0 +__all__ = ['init_prompt'] + +# %% ../nbs/00_engineer_prompt.ipynb 3 from langchain.chains import ConversationChain +from langchain.chat_models import PromptLayerChatOpenAI from langchain.memory import ConversationBufferMemory from langchain.prompts.chat import ( + AIMessagePromptTemplate, ChatPromptTemplate, - SystemMessagePromptTemplate, HumanMessagePromptTemplate, - AIMessagePromptTemplate, MessagesPlaceholder, + SystemMessagePromptTemplate, ) +from langchain.schema import AIMessage, HumanMessage, SystemMessage -# TODO Multiple chains sequenced? -# I think your way works fine, though you'd probably want to wrap it up in some initializer so you can "initialize" the chain via LLM calls. I'd probably use 2 chains and have a wrapping chain switch from the first to the second after initializing. -# https://discord.com/channels/1038097195422978059/1038097349660135474/1100533951136800828 - +# %% ../nbs/00_engineer_prompt.ipynb 7 init_prompt = ChatPromptTemplate.from_messages( [ SystemMessagePromptTemplate.from_template( @@ -65,41 +68,3 @@ Steps (detailed): ), ] ) - - -if __name__ == "__main__": - chat = PromptLayerChatOpenAI( - temperature=1, pl_tags=["langchain"], return_pl_id=True - ) - memory = ConversationBufferMemory(return_messages=True) - chat_msgs = init_prompt.format_prompt( - ingredients="tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread", - allergies="", - recipe_freeform_input="The preparation time should be less than 30 minutes. I really love Thai food!", - ) - - chat_msgs = chat_msgs.to_messages() - results = chat.generate([chat_msgs]) - chat_msgs.extend( - [ - results.generations[0][0].message, - MessagesPlaceholder(variable_name="history"), - HumanMessagePromptTemplate.from_template("{input}"), - ] - ) - open_prompt = ChatPromptTemplate.from_messages(chat_msgs) - conversation = ConversationChain( - llm=chat, verbose=True, memory=memory, prompt=open_prompt - ) - - result = conversation.predict(input="Recommend a different recipe please.") - print(result) - -#! PL score example -# chat_results = chat.generate([[HumanMessage(content=prompt)]]) - -# for res in chat_results.generations: -# pl_request_id = res[0].generation_info["pl_request_id"] -# print(res[0].text) -# score = int(input("Enter a score from 0 to 100 for how the prompt performed: ")) -# promptlayer.track.score(request_id=pl_request_id, score=score) diff --git a/lv_recipe_chatbot/lchain_tool.py b/lv_recipe_chatbot/lchain_tool.py new file mode 100644 index 0000000000000000000000000000000000000000..68ee94a8d47e91ecea68be036f2a21faba94136c --- /dev/null +++ b/lv_recipe_chatbot/lchain_tool.py @@ -0,0 +1,26 @@ +# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_lchain_tool.ipynb. + +# %% auto 0 +__all__ = ['RecipeSerpAPIWrapper'] + +# %% ../nbs/02_lchain_tool.ipynb 3 +import os + +from IPython.display import Image +from langchain.agents import AgentType, Tool, initialize_agent, load_tools +from langchain.agents.agent_toolkits import create_python_agent +from langchain.chat_models import ChatOpenAI +from langchain.python import PythonREPL +from langchain.tools.python.tool import PythonREPLTool +from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper +from serpapi import GoogleSearch + +# %% ../nbs/02_lchain_tool.ipynb 12 +class RecipeSerpAPIWrapper(SerpAPIWrapper): + @staticmethod + def _process_response(res: dict) -> str: + """Process response from SerpAPI.""" + if "error" in res.keys(): + raise ValueError(f"Got error from SerpAPI: {res['error']}") + if "recipes_results" in res.keys(): + return res["recipes_results"] diff --git a/nbs/00_engineer_prompt.ipynb b/nbs/00_engineer_prompt.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..a4ac39ff4e3299f62bc162bddef0655f0e1e659a --- /dev/null +++ b/nbs/00_engineer_prompt.ipynb @@ -0,0 +1,318 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# engineer_prompt\n", + "\n", + "> Engineering prompts" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| default_exp engineer_prompt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "from nbdev.showdoc import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "from langchain.chains import ConversationChain\n", + "from langchain.chat_models import PromptLayerChatOpenAI\n", + "from langchain.memory import ConversationBufferMemory\n", + "from langchain.prompts.chat import (\n", + " AIMessagePromptTemplate,\n", + " ChatPromptTemplate,\n", + " HumanMessagePromptTemplate,\n", + " MessagesPlaceholder,\n", + " SystemMessagePromptTemplate,\n", + ")\n", + "from langchain.schema import AIMessage, HumanMessage, SystemMessage" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Setup env" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "load_dotenv()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "init_prompt = ChatPromptTemplate.from_messages(\n", + " [\n", + " SystemMessagePromptTemplate.from_template(\n", + " \"\"\"\n", + "The following is a conversation between a human and a friendly AI chef. \n", + "The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n", + "\n", + "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n", + "\n", + "Let's think step by step.\n", + "If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes. \n", + " \"\"\".strip()\n", + " ),\n", + " AIMessagePromptTemplate.from_template(\n", + " \"What ingredients do you wish to cook with?\"\n", + " ),\n", + " HumanMessagePromptTemplate.from_template(\"Ingredients: {ingredients}\"),\n", + " AIMessagePromptTemplate.from_template(\n", + " \"Do you have any allergies I should be aware of?\"\n", + " ),\n", + " HumanMessagePromptTemplate.from_template(\"Allergies: {allergies}\"),\n", + " AIMessagePromptTemplate.from_template(\n", + " \"Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\"\n", + " ),\n", + " HumanMessagePromptTemplate.from_template(\n", + " \"\"\"\n", + "Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\n", + "Respect the human's allergies (if any).\n", + "Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n", + "\n", + "###\n", + "Preferences: {recipe_freeform_input}\n", + "###\n", + "\n", + "Output format:\n", + "\n", + "**Vegan recipe name**\n", + "Preparation time (humanized)\n", + "\n", + "Ingredients (List of ingredients with quantities):\n", + "- \n", + "\n", + "Steps (detailed):\n", + "1.\n", + "2.\n", + "3.\n", + "...\n", + "\"\"\".strip()\n", + " ),\n", + " ]\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Evaluate chat backend " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Anthropic module not found. Install with `pip install anthropic`.\n", + "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new ConversationChain chain...\u001b[0m\n", + "Prompt after formatting:\n", + "\u001b[32;1m\u001b[1;3mSystem: The following is a conversation between a human and a friendly AI chef. \n", + "The AI is compassionate to animals and only recommends vegan recipes based on the ingredients, allergies, and other preferences the human has.\n", + "\n", + "Knowledge: A vegan diet implies a plant-based diet avoiding all animal foods such as meat (including fish, shellfish and insects), dairy, eggs and honey \n", + "\n", + "Let's think step by step.\n", + "If the human messages are unrelated to vegan recipes, remind them of your purpose to recommend vegan recipes.\n", + "AI: What ingredients do you wish to cook with?\n", + "Human: Ingredients: tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\n", + "AI: Do you have any allergies I should be aware of?\n", + "Human: Allergies: \n", + "AI: Do you have any preferences I should consider for the recipe such as preparation time, difficulty, or cuisine region?\n", + "Human: Give me a vegan recipe that includes at least a few of the ingredients provided (if any).\n", + "Respect the human's allergies (if any).\n", + "Follow these other preferences as closely as possible if they are inline with your purpose of recommending vegan recipes:\n", + "\n", + "###\n", + "Preferences: The preparation time should be less than 30 minutes. I really love Thai food!\n", + "###\n", + "\n", + "Output format:\n", + "\n", + "**Vegan recipe name**\n", + "Preparation time (humanized)\n", + "\n", + "Ingredients (List of ingredients with quantities):\n", + "- \n", + "\n", + "Steps (detailed):\n", + "1.\n", + "2.\n", + "3.\n", + "...\n", + "AI: Sure! How about a vegan Thai tofu lettuce wraps recipe? It should take less than 30 minutes to prepare.\n", + "\n", + "**Vegan Thai Tofu Lettuce Wraps**\n", + "Preparation time: 25 minutes\n", + "\n", + "Ingredients:\n", + "- 1 package firm tofu\n", + "- 1/4 cup vegan fish sauce (you can use soy sauce as a substitute)\n", + "- 2 tablespoons maple syrup\n", + "- 1 tablespoon lime juice\n", + "- 1 teaspoon chili paste\n", + "- 1 bell pepper, sliced\n", + "- 2 carrots, julienned\n", + "- 1/4 cup sliced pickles\n", + "- 1/4 cup sliced olives\n", + "- 6 large lettuce leaves\n", + "- 1/4 cup chopped fresh cilantro\n", + "\n", + "Steps:\n", + "1. Preheat a skillet over medium-high heat and add cubed tofu. Cook for about 5-7 minutes, flipping occasionally, until all the pieces are golden brown. Set aside.\n", + "2. In a mixing bowl, whisk together the fish sauce (or soy sauce), maple syrup, lime juice, and chili paste until combined.\n", + "3. In a large mixing bowl, add the bell pepper, carrots, pickles, olives, and cooked tofu. Pour the dressing over the ingredients, and toss until everything is evenly coated with the sauce.\n", + "4. Assemble the lettuce wraps by separating the lettuce leaves and spooning the tofu mixture into each one. Top with fresh cilantro and serve immediately. Enjoy your delicious vegan Thai tofu lettuce wraps!\n", + "Human: Recommend a different recipe please.\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n", + "Of course! How about a Mediterranean-inspired sandwich that includes tofu, olives, and tomatoes?\n", + "\n", + "**Mediterranean Tofu Sandwich**\n", + "Preparation time: 20 minutes\n", + "\n", + "Ingredients:\n", + "- 1 package extra-firm tofu, drained and sliced into 1/2-inch slices\n", + "- 2 tablespoons olive oil\n", + "- 1 teaspoon dried oregano\n", + "- Salt and pepper\n", + "- 1/4 cup vegan mayo\n", + "- 1 garlic clove, minced\n", + "- 2 teaspoons lemon juice\n", + "- 1 large tomato, sliced\n", + "- 1/4 cup sliced kalamata olives\n", + "- 1/4 cup chopped lettuce\n", + "- 1/4 cup sliced pickles\n", + "- Bread of your choice (I recommend ciabatta)\n", + "\n", + "Steps:\n", + "1. Preheat a skillet over medium-high heat and add the olive oil.\n", + "2. Season the tofu slices with oregano, salt, and pepper, then add them to the skillet. Cook for about 5-7 minutes on each side or until golden brown. Set aside.\n", + "3. In a small bowl, mix the vegan mayo, minced garlic, and lemon juice. Spread the mixture onto the slices of bread.\n", + "4. Layer the tomato slices, cooked tofu, olives, lettuce, and pickles onto the bread. Add salt and pepper to taste.\n", + "5. Top with the other slice of bread, slice in half, and enjoy your delicious Mediterranean tofu sandwich!\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: While logging your request PromptLayer had the following error: Invalid API key, please check your PromptLayer API key and try again\n" + ] + } + ], + "source": [ + "chat = PromptLayerChatOpenAI(temperature=1, pl_tags=[\"langchain\"], return_pl_id=True)\n", + "memory = ConversationBufferMemory(return_messages=True)\n", + "chat_msgs = init_prompt.format_prompt(\n", + " ingredients=\"tofu, pickles, olives, tomatoes, lettuce, bell peppers, carrots, bread\",\n", + " allergies=\"\",\n", + " recipe_freeform_input=\"The preparation time should be less than 30 minutes. I really love Thai food!\",\n", + ")\n", + "\n", + "chat_msgs = chat_msgs.to_messages()\n", + "results = chat.generate([chat_msgs])\n", + "chat_msgs.extend(\n", + " [\n", + " results.generations[0][0].message,\n", + " MessagesPlaceholder(variable_name=\"history\"),\n", + " HumanMessagePromptTemplate.from_template(\"{input}\"),\n", + " ]\n", + ")\n", + "open_prompt = ChatPromptTemplate.from_messages(chat_msgs)\n", + "conversation = ConversationChain(\n", + " llm=chat, verbose=True, memory=memory, prompt=open_prompt\n", + ")\n", + "\n", + "result = conversation.predict(input=\"Recommend a different recipe please.\")\n", + "print(result)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "import nbdev\n", + "\n", + "nbdev.nbdev_export()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/nbs/01_app.ipynb b/nbs/01_app.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..782ba719bc3b02813cd9806555cf8d39b2998ff3 --- /dev/null +++ b/nbs/01_app.ipynb @@ -0,0 +1,211 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# app\n", + "\n", + "> Gradio app.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| default_exp app" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "from nbdev.showdoc import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "import os\n", + "\n", + "import gradio as gr\n", + "from fastcore.utils import in_jupyter\n", + "from langchain.chains import ConversationChain\n", + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.memory import ConversationBufferMemory\n", + "from langchain.prompts.chat import (\n", + " ChatPromptTemplate,\n", + " HumanMessagePromptTemplate,\n", + " MessagesPlaceholder,\n", + ")\n", + "\n", + "from lv_recipe_chatbot.engineer_prompt import init_prompt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "class ConversationBot:\n", + " def __init__(\n", + " self,\n", + " ):\n", + " self.chat = ChatOpenAI(temperature=1, verbose=True)\n", + " self.memory = ConversationBufferMemory(return_messages=True)\n", + " self.init_prompt_msgs = init_prompt.messages\n", + " self.ai_prompt_questions = {\n", + " \"ingredients\": self.init_prompt_msgs[1],\n", + " \"allergies\": self.init_prompt_msgs[3],\n", + " \"recipe_open_params\": self.init_prompt_msgs[5],\n", + " }\n", + "\n", + " def respond(self, user_msg, chat_history):\n", + " response = self._get_bot_response(user_msg, chat_history)\n", + " chat_history.append((user_msg, response))\n", + " return \"\", chat_history\n", + "\n", + " def init_conversation(self, formatted_chat_prompt):\n", + " self.conversation = ConversationChain(\n", + " llm=self.chat,\n", + " memory=self.memory,\n", + " prompt=formatted_chat_prompt,\n", + " verbose=True,\n", + " )\n", + "\n", + " def reset(self):\n", + " self.memory.clear()\n", + "\n", + " def _get_bot_response(self, user_msg: str, chat_history) -> str:\n", + " if len(chat_history) < 2:\n", + " return self.ai_prompt_questions[\"allergies\"].prompt.template\n", + "\n", + " if len(chat_history) < 3:\n", + " return self.ai_prompt_questions[\"recipe_open_params\"].prompt.template\n", + "\n", + " if len(chat_history) < 4:\n", + " user = 0\n", + " ai = 1\n", + " user_msgs = [msg_pair[user] for msg_pair in chat_history[1:]]\n", + " f_init_prompt = init_prompt.format_prompt(\n", + " ingredients=user_msgs[0],\n", + " allergies=user_msgs[1],\n", + " recipe_freeform_input=user_msg,\n", + " )\n", + " chat_msgs = f_init_prompt.to_messages()\n", + " results = self.chat.generate([chat_msgs])\n", + " chat_msgs.extend(\n", + " [\n", + " results.generations[0][0].message,\n", + " MessagesPlaceholder(variable_name=\"history\"),\n", + " HumanMessagePromptTemplate.from_template(\"{input}\"),\n", + " ]\n", + " )\n", + " open_prompt = ChatPromptTemplate.from_messages(chat_msgs)\n", + " # prepare the open conversation chain from this point\n", + " self.init_conversation(open_prompt)\n", + " return results.generations[0][0].message.content\n", + "\n", + " response = self.conversation.predict(input=user_msg)\n", + " return response" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "def launch_demo():\n", + " with gr.Blocks() as demo:\n", + " bot = ConversationBot()\n", + " chatbot = gr.Chatbot(\n", + " value=[(None, bot.ai_prompt_questions[\"ingredients\"].prompt.template)]\n", + " )\n", + "\n", + " msg = gr.Textbox()\n", + " clear = gr.Button(\"Clear\")\n", + "\n", + " msg.submit(\n", + " fn=bot.respond, inputs=[msg, chatbot], outputs=[msg, chatbot], queue=False\n", + " )\n", + " clear.click(lambda: None, None, chatbot, queue=False).then(bot.reset)\n", + " demo.launch(\n", + " auth=(\n", + " os.environ[\"GRADIO_DEMO_USERNAME\"],\n", + " os.environ[\"GRADIO_DEMO_PASSWORD\"],\n", + " )\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load environment for the demo" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running on local URL: http://127.0.0.1:7862\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + } + ], + "source": [ + "load_dotenv()\n", + "launch_demo()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "import nbdev\n", + "\n", + "nbdev.nbdev_export()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/nbs/02_lchain_tool.ipynb b/nbs/02_lchain_tool.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..158c00d0555cafc647f7fdb8fc92586b9723add1 --- /dev/null +++ b/nbs/02_lchain_tool.ipynb @@ -0,0 +1,1986 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# lchain_tool\n", + "\n", + "> Exploring Langchain Tool capabilities" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| default_exp lchain_tool" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "from nbdev.showdoc import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "import os\n", + "\n", + "from IPython.display import Image\n", + "from langchain.agents import AgentType, Tool, initialize_agent, load_tools\n", + "from langchain.agents.agent_toolkits import create_python_agent\n", + "from langchain.chat_models import ChatOpenAI\n", + "from langchain.python import PythonREPL\n", + "from langchain.tools.python.tool import PythonREPLTool\n", + "from langchain.utilities import GoogleSerperAPIWrapper, SerpAPIWrapper\n", + "from serpapi import GoogleSearch" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from dotenv import load_dotenv" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "load_dotenv()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "llm = ChatOpenAI(temperature=0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tools = load_tools([\"llm-math\"], llm=llm)\n", + "agent = initialize_agent(\n", + " tools,\n", + " llm,\n", + " agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,\n", + " handle_parsing_errors=True,\n", + " verbose=True,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new AgentExecutor chain...\u001b[0m\n", + "\u001b[32;1m\u001b[1;3mWe can calculate this using the Calculator tool.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"0.03 * 300 * 30\"\n", + "}\n", + "```\n", + "\n", + "\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: This is the correct answer to the question.\u001b[0m\n", + "Observation: Invalid or incomplete response\n", + "Thought:\u001b[32;1m\u001b[1;3mLet me try the same action again.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"0.03 * 300 * 30\"\n", + "}\n", + "```\n", + "\n", + "\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mCould not parse LLM output: The tool gave the same answer, so I can be confident that it is correct.\n", + "\u001b[0m\n", + "Observation: Invalid or incomplete response\n", + "Thought:\u001b[32;1m\u001b[1;3mThere seems to be an issue with the LLM response. Let me try a different way to calculate the answer.\n", + "\n", + "Action:\n", + "```\n", + "{\n", + " \"action\": \"Calculator\",\n", + " \"action_input\": \"300 * 30 * 0.03\"\n", + "}\n", + "```\n", + "\n", + "\u001b[0m\n", + "Observation: \u001b[36;1m\u001b[1;3mAnswer: 270.0\u001b[0m\n", + "Thought:\u001b[32;1m\u001b[1;3mI have successfully calculated the answer to the question using the calculator tool.\n", + "\n", + "Final Answer: 270.0\u001b[0m\n", + "\n", + "\u001b[1m> Finished chain.\u001b[0m\n" + ] + }, + { + "data": { + "text/plain": [ + "{'input': 'What is the 3% of of 300 * 30?', 'output': '270.0'}" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "agent(\"What is the 3% of of 300 * 30?\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[SerpAPI Google Images](https://python.langchain.com/en/latest/modules/agents/tools/examples/google_serper.html#searching-for-google-images)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'title': 'Easy Tofu Pad Thai',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'source': 'Minimalist Baker',\n", + " 'rating': 4.9,\n", + " 'reviews': 117,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Pad thai rice',\n", + " 'peanut sauce',\n", + " 'thai red',\n", + " 'soy sauce',\n", + " 'bean sprouts']},\n", + " {'title': 'Vegan Pad Thai',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'source': 'Nora Cooks',\n", + " 'rating': 5.0,\n", + " 'reviews': 53,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Stir fry rice',\n", + " 'mung bean sprouts',\n", + " 'soy sauce',\n", + " 'maple syrup',\n", + " 'sriracha hot sauce']},\n", + " {'title': 'Vegan Pad Thai',\n", + " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n", + " 'source': 'Pick Up Limes',\n", + " 'rating': 5.0,\n", + " 'reviews': 34,\n", + " 'total_time': '30 min',\n", + " 'ingredients': ['Brown rice noodles',\n", + " 'red hot',\n", + " 'soy sauce',\n", + " 'bean sprouts',\n", + " 'sriracha hot sauce']}]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "params = {\n", + " \"q\": \"Vegan pad thai recipes\",\n", + " \"location\": \"United States\",\n", + " \"hl\": \"en\",\n", + " \"gl\": \"us\",\n", + " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", + "}\n", + "\n", + "search = GoogleSearch(params)\n", + "results = search.get_dict()\n", + "recipes_results = results[\"recipes_results\"]\n", + "recipes_results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "### SerpAPIWrapper\n", + "\n", + "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", + "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None,\n", + "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ], + "text/plain": [ + "---\n", + "\n", + "### SerpAPIWrapper\n", + "\n", + "> SerpAPIWrapper (search_engine:Any=None, params:dict={'engine': 'google',\n", + "> 'google_domain': 'google.com', 'gl': 'us', 'hl': 'en'},\n", + "> serpapi_api_key:Optional[str]=None,\n", + "> aiosession:Optional[aiohttp.client.ClientSession]=None)\n", + "\n", + "Wrapper around SerpAPI.\n", + "\n", + "To use, you should have the ``google-search-results`` python package installed,\n", + "and the environment variable ``SERPAPI_API_KEY`` set with your API key, or pass\n", + "`serpapi_api_key` as a named parameter to the constructor.\n", + "\n", + "Example:\n", + " .. code-block:: python\n", + "\n", + " from langchain import SerpAPIWrapper\n", + " serpapi = SerpAPIWrapper()" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "show_doc(SerpAPIWrapper)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "class RecipeSerpAPIWrapper(SerpAPIWrapper):\n", + " @staticmethod\n", + " def _process_response(res: dict) -> str:\n", + " \"\"\"Process response from SerpAPI.\"\"\"\n", + " if \"error\" in res.keys():\n", + " raise ValueError(f\"Got error from SerpAPI: {res['error']}\")\n", + " if \"recipes_results\" in res.keys():\n", + " return res[\"recipes_results\"]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "params = {\n", + " \"location\": \"United States\",\n", + " \"hl\": \"en\",\n", + " \"gl\": \"us\",\n", + "}\n", + "search = RecipeSerpAPIWrapper(params=params)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'title': 'Easy Vegan Fried Rice',\n", + " 'link': 'https://minimalistbaker.com/easy-vegan-fried-rice/',\n", + " 'source': 'Minimalist Baker',\n", + " 'rating': 4.8,\n", + " 'reviews': 457,\n", + " 'total_time': '1 hr 15 min',\n", + " 'ingredients': ['Peanut butter',\n", + " 'grain brown rice',\n", + " 'soy sauce',\n", + " 'maple syrup',\n", + " 'chili garlic sauce']},\n", + " {'title': 'The Best Vegan Fried Rice',\n", + " 'link': 'https://shortgirltallorder.com/best-vegan-fried-rice',\n", + " 'source': 'Short Girl Tall Order',\n", + " 'rating': 4.8,\n", + " 'reviews': 65,\n", + " 'total_time': '28 min',\n", + " 'ingredients': ['Soy sauce',\n", + " 'white rice',\n", + " 'rice wine vinegar',\n", + " 'sugar',\n", + " 'fresh peas']},\n", + " {'title': 'Vegan Fried Rice',\n", + " 'link': 'https://www.noracooks.com/vegan-fried-rice/',\n", + " 'source': 'Nora Cooks',\n", + " 'rating': 5.0,\n", + " 'reviews': 15,\n", + " 'total_time': '20 min',\n", + " 'ingredients': ['Gluten free',\n", + " 'nutritional yeast',\n", + " 'toasted sesame oil',\n", + " 'carrots',\n", + " 'olive oil']}]" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "vegan_recipes = search.run(\"Vegan fried rice recipes\")\n", + "vegan_recipes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'search_metadata': {'id': '647fff28b7b1ccd51d11a01d',\n", + " 'status': 'Success',\n", + " 'json_endpoint': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.json',\n", + " 'created_at': '2023-06-07 03:53:12 UTC',\n", + " 'processed_at': '2023-06-07 03:53:12 UTC',\n", + " 'google_images_url': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&oq=Vegan+pad+thai+recipes&uule=w+CAIQICINVW5pdGVkIFN0YXRlcw&hl=en&gl=us&tbm=isch',\n", + " 'raw_html_file': 'https://serpapi.com/searches/b57d5407e6517b3e/647fff28b7b1ccd51d11a01d.html',\n", + " 'total_time_taken': 10.18},\n", + " 'search_parameters': {'engine': 'google_images',\n", + " 'q': 'Vegan pad thai recipes',\n", + " 'location_requested': 'United States',\n", + " 'location_used': 'United States',\n", + " 'google_domain': 'google.com',\n", + " 'hl': 'en',\n", + " 'gl': 'us',\n", + " 'device': 'desktop'},\n", + " 'search_information': {'image_results_state': 'Results for exact spelling',\n", + " 'menu_items': [{'position': 1,\n", + " 'title': 'All',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEAI',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 2,\n", + " 'title': 'Videos',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=vid&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEAQ',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_videos&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 3, 'title': 'Images'},\n", + " {'position': 4,\n", + " 'title': 'Shopping',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=shop&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEAg',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google_shopping&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes'},\n", + " {'position': 5,\n", + " 'title': 'Maps',\n", + " 'link': 'https://maps.google.com/maps?q=Vegan+pad+thai+recipes&source=lmns&entry=mc&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAR6BAgBEAo'},\n", + " {'position': 6,\n", + " 'title': 'Books',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=bks&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAB6BAgBEA0'},\n", + " {'position': 7,\n", + " 'title': 'News',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=nws&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAF6BAgBEA4',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&q=Vegan+pad+thai+recipes&tbm=nws'},\n", + " {'position': 8,\n", + " 'title': 'Flights',\n", + " 'link': 'https://www.google.com/travel/flights?q=Vegan+pad+thai+recipes&source=lmns&tbm=flm&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAJ6BAgBEA8'},\n", + " {'position': 9,\n", + " 'title': 'Finance',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&source=lmns&tbm=fin&gl=us&hl=en&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q0pQJKAN6BAgBEBA'}]},\n", + " 'suggested_searches': [{'name': 'rice noodles',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAHoECAEQKw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:rice+noodles:gk0lY1Ku8x8%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Arice%2Bnoodles%3Agk0lY1Ku8x8%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b7f361a9f8fb38098b46394cb9c659c83.jpeg'},\n", + " {'name': 'gluten free',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAXoECAEQLQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:gluten+free:_Jv5VE84jYQ%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Agluten%2Bfree%3A_Jv5VE84jYQ%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba4acd7acf58a4e539824754bccf790f0.jpeg'},\n", + " {'name': 'tofu',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoAnoECAEQLw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:tofu:EdnrGNBK_3E%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Atofu%3AEdnrGNBK_3E%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b57cb6349f17e3b4997748a7fb2213981.jpeg'},\n", + " {'name': 'thai peanut sauce',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoA3oECAEQMQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+peanut+sauce:AOyraWKuKIU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bpeanut%2Bsauce%3AAOyraWKuKIU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2bc44c0d5d0eef2c4dfefe036887628a3c.jpeg'},\n", + " {'name': 'vegan gluten',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBHoECAEQMw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:vegan+gluten:YD_J3kTgidI%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Avegan%2Bgluten%3AYD_J3kTgidI%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b631482aae166e90902888b39f9df86d4.jpeg'},\n", + " {'name': 'thai food',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBXoECAEQNQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+food:0nWr99Uxrwc%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Bfood%3A0nWr99Uxrwc%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3abb47a217c7337c6259316ffb3146b6.jpeg'},\n", + " {'name': 'thai tofu pad',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoBnoECAEQNw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:thai+tofu+pad:-u5KMb62hFM%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Athai%2Btofu%2Bpad%3A-u5KMb62hFM%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2ba9dc874972edb8879d31906ca8d02d1e.jpeg'},\n", + " {'name': 'food network',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoB3oECAEQOQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:food+network:4fsBYIFuk6M%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afood%2Bnetwork%3A4fsBYIFuk6M%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3542cf3034c40352d8800de25efd446c.jpeg'},\n", + " {'name': 'peanut butter',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCHoECAEQOw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:peanut+butter:FJXMrvqXmOU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Apeanut%2Bbutter%3AFJXMrvqXmOU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b5b6523f5ed417f4c899d005473ba16b5.jpeg'},\n", + " {'name': 'stir fry',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCXoECAEQPQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:stir+fry:o0twgEKDva0%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Astir%2Bfry%3Ao0twgEKDva0%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3337398b3fc538d59c1a2d960953452d.jpeg'},\n", + " {'name': 'plant based',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoCnoECAEQPw',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:plant+based:6BEj1Wk084g%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Aplant%2Bbased%3A6BEj1Wk084g%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2b3d37839120548e6228cc4e71e1b7c7af.jpeg'},\n", + " {'name': 'fried tofu',\n", + " 'link': 'https://www.google.com/search?q=Vegan+pad+thai+recipes&tbm=isch&hl=en&gl=us&chips=q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D&sa=X&ved=2ahUKEwiEnJSdobD_AhWTE1kFHecGCJ4Q4lYoC3oECAEQQQ',\n", + " 'chips': 'q:vegan+pad+thai+recipes,online_chips:fried+tofu:EpVuI9_hNoU%3D',\n", + " 'serpapi_link': 'https://serpapi.com/search.json?chips=q%3Avegan%2Bpad%2Bthai%2Brecipes%2Conline_chips%3Afried%2Btofu%3AEpVuI9_hNoU%253D&device=desktop&engine=google_images&gl=us&google_domain=google.com&hl=en&location=United+States&q=Vegan+pad+thai+recipes',\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/a55ec478bf73d4bcc2fb5b01f1529f2be19daee44662280115fa006abc2bf75b.jpeg'}],\n", + " 'images_results': [{'position': 1,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a28ca4ca4a3abf6af168f575eef7bd2e8f81a12e175fcf53.jpeg',\n", + " 'related_content_id': 'aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFRiaDN5TnVsUkxUbE1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/Easy-Vegan-Pad-Thai-SQUARE.jpg',\n", + " 'original_width': 1452,\n", + " 'original_height': 1453,\n", + " 'is_product': True},\n", + " {'position': 2,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822a79ad529f726d1a65fdd09459c0a0b6a.jpeg',\n", + " 'related_content_id': 'RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RGJrQjdJY0VUdHpFak1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Thai-Recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 3,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3695828a207980e4280bb4e14cdccb84ebf5350f19237416f8.jpeg',\n", + " 'related_content_id': 'b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=b3RSNEh0U2h3MkxNQ01cIixcIkRyYnlKUWQ1RnFmc1RN',\n", + " 'source': 'Lazy Cat Kitchen',\n", + " 'title': 'Healthier vegan pad thai - Lazy Cat Kitchen',\n", + " 'link': 'https://www.lazycatkitchen.com/healthier-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2021/01/healthier-vegan-pad-thai-macro-1024x1536.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 4,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36885ca51553e15b434e41039ef307ecbb4869522eeeefcfa5.jpeg',\n", + " 'related_content_id': 'akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=akFDYVpJNDhFcmVMN01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'source': 'Full of Plants',\n", + " 'title': 'The Best Vegan Pad Thai - Full of Plants',\n", + " 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://fullofplants.com/wp-content/uploads/2022/03/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-thumb.jpg',\n", + " 'original_width': 1440,\n", + " 'original_height': 1440,\n", + " 'is_product': True},\n", + " {'position': 5,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a554bfded8055a9df50470d25fe62e19b9de5f16e262497f.jpeg',\n", + " 'related_content_id': 'MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MG9uZ1JON0pQMkRTWk1cIixcImtEc004Sm4xbEhDUVRN',\n", + " 'source': 'earthofmaria.com',\n", + " 'title': 'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria',\n", + " 'link': 'https://earthofmaria.com/easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://earthofmaria.com/wp-content/uploads/2019/04/Easy-Vegan-Pad-Thai-Gluten-free-6.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 6,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36f9a1c02c421efe07d8d147f542087ff245f0933ec60896cd.jpeg',\n", + " 'related_content_id': 'N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=N2lGVE5zbnFWNmNpV01cIixcImVHWEY5TnlPVFpndGhN',\n", + " 'source': 'My Darling Vegan',\n", + " 'title': 'Easy Vegan Pad Thai - My Darling Vegan',\n", + " 'link': 'https://www.mydarlingvegan.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.mydarlingvegan.com/wp-content/uploads/2021/07/Vegan-Pad-Thai-2.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 7,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36a75a0136dd1f95918c9bb1ded2f17e5c31f13d3708cc723f.jpeg',\n", + " 'related_content_id': 'NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NDBJVGUxMWp6VmhoQU1cIixcIkE0bF9LaG50aXJUdS1N',\n", + " 'source': 'Pinch Me Good',\n", + " 'title': 'Easy Vegetarian Pad Thai - Pinch Me Good',\n", + " 'link': 'https://pinchmegood.com/easy-vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://pinchmegood.com/wp-content/uploads/2019/03/Easy-Vegetarian-Pad-Thai.jpg',\n", + " 'original_width': 924,\n", + " 'original_height': 1386,\n", + " 'is_product': True},\n", + " {'position': 8,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36cdf1d570098da37da75a20a5a2ed59916c3cc1ac656f5b45.jpeg',\n", + " 'related_content_id': 'NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVI5WlhqODdqY3dQdE1cIixcIlJTVVkycEFmRGJQQlVN',\n", + " 'source': 'Vegan Huggs',\n", + " 'title': '30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs',\n", + " 'link': 'https://veganhuggs.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veganhuggs.com/wp-content/uploads/2019/03/vegan-pad-thai-3.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 1020,\n", + " 'is_product': True},\n", + " {'position': 9,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd364677ba205872944cc9932a27c40873a1e3f4424ca6219c9b.jpeg',\n", + " 'related_content_id': 'OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=OV9FdUNLV0Q1RFNaVE1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'source': 'Ministry of Curry',\n", + " 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n", + " 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-1.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 10,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd3600f3b428f18999842a7c3ddc41991cd1d626950bd108397d.jpeg',\n", + " 'related_content_id': 'bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzd5Tzg0TGkwdVo4U01cIixcInVXNm1FMjU0TjY5SHFN',\n", + " 'source': 'Lazy Cat Kitchen',\n", + " 'title': 'Vegan pad thai - Lazy Cat Kitchen',\n", + " 'link': 'https://www.lazycatkitchen.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn77-s3.lazycatkitchen.com/wp-content/uploads/2016/05/vegan-pad-thai-1000x1500.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1500,\n", + " 'is_product': True},\n", + " {'position': 11,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224470ef6b1b3462b418875bdedefa3d79.jpeg',\n", + " 'related_content_id': 'NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NmlRemZjMjdsNGVDWk1cIixcIllkSTZvdWJFcWFZVkVN',\n", + " 'source': 'Well Plated by Erin',\n", + " 'title': 'Vegetarian Pad Thai {30-Minute Recipe} - WellPlated.com',\n", + " 'link': 'https://www.wellplated.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.wellplated.com/wp-content/uploads/2017/08/Healthy-Vegetarian-Pad-Thai.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1469,\n", + " 'is_product': True},\n", + " {'position': 12,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82276df3b8fda0d0c061010978e4b536cc1.jpeg',\n", + " 'related_content_id': 'WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WHlGMzJXNTJQbHg1ME1cIixcImdGaHFxbXAwOUtkMUlN',\n", + " 'source': 'The Spruce Eats',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.thespruceeats.com/vegetarian-pad-thai-3217746',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thespruceeats.com/thmb/wF19pUZKaKo66pofbpjI0eS1SLc=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/vegetarian-pad-thai-3217746-step-11-231a859fac40430583b044297aaf4a87.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 13,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82281ba3f6ced7a769ced6de3c3b0f1fe41.jpeg',\n", + " 'related_content_id': 'MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MDBRd2hGRzdGMG1rTU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/Y6WvULetSWWIjzcQONSg9n8PFgg=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-2f0142cca68e4f9592381d281a391d59.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 14,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8224df1973dd2dbff9bcbe3402164ae150c.jpeg',\n", + " 'related_content_id': 'bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bzVOdWdXQUItLUZYOE1cIixcIldwNnpKWXhpbzhQSEdN',\n", + " 'source': 'Food Network',\n", + " 'title': 'Vegetarian Pad Thai Recipe | Food Network Kitchen | Food Network',\n", + " 'link': 'https://www.foodnetwork.com/recipes/food-network-kitchen/vegetarian-pad-thai-7183115',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2019/9/10/0/FNK_Vegetarian-Tofu-Pad-Thai_H2_s4x3.jpg.rend.hgtvcom.616.462.suffix/1568385716096.jpeg',\n", + " 'original_width': 616,\n", + " 'original_height': 462,\n", + " 'is_product': True},\n", + " {'position': 15,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822ed36be9df00a80e5203ab96f92fc31fd.jpeg',\n", + " 'related_content_id': 'RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RjhuaUxEaExUek9Ebk1cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'source': 'Bianca Zapatka',\n", + " 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n", + " 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/pad-thai-vegan-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-720x1008.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 1008,\n", + " 'is_product': True},\n", + " {'position': 16,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8223cb49bc3c204d16373a0a6e257d6e54f.jpeg',\n", + " 'related_content_id': 'UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UmZJNlhwUEVOZnZZa01cIixcImZZcTdhazBsMzJwVnJN',\n", + " 'source': 'EatPlant-Based.com',\n", + " 'title': 'Easy Vegan Pad Thai - EatPlant-Based',\n", + " 'link': 'https://eatplant-based.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://eatplant-based.com/wp-content/uploads/2022/03/Awakened-Pad-Thai-3.jpeg',\n", + " 'original_width': 668,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 17,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225dcace1e2fb2aebe208ed1bfde7e8775.jpeg',\n", + " 'related_content_id': 'UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHFZekVfb09HbXJzME1cIixcIllWX18xZmNxVktjOEJN',\n", + " 'source': 'Taste of Home',\n", + " 'title': 'Vegetarian Pad Thai Recipe: How to Make It',\n", + " 'link': 'https://www.tasteofhome.com/recipes/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://tmbidigitalassetsazure.blob.core.windows.net/rms3-prod/attachments/37/1200x1200/Vegetarian-Pad-Thai_EXPS_HCK18_197935_B04_014_4b.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 18,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c82263e484cb2a264123c087cf8b9eb10c0d.jpeg',\n", + " 'related_content_id': 'djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=djBzUlhFMkVqTUJ1VU1cIixcIjV6ZTZfb285ZmZXckFN',\n", + " 'source': 'Taste',\n", + " 'title': '10-minute vegetarian pad Thai recipe',\n", + " 'link': 'https://www.taste.com.au/recipes/10-minute-vegetarian-pad-thai-recipe/4bq39nic',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://img.taste.com.au/jgHrD_eG/w720-h480-cfill-q80/taste/2021/02/10-minute-vegetarian-pad-thai-168946-2.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 480,\n", + " 'is_product': True},\n", + " {'position': 19,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c822f423edd39d8f9d0285cc270a8c00a7ee.jpeg',\n", + " 'related_content_id': 'ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZjVXNnIxeExuVFlGUk1cIixcIjdzb3JhQzJVd3Fvcm5N',\n", + " 'source': 'YouTube',\n", + " 'title': 'Vegetarian Pad Thai Recipe TO MAKE TONIGHT (ผัดไทย)! - YouTube',\n", + " 'link': 'https://www.youtube.com/watch?v=zy_P70hXhdM',\n", + " 'tag': '8:44',\n", + " 'original': 'https://i.ytimg.com/vi/zy_P70hXhdM/maxresdefault.jpg',\n", + " 'original_width': 1280,\n", + " 'original_height': 720,\n", + " 'is_product': True},\n", + " {'position': 20,\n", + " 'thumbnail': 'https://serpapi.com/searches/647fff28b7b1ccd51d11a01d/images/6f34b4708ae4dd36dee6fed89369c8225cd1fe40684d95943ec058d4b84eb560.jpeg',\n", + " 'related_content_id': 'UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UHR0NTdlcWhhZmpGYk1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'source': 'Vegan Recipes from Cassie Howard',\n", + " 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n", + " 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 903,\n", + " 'is_product': True},\n", + " {'position': 21,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvfVfg8ufhxGbAvq1idiNghBJ-fXS2MqelDQ&usqp=CAU',\n", + " 'related_content_id': 'NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NVppWC1xN01sUlJJdU1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'source': 'Spice Cravings',\n", + " 'title': 'Vegan Pad Thai | Spice Cravings',\n", + " 'link': 'https://spicecravings.com/vegan-pad-thai',\n", + " 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 22,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTJ89CXPkap5RGkJHmeArqtTdY3pSO7w0DdNQ&usqp=CAU',\n", + " 'related_content_id': 'bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bF9ZRXVsUUpYMkdaSk1cIixcIjRSLXVUYlc5LXVFQkRN',\n", + " 'source': 'Pick Up Limes',\n", + " 'title': 'Vegan Pad Thai | Pick Up Limes',\n", + " 'link': 'https://www.pickuplimes.com/recipe/speedy-vegan-pad-thai-116',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://cdn.pickuplimes.com/cache/1d/72/1d7201d4341ab93affd3ecfec7a7d5a2.jpg',\n", + " 'original_width': 1280,\n", + " 'original_height': 1920,\n", + " 'is_product': True},\n", + " {'position': 23,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRzjMINzFCCY2VU4QrzHkzBsVvtiJHsoF4Apw&usqp=CAU',\n", + " 'related_content_id': 'MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=MU5vZ0E4Nzl1X0tBMU1cIixcIjVka2VfTFRxdWtYMGlN',\n", + " 'source': 'The Healthy Maven',\n", + " 'title': 'Veggie Pad Thai Recipe [20 Minutes] - The Healthy Maven',\n", + " 'link': 'https://www.thehealthymaven.com/pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thehealthymaven.com/wp-content/uploads/2020/03/veggie-pad-thai-4-1-e1583795458972.jpg',\n", + " 'original_width': 780,\n", + " 'original_height': 790,\n", + " 'is_product': True},\n", + " {'position': 24,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTcv-xbBlo4x_uqyZY7fN4xVDtd0keRb9zt2Q&usqp=CAU',\n", + " 'related_content_id': 'aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aEkwNFQxVDVtX3h5eE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'source': \"Del's cooking twist\",\n", + " 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n", + " 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3679.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1740,\n", + " 'is_product': True},\n", + " {'position': 25,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-3rXOoQrYAAnTPYimImLdkllhrvwGjtpzuQ&usqp=CAU',\n", + " 'related_content_id': 'cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cmIyRFFvQndTNlBrTE1cIixcIkNyRkZLOWlYS2ZDX19N',\n", + " 'source': \"Omnivore's Cookbook\",\n", + " 'title': \"Vegan Pad Thai - Omnivore's Cookbook\",\n", + " 'link': 'https://omnivorescookbook.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://omnivorescookbook.com/wp-content/uploads/2019/04/1401_Vegan-Pad-Thai_002.jpg',\n", + " 'original_width': 800,\n", + " 'original_height': 1198,\n", + " 'is_product': True},\n", + " {'position': 26,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRA6EbuGHJJ05llESu7R4DnXGJz0tLdAKHCag&usqp=CAU',\n", + " 'related_content_id': 'aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aFNpdVltbXI3QUN2NE1cIixcIldDRjR6OS16U04yMmdN',\n", + " 'source': 'plantd',\n", + " 'title': 'Vegan Pad Thai with Peanut Sauce',\n", + " 'link': 'https://plantd.co/vegan-pad-thai-with-peanut-sauce/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://plantd.co/wp-content/uploads/2020/03/Vegan-Pad-Thai-with-Peanut-Sauce.png',\n", + " 'original_width': 1600,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 27,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-tJjj9tbpEaxSJtIxspo7uUdJEUzv9RvOIg&usqp=CAU',\n", + " 'related_content_id': 'dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dXdZLTBjNUt3d3FKbE1cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'source': 'From My Bowl',\n", + " 'title': 'Vegan Pad Thai - From My Bowl',\n", + " 'link': 'https://frommybowl.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-19-1.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 28,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNiutaTkD8VXJuR7_mWK2pI6B7cPV98YJ1Yw&usqp=CAU',\n", + " 'related_content_id': 'NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NGlJclloYkcyM2NGOE1cIixcImJ3RG1sNS1NenhyWUFN',\n", + " 'source': 'The Foodie Takes Flight',\n", + " 'title': 'Vegan Pad Thai - The Foodie Takes Flight',\n", + " 'link': 'https://thefoodietakesflight.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://thefoodietakesflight.com/wp-content/uploads/2021/06/vegan-pad-thai-recipe-10.png',\n", + " 'original_width': 790,\n", + " 'original_height': 1150,\n", + " 'is_product': True},\n", + " {'position': 29,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQtjaP5_LFHgeZL956hjrCANLq2zxN0VcNuDw&usqp=CAU',\n", + " 'related_content_id': 'S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S0lXdzI0d3hGaE1EZk1cIixcIjZUTzYtQU1aTFM5OF9N',\n", + " 'source': 'One Ingredient Chef',\n", + " 'title': 'Vegetarian Pad Thai Recipe | One Ingredient Chef',\n", + " 'link': 'https://www.oneingredientchef.com/vegetarian-pad-thai/',\n", + " 'original': 'https://www.oneingredientchef.com/wp-content/uploads/2013/06/VegetarianPadThai.jpg',\n", + " 'original_width': 700,\n", + " 'original_height': 783,\n", + " 'is_product': False},\n", + " {'position': 30,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8a0V5sne-due2_0i_cLMG7mIDmIWWIlNdyg&usqp=CAU',\n", + " 'related_content_id': 'RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RlhhTjktX0VPaTlNYU1cIixcIkw2VUt4V3Y3ekhDRDZN',\n", + " 'source': 'Love and Good Stuff',\n", + " 'title': 'Vegetable Pad Thai - Love & Good Stuff',\n", + " 'link': 'https://loveandgoodstuff.com/vegetable-pad-thai/',\n", + " 'original': 'https://loveandgoodstuff.com/wp-content/uploads/2018/04/vegetable-pad-thai-6.jpg',\n", + " 'original_width': 669,\n", + " 'original_height': 1000,\n", + " 'is_product': False},\n", + " {'position': 31,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq76Wud8JULmlFchKPTVnyslWUxpH0-tSocw&usqp=CAU',\n", + " 'related_content_id': 'YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YzVZOWJhYlRWMlctVE1cIixcIklnNHdwT0w0bmVSc3RN',\n", + " 'source': 'Vibrant plate',\n", + " 'title': 'The Best Vegan Tofu Pad Thai - Vibrant plate',\n", + " 'link': 'https://www.vibrantplate.com/best-vegan-tofu-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.vibrantplate.com/wp-content/uploads/2021/01/Vegan-Tofu-Pad-Thai-05.jpg',\n", + " 'original_width': 800,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 32,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTMA_IXXqLXbDaKJStkocE79DhiNy3h1wNfyg&usqp=CAU',\n", + " 'related_content_id': 'X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1ZKT3RFSGJSQmEzS01cIixcImNGUVM5NFhpV2RpX21N',\n", + " 'source': 'From My Bowl',\n", + " 'title': 'Vegan Pad Thai - From My Bowl',\n", + " 'link': 'https://frommybowl.com/vegan-pad-thai/',\n", + " 'original': 'https://frommybowl.com/wp-content/uploads/2023/03/Vegan_Pad_Thai_FromMyBowl-23.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1500,\n", + " 'is_product': False},\n", + " {'position': 33,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUQbieaco9iYa16jcjeZbf-gmoP7gSvJyl0Q&usqp=CAU',\n", + " 'related_content_id': 'd1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d1BiY3hIQXlDcmhudU1cIixcInUzdzZ2dGVndVZIdU1N',\n", + " 'source': 'BBC',\n", + " 'title': 'Vegetable pad Thai recipe - BBC Food',\n", + " 'link': 'https://www.bbc.co.uk/food/recipes/stirfryvegetarianpha_70987',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://ichef.bbci.co.uk/food/ic/food_16x9_832/recipes/stirfryvegetarianpha_70987_16x9.jpg',\n", + " 'original_width': 832,\n", + " 'original_height': 468,\n", + " 'is_product': True},\n", + " {'position': 34,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT1WQnyJsXAny3gepgi_275uhe3V8VkQTMRtw&usqp=CAU',\n", + " 'related_content_id': 'U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=U3NtaEk3ZjFnRXJkVk1cIixcIlVCcDBBTHMzYkNQeURN',\n", + " 'source': 'Cilantro and Citronella',\n", + " 'title': 'Vegetarian Pad Thai',\n", + " 'link': 'https://www.cilantroandcitronella.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.cilantroandcitronella.com/wp-content/uploads/2015/03/pad-thai_1_04.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 1020,\n", + " 'is_product': True},\n", + " {'position': 35,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT9yCD2ZFN3V0txxVJK59VZKQw8dHdf52U_9w&usqp=CAU',\n", + " 'related_content_id': 'ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ckV1TXpfbkdkdml1dU1cIixcInhTcm00c05Fb3hsQ2xN',\n", + " 'source': 'Eat With Clarity',\n", + " 'title': 'Best Vegan Pad Thai (Easy!) - Eat With Clarity',\n", + " 'link': 'https://eatwithclarity.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://eatwithclarity.com/wp-content/uploads/2020/06/vegan-pad-thai-9.jpg',\n", + " 'original_width': 1190,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 36,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ-b-oobMM5KXLy32E-dTEmszExv0RTVq8OQQ&usqp=CAU',\n", + " 'related_content_id': 'VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VVRlMWhvVGJYdE1fdU1cIixcIjlueVA1ODMxR00ydG9N',\n", + " 'source': 'Tesco Real Food',\n", + " 'title': 'Vegetarian pad Thai | Tesco Real Food',\n", + " 'link': 'https://realfood.tesco.com/recipes/vegetarian-pad-thai.html',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://realfood.tesco.com/media/images/Veg-Pad-Thai-LGH-069d45e9-fd6c-44d1-b747-83dbac2d921d-0-1400x919.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 919,\n", + " 'is_product': True},\n", + " {'position': 37,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtwz03hn90q7ot7m4-179UzOn7cQYaLBHrnA&usqp=CAU',\n", + " 'related_content_id': 'aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aXRwNmlJU3VSVjh3b01cIixcIlIxQlU1Nk03SjU2V0VN',\n", + " 'source': 'Klaraslife',\n", + " 'title': 'Vegan Pad Thai with cashew butter & broccoli - Klara`s Life',\n", + " 'link': 'https://klaraslife.com/en/vegan-pad-thai-with-cashew-butter-broccoli/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://klaraslife.com/wp-content/uploads/2019/11/IMG_0935.jpg',\n", + " 'original_width': 4000,\n", + " 'original_height': 5895,\n", + " 'is_product': True},\n", + " {'position': 38,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQDKEP2qkfB6nWHtF58pTBj7TJv2Jz63JYOw&usqp=CAU',\n", + " 'related_content_id': 'Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ml9EcEtuVmZzaGYwa01cIixcIlVuQncwamxaTk5zdUlN',\n", + " 'source': 'Fit Foodie Nutter',\n", + " 'title': '30 MINUTE EASY VEGAN PAD THAI –',\n", + " 'link': 'https://fitfoodienutter.com/recipe/30-minute-easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://fitfoodienutter.com/wp-content/uploads/2021/09/Vegan-Pad-Thai-12.jpg',\n", + " 'original_width': 870,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 39,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIadiylajWRN_JnkLntJZSunU8qi7S1wxGvQ&usqp=CAU',\n", + " 'related_content_id': 'SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SF9PdVVtTWxUWUtlQk1cIixcIjZLRUp3cjRHNFl1XzdN',\n", + " 'source': 'Gimme Some Oven',\n", + " 'title': 'Pad Thai - Gimme Some Oven',\n", + " 'link': 'https://www.gimmesomeoven.com/pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.gimmesomeoven.com/wp-content/uploads/2019/01/Pad-Thai-Recipe-1.jpg',\n", + " 'original_width': 1392,\n", + " 'original_height': 2088,\n", + " 'is_product': True},\n", + " {'position': 40,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRIpRVuMoifY2CKjWhZ_37sDaI5hp1tAw5T1Q&usqp=CAU',\n", + " 'related_content_id': 'SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SVBSMXpMeF9zbjlhT01cIixcImp3N3I0SlpfRkRqbnFN',\n", + " 'source': 'The Kitchen Abroad',\n", + " 'title': 'Quick One Pan Vegan Pad Thai Recipe with Tofu',\n", + " 'link': 'https://www.thekitchenabroad.com/one-pan-vegan-pad-thai-recipe-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thekitchenabroad.com/wp-content/uploads/2020/06/Vegan-Pad-Thai-Recipe-with-Tofu-10.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1365,\n", + " 'is_product': True},\n", + " {'position': 41,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTkI3AiNwZau82RGak_znF-NEWDMatcRdQ_2Q&usqp=CAU',\n", + " 'related_content_id': 'SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SHRlUEJFQWZLVUQ1ak1cIixcIklIaFQ0dmRrbl9BYURN',\n", + " 'source': 'Food Network',\n", + " 'title': 'Quick Veggie Pad Thai Recipe | Ree Drummond | Food Network',\n", + " 'link': 'https://www.foodnetwork.com/recipes/ree-drummond/quick-veggie-pad-thai-9422028',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://food.fnr.sndimg.com/content/dam/images/food/fullset/2020/09/25/WU2503__vegetable-pad-thai_s4x3.jpg.rend.hgtvcom.616.462.suffix/1601058180561.jpeg',\n", + " 'original_width': 616,\n", + " 'original_height': 462,\n", + " 'is_product': True},\n", + " {'position': 42,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRJRZhgKxI1FzkCO0zB3RxLW1vAsi4WwL0Y7w&usqp=CAU',\n", + " 'related_content_id': 'aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aVBNMGFkVWpFZWg1VU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'source': 'Delish Knowledge',\n", + " 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n", + " 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles5-copy-1.jpg',\n", + " 'original_width': 1000,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 43,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSGA5db-ShQpar2dyZk0cAxA4-cdHYsisG3g&usqp=CAU',\n", + " 'related_content_id': 'Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y2Y5SzBCanIyUkg3MU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'source': 'Six Hungry Feet',\n", + " 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n", + " 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n", + " 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-10.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1500,\n", + " 'is_product': False},\n", + " {'position': 44,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQolfY7XMQv1Q3zJr8XCj0pasBRTBn7MrJocA&usqp=CAU',\n", + " 'related_content_id': 'Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Mk1tTjItRjk4dHhIc01cIixcImg0dTVaclVEN0dabWlN',\n", + " 'source': 'White On Rice Couple',\n", + " 'title': 'Vegetable Pad Thai Recipe w/ Cabbage EASY HEALTHY | White On Rice',\n", + " 'link': 'https://whiteonricecouple.com/cabbage-vegetable-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://whiteonricecouple.com/recipe/images/Cabbage-Vegetable-Pad-Thai-1.jpg',\n", + " 'original_width': 530,\n", + " 'original_height': 699,\n", + " 'is_product': True},\n", + " {'position': 45,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSium1YAIBcY-ty66CcxIZfjPydnxVlddWGwQ&usqp=CAU',\n", + " 'related_content_id': 'VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VTRTMnZqRks3dm83aU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-14.jpg',\n", + " 'original_width': 1456,\n", + " 'original_height': 2184,\n", + " 'is_product': False},\n", + " {'position': 46,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT_1bo3u0kxqiO87hkxwyR5bhvZtWff-OdRRA&usqp=CAU',\n", + " 'related_content_id': 'dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dzZjWThrTVJjbWZySU1cIixcIk9tQkpZN0tPYXJxcU5N',\n", + " 'source': 'Make It Dairy Free',\n", + " 'title': 'Vegan Pad Thai - Make It Dairy Free',\n", + " 'link': 'https://makeitdairyfree.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://makeitdairyfree.com/wp-content/uploads/2022/12/vegan-pad-thai-2.jpg',\n", + " 'original_width': 736,\n", + " 'original_height': 1104,\n", + " 'is_product': True},\n", + " {'position': 47,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSW5-PJKenKvHTGKrhmzwyhhFUlvEkg25eRuQ&usqp=CAU',\n", + " 'related_content_id': 'WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WWZTcjM0TVZwMHp2Y01cIixcIkNCS1JvOVlSUHBod09N',\n", + " 'source': 'Bianca Zapatka',\n", + " 'title': 'Vegan Pad Thai with Veggie Noodles & Tofu - Bianca Zapatka | Recipes',\n", + " 'link': 'https://biancazapatka.com/en/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://biancazapatka.com/wp-content/uploads/2019/05/vegan-pad-thai-recipe-easy-healthy-crispy-tofu-veggie-noodles-peanut-sauce-creamy-pasta-stir-fry-gemuese-nudeln-zoodles-rezept-asian-food.jpg',\n", + " 'original_width': 1440,\n", + " 'original_height': 2016,\n", + " 'is_product': True},\n", + " {'position': 48,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRiWrdDbuV_CM0exB7yBqyoCOWaYqD6nTtJQ&usqp=CAU',\n", + " 'related_content_id': 'T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=T01IckRwTlB6Sm1OR01cIixcIk9XZExvUTkzREJkd3BN',\n", + " 'source': 'Running on Real Food',\n", + " 'title': 'Easy Vegan Tofu Pad Thai Recipe - Running on Real Food',\n", + " 'link': 'https://runningonrealfood.com/tofu-pad-thai/',\n", + " 'original': 'https://runningonrealfood.com/wp-content/uploads/2021/05/Best-Vegan-Tofu-Pad-Thai-Recipe-12.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 2100,\n", + " 'is_product': False},\n", + " {'position': 49,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTtOw74y8VyL5dib33Rkr_Bu4Jo9K4Q3sJy1w&usqp=CAU',\n", + " 'related_content_id': 'Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ym1IcVh5VENheWpLMU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/zH71oEuQnxw3B8536gZDM2_NkWI=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-3-f47ff2bc806b4de9821e332a6126bcc1.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 2250,\n", + " 'is_product': True},\n", + " {'position': 50,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPCaY87F2KeBqK2WQUNljTakrtO7Zlae5L4g&usqp=CAU',\n", + " 'related_content_id': 'M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M1U2cWZ0c0YybEYzWk1cIixcIjRVaFFibWlwS1IzeGtN',\n", + " 'source': 'Whitney Bond',\n", + " 'title': 'Vegetable Pad Thai Recipe - WhitneyBond.com',\n", + " 'link': 'https://whitneybond.com/whats-for-dinner-spicy-vegetable-pad-thai/',\n", + " 'original': 'https://whitneybond.com/wp-content/uploads/2013/01/Vegetable-Pad-Thai-4.jpg',\n", + " 'original_width': 1140,\n", + " 'original_height': 1280,\n", + " 'is_product': False},\n", + " {'position': 51,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSDWkQoMHapJVpYkNaQJbPyubSBwdP5is9eaw&usqp=CAU',\n", + " 'related_content_id': 'eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eExnY1pCejNkeHF5TU1cIixcImxKd1RjVTctblFKVkVN',\n", + " 'source': 'Six Hungry Feet',\n", + " 'title': 'Vegan Pad Thai with Tofu - Six Hungry Feet',\n", + " 'link': 'https://sixhungryfeet.com/vegetarian-pad-thai-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://sixhungryfeet.com/wp-content/uploads/2022/02/Vegan-Pad-Thai-with-Tofu-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1500,\n", + " 'is_product': True},\n", + " {'position': 52,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQxAM2SH_lgbsUJZh0aljTp6OEQ0lNfSd2_BQ&usqp=CAU',\n", + " 'related_content_id': 'cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cEhDT3AyZFVNMFJfeE1cIixcIkpENEZWRGhnWm9oLWdN',\n", + " 'source': \"Mom's Dinner\",\n", + " 'title': \"The Best Vegetable Pad Thai - Mom's Dinner\",\n", + " 'link': 'https://momsdinner.net/vegetable-pad-thai/',\n", + " 'original': 'https://momsdinner.net/wp-content/uploads/2021/04/Vegetable-Pad-Thai-Recipe-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1680,\n", + " 'is_product': False},\n", + " {'position': 53,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQwMUvtpa5kSIoAJ3kltgwtiuUYkvK9DJyg3w&usqp=CAU',\n", + " 'related_content_id': 'NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NUNBNnpReG1HLVhJYk1cIixcIjlhbXFYUi1CUXZVRGdN',\n", + " 'source': 'From The Comfort Of My Bowl',\n", + " 'title': 'Easy Vegan Pad Thai - From The Comfort Of My Bowl',\n", + " 'link': 'https://www.fromthecomfortofmybowl.com/vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.fromthecomfortofmybowl.com/wp-content/uploads/2021/03/best-vegan-pad-thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 900,\n", + " 'is_product': True},\n", + " {'position': 54,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRPqWPCZyN1t4YbQNSYBWPLWSwzenu1C7a52A&usqp=CAU',\n", + " 'related_content_id': 'ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZUp6VWVaSjNFSFV2NU1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'source': 'Nora Cooks',\n", + " 'title': 'Vegan Pad Thai - Nora Cooks',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-5.jpg',\n", + " 'original_width': 1334,\n", + " 'original_height': 2001,\n", + " 'is_product': False},\n", + " {'position': 55,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREUFAdGtWRgMx9Qv45bdNbkRdlZnSFQZX7tQ&usqp=CAU',\n", + " 'related_content_id': 'bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bnhBOTRJZDBTNWx2SE1cIixcImhmYVFITHA0RWpPOG9N',\n", + " 'source': 'Vegan Heaven',\n", + " 'title': 'Vegan Pad Thai - Vegan Heaven',\n", + " 'link': 'https://veganheaven.org/recipe/vegan-pad-thai/',\n", + " 'original': 'https://veganheaven.org/wp-content/uploads/2019/04/Vegan-Pad-Thai_.jpg',\n", + " 'original_width': 680,\n", + " 'original_height': 900,\n", + " 'is_product': False},\n", + " {'position': 56,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQW5Nh8vx1J5kcDtF7MZSnXljnKoalv8wq2RA&usqp=CAU',\n", + " 'related_content_id': 'cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cHNMbm5ZOXRrWTFldk1cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-1-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 57,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRUtq_lbZ4d5Xfs2jW-qamRXEi-0T6rhsLjTg&usqp=CAU',\n", + " 'related_content_id': 'bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bEtyRElTc2lqZmp3VU1cIixcIms0TnRQM1hTNk9KaWpN',\n", + " 'source': 'The Petite Cook',\n", + " 'title': 'The Easiest Vegan Pad Thai - The Petite Cook™',\n", + " 'link': 'https://www.thepetitecook.com/the-easiest-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.thepetitecook.com/wp-content/uploads/2017/03/vegan-pad-thai-recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 58,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4uozc69jm3VWqxSKMG8hWocGvUtO4CXHPeA&usqp=CAU',\n", + " 'related_content_id': 'cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cW1Md3FPOHhsMU1qcU1cIixcIjV2ZXlPLWxUTmp5S29N',\n", + " 'source': 'Food with Feeling',\n", + " 'title': 'Vegan Pad Thai - Food with Feeling',\n", + " 'link': 'https://foodwithfeeling.com/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://foodwithfeeling.com/wp-content/uploads/2021/02/Vegan-Pad-Thai-7.jpg',\n", + " 'original_width': 700,\n", + " 'original_height': 1050,\n", + " 'is_product': True},\n", + " {'position': 59,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcShtayJD_o-2NYDRaFdO7kc0IBDFrXsaLRAmw&usqp=CAU',\n", + " 'related_content_id': 'VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VllGQWpkcUxPVlAzMU1cIixcIlFMdks3TWduZ05uRHFN',\n", + " 'source': 'HealthyGirl Kitchen',\n", + " 'title': 'Vegan Pad Thai (easy!) - HealthyGirl Kitchen',\n", + " 'link': 'https://healthygirlkitchen.com/recipes/authentic-vegan-pad-thai/',\n", + " 'original': 'https://healthygirlkitchen.com/wp-content/uploads/2020/11/20201112-DSC_6273-2.jpeg',\n", + " 'original_width': 2500,\n", + " 'original_height': 1669,\n", + " 'is_product': False},\n", + " {'position': 60,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRFnQxVF9fa3yOIanaxEOhaThezpWFnL4LdKw&usqp=CAU',\n", + " 'related_content_id': 'Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Tk1YRm1jencyaVhtaU1cIixcIkU1N2UyV1FFTW9TYXhN',\n", + " 'source': 'PETA',\n", + " 'title': 'Easy Vegan Pad Thai | PETA',\n", + " 'link': 'https://www.peta.org/recipes/easy-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.peta.org/wp-content/uploads/2014/03/vegan-pad-thai-e1429117378854-602x452-1444238253.jpg',\n", + " 'original_width': 602,\n", + " 'original_height': 452,\n", + " 'is_product': True},\n", + " {'position': 61,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJ2bEV_hnyoEftoYQQ2ivw6GAWsG3zvHcH2A&usqp=CAU',\n", + " 'related_content_id': 'NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=NWhGNGlpc0FBc3UyVU1cIixcImc3ZllqbzBsOWJraXBN',\n", + " 'source': 'Ministry of Curry',\n", + " 'title': 'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry',\n", + " 'link': 'https://ministryofcurry.com/vegetarian-pad-thai/',\n", + " 'tag': 'Video',\n", + " 'original': 'https://ministryofcurry.com/wp-content/uploads/2021/01/Pad-Thai_-2.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 1536,\n", + " 'is_product': True},\n", + " {'position': 62,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR0nCQUNnm-ZcLUpjYC487WehnBzJaNNAlVsA&usqp=CAU',\n", + " 'related_content_id': 'cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=cTQ0VGJNT1V2LVBGbE1cIixcIk1UMFVtZDY2S29iUW1N',\n", + " 'source': 'Crowded Kitchen',\n", + " 'title': 'Vegan Pad Thai with Tofu - Crowded Kitchen',\n", + " 'link': 'https://www.crowdedkitchen.com/vegan-pad-thai/',\n", + " 'original': 'https://www.crowdedkitchen.com/wp-content/uploads/2021/01/pad-thai-new-8.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 63,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT96UeZ4BgEN0Q2Xp0fwWYr8KuHmgbo64Lukw&usqp=CAU',\n", + " 'related_content_id': 'dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dlVXQzJRSzNmdXBDd01cIixcInNSTGNaazFpZEtwVnZN',\n", + " 'source': 'Healing Tomato',\n", + " 'title': 'Pad Thai Recipe (Vegan) - HealingTomato.com',\n", + " 'link': 'https://www.healingtomato.com/pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.healingtomato.com/wp-content/uploads/2016/01/pad-thai.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 593,\n", + " 'is_product': True},\n", + " {'position': 64,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQs0sHzHet343DWkhIN84nY2KeHE-mAR3zFTA&usqp=CAU',\n", + " 'related_content_id': 'QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QmhGbndDS2MxQUNXVE1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'source': 'Detoxinista',\n", + " 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n", + " 'link': 'https://detoxinista.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1627,\n", + " 'is_product': True},\n", + " {'position': 65,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQHQuNuSPWyl4_RjkFeElvxvkLOtuWWqW6GAQ&usqp=CAU',\n", + " 'related_content_id': 'emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=emx5TGR6NVM4REdLU01cIixcImI1N0lCcWU2Z1hDQVVN',\n", + " 'source': 'Loving It Vegan',\n", + " 'title': 'Vegan Pad Thai - Loving It Vegan',\n", + " 'link': 'https://lovingitvegan.com/vegan-pad-thai/',\n", + " 'original': 'https://lovingitvegan.com/wp-content/uploads/2022/06/Vegan-Pad-Thai-22.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 66,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRjWUg8dInH0c5rR8rRXl8EMKCxg1ccEhUekQ&usqp=CAU',\n", + " 'related_content_id': 'RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJqQjJ0ZUd3dmJGc01cIixcIlBONXdEWG5LU0s5OHRN',\n", + " 'source': 'Hot For Food',\n", + " 'title': 'vegan pad thai - hot for food by Lauren Toyota',\n", + " 'link': 'https://www.hotforfoodblog.com/recipes/2015/02/02/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.hotforfoodblog.com/wp-content/uploads/2015/02/veganpadthai_hotforfoodblog_filtered1-500x375.jpg',\n", + " 'original_width': 500,\n", + " 'original_height': 375,\n", + " 'is_product': True},\n", + " {'position': 67,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSur4LsaevwvR_0eZ2F3Tf-YVx6-jDRus6E-w&usqp=CAU',\n", + " 'related_content_id': 'TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TWdhZm1EbUQybEpQVE1cIixcIlVZeGRNWmxUbXdrUDVN',\n", + " 'source': 'Vegan Recipes from Cassie Howard',\n", + " 'title': 'Vegan Pad Thai | Vegan Recipes from Cassie Howard',\n", + " 'link': 'http://www.veganinsanity.com/recipes/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'http://www.veganinsanity.com/wp-content/uploads/2014/06/Pad-Thai-Vegan.jpg',\n", + " 'original_width': 600,\n", + " 'original_height': 399,\n", + " 'is_product': True},\n", + " {'position': 68,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRTcDJm39S6nz4sTyLF-l6j6CeiVTVkPOXQ5g&usqp=CAU',\n", + " 'related_content_id': 'WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=WDVwY0w1bENyeXMwM01cIixcIlJabzU1NFZ5NXlrZkpN',\n", + " 'source': 'Gluten-Free, Allergy-Free, and Vegan Recipes',\n", + " 'title': 'Easy Vegan Pad Thai (Gluten-Free, Allergy-Free, Nut-Free, Soy-Free)',\n", + " 'link': 'https://strengthandsunshine.com/vegan-pad-thai-gluten-free/',\n", + " 'original': 'https://strengthandsunshine.com/wp-content/uploads/2019/05/Easy-Vegan-Pad-Thai-Gluten-Free-Allergy-Free-PM1.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': False},\n", + " {'position': 69,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQru1It4T3WzwaedAbLeetEsVNE6DkIrC4L4w&usqp=CAU',\n", + " 'related_content_id': 'dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=dGNFOWkwajFBWFRBeU1cIixcInNMNHU3NVlQNjJMaVBN',\n", + " 'source': \"Archana's Kitchen\",\n", + " 'title': \"Vegetarian Pad Thai Recipe by Archana's Kitchen\",\n", + " 'link': 'https://www.archanaskitchen.com/vegetarian-pad-thai',\n", + " 'original': 'https://www.archanaskitchen.com/images/archanaskitchen/0-Archanas-Kitchen-Recipes/2018/Vegetarian_Pad_Thai_Recipe-4-2.jpg',\n", + " 'original_width': 1600,\n", + " 'original_height': 1200,\n", + " 'is_product': False},\n", + " {'position': 70,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQzSTdgEdXp-bEPIX-4ssadcX6rzD4KQxGE5w&usqp=CAU',\n", + " 'related_content_id': 'ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ODhYU2E1dlpWLVhza01cIixcIkZLMml1QkZLSlptRHhN',\n", + " 'source': 'Pinch of Yum',\n", + " 'title': 'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum',\n", + " 'link': 'https://pinchofyum.com/rainbow-vegetarian-pad-thai-with-peanuts-and-basil',\n", + " 'original': 'https://pinchofyum.com/wp-content/uploads/Vegetarian-Pad-Tha-6.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 71,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTyPzitaptGw98mR0Oqbxxc2B8FtDlN7vpDDw&usqp=CAU',\n", + " 'related_content_id': 'RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RUJXRy15RU1kbmZBbE1cIixcIlVSQWN6a2ltMWw3U0pN',\n", + " 'source': 'Fooby',\n", + " 'title': 'Vegan Pad Thai - Recipes | fooby.ch',\n", + " 'link': 'https://fooby.ch/en/recipes/17187/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://recipecontent.fooby.ch/17187_3-2_480-320.jpg',\n", + " 'original_width': 480,\n", + " 'original_height': 321,\n", + " 'is_product': True},\n", + " {'position': 72,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ9woGokoujYfjUge4wgpyswfCjstd_9uf1qw&usqp=CAU',\n", + " 'related_content_id': 'XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=XzJGTWtNa2N1dnZCRk1cIixcInlqblZTLVBtdWtGSDFN',\n", + " 'source': 'Nora Cooks',\n", + " 'title': 'Vegan Pad Thai - Nora Cooks',\n", + " 'link': 'https://www.noracooks.com/vegan-pad-thai/',\n", + " 'original': 'https://www.noracooks.com/wp-content/uploads/2023/01/30MinuteVeganPadThai-7.jpg',\n", + " 'original_width': 1334,\n", + " 'original_height': 2001,\n", + " 'is_product': False},\n", + " {'position': 73,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSexYRHt5Ul2JMDLnWUdBxc6ELsg2E1iDL31w&usqp=CAU',\n", + " 'related_content_id': 'ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ZEY4blBOM0QzamRSbE1cIixcIkFvdkdRY0Jmems3TDJN',\n", + " 'source': \"Del's cooking twist\",\n", + " 'title': \"Easy Pad Thai (vegan, gluten-free) - Del's cooking twist\",\n", + " 'link': 'https://www.delscookingtwist.com/easy-pad-tai-vegan-gluten-free/',\n", + " 'original': 'https://www.delscookingtwist.com/wp-content/uploads/2018/09/Easy-Vegan-Pad-Thai_3702.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 822,\n", + " 'is_product': False},\n", + " {'position': 74,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSnQTyIRwdSk4FpeGIc-MQnw9411wG2ENeCIg&usqp=CAU',\n", + " 'related_content_id': 'TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TFdwM3hXWXVGMVFxMU1cIixcIlhTaXRGOWFUN1JES3ZN',\n", + " 'source': 'Minimalist Baker',\n", + " 'title': 'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes',\n", + " 'link': 'https://minimalistbaker.com/easy-tofu-pad-thai/',\n", + " 'original': 'https://minimalistbaker.com/wp-content/uploads/2019/01/AMAZING-Easy-Vegan-Pad-Thai-with-Tofu-Ready-in-30-minutes-BIG-flavor-SO-satisfying-betterthantakeout-thai-padthai-plantbased-glutenfree-minimalistbaker-13.jpg',\n", + " 'original_width': 1456,\n", + " 'original_height': 2184,\n", + " 'is_product': False},\n", + " {'position': 75,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcREuE_KU8at0L9CjOGH_t4b-8Up9fL1WBIsUg&usqp=CAU',\n", + " 'related_content_id': 'RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=RHlpeHBOekhOWlpXM01cIixcInM5YXRwVXU2WWlZMjdN',\n", + " 'source': 'Tasty',\n", + " 'title': 'Vegan Pad Thai Recipe by Tasty',\n", + " 'link': 'https://tasty.co/recipe/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://img.buzzfeed.com/thumbnailer-prod-us-east-1/video-api/assets/148610.jpg?resize=1200:*',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 76,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRqsk8XwnF_PLPcNqIatUj46HUH78xjZGBA5g&usqp=CAU',\n", + " 'related_content_id': 'X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=X1RFZzVUbVdsQ3h4Yk1cIixcIjNpV01RU0Y2NHlHUlBN',\n", + " 'source': 'Brand New Vegan',\n", + " 'title': 'Easy Vegan Pad Thai - Brand New Vegan',\n", + " 'link': 'https://www.brandnewvegan.com/recipes/easy-vegan-pad-thai',\n", + " 'original': 'https://www.brandnewvegan.com/wp-content/uploads/easy-vegan-pad-thai-h1-1024x682.jpg',\n", + " 'original_width': 1024,\n", + " 'original_height': 682,\n", + " 'is_product': False},\n", + " {'position': 77,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTjlYvkOX8aA0iNS-32KeueAcXbjYMIcRkfnQ&usqp=CAU',\n", + " 'related_content_id': 'TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TmI0cnJYX2pDd05yOE1cIixcIjU3eG1ZMWtrS3k3eTFN',\n", + " 'source': \"Kathy's Vegan Kitchen\",\n", + " 'title': \"Vegan Pad Thai Recipe | Kathy's Vegan Kitchen\",\n", + " 'link': 'https://www.kathysvegankitchen.com/vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.kathysvegankitchen.com/wp-content/uploads/2021/09/Pad-Thai-.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1277,\n", + " 'is_product': True},\n", + " {'position': 78,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSEcvBpOj0RPCU23uRqHp6VJJrxfS3tQYnURw&usqp=CAU',\n", + " 'related_content_id': 'SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SzFQMUJNWVZzX3FxdU1cIixcIk56WU9UMmcxZGE0bDRN',\n", + " 'source': 'Real Thai Recipes',\n", + " 'title': 'Vegetarian Pad Thai » Real Thai Recipes » Authentic Thai recipes from Thailand',\n", + " 'link': 'https://www.realthairecipes.com/recipes/vegetarian-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.realthairecipes.com/wp-content/uploads/vegetarian-pad-thai1.jpg',\n", + " 'original_width': 440,\n", + " 'original_height': 261,\n", + " 'is_product': True},\n", + " {'position': 79,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQJulkx7A2HLYWmkLlETfrNWofaQ6XllHyzeg&usqp=CAU',\n", + " 'related_content_id': 'ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=ajFCdDB5TkVRbzZDU01cIixcImZkNi15X05vNV9QV2pN',\n", + " 'source': 'Choosing Chia',\n", + " 'title': 'Raw Pad Thai - Choosing Chia',\n", + " 'link': 'https://choosingchia.com/raw-vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://choosingchia.com/jessh-jessh/uploads/2021/06/raw-pad-thai-4.jpg',\n", + " 'original_width': 1360,\n", + " 'original_height': 2040,\n", + " 'is_product': True},\n", + " {'position': 80,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRf0Cju8qWUiOS3tuTGbs7-pXIIdVRzRLVJcQ&usqp=CAU',\n", + " 'related_content_id': 'TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=TW5ZYmFSX29rWjJtYU1cIixcIldJcnR3T3otUkx3Y0NN',\n", + " 'source': \"Cook's Hideout\",\n", + " 'title': \"Vegan Pad Thai Noodles | Cook's Hideout\",\n", + " 'link': 'https://www.cookshideout.com/pad-thai-vegan-recipe',\n", + " 'tag': '0:51',\n", + " 'original': 'https://www.cookshideout.com/wp-content/uploads/2014/03/Vegan-Pad-Thai_4S.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1807,\n", + " 'is_product': True},\n", + " {'position': 81,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRq0f_iTXyVwmnFhPzttm7_lJp8ajUCmufkNQ&usqp=CAU',\n", + " 'related_content_id': 'SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=SWhIZURaRmwydUMybU1cIixcIlNMcHpKV3pZY09nbXJN',\n", + " 'source': \"Chang's\",\n", + " 'title': \"Rainbow Vegetarian Pad Thai with Crispy Noodles - Chang's Authentic Asian Cooking\",\n", + " 'link': 'https://www.changs.com/recipes/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles/',\n", + " 'original': 'https://ik.imagekit.io/webtactics/changs/tr:w-750,h-1000/cgblog/id298/Rainbow-Vegetarian-Pad-Thai-with-Crispy-Noodles.jpg',\n", + " 'original_width': 750,\n", + " 'original_height': 1000,\n", + " 'is_product': False},\n", + " {'position': 82,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTNxrIDPiE9qq8FTzKays6PAe4vKBNCSql2dw&usqp=CAU',\n", + " 'related_content_id': 'VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=VzNub1k0aDF4M2Y5R01cIixcIkhvWUpOZVFZT2NiTGJN',\n", + " 'source': 'Connoisseurus Veg',\n", + " 'title': 'Vegan Pad Thai - Connoisseurus Veg',\n", + " 'link': 'https://www.connoisseurusveg.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.connoisseurusveg.com/wp-content/uploads/2021/04/vegan-pad-thai-r-8-of-10.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 83,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdkOE8fHkjIYt-VHnxHhCKT1Q4Ccu__Id64Q&usqp=CAU',\n", + " 'related_content_id': 'R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=R0tyMmdLYjVENjlHZk1cIixcIjV3Y2xRb1FzM0RXYlhN',\n", + " 'source': \"Madhu's Everyday Indian\",\n", + " 'title': \"Easy Vegan Pad Thai Recipe - Madhu's Everyday Indian\",\n", + " 'link': 'https://www.madhuseverydayindian.com/vegan-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.madhuseverydayindian.com/wp-content/uploads/2019/11/pad-thai-3.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': True},\n", + " {'position': 84,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRAqAWfnCA_xgZ33xmKJYH-GElMv8BR9SfEg&usqp=CAU',\n", + " 'related_content_id': 'YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YnBKLW9ueElrQ3I5VU1cIixcInREeldFQjEycnkzUmRN',\n", + " 'source': 'Simply Recipes',\n", + " 'title': 'Vegetarian Pad Thai Recipe',\n", + " 'link': 'https://www.simplyrecipes.com/vegetarian-pad-thai-recipe-6824813',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://www.simplyrecipes.com/thmb/sNXRcU7H5YlFa9nto8PzROCcK6E=/1500x0/filters:no_upscale():max_bytes(150000):strip_icc()/Simply-Recipes-Vegetarian-Pad-Thai-LEAD-7-f2309902236d45f38dd937e894d7a95f.jpg',\n", + " 'original_width': 1500,\n", + " 'original_height': 1000,\n", + " 'is_product': True},\n", + " {'position': 85,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSvt5v5lIPiITlJSSh6yiG-k8NDEdEaAvrUZg&usqp=CAU',\n", + " 'related_content_id': 'M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=M3VjNTAtcU9IRGtRZ01cIixcIldsdUtpRjZvaGVrS2tN',\n", + " 'source': 'Ve Eat Cook Bake',\n", + " 'title': 'Vegan Tofu Pad Thai Recipe (easy, oil free) - Ve Eat Cook Bake',\n", + " 'link': 'https://veeatcookbake.com/vegan-pad-thai-sauce/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veeatcookbake.com/wp-content/uploads/2020/01/vegan-tofu-pad-thai-3.jpg',\n", + " 'original_width': 720,\n", + " 'original_height': 1080,\n", + " 'is_product': True},\n", + " {'position': 86,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSmmjnFxGBdd4XrLb3_NV9S6DqDsrm8gCArrQ&usqp=CAU',\n", + " 'related_content_id': 'd3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=d3pzc0w3dTZxcnpfRU1cIixcInlqUFhDSS1KQ3ItWkRN',\n", + " 'source': 'Pinterest',\n", + " 'title': 'Easy Vegan Pad Thai Recipe w/ Sauce - Choosing Chia | Recipe | Easy asian noodle recipes, Vegan pad thai, Easy asian noodles',\n", + " 'link': 'https://www.pinterest.com/pin/easy-vegan-pad-thai-recipe-w-sauce-choosing-chia--495044184044777788/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://i.pinimg.com/736x/20/05/d9/2005d9d549ea0aa25d2823c4bd47de66.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': True},\n", + " {'position': 87,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-brimcB4Yy8KjKGPRL_XwmcMsukorzxhh7w&usqp=CAU',\n", + " 'related_content_id': 'bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bHloaW9JSmJ1VV9Qbk1cIixcIkQ1Y1NkRDludWxpWjNN',\n", + " 'source': 'Spice Cravings',\n", + " 'title': 'Vegan Pad Thai | Spice Cravings',\n", + " 'link': 'https://spicecravings.com/vegan-pad-thai',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://spicecravings.com/wp-content/uploads/2021/06/Vegan-pad-Thai-Featured.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 88,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTmLLjuIxWgB0eAVv4CpMkufWKkwP0OLh95rw&usqp=CAU',\n", + " 'related_content_id': 'QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=QV9Kcng3Um9lbjZuSU1cIixcIktXVVQzZkJzVnd5YzJN',\n", + " 'source': 'Delish Knowledge',\n", + " 'title': '15-Minute Vegan Pad Thai - Delish Knowledge',\n", + " 'link': 'https://www.delishknowledge.com/15-minute-vegan-pad-thai/',\n", + " 'original': 'https://www.delishknowledge.com/wp-content/uploads/15-Minute-Vegan-Pad-Thai-Noodles2.jpeg',\n", + " 'original_width': 981,\n", + " 'original_height': 1471,\n", + " 'is_product': False},\n", + " {'position': 89,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQQBFHo9kgwduVWWgXYbjwx8oHmzkRq4eFx_w&usqp=CAU',\n", + " 'related_content_id': 'eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=eWtpUVJZUlMxSFlMS01cIixcIkVYSjJpMTJNTGxJVkpN',\n", + " 'source': 'Nifty Recipes',\n", + " 'title': 'Easy Vegan Pad Thai from Tasty - recipe on Niftyrecipe.com',\n", + " 'link': 'https://niftyrecipe.com/video/1616/easy-vegan-pad-thai',\n", + " 'original': 'https://niftyrecipe.com/uploads/youtube/parse/gVXDvCI32N8.jpg',\n", + " 'original_width': 640,\n", + " 'original_height': 480,\n", + " 'is_product': False},\n", + " {'position': 90,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQDNoodvmhaxXBanZUWokpcjFLd1lBmPi6N9g&usqp=CAU',\n", + " 'related_content_id': 'UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=UTQyU1VUa0lVWU80Vk1cIixcIjlIajF4Rkw1LV91cHZN',\n", + " 'source': 'Detoxinista',\n", + " 'title': 'Best Ever Vegan Pad Thai - Detoxinista',\n", + " 'link': 'https://detoxinista.com/vegan-pad-thai/',\n", + " 'original': 'https://detoxinista.com/wp-content/uploads/2021/01/vegan-pad-thai-recipe.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1513,\n", + " 'is_product': False},\n", + " {'position': 91,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTVHfWG0FG8Dlr4vAkRFB2CJEN1EUPWqp5dWQ&usqp=CAU',\n", + " 'related_content_id': 'S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=S3pfN3d3NlZib0t4Nk1cIixcIjBVRW1Sejl4ZUxXeHdN',\n", + " 'source': 'Mom Always Finds Out',\n", + " 'title': 'Recipe} Vegetarian Pad Thai in Less than 15 Minutes - Mom Always Finds Out',\n", + " 'link': 'https://www.momalwaysfindsout.com/quick-pad-thai-recipe/',\n", + " 'original': 'http://momalwaysfindsout.com/wp-content/uploads/2013/08/easy-vegetarian-pad-thai-recipe.jpg',\n", + " 'original_width': 526,\n", + " 'original_height': 416,\n", + " 'is_product': False},\n", + " {'position': 92,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRhwBcrNUbTx9kzPKfcmWE0Ra7gapkAfRrcfw&usqp=CAU',\n", + " 'related_content_id': 'YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YS1RY05JbjBWUmVxTU1cIixcIm9kOFJZYkVBU0VoSTlN',\n", + " 'source': 'Nutriciously',\n", + " 'title': 'Colorful Raw Vegan Pad Thai Salad – Nutriciously',\n", + " 'link': 'https://nutriciously.com/raw-vegan-pad-thai-recipe/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://nutriciously.com/wp-content/uploads/Raw-Vegan-Pad-Thai-by-Nutriciously-3-735x1102.jpg',\n", + " 'original_width': 735,\n", + " 'original_height': 1102,\n", + " 'is_product': True},\n", + " {'position': 93,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTE247S-7oA7iBXdWKaWSVW76NBNMj9G1zMMA&usqp=CAU',\n", + " 'related_content_id': 'YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=YlAyMGt1UWN0N3VLeU1cIixcInl4LTljQm5yNHV5TWFN',\n", + " 'source': 'Jessica in the Kitchen',\n", + " 'title': 'Easy Vegan Pad Thai | Jessica in the Kitchen',\n", + " 'link': 'https://jessicainthekitchen.com/vegan-pad-thai/',\n", + " 'original': 'https://jessicainthekitchen.com/wp-content/uploads/2022/08/Vegan-Pad-Thai0046.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1800,\n", + " 'is_product': False},\n", + " {'position': 94,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTEICg4TzsYnpMi-FDoDIIiTxIEYlkJotNZJw&usqp=CAU',\n", + " 'related_content_id': 'Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z2ZwSUIzMHNhelRlNU1cIixcIkJTaldiRDBqMnU0MWlN',\n", + " 'source': 'Feasting At Home',\n", + " 'title': 'Pad Thai (Video!) | Feasting at Home',\n", + " 'link': 'https://www.feastingathome.com/15-minute-pad-thai/',\n", + " 'original': 'https://www.feastingathome.com/wp-content/uploads/2016/04/easy-authentic-pad-thai-recipe-100-8.jpg',\n", + " 'original_width': 750,\n", + " 'original_height': 1125,\n", + " 'is_product': False},\n", + " {'position': 95,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRRaL2_fWqKRkIvDq4dn5kZqexIjDD5rIpb-Q&usqp=CAU',\n", + " 'related_content_id': 'aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=aHgxT2JLVE1kMVliNk1cIixcIlNEUzJRZjdyVTkxU1FN',\n", + " 'source': 'a Veg Taste from A to Z',\n", + " 'title': 'Vegan Pad Thai with Cashews -',\n", + " 'link': 'https://avegtastefromatoz.com/vegan-pad-thai-cashews/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://avegtastefromatoz.com/wp-content/uploads/2020/09/pad-thai-5.jpg',\n", + " 'original_width': 2048,\n", + " 'original_height': 2048,\n", + " 'is_product': True},\n", + " {'position': 96,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSQmbOr5bqa0rC0nX95VxH-6RasxkuymwUMg&usqp=CAU',\n", + " 'related_content_id': 'Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Q1dpaG83YTJNS0V2M01cIixcIkctdzFabWdrRE5OTGZN',\n", + " 'source': 'Plant-Based on a Budget',\n", + " 'title': 'Vegan Vegetable Pad Thai - Plant-Based on a Budget',\n", + " 'link': 'https://plantbasedonabudget.com/avocado-basil-pad-thai/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://plantbasedonabudget.com/wp-content/uploads/2014/05/Vegan-Avocado-Basil-Pad-Thai-Plant-Based-on-a-Budget-1-2.jpg',\n", + " 'original_width': 1200,\n", + " 'original_height': 1200,\n", + " 'is_product': True},\n", + " {'position': 97,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQOF76mQo9LZPzWv_vzVAz-od1L271ioKWNVA&usqp=CAU',\n", + " 'related_content_id': 'Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Ri1IOHk0VkhoVmZxT01cIixcIk9jS3J6azl3RWFQTjNN',\n", + " 'source': 'Full of Plants',\n", + " 'title': 'The Best Vegan Pad Thai - Full of Plants',\n", + " 'link': 'https://fullofplants.com/the-best-vegan-pad-thai/',\n", + " 'original': 'https://fullofplants.com/wp-content/uploads/2022/02/easy-vegan-pad-thai-noodle-dish-with-bean-sprouts-10-1400x2100.jpg',\n", + " 'original_width': 1400,\n", + " 'original_height': 2100,\n", + " 'is_product': False},\n", + " {'position': 98,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS-8yozAbc9Gpm97m_vt6sgcJ3mpTliabYGMQ&usqp=CAU',\n", + " 'related_content_id': 'bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=bWtmOFRzYU5PSmlaSE1cIixcIkhsaC11Z195bUp2MmlN',\n", + " 'source': \"It's All Good Vegan\",\n", + " 'title': \"Creamy Pad Thai Noodles - It's All Good Vegan\",\n", + " 'link': 'https://itsallgoodvegan.com/2020/02/19/creamy-pad-thai-noodles/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://itsallgoodvegan.com/wp-content/uploads/2020/02/img_2841.jpg',\n", + " 'original_width': 1638,\n", + " 'original_height': 2048,\n", + " 'is_product': True},\n", + " {'position': 99,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSa2HSMw-ypurNqm48DPPpuKZOFbmDO65klnA&usqp=CAU',\n", + " 'related_content_id': 'Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Z0FiQk9qbFpFZ2hyYk1cIixcImZNQ0FIZk4tZkJCeXNN',\n", + " 'source': 'Veggiekins',\n", + " 'title': 'Vegan Pad Thai with Tofu (gluten free) (Gluten-Free) - Veggiekins Blog',\n", + " 'link': 'https://veggiekinsblog.com/2021/03/24/vegan-pad-thai-with-tofu/',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://veggiekinsblog.com/wp-content/uploads/2021/03/Vegan-Pad-Thai-with-Tofu-4-scaled.jpg',\n", + " 'original_width': 1708,\n", + " 'original_height': 2560,\n", + " 'is_product': True},\n", + " {'position': 100,\n", + " 'thumbnail': 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQEZmnz4duD3odLwVNqQ_OfHJ1zPNaofthtXw&usqp=CAU',\n", + " 'related_content_id': 'Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n", + " 'serpapi_related_content_link': 'https://serpapi.com/search.json?engine=google_images_related_content&gl=us&hl=en&q=Vegan+pad+thai+recipes&related_content_id=Y1R0T2JXekVMS1YtTk1cIixcIi1Va1JxelIyZDZlcU1N',\n", + " 'source': 'Zucker&Jagdwurst',\n", + " 'title': 'Vegan Pad Thai with “chicken“ - Zucker&Jagdwurst',\n", + " 'link': 'https://www.zuckerjagdwurst.com/en/recipes/vegan-pad-thai-with-chicken',\n", + " 'tag': 'Recipe',\n", + " 'original': 'https://assets.zuckerjagdwurst.com/q9pjl6288ajpcx8s994gccncy1i1/1110/740/65/true/center/R435+Veganes+Pad+Thai+mit+%E2%80%9EHu%CC%88hnchen%E2%80%9C39.jpg?animated=false',\n", + " 'original_width': 1110,\n", + " 'original_height': 740,\n", + " 'is_product': True}]}" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "params = {\n", + " \"engine\": \"google_images\",\n", + " \"q\": \"Vegan pad thai recipes\",\n", + " \"location\": \"United States\",\n", + " \"api_key\": os.environ[\"SERPAPI_API_KEY\"],\n", + "}\n", + "\n", + "search = GoogleSearch(params)\n", + "results = search.get_dict()\n", + "results" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'Easy Tofu Pad Thai (Vegan) | Minimalist Baker Recipes'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Rainbow Vegetarian Pad Thai with Peanuts and Basil Recipe - Pinch of Yum'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Healthier vegan pad thai - Lazy Cat Kitchen'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'The Best Vegan Pad Thai - Full of Plants'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegan Pad Thai (Gluten-free) - Earth of Maria'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegan Pad Thai - My Darling Vegan'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Easy Vegetarian Pad Thai - Pinch Me Good'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'30-Minute Vegan Pad Thai - A Weeknight Winner! - Vegan Huggs'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Vegetarian Pad Thai - Easy Skillet Recipe - Ministry of Curry'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "'Vegan pad thai - Lazy Cat Kitchen'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for r in results[\"images_results\"][0:10]:\n", + " display(r[\"title\"], Image(url=r[\"thumbnail\"]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# You can create the tool to pass to an agent\n", + "serpapi_recipe_tool = Tool(\n", + " name=\"\",\n", + " description=\"A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\",\n", + " func=search.run,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This doc should be corrected [LangChain serpapi doc could be updated](https://python.langchain.com/en/latest/modules/agents/tools/examples/serpapi.html)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "search = GoogleSerperAPIWrapper(type=\"search\")\n", + "results = search.results(\"Lion\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[edamam](https://www.edamam.com/)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "import nbdev\n", + "\n", + "nbdev.nbdev_export()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/nbs/03_edamam_api.ipynb b/nbs/03_edamam_api.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..7d280e4ca41addf461326dc98e52a0e5b30f49bb --- /dev/null +++ b/nbs/03_edamam_api.ipynb @@ -0,0 +1,71 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# edamam_api\n", + "\n", + "> Tinkering with the [](Edamam API)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| default_exp edamam_api" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "from nbdev.showdoc import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "def foo():\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "import nbdev\n", + "\n", + "nbdev.nbdev_export()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/nbs/_quarto.yml b/nbs/_quarto.yml new file mode 100644 index 0000000000000000000000000000000000000000..0a6dfcb2f20aeeb3b9b36e44d534c646114dc302 --- /dev/null +++ b/nbs/_quarto.yml @@ -0,0 +1,20 @@ +project: + type: website + +format: + html: + theme: cosmo + css: styles.css + toc: true + +website: + twitter-card: true + open-graph: true + repo-actions: [issue] + navbar: + background: primary + search: true + sidebar: + style: floating + +metadata-files: [nbdev.yml, sidebar.yml] \ No newline at end of file diff --git a/nbs/index.ipynb b/nbs/index.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..42c11a3dbed6488cfb187edf85122b932a64d6a0 --- /dev/null +++ b/nbs/index.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "#| hide\n", + "from lv_recipe_chatbot import app" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# lv-recipe-chatbot\n", + "\n", + "> An experimental Vegan recipe chatbot" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This file will become your README and also the index of your documentation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Install" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```sh\n", + "pip install lv_recipe_chatbot\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## How to use" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Running on local URL: http://127.0.0.1:7860\n", + "\n", + "To create a public link, set `share=True` in `launch()`.\n" + ] + } + ], + "source": [ + "from dotenv import load_dotenv\n", + "\n", + "load_dotenv()\n", + "\n", + "app.launch_demo()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "or \n", + "```sh\n", + "python3 app.py\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Dev quick-start\n", + "\n", + "`git clone` the repo \n", + "\n", + "```sh\n", + "cd lv-recipe-chatbot\n", + "``` \n", + "\n", + "Make sure to use the version of python specified in `py_version.txt` \n", + "Create a virtual environment.\n", + "\n", + "```sh\n", + "python3 -m venv env\n", + "```\n", + "\n", + "Activate the env and install dependencies.\n", + "\n", + "```sh\n", + "source env/bin/activate\n", + "pip install -r requirements.txt\n", + "pip install -r requirements/dev.txt\n", + "```\n", + "\n", + "To make the Jupyter environment, git friendly: `nbdev_install_hooks` \n", + "If you want to render documentation locally, you will want to [install Quarto](https://nbdev.fast.ai/tutorials/tutorial.html#install-quarto).\n", + "\n", + "`nbdev_install_quarto` \n", + "\n", + "Put API secrets in .env\n", + "\n", + "```sh\n", + "cp .env.example .env\n", + "```\n", + "\n", + "Edit .env with your secret key(s). Only `OPEN_AI_KEY` is required.\n", + "\n", + "Then start the Gradio demo from within the virtual environment. \n", + "\n", + "```sh\n", + "python3 app.py\n", + "```\n", + "\n", + "Preview documentation\n", + "\n", + "```sh\n", + "nbdev_preview\n", + "```\n", + "\n", + "## Dependencies\n", + "\n", + "If a new dependency for development is helpful for developers, add it to `dev.txt`. \n", + "If it is a dependency for the app that is imported in source code, add it to `core.txt`. \n", + "Then run:\n", + "\n", + "```sh\n", + "pipreqs --force\n", + "```\n", + "\n", + "This will update our `requirements.txt` to include the dependency as it should be pinned in the environment. \n", + "\n", + "\n", + "## Development\n", + "\n", + "[quick nbdev tutorial](https://nbdev.fast.ai/tutorials)\n", + "\n", + "Make changes in `/nbs`. \n", + "Update the package files with `nbdev_export` then reimport with `pip install -e '.[dev]'`\n", + "\n", + "Preview doc `nbdev_preview` \n", + "Build docs, test and update README `nbdev_prepare`\n", + "\n", + "\n", + "\n", + "## Useful links\n", + "\n", + "* [Task Matrix (Formerly Visual ChatGPT)](https://github.com/microsoft/TaskMatrix)\n", + "* [LangChain](https://python.langchain.com/en/latest/index.html)\n", + "* [LLM Prompt Engineering](https://www.promptingguide.ai)\n", + "* [OpenAI best practices for prompts](https://help.openai.com/en/articles/6654000-best-practices-for-prompt-engineering-with-openai-api)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "python3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/nbs/nbdev.yml b/nbs/nbdev.yml new file mode 100644 index 0000000000000000000000000000000000000000..7314ea6b69efe5a314f9d3814242161eb07a72d1 --- /dev/null +++ b/nbs/nbdev.yml @@ -0,0 +1,9 @@ +project: + output-dir: _docs + +website: + title: "lv-recipe-chatbot" + site-url: "https://animalequality.github.io/lv-recipe-chatbot" + description: "An experimental Vegan recipe chatbot" + repo-branch: main + repo-url: "https://github.com/animalequality/lv-recipe-chatbot" diff --git a/nbs/sidebar.yml b/nbs/sidebar.yml new file mode 100644 index 0000000000000000000000000000000000000000..fc9c7b717fea0dee0ce3403ad5d6db5c4c5432e9 --- /dev/null +++ b/nbs/sidebar.yml @@ -0,0 +1,8 @@ +website: + sidebar: + contents: + - index.ipynb + - 00_engineer_prompt.ipynb + - 01_app.ipynb + - 02_lchain_tool.ipynb + - 03_edamam_api.ipynb diff --git a/nbs/styles.css b/nbs/styles.css new file mode 100644 index 0000000000000000000000000000000000000000..66ccc49ee8f0e73901dac02dc4e9224b7d1b2c78 --- /dev/null +++ b/nbs/styles.css @@ -0,0 +1,37 @@ +.cell { + margin-bottom: 1rem; +} + +.cell > .sourceCode { + margin-bottom: 0; +} + +.cell-output > pre { + margin-bottom: 0; +} + +.cell-output > pre, .cell-output > .sourceCode > pre, .cell-output-stdout > pre { + margin-left: 0.8rem; + margin-top: 0; + background: none; + border-left: 2px solid lightsalmon; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.cell-output > .sourceCode { + border: none; +} + +.cell-output > .sourceCode { + background: none; + margin-top: 0; +} + +div.description { + padding-left: 2px; + padding-top: 5px; + font-style: italic; + font-size: 135%; + opacity: 70%; +} diff --git a/requirements/core.txt b/requirements/core.txt index 938c27a2ca040c7898e821ca18230bfbd0d792f6..c0b8290e51ca4ec409b8ad42c3ded4d470876a7c 100644 --- a/requirements/core.txt +++ b/requirements/core.txt @@ -1,3 +1,6 @@ langchain openai -gradio \ No newline at end of file +gradio +tqdm +google-search-results +duckduckgo-search \ No newline at end of file diff --git a/requirements/dev.txt b/requirements/dev.txt index 1334d40b819815befed54d41f632bb5998e70b10..1546c60997b52c0eeb1e0357cf26b1e10eb0fb6e 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -6,4 +6,6 @@ nbdev isort jupyterlab promptlayer -pipreqs \ No newline at end of file +pipreqs +jupyterlab-code-formatter +# jupyterlab-quarto currently breaks markdown output \ No newline at end of file diff --git a/scripts/prepend_raw_hface_block_readme.sh b/scripts/prepend_raw_hface_block_readme.sh new file mode 100755 index 0000000000000000000000000000000000000000..9f1b0b5a90391f73c11e7ff5f01834ef3651b090 --- /dev/null +++ b/scripts/prepend_raw_hface_block_readme.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +yaml_file="hface.yaml" +readme_file="README.md" + +# Read the content of the YAML file +yaml_content=$(cat "$yaml_file") + +# Read the content of the README file +readme_content=$(cat "$readme_file") + +# Combine the YAML content and README content +combined_content="$yaml_content/n$readme_content" + +# Overwrite the README file with the combined content +echo -e "$combined_content" > "$readme_file" diff --git a/settings.ini b/settings.ini new file mode 100644 index 0000000000000000000000000000000000000000..9046299c6ea8d00c8f4c7bfe4b735dab44d7e397 --- /dev/null +++ b/settings.ini @@ -0,0 +1,43 @@ +[DEFAULT] +# All sections below are required unless otherwise specified. +# See https://github.com/fastai/nbdev/blob/master/settings.ini for examples. + +### Python library ### +repo = lv-recipe-chatbot +lib_name = %(repo)s +version = 0.0.1 +min_python = 3.7 +license = apache2 +black_formatting = False + +### nbdev ### +doc_path = _docs +lib_path = lv_recipe_chatbot +nbs_path = nbs +recursive = True +tst_flags = notest +put_version_in_init = True + +### Docs ### +branch = main +custom_sidebar = False +doc_host = https://%(user)s.github.io +doc_baseurl = /%(repo)s +git_url = https://github.com/%(user)s/%(repo)s +title = %(lib_name)s + +### PyPI ### +audience = Developers +author = Evan Lesmez +author_email = evanl@animalequality.org +copyright = 2023 onwards, %(author)s +description = An experimental Vegan recipe chatbot +keywords = nbdev jupyter notebook python +language = English +status = 3 +user = animalequality + +### Optional ### +# requirements = fastcore pandas +# dev_requirements = +# console_scripts = \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..e3281ae9bd7b98568e77014dba1b7b353d409205 --- /dev/null +++ b/setup.py @@ -0,0 +1,57 @@ +from pkg_resources import parse_version +from configparser import ConfigParser +import setuptools, shlex +assert parse_version(setuptools.__version__)>=parse_version('36.2') + +# note: all settings are in settings.ini; edit there, not here +config = ConfigParser(delimiters=['=']) +config.read('settings.ini', encoding='utf-8') +cfg = config['DEFAULT'] + +cfg_keys = 'version description keywords author author_email'.split() +expected = cfg_keys + "lib_name user branch license status min_python audience language".split() +for o in expected: assert o in cfg, "missing expected setting: {}".format(o) +setup_cfg = {o:cfg[o] for o in cfg_keys} + +licenses = { + 'apache2': ('Apache Software License 2.0','OSI Approved :: Apache Software License'), + 'mit': ('MIT License', 'OSI Approved :: MIT License'), + 'gpl2': ('GNU General Public License v2', 'OSI Approved :: GNU General Public License v2 (GPLv2)'), + 'gpl3': ('GNU General Public License v3', 'OSI Approved :: GNU General Public License v3 (GPLv3)'), + 'bsd3': ('BSD License', 'OSI Approved :: BSD License'), +} +statuses = [ '1 - Planning', '2 - Pre-Alpha', '3 - Alpha', + '4 - Beta', '5 - Production/Stable', '6 - Mature', '7 - Inactive' ] +py_versions = '3.6 3.7 3.8 3.9 3.10'.split() + +requirements = shlex.split(cfg.get('requirements', '')) +if cfg.get('pip_requirements'): requirements += shlex.split(cfg.get('pip_requirements', '')) +min_python = cfg['min_python'] +lic = licenses.get(cfg['license'].lower(), (cfg['license'], None)) +dev_requirements = (cfg.get('dev_requirements') or '').split() + +setuptools.setup( + name = cfg['lib_name'], + license = lic[0], + classifiers = [ + 'Development Status :: ' + statuses[int(cfg['status'])], + 'Intended Audience :: ' + cfg['audience'].title(), + 'Natural Language :: ' + cfg['language'].title(), + ] + ['Programming Language :: Python :: '+o for o in py_versions[py_versions.index(min_python):]] + (['License :: ' + lic[1] ] if lic[1] else []), + url = cfg['git_url'], + packages = setuptools.find_packages(), + include_package_data = True, + install_requires = requirements, + extras_require={ 'dev': dev_requirements }, + dependency_links = cfg.get('dep_links','').split(), + python_requires = '>=' + cfg['min_python'], + long_description = open('README.md', encoding='utf-8').read(), + long_description_content_type = 'text/markdown', + zip_safe = False, + entry_points = { + 'console_scripts': cfg.get('console_scripts','').split(), + 'nbdev': [f'{cfg.get("lib_path")}={cfg.get("lib_path")}._modidx:d'] + }, + **setup_cfg) + +