Merge branch 'mealie-next' into fix/translation-issues-when-scraping

This commit is contained in:
Michael Genson 2024-01-10 11:35:28 -06:00 committed by GitHub
commit 14497b9b5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 1318 additions and 573 deletions

81
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,81 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "mealie-next" ]
pull_request:
branches: [ "mealie-next" ]
schedule:
- cron: '36 9 * * 3'
jobs:
analyze:
name: Analyze
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners
# Consider using larger runners for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript-typescript', 'python' ]
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@ -7,12 +7,11 @@ Create Date: 2023-02-14 20:45:41.102571
"""
import sqlalchemy as sa
from sqlalchemy import orm, select
from sqlalchemy.orm import Mapped, mapped_column, DeclarativeBase
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from text_unidecode import unidecode
import mealie.db.migration_types
from alembic import op
from mealie.db.models._model_utils import GUID
# revision identifiers, used by Alembic.
@ -52,30 +51,46 @@ def do_data_migration():
session = orm.Session(bind=bind)
recipes = session.execute(select(RecipeModel)).scalars().all()
ingredients = session.execute(select(RecipeIngredient)).scalars().all()
for recipe in recipes:
if recipe.name is not None:
recipe.name_normalized = unidecode(recipe.name).lower().strip()
session.execute(
sa.text(
f"UPDATE {RecipeModel.__tablename__} SET name_normalized=:name_normalized WHERE id=:id"
).bindparams(name_normalized=unidecode(recipe.name).lower().strip(), id=recipe.id)
)
if recipe.description is not None:
recipe.description_normalized = unidecode(recipe.description).lower().strip()
session.add(recipe)
session.execute(
sa.text(
f"UPDATE {RecipeModel.__tablename__} SET description_normalized=:description_normalized WHERE id=:id"
).bindparams(description_normalized=unidecode(recipe.description).lower().strip(), id=recipe.id)
)
ingredients = session.execute(select(RecipeIngredient)).scalars().all()
for ingredient in ingredients:
if ingredient.note is not None:
ingredient.note_normalized = unidecode(ingredient.note).lower().strip()
session.execute(
sa.text(
f"UPDATE {RecipeIngredient.__tablename__} SET note_normalized=:note_normalized WHERE id=:id"
).bindparams(note_normalized=unidecode(ingredient.note).lower().strip(), id=ingredient.id)
)
if ingredient.original_text is not None:
ingredient.original_text_normalized = unidecode(ingredient.original_text).lower().strip()
session.add(ingredient)
session.execute(
sa.text(
f"UPDATE {RecipeIngredient.__tablename__} SET original_text_normalized=:original_text_normalized WHERE id=:id"
).bindparams(
original_text_normalized=unidecode(ingredient.original_text).lower().strip(), id=ingredient.id
)
)
session.commit()
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
# Set column to nullable first, since we do not have values here yet
op.add_column("recipes", sa.Column("name_normalized", sa.String(), nullable=True))
# Set column default first, since we do not have values here yet
op.add_column("recipes", sa.Column("name_normalized", sa.String(), nullable=False, server_default=""))
op.add_column("recipes", sa.Column("description_normalized", sa.String(), nullable=True))
op.drop_index("ix_recipes_description", table_name="recipes")
op.drop_index("ix_recipes_name", table_name="recipes")
@ -95,9 +110,9 @@ def upgrade():
unique=False,
)
do_data_migration()
# Make recipes.name_normalized not nullable now that column should be filled for all rows
# Remove server default now that column should be filled for all rows
with op.batch_alter_table("recipes", schema=None) as batch_op:
batch_op.alter_column("name_normalized", nullable=False, existing_type=sa.String())
batch_op.alter_column("name_normalized", existing_type=sa.String(), server_default=None)
# ### end Alembic commands ###

View File

@ -24,10 +24,10 @@ depends_on = None
def populate_shopping_lists_multi_purpose_labels(shopping_lists_multi_purpose_labels_table: sa.Table, session: Session):
shopping_lists = session.query(ShoppingList).all()
labels = session.query(MultiPurposeLabel).all()
shopping_lists_labels_data: list[dict] = []
for shopping_list in shopping_lists:
labels = session.query(MultiPurposeLabel).filter(MultiPurposeLabel.group_id == ShoppingList.group_id).all()
for i, label in enumerate(labels):
shopping_lists_labels_data.append(
{"id": uuid4(), "shopping_list_id": shopping_list.id, "label_id": label.id, "position": i}

View File

@ -24,17 +24,22 @@ def populate_group_slugs(session: Session):
seen_slugs: set[str] = set()
for group in groups:
original_name = group.name
new_name = original_name
attempts = 0
while True:
slug = slugify(group.name)
slug = slugify(new_name)
if slug not in seen_slugs:
break
attempts += 1
group.name = f"{original_name} ({attempts})"
new_name = f"{original_name} ({attempts})"
seen_slugs.add(slug)
group.slug = slug
session.execute(
sa.text(f"UPDATE {Group.__tablename__} SET name=:name, slug=:slug WHERE id=:id").bindparams(
name=new_name, slug=slug, id=group.id
)
)
session.commit()

View File

@ -69,9 +69,11 @@ def _resolve_duplicate_food(
):
recipe_ingredient.food_id = keep_food_id
session.commit()
session.execute(
sa.text(f"DELETE FROM {IngredientFoodModel.__tablename__} WHERE id=:id").bindparams(id=dupe_food_id)
)
session.commit()
def _resolve_duplicate_unit(
@ -85,9 +87,11 @@ def _resolve_duplicate_unit(
for recipe_ingredient in session.query(RecipeIngredientModel).filter_by(unit_id=dupe_unit_id).all():
recipe_ingredient.unit_id = keep_unit_id
session.commit()
session.execute(
sa.text(f"DELETE FROM {IngredientUnitModel.__tablename__} WHERE id=:id").bindparams(id=dupe_unit_id)
)
session.commit()
def _resolve_duplicate_label(
@ -101,7 +105,9 @@ def _resolve_duplicate_label(
for ingredient_food in session.query(IngredientFoodModel).filter_by(label_id=dupe_label_id).all():
ingredient_food.label_id = keep_label_id
session.commit()
session.execute(sa.text(f"DELETE FROM {MultiPurposeLabel.__tablename__} WHERE id=:id").bindparams(id=dupe_label_id))
session.commit()
def _resolve_duplicate_foods_units_labels(session: Session):
@ -140,6 +146,7 @@ def _remove_duplicates_from_m2m_table(session: Session, table_meta: TableMeta):
)
session.execute(query)
session.commit()
def _remove_duplicates_from_m2m_tables(session: Session, table_metas: list[TableMeta]):

View File

@ -0,0 +1,74 @@
import json
import logging
import random
import string
from datetime import datetime
from uuid import UUID
logger = logging.getLogger("anonymize_backups")
def is_uuid4(value: str):
try:
UUID(value)
return True
except ValueError:
return False
def is_iso_datetime(value: str):
try:
datetime.fromisoformat(value)
return True
except ValueError:
return False
def random_string(length=10):
return "".join(random.choice(string.ascii_lowercase) for _ in range(length))
def clean_value(value):
try:
match value:
# preserve non-strings
case int(value) | float(value):
return value
case None:
return value
# preserve UUIDs and datetimes
case str(value) if is_uuid4(value) or is_iso_datetime(value):
return value
# randomize strings
case str(value):
return random_string()
case _:
pass
except Exception as e:
logger.exception(e)
logger.error(f"Failed to anonymize value: {value}")
return value
def walk_data_and_anonymize(data):
for k, v in data.items():
if isinstance(v, list):
for item in v:
walk_data_and_anonymize(item)
else:
# preserve alembic version number and enums
if k in ["auth_method", "version_num"]:
continue
data[k] = clean_value(v)
def anonymize_database_json(input_filepath: str, output_filepath: str):
with open(input_filepath) as f:
data = json.load(f)
walk_data_and_anonymize(data)
with open(output_filepath, "w") as f:
json.dump(data, f)

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

View File

@ -1,5 +1,5 @@
!!! info
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
This guide was submitted by a community member. Find something wrong? Submit a PR to get it fixed!
In a lot of ways, Home Assistant is why this project exists! Since Mealie has a robust API it makes it a great fit for interacting with Home Assistant and pulling information into your dashboard.

View File

@ -41,22 +41,15 @@ Yes. If you are using the v1 branches (including beta), you can upgrade to the l
## How can I change the theme?
You can change the theme by settings the environment variables on the frontend container.
You can change the theme by settings the environment variables.
- [Frontend Theme](../installation/frontend-config#themeing)
## How can I change the language?
Languages need to be set on the frontend and backend containers as ENV variables.
- [Frontend Config](../installation/frontend-config/)
- [Backend Config](../installation/backend-config/)
- [Backend Config - Themeing](./installation/backend-config.md#themeing)
## How can I change the Login Session Timeout?
Login session can be configured by setting the `TOKEN_TIME` variable on the backend container.
- [Backend Config](../installation/backend-config/)
- [Backend Config](./installation/backend-config.md)
## Can I serve Mealie on a subpath?
@ -105,8 +98,9 @@ python /app/mealie/scripts/change_password.py
Managing private groups and recipes can be confusing. The following diagram and notes should help explain how they work to determine if a recipe can be shared publicly.
- Private links that are generated using the `Share` button bypass all group and recipe permissions.
- Private links that are generated from the recipe page using the `Share` button bypass all group and recipe permissions
- Private groups block all access to recipes, including those that are public, except as noted above.
- Groups with "Allow users outside of your group to see your recipes" disabled block all access to recipes, except as noted above.
- Private recipes block all access to the recipe from public links. This does not affect Private Links.
```mermaid
@ -130,6 +124,8 @@ stateDiagram-v2
p3 --> n1: No
```
For more information, check out the [Permissions and Public Access guide](./usage/permissions-and-public-access.md).
## Can I use fail2ban with mealie?
Yes, mealie is configured to properly forward external IP addresses into the `mealie.log` logfile. Note that due to restrictions in docker, IP address forwarding only works on Linux.

View File

@ -16,19 +16,15 @@ The version 1 release of Mealie should be seen as an entirely different applicat
## Migration Considerations
Before you migrate to v1.0.0-beta-x please consider the following:
Before you migrate to v1.0.0 please consider the following:
**API Integration Will Break**
Several of the endpoints in the API have changed. This means that you will need to update your code to use the new endpoints.
**Meal Plan Notifications Are Not Yet Implemented**
**Recipes Are Private By Default**
If you're using the Meal Plan webhook feature it has yet to be implemented in v1. This feature is being significantly improved in v1 and has yet to be fully fleshed out. If you were a heavy user, you may want to wait until v1 to use this feature.
**Recipes are Now Private**
This can be a plus or a minus depending on your use case. If you relied on the old implementation that allowed viewing of recipes without logging in, you will loose that access. We are planning on implementing a public facing interface for groups/tenants to allow unauthenticated users to view public recipes.
By default, recipes can only be viewed by logged-in users. You can fine-tune public recipe access, or keep your instance fully private. For more information, check out the [Permissions and Public Access guide](../getting-started/usage/permissions-and-public-access.md).
## Step 1: Setting Up The New Application
@ -37,7 +33,9 @@ Given the nature of the upgrade, it is highly recommended that you stand up a ne
## Step 2: Exporting Your Data from Pre-v1
In your instance of Mealie prior to v1, perform an export of your data in the Admin section. Be sure to include the recipes when performing the export. Checking additional items won't impact the migration, but they will be ignored if they are included.
In your instance of Mealie prior to v1, perform an export (backup) of your data in the Admin section. Be sure to include the recipes when performing the export. Checking additional items won't impact the migration, but they will be ignored if they are included. The backups section is located on the admin dashboard in the section labeled "Backups":
![pre-v1-backup-location-image](../../assets/img/pre-v1-backup-location.png)
## Step 3: Using the Migration Tool

View File

@ -0,0 +1,57 @@
# Permissions and Public Access
Mealie provides various levels of user access and permissions. This includes:
- Authentication and registration ([check out the LDAP guide](./ldap.md) for how to configure access using LDAP)
- Customizable user permissions
- Fine-tuned public access for non-users
## Customizable User Permissions
Each user can be configured to have varying levels of access. Some of these permissions include:
- Access to Administrator tools
- Access to inviting other users
- Access to manage their group and group data
Administrators can navigate to the Settings page and access the User Management page to configure these settings.
[User Management Demo](https://demo.mealie.io/admin/manage/users){ .md-button .md-button--primary }
## Public Recipe Access
By default, groups are set to private, meaning only logged-in users may access the group. In order for a recipe to be viewable by public (not logged-in) users, two criteria must be met:
1. The group must not be private, *and* the group setting for allowing users outside of your group to see your recipes must be enabled. These can be toggled on the Group Settings page
2. The recipe must be set to public. This can be toggled for each recipe individually, or in bulk using the Recipe Data Management page
Additionally, if the group is not private, public users can view all public group data (public recipes, public cookbooks, etc.) from the home page ([e.g. the demo home page](https://demo.mealie.io/g/home)).
[Group Settings Demo](https://demo.mealie.io/group){ .md-button .md-button--primary }
More broadly, here are the rules for how recipe access is determined:
- Private links that are generated from the recipe page using the `Share` button bypass all group and recipe permissions
- Private groups block all access to recipes, including those that are public, except as noted above.
- Groups with "Allow users outside of your group to see your recipes" disabled block all access to recipes, except as noted above.
- Private recipes block all access to the recipe from public links. This does not affect Private Links.
```mermaid
stateDiagram-v2
r1: Request Access
p1: Using Private Link?
p2: Is Group Private?
p3: Is Recipe Private?
s1: Deny Access
n1: Allow Access
r1 --> p1
p1 --> p2: No
p1 --> n1: Yes
p2 --> s1: Yes
p2 --> p3: No
p3 --> s1: Yes
p3 --> n1: No
```

File diff suppressed because one or more lines are too long

View File

@ -139,7 +139,7 @@ export default defineComponent({
default: false,
},
},
setup(props, context) {
setup(_, context) {
const deleteDialog = ref(false);
const { i18n, $globals } = useContext();

View File

@ -1,7 +1,7 @@
<template>
<div v-if="value.length > 0 || edit" class="mt-8">
<h2 class="my-4">{{ $t("recipe.note") }}</h2>
<div v-for="(note, index) in value" :key="'note' + index" class="mt-1">
<div v-for="(note, index) in value" :id="'note' + index" :key="'note' + index" class="mt-1">
<v-card v-if="edit">
<v-card-text>
<div class="d-flex align-center">

View File

@ -5,12 +5,15 @@
<BaseDialog
v-if="deleteTarget"
v-model="dialogs.delete"
:title="$t('general.delete-with-name', { name: deleteTarget.name })"
:title="$t('general.delete-with-name', { name: $t(translationKey) })"
color="error"
:icon="$globals.icons.alertCircle"
@confirm="deleteOne()"
>
<v-card-text> {{ $t("general.confirm-delete-generic-with-name", { name: deleteTarget.name }) }} </v-card-text>
<v-card-text>
<p>{{ $t("general.confirm-delete-generic-with-name", { name: $t(translationKey) }) }}</p>
<p class="mt-4 mb-0 ml-4">{{ deleteTarget.name }}</p>
</v-card-text>
</BaseDialog>
<BaseDialog v-if="updateTarget" v-model="dialogs.update" :title="$t('general.update')" @confirm="updateOne()">
@ -136,6 +139,15 @@ export default defineComponent({
const presets = useContextPresets();
const translationKey = computed<string>(() => {
const typeMap = {
"categories": "category.category",
"tags": "tag.tag",
"tools": "tool.tool"
};
return typeMap[props.itemType] || "";
});
const deleteTarget = ref<GenericItem | null>(null);
const updateTarget = ref<GenericItem | null>(null);
@ -223,6 +235,7 @@ export default defineComponent({
presets,
itemsSorted,
searchString,
translationKey,
};
},
// Needed for useMeta

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Nuwe resepname moet uniek wees",
"scrape-recipe": "Skraap resep",
"scrape-recipe-description": "Voeg 'n resep by via 'n url. Voer die url van die webwerf in wat jy vir 'n resep wil skandeer, Mealie sal probeer om die resep vanaf daardie plek te skandeer en by jou versameling te voeg.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Voer oorspronklike sleutelwoorde as merkers in",
"stay-in-edit-mode": "Bly in redigeer modus",
"import-from-zip": "Voer vanaf zip in",
@ -789,7 +791,8 @@
"tags": "Merkers",
"untagged-count": "Nie gemerk {count}",
"create-a-tag": "Skep 'n merker",
"tag-name": "Merker naam"
"tag-name": "Merker naam",
"tag": "Tag"
},
"tool": {
"tools": "Kookgerei",
@ -798,7 +801,8 @@
"tool-name": "Naam van die kookgerei",
"create-new-tool": "Skep nuwe kookgerei",
"on-hand-checkbox-label": "Wys as in besit (gemerk)",
"required-tools": "Vereiste kookgerei"
"required-tools": "Vereiste kookgerei",
"tool": "Tool"
},
"user": {
"admin": "Administrateur",

View File

@ -128,7 +128,7 @@
"no-recipe-found": "لم يتم العثور على وصفة",
"ok": "موافق",
"options": "الخيارات:",
"plural-name": "Plural Name",
"plural-name": "إسم المعدود",
"print": "طباعة",
"print-preferences": "إعدادات الطباعة",
"random": "عشوائي",
@ -191,7 +191,7 @@
"clipboard-not-supported": "الحافظة غير مدعومة",
"copied-to-clipboard": "نُسِخَ إلى الحافظة",
"your-browser-does-not-support-clipboard": "المتصفح الخاص بك لا يدعم الحافظة",
"copied-items-to-clipboard": "No item copied to clipboard|One item copied to clipboard|Copied {count} items to clipboard",
"copied-items-to-clipboard": "لم يتم نسخ أي عنصر إلى الحافظة<unk> عنصر واحد تم نسخه إلى الحافظة<unk> تم نسخه إلى الحافظة {count}",
"actions": "الإجراءت",
"selected-count": "تم اختيار: {count}",
"export-all": "تصدير الكل",
@ -214,7 +214,7 @@
"group-id-with-value": "رقم تعريف المجموعة: {groupID}",
"group-name": "اسم المجموعة",
"group-not-found": "لم يتم العثور على المجموعة",
"group-token": "Group Token",
"group-token": "رمز المجموعة",
"group-with-value": "المجموعة: {groupID}",
"groups": "المجموعات",
"manage-groups": "إدارة المجموعات",
@ -227,7 +227,7 @@
},
"manage-members": "إدارة الأعضاء",
"manage-members-description": "Manage the permissions of the members in your groups. {manage} allows the user to access the data-management page {invite} allows the user to generate invitation links for other users. Group owners cannot change their own permissions.",
"manage": "Manage",
"manage": "إدارة الحساب",
"invite": "دعوة",
"looking-to-update-your-profile": "هل ترغب في تحديث ملفك الشخصي؟",
"default-recipe-preferences-description": "هذه هي الإعدادات الافتراضية عند إنشاء وصفة جديدة في مجموعتك. يمكن تغيير هذه الوصفات الفردية في قائمة إعدادات الوصفات.",
@ -235,7 +235,7 @@
"group-preferences": "إعدادات المجموعة",
"private-group": "مجموعة خاصة",
"private-group-description": "Setting your group to private will default all public view options to default. This overrides an individual recipes public view settings.",
"allow-users-outside-of-your-group-to-see-your-recipes": "Allow users outside of your group to see your recipes",
"allow-users-outside-of-your-group-to-see-your-recipes": "السماح للمستخدمين خارج مجموعتك لمشاهدة وصفاتك",
"allow-users-outside-of-your-group-to-see-your-recipes-description": "When enabled you can use a public share link to share specific recipes without authorizing the user. When disabled, you can only share recipes with users who are in your group or with a pre-generated private link",
"show-nutrition-information": "عرض معلومات التغذية",
"show-nutrition-information-description": "When enabled the nutrition information will be shown on the recipe if available. If there is no nutrition information available, the nutrition information will not be shown",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -199,7 +199,7 @@
"upload-file": "Качване на файл",
"created-on-date": "Създадено на {0}",
"unsaved-changes": "Имате незапазени промени. Желаете ли да ги запазите преди да излезете? Натиснете Ок за запазване и Отказ за отхвърляне на промените.",
"clipboard-copy-failure": "Failed to copy to the clipboard."
"clipboard-copy-failure": "Линкът към рецептата е копиран в клипборда."
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Сигурни ли сте, че искате да изтриете <b>{groupName}<b/>?",
@ -250,7 +250,7 @@
"general-preferences": "Общи предпочитания",
"group-recipe-preferences": "Предпочитания за рецепта по група",
"report": "Сигнал",
"report-with-id": "Номер на сигнала: {id}",
"report-with-id": "Номер на доклада: {id}",
"group-management": "Управление на групите",
"admin-group-management": "Административно управление на групите",
"admin-group-management-text": "Промените по тази група ще бъдат отразени моментално.",
@ -515,7 +515,7 @@
"message-key": "Ключ на съобщението",
"parse": "Анализирай",
"attach-images-hint": "Прикачете снимки като ги влачете и пуснете в редактора",
"drop-image": "Влачете и пуснете снимка",
"drop-image": "Премахване на изображение",
"enable-ingredient-amounts-to-use-this-feature": "Пуснете количествата на съставките за да използвате функционалността",
"recipes-with-units-or-foods-defined-cannot-be-parsed": "Рецепти със зададени мерни единици и храни ме могат да бъдат анализирани.",
"parse-ingredients": "Анализирай съставките",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Името на рецептата трябва да бъде уникално",
"scrape-recipe": "Обхождане на рецепта",
"scrape-recipe-description": "Обходи рецепта по линк. Предоставете линк за сайт, който искате да бъде обходен. Mealie ще опита да обходи рецептата от този сайт и да я добави във Вашата колекция.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Импортирай оригиналните ключови думи като тагове",
"stay-in-edit-mode": "Остани в режим на редакция",
"import-from-zip": "Импортирай от Zip",
@ -789,7 +791,8 @@
"tags": "Тагове",
"untagged-count": "Без таг {count}",
"create-a-tag": "Създаване на таг",
"tag-name": "Име на тага"
"tag-name": "Име на тага",
"tag": "Тагове"
},
"tool": {
"tools": "Инструменти",
@ -798,7 +801,8 @@
"tool-name": "Име на инструмента",
"create-new-tool": "Създаване на нов инструмент",
"on-hand-checkbox-label": "Показване като налични (отметнато)",
"required-tools": "Задължителни инструменти"
"required-tools": "Задължителни инструменти",
"tool": "Инструменти"
},
"user": {
"admin": "Админ",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Els noms de les noves receptes han de ser únics",
"scrape-recipe": "Rastrejar recepta",
"scrape-recipe-description": "Rastrejar recepta des de l'Url. Proporciona un Url del lloc que vols rastrejar i Mealie intentarà analitzar la recepta del lloc web i afegir-la a la teva col·lecció.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importa les paraules clau originals com a tags",
"stay-in-edit-mode": "Segueix en el mode d'edició",
"import-from-zip": "Importa des d'un ZIP",
@ -789,7 +791,8 @@
"tags": "Etiquetes",
"untagged-count": "{count} sense etiquetar",
"create-a-tag": "Crea una etiqueta",
"tag-name": "Nom de l'etiqueta"
"tag-name": "Nom de l'etiqueta",
"tag": "Tag"
},
"tool": {
"tools": "Estris",
@ -798,7 +801,8 @@
"tool-name": "Nom de l'estri",
"create-new-tool": "Crea un nou estri",
"on-hand-checkbox-label": "Mostra com a disponible (marcat)",
"required-tools": "Eines necessàries"
"required-tools": "Eines necessàries",
"tool": "Tool"
},
"user": {
"admin": "Administrador/a",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Zůstat v režimu úprav",
"import-from-zip": "Importovat ze zipu",
@ -789,7 +791,8 @@
"tags": "Štítky",
"untagged-count": "Bez štítku {count}",
"create-a-tag": "Vytvořit štítek",
"tag-name": "Název štítku"
"tag-name": "Název štítku",
"tag": "Tag"
},
"tool": {
"tools": "Nástroje",
@ -798,7 +801,8 @@
"tool-name": "Název nástroje",
"create-new-tool": "Vytvořit nový nástroj",
"on-hand-checkbox-label": "Zobrazit jako \"Po ruce\" (zaškrtnuto)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Správce",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Opskriftsnavnet er allerede i brug",
"scrape-recipe": "Scrape Opskrift",
"scrape-recipe-description": "Hent en opskrift fra en hjemmeside. Angiv URL'en til den hjemmeside, du vil hente data fra, og Mealie vil forsøge at hente opskriften og tilføje den til din samling.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importér originale nøgleord som mærker",
"stay-in-edit-mode": "Bliv i redigeringstilstand",
"import-from-zip": "Importer fra zip-fil",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Ikke-tagget: {count}",
"create-a-tag": "Opret tag",
"tag-name": "Tag navn"
"tag-name": "Tag navn",
"tag": "Tag"
},
"tool": {
"tools": "Værktøjer",
@ -798,7 +801,8 @@
"tool-name": "Værktøjsnavn",
"create-new-tool": "Opret et nyt værktøj",
"on-hand-checkbox-label": "Vis som \"Har allerede\" (afkrydset)",
"required-tools": "Nødvendige Værktøjer"
"required-tools": "Nødvendige Værktøjer",
"tool": "Tool"
},
"user": {
"admin": "Administrator",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Neue Rezeptnamen müssen eindeutig sein",
"scrape-recipe": "Rezept einlesen",
"scrape-recipe-description": "Importiere ein Rezept mit der URL. Gib die URL für die Seite an, die du importieren möchtest und Mealie wird versuchen, das Rezept von dieser Seite einzulesen und deiner Sammlung hinzuzufügen.",
"scrape-recipe-have-a-lot-of-recipes": "Hast Du viele Rezepte, die Du auf einmal einlesen willst?",
"scrape-recipe-suggest-bulk-importer": "Probiere den Massenimporter aus",
"import-original-keywords-as-tags": "Importiere ursprüngliche Stichwörter als Schlagwörter",
"stay-in-edit-mode": "Im Bearbeitungsmodus bleiben",
"import-from-zip": "Von Zip importieren",
@ -789,7 +791,8 @@
"tags": "Schlagworte",
"untagged-count": "{count} ohne Schlagworte",
"create-a-tag": "Ein Schlagwort erstellen",
"tag-name": "Name des Schlagworts"
"tag-name": "Name des Schlagworts",
"tag": "Schlagwort"
},
"tool": {
"tools": "Utensilien",
@ -798,7 +801,8 @@
"tool-name": "Name des Utensils",
"create-new-tool": "Neues Utensil erstellen",
"on-hand-checkbox-label": "Als \"vorhanden\" anzeigen (markiert)",
"required-tools": "Benötigte Utensilien"
"required-tools": "Benötigte Utensilien",
"tool": "Utensil"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Ετικέτες",
"untagged-count": "Χωρίς ετικέτα {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Εργαλεία",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Διαχειριστής",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "El nombre de la receta debe ser único",
"scrape-recipe": "Analiza receta",
"scrape-recipe-description": "Importa una receta por URL. Proporcione la URL para el sitio que desea importar, y Mealie intentará importar la receta de ese sitio y añadirla a su colección.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importar palabras clave originales como etiquetas",
"stay-in-edit-mode": "Permanecer en modo edición",
"import-from-zip": "Importar desde zip",
@ -789,7 +791,8 @@
"tags": "Etiquetas",
"untagged-count": "{count} sin etiquetar",
"create-a-tag": "Crear una etiqueta",
"tag-name": "Nombre de la etiqueta"
"tag-name": "Nombre de la etiqueta",
"tag": "Etiqueta"
},
"tool": {
"tools": "Utensilios",
@ -798,7 +801,8 @@
"tool-name": "Nombre del utensilio",
"create-new-tool": "Crear nuevo utensilio",
"on-hand-checkbox-label": "Mostrar como disponible (marcado)",
"required-tools": "Utensilios necesarios"
"required-tools": "Utensilios necesarios",
"tool": "Herramienta"
},
"user": {
"admin": "Administrador/a",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Reseptin nimen on oltava yksilöllinen",
"scrape-recipe": "Reseptin kaappain",
"scrape-recipe-description": "Kaappaa resepti urlin avulla. Anna sen reseptin url-osoite, jonka haluat kaapata, ja Mealie yrittää kaapata reseptin kyseiseltä sivustolta ja lisätä sen kokoelmaasi.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Tuo alkuperäiset avainsanat tunnisteiksi",
"stay-in-edit-mode": "Pysy muokkaustilassa",
"import-from-zip": "Tuo zip-arkistosta",
@ -789,7 +791,8 @@
"tags": "Tunnisteet",
"untagged-count": "Tunnisteettomat {count}",
"create-a-tag": "Luo tunniste",
"tag-name": "Tunnisteen nimi"
"tag-name": "Tunnisteen nimi",
"tag": "Tag"
},
"tool": {
"tools": "Työkalut",
@ -798,7 +801,8 @@
"tool-name": "Työkalun Nimi",
"create-new-tool": "Luo Uusi Työkalu",
"on-hand-checkbox-label": "Näytä työkalut, jotka omistan jo (valittu)",
"required-tools": "Tarvittavat Työkalut"
"required-tools": "Tarvittavat Työkalut",
"tool": "Tool"
},
"user": {
"admin": "Ylläpitäjä",

View File

@ -198,8 +198,8 @@
"refresh": "Actualiser",
"upload-file": "Transférer un fichier",
"created-on-date": "Créé le {0}",
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous enregistrer avant de partir? OK pour enregistrer, Annuler pour ignorer les modifications.",
"clipboard-copy-failure": "Failed to copy to the clipboard."
"unsaved-changes": "Vous avez des modifications non enregistrées. Voulez-vous les enregistrer? Ok pour enregistrer, annuler pour ignorer les modifications.",
"clipboard-copy-failure": "Échec de la copie vers le presse-papiers."
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Êtes-vous certain de vouloir supprimer <b>{groupName}<b/>?",
@ -250,7 +250,7 @@
"general-preferences": "Préférences générales",
"group-recipe-preferences": "Préférences de recette du groupe",
"report": "Rapport",
"report-with-id": "Identifiant du rapport : {id}",
"report-with-id": "ID du rapport: {id}",
"group-management": "Gestion des groupes",
"admin-group-management": "Administration des groupes",
"admin-group-management-text": "Les modifications apportées à ce groupe seront immédiatement prises en compte.",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Les noms de nouvelles recettes doivent être uniques",
"scrape-recipe": "Récupérer une recette",
"scrape-recipe-description": "Récupérer une recette par URL. Fournissez l'URL de la page que vous voulez récupérer, et Mealie essaiera d'en extraire la recette pour l'ajouter à votre collection.",
"scrape-recipe-have-a-lot-of-recipes": "Vous avez un tas de recettes à récupérer dun coup ?",
"scrape-recipe-suggest-bulk-importer": "Essayez limportateur de masse",
"import-original-keywords-as-tags": "Importer les mots-clés d'origine en tant que tags",
"stay-in-edit-mode": "Rester en mode édition",
"import-from-zip": "Importer depuis un zip",
@ -553,7 +555,7 @@
"tree-view": "Vue en arborescence",
"recipe-yield": "Nombre de parts",
"unit": "Unité",
"upload-image": "Envoyer une image",
"upload-image": "Ajouter une image",
"screen-awake": "Garder lécran allumé",
"remove-image": "Supprimer limage"
},
@ -574,7 +576,7 @@
"search-hint": "Appuyez sur « /»",
"advanced": "Avancé",
"auto-search": "Recherche automatique",
"no-results": "Aucun résultat trouvé"
"no-results": "Pas de résultats trouvés"
},
"settings": {
"add-a-new-theme": "Ajouter un nouveau thème",
@ -789,7 +791,8 @@
"tags": "Mots-clés",
"untagged-count": "{count} sans mot-clés",
"create-a-tag": "Créer une étiquette",
"tag-name": "Nom d'étiquette"
"tag-name": "Nom d'étiquette",
"tag": "Étiquette"
},
"tool": {
"tools": "Outils",
@ -798,7 +801,8 @@
"tool-name": "Nom de lustensile",
"create-new-tool": "Créer un nouvel ustensile",
"on-hand-checkbox-label": "Afficher comme disponible (coché)",
"required-tools": "Ustensiles nécessaires"
"required-tools": "Ustensiles nécessaires",
"tool": "Ustensile"
},
"user": {
"admin": "Administrateur",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Les noms de nouvelles recettes doivent être uniques",
"scrape-recipe": "Récupérer une recette",
"scrape-recipe-description": "Récupérer une recette par URL. Fournissez l'URL de la page que vous voulez récupérer, et Mealie essaiera d'en extraire la recette pour l'ajouter à votre collection.",
"scrape-recipe-have-a-lot-of-recipes": "Vous avez un tas de recettes à récupérer dun coup ?",
"scrape-recipe-suggest-bulk-importer": "Essayez limportateur de masse",
"import-original-keywords-as-tags": "Importer les mots-clés d'origine en tant que tags",
"stay-in-edit-mode": "Rester en mode édition",
"import-from-zip": "Importer depuis un zip",
@ -789,7 +791,8 @@
"tags": "Mots-clés",
"untagged-count": "{count} sans mot-clés",
"create-a-tag": "Créer un mot-clé",
"tag-name": "Mot-clé"
"tag-name": "Mot-clé",
"tag": "Étiquette"
},
"tool": {
"tools": "Ustensiles",
@ -798,7 +801,8 @@
"tool-name": "Nom de lustensile",
"create-new-tool": "Créer un nouvel ustensile",
"on-hand-checkbox-label": "Afficher comme disponible (coché)",
"required-tools": "Ustensiles nécessaires"
"required-tools": "Ustensiles nécessaires",
"tool": "Ustensile"
},
"user": {
"admin": "Administrateur",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Etiqueta"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Ferramenta"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "שם מתכון חדש חייב להיות ייחודי",
"scrape-recipe": "קריאת מתכון",
"scrape-recipe-description": "קריאת מתכון בעזרת לינק. ספק את הלינק של האתר שברצונך לקרוא, ומילי תנסה לקרוא את המתכון מהאתר ולהוסיף אותו לאוסף.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "ייבא שמות מפתח מקוריות כתגיות",
"stay-in-edit-mode": "השאר במצב עריכה",
"import-from-zip": "ייבא מקובץ",
@ -789,7 +791,8 @@
"tags": "תגיות",
"untagged-count": "לא מתוייג {count}",
"create-a-tag": "צור תגית",
"tag-name": "שם תגית"
"tag-name": "שם תגית",
"tag": "Tag"
},
"tool": {
"tools": "כלים",
@ -798,7 +801,8 @@
"tool-name": "שם כלי",
"create-new-tool": "יצירת כלי חדש",
"on-hand-checkbox-label": "הראה מה יש לי במטבח",
"required-tools": "צריך כלים"
"required-tools": "צריך כלים",
"tool": "Tool"
},
"user": {
"admin": "אדמין",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Naziv novog recepta mora imati jedinstveno ime",
"scrape-recipe": "Prikupi (skraperaj) recept",
"scrape-recipe-description": "Prikupi (skraperaj) recept putem URL-a. Priložite URL web stranice s koje želite prikupiti recept, a Mealie će pokušati prikupiti recept s te stranice i dodati ga u vašu kolekciju.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Uvezi originalne ključne riječi kao oznake",
"stay-in-edit-mode": "Ostanite u načinu uređivanja",
"import-from-zip": "Uvoz iz Zip-a",
@ -789,7 +791,8 @@
"tags": "Oznake",
"untagged-count": "Neoznačeno {count}",
"create-a-tag": "Kreiraj Oznaku",
"tag-name": "Naziv Oznake"
"tag-name": "Naziv Oznake",
"tag": "Tag"
},
"tool": {
"tools": "Alati",
@ -798,7 +801,8 @@
"tool-name": "Naziv Alata",
"create-new-tool": "Kreiraj Novi Alat",
"on-hand-checkbox-label": "Prikaži Alat Dostupnim (Označeno)",
"required-tools": "Potrebni Alati"
"required-tools": "Potrebni Alati",
"tool": "Tool"
},
"user": {
"admin": "Administrator",

View File

@ -42,7 +42,7 @@
"category-deleted": "Kategória törölve",
"category-deletion-failed": "Kategória törlése sikertelen",
"category-filter": "Kategória szűrő",
"category-update-failed": "Kategória elmentése sikertelen",
"category-update-failed": "Kategória frissítése sikertelen",
"category-updated": "Kategória frissítve",
"uncategorized-count": "Kategórizálatlan {count}",
"create-a-category": "Kategória létrehozása",
@ -53,7 +53,7 @@
"apprise-url": "Apprise URL",
"database": "Adatbázis",
"delete-event": "Esemény törlése",
"event-delete-confirmation": "Biztosan törölni akarod az eseményt?",
"event-delete-confirmation": "Biztosan törölni szeretné ezt az eseményt?",
"event-deleted": "Esemény törölve",
"event-updated": "Esemény Frissítve",
"new-notification-form-description": "A Mealie az Apprise könyvtárat használja az értesítésekhez. Számos lehetőséget kínál különbőző értesítési szolgáltatásokhoz. Nézd meg a wiki oldalukon, hogy kell URL-t létrehozni az általad használt szolgáltatáshoz. Az értesítés tipusának kiválasztásával egyéb beállítási lehetőségek jelenhetnek meg.",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Az új recept nevének egyedinek kell lennie",
"scrape-recipe": "Recept kinyerése",
"scrape-recipe-description": "Recept (adatok) kinyerése Url alapján. Adja meg a beolvasni kívánt oldal Url-címét, és Mealie megpróbálja beolvasni a receptet az adott oldalról, majd hozzáadja azt gyűjteményéhez.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Eredeti kulcsszavak importálása címkeként",
"stay-in-edit-mode": "Maradjon Szerkesztés módban",
"import-from-zip": "Importálás ZIP-ből",
@ -789,7 +791,8 @@
"tags": "Címkék",
"untagged-count": "Címkézetlen {count}",
"create-a-tag": "Címke létrehozása",
"tag-name": "Címke Neve"
"tag-name": "Címke Neve",
"tag": "Címke"
},
"tool": {
"tools": "Eszközök",
@ -798,7 +801,8 @@
"tool-name": "Eszköz neve",
"create-new-tool": "Új eszköz létrehozása",
"on-hand-checkbox-label": "Készleten lévőnek mutatni (Ellenőrizve)",
"required-tools": "Szükséges eszközök"
"required-tools": "Szükséges eszközök",
"tool": "Eszköz"
},
"user": {
"admin": "Adminisztrátor",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "I nuovi nomi delle ricette devono essere univoci",
"scrape-recipe": "Recupera Ricetta",
"scrape-recipe-description": "Recupera una ricetta da url. Fornire l'url per il sito che si desidera analizzare, e Mealie cercherà di recuperare la ricetta da quel sito e aggiungerlo alla vostra raccolta.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importa parole chiave originali come tag",
"stay-in-edit-mode": "Rimani in modalità Modifica",
"import-from-zip": "Importa da Zip",
@ -789,7 +791,8 @@
"tags": "Tag",
"untagged-count": "Senza Tag {count}",
"create-a-tag": "Crea un Tag",
"tag-name": "Nome del Tag"
"tag-name": "Nome del Tag",
"tag": "Tag"
},
"tool": {
"tools": "Strumenti",
@ -798,7 +801,8 @@
"tool-name": "Nome dell'Utensile",
"create-new-tool": "Crea un Nuovo Utensile",
"on-hand-checkbox-label": "Mostra come Disponibile (Spuntato)",
"required-tools": "Strumenti necessari"
"required-tools": "Strumenti necessari",
"tool": "Tool"
},
"user": {
"admin": "Amministratore",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Naujo recepto pavadinimas turi būti unikalus",
"scrape-recipe": "Nuskaityti receptą",
"scrape-recipe-description": "Nuskaityti receptą iš URL nuorodos. Pateikite recepto nuorodą, ir Mealie pabandys paimti recepto informaciją iš šios svetainės ir patalpinti ją jūsų kolekcijoje.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Įkelti pradinius raktažodžius kaip žymas",
"stay-in-edit-mode": "Toliau redaguoti",
"import-from-zip": "Įkelti iš .ZIP archyvo",
@ -789,7 +791,8 @@
"tags": "Žymos",
"untagged-count": "Nepažymėtų {count}",
"create-a-tag": "Kurti žymą",
"tag-name": "Žymos pavadinimas"
"tag-name": "Žymos pavadinimas",
"tag": "Tag"
},
"tool": {
"tools": "Įrankiai",
@ -798,7 +801,8 @@
"tool-name": "Įrankio pavadinimas",
"create-new-tool": "Pridėti naują įrankį",
"on-hand-checkbox-label": "Rodyti kaip turimą virtuvėje",
"required-tools": "Reikalingi įrankiai"
"required-tools": "Reikalingi įrankiai",
"tool": "Tool"
},
"user": {
"admin": "Administratorius",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Nieuwe receptnamen moeten uniek zijn",
"scrape-recipe": "Scrape recept",
"scrape-recipe-description": "Voeg een recept toe via een url. Geef de url op van de site welke je wil scannen voor een recept., en Mealie zal proberen het recept vanaf die plek te scannen en aan je collectie toe te voegen.",
"scrape-recipe-have-a-lot-of-recipes": "Heb je veel recepten die je in 1 keer wil importeren?",
"scrape-recipe-suggest-bulk-importer": "Probeer de bulk importer uit",
"import-original-keywords-as-tags": "Importeer oorspronkelijke trefwoorden als tags",
"stay-in-edit-mode": "Blijf in bewerkingsmodus",
"import-from-zip": "Importeren uit zip",
@ -789,7 +791,8 @@
"tags": "Labels",
"untagged-count": "Niet gelabeld {count}",
"create-a-tag": "Maak een nieuw label aan",
"tag-name": "Labelnaam"
"tag-name": "Labelnaam",
"tag": "Label"
},
"tool": {
"tools": "Keukengerei",
@ -798,7 +801,8 @@
"tool-name": "Naam van het keukengerei",
"create-new-tool": "Nieuw keukengerei aanmaken",
"on-hand-checkbox-label": "Tonen als in bezit (gemarkeerd)",
"required-tools": "Benodig kookgerei"
"required-tools": "Benodig kookgerei",
"tool": "Keukengerei"
},
"user": {
"admin": "Beheerder",

View File

@ -348,7 +348,7 @@
"recipe-data-migrations": "Overføring av oppskrifter",
"recipe-data-migrations-explanation": "Oppskrifter kan overføres fra et annet støttet program til Mealie. Dette er en flott måte å komme i gang med Mealie på.",
"choose-migration-type": "Velg type overføring",
"tag-all-recipes": "Merk alle oppskrifter med {tag-name}-emneord",
"tag-all-recipes": "Merk alle oppskrifter med emneordet {tag-name}",
"nextcloud-text": "Oppskrifter fra Nextcloud kan importeres fra en zip-fil som inneholder dataene lagret i Nextcloud. Se eksempelet på mappestrukture nedenfor for å sikre at oppskriftene kan importeres.",
"chowdown-text": "Mealie støtter Chowdown-arkivformatet. Last ned kodearkivet som en .zip-fil og last den opp nedenfor",
"recipe-1": "Oppskrift 1",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Navn på oppskrift må være unike",
"scrape-recipe": "Skrap oppskrift",
"scrape-recipe-description": "Skrap en oppskrift ved bruk av nettadresse. Oppgi nettadressen til nettstedet du vil skrape, så vil Mealie forsøke å skrape oppskriften fra den siden og legge den til i samlingen din.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importer originale søkeord som emneord",
"stay-in-edit-mode": "Forbli i redigeringsmodus",
"import-from-zip": "Importer fra zip-fil",
@ -789,7 +791,8 @@
"tags": "Emneord",
"untagged-count": "Umerkede {count}",
"create-a-tag": "Opprett et emneord",
"tag-name": "Navn på emneord"
"tag-name": "Navn på emneord",
"tag": "Tag"
},
"tool": {
"tools": "Kjøkkenredskap",
@ -798,7 +801,8 @@
"tool-name": "Navn på kjøkkenredskap",
"create-new-tool": "Opprett nytt kjøkkenredskap",
"on-hand-checkbox-label": "Vis som tilgjengelig (avmerket)",
"required-tools": "Påkrevde kjøkkenredskaper"
"required-tools": "Påkrevde kjøkkenredskaper",
"tool": "Tool"
},
"user": {
"admin": "Administrator",
@ -971,7 +975,7 @@
"seed-data": "Tilføringsdata",
"seed": "Tilfør",
"data-management": "Databehandling",
"data-management-description": "Velg hvilke data du vil gjøre endringer på.",
"data-management-description": "Velg hvilke data du vil endre.",
"select-data": "Velg data",
"select-language": "Velg språk",
"columns": "Kolonner",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Nazwa przepisu musi być unikalna",
"scrape-recipe": "Scrapuj Przepis",
"scrape-recipe-description": "Wczytaj przepis przez URL. Podaj adres URL witryny z przepisem, który chcesz wczytać, a Mealie spróbuje wyodrębnić przepis z tej strony i dodać go do kolekcji.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importuj oryginalne słowa kluczowe jako tagi",
"stay-in-edit-mode": "Pozostań w trybie edycji",
"import-from-zip": "Importuj z pliku Zip",
@ -789,7 +791,8 @@
"tags": "Tagi",
"untagged-count": "{count} bez etykiety",
"create-a-tag": "Utwórz znacznik",
"tag-name": "Nazwa znacznika"
"tag-name": "Nazwa znacznika",
"tag": "Tag"
},
"tool": {
"tools": "Narzędzia",
@ -798,7 +801,8 @@
"tool-name": "Nazwa narzędzia",
"create-new-tool": "Utwórz nowe narzędzie",
"on-hand-checkbox-label": "Pokaż jako Posiadane (Zaznaczono)",
"required-tools": "Wymagane Narzędzia"
"required-tools": "Wymagane Narzędzia",
"tool": "Tool"
},
"user": {
"admin": "Administrator",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Novos nomes de receitas devem ser únicos",
"scrape-recipe": "Extrair receita do site",
"scrape-recipe-description": "Scrape uma receita por url. Forneça o Url para o site que você deseja scrape, e Mealie tentará raspar a receita desse site e adicioná-la à sua coleção.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importar palavras-chave originais como marcadores",
"stay-in-edit-mode": "Permanecer no modo de edição",
"import-from-zip": "Importar do .zip",
@ -789,7 +791,8 @@
"tags": "Marcadores",
"untagged-count": "{count} sem marcador",
"create-a-tag": "Criar um marcador",
"tag-name": "Nome do Marcador"
"tag-name": "Nome do Marcador",
"tag": "Tag"
},
"tool": {
"tools": "Ferramentas",
@ -798,7 +801,8 @@
"tool-name": "Nome da ferramenta",
"create-new-tool": "Criar Ferramenta",
"on-hand-checkbox-label": "Mostrar como disponível (checado)",
"required-tools": "Ferramentas necessárias"
"required-tools": "Ferramentas necessárias",
"tool": "Tool"
},
"user": {
"admin": "Administrador",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Os nomes de receitas devem ser únicos",
"scrape-recipe": "Obter receita da Web (Scrape)",
"scrape-recipe-description": "Fazer scrape a receita por URL. Indique o URL da página a que quer fazer scrape e o Mealie tentará obter a receita dessa página e adicioná-la à sua coleção.",
"scrape-recipe-have-a-lot-of-recipes": "Tem muitas receitas para processar em simultâneo?",
"scrape-recipe-suggest-bulk-importer": "Experimente o importador em massa",
"import-original-keywords-as-tags": "Importar palavras-chave originais como etiquetas",
"stay-in-edit-mode": "Permanecer no modo de edição",
"import-from-zip": "Importar de Zip",
@ -789,7 +791,8 @@
"tags": "Etiquetas",
"untagged-count": "Sem etiqueta {count}",
"create-a-tag": "Criar uma Etiqueta",
"tag-name": "Nome da Etiqueta"
"tag-name": "Nome da Etiqueta",
"tag": "Etiqueta"
},
"tool": {
"tools": "Utensílios",
@ -798,7 +801,8 @@
"tool-name": "Nome do Utensílio",
"create-new-tool": "Criar Utensílio",
"on-hand-checkbox-label": "Mostrar como À Mão (Verificado)",
"required-tools": "Utensílios Necessários"
"required-tools": "Utensílios Necessários",
"tool": "Utensílio"
},
"user": {
"admin": "Administrador",

View File

@ -77,7 +77,7 @@
"tag-events": "Etichetele de Evenimente",
"category-events": "Categorie de Evenimente",
"when-a-new-user-joins-your-group": "Când un utilizator nou se alătură grupului tău",
"recipe-events": "Recipe Events"
"recipe-events": "Evenimente rețetă"
},
"general": {
"cancel": "Anulează",
@ -114,10 +114,10 @@
"json": "JSON",
"keyword": "Cuvânt cheie",
"link-copied": "Link copiat",
"loading": "Loading",
"loading": "Se încarcă",
"loading-events": "Se încarcă evenimentele",
"loading-recipe": "Loading recipe...",
"loading-ocr-data": "Loading OCR data...",
"loading-recipe": "Se încarcă rețeta...",
"loading-ocr-data": "Se încarcă datele OCR...",
"loading-recipes": "Se încarcă rețetele",
"message": "Mesaj",
"monday": "Luni",
@ -128,7 +128,7 @@
"no-recipe-found": "Nici o rețetă găsită",
"ok": "OK",
"options": "Opțiuni:",
"plural-name": "Plural Name",
"plural-name": "Denumire Plural",
"print": "Imprimare",
"print-preferences": "Preferințe de imprimare",
"random": "Aleatoriu",
@ -198,8 +198,8 @@
"refresh": "Reîncarcă",
"upload-file": "Încărcă fișier",
"created-on-date": "Creat pe {0}",
"unsaved-changes": "You have unsaved changes. Do you want to save before leaving? Okay to save, Cancel to discard changes.",
"clipboard-copy-failure": "Failed to copy to the clipboard."
"unsaved-changes": "Aveți modificări nesalvate. Doriți să salvați înainte de a închide aplicația? Apăsați \"OK\" pentru a salva sau \"Anulare\" pentru a renunța la modificări.",
"clipboard-copy-failure": "Copierea în clipboard a eșuat."
},
"group": {
"are-you-sure-you-want-to-delete-the-group": "Sunteți sigur că doriți să ștergeți <b>{groupName}<b/>?",
@ -214,7 +214,7 @@
"group-id-with-value": "ID-ul grupului: {groupID}",
"group-name": "Numele Grupului",
"group-not-found": "Grupul nu a fost găsit",
"group-token": "Group Token",
"group-token": "Token de grup",
"group-with-value": "Grup: {groupID}",
"groups": "Grupuri",
"manage-groups": "Gestionare grupuri",
@ -250,7 +250,7 @@
"general-preferences": "Preferințe generale",
"group-recipe-preferences": "Preferințe Rețetă de grup",
"report": "Raportează",
"report-with-id": "Report ID: {id}",
"report-with-id": "ID Raport: {id}",
"group-management": "Management grup",
"admin-group-management": "Gestionare grup administratori",
"admin-group-management-text": "Modificările la acest grup se vor reflecta imediat.",
@ -301,73 +301,73 @@
"this-rule-will-apply": "Această regulă va aplica {dayCriteria} {mealTypeCriteria}.",
"to-all-days": "la toate zilele",
"on-days": "on {0}s",
"for-all-meal-types": "for all meal types",
"for-type-meal-types": "for {0} meal types",
"meal-plan-rules": "Meal Plan Rules",
"new-rule": "New Rule",
"meal-plan-rules-description": "You can create rules for auto selecting recipes for your meal plans. These rules are used by the server to determine the random pool of recipes to select from when creating meal plans. Note that if rules have the same day/type constraints then the categories of the rules will be merged. In practice, it's unnecessary to create duplicate rules, but it's possible to do so.",
"new-rule-description": "When creating a new rule for a meal plan you can restrict the rule to be applicable for a specific day of the week and/or a specific type of meal. To apply a rule to all days or all meal types you can set the rule to \"Any\" which will apply it to all the possible values for the day and/or meal type.",
"recipe-rules": "Recipe Rules",
"applies-to-all-days": "Applies to all days",
"for-all-meal-types": "pentru toate tipurile de mese",
"for-type-meal-types": "pentru {0} tipuri de mese",
"meal-plan-rules": "Regulile Planului de Masă",
"new-rule": "Regulă nouă",
"meal-plan-rules-description": "Puteți crea reguli pentru selectarea automată a rețetelor pentru planurile dumneavoastră de masă. Aceste reguli sunt folosite de către server pentru a determina rețetele valabile pentru selecție, atunci când creezi planurile de masă. În cazul in care regulile au aceleași constrângeri de zi sau de tip, atunci categoriile regulilor vor fi fuzionate. În practică, este inutilă creerea regulilor dublate, dar este posibil să se întample acest lucru.",
"new-rule-description": "Atunci când creați o nouă regulă pentru un plan de masă puteți restricționa regula aplicabilă pentru o anumită zi a săptămânii și/sau pentru un anumit tip de masă. Pentru a aplica o regulă pentru toate zilele sau toate tipurile de mese puteţi seta regula la \"Oricare\" ce va fi aplicată la toate valorile posibile pentru ziua şi/sau tipul mesei.",
"recipe-rules": "Reguli rețetă",
"applies-to-all-days": "Se aplică pentru toate zilele",
"applies-on-days": "Applies on {0}s",
"meal-plan-settings": "Meal Plan Settings"
"meal-plan-settings": "Setările Planului de Masă"
},
"migration": {
"migration-data-removed": "Migration data removed",
"migration-data-removed": "Datele migrării au fost șterse",
"new-migration": "New Migration",
"no-file-selected": "No File Selected",
"no-migration-data-available": "No Migration Data Available",
"previous-migrations": "Previous Migrations",
"recipe-migration": "Recipe Migration",
"chowdown": {
"description": "Migrate data from Chowdown",
"description": "Migrează datele din Chowdown",
"description-long": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below.",
"title": "Chowdown"
},
"nextcloud": {
"description": "Migrate data from a Nextcloud Cookbook instance",
"description": "Migrează datele dintr-o instanță de Nextcloud Cookbook",
"description-long": "Nextcloud recipes can be imported from a zip file that contains the data stored in Nextcloud. See the example folder structure below to ensure your recipes are able to be imported.",
"title": "Nextcloud Cookbook"
},
"copymethat": {
"description-long": "Mealie can import recipes from Copy Me That. Export your recipes in HTML format, then upload the .zip below.",
"description-long": "Mealie poate importa rețete din Copy Me That. Exportă rețetele în format HTML, apoi încarcă fișierul de tip \".ZIP\" folosind câmpul de mai jos.",
"title": "Copy Me That Recipe Manager"
},
"paprika": {
"description-long": "Mealie can import recipes from the Paprika application. Export your recipes from paprika, rename the export extension to .zip and upload it below.",
"description-long": "Mealie poate importa rețete din aplicația Paprika. Exportă rețetele din Paprika, redenumește extensia de export în \".ZIP\" și încarcă-o folosind câmpul de mai jos.",
"title": "Paprika Recipe Manager"
},
"mealie-pre-v1": {
"description-long": "Mealie can import recipes from the Mealie application from a pre v1.0 release. Export your recipes from your old instance, and upload the zip file below. Note that only recipes can be imported from the export.",
"description-long": "Mealie poate importa rețetele din aplicația Mealie dintr-o lansare pre-v1.0. Exportă rețetele din vechea aplicație, apoi încarcă fișierul de tip \".ZIP\" folosind câmpul de mai jos. Numai rețetele pot fi importate din export.",
"title": "Mealie Pre v1.0"
},
"tandoor": {
"description-long": "Mealie can import recipes from Tandoor. Export your data in the \"Default\" format, then upload the .zip below.",
"title": "Tandoor Recipes"
"description-long": "Mealie poate importa rețete din Tandoor. Exportă datele în formatul \"Implicit\", apoi încarcă fișierul de tip \".ZIP\" folosind câmpul de mai jos.",
"title": "Rețete Tandoor"
},
"recipe-data-migrations": "Recipe Data Migrations",
"recipe-data-migrations-explanation": "Recipes can be migrated from another supported application to Mealie. This is a great way to get started with Mealie.",
"choose-migration-type": "Choose Migration Type",
"tag-all-recipes": "Tag all recipes with {tag-name} tag",
"nextcloud-text": "Nextcloud recipes can be imported from a zip file that contains the data stored in Nextcloud. See the example folder structure below to ensure your recipes are able to be imported.",
"chowdown-text": "Mealie natively supports the chowdown repository format. Download the code repository as a .zip file and upload it below",
"recipe-1": "Recipe 1",
"recipe-2": "Recipe 2",
"recipe-data-migrations": "Migrarea datelor rețetelor",
"recipe-data-migrations-explanation": "Rețetele pot fi migrate de la o altă aplicație ce este suportată de Mealie. Acesta este un mod excelent de a începe să folosiți Mealie.",
"choose-migration-type": "Alegeți tipul de migrare",
"tag-all-recipes": "Etichetați toate rețetele cu eticheta {tag-name}",
"nextcloud-text": "Rețetele din Nextcloud pot fi importate dintr-un fișier de tip \".ZIP\" ce conține toate datele stocate în Nextcloud. Vedeți structura directorului din exemplul de mai jos pentru a vă asigura că rețetele pot fi importate cu succes.",
"chowdown-text": "Mealie acceptă nativ formatul repo-ului Chowdown. Descărcați depozitul de cod ca fișier \".ZIP\" și încărcați-l mai jos.",
"recipe-1": "Rețeta 1",
"recipe-2": "Rețeta 2",
"paprika-text": "Mealie can import recipes from the Paprika application. Export your recipes from paprika, rename the export extension to .zip and upload it below.",
"mealie-text": "Mealie can import recipes from the Mealie application from a pre v1.0 release. Export your recipes from your old instance, and upload the zip file below. Note that only recipes can be imported from the export.",
"plantoeat": {
"title": "Plan to Eat",
"title": "Planifică să Mănânci",
"description-long": "Mealie can import recipies from Plan to Eat."
}
},
"new-recipe": {
"bulk-add": "Bulk Add",
"bulk-add": "Adăugare în masă",
"error-details": "Only websites containing ld+json or microdata can be imported by Mealie. Most major recipe websites support this data structure. If your site cannot be imported but there is json data in the log, please submit a github issue with the URL and data.",
"error-title": "Looks Like We Couldn't Find Anything",
"from-url": "Import a Recipe",
"from-url": "Importați o rețetă",
"github-issues": "GitHub Issues",
"google-ld-json-info": "Google ld+json Info",
"must-be-a-valid-url": "Must be a Valid URL",
"must-be-a-valid-url": "Trebuie să fie o adresă URL validă",
"paste-in-your-recipe-data-each-line-will-be-treated-as-an-item-in-a-list": "Paste in your recipe data. Each line will be treated as an item in a list",
"recipe-markup-specification": "Recipe Markup Specification",
"recipe-url": "Recipe URL",
@ -407,20 +407,20 @@
"categories": "Categories",
"comment-action": "Comment",
"comment": "Comment",
"comments": "Comments",
"delete-confirmation": "Are you sure you want to delete this recipe?",
"delete-recipe": "Delete Recipe",
"description": "Description",
"comments": "Comentarii",
"delete-confirmation": "Sunteți sigur că doriți să ștergeți această rețetă?",
"delete-recipe": "Șterge rețeta",
"description": "Descriere",
"disable-amount": "Disable Ingredient Amounts",
"disable-comments": "Disable Comments",
"duplicate": "Duplicate recipe",
"duplicate-name": "Name of the new recipe",
"edit-scale": "Edit Scale",
"fat-content": "Fat",
"fiber-content": "Fiber",
"grams": "grams",
"disable-comments": "Dezactivează comentariile",
"duplicate": "Reţeta duplicată",
"duplicate-name": "Denumirea noii rețete",
"edit-scale": "Modifică scara",
"fat-content": "Grăsime",
"fiber-content": "Fibră",
"grams": "grame",
"ingredient": "Ingredient",
"ingredients": "Ingredients",
"ingredients": "Ingrediente",
"insert-ingredient": "Insert Ingredient",
"insert-section": "Adăugare secțiune",
"instructions": "Instrucțiuni",
@ -471,51 +471,51 @@
"add-to-plan": "Adaugă la Plan",
"add-to-timeline": "Adaugă la Cronologie",
"recipe-added-to-list": "Rețeta a fost adăugată la listă",
"recipes-added-to-list": "Recipes added to list",
"recipes-added-to-list": "Rețeta a fost adăugată în listă",
"recipe-added-to-mealplan": "Rețeta a fist adăugată la planul de mese",
"failed-to-add-recipes-to-list": "Failed to add recipe to list",
"failed-to-add-recipes-to-list": "Adăugarea rețetei în listă a eșuat",
"failed-to-add-recipe-to-mealplan": "Adăugarea rețetei la planul de mese a eșuat",
"yield": "Yield",
"quantity": "Quantity",
"choose-unit": "Choose Unit",
"yield": "Producție",
"quantity": "Cantitate",
"choose-unit": "Alegeţi unitatea",
"press-enter-to-create": "Press Enter to Create",
"choose-food": "Choose Food",
"notes": "Notes",
"toggle-section": "Toggle Section",
"see-original-text": "See Original Text",
"original-text-with-value": "Original Text: {originalText}",
"ingredient-linker": "Ingredient Linker",
"linked-to-other-step": "Linked to other step",
"notes": "Note",
"toggle-section": "Activează/dezactivează secțiunea",
"see-original-text": "Vezi Textul Original",
"original-text-with-value": "Text original: {originalText}",
"ingredient-linker": "Legarea cu ingrediente",
"linked-to-other-step": "Conectat la alt pas",
"auto": "Auto",
"cook-mode": "Cook Mode",
"link-ingredients": "Link Ingredients",
"merge-above": "Merge Above",
"reset-scale": "Reset Scale",
"decrease-scale-label": "Decrease Scale by 1",
"increase-scale-label": "Increase Scale by 1",
"locked": "Locked",
"public-link": "Public Link",
"cook-mode": "Modul de gătire",
"link-ingredients": "Link-uri Ingrediente",
"merge-above": "Îmbină deasupra",
"reset-scale": "Resetează scara",
"decrease-scale-label": "Scade scara cu 1",
"increase-scale-label": "Crește scara cu 1",
"locked": "Blocat",
"public-link": "Link public",
"timer": {
"kitchen-timer": "Kitchen Timer",
"start-timer": "Start Timer",
"pause-timer": "Pause Timer",
"resume-timer": "Resume Timer",
"stop-timer": "Stop Timer"
"kitchen-timer": "Cronometru bucătărie",
"start-timer": "Pornește cronometrul",
"pause-timer": "Pauză cronometru",
"resume-timer": "Reluați cronometrul",
"stop-timer": "Oprește Cronometrul"
},
"edit-timeline-event": "Edit Timeline Event",
"timeline": "Timeline",
"edit-timeline-event": "Modifică Evenimentul din Cronologie",
"timeline": "Cronologie",
"timeline-is-empty": "Nothing on the timeline yet. Try making this recipe!",
"group-global-timeline": "{groupName} Global Timeline",
"open-timeline": "Open Timeline",
"made-this": "I Made This",
"how-did-it-turn-out": "How did it turn out?",
"user-made-this": "{user} made this",
"group-global-timeline": "Cronologia globală a grupului {groupName} ",
"open-timeline": "Deschide Cronologia",
"made-this": "Am făcut asta",
"how-did-it-turn-out": "Cum a ieșit?",
"user-made-this": "{user} a făcut asta",
"last-made-date": "Last Made {date}",
"api-extras-description": "Recipes extras are a key feature of the Mealie API. They allow you to create custom JSON key/value pairs within a recipe, to reference from 3rd party applications. You can use these keys to provide information, for example to trigger automations or custom messages to relay to your desired device.",
"message-key": "Message Key",
"parse": "Parse",
"attach-images-hint": "Attach images by dragging & dropping them into the editor",
"drop-image": "Drop image",
"drop-image": "Trage imaginea",
"enable-ingredient-amounts-to-use-this-feature": "Enable ingredient amounts to use this feature",
"recipes-with-units-or-foods-defined-cannot-be-parsed": "Recipes with units or foods defined cannot be parsed.",
"parse-ingredients": "Parse ingredients",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Numele rețetei trebuie să fie unic",
"scrape-recipe": "Importare rețetă",
"scrape-recipe-description": "Importa o rețetă prin url. Oferiți url-ul pentru site-ul pe care doriți să îl importați, și Mealie va încerca să importe rețeta de pe acel site și să o adauge la colecția ta.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importă cuvintele cheie originale ca tag-uri",
"stay-in-edit-mode": "Rămâi în modul Editare",
"import-from-zip": "Importă din zip",
@ -574,16 +576,16 @@
"search-hint": "Apasă „/”",
"advanced": "Avansat",
"auto-search": "Căutare automată",
"no-results": "No results found"
"no-results": "Nu s-au găsit rezultate"
},
"settings": {
"add-a-new-theme": "Adaugă o nouă temă",
"admin-settings": "Setări administrator",
"backup": {
"backup-created": "Backup created successfully",
"backup-created": "Copia de rezervă a fost salvată",
"backup-created-at-response-export_path": "Backup creat la {path}",
"backup-deleted": "Backup şters",
"restore-success": "Restore successful",
"restore-success": "Restaurare efectuată",
"backup-tag": "Backup la Tag-uri",
"create-heading": "Create a Backup",
"delete-backup": "Șterge Backup",
@ -614,37 +616,37 @@
"card-per-section": "Card Per Section",
"home-page": "Home Page",
"home-page-sections": "Home Page Sections",
"show-recent": "Show Recent"
"show-recent": "Afișare Recente"
},
"language": "Language",
"latest": "Latest",
"language": "Limbă",
"latest": "Ultimele",
"local-api": "Local API",
"locale-settings": "Locale settings",
"migrations": "Migrations",
"new-page": "New Page",
"notify": "Notify",
"organize": "Organize",
"page-name": "Page Name",
"pages": "Pages",
"profile": "Profile",
"new-page": "Pagină nouă",
"notify": "Notificare",
"organize": "Organizare",
"page-name": "Numele paginii",
"pages": "Pagini",
"profile": "Profil",
"remove-existing-entries-matching-imported-entries": "Remove existing entries matching imported entries",
"set-new-time": "Set New Time",
"set-new-time": "Setează timp nou",
"settings-update-failed": "Settings update failed",
"settings-updated": "Settings updated",
"site-settings": "Site Settings",
"site-settings": "Setările site-ului",
"theme": {
"accent": "Accent",
"dark": "Dark",
"default-to-system": "Default to system",
"error": "Error",
"error-creating-theme-see-log-file": "Error creating theme. See log file.",
"default-to-system": "Implicit în sistem",
"error": "Eroare",
"error-creating-theme-see-log-file": "Eroare la crearea temei. Vezi fişierul de jurnal.",
"error-deleting-theme": "Error deleting theme",
"error-updating-theme": "Error updating theme",
"info": "Info",
"light": "Light",
"primary": "Primary",
"secondary": "Secondary",
"success": "Success",
"success": "Succes",
"switch-to-dark-mode": "Switch to dark mode",
"switch-to-light-mode": "Switch to light mode",
"theme-deleted": "Theme deleted",
@ -652,9 +654,9 @@
"theme-name-is-required": "Theme Name is required.",
"theme-saved": "Theme Saved",
"theme-updated": "Theme updated",
"warning": "Warning",
"light-mode": "Light Mode",
"dark-mode": "Dark Mode"
"warning": "Atenţie",
"light-mode": "Mod Luminos",
"dark-mode": "Mod Întunecat"
},
"token": {
"active-tokens": "ACTIVE TOKENS",
@ -692,13 +694,13 @@
"configuration": "Configuration",
"docker-volume": "Docker Volume",
"docker-volume-help": "Mealie requires that the frontend container and the backend share the same docker volume or storage. This ensures that the frontend container can properly access the images and assets stored on disk.",
"volumes-are-misconfigured": "Volumes are misconfigured.",
"volumes-are-misconfigured": "Volumele sunt configurate greșit.",
"volumes-are-configured-correctly": "Volumes are configured correctly.",
"status-unknown-try-running-a-validation": "Status Unknown. Try running a validation.",
"validate": "Validate",
"email-configuration-status": "Email Configuration Status",
"email-configured": "Email Configured",
"email-test-results": "Email Test Results",
"email-configured": "E-mail configurat",
"email-test-results": "Trimite rezultatele testului pe e-mail",
"ready": "Ready",
"not-ready": "Not Ready - Check Environmental Variables",
"succeeded": "Succeeded",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Etichetă"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Instrument"
},
"user": {
"admin": "Admin",
@ -833,7 +837,7 @@
"password-updated": "Password updated",
"password": "Password",
"password-strength": "Password is {strength}",
"please-enter-password": "Please enter your new password.",
"please-enter-password": "Vă rugăm să introduceţi parola nouă.",
"register": "Register",
"reset-password": "Reset Password",
"sign-in": "Sign in",
@ -854,7 +858,7 @@
"username": "Username",
"users-header": "USERS",
"users": "Users",
"user-not-found": "User not found",
"user-not-found": "Utilizatorul nu a fost găsit",
"webhook-time": "Webhook Time",
"webhooks-enabled": "Webhooks Enabled",
"you-are-not-allowed-to-create-a-user": "You are not allowed to create a user",
@ -877,7 +881,7 @@
"user-management": "User Management",
"reset-locked-users": "Reset Locked Users",
"admin-user-creation": "Admin User Creation",
"admin-user-management": "Admin User Management",
"admin-user-management": "Gestionare utilizatori de tip administrator",
"user-details": "User Details",
"user-name": "User Name",
"authentication-method": "Authentication Method",
@ -890,8 +894,8 @@
"enable-advanced-features": "Enable advanced features",
"it-looks-like-this-is-your-first-time-logging-in": "It looks like this is your first time logging in.",
"dont-want-to-see-this-anymore-be-sure-to-change-your-email": "Don't want to see this anymore? Be sure to change your email in your user settings!",
"forgot-password": "Forgot Password",
"forgot-password-text": "Please enter your email address and we will send you a link to reset your password.",
"forgot-password": "Recuperare parola",
"forgot-password-text": "Va rugam introduceti adresa de e-mail pentru a va trimite un link de resetare parola.",
"changes-reflected-immediately": "Changes to this user will be reflected immediately."
},
"language-dialog": {

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Название рецепта должно быть уникальным",
"scrape-recipe": "Отсканировать рецепт",
"scrape-recipe-description": "Отсканировать рецепт по ссылке. Предоставьте ссылку на страницу, которую вы хотите отсканировать, и Mealie попытается вырезать рецепт с этого сайта и добавить его в свою коллекцию.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Импортировать исходные ключевые слова как теги",
"stay-in-edit-mode": "Остаться в режиме редактирования",
"import-from-zip": "Импорт из архива",
@ -789,7 +791,8 @@
"tags": "Теги",
"untagged-count": "Не помеченные {count}",
"create-a-tag": "Создать тег",
"tag-name": "Название тега"
"tag-name": "Название тега",
"tag": "Tag"
},
"tool": {
"tools": "Инструменты",
@ -798,7 +801,8 @@
"tool-name": "Название инструмента",
"create-new-tool": "Создать новый инструмент",
"on-hand-checkbox-label": "Показывать \"в наличии\" (отмечено)",
"required-tools": "Необходимые инструменты"
"required-tools": "Необходимые инструменты",
"tool": "Tool"
},
"user": {
"admin": "Администратор",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Názvy nových receptov musia byť jedinečné",
"scrape-recipe": "Scrapovať recept",
"scrape-recipe-description": "Stiahne recept zo zadaného url odkazu. Zadajte url stránky, z ktorej chcete stiahnuť recept, a Mealie sa pokúsi recept stiahnuť a vložiť do vašej zbierky.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importuj pôvodné kľúčové slová ako tagy",
"stay-in-edit-mode": "Zostať v režime editovania",
"import-from-zip": "Importovať zo Zip-súboru",
@ -789,7 +791,8 @@
"tags": "Štítky",
"untagged-count": "Neoznačené {count}",
"create-a-tag": "Vytvoriť štítok",
"tag-name": "Názov štítku"
"tag-name": "Názov štítku",
"tag": "Tag"
},
"tool": {
"tools": "Nástroje",
@ -798,7 +801,8 @@
"tool-name": "Názov náčinia",
"create-new-tool": "Vytvoriť nové náčinie",
"on-hand-checkbox-label": "Zobraz ako \"K dispozícii\" (Checked)",
"required-tools": "Potrebné nástroje"
"required-tools": "Potrebné nástroje",
"tool": "Tool"
},
"user": {
"admin": "Administrátor",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Značke",
"untagged-count": "Brez značke {count}",
"create-a-tag": "Ustvari značko",
"tag-name": "Ime značke"
"tag-name": "Ime značke",
"tag": "Tag"
},
"tool": {
"tools": "Orodja",
@ -798,7 +801,8 @@
"tool-name": "Ime orodja",
"create-new-tool": "Ustvari orodje",
"on-hand-checkbox-label": "Prikaži kot Na voljo (obkljukano)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Administrator",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Увези оригиналне кључне речи као ознаке",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Увези из Zip архиве",
@ -789,7 +791,8 @@
"tags": "Ознаке",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Прибор",
@ -798,7 +801,8 @@
"tool-name": "Назив прибора",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Потребан прибор"
"required-tools": "Потребан прибор",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Nya receptnamn måste vara unika",
"scrape-recipe": "Skrapa Recept",
"scrape-recipe-description": "Hämta ett recept med webbadress. Ange URL:en för webbplatsen du vill hämta, och Mealie kommer att försöka hämta receptet från den webbplatsen och lägga till det i din samling.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Importera ursprungliga sökord som taggar",
"stay-in-edit-mode": "Stanna kvar i redigeringsläge",
"import-from-zip": "Importera från zip",
@ -789,7 +791,8 @@
"tags": "Taggar",
"untagged-count": "Otaggad {count}",
"create-a-tag": "Skapa tagg",
"tag-name": "Taggnamn"
"tag-name": "Taggnamn",
"tag": "Tag"
},
"tool": {
"tools": "Redskap",
@ -798,7 +801,8 @@
"tool-name": "Verktygsnamn",
"create-new-tool": "Skapa nytt verktyg",
"on-hand-checkbox-label": "Visa som tillgänglig (markerad)",
"required-tools": "Verktyg som krävs"
"required-tools": "Verktyg som krävs",
"tool": "Tool"
},
"user": {
"admin": "Administratör",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Zip'ten içeri aktar",
@ -789,7 +791,8 @@
"tags": "Etiketler",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Etiket Adı"
"tag-name": "Etiket Adı",
"tag": "Etiket"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Araç"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "Назви нового рецепту має бути унікальна",
"scrape-recipe": "Розпізнати рецепт",
"scrape-recipe-description": "Розпізнати рецепт за посиланням. Вкажіть посилання на рецепт який ви хочете розпізнати й Mealie спробує розпізнати його і додати в вашу колекцію.",
"scrape-recipe-have-a-lot-of-recipes": "Багато рецептів, які ви хочете розпізнати відразу?",
"scrape-recipe-suggest-bulk-importer": "Спробуйте масовий розпізнавач",
"import-original-keywords-as-tags": "Імпортувати оригінальні ключові слова як теги",
"stay-in-edit-mode": "Залишитися в режимі редактора",
"import-from-zip": "Імпортувати з Zip",
@ -789,7 +791,8 @@
"tags": "Мітки",
"untagged-count": "Без мітки {count}",
"create-a-tag": "Створити тег",
"tag-name": "Назва тегу"
"tag-name": "Назва тегу",
"tag": "Мітка"
},
"tool": {
"tools": "Інструменти",
@ -798,7 +801,8 @@
"tool-name": "Назва інструмента",
"create-new-tool": "Створити новий інструмент",
"on-hand-checkbox-label": "Показувати як в наявності (позначено)",
"required-tools": "Необхідні інструменти"
"required-tools": "Необхідні інструменти",
"tool": "Інструмент"
},
"user": {
"admin": "Адміністратор",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -789,7 +791,8 @@
"tags": "Tags",
"untagged-count": "Untagged {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "Admin",

View File

@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "新食谱名必须唯一",
"scrape-recipe": "刮削食谱",
"scrape-recipe-description": "通过URL刮削食谱。提供你想要刮削网址的URLMealie会尝试从该网址刮削食谱并添加到你的收藏中。",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "导入原始关键字作为标签",
"stay-in-edit-mode": "留在编辑模式",
"import-from-zip": "从Zip压缩包导入",
@ -789,7 +791,8 @@
"tags": "标签",
"untagged-count": "无标签的共 {count} 个",
"create-a-tag": "创建标签",
"tag-name": "标签名称"
"tag-name": "标签名称",
"tag": "Tag"
},
"tool": {
"tools": "用具",
@ -798,7 +801,8 @@
"tool-name": "用具名称",
"create-new-tool": "新建用具",
"on-hand-checkbox-label": "显示为在手上(选中)",
"required-tools": "所需用具"
"required-tools": "所需用具",
"tool": "Tool"
},
"user": {
"admin": "管理员",

View File

@ -249,7 +249,7 @@
"disable-organizing-recipe-ingredients-by-units-and-food-description": "Hides the Food, Unit, and Amount fields for ingredients and treats ingredients as plain text fields.",
"general-preferences": "General Preferences",
"group-recipe-preferences": "Group Recipe Preferences",
"report": "Report",
"report": "報告",
"report-with-id": "Report ID: {id}",
"group-management": "Group Management",
"admin-group-management": "Admin Group Management",
@ -292,7 +292,7 @@
"day-any": "Any",
"editor": "Editor",
"meal-recipe": "Meal Recipe",
"meal-title": "Meal Title",
"meal-title": "用餐標題",
"meal-note": "Meal Note",
"note-only": "Note Only",
"random-meal": "Random Meal",
@ -533,6 +533,8 @@
"new-recipe-names-must-be-unique": "New recipe names must be unique",
"scrape-recipe": "Scrape Recipe",
"scrape-recipe-description": "Scrape a recipe by url. Provide the url for the site you want to scrape, and Mealie will attempt to scrape the recipe from that site and add it to your collection.",
"scrape-recipe-have-a-lot-of-recipes": "Have a lot of recipes you want to scrape at once?",
"scrape-recipe-suggest-bulk-importer": "Try out the bulk importer",
"import-original-keywords-as-tags": "Import original keywords as tags",
"stay-in-edit-mode": "Stay in Edit mode",
"import-from-zip": "Import from Zip",
@ -706,7 +708,7 @@
"general-about": "General About",
"application-version": "Application Version",
"application-version-error-text": "Your current version ({0}) does not match the latest release. Considering updating to the latest version ({1}).",
"mealie-is-up-to-date": "Mealie is up to date",
"mealie-is-up-to-date": "Mealie已經更新了",
"secure-site": "Secure Site",
"secure-site-error-text": "Serve via localhost or secure with https. Clipboard and additional browser APIs may not work.",
"secure-site-success-text": "Site is accessed by localhost or https",
@ -751,7 +753,7 @@
"all-recipes": "所有食譜",
"backups": "Backups",
"categories": "類別",
"cookbooks": "Cookbooks",
"cookbooks": "食譜",
"dashboard": "控制面板",
"home-page": "首頁",
"manage-users": "管理使用者",
@ -766,8 +768,8 @@
"background-tasks": "Background Tasks",
"parser": "Parser",
"developer": "Developer",
"cookbook": "Cookbook",
"create-cookbook": "Create a new cookbook"
"cookbook": "食譜",
"create-cookbook": "新建一個食譜合集"
},
"signup": {
"error-signing-up": "註冊失敗",
@ -789,7 +791,8 @@
"tags": "標籤",
"untagged-count": "為標記的 {count}",
"create-a-tag": "Create a Tag",
"tag-name": "Tag Name"
"tag-name": "Tag Name",
"tag": "Tag"
},
"tool": {
"tools": "Tools",
@ -798,7 +801,8 @@
"tool-name": "Tool Name",
"create-new-tool": "Create New Tool",
"on-hand-checkbox-label": "Show as On Hand (Checked)",
"required-tools": "Required Tools"
"required-tools": "Required Tools",
"tool": "Tool"
},
"user": {
"admin": "管理員",
@ -897,7 +901,7 @@
"language-dialog": {
"translated": "translated",
"choose-language": "Choose Language",
"select-description": "Choose the language for the Mealie UI. The setting only applies to you, not other users.",
"select-description": "選擇Mealie 使用者介面 的語言。 此設定僅適用於您,不適用於其他使用者。",
"how-to-contribute-description": "Is something not translated yet, mistranslated, or your language missing from the list? {read-the-docs-link} on how to contribute!",
"read-the-docs": "Read the docs"
},
@ -1049,7 +1053,7 @@
"split-by-block": "Split by text block",
"flatten": "Flatten regardless of original formating",
"help": {
"help": "Help",
"help": "幫助",
"mouse-modes": "Mouse modes",
"selection-mode": "Selection Mode (default)",
"selection-mode-desc": "The selection mode is the main mode that can be used to enter data:",
@ -1101,7 +1105,7 @@
"actions-description-destructive": "destructive",
"actions-description-irreversible": "irreversible",
"logs-action-refresh": "Refresh Logs",
"logs-page-title": "Mealie Logs",
"logs-page-title": "Mealie紀錄",
"logs-tail-lines-label": "Tail Lines"
},
"mainentance": {
@ -1160,14 +1164,14 @@
"looking-for-privacy-settings": "Looking for Privacy Settings?",
"manage-your-api-tokens": "Manage Your API Tokens",
"manage-user-profile": "Manage User Profile",
"manage-cookbooks": "Manage Cookbooks",
"manage-cookbooks": "管理食譜",
"manage-members": "Manage Members",
"manage-webhooks": "Manage Webhooks",
"manage-notifiers": "Manage Notifiers",
"manage-data-migrations": "Manage Data Migrations"
},
"cookbook": {
"cookbooks": "Cookbooks",
"cookbooks": "食譜",
"description": "Cookbooks are another way to organize recipes by creating cross sections of recipes and tags. Creating a cookbook will add an entry to the side-bar and all the recipes with the tags and categories chosen will be displayed in the cookbook.",
"public-cookbook": "Public Cookbook",
"public-cookbook-description": "Public Cookbooks can be shared with non-mealie users and will be displayed on your groups page.",
@ -1176,7 +1180,7 @@
"require-all-categories": "Require All Categories",
"require-all-tags": "Require All Tags",
"require-all-tools": "Require All Tools",
"cookbook-name": "Cookbook Name",
"cookbook-with-name": "Cookbook {0}"
"cookbook-name": "食譜名",
"cookbook-with-name": "食譜 {0}"
}
}

View File

@ -16,7 +16,7 @@ export default {
hid: "og:image",
property: "og:image",
content:
"https://raw.githubusercontent.com/hay-kot/mealie/dev/frontend/public/img/icons/android-chrome-512x512.png",
"https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-512x512.png",
},
{ charset: "utf-8" },
{ name: "viewport", content: "width=device-width, initial-scale=1" },

View File

@ -20,7 +20,7 @@
<AdvancedOnly>
<v-container class="d-flex justify-center align-center my-4">
<a :to="`/group/migrations`"> {{ $t('recipe.looking-for-migrations') }}</a>
<router-link :to="`/group/migrations`"> {{ $t('recipe.looking-for-migrations') }}</router-link>
</v-container>
</AdvancedOnly>
</div>
@ -42,6 +42,11 @@ export default defineComponent({
text: i18n.tc("recipe.import-with-url"),
value: "url",
},
{
icon: $globals.icons.link,
text: i18n.tc("recipe.bulk-url-import"),
value: "bulk",
},
{
icon: $globals.icons.edit,
text: i18n.tc("recipe.create-recipe"),
@ -52,11 +57,6 @@ export default defineComponent({
text: i18n.tc("recipe.import-with-zip"),
value: "zip",
},
{
icon: $globals.icons.link,
text: i18n.tc("recipe.bulk-url-import"),
value: "bulk",
},
{
icon: $globals.icons.robot,
text: i18n.tc("recipe.debug-scraper"),

View File

@ -4,7 +4,8 @@
<div>
<v-card-title class="headline"> {{ $t('recipe.scrape-recipe') }} </v-card-title>
<v-card-text>
{{ $t('recipe.scrape-recipe-description') }}
<p>{{ $t('recipe.scrape-recipe-description') }}</p>
<p>{{ $t('recipe.scrape-recipe-have-a-lot-of-recipes') }} <a :href="bulkImporterTarget">{{ $t('recipe.scrape-recipe-suggest-bulk-importer') }}</a>.</p>
<v-text-field
v-model="recipeUrl"
:label="$t('new-recipe.recipe-url')"
@ -94,6 +95,8 @@ export default defineComponent({
const router = useRouter();
const tags = useTagStore();
const bulkImporterTarget = computed(() => `/g/${groupSlug.value}/r/create/bulk`);
function handleResponse(response: AxiosResponse<string> | null, edit = false, refreshTags = false) {
if (response?.status !== 201) {
state.error = true;
@ -167,6 +170,7 @@ export default defineComponent({
}
return {
bulkImporterTarget,
recipeUrl,
importKeywordsAsTags,
stayInEditMode,

View File

@ -39,7 +39,9 @@
>
<v-card-text>
{{ $t("general.confirm-delete-generic") }}
<MultiPurposeLabel v-if="deleteTarget" class="mt-4 ml-4" :label="deleteTarget" />
<v-row>
<MultiPurposeLabel v-if="deleteTarget" class="mt-4 ml-4 mb-1" :label="deleteTarget" />
</v-row>
</v-card-text>
</BaseDialog>

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -1,5 +1,6 @@
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.routing import APIRoute
@ -48,6 +49,17 @@ app = FastAPI(
app.add_middleware(GZipMiddleware, minimum_size=1000)
if not settings.PRODUCTION:
allowed_origins = ["http://localhost:3000"]
app.add_middleware(
CORSMiddleware,
allow_origins=allowed_origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
register_debug_handler(app)

View File

@ -0,0 +1,150 @@
from uuid import uuid4
from slugify import slugify
from sqlalchemy.orm import Session
from mealie.core import root_logger
from mealie.db.models.group.group import Group
from mealie.db.models.group.shopping_list import ShoppingList, ShoppingListMultiPurposeLabel
from mealie.db.models.labels import MultiPurposeLabel
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
logger = root_logger.get_logger("init_db")
def fix_recipe_normalized_search_properties(session: Session):
recipes = session.query(RecipeModel).all()
recipes_fixed = False
for recipe in recipes:
add_to_session = False
if recipe.name and not recipe.name_normalized:
recipe.name_normalized = RecipeModel.normalize(recipe.name)
add_to_session = True
if recipe.description and not recipe.description_normalized:
recipe.description_normalized = RecipeModel.normalize(recipe.description)
add_to_session = True
for ingredient in recipe.recipe_ingredient:
if ingredient.note and not ingredient.note_normalized:
ingredient.note_normalized = RecipeModel.normalize(ingredient.note)
add_to_session = True
if ingredient.original_text and not ingredient.original_text_normalized:
ingredient.original_text = RecipeModel.normalize(ingredient.original_text_normalized)
add_to_session = True
if add_to_session:
recipes_fixed = True
session.add(recipe)
if recipes_fixed:
logger.info("Updating recipe normalized search properties")
session.commit()
def fix_shopping_list_label_settings(session: Session):
shopping_lists = session.query(ShoppingList).all()
labels = session.query(MultiPurposeLabel).all()
label_settings_fixed = False
for shopping_list in shopping_lists:
labels_by_id = {label.id: label for label in labels if label.group_id == shopping_list.group_id}
for label_setting in shopping_list.label_settings:
if not labels_by_id.pop(label_setting.label_id, None):
# label setting is no longer valid, so delete it
session.delete(label_setting)
label_settings_fixed = True
if not labels_by_id:
# all labels are accounted for, so we don't need to add any
continue
label_settings_fixed = True
for i, label in enumerate(labels_by_id.values()):
new_label_setting = ShoppingListMultiPurposeLabel(
id=uuid4(),
shopping_list_id=shopping_list.id,
label_id=label.id,
position=i + len(shopping_list.label_settings),
)
session.add(new_label_setting)
if label_settings_fixed:
logger.info("Fixing shopping list label settings")
session.commit()
def fix_group_slugs(session: Session):
groups = session.query(Group).all()
seen_slugs: set[str] = set()
groups_fixed = False
for group in groups:
if not group.slug:
original_name = group.name
new_name = original_name
attempts = 0
while True:
slug = slugify(group.name)
if slug not in seen_slugs:
break
attempts += 1
new_name = f"{original_name} ({attempts})"
groups_fixed = True
group.name = new_name
group.slug = slug
if groups_fixed:
logger.info("Adding missing group slugs")
session.commit()
def fix_normalized_unit_and_food_names(session: Session):
units = session.query(IngredientUnitModel).all()
units_fixed = False
for unit in units:
add_to_session = False
if unit.name and not unit.name_normalized:
unit.name_normalized = IngredientUnitModel.normalize(unit.name)
add_to_session = True
if unit.abbreviation and not unit.abbreviation_normalized:
unit.abbreviation_normalized = IngredientUnitModel.normalize(unit.abbreviation)
add_to_session = True
if add_to_session:
units_fixed = True
session.add(unit)
if units_fixed:
logger.info("Updating unit normalized search properties")
session.commit()
foods = session.query(IngredientFoodModel).all()
foods_fixed = False
for food in foods:
add_to_session = False
if food.name and not food.name_normalized:
food.name_normalized = IngredientFoodModel.normalize(food.name)
add_to_session = True
if add_to_session:
foods_fixed = True
session.add(food)
if foods_fixed:
logger.info("Updating food normalized search properties")
session.commit()
def fix_migration_data(session: Session):
logger.info("Checking for migration data fixes")
fix_recipe_normalized_search_properties(session)
fix_shopping_list_label_settings(session)
fix_group_slugs(session)
fix_normalized_unit_and_food_names(session)

View File

@ -11,6 +11,7 @@ from mealie.core import root_logger
from mealie.core.config import get_app_settings
from mealie.db.db_setup import session_context
from mealie.db.fixes.fix_group_with_no_name import fix_group_with_no_name
from mealie.db.fixes.fix_migration_data import fix_migration_data
from mealie.db.fixes.fix_slug_foods import fix_slug_food_names
from mealie.repos.all_repositories import get_repositories
from mealie.repos.repository_factory import AllRepositories
@ -97,6 +98,9 @@ def main():
session.execute(text("CREATE EXTENSION IF NOT EXISTS pg_trgm;"))
db = get_repositories(session)
safe_try(lambda: fix_migration_data(session))
safe_try(lambda: fix_slug_food_names(db))
safe_try(lambda: fix_group_with_no_name(session))
if db.users.get_all():
logger.debug("Database exists")
@ -104,9 +108,6 @@ def main():
logger.info("Database contains no users, initializing...")
init_db(db)
safe_try(lambda: fix_slug_food_names(db))
safe_try(lambda: fix_group_with_no_name(session))
if __name__ == "__main__":
main()

View File

@ -1,5 +1,7 @@
import uuid
from typing import Any
from sqlalchemy import Dialect
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.types import CHAR, TypeDecorator
@ -17,13 +19,8 @@ class GUID(TypeDecorator):
def generate():
return uuid.uuid4()
def load_dialect_impl(self, dialect):
if dialect.name == "postgresql":
return dialect.type_descriptor(UUID())
else:
return dialect.type_descriptor(CHAR(32))
def process_bind_param(self, value, dialect):
@staticmethod
def convert_value_to_guid(value: Any, dialect: Dialect) -> str | None:
if value is None:
return value
elif dialect.name == "postgresql":
@ -35,7 +32,25 @@ class GUID(TypeDecorator):
# hexstring
return "%.32x" % value.int
def load_dialect_impl(self, dialect):
if dialect.name == "postgresql":
return dialect.type_descriptor(UUID())
else:
return dialect.type_descriptor(CHAR(32))
def process_bind_param(self, value, dialect):
return self.convert_value_to_guid(value, dialect)
def _uuid_value(self, value):
if value is None:
return value
else:
if not isinstance(value, uuid.UUID):
value = uuid.UUID(value)
return value
def process_result_value(self, value, dialect):
if value is not None and not isinstance(value, uuid.UUID):
value = uuid.UUID(value)
return value
return self._uuid_value(value)
def sort_key_function(self, value):
return self._uuid_value(value)

View File

@ -1,9 +1,9 @@
{
"generic": {
"server-error": "Váratlan hiba történt"
"server-error": "Egy váratlan hiba történt"
},
"recipe": {
"unique-name-error": "A receptek nevének egyedinek kell lennie"
"unique-name-error": "A receptek neveinek egyedi értéknek kell lenniük"
},
"mealplan": {
"no-recipes-match-your-rules": "Nem található recept a beállítottt szabályok alapján"
@ -12,7 +12,7 @@
"user-updated": "Felhasználó frissítve",
"password-updated": "Jelszó frissítve",
"invalid-current-password": "Érvénytelen jelenlegi jelszó",
"ldap-update-password-unavailable": "Nem sikerült jelszót váltani, a felhasználó LDAP-al lépett be"
"ldap-update-password-unavailable": "A jelszó frissítése sikertelen, a felhasználó LDAP-al lépett be"
},
"group": {
"report-deleted": "A jelentés törlésre került."

View File

@ -84,9 +84,7 @@ def content_with_meta(group_slug: str, recipe: Recipe) -> str:
f"{__app_settings.BASE_URL}/api/media/recipes/{recipe.id}/images/original.webp?version={recipe.image}"
)
else:
image_url = (
"https://raw.githubusercontent.com/hay-kot/mealie/dev/frontend/public/img/icons/android-chrome-512x512.png"
)
image_url = "https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-512x512.png"
ingredients: list[str] = []
if recipe.settings.disable_amount: # type: ignore

View File

@ -1,4 +1,5 @@
import datetime
import uuid
from os import path
from pathlib import Path
@ -10,6 +11,8 @@ from sqlalchemy.orm import sessionmaker
from alembic import command
from alembic.config import Config
from mealie.db import init_db
from mealie.db.models._model_utils import GUID
from mealie.services._base_service import BaseService
PROJECT_DIR = Path(__file__).parent.parent.parent.parent
@ -38,23 +41,33 @@ class AlchemyExporter(BaseService):
self.session_maker = sessionmaker(bind=self.engine)
@staticmethod
def convert_to_datetime(data: dict) -> dict:
def is_uuid(value: str) -> bool:
try:
uuid.UUID(value)
return True
except ValueError:
return False
def convert_types(self, data: dict) -> dict:
"""
walks the dictionary to convert all things that look like timestamps to datetime objects
walks the dictionary to restore all things that look like string representations of their complex types
used in the context of reading a json file into a database via SQLAlchemy.
"""
for key, value in data.items():
if isinstance(value, dict):
data = AlchemyExporter.convert_to_datetime(value)
data = self.convert_types(value)
elif isinstance(value, list): # assume that this is a list of dictionaries
data[key] = [AlchemyExporter.convert_to_datetime(item) for item in value]
data[key] = [self.convert_types(item) for item in value]
elif isinstance(value, str):
if key in AlchemyExporter.look_for_datetime:
data[key] = AlchemyExporter.DateTimeParser(dt=value).dt
if key in AlchemyExporter.look_for_date:
data[key] = AlchemyExporter.DateTimeParser(date=value).date
if key in AlchemyExporter.look_for_time:
data[key] = AlchemyExporter.DateTimeParser(time=value).time
if self.is_uuid(value):
# convert the data to the current database's native GUID type
data[key] = GUID.convert_value_to_guid(value, self.engine.dialect)
if key in self.look_for_datetime:
data[key] = self.DateTimeParser(dt=value).dt
if key in self.look_for_date:
data[key] = self.DateTimeParser(date=value).date
if key in self.look_for_time:
data[key] = self.DateTimeParser(time=value).time
return data
def dump_schema(self) -> dict:
@ -105,7 +118,7 @@ class AlchemyExporter(BaseService):
del db_dump["alembic_version"]
"""Restores all data from dictionary into the database"""
with self.engine.begin() as connection:
data = AlchemyExporter.convert_to_datetime(db_dump)
data = self.convert_types(db_dump)
self.meta.reflect(bind=self.engine)
for table_name, rows in data.items():
@ -139,8 +152,8 @@ SELECT SETVAL('shopping_list_item_extras_id_seq', (SELECT MAX(id) FROM shopping_
)
)
# Run all migrations up to current version
command.upgrade(alembic_cfg, "head")
# Re-init database to finish migrations
init_db.main()
def drop_all(self) -> None:
"""Drops all data from the database"""

View File

@ -83,7 +83,7 @@ class BackupV2(BaseService):
# Validation
if not contents.validate():
self.logger.error(
"Invalid backup file. file does not contain required elements (data directory and database.json"
"Invalid backup file. file does not contain required elements (data directory and database.json)"
)
raise ValueError("Invalid backup file")

View File

@ -212,7 +212,7 @@
<td style="width: 550px">
<img
height="auto"
src="https://api-test.emailbuilder.top/saemailbuilder/dc23dc82-ffd7-4f4c-b563-94f23db4c2c3/images/256d8bd6-ffde-4bf2-b577-dd8306dae877/file.png"
src="https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/mealie-email-banner.png"
style="
border: 0;
display: block;

View File

@ -16,7 +16,7 @@ class ApprisePublisher:
def __init__(self, hard_fail=False) -> None:
asset = apprise.AppriseAsset(
async_mode=True,
image_url_mask="https://raw.githubusercontent.com/hay-kot/mealie/dev/frontend/public/img/icons/android-chrome-maskable-512x512.png",
image_url_mask="https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-maskable-512x512.png",
)
self.apprise = apprise.Apprise(asset=asset)
self.hard_fail = hard_fail

566
poetry.lock generated
View File

@ -97,13 +97,13 @@ requests-oauthlib = "*"
[[package]]
name = "astroid"
version = "2.15.6"
version = "2.15.8"
description = "An abstract syntax tree for Python with inference support."
optional = false
python-versions = ">=3.7.2"
files = [
{file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"},
{file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"},
{file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
{file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
]
[package.dependencies]
@ -132,34 +132,54 @@ docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-
tests = ["attrs[tests-no-zope]", "zope.interface"]
tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
[[package]]
name = "babel"
version = "2.14.0"
description = "Internationalization utilities"
optional = false
python-versions = ">=3.7"
files = [
{file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"},
{file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"},
]
[package.extras]
dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"]
[[package]]
name = "bcrypt"
version = "4.0.1"
version = "4.1.2"
description = "Modern password hashing for your software and your servers"
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
files = [
{file = "bcrypt-4.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b1023030aec778185a6c16cf70f359cbb6e0c289fd564a7cfa29e727a1c38f8f"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:08d2947c490093a11416df18043c27abe3921558d2c03e2076ccb28a116cb6d0"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eaa47d4661c326bfc9d08d16debbc4edf78778e6aaba29c1bc7ce67214d4410"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae88eca3024bb34bb3430f964beab71226e761f51b912de5133470b649d82344"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:a522427293d77e1c29e303fc282e2d71864579527a04ddcfda6d4f8396c6c36a"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:fbdaec13c5105f0c4e5c52614d04f0bca5f5af007910daa8b6b12095edaa67b3"},
{file = "bcrypt-4.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ca3204d00d3cb2dfed07f2d74a25f12fc12f73e606fcaa6975d1f7ae69cacbb2"},
{file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:089098effa1bc35dc055366740a067a2fc76987e8ec75349eb9484061c54f535"},
{file = "bcrypt-4.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e9a51bbfe7e9802b5f3508687758b564069ba937748ad7b9e890086290d2f79e"},
{file = "bcrypt-4.0.1-cp36-abi3-win32.whl", hash = "sha256:2caffdae059e06ac23fce178d31b4a702f2a3264c20bfb5ff541b338194d8fab"},
{file = "bcrypt-4.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:8a68f4341daf7522fe8d73874de8906f3a339048ba406be6ddc1b3ccb16fc0d9"},
{file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf4fa8b2ca74381bb5442c089350f09a3f17797829d958fad058d6e44d9eb83c"},
{file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:67a97e1c405b24f19d08890e7ae0c4f7ce1e56a712a016746c8b2d7732d65d4b"},
{file = "bcrypt-4.0.1-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b3b85202d95dd568efcb35b53936c5e3b3600c7cdcc6115ba461df3a8e89f38d"},
{file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbb03eec97496166b704ed663a53680ab57c5084b2fc98ef23291987b525cb7d"},
{file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:5ad4d32a28b80c5fa6671ccfb43676e8c1cc232887759d1cd7b6f56ea4355215"},
{file = "bcrypt-4.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b57adba8a1444faf784394de3436233728a1ecaeb6e07e8c22c8848f179b893c"},
{file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b2cea8a9ed3d55b4491887ceadb0106acf7c6387699fca771af56b1cdeeda"},
{file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:2b3ac11cf45161628f1f3733263e63194f22664bf4d0c0f3ab34099c02134665"},
{file = "bcrypt-4.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3100851841186c25f127731b9fa11909ab7b1df6fc4b9f8353f4f1fd952fbf71"},
{file = "bcrypt-4.0.1.tar.gz", hash = "sha256:27d375903ac8261cfe4047f6709d16f7d18d39b1ec92aaf72af989552a650ebd"},
{file = "bcrypt-4.1.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ac621c093edb28200728a9cca214d7e838529e557027ef0581685909acd28b5e"},
{file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea505c97a5c465ab8c3ba75c0805a102ce526695cd6818c6de3b1a38f6f60da1"},
{file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57fa9442758da926ed33a91644649d3e340a71e2d0a5a8de064fb621fd5a3326"},
{file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:eb3bd3321517916696233b5e0c67fd7d6281f0ef48e66812db35fc963a422a1c"},
{file = "bcrypt-4.1.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6cad43d8c63f34b26aef462b6f5e44fdcf9860b723d2453b5d391258c4c8e966"},
{file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:44290ccc827d3a24604f2c8bcd00d0da349e336e6503656cb8192133e27335e2"},
{file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:732b3920a08eacf12f93e6b04ea276c489f1c8fb49344f564cca2adb663b3e4c"},
{file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1c28973decf4e0e69cee78c68e30a523be441972c826703bb93099868a8ff5b5"},
{file = "bcrypt-4.1.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b8df79979c5bae07f1db22dcc49cc5bccf08a0380ca5c6f391cbb5790355c0b0"},
{file = "bcrypt-4.1.2-cp37-abi3-win32.whl", hash = "sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369"},
{file = "bcrypt-4.1.2-cp37-abi3-win_amd64.whl", hash = "sha256:9800ae5bd5077b13725e2e3934aa3c9c37e49d3ea3d06318010aa40f54c63551"},
{file = "bcrypt-4.1.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:71b8be82bc46cedd61a9f4ccb6c1a493211d031415a34adde3669ee1b0afbb63"},
{file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e3c6642077b0c8092580c819c1684161262b2e30c4f45deb000c38947bf483"},
{file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:387e7e1af9a4dd636b9505a465032f2f5cb8e61ba1120e79a0e1cd0b512f3dfc"},
{file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7"},
{file = "bcrypt-4.1.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2a298db2a8ab20056120b45e86c00a0a5eb50ec4075b6142db35f593b97cb3fb"},
{file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ba55e40de38a24e2d78d34c2d36d6e864f93e0d79d0b6ce915e4335aa81d01b1"},
{file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3566a88234e8de2ccae31968127b0ecccbb4cddb629da744165db72b58d88ca4"},
{file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b90e216dc36864ae7132cb151ffe95155a37a14e0de3a8f64b49655dd959ff9c"},
{file = "bcrypt-4.1.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:69057b9fc5093ea1ab00dd24ede891f3e5e65bee040395fb1e66ee196f9c9b4a"},
{file = "bcrypt-4.1.2-cp39-abi3-win32.whl", hash = "sha256:02d9ef8915f72dd6daaef40e0baeef8a017ce624369f09754baf32bb32dba25f"},
{file = "bcrypt-4.1.2-cp39-abi3-win_amd64.whl", hash = "sha256:be3ab1071662f6065899fe08428e45c16aa36e28bc42921c4901a191fda6ee42"},
{file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d75fc8cd0ba23f97bae88a6ec04e9e5351ff3c6ad06f38fe32ba50cbd0d11946"},
{file = "bcrypt-4.1.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:a97e07e83e3262599434816f631cc4c7ca2aa8e9c072c1b1a7fec2ae809a1d2d"},
{file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e51c42750b7585cee7892c2614be0d14107fad9581d1738d954a262556dd1aab"},
{file = "bcrypt-4.1.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba4e4cc26610581a6329b3937e02d319f5ad4b85b074846bf4fef8a8cf51e7bb"},
{file = "bcrypt-4.1.2.tar.gz", hash = "sha256:33313a1200a3ae90b75587ceac502b048b840fc69e7f7a0905b5f87fac7a1258"},
]
[package.extras]
@ -375,71 +395,63 @@ files = [
[[package]]
name = "coverage"
version = "7.2.7"
version = "7.4.0"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"},
{file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"},
{file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"},
{file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"},
{file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"},
{file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"},
{file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"},
{file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"},
{file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"},
{file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"},
{file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"},
{file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"},
{file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"},
{file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"},
{file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"},
{file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"},
{file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"},
{file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"},
{file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"},
{file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"},
{file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"},
{file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"},
{file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"},
{file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"},
{file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"},
{file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"},
{file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"},
{file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"},
{file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"},
{file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"},
{file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"},
{file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"},
{file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"},
{file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"},
{file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"},
{file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"},
{file = "coverage-7.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36b0ea8ab20d6a7564e89cb6135920bc9188fb5f1f7152e94e8300b7b189441a"},
{file = "coverage-7.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0676cd0ba581e514b7f726495ea75aba3eb20899d824636c6f59b0ed2f88c471"},
{file = "coverage-7.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ca5c71a5a1765a0f8f88022c52b6b8be740e512980362f7fdbb03725a0d6b9"},
{file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7c97726520f784239f6c62506bc70e48d01ae71e9da128259d61ca5e9788516"},
{file = "coverage-7.4.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:815ac2d0f3398a14286dc2cea223a6f338109f9ecf39a71160cd1628786bc6f5"},
{file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:80b5ee39b7f0131ebec7968baa9b2309eddb35b8403d1869e08f024efd883566"},
{file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5b2ccb7548a0b65974860a78c9ffe1173cfb5877460e5a229238d985565574ae"},
{file = "coverage-7.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:995ea5c48c4ebfd898eacb098164b3cc826ba273b3049e4a889658548e321b43"},
{file = "coverage-7.4.0-cp310-cp310-win32.whl", hash = "sha256:79287fd95585ed36e83182794a57a46aeae0b64ca53929d1176db56aacc83451"},
{file = "coverage-7.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5b14b4f8760006bfdb6e08667af7bc2d8d9bfdb648351915315ea17645347137"},
{file = "coverage-7.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:04387a4a6ecb330c1878907ce0dc04078ea72a869263e53c72a1ba5bbdf380ca"},
{file = "coverage-7.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ea81d8f9691bb53f4fb4db603203029643caffc82bf998ab5b59ca05560f4c06"},
{file = "coverage-7.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74775198b702868ec2d058cb92720a3c5a9177296f75bd97317c787daf711505"},
{file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76f03940f9973bfaee8cfba70ac991825611b9aac047e5c80d499a44079ec0bc"},
{file = "coverage-7.4.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:485e9f897cf4856a65a57c7f6ea3dc0d4e6c076c87311d4bc003f82cfe199d25"},
{file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6ae8c9d301207e6856865867d762a4b6fd379c714fcc0607a84b92ee63feff70"},
{file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bf477c355274a72435ceb140dc42de0dc1e1e0bf6e97195be30487d8eaaf1a09"},
{file = "coverage-7.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:83c2dda2666fe32332f8e87481eed056c8b4d163fe18ecc690b02802d36a4d26"},
{file = "coverage-7.4.0-cp311-cp311-win32.whl", hash = "sha256:697d1317e5290a313ef0d369650cfee1a114abb6021fa239ca12b4849ebbd614"},
{file = "coverage-7.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:26776ff6c711d9d835557ee453082025d871e30b3fd6c27fcef14733f67f0590"},
{file = "coverage-7.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:13eaf476ec3e883fe3e5fe3707caeb88268a06284484a3daf8250259ef1ba143"},
{file = "coverage-7.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846f52f46e212affb5bcf131c952fb4075b55aae6b61adc9856222df89cbe3e2"},
{file = "coverage-7.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26f66da8695719ccf90e794ed567a1549bb2644a706b41e9f6eae6816b398c4a"},
{file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:164fdcc3246c69a6526a59b744b62e303039a81e42cfbbdc171c91a8cc2f9446"},
{file = "coverage-7.4.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:316543f71025a6565677d84bc4df2114e9b6a615aa39fb165d697dba06a54af9"},
{file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bb1de682da0b824411e00a0d4da5a784ec6496b6850fdf8c865c1d68c0e318dd"},
{file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:0e8d06778e8fbffccfe96331a3946237f87b1e1d359d7fbe8b06b96c95a5407a"},
{file = "coverage-7.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a56de34db7b7ff77056a37aedded01b2b98b508227d2d0979d373a9b5d353daa"},
{file = "coverage-7.4.0-cp312-cp312-win32.whl", hash = "sha256:51456e6fa099a8d9d91497202d9563a320513fcf59f33991b0661a4a6f2ad450"},
{file = "coverage-7.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:cd3c1e4cb2ff0083758f09be0f77402e1bdf704adb7f89108007300a6da587d0"},
{file = "coverage-7.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e9d1bf53c4c8de58d22e0e956a79a5b37f754ed1ffdbf1a260d9dcfa2d8a325e"},
{file = "coverage-7.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:109f5985182b6b81fe33323ab4707011875198c41964f014579cf82cebf2bb85"},
{file = "coverage-7.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc9d4bc55de8003663ec94c2f215d12d42ceea128da8f0f4036235a119c88ac"},
{file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc6d65b21c219ec2072c1293c505cf36e4e913a3f936d80028993dd73c7906b1"},
{file = "coverage-7.4.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a10a4920def78bbfff4eff8a05c51be03e42f1c3735be42d851f199144897ba"},
{file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b8e99f06160602bc64da35158bb76c73522a4010f0649be44a4e167ff8555952"},
{file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7d360587e64d006402b7116623cebf9d48893329ef035278969fa3bbf75b697e"},
{file = "coverage-7.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29f3abe810930311c0b5d1a7140f6395369c3db1be68345638c33eec07535105"},
{file = "coverage-7.4.0-cp38-cp38-win32.whl", hash = "sha256:5040148f4ec43644702e7b16ca864c5314ccb8ee0751ef617d49aa0e2d6bf4f2"},
{file = "coverage-7.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:9864463c1c2f9cb3b5db2cf1ff475eed2f0b4285c2aaf4d357b69959941aa555"},
{file = "coverage-7.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:936d38794044b26c99d3dd004d8af0035ac535b92090f7f2bb5aa9c8e2f5cd42"},
{file = "coverage-7.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:799c8f873794a08cdf216aa5d0531c6a3747793b70c53f70e98259720a6fe2d7"},
{file = "coverage-7.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7defbb9737274023e2d7af02cac77043c86ce88a907c58f42b580a97d5bcca9"},
{file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1526d265743fb49363974b7aa8d5899ff64ee07df47dd8d3e37dcc0818f09ed"},
{file = "coverage-7.4.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf635a52fc1ea401baf88843ae8708591aa4adff875e5c23220de43b1ccf575c"},
{file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:756ded44f47f330666843b5781be126ab57bb57c22adbb07d83f6b519783b870"},
{file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0eb3c2f32dabe3a4aaf6441dde94f35687224dfd7eb2a7f47f3fd9428e421058"},
{file = "coverage-7.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bfd5db349d15c08311702611f3dccbef4b4e2ec148fcc636cf8739519b4a5c0f"},
{file = "coverage-7.4.0-cp39-cp39-win32.whl", hash = "sha256:53d7d9158ee03956e0eadac38dfa1ec8068431ef8058fe6447043db1fb40d932"},
{file = "coverage-7.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:cfd2a8b6b0d8e66e944d47cdec2f47c48fef2ba2f2dff5a9a75757f64172857e"},
{file = "coverage-7.4.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:c530833afc4707fe48524a44844493f36d8727f04dcce91fb978c414a8556cc6"},
{file = "coverage-7.4.0.tar.gz", hash = "sha256:707c0f58cb1712b8809ece32b68996ee1e609f71bd14615bd8f87a1293cb610e"},
]
[package.extras]
@ -738,24 +750,24 @@ lxml = ["lxml"]
[[package]]
name = "httpcore"
version = "0.16.3"
version = "1.0.2"
description = "A minimal low-level HTTP client."
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"},
{file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"},
{file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"},
{file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"},
]
[package.dependencies]
anyio = ">=3.0,<5.0"
certifi = "*"
h11 = ">=0.13,<0.15"
sniffio = "==1.*"
[package.extras]
asyncio = ["anyio (>=4.0,<5.0)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (==1.*)"]
trio = ["trio (>=0.22.0,<0.23.0)"]
[[package]]
name = "httptools"
@ -812,18 +824,19 @@ test = ["Cython (>=0.29.24,<0.30.0)"]
[[package]]
name = "httpx"
version = "0.24.1"
version = "0.26.0"
description = "The next generation HTTP client."
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"},
{file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"},
{file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"},
{file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"},
]
[package.dependencies]
anyio = "*"
certifi = "*"
httpcore = ">=0.15.0,<0.18.0"
httpcore = "==1.*"
idna = "*"
sniffio = "*"
@ -974,110 +987,111 @@ files = [
[[package]]
name = "lxml"
version = "4.9.3"
version = "4.9.4"
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
files = [
{file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"},
{file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"},
{file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"},
{file = "lxml-4.9.3-cp27-cp27m-win32.whl", hash = "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7"},
{file = "lxml-4.9.3-cp27-cp27m-win_amd64.whl", hash = "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1"},
{file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"},
{file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"},
{file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"},
{file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"},
{file = "lxml-4.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c"},
{file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"},
{file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"},
{file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"},
{file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"},
{file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"},
{file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"},
{file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"},
{file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"},
{file = "lxml-4.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a"},
{file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"},
{file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"},
{file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"},
{file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"},
{file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"},
{file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"},
{file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"},
{file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"},
{file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"},
{file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"},
{file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"},
{file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"},
{file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"},
{file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"},
{file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"},
{file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"},
{file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"},
{file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"},
{file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"},
{file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"},
{file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"},
{file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"},
{file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"},
{file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"},
{file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"},
{file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"},
{file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"},
{file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"},
{file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"},
{file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"},
{file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"},
{file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"},
{file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"},
{file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"},
{file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"},
{file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"},
{file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3"},
{file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"},
{file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"},
{file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e214025e23db238805a600f1f37bf9f9a15413c7bf5f9d6ae194f84980c78722"},
{file = "lxml-4.9.4-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec53a09aee61d45e7dbe7e91252ff0491b6b5fee3d85b2d45b173d8ab453efc1"},
{file = "lxml-4.9.4-cp27-cp27m-win32.whl", hash = "sha256:7d1d6c9e74c70ddf524e3c09d9dc0522aba9370708c2cb58680ea40174800013"},
{file = "lxml-4.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:cb53669442895763e61df5c995f0e8361b61662f26c1b04ee82899c2789c8f69"},
{file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:647bfe88b1997d7ae8d45dabc7c868d8cb0c8412a6e730a7651050b8c7289cf2"},
{file = "lxml-4.9.4-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4d973729ce04784906a19108054e1fd476bc85279a403ea1a72fdb051c76fa48"},
{file = "lxml-4.9.4-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:056a17eaaf3da87a05523472ae84246f87ac2f29a53306466c22e60282e54ff8"},
{file = "lxml-4.9.4-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aaa5c173a26960fe67daa69aa93d6d6a1cd714a6eb13802d4e4bd1d24a530644"},
{file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:647459b23594f370c1c01768edaa0ba0959afc39caeeb793b43158bb9bb6a663"},
{file = "lxml-4.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:bdd9abccd0927673cffe601d2c6cdad1c9321bf3437a2f507d6b037ef91ea307"},
{file = "lxml-4.9.4-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:00e91573183ad273e242db5585b52670eddf92bacad095ce25c1e682da14ed91"},
{file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a602ed9bd2c7d85bd58592c28e101bd9ff9c718fbde06545a70945ffd5d11868"},
{file = "lxml-4.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de362ac8bc962408ad8fae28f3967ce1a262b5d63ab8cefb42662566737f1dc7"},
{file = "lxml-4.9.4-cp310-cp310-win32.whl", hash = "sha256:33714fcf5af4ff7e70a49731a7cc8fd9ce910b9ac194f66eaa18c3cc0a4c02be"},
{file = "lxml-4.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:d3caa09e613ece43ac292fbed513a4bce170681a447d25ffcbc1b647d45a39c5"},
{file = "lxml-4.9.4-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:359a8b09d712df27849e0bcb62c6a3404e780b274b0b7e4c39a88826d1926c28"},
{file = "lxml-4.9.4-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:43498ea734ccdfb92e1886dfedaebeb81178a241d39a79d5351ba2b671bff2b2"},
{file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4855161013dfb2b762e02b3f4d4a21cc7c6aec13c69e3bffbf5022b3e708dd97"},
{file = "lxml-4.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c71b5b860c5215fdbaa56f715bc218e45a98477f816b46cfde4a84d25b13274e"},
{file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9a2b5915c333e4364367140443b59f09feae42184459b913f0f41b9fed55794a"},
{file = "lxml-4.9.4-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d82411dbf4d3127b6cde7da0f9373e37ad3a43e89ef374965465928f01c2b979"},
{file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:273473d34462ae6e97c0f4e517bd1bf9588aa67a1d47d93f760a1282640e24ac"},
{file = "lxml-4.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:389d2b2e543b27962990ab529ac6720c3dded588cc6d0f6557eec153305a3622"},
{file = "lxml-4.9.4-cp311-cp311-win32.whl", hash = "sha256:8aecb5a7f6f7f8fe9cac0bcadd39efaca8bbf8d1bf242e9f175cbe4c925116c3"},
{file = "lxml-4.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:c7721a3ef41591341388bb2265395ce522aba52f969d33dacd822da8f018aff8"},
{file = "lxml-4.9.4-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:dbcb2dc07308453db428a95a4d03259bd8caea97d7f0776842299f2d00c72fc8"},
{file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:01bf1df1db327e748dcb152d17389cf6d0a8c5d533ef9bab781e9d5037619229"},
{file = "lxml-4.9.4-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e8f9f93a23634cfafbad6e46ad7d09e0f4a25a2400e4a64b1b7b7c0fbaa06d9d"},
{file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3f3f00a9061605725df1816f5713d10cd94636347ed651abdbc75828df302b20"},
{file = "lxml-4.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:953dd5481bd6252bd480d6ec431f61d7d87fdcbbb71b0d2bdcfc6ae00bb6fb10"},
{file = "lxml-4.9.4-cp312-cp312-win32.whl", hash = "sha256:266f655d1baff9c47b52f529b5f6bec33f66042f65f7c56adde3fcf2ed62ae8b"},
{file = "lxml-4.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:f1faee2a831fe249e1bae9cbc68d3cd8a30f7e37851deee4d7962b17c410dd56"},
{file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:23d891e5bdc12e2e506e7d225d6aa929e0a0368c9916c1fddefab88166e98b20"},
{file = "lxml-4.9.4-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e96a1788f24d03e8d61679f9881a883ecdf9c445a38f9ae3f3f193ab6c591c66"},
{file = "lxml-4.9.4-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:5557461f83bb7cc718bc9ee1f7156d50e31747e5b38d79cf40f79ab1447afd2d"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:fdb325b7fba1e2c40b9b1db407f85642e32404131c08480dd652110fc908561b"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d74d4a3c4b8f7a1f676cedf8e84bcc57705a6d7925e6daef7a1e54ae543a197"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ac7674d1638df129d9cb4503d20ffc3922bd463c865ef3cb412f2c926108e9a4"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:ddd92e18b783aeb86ad2132d84a4b795fc5ec612e3545c1b687e7747e66e2b53"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bd9ac6e44f2db368ef8986f3989a4cad3de4cd55dbdda536e253000c801bcc7"},
{file = "lxml-4.9.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bc354b1393dce46026ab13075f77b30e40b61b1a53e852e99d3cc5dd1af4bc85"},
{file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f836f39678cb47c9541f04d8ed4545719dc31ad850bf1832d6b4171e30d65d23"},
{file = "lxml-4.9.4-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9c131447768ed7bc05a02553d939e7f0e807e533441901dd504e217b76307745"},
{file = "lxml-4.9.4-cp36-cp36m-win32.whl", hash = "sha256:bafa65e3acae612a7799ada439bd202403414ebe23f52e5b17f6ffc2eb98c2be"},
{file = "lxml-4.9.4-cp36-cp36m-win_amd64.whl", hash = "sha256:6197c3f3c0b960ad033b9b7d611db11285bb461fc6b802c1dd50d04ad715c225"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:7b378847a09d6bd46047f5f3599cdc64fcb4cc5a5a2dd0a2af610361fbe77b16"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:1343df4e2e6e51182aad12162b23b0a4b3fd77f17527a78c53f0f23573663545"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6dbdacf5752fbd78ccdb434698230c4f0f95df7dd956d5f205b5ed6911a1367c"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:506becdf2ecaebaf7f7995f776394fcc8bd8a78022772de66677c84fb02dd33d"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca8e44b5ba3edb682ea4e6185b49661fc22b230cf811b9c13963c9f982d1d964"},
{file = "lxml-4.9.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9d9d5726474cbbef279fd709008f91a49c4f758bec9c062dfbba88eab00e3ff9"},
{file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:bbdd69e20fe2943b51e2841fc1e6a3c1de460d630f65bde12452d8c97209464d"},
{file = "lxml-4.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8671622256a0859f5089cbe0ce4693c2af407bc053dcc99aadff7f5310b4aa02"},
{file = "lxml-4.9.4-cp37-cp37m-win32.whl", hash = "sha256:dd4fda67f5faaef4f9ee5383435048ee3e11ad996901225ad7615bc92245bc8e"},
{file = "lxml-4.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6bee9c2e501d835f91460b2c904bc359f8433e96799f5c2ff20feebd9bb1e590"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:1f10f250430a4caf84115b1e0f23f3615566ca2369d1962f82bef40dd99cd81a"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3b505f2bbff50d261176e67be24e8909e54b5d9d08b12d4946344066d66b3e43"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1449f9451cd53e0fd0a7ec2ff5ede4686add13ac7a7bfa6988ff6d75cff3ebe2"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4ece9cca4cd1c8ba889bfa67eae7f21d0d1a2e715b4d5045395113361e8c533d"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59bb5979f9941c61e907ee571732219fa4774d5a18f3fa5ff2df963f5dfaa6bc"},
{file = "lxml-4.9.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b1980dbcaad634fe78e710c8587383e6e3f61dbe146bcbfd13a9c8ab2d7b1192"},
{file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9ae6c3363261021144121427b1552b29e7b59de9d6a75bf51e03bc072efb3c37"},
{file = "lxml-4.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bcee502c649fa6351b44bb014b98c09cb00982a475a1912a9881ca28ab4f9cd9"},
{file = "lxml-4.9.4-cp38-cp38-win32.whl", hash = "sha256:a8edae5253efa75c2fc79a90068fe540b197d1c7ab5803b800fccfe240eed33c"},
{file = "lxml-4.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:701847a7aaefef121c5c0d855b2affa5f9bd45196ef00266724a80e439220e46"},
{file = "lxml-4.9.4-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:f610d980e3fccf4394ab3806de6065682982f3d27c12d4ce3ee46a8183d64a6a"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:aa9b5abd07f71b081a33115d9758ef6077924082055005808f68feccb27616bd"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:365005e8b0718ea6d64b374423e870648ab47c3a905356ab6e5a5ff03962b9a9"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:16b9ec51cc2feab009e800f2c6327338d6ee4e752c76e95a35c4465e80390ccd"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:a905affe76f1802edcac554e3ccf68188bea16546071d7583fb1b693f9cf756b"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd814847901df6e8de13ce69b84c31fc9b3fb591224d6762d0b256d510cbf382"},
{file = "lxml-4.9.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:91bbf398ac8bb7d65a5a52127407c05f75a18d7015a270fdd94bbcb04e65d573"},
{file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f99768232f036b4776ce419d3244a04fe83784bce871b16d2c2e984c7fcea847"},
{file = "lxml-4.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bb5bd6212eb0edfd1e8f254585290ea1dadc3687dd8fd5e2fd9a87c31915cdab"},
{file = "lxml-4.9.4-cp39-cp39-win32.whl", hash = "sha256:88f7c383071981c74ec1998ba9b437659e4fd02a3c4a4d3efc16774eb108d0ec"},
{file = "lxml-4.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:936e8880cc00f839aa4173f94466a8406a96ddce814651075f95837316369899"},
{file = "lxml-4.9.4-pp310-pypy310_pp73-macosx_11_0_x86_64.whl", hash = "sha256:f6c35b2f87c004270fa2e703b872fcc984d714d430b305145c39d53074e1ffe0"},
{file = "lxml-4.9.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:606d445feeb0856c2b424405236a01c71af7c97e5fe42fbc778634faef2b47e4"},
{file = "lxml-4.9.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a1bdcbebd4e13446a14de4dd1825f1e778e099f17f79718b4aeaf2403624b0f7"},
{file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0a08c89b23117049ba171bf51d2f9c5f3abf507d65d016d6e0fa2f37e18c0fc5"},
{file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:232fd30903d3123be4c435fb5159938c6225ee8607b635a4d3fca847003134ba"},
{file = "lxml-4.9.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:231142459d32779b209aa4b4d460b175cadd604fed856f25c1571a9d78114771"},
{file = "lxml-4.9.4-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:520486f27f1d4ce9654154b4494cf9307b495527f3a2908ad4cb48e4f7ed7ef7"},
{file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:562778586949be7e0d7435fcb24aca4810913771f845d99145a6cee64d5b67ca"},
{file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a9e7c6d89c77bb2770c9491d988f26a4b161d05c8ca58f63fb1f1b6b9a74be45"},
{file = "lxml-4.9.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:786d6b57026e7e04d184313c1359ac3d68002c33e4b1042ca58c362f1d09ff58"},
{file = "lxml-4.9.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:95ae6c5a196e2f239150aa4a479967351df7f44800c93e5a975ec726fef005e2"},
{file = "lxml-4.9.4-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:9b556596c49fa1232b0fff4b0e69b9d4083a502e60e404b44341e2f8fb7187f5"},
{file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:cc02c06e9e320869d7d1bd323df6dd4281e78ac2e7f8526835d3d48c69060683"},
{file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:857d6565f9aa3464764c2cb6a2e3c2e75e1970e877c188f4aeae45954a314e0c"},
{file = "lxml-4.9.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c42ae7e010d7d6bc51875d768110c10e8a59494855c3d4c348b068f5fb81fdcd"},
{file = "lxml-4.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f10250bb190fb0742e3e1958dd5c100524c2cc5096c67c8da51233f7448dc137"},
{file = "lxml-4.9.4.tar.gz", hash = "sha256:b1541e50b78e15fa06a2670157a1962ef06591d4c998b998047fff5e3236880e"},
]
[package.extras]
cssselect = ["cssselect (>=0.7)"]
html5 = ["html5lib"]
htmlsoup = ["BeautifulSoup4"]
source = ["Cython (>=0.29.35)"]
source = ["Cython (==0.29.37)"]
[[package]]
name = "mako"
@ -1245,13 +1259,13 @@ requests = ">=2.18.4"
[[package]]
name = "mkdocs"
version = "1.5.2"
version = "1.5.3"
description = "Project documentation with Markdown."
optional = false
python-versions = ">=3.7"
files = [
{file = "mkdocs-1.5.2-py3-none-any.whl", hash = "sha256:60a62538519c2e96fe8426654a67ee177350451616118a41596ae7c876bb7eac"},
{file = "mkdocs-1.5.2.tar.gz", hash = "sha256:70d0da09c26cff288852471be03c23f0f521fc15cf16ac89c7a3bfb9ae8d24f9"},
{file = "mkdocs-1.5.3-py3-none-any.whl", hash = "sha256:3b3a78e736b31158d64dbb2f8ba29bd46a379d0c6e324c2246c3bc3d2189cfc1"},
{file = "mkdocs-1.5.3.tar.gz", hash = "sha256:eb7c99214dcb945313ba30426c2451b735992c73c2e10838f76d09e39ff4d0e2"},
]
[package.dependencies]
@ -1275,35 +1289,42 @@ min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-imp
[[package]]
name = "mkdocs-material"
version = "9.1.21"
version = "9.5.3"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "mkdocs_material-9.1.21-py3-none-any.whl", hash = "sha256:58bb2f11ef240632e176d6f0f7d1cff06be1d11c696a5a1b553b808b4280ed47"},
{file = "mkdocs_material-9.1.21.tar.gz", hash = "sha256:71940cdfca84ab296b6362889c25395b1621273fb16c93deda257adb7ff44ec8"},
{file = "mkdocs_material-9.5.3-py3-none-any.whl", hash = "sha256:76c93a8525cceb0b395b9cedab3428bf518cf6439adef2b940f1c1574b775d89"},
{file = "mkdocs_material-9.5.3.tar.gz", hash = "sha256:5899219f422f0a6de784232d9d40374416302ffae3c160cacc72969fcc1ee372"},
]
[package.dependencies]
colorama = ">=0.4"
jinja2 = ">=3.0"
markdown = ">=3.2"
mkdocs = ">=1.5.0"
mkdocs-material-extensions = ">=1.1"
pygments = ">=2.14"
pymdown-extensions = ">=9.9.1"
regex = ">=2022.4.24"
requests = ">=2.26"
babel = ">=2.10,<3.0"
colorama = ">=0.4,<1.0"
jinja2 = ">=3.0,<4.0"
markdown = ">=3.2,<4.0"
mkdocs = ">=1.5.3,<1.6.0"
mkdocs-material-extensions = ">=1.3,<2.0"
paginate = ">=0.5,<1.0"
pygments = ">=2.16,<3.0"
pymdown-extensions = ">=10.2,<11.0"
regex = ">=2022.4"
requests = ">=2.26,<3.0"
[package.extras]
git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2,<2.0)"]
imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=9.4,<10.0)"]
recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"]
[[package]]
name = "mkdocs-material-extensions"
version = "1.1.1"
version = "1.3.1"
description = "Extension pack for Python Markdown and MkDocs Material."
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "mkdocs_material_extensions-1.1.1-py3-none-any.whl", hash = "sha256:e41d9f38e4798b6617ad98ca8f7f1157b1e4385ac1459ca1e4ea219b556df945"},
{file = "mkdocs_material_extensions-1.1.1.tar.gz", hash = "sha256:9c003da71e2cc2493d910237448c672e00cefc800d3d6ae93d2fc69979e3bd93"},
{file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"},
{file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"},
]
[[package]]
@ -1462,6 +1483,16 @@ files = [
{file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"},
]
[[package]]
name = "paginate"
version = "0.5.6"
description = "Divides large result sets into pages for easier browsing"
optional = false
python-versions = "*"
files = [
{file = "paginate-0.5.6.tar.gz", hash = "sha256:5e6007b6a9398177a7e1648d04fdd9f8c9766a1a945bceac82f1929e8c78af2d"},
]
[[package]]
name = "passlib"
version = "1.7.4"
@ -1703,47 +1734,47 @@ pyasn1 = ">=0.4.6,<0.5.0"
[[package]]
name = "pydantic"
version = "1.10.12"
version = "1.10.13"
description = "Data validation and settings management using python type hints"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic-1.10.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718"},
{file = "pydantic-1.10.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe"},
{file = "pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b"},
{file = "pydantic-1.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d"},
{file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09"},
{file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed"},
{file = "pydantic-1.10.12-cp310-cp310-win_amd64.whl", hash = "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a"},
{file = "pydantic-1.10.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc"},
{file = "pydantic-1.10.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405"},
{file = "pydantic-1.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62"},
{file = "pydantic-1.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494"},
{file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246"},
{file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33"},
{file = "pydantic-1.10.12-cp311-cp311-win_amd64.whl", hash = "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f"},
{file = "pydantic-1.10.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a"},
{file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565"},
{file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350"},
{file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303"},
{file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5"},
{file = "pydantic-1.10.12-cp37-cp37m-win_amd64.whl", hash = "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8"},
{file = "pydantic-1.10.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62"},
{file = "pydantic-1.10.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb"},
{file = "pydantic-1.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0"},
{file = "pydantic-1.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c"},
{file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d"},
{file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33"},
{file = "pydantic-1.10.12-cp38-cp38-win_amd64.whl", hash = "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47"},
{file = "pydantic-1.10.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6"},
{file = "pydantic-1.10.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523"},
{file = "pydantic-1.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86"},
{file = "pydantic-1.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1"},
{file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe"},
{file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb"},
{file = "pydantic-1.10.12-cp39-cp39-win_amd64.whl", hash = "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d"},
{file = "pydantic-1.10.12-py3-none-any.whl", hash = "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942"},
{file = "pydantic-1.10.12.tar.gz", hash = "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303"},
{file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"},
{file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"},
{file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"},
{file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"},
{file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"},
{file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"},
{file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"},
{file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"},
{file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"},
{file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"},
{file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"},
{file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"},
{file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"},
{file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"},
{file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"},
{file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"},
{file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"},
{file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"},
{file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"},
{file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"},
{file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"},
{file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"},
{file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"},
{file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"},
{file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"},
{file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"},
{file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"},
{file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"},
{file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"},
{file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"},
{file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"},
{file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"},
{file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"},
{file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"},
{file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"},
{file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"},
]
[package.dependencies]
@ -1772,17 +1803,18 @@ dev = ["coverage", "pytest", "pytest-cov"]
[[package]]
name = "pygments"
version = "2.14.0"
version = "2.17.2"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
python-versions = ">=3.6"
python-versions = ">=3.7"
files = [
{file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"},
{file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"},
{file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"},
{file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"},
]
[package.extras]
plugins = ["importlib-metadata"]
windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pyhumps"
@ -1797,17 +1829,17 @@ files = [
[[package]]
name = "pylint"
version = "2.17.5"
version = "2.17.7"
description = "python code static checker"
optional = false
python-versions = ">=3.7.2"
files = [
{file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"},
{file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"},
{file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"},
{file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"},
]
[package.dependencies]
astroid = ">=2.15.6,<=2.17.0-dev0"
astroid = ">=2.15.8,<=2.17.0-dev0"
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
dill = [
{version = ">=0.2", markers = "python_version < \"3.11\""},
@ -1825,17 +1857,21 @@ testutils = ["gitpython (>3)"]
[[package]]
name = "pymdown-extensions"
version = "9.9.2"
version = "10.4"
description = "Extension pack for Python Markdown."
optional = false
python-versions = ">=3.7"
python-versions = ">=3.8"
files = [
{file = "pymdown_extensions-9.9.2-py3-none-any.whl", hash = "sha256:c3d804eb4a42b85bafb5f36436342a5ad38df03878bb24db8855a4aa8b08b765"},
{file = "pymdown_extensions-9.9.2.tar.gz", hash = "sha256:ebb33069bafcb64d5f5988043331d4ea4929325dc678a6bcf247ddfcf96499f8"},
{file = "pymdown_extensions-10.4-py3-none-any.whl", hash = "sha256:cfc28d6a09d19448bcbf8eee3ce098c7d17ff99f7bd3069db4819af181212037"},
{file = "pymdown_extensions-10.4.tar.gz", hash = "sha256:bc46f11749ecd4d6b71cf62396104b4a200bad3498cb0f5dad1b8502fe461a35"},
]
[package.dependencies]
markdown = ">=3.2"
pyyaml = "*"
[package.extras]
extra = ["pygments (>=2.12)"]
[[package]]
name = "pyparsing"
@ -1958,12 +1994,12 @@ pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"]
[[package]]
name = "python-ldap"
version = "3.4.3"
version = "3.4.4"
description = "Python modules for implementing LDAP clients"
optional = false
python-versions = ">=3.6"
files = [
{file = "python-ldap-3.4.3.tar.gz", hash = "sha256:ab26c519a0ef2a443a2a10391fa3c5cb52d7871323399db949ebfaa9f25ee2a0"},
{file = "python-ldap-3.4.4.tar.gz", hash = "sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828"},
]
[package.dependencies]
@ -3034,4 +3070,4 @@ pgsql = ["psycopg2-binary"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "d7537958ae2ddbf8e2b350cb7b1189492a62b02becfe087efbc37a3b0115ff13"
content-hash = "cd8bc56d15a37be0ba4412181e1e7c9ec021c4c03ad7c6df10cda4cbc2fcde14"

View File

@ -22,7 +22,7 @@ bcrypt = "^4.0.1"
extruct = "^0.14.0"
fastapi = "^0.104.1"
gunicorn = "^20.1.0"
httpx = "^0.24.1"
httpx = "^0.26.0"
lxml = "^4.7.1"
orjson = "^3.8.0"
passlib = "^1.7.4"

View File

@ -1,5 +1,8 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"enabledManagers": [
"poetry"
],
"extends": [
"config:base"
]

View File

@ -4,6 +4,18 @@ CWD = Path(__file__).parent
locale_dir = CWD / "locale"
backup_version_44e8d670719d_1 = CWD / "backups/backup_version_44e8d670719d_1.zip"
"""44e8d670719d: add extras to shopping lists, list items, and ingredient foods"""
backup_version_44e8d670719d_2 = CWD / "backups/backup_version_44e8d670719d_2.zip"
"""44e8d670719d: add extras to shopping lists, list items, and ingredient foods"""
backup_version_ba1e4a6cfe99_1 = CWD / "backups/backup_version_ba1e4a6cfe99_1.zip"
"""ba1e4a6cfe99: added plural names and alias tables for foods and units"""
backup_version_bcfdad6b7355_1 = CWD / "backups/backup_version_bcfdad6b7355_1.zip"
"""bcfdad6b7355: remove tool name and slug unique contraints"""
migrations_paprika = CWD / "migrations/paprika.zip"
migrations_chowdown = CWD / "migrations/chowdown.zip"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,7 +5,7 @@
<meta data-n-head="1" data-hid="og:title" property="og:title" content="Mealie">
<meta data-n-head="1" data-hid="og:site_name" property="og:site_name" content="Mealie">
<meta data-n-head="1" data-hid="og:description" property="og:description" content="Mealie is a recipe management app for your kitchen.">
<meta data-n-head="1" data-hid="og:image" property="og:image" content="https://raw.githubusercontent.com/hay-kot/mealie/dev/frontend/public/img/icons/android-chrome-512x512.png">
<meta data-n-head="1" data-hid="og:image" property="og:image" content="https://raw.githubusercontent.com/mealie-recipes/mealie/9571816ac4eed5beacfc0abf6c03eff1427fd0eb/frontend/static/icons/android-chrome-512x512.png">
<meta data-n-head="1" charset="utf-8">
<meta data-n-head="1" name="viewport" content="width=device-width,initial-scale=1">
<meta data-n-head="1" data-hid="description" name="description" content="Mealie is a recipe management app for your kitchen.">

View File

@ -1,8 +1,18 @@
import filecmp
from pathlib import Path
from typing import Any
from typing import Any, cast
import pytest
from sqlalchemy.orm import Session
import tests.data as test_data
from mealie.core.config import get_app_settings
from mealie.db.db_setup import session_context
from mealie.db.models.group import Group
from mealie.db.models.group.shopping_list import ShoppingList
from mealie.db.models.labels import MultiPurposeLabel
from mealie.db.models.recipe.ingredient import IngredientFoodModel, IngredientUnitModel
from mealie.db.models.recipe.recipe import RecipeModel
from mealie.services.backups_v2.alchemy_exporter import AlchemyExporter
from mealie.services.backups_v2.backup_file import BackupFile
from mealie.services.backups_v2.backup_v2 import BackupV2
@ -56,3 +66,90 @@ def test_database_restore():
for s1, s2 in zip(snapshop_1, snapshop_2):
assert snapshop_1[s1].sort(key=dict_sorter) == snapshop_2[s2].sort(key=dict_sorter)
@pytest.mark.parametrize(
"backup_path",
[
test_data.backup_version_44e8d670719d_1,
test_data.backup_version_44e8d670719d_2,
test_data.backup_version_ba1e4a6cfe99_1,
test_data.backup_version_bcfdad6b7355_1,
],
ids=[
"44e8d670719d_1: add extras to shopping lists, list items, and ingredient foods",
"44e8d670719d_2: add extras to shopping lists, list items, and ingredient foods",
"ba1e4a6cfe99_1: added plural names and alias tables for foods and units",
"bcfdad6b7355_1: remove tool name and slug unique contraints",
],
)
def test_database_restore_data(backup_path: Path):
"""
This tests real user backups to make sure the data is restored correctly. The data has been anonymized, but
relationships and data types should be preserved.
This test should verify all migrations that do some sort of database manipulation (e.g. populating a new column).
If a new migration is added that does any sort of data manipulation, this test should be updated.
"""
settings = get_app_settings()
backup_v2 = BackupV2(settings.DB_URL)
# create a backup of the existing data so we can restore it later
original_data_backup = backup_v2.backup()
try:
assert backup_path.exists()
backup_v2.restore(backup_path)
# make sure migrations populated data successfully
with session_context() as session:
session = cast(Session, session)
groups = session.query(Group).all()
recipes = session.query(RecipeModel).all()
shopping_lists = session.query(ShoppingList).all()
labels = session.query(MultiPurposeLabel).all()
foods = session.query(IngredientFoodModel).all()
units = session.query(IngredientUnitModel).all()
# 2023-02-14-20.45.41_5ab195a474eb_add_normalized_search_properties
for recipe in recipes:
if recipe.name:
assert recipe.name_normalized
if recipe.description:
assert recipe.description_normalized
for ingredient in recipe.recipe_ingredient:
if ingredient.note:
assert ingredient.note_normalized
if ingredient.original_text:
assert ingredient.original_text_normalized
# 2023-02-21-22.03.19_b04a08da2108_added_shopping_list_label_settings
for shopping_list in shopping_lists:
group_labels = [label for label in labels if label.group_id == shopping_list.group_id]
assert len(shopping_list.label_settings) == len(group_labels)
for label_setting, label in zip(
sorted(shopping_list.label_settings, key=lambda x: x.label.id),
sorted(group_labels, key=lambda x: x.id),
strict=True,
):
assert label_setting.label == label
# 2023-08-06-21.00.34_04ac51cbe9a4_added_group_slug
for group in groups:
assert group.slug
# 2023-09-01-14.55.42_0341b154f79a_added_normalized_unit_and_food_names
for food in foods:
if food.name:
assert food.name_normalized
for unit in units:
assert unit.name_normalized
if unit.abbreviation:
assert unit.abbreviation_normalized
finally:
backup_v2.restore(original_data_backup)