Compare commits

..

No commits in common. "00494195789f282812b368e4e9a0ab80ddebdab6" and "ad3f06d6ff8e81ffaf83545799dfb71dfd80bc09" have entirely different histories.

38 changed files with 166 additions and 395 deletions

View file

@ -1,16 +0,0 @@
DEBUG=True
ODOO_URL=https://test.central.vshn.ch
ODOO_DB=VSHNTest
ODOO_USERNAME=CHANGEME
ODOO_PASSWORD=CHANGEME
BROKER_USERNAME=broker
BROKER_PASSWORD=CHANGEME
ALLOWED_HOSTS=localhost,127.0.0.1
SECRET_KEY="django-insecure-CHANGEME"
ODOO_LEAD_CAMPAIGN_ID=6
ODOO_LEAD_SOURCE_ID=28
ODOO_LEAD_MEDIUM_ID=1
ODOO_LEAD_TAG_ID=6
ODOO_MAILING_LIST_ID=14
EMAIL_HOST_USER=CHANGEME
EMAIL_HOST_PASSWORD=CHANGEME

View file

@ -42,7 +42,7 @@ jobs:
container: catthehacker/ubuntu:act-latest container: catthehacker/ubuntu:act-latest
environment: environment:
name: prod name: prod
url: https://servala.com/ url: https://serva.la/
steps: steps:
- name: Checkout repository - name: Checkout repository

View file

@ -35,6 +35,6 @@ deploy:
- oc -n ${NAMESPACE} rollout restart deployment/servala - oc -n ${NAMESPACE} rollout restart deployment/servala
environment: environment:
name: prod name: prod
url: https://servala.com/ url: https://poc.serva.la/
only: only:
- main - main

View file

@ -1,12 +1,8 @@
# Servala Website # Servala Frontend
This is the Django source-code of the website powering https://servala.com. This is a PoC for a Servala Frontend with the aim to collect leads and measure market interest.
## Running locally * List services
* Show CSPs
``` * Collect leads with a form
cp .env.example .env * Expose some OSB API mocks to collect leads
source .env
uv run --extra dev manage.py migrate
uv run --extra dev manage.py runserver
```

View file

@ -42,18 +42,7 @@
# Proxy all other requests to Gunicorn # Proxy all other requests to Gunicorn
handle { handle {
reverse_proxy unix//app/run/gunicorn.sock { reverse_proxy unix//app/run/gunicorn.sock
header_up X-Forwarded-Proto https
header_up X-Forwarded-Host {host}
}
}
@plausible path /js/script.js /api/event
handle @plausible {
rewrite /js/script.js /js/script.file-downloads.hash.outbound-links.tagged-events.js
reverse_proxy https://plausible.io {
header_up Host {http.reverse_proxy.upstream.hostport}
}
} }
# Basic compression for better performance # Basic compression for better performance

View file

@ -97,70 +97,3 @@ class OdooAPI:
logger.error(f"Unexpected error creating lead: {str(e)}") logger.error(f"Unexpected error creating lead: {str(e)}")
logger.debug("Full error details:", exc_info=True) logger.debug("Full error details:", exc_info=True)
raise raise
def add_to_mailing_list(self, email, mailing_list_id=46):
"""Add an email to a mailing list in Odoo"""
try:
logger.info(
f"Attempting to add {email} to mailing list ID {mailing_list_id}"
)
# Ensure we have a valid connection
if not self.odoo:
logger.warning("No active Odoo connection, attempting to reconnect")
self._connect()
# Add contact to mailing list
MailingContact = self.odoo.env["mailing.contact"]
existing_mailing_contacts = MailingContact.search([("email", "=", email)])
if existing_mailing_contacts:
mailing_contact_id = existing_mailing_contacts[0]
# Check if already in this list
MailingContactList = self.odoo.env["mailing.contact.subscription"]
existing_subscriptions = MailingContactList.search(
[
("contact_id", "=", mailing_contact_id),
("list_id", "=", mailing_list_id),
]
)
if not existing_subscriptions:
# Add to this specific list
MailingContactList.create(
{
"contact_id": mailing_contact_id,
"list_id": mailing_list_id,
"opt_out": False,
}
)
else:
# Create new mailing contact and subscription
mailing_contact_id = MailingContact.create(
{
"name": email.split("@")[0],
"email": email,
}
)
MailingContactList = self.odoo.env["mailing.contact.subscription"]
MailingContactList.create(
{
"contact_id": mailing_contact_id,
"list_id": mailing_list_id,
"opt_out": False,
}
)
logger.info(f"Successfully added {email} to mailing list")
return True
except odoorpc.error.RPCError as e:
logger.error(f"RPC Error adding to mailing list: {str(e)}")
logger.debug("Full RPC error details:", exc_info=True)
return False
except Exception as e:
logger.error(f"Unexpected error adding to mailing list: {str(e)}")
logger.debug("Full error details:", exc_info=True)
return False

View file

@ -12083,6 +12083,7 @@ a.btn:focus {
} }
.card__image__wide { .card__image__wide {
width: 150px;
height: 80px; height: 80px;
margin-bottom: 16px margin-bottom: 16px
} }
@ -12108,15 +12109,6 @@ a.btn:focus {
margin-bottom: 0 margin-bottom: 0
} }
.card-logo {
max-height: 80px;
max-width: 100%;
width: auto;
object-fit: contain;
display: block;
margin: 0 auto;
}
@media (min-width: 992px) { @media (min-width: 992px) {
.section-hero__header { .section-hero__header {
width: 56% width: 56%

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before After
Before After

File diff suppressed because one or more lines are too long

View file

@ -1,7 +1,6 @@
{% load static %} {% load static %}
{% load canonical_tags %} {% load canonical_tags %}
{% load social_meta_tags %} {% load social_meta_tags %}
{% load json_ld_tags %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -13,14 +12,12 @@
<link rel="icon" type="image/x-icon" href="{% static "img/favicon.ico" %}"> <link rel="icon" type="image/x-icon" href="{% static "img/favicon.ico" %}">
<link rel="sitemap" type="application/xml" title="Sitemap" href="/sitemap.xml"> <link rel="sitemap" type="application/xml" title="Sitemap" href="/sitemap.xml">
{% social_meta_tags %} {% social_meta_tags %}
{% json_ld_structured_data %}
<link rel="stylesheet" href='{% static "css/bootstrap-icons.min.css" %}'> <link rel="stylesheet" href='{% static "css/bootstrap-icons.min.css" %}'>
<link rel="stylesheet" type="text/css" href='{% static "css/servala-main.css" %}'> <link rel="stylesheet" type="text/css" href='{% static "css/servala-main.css" %}'>
{% block extra_css %}{% endblock %} {% block extra_css %}{% endblock %}
<script defer data-api="/api/event" data-domain="servala.com" src="/js/script.js"></script> <script defer data-domain="servala.com" src="https://plausible.io/js/script.file-downloads.hash.outbound-links.tagged-events.js"></script>
<script defer src="{% static "js/htmx204.min.js" %}"></script>
<script defer src="{% static "js/alpine-collapse.min.js" %}"></script> <script defer src="{% static "js/alpine-collapse.min.js" %}"></script>
<script defer src="{% static "js/servala-main.js" %}"></script> <script defer src="{% static "js/servala-main.js" %}"></script>
{% block extra_js %}{% endblock %} {% block extra_js %}{% endblock %}
@ -103,18 +100,11 @@
<h2 class="section-h1 fs-40 fs-lg-60 d-inline-block mb-24">Ready to Get Started?</h2> <h2 class="section-h1 fs-40 fs-lg-60 d-inline-block mb-24">Ready to Get Started?</h2>
</div> </div>
<div class="text-gray-300 w-lg-37 mx-auto mb-24"> <div class="text-gray-300 w-lg-37 mx-auto mb-24">
<p class="mb-0">Subscribe to our newsletter to stay informed.</p> <p class="mb-0">Explore all available Services on Servala, with new ones added regularly.</p>
</div> </div>
<div class="mt-4"> <div>
<form hx-post="{% url 'services:subscribe' %}" hx-target="#signup-form-container" hx-swap="outerHTML"> <a class="btn btn-primary btn-lg mr-md-17 mb-17 mb-md-0 w-100 w-md-auto" href="{% url 'services:homepage' %}" role="button">Discover
{% csrf_token %} Services</a>
<div id="signup-form-container" class="d-flex justify-content-center">
<div class="input-group" style="max-width: 500px;">
<input type="email" name="email" class="form-control" id="email-input" placeholder="Your email address" required>
<button type="submit" class="btn btn-primary plausible-event-name=Newsletter+Sign-Up">Subscribe to updates</button>
</div>
</div>
</form>
</div> </div>
</header> </header>
</div> </div>

View file

@ -8,7 +8,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">About Servala</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">About Servala</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Open Cloud Native Service Hub. Unlock the Power of Cloud Native Applications.</p> <p class="mb-0">Open Cloud Native Service Hub. Unlock the Power of Cloud Native Applications.</p>
</div> </div>
@ -33,12 +33,12 @@
</div> </div>
<div class="page-action"> <div class="page-action">
<a class="btn btn-primary btn-lg mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-0 w-100 w-md-auto" href="{% static "servala-flyer.pdf" %}" role="button">Download Flyer</a> <a class="btn btn-primary btn-lg mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-0 w-100 w-md-auto" href="{% static "servala-flyer.pdf" %}" role="button">Download Flyer</a>
<a class="btn btn-outline btn-lg w-100 w-md-auto" href="https://products.vshn.ch/servala/index.html" target="_blank" role="button">Learn More</a> <a class="btn btn-outline btn-lg w-100 w-md-auto" href="{% url 'services:service_list' %}" role="button">Discover Services</a>
</div> </div>
</div> </div>
<div class="w-lg-30"> <div class="w-lg-30">
<div class="page-header__image-wrapper"> <div class="page-header__image-wrapper">
<img class="page-header__image" src="{% static "img/servala-people.png" %}" alt="About Servala"> <img class="page-header__image" src="{% static "img/about-image.png" %}" alt="About Servala">
</div> </div>
</div> </div>
</div> </div>
@ -47,43 +47,31 @@
<h2 class="fs-32 fw-semibold mt-3">Who benefits from using Servala?</h2> <h2 class="fs-32 fw-semibold mt-3">Who benefits from using Servala?</h2>
<div class="text-gray-500 fs-19 lh-1-7"> <div class="text-gray-500 fs-19 lh-1-7">
<p>Servala is designed for Software Vendors, Cloud Providers and Enterprises and their users, enabling them to offer, integrate, and consume cloud-native services and applications and DevOps tools with ease.</p> <p>Servala is designed for Software Vendors, Cloud Providers and Enterprises and their users, enabling them to offer, integrate, and consume cloud-native services and applications and DevOps tools with ease.</p>
<p>For <a href="https://products.vshn.ch/servala/isv.html" target="_blank"><strong>Software Vendors</strong></a>, Servala provides a powerful channel to distribute, monetize, and operate their software as managed services. <p>For <strong>Software Vendors</strong>, Servala provides a powerful channel to distribute, monetize, and operate their software as managed services. <strong>Cloud Providers</strong> can extend their core infrastructure offerings with value-added services. <strong>Enterprise Private Clouds</strong> gain seamless access to trusted services and applications while maintaining full control over security and compliance - all within an open and agnostic ecosystem.</p>
<a href="https://products.vshn.ch/servala/csp.html" target="_blank"><strong>Cloud Providers</strong></a> can extend their core infrastructure offerings with value-added services.
<a href="https://products.vshn.ch/servala/enterprise.html" target="_blank"><strong>Enterprise Private Clouds</strong></a> gain seamless access to trusted services and applications while maintaining full control over security and compliance - all within an open and agnostic ecosystem.
</p>
</div> </div>
<article class="pt-5"> <article class="pt-20">
<h3 class="fs-24 fw-semibold">Software Vendors</h3> <h3 class="fs-24 fw-semibold">Software Vendors</h3>
<ul class="list-disc pl-8 text-gray-500 fs-19"> <ul class="list-disc pl-8 text-gray-500 fs-19">
<li>Transform software into SaaS offerings.</li> <li>Transform software into SaaS offerings.</li>
<li>Reach new markets and ecosystems through our existing partner network.</li> <li>Reach new markets and ecosystems through our existing partner network.</li>
<li>Streamline operations and monetization.</li> <li>Streamline operations and monetization.</li>
</ul> </ul>
<div class="page-action">
<a class="btn btn-primary mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-17 w-100 w-md-auto" href="https://products.vshn.ch/servala/isv.html" target="_blank" role="button">Learn More</a>
</div>
</article> </article>
<article class="pt-5"> <article class="pt-20">
<h3 class="fs-24 fw-semibold">Cloud Providers</h3> <h3 class="fs-24 fw-semibold">Cloud Providers</h3>
<ul class="list-disc pl-8 text-gray-500 fs-19"> <ul class="list-disc pl-8 text-gray-500 fs-19">
<li>Offer value-added services and applications to customers.</li> <li>Offer value-added services and applications to customers.</li>
<li>Enhance operational efficiency and market reach.</li> <li>Enhance operational efficiency and market reach.</li>
<li>Keep pace with fast-changing industry demands.</li> <li>Keep pace with fast-changing industry demands.</li>
</ul> </ul>
<div class="page-action">
<a class="btn btn-primary mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-17 w-100 w-md-auto" href="https://products.vshn.ch/servala/csp.html" target="_blank" role="button">Learn More</a>
</div>
</article> </article>
<article class="pt-5"> <article class="pt-20">
<h3 class="fs-24 fw-semibold">Enterprise Private Clouds</h3> <h3 class="fs-24 fw-semibold">Enterprise Private Clouds</h3>
<ul class="list-disc pl-8 text-gray-500 fs-19"> <ul class="list-disc pl-8 text-gray-500 fs-19">
<li>Access scalable, secure, and cost-efficient services.</li> <li>Access scalable, secure, and cost-efficient services.</li>
<li>Enable self-service installation of trusted applications without managing infrastructure.</li> <li>Enable self-service installation of trusted applications without managing infrastructure.</li>
<li>Ensure compliance, boost developer productivity, and simplify operations.</li> <li>Ensure compliance, boost developer productivity, and simplify operations.</li>
</ul> </ul>
<div class="page-action">
<a class="btn btn-primary mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-17 w-100 w-md-auto" href="https://products.vshn.ch/servala/enterprise.html" target="_blank" role="button">Learn More</a>
</div>
</article> </article>
</div> </div>
@ -209,7 +197,7 @@
</div> </div>
<div class="w-lg-30"> <div class="w-lg-30">
<div class="page-header__image-wrapper"> <div class="page-header__image-wrapper">
<img class="page-header__image" src="{% static "img/sir-vala-text.png" %}" alt="Cartoon serval cat named Sir Vala with blue eyes and a happy expression. It's the mascot of Servala - Open Cloud Native Service Hub" title="Sir Vala - Mascot of Servala"> <img class="page-header__image" src="{% static "img/sir-vala-text.png" %}" alt="Servala Mascot Sir Vala">
</div> </div>
</div> </div>
</div> </div>

View file

@ -43,7 +43,7 @@
<div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0"> <div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0">
<div class="card h-100 d-flex flex-column"> <div class="card h-100 d-flex flex-column">
<div class="card__image"> <div class="card__image">
<a href="{{ service.get_absolute_url }}"><img class="img-fluid card-logo" src="{{ service.logo.url }}" alt="{{ service.name }} logo"></a> <a href="{{ service.get_absolute_url }}"><img class="img-fluid" src="{{ service.logo.url }}" alt="{{ service.name }} logo" style="max-height: 80px; max-width: 250px; object-fit: contain;"></a>
</div> </div>
<div class="card__header"> <div class="card__header">
<h3 class="card__title"><a href="{{ service.get_absolute_url }}" class="text-decoration-none">{{ service.name }}</a></h3> <h3 class="card__title"><a href="{{ service.get_absolute_url }}" class="text-decoration-none">{{ service.name }}</a></h3>
@ -64,7 +64,7 @@
</div> </div>
</div> </div>
<div class="page-action d-lg-none"> <div class="page-action d-lg-none">
<a class="btn btn-outline-primary btn-lg w-100" href="{% url 'services:service_list' %}" role="button">See All</a> <a class="btn btn-outline-primary btn-lg w-100" href="#" role="button">See All</a>
</div> </div>
</div> </div>
</div> </div>
@ -91,7 +91,7 @@
<div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0"> <div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0">
<div class="card h-100 d-flex flex-column"> <div class="card h-100 d-flex flex-column">
<div class="card__image__wide mb-4"> <div class="card__image__wide mb-4">
<a href="{{ provider.get_absolute_url }}"><img class="img-fluid card-logo" src="{{ provider.logo.url }}" alt="{{ provider.name }} logo"></a> <a href="{{ provider.get_absolute_url }}"><img class="img-fluid" src="{{ provider.logo.url }}" alt="{{ provider.name }} logo" style="max-height: 80px; max-width: 250px; object-fit: contain;"></a>
</div> </div>
<div class="card__header"> <div class="card__header">
<h3 class="card__title"><a href="{{ provider.get_absolute_url }}" class="text-decoration-none">{{ provider.name }}</a></h3> <h3 class="card__title"><a href="{{ provider.get_absolute_url }}" class="text-decoration-none">{{ provider.name }}</a></h3>
@ -111,7 +111,7 @@
</div> </div>
</div> </div>
<div class="page-action d-lg-none"> <div class="page-action d-lg-none">
<a class="btn btn-outline-primary btn-lg w-100" href="{% url 'services:provider_list' %}" role="button">See All</a> <a class="btn btn-outline-primary btn-lg w-100" href="#" role="button">See All</a>
</div> </div>
</div> </div>
</div> </div>
@ -136,7 +136,7 @@
<div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0"> <div class="col-12 col-md-6 col-lg-3 mb-20 mb-lg-0">
<div class="card h-100 d-flex flex-column"> <div class="card h-100 d-flex flex-column">
<div class="card__image__wide mb-4"> <div class="card__image__wide mb-4">
<a href="{{ partner.get_absolute_url }}"><img class="img-fluid card-logo" src="{{ partner.logo.url }}" alt="{{ partner.name }} logo"></a> <a href="{{ partner.get_absolute_url }}"><img class="img-fluid" src="{{ partner.logo.url }}" alt="{{ partner.name }} logo" style="max-height: 80px; max-width: 250px; object-fit: contain;"></a>
</div> </div>
<div class="card__header"> <div class="card__header">
<h3 class="card__title"><a href="{{ partner.get_absolute_url }}" class="text-decoration-none">{{ partner.name }}</a></h3> <h3 class="card__title"><a href="{{ partner.get_absolute_url }}" class="text-decoration-none">{{ partner.name }}</a></h3>
@ -154,7 +154,7 @@
</div> </div>
</div> </div>
<div class="page-action d-lg-none"> <div class="page-action d-lg-none">
<a class="btn btn-outline-primary btn-lg w-100" href="{% url 'services:partner_list' %}" role="button">See All</a> <a class="btn btn-outline-primary btn-lg w-100" href="#" role="button">See All</a>
</div> </div>
</div> </div>
</div> </div>
@ -164,7 +164,7 @@
<div class="row"> <div class="row">
<div class="col-12 col-lg-4 mb-30 mb-lg-0"> <div class="col-12 col-lg-4 mb-30 mb-lg-0">
<div class="section-logo mx-auto"> <div class="section-logo mx-auto">
<img class="img-fluid" src="{% static "img/section-logo.png" %}" alt="Servala Icon Logo"> <img class="img-fluid" src="{% static "img/section-logo.png" %}" alt="">
</div> </div>
</div> </div>
<div class="col-12 col-lg-8"> <div class="col-12 col-lg-8">

View file

@ -7,7 +7,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Contact Us</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Contact Us</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">We'd love to hear from you!</p> <p class="mb-0">We'd love to hear from you!</p>
</div> </div>

View file

@ -10,7 +10,7 @@
<div class="flex-1 pr-lg-40 mb-40 mb-lg-0"> <div class="flex-1 pr-lg-40 mb-40 mb-lg-0">
<div class="bg-gray-50 rounded-20 p-40"> <div class="bg-gray-50 rounded-20 p-40">
<header> <header>
<h1 class="fs-44 fw-semibold mb-40">Inquiry for {{ service.name }}</h1> <h2 class="fs-44 fw-semibold mb-40">Inquiry for {{ service.name }}</h2>
</header> </header>
<form method="post"> <form method="post">
@ -78,7 +78,7 @@
<div class="d-flex align-items-center mb-24"> <div class="d-flex align-items-center mb-24">
<div class="card__image mb-0"> <div class="card__image mb-0">
{% if selected_offering.service.logo %} {% if selected_offering.service.logo %}
<img class="img-fluid" src="{{ selected_offering.service.logo.url }}" alt="Service Logo"> <img class="img-fluid" src="{{ selected_offering.service.logo.url }}" alt="">
{% endif %} {% endif %}
</div> </div>
<div class="card__header ps-16"> <div class="card__header ps-16">

View file

@ -1,16 +1,15 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load static %} {% load static %}
{% load contact_tags %}
{% block title %}Managed {{ offering.service.name }} on {{ offering.cloud_provider.name }}{% endblock %} {% block title %}{{ offering.service.name }} on {{ offering.cloud_provider.name }}{% endblock %}
{% block content %} {% block content %}
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Managed {{ offering.service.name }} on {{ offering.cloud_provider.name }}</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Service Offering</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Details about {{ offering.service.name }} managed by VSHN on {{ offering.cloud_provider.name }}</p> <p class="mb-0">{{ offering.service.name }} managed by VSHN on {{ offering.cloud_provider.name }}</p>
</div> </div>
</header> </header>
</div> </div>
@ -143,7 +142,6 @@
{% endif %} {% endif %}
<!-- Plans --> <!-- Plans -->
{% if offering.plans.all %}
<div class="pt-24" id="plans" style="scroll-margin-top: 30px;"> <div class="pt-24" id="plans" style="scroll-margin-top: 30px;">
<h3 class="fs-24 fw-semibold lh-1 mb-12">Available Plans</h3> <h3 class="fs-24 fw-semibold lh-1 mb-12">Available Plans</h3>
<div class="row"> <div class="row">
@ -175,24 +173,19 @@
<div class="alert alert-info"> <div class="alert alert-info">
<p>No plans available yet.</p> <p>No plans available yet.</p>
<h4 class="mb-3">I'm interested in this offering</h4> <h4 class="mb-3">I'm interested in this offering</h4>
{% load contact_tags %}
{% embedded_contact_form source="Offering Interest" service=offering.service offering_id=offering.id %} {% embedded_contact_form source="Offering Interest" service=offering.service offering_id=offering.id %}
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
{% else %}
<div class="col-12" id="interest" style="scroll-margin-top: 30px;">
<h4 class="mb-3">I'm interested in this offering</h4>
{% load contact_tags %}
{% embedded_contact_form source="Offering Interest" service=offering.service offering_id=offering.id %}
</div>
{% endif %}
{% if offering.plans.exists %} {% if offering.plans.exists %}
<div class="pt-40"> <div class="pt-40">
<h4 class="fs-22 fw-semibold lh-1 mb-12">I'm interested in a plan</h4> <h4 class="fs-22 fw-semibold lh-1 mb-12">I'm interested in a plan</h4>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
{% load contact_tags %}
{% embedded_contact_form source="Plan Order" service=offering.service offering_id=offering.id choices=offering.plans.all choice_label="Select a Plan" %} {% embedded_contact_form source="Plan Order" service=offering.service offering_id=offering.id choices=offering.plans.all choice_label="Select a Plan" %}
</div> </div>
</div> </div>

View file

@ -6,7 +6,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Service Offerings</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Service Offerings</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Explore all available Offerings on Servala, with new ones added regularly. These ready-made packages bundle a Service on a Cloud Provider, making them ready for immediate use.</p> <p class="mb-0">Explore all available Offerings on Servala, with new ones added regularly. These ready-made packages bundle a Service on a Cloud Provider, making them ready for immediate use.</p>
</div> </div>

View file

@ -7,10 +7,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">{{ partner.name }} on Servala</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Consulting Partner</h2>
<div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">About the consulting partner {{ partner.name }} on Servala</p>
</div>
</header> </header>
</div> </div>
</section> </section>

View file

@ -9,7 +9,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Consulting Partners</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Consulting Partners</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Browse our network of expert Consulting Partners on Servala, with new partners added regularly. They'll help you get up to speed and make the most of specific services.</p> <p class="mb-0">Browse our network of expert Consulting Partners on Servala, with new partners added regularly. They'll help you get up to speed and make the most of specific services.</p>
</div> </div>

View file

@ -1,16 +1,13 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load contact_tags %} {% load contact_tags %}
{% block title %}Cloud Provider {{ provider.name }}{% endblock %} {% block title %}Service Provider {{ provider.name }}{% endblock %}
{% block content %} {% block content %}
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">{{ provider.name }} on Servala</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Service Provider</h2>
<div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">About the cloud provider {{ provider.name }} on Servala</p>
</div>
</header> </header>
</div> </div>
</section> </section>

View file

@ -2,14 +2,14 @@
{% load static %} {% load static %}
{% load contact_tags %} {% load contact_tags %}
{% block title %}Cloud Providers{% endblock %} {% block title %}Service Providers{% endblock %}
{% block meta_description %}Discover cloud providers on Servala offering reliable infrastructure and innovative cloud computing solutions for businesses of all sizes.{% endblock %} {% block meta_description %}Discover cloud providers on Servala offering reliable infrastructure and innovative cloud computing solutions for businesses of all sizes.{% endblock %}
{% block content %} {% block content %}
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Cloud Providers</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Cloud Providers</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Explore all available Cloud Providers on Servala, with new ones added regularly.</p> <p class="mb-0">Explore all available Cloud Providers on Servala, with new ones added regularly.</p>
</div> </div>

View file

@ -6,9 +6,9 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">{{ service.name }} on Servala</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Service Details</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Details about the service {{ service.name }} on Servala</p> <p class="mb-0">{{ service.name }}</p>
</div> </div>
</header> </header>
</div> </div>
@ -142,15 +142,11 @@
{% if service.offerings.exists %} {% if service.offerings.exists %}
<h3 class="fs-24 fw-semibold lh-1 mb-12">Get it on</h3> <h3 class="fs-24 fw-semibold lh-1 mb-12">Get it on</h3>
<p>Choose one of our trusted service providers</p> <p>Choose one of our trusted service providers</p>
<div class="d-flex flex-wrap gap-3"> {% for offering in service.offerings.all %}
{% for offering in service.offerings.all %} <p><a class="btn btn-primary btn-lg mr-md-17 mb-17 mb-md-0px mb-lg-17 mb-xl-0 w-100 w-md-auto"
{% if not offering.cloud_provider.disable_listing %} href="{% url 'services:offering_detail' offering.cloud_provider.slug offering.service.slug %}"
<a class="btn btn-primary btn-lg w-auto" role="button">{{ offering.cloud_provider.name }}</a></p>
href="{% url 'services:offering_detail' offering.cloud_provider.slug offering.service.slug %}" {% endfor %}
role="button">{{ offering.cloud_provider.name }}</a>
{% endif %}
{% endfor %}
</div>
{% else %} {% else %}
<div class="pt-40"> <div class="pt-40">
<h3 class="fs-24 fw-semibold lh-1 mb-12">Contact Us About This Service</h3> <h3 class="fs-24 fw-semibold lh-1 mb-12">Contact Us About This Service</h3>

View file

@ -9,7 +9,7 @@
<section class="section bg-primary-subtle"> <section class="section bg-primary-subtle">
<div class="container mx-auto px-20 px-lg-0 pt-40 pb-60"> <div class="container mx-auto px-20 px-lg-0 pt-40 pb-60">
<header class="section-primary__header text-center"> <header class="section-primary__header text-center">
<h1 class="section-h1 fs-40 fs-lg-64 mb-24">Services</h1> <h2 class="section-h1 fs-40 fs-lg-64 mb-24">Services</h2>
<div class="text-gray-300 w-lg-37 mx-auto"> <div class="text-gray-300 w-lg-37 mx-auto">
<p class="mb-0">Explore all available Services on Servala, with new ones added regularly.</p> <p class="mb-0">Explore all available Services on Servala, with new ones added regularly.</p>
</div> </div>

View file

@ -8,7 +8,7 @@
<div class="col-md-8 text-center"> <div class="col-md-8 text-center">
<div class="card shadow-sm"> <div class="card shadow-sm">
<div class="card-body p-5"> <div class="card-body p-5">
<h1 class="mb-4">Thank You!</h1> <h2 class="mb-4">Thank You!</h2>
<p class="lead">Your message has been sent successfully.</p> <p class="lead">Your message has been sent successfully.</p>
<p>We'll get back to you as soon as possible.</p> <p>We'll get back to you as soon as possible.</p>
<a href="{% url 'services:homepage' %}" class="btn btn-primary mt-3">Take me home</a> <a href="{% url 'services:homepage' %}" class="btn btn-primary mt-3">Take me home</a>

View file

@ -1,7 +0,0 @@
<div id="signup-form-container" class="text-center py-3">
<div class="alert alert-danger" role="alert">
<h4 class="section-h1">Oops!</h4>
<p class="text-gray-300">Something went wrong. Please try again later.</p>
<button class="btn btn-primary mt-2" onclick="location.reload()">Try Again</button>
</div>
</div>

View file

@ -1,6 +0,0 @@
<div id="signup-form-container" class="text-center py-3">
<div role="alert">
<h4 class="section-h1">Thank you!</h4>
<p class="text-gray-300">You have been successfully subscribed to our mailing list.</p>
</div>
</div>

View file

@ -1,6 +1,6 @@
# hub/services/templatetags/json_ld_tags.py # hub/services/templatetags/json_ld_tags.py
from django import template from django import template
from django.urls import resolve, Resolver404 from django.urls import resolve
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
import json import json
@ -11,14 +11,14 @@ register = template.Library()
def json_ld_structured_data(context): def json_ld_structured_data(context):
""" """
Generates appropriate JSON-LD structured data based on the current page. Generates appropriate JSON-LD structured data based on the current page.
For schemas, see https://schema.org/
""" """
request = context.get("request") request = context["request"]
if not request:
return ""
current_url = request.path current_url = request.path
base_url = f"{request.scheme}://{request.get_host()}" resolved_view = resolve(current_url)
view_name = resolved_view.url_name
# Base URL for building absolute URLs
base_url = request.build_absolute_uri("/").rstrip("/")
# Default organization data (for Servala) # Default organization data (for Servala)
organization_data = { organization_data = {
@ -30,8 +30,8 @@ def json_ld_structured_data(context):
"contactPoint": { "contactPoint": {
"@type": "ContactPoint", "@type": "ContactPoint",
"telephone": "+41 44 545 53 00", "telephone": "+41 44 545 53 00",
"email": "hi@servala.com", "email": "hi@serva.la",
"contactType": "Sales", "contactType": "Customer Support",
}, },
"address": { "address": {
"@type": "PostalAddress", "@type": "PostalAddress",
@ -42,45 +42,27 @@ def json_ld_structured_data(context):
}, },
} }
# Add try-except around the view resolution # Handle different page types
try: if view_name == "homepage":
resolved_view = resolve(current_url)
view_name = resolved_view.url_name
except Resolver404:
# For 404 pages or other unresolvable URLs, return minimal data
data = { data = {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "WebSite", "@type": "WebSite",
"name": "Servala - Open Cloud Native Service Hub", "name": "Servala - Open Cloud Native Service Hub",
"url": base_url, "url": base_url,
} "description": "Servala connects businesses, developers, and cloud service providers on one unique hub with secure, scalable, and easy-to-use cloud-native services.",
json_ld = json.dumps(data, indent=2) "potentialAction": {
return mark_safe(f'<script type="application/ld+json">{json_ld}</script>') "@type": "SearchAction",
"target": f"{base_url}/services/?search={{search_term_string}}",
# Handle different page types "query-input": "required name=search_term_string",
if view_name == "homepage":
data = [
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Servala - Open Cloud Native Service Hub",
"url": base_url,
"description": "Servala connects businesses, developers, and cloud service providers on one unique hub with secure, scalable, and easy-to-use cloud-native services.",
"potentialAction": {
"@type": "SearchAction",
"target": f"{base_url}/service/?search={{search_term_string}}",
"query-input": "required name=search_term_string",
},
}, },
organization_data, }
]
elif view_name == "service_list": elif view_name == "service_list":
data = { data = {
"@context": "https://schema.org", "@context": "https://schema.org",
"@type": "CollectionPage", "@type": "CollectionPage",
"name": "Cloud Services - Servala", "name": "Cloud Services - Servala",
"url": f"{base_url}/service/", "url": f"{base_url}/services/",
"description": "Explore all available cloud services on Servala, with new services added regularly.", "description": "Explore all available cloud services on Servala, with new services added regularly.",
"isPartOf": {"@type": "WebSite", "name": "Servala", "url": base_url}, "isPartOf": {"@type": "WebSite", "name": "Servala", "url": base_url},
} }

View file

@ -21,5 +21,4 @@ urlpatterns = [
path("contact/", views.leads.contact, name="contact"), path("contact/", views.leads.contact, name="contact"),
path("contact/thank-you/", views.thank_you, name="thank_you"), path("contact/thank-you/", views.thank_you, name="thank_you"),
path("contact-form/", views.contact_form, name="contact_form"), path("contact-form/", views.contact_form, name="contact_form"),
path("subscribe/", views.subscribe, name="subscribe"),
] ]

View file

@ -4,4 +4,3 @@ from .partners import *
from .providers import * from .providers import *
from .services import * from .services import *
from .pages import * from .pages import *
from .subscriptions import *

View file

@ -1,6 +1,5 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.db.models import Q from django.db.models import Q
from django.db.models import Count
from hub.services.models import ( from hub.services.models import (
Service, Service,
ServiceOffering, ServiceOffering,
@ -48,16 +47,14 @@ def provider_detail(request, slug):
.prefetch_related("categories") .prefetch_related("categories")
) )
# Get the provider's offerings and sort them by service attributes and plan availability # Get the provider's offerings and sort them by service attributes
# Exclude offerings with disabled services # Exclude offerings with disabled services
ordered_offerings = ( ordered_offerings = (
ServiceOffering.objects.filter( ServiceOffering.objects.filter(
cloud_provider=provider, service__disable_listing=False cloud_provider=provider, service__disable_listing=False
) )
.select_related("service") .select_related("service")
.annotate(has_plans=Count("plans"))
.order_by( .order_by(
"-has_plans", # Offerings with plans first
"-service__is_featured", # Featured first (True before False) "-service__is_featured", # Featured first (True before False)
"service__is_coming_soon", # Coming soon last (False before True) "service__is_coming_soon", # Coming soon last (False before True)
"service__name", # Alphabetically within each group "service__name", # Alphabetically within each group

View file

@ -1,36 +0,0 @@
import logging
from django.conf import settings
from django.shortcuts import render
from django.views.decorators.http import require_POST
from hub.services.odoo import OdooAPI
logger = logging.getLogger(__name__)
@require_POST
def subscribe(request):
"""Handle mailing list subscription requests"""
email = request.POST.get("email", "")
if not email:
return render(request, "subscriptions/error.html")
try:
# Get mailing list ID from settings
mailing_list_id = settings.ODOO_CONFIG.get("mailing_list_id", 46)
# Connect to Odoo
odoo = OdooAPI()
# Add subscriber to mailing list
result = odoo.add_to_mailing_list(email, mailing_list_id)
if result:
return render(request, "subscriptions/success.html")
else:
return render(request, "subscriptions/error.html")
except Exception as e:
logger.error(
f"Failed to add subscriber to mailing list: {str(e)}", exc_info=True
)
return render(request, "subscriptions/error.html")

View file

@ -55,10 +55,6 @@ CSRF_TRUSTED_ORIGINS = [f"https://{h}" for h in HTTPS_HOSTS] + [
# Primary website URL # Primary website URL
WEBSITE_URL = env.str("WEBSITE_URL", default="https://servala.com") WEBSITE_URL = env.str("WEBSITE_URL", default="https://servala.com")
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
USE_X_FORWARDED_HOST = True
USE_X_FORWARDED_PORT = True
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [
@ -208,7 +204,6 @@ ODOO_CONFIG = {
"source_id": env.str("ODOO_LEAD_SOURCE_ID", default="1"), "source_id": env.str("ODOO_LEAD_SOURCE_ID", default="1"),
"medium_id": env.str("ODOO_LEAD_MEDIUM_ID", default="1"), "medium_id": env.str("ODOO_LEAD_MEDIUM_ID", default="1"),
"tag_id": env.str("ODOO_LEAD_TAG_ID", default="1"), "tag_id": env.str("ODOO_LEAD_TAG_ID", default="1"),
"mailing_list_id": env.int("ODOO_MAILING_LIST_ID", default=46),
} }
BROKER_USERNAME = env.str("BROKER_USERNAME", default="broker") BROKER_USERNAME = env.str("BROKER_USERNAME", default="broker")

View file

@ -6,7 +6,6 @@ from django.shortcuts import render
from django.urls import path, include from django.urls import path, include
from django.contrib.sitemaps.views import sitemap from django.contrib.sitemaps.views import sitemap
from django.http import HttpResponse from django.http import HttpResponse
from django.views.generic.base import RedirectView
from hub.services.views.errors import bad_request, page_not_found, server_error from hub.services.views.errors import bad_request, page_not_found, server_error
@ -22,7 +21,7 @@ from .sitemaps import (
def robots_txt(request): def robots_txt(request):
content = """User-agent: * content = """User-agent: *
Allow: / Allow: /
Sitemap: https://servala.com/sitemap.xml Sitemap: https://serva.la/sitemap.xml
""" """
return HttpResponse(content, content_type="text/plain") return HttpResponse(content, content_type="text/plain")
@ -50,11 +49,6 @@ urlpatterns = [
name="django.contrib.sitemaps.views.sitemap", name="django.contrib.sitemaps.views.sitemap",
), ),
path("robots.txt", robots_txt, name="robots_txt"), path("robots.txt", robots_txt, name="robots_txt"),
path(
"favicon.ico",
RedirectView.as_view(url=settings.STATIC_URL + "img/favicon.ico"),
name="favicon",
),
] ]
if settings.DEBUG: if settings.DEBUG:
urlpatterns += [ urlpatterns += [

View file

@ -5,7 +5,7 @@ description = "Add your description here"
readme = "README.md" readme = "README.md"
requires-python = ">=3.13" requires-python = ">=3.13"
dependencies = [ dependencies = [
"django>=5.2", "django>=5.1.5",
"django-admin-sortable2>=2.2.4", "django-admin-sortable2>=2.2.4",
"django-jazzmin>=3.0.1", "django-jazzmin>=3.0.1",
"django-nested-admin>=4.1.1", "django-nested-admin>=4.1.1",

182
uv.lock generated
View file

@ -1,14 +1,14 @@
version = 1 version = 1
revision = 2 revision = 1
requires-python = ">=3.13" requires-python = ">=3.13"
[[package]] [[package]]
name = "asgiref" name = "asgiref"
version = "3.8.1" version = "3.8.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186, upload-time = "2024-03-22T14:39:36.863Z" } sdist = { url = "https://files.pythonhosted.org/packages/29/38/b3395cc9ad1b56d2ddac9970bc8f4141312dbaec28bc7c218b0dfafd0f42/asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590", size = 35186 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828, upload-time = "2024-03-22T14:39:34.521Z" }, { url = "https://files.pythonhosted.org/packages/39/e3/893e8757be2612e6c266d9bb58ad2e3651524b5b40cf56761e985a28b13e/asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47", size = 23828 },
] ]
[[package]] [[package]]
@ -19,32 +19,32 @@ dependencies = [
{ name = "django" }, { name = "django" },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/98/9f/fc9905758256af4f68a55da94ab78a13e7775074edfdcaddd757d4921686/dj_database_url-2.3.0.tar.gz", hash = "sha256:ae52e8e634186b57e5a45e445da5dc407a819c2ceed8a53d1fac004cc5288787", size = 10980, upload-time = "2024-10-23T10:05:19.953Z" } sdist = { url = "https://files.pythonhosted.org/packages/98/9f/fc9905758256af4f68a55da94ab78a13e7775074edfdcaddd757d4921686/dj_database_url-2.3.0.tar.gz", hash = "sha256:ae52e8e634186b57e5a45e445da5dc407a819c2ceed8a53d1fac004cc5288787", size = 10980 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/e5/91/641a4e5c8903ed59f6cbcce571003bba9c5d2f731759c31db0ba83bb0bdb/dj_database_url-2.3.0-py3-none-any.whl", hash = "sha256:bb0d414ba0ac5cd62773ec7f86f8cc378a9dbb00a80884c2fc08cc570452521e", size = 7793, upload-time = "2024-10-23T10:05:41.254Z" }, { url = "https://files.pythonhosted.org/packages/e5/91/641a4e5c8903ed59f6cbcce571003bba9c5d2f731759c31db0ba83bb0bdb/dj_database_url-2.3.0-py3-none-any.whl", hash = "sha256:bb0d414ba0ac5cd62773ec7f86f8cc378a9dbb00a80884c2fc08cc570452521e", size = 7793 },
] ]
[[package]] [[package]]
name = "dj-email-url" name = "dj-email-url"
version = "1.0.6" version = "1.0.6"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/14/ef/8eb478accd9b0369d46a98d1b43027ee0c254096149265c78e6b2e2fa3b0/dj-email-url-1.0.6.tar.gz", hash = "sha256:55ffe3329e48f54f8a75aa36ece08f365e09d61f8a209773ef09a1d4760e699a", size = 15590, upload-time = "2022-09-24T11:04:50.281Z" } sdist = { url = "https://files.pythonhosted.org/packages/14/ef/8eb478accd9b0369d46a98d1b43027ee0c254096149265c78e6b2e2fa3b0/dj-email-url-1.0.6.tar.gz", hash = "sha256:55ffe3329e48f54f8a75aa36ece08f365e09d61f8a209773ef09a1d4760e699a", size = 15590 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/8a/f9/fcb9745099d821f9a26092d3d6f4df8f10049885045c3a93ff726d2e40a6/dj_email_url-1.0.6-py2.py3-none-any.whl", hash = "sha256:cbd08327fbb08b104eac160fb4703f375532e4c0243eb230f5b960daee7a96db", size = 6296, upload-time = "2022-09-24T11:04:47.191Z" }, { url = "https://files.pythonhosted.org/packages/8a/f9/fcb9745099d821f9a26092d3d6f4df8f10049885045c3a93ff726d2e40a6/dj_email_url-1.0.6-py2.py3-none-any.whl", hash = "sha256:cbd08327fbb08b104eac160fb4703f375532e4c0243eb230f5b960daee7a96db", size = 6296 },
] ]
[[package]] [[package]]
name = "django" name = "django"
version = "5.2" version = "5.1.5"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "asgiref" }, { name = "asgiref" },
{ name = "sqlparse" }, { name = "sqlparse" },
{ name = "tzdata", marker = "sys_platform == 'win32'" }, { name = "tzdata", marker = "sys_platform == 'win32'" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/4c/1b/c6da718c65228eb3a7ff7ba6a32d8e80fa840ca9057490504e099e4dd1ef/Django-5.2.tar.gz", hash = "sha256:1a47f7a7a3d43ce64570d350e008d2949abe8c7e21737b351b6a1611277c6d89", size = 10824891, upload-time = "2025-04-02T13:08:06.874Z" } sdist = { url = "https://files.pythonhosted.org/packages/e4/17/834e3e08d590dcc27d4cc3c5cd4e2fb757b7a92bab9de8ee402455732952/Django-5.1.5.tar.gz", hash = "sha256:19bbca786df50b9eca23cee79d495facf55c8f5c54c529d9bf1fe7b5ea086af3", size = 10700031 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/63/e0/6a5b5ea350c5bd63fe94b05e4c146c18facb51229d9dee42aa39f9fc2214/Django-5.2-py3-none-any.whl", hash = "sha256:91ceed4e3a6db5aedced65e3c8f963118ea9ba753fc620831c77074e620e7d83", size = 8301361, upload-time = "2025-04-02T13:08:01.465Z" }, { url = "https://files.pythonhosted.org/packages/11/e6/e92c8c788b83d109f34d933c5e817095d85722719cb4483472abc135f44e/Django-5.1.5-py3-none-any.whl", hash = "sha256:c46eb936111fffe6ec4bc9930035524a8be98ec2f74d8a0ff351226a3e52f459", size = 8276957 },
] ]
[[package]] [[package]]
@ -54,9 +54,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/ee/a1/0651ad69906f9ec9e73897353e933611550c6d31bfa9f721319c0ed99108/django_admin_sortable2-2.2.4.tar.gz", hash = "sha256:155e6114c7a931bceed9513af014f782ff1e643d99e81ddfef934f1daecd669d", size = 68207, upload-time = "2024-11-15T09:43:15.451Z" } sdist = { url = "https://files.pythonhosted.org/packages/ee/a1/0651ad69906f9ec9e73897353e933611550c6d31bfa9f721319c0ed99108/django_admin_sortable2-2.2.4.tar.gz", hash = "sha256:155e6114c7a931bceed9513af014f782ff1e643d99e81ddfef934f1daecd669d", size = 68207 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/66/c3/e804b1f04546c1060e566f35177c346590820a95bfb981d1f6360b419437/django_admin_sortable2-2.2.4-py3-none-any.whl", hash = "sha256:406c5b6d6e84ad982cc6e53c3f34b5db5f0a3f34891126af90c9fb2c372f53d5", size = 90816, upload-time = "2024-11-15T09:43:13.665Z" }, { url = "https://files.pythonhosted.org/packages/66/c3/e804b1f04546c1060e566f35177c346590820a95bfb981d1f6360b419437/django_admin_sortable2-2.2.4-py3-none-any.whl", hash = "sha256:406c5b6d6e84ad982cc6e53c3f34b5db5f0a3f34891126af90c9fb2c372f53d5", size = 90816 },
] ]
[[package]] [[package]]
@ -67,18 +67,18 @@ dependencies = [
{ name = "asgiref" }, { name = "asgiref" },
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/9f/bc/3c67f7daca53b826ec51888576fe5e117d9442d2d0acb58f4264d48b9dba/django_browser_reload-1.17.0.tar.gz", hash = "sha256:3667939cde0eee1a6d698dbe3b78cf10b573dabc4e711fb7933f1ba91fb98da4", size = 14312, upload-time = "2024-10-29T10:31:14.846Z" } sdist = { url = "https://files.pythonhosted.org/packages/9f/bc/3c67f7daca53b826ec51888576fe5e117d9442d2d0acb58f4264d48b9dba/django_browser_reload-1.17.0.tar.gz", hash = "sha256:3667939cde0eee1a6d698dbe3b78cf10b573dabc4e711fb7933f1ba91fb98da4", size = 14312 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/8f/62fc4fbf5c05c2210e6cb616f1c2a3da53871dfecbaa4c44b1f482ca3e8f/django_browser_reload-1.17.0-py3-none-any.whl", hash = "sha256:d372c12c1c5962c02279a53cac7e8a020c48f104592c637a06d0768b28d2d6be", size = 12228, upload-time = "2024-10-29T10:31:13.332Z" }, { url = "https://files.pythonhosted.org/packages/7f/8f/62fc4fbf5c05c2210e6cb616f1c2a3da53871dfecbaa4c44b1f482ca3e8f/django_browser_reload-1.17.0-py3-none-any.whl", hash = "sha256:d372c12c1c5962c02279a53cac7e8a020c48f104592c637a06d0768b28d2d6be", size = 12228 },
] ]
[[package]] [[package]]
name = "django-cache-url" name = "django-cache-url"
version = "3.4.5" version = "3.4.5"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/20/28/d420aaa89028d2ec0cf17c1510d06ff6a8ed0bf1abfb7f33c999e1c5befa/django-cache-url-3.4.5.tar.gz", hash = "sha256:eb9fb194717524348c95cad9905b70b647452741c1d9e481fac6d2125f0ad917", size = 7230, upload-time = "2023-12-04T17:19:46.21Z" } sdist = { url = "https://files.pythonhosted.org/packages/20/28/d420aaa89028d2ec0cf17c1510d06ff6a8ed0bf1abfb7f33c999e1c5befa/django-cache-url-3.4.5.tar.gz", hash = "sha256:eb9fb194717524348c95cad9905b70b647452741c1d9e481fac6d2125f0ad917", size = 7230 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/48/90/01755e4a42558b763f7021e9369aa6aa94c2ede7313deed56cb7483834ab/django_cache_url-3.4.5-py2.py3-none-any.whl", hash = "sha256:5f350759978483ab85dc0e3e17b3d53eed3394a28148f6bf0f53d11d0feb5b3c", size = 4760, upload-time = "2023-12-04T17:19:44.355Z" }, { url = "https://files.pythonhosted.org/packages/48/90/01755e4a42558b763f7021e9369aa6aa94c2ede7313deed56cb7483834ab/django_cache_url-3.4.5-py2.py3-none-any.whl", hash = "sha256:5f350759978483ab85dc0e3e17b3d53eed3394a28148f6bf0f53d11d0feb5b3c", size = 4760 },
] ]
[[package]] [[package]]
@ -88,9 +88,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/84/96/21b6255e90d92a3eb4e93bea9376635d54258e0353ebb913a55e40ae9254/django_jazzmin-3.0.1.tar.gz", hash = "sha256:67ae148bade41267a09ca8e4352ddefa6121795ebbac238bb9a6564ff841eb1b", size = 2053550, upload-time = "2024-10-08T17:40:59.771Z" } sdist = { url = "https://files.pythonhosted.org/packages/84/96/21b6255e90d92a3eb4e93bea9376635d54258e0353ebb913a55e40ae9254/django_jazzmin-3.0.1.tar.gz", hash = "sha256:67ae148bade41267a09ca8e4352ddefa6121795ebbac238bb9a6564ff841eb1b", size = 2053550 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ad/5b/2f8c4b168e6c41bf1e4b14d787deb23d80f618f0693db913bbe208a4a907/django_jazzmin-3.0.1-py3-none-any.whl", hash = "sha256:12a0a4c1d4fd09c2eef22acf6a1f03112b515ba695c59faa8ea80efc81c1f21b", size = 2125957, upload-time = "2024-10-08T17:40:57.359Z" }, { url = "https://files.pythonhosted.org/packages/ad/5b/2f8c4b168e6c41bf1e4b14d787deb23d80f618f0693db913bbe208a4a907/django_jazzmin-3.0.1-py3-none-any.whl", hash = "sha256:12a0a4c1d4fd09c2eef22acf6a1f03112b515ba695c59faa8ea80efc81c1f21b", size = 2125957 },
] ]
[[package]] [[package]]
@ -100,9 +100,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/0a/02/5d3b57d2ad3c1819aaf921fa6b9d7fbc54ec5d81871a7fb6f4f0b146dd4e/django_js_asset-3.0.1.tar.gz", hash = "sha256:5ad51814edf38d28e6280e6ecad50ee40551363a2f6a6bfe93577dee793dc378", size = 7701, upload-time = "2024-12-17T17:16:33.559Z" } sdist = { url = "https://files.pythonhosted.org/packages/0a/02/5d3b57d2ad3c1819aaf921fa6b9d7fbc54ec5d81871a7fb6f4f0b146dd4e/django_js_asset-3.0.1.tar.gz", hash = "sha256:5ad51814edf38d28e6280e6ecad50ee40551363a2f6a6bfe93577dee793dc378", size = 7701 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/61/d1/be003d14c880c100d8713b2ca0a286728e6e8b47e50d25e2fab31adc9632/django_js_asset-3.0.1-py3-none-any.whl", hash = "sha256:0b7ee73c45ca65cccbcc2f60cbe8fbc87ff133b543c282cb64fe6c13d7ca4c10", size = 4283, upload-time = "2024-12-17T17:16:34.818Z" }, { url = "https://files.pythonhosted.org/packages/61/d1/be003d14c880c100d8713b2ca0a286728e6e8b47e50d25e2fab31adc9632/django_js_asset-3.0.1-py3-none-any.whl", hash = "sha256:0b7ee73c45ca65cccbcc2f60cbe8fbc87ff133b543c282cb64fe6c13d7ca4c10", size = 4283 },
] ]
[[package]] [[package]]
@ -112,9 +112,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "python-monkey-business" }, { name = "python-monkey-business" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/1c/d1/bd500d354dcc3ccbf74507c97dabc5aee18bf0620d2df3deb3971b5c14ed/django-nested-admin-4.1.1.tar.gz", hash = "sha256:645d63b38d579b034a65e0983f1f8cbb8824c75b4232f8d62a1583fa7a9f568f", size = 421628, upload-time = "2024-08-13T02:16:36.9Z" } sdist = { url = "https://files.pythonhosted.org/packages/1c/d1/bd500d354dcc3ccbf74507c97dabc5aee18bf0620d2df3deb3971b5c14ed/django-nested-admin-4.1.1.tar.gz", hash = "sha256:645d63b38d579b034a65e0983f1f8cbb8824c75b4232f8d62a1583fa7a9f568f", size = 421628 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/fe/e2/2a58c3c21c2e8c383f7e9de2874fa7b443705146e54d0364f1fe6fc31b7e/django_nested_admin-4.1.1-py3-none-any.whl", hash = "sha256:7e72ab7a8ae4c91074f6f709ce38fdf54f9c5f78d19e68772e0f05b83090ec9f", size = 465355, upload-time = "2024-08-13T02:16:34.405Z" }, { url = "https://files.pythonhosted.org/packages/fe/e2/2a58c3c21c2e8c383f7e9de2874fa7b443705146e54d0364f1fe6fc31b7e/django_nested_admin-4.1.1-py3-none-any.whl", hash = "sha256:7e72ab7a8ae4c91074f6f709ce38fdf54f9c5f78d19e68772e0f05b83090ec9f", size = 465355 },
] ]
[[package]] [[package]]
@ -125,9 +125,9 @@ dependencies = [
{ name = "django" }, { name = "django" },
{ name = "django-js-asset" }, { name = "django-js-asset" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/d6/2d/28aeb5d89b96b0850f286f50d1bb51259d3425242035fb9f893073350b22/django_prose_editor-0.10.3.tar.gz", hash = "sha256:4ecef8cbd0286065ec54e18e15419495c80404a408860cad2189180724f93d49", size = 260180, upload-time = "2025-01-21T18:21:41.748Z" } sdist = { url = "https://files.pythonhosted.org/packages/d6/2d/28aeb5d89b96b0850f286f50d1bb51259d3425242035fb9f893073350b22/django_prose_editor-0.10.3.tar.gz", hash = "sha256:4ecef8cbd0286065ec54e18e15419495c80404a408860cad2189180724f93d49", size = 260180 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/f2/fd/922e6f3e9827c31a9bc00751ac02f0798c5beeae4994a97dbb978a1a55a2/django_prose_editor-0.10.3-py3-none-any.whl", hash = "sha256:776f0eb86791e72278f55abc98e426620f9bff5554a46c513069f8c089d80960", size = 261340, upload-time = "2025-01-21T18:21:45.122Z" }, { url = "https://files.pythonhosted.org/packages/f2/fd/922e6f3e9827c31a9bc00751ac02f0798c5beeae4994a97dbb978a1a55a2/django_prose_editor-0.10.3-py3-none-any.whl", hash = "sha256:776f0eb86791e72278f55abc98e426620f9bff5554a46c513069f8c089d80960", size = 261340 },
] ]
[package.optional-dependencies] [package.optional-dependencies]
@ -142,9 +142,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/a2/11/ab9c6b0105d55b9a8197b9795d77fec72d1ec065c2cb479410c6ca1f7daf/django_schema_viewer-0.5.2.tar.gz", hash = "sha256:4c9316a3831e6015270b432404f1589b6b711b13ebc6d797b1fce82d1fa7281e", size = 486063, upload-time = "2025-01-11T23:55:38.135Z" } sdist = { url = "https://files.pythonhosted.org/packages/a2/11/ab9c6b0105d55b9a8197b9795d77fec72d1ec065c2cb479410c6ca1f7daf/django_schema_viewer-0.5.2.tar.gz", hash = "sha256:4c9316a3831e6015270b432404f1589b6b711b13ebc6d797b1fce82d1fa7281e", size = 486063 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/aa/1a/f2dc4b54b18da7fd8dec7149c86f484581addd010f65f7a40bf16addbf39/django_schema_viewer-0.5.2-py3-none-any.whl", hash = "sha256:d799f52194cb906add990a1f178d92b0acfcb0a2e54c022843784e06fb12d75b", size = 492672, upload-time = "2025-01-11T23:55:40.496Z" }, { url = "https://files.pythonhosted.org/packages/aa/1a/f2dc4b54b18da7fd8dec7149c86f484581addd010f65f7a40bf16addbf39/django_schema_viewer-0.5.2-py3-none-any.whl", hash = "sha256:d799f52194cb906add990a1f178d92b0acfcb0a2e54c022843784e06fb12d75b", size = 492672 },
] ]
[[package]] [[package]]
@ -154,9 +154,9 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "django" }, { name = "django" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/2c/ce/31482eb688bdb4e271027076199e1aa8d02507e530b6d272ab8b4481557c/djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad", size = 1067420, upload-time = "2024-06-19T07:59:32.891Z" } sdist = { url = "https://files.pythonhosted.org/packages/2c/ce/31482eb688bdb4e271027076199e1aa8d02507e530b6d272ab8b4481557c/djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad", size = 1067420 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/7c/b6/fa99d8f05eff3a9310286ae84c4059b08c301ae4ab33ae32e46e8ef76491/djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20", size = 1071235, upload-time = "2024-06-19T07:59:26.106Z" }, { url = "https://files.pythonhosted.org/packages/7c/b6/fa99d8f05eff3a9310286ae84c4059b08c301ae4ab33ae32e46e8ef76491/djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20", size = 1071235 },
] ]
[[package]] [[package]]
@ -167,9 +167,9 @@ dependencies = [
{ name = "marshmallow" }, { name = "marshmallow" },
{ name = "python-dotenv" }, { name = "python-dotenv" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/3c/8f/952bd034eac79c8b68b6c770cb78c2bdcb3140d31ff224847f3520077d75/environs-14.1.0.tar.gz", hash = "sha256:a5f2afe9d5a21b468e74a3cceacf5d2371fd67dbb9a7e54fe62290c75a09cdfa", size = 30985, upload-time = "2025-01-10T15:27:49.362Z" } sdist = { url = "https://files.pythonhosted.org/packages/3c/8f/952bd034eac79c8b68b6c770cb78c2bdcb3140d31ff224847f3520077d75/environs-14.1.0.tar.gz", hash = "sha256:a5f2afe9d5a21b468e74a3cceacf5d2371fd67dbb9a7e54fe62290c75a09cdfa", size = 30985 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/d5/ad/57cfa3e8a006df88e723524127dbab2971a4877c97e7bad070257e15cb6c/environs-14.1.0-py3-none-any.whl", hash = "sha256:a7edda1668ddf1fbfcb7662bdc242dac25648eff2c7fdbaa5d959693afed7a3e", size = 15332, upload-time = "2025-01-10T15:27:42.865Z" }, { url = "https://files.pythonhosted.org/packages/d5/ad/57cfa3e8a006df88e723524127dbab2971a4877c97e7bad070257e15cb6c/environs-14.1.0-py3-none-any.whl", hash = "sha256:a7edda1668ddf1fbfcb7662bdc242dac25648eff2c7fdbaa5d959693afed7a3e", size = 15332 },
] ]
[package.optional-dependencies] [package.optional-dependencies]
@ -186,103 +186,103 @@ source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "packaging" }, { name = "packaging" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/ed/3a/b392ca6582ce5c2e515a8ca365f89b6e631d864a80ecdc72e0bc1bf3aec6/marshmallow-3.26.0.tar.gz", hash = "sha256:eb36762a1cc76d7abf831e18a3a1b26d3d481bbc74581b8e532a3d3a8115e1cb", size = 221490, upload-time = "2025-01-23T03:20:11.904Z" } sdist = { url = "https://files.pythonhosted.org/packages/ed/3a/b392ca6582ce5c2e515a8ca365f89b6e631d864a80ecdc72e0bc1bf3aec6/marshmallow-3.26.0.tar.gz", hash = "sha256:eb36762a1cc76d7abf831e18a3a1b26d3d481bbc74581b8e532a3d3a8115e1cb", size = 221490 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/d6/0d/80d7071803df1957c304bc096a714334dda7eb41ecfdd28dcfb49b1cde0e/marshmallow-3.26.0-py3-none-any.whl", hash = "sha256:1287bca04e6a5f4094822ac153c03da5e214a0a60bcd557b140f3e66991b8ca1", size = 50846, upload-time = "2025-01-23T03:20:09.805Z" }, { url = "https://files.pythonhosted.org/packages/d6/0d/80d7071803df1957c304bc096a714334dda7eb41ecfdd28dcfb49b1cde0e/marshmallow-3.26.0-py3-none-any.whl", hash = "sha256:1287bca04e6a5f4094822ac153c03da5e214a0a60bcd557b140f3e66991b8ca1", size = 50846 },
] ]
[[package]] [[package]]
name = "nh3" name = "nh3"
version = "0.2.20" version = "0.2.20"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/46/f2/eb781d94c7855e9129cbbdd3ab09a470441e4176a82a396ae1df270a7333/nh3-0.2.20.tar.gz", hash = "sha256:9705c42d7ff88a0bea546c82d7fe5e59135e3d3f057e485394f491248a1f8ed5", size = 17489, upload-time = "2024-12-17T12:50:22.381Z" } sdist = { url = "https://files.pythonhosted.org/packages/46/f2/eb781d94c7855e9129cbbdd3ab09a470441e4176a82a396ae1df270a7333/nh3-0.2.20.tar.gz", hash = "sha256:9705c42d7ff88a0bea546c82d7fe5e59135e3d3f057e485394f491248a1f8ed5", size = 17489 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/3c/65/d31d93b6d1e5fe80d0cc18f0b96eaa561edfa0a15a6ef6b0fce50202a931/nh3-0.2.20-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e1061a4ab6681f6bdf72b110eea0c4e1379d57c9de937db3be4202f7ad6043db", size = 1202187, upload-time = "2024-12-17T12:49:28.903Z" }, { url = "https://files.pythonhosted.org/packages/3c/65/d31d93b6d1e5fe80d0cc18f0b96eaa561edfa0a15a6ef6b0fce50202a931/nh3-0.2.20-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e1061a4ab6681f6bdf72b110eea0c4e1379d57c9de937db3be4202f7ad6043db", size = 1202187 },
{ url = "https://files.pythonhosted.org/packages/b4/ae/5b03bf198e06921454012e4b9a51e676d26fd37d9fdc1f29371a0b380487/nh3-0.2.20-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb4254b1dac4a1ee49919a5b3f1caf9803ea8dada1816d9e8289e63d3cd0dd9a", size = 737822, upload-time = "2024-12-17T12:49:30.42Z" }, { url = "https://files.pythonhosted.org/packages/b4/ae/5b03bf198e06921454012e4b9a51e676d26fd37d9fdc1f29371a0b380487/nh3-0.2.20-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb4254b1dac4a1ee49919a5b3f1caf9803ea8dada1816d9e8289e63d3cd0dd9a", size = 737822 },
{ url = "https://files.pythonhosted.org/packages/0a/53/a12dffb6ee3772deba82eb5997667fc835afd2e813d1f4080d8738f29eec/nh3-0.2.20-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ae9cbd713524cdb81e64663d0d6aae26f678db9f2cd9db0bf162606f1f9f20c", size = 756643, upload-time = "2024-12-17T12:49:31.767Z" }, { url = "https://files.pythonhosted.org/packages/0a/53/a12dffb6ee3772deba82eb5997667fc835afd2e813d1f4080d8738f29eec/nh3-0.2.20-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ae9cbd713524cdb81e64663d0d6aae26f678db9f2cd9db0bf162606f1f9f20c", size = 756643 },
{ url = "https://files.pythonhosted.org/packages/d0/0c/6cd2c5ac3e6e31f2a28721e8e2a924cb6b05ad054bf787bd1816ffd40b96/nh3-0.2.20-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e1f7370b4e14cc03f5ae141ef30a1caf81fa5787711f80be9081418dd9eb79d2", size = 923415, upload-time = "2024-12-17T12:49:34.434Z" }, { url = "https://files.pythonhosted.org/packages/d0/0c/6cd2c5ac3e6e31f2a28721e8e2a924cb6b05ad054bf787bd1816ffd40b96/nh3-0.2.20-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e1f7370b4e14cc03f5ae141ef30a1caf81fa5787711f80be9081418dd9eb79d2", size = 923415 },
{ url = "https://files.pythonhosted.org/packages/64/f0/229a6c8b81b86ba22d8e7f27ade62cb2fcfb987e570f49944fdd8490a76a/nh3-0.2.20-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:ac4d27dc836a476efffc6eb661994426b8b805c951b29c9cf2ff36bc9ad58bc5", size = 994959, upload-time = "2024-12-17T12:49:37.357Z" }, { url = "https://files.pythonhosted.org/packages/64/f0/229a6c8b81b86ba22d8e7f27ade62cb2fcfb987e570f49944fdd8490a76a/nh3-0.2.20-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:ac4d27dc836a476efffc6eb661994426b8b805c951b29c9cf2ff36bc9ad58bc5", size = 994959 },
{ url = "https://files.pythonhosted.org/packages/75/e3/62ae3d3b658739ee15b129356fe6d4c4bc8ab235d7bf2e0d2794d64f7bc6/nh3-0.2.20-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4fd2e9248725ebcedac3997a8d3da0d90a12a28c9179c6ba51f1658938ac30d0", size = 915777, upload-time = "2024-12-17T12:49:40.012Z" }, { url = "https://files.pythonhosted.org/packages/75/e3/62ae3d3b658739ee15b129356fe6d4c4bc8ab235d7bf2e0d2794d64f7bc6/nh3-0.2.20-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:4fd2e9248725ebcedac3997a8d3da0d90a12a28c9179c6ba51f1658938ac30d0", size = 915777 },
{ url = "https://files.pythonhosted.org/packages/45/bd/8405d03371e335f02eb72e09dcf73307f8fd3095e4165cec6836346fe3db/nh3-0.2.20-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f7d564871833ddbe54df3aa59053b1110729d3a800cb7628ae8f42adb3d75208", size = 908614, upload-time = "2024-12-17T12:49:42.895Z" }, { url = "https://files.pythonhosted.org/packages/45/bd/8405d03371e335f02eb72e09dcf73307f8fd3095e4165cec6836346fe3db/nh3-0.2.20-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f7d564871833ddbe54df3aa59053b1110729d3a800cb7628ae8f42adb3d75208", size = 908614 },
{ url = "https://files.pythonhosted.org/packages/ee/f8/5d977f09cf82c1f22a864375f471db111530fc79c88efdf0659fe6d3d6bc/nh3-0.2.20-cp313-cp313t-win32.whl", hash = "sha256:d2a176fd4306b6f0f178a3f67fac91bd97a3a8d8fafb771c9b9ef675ba5c8886", size = 540482, upload-time = "2024-12-17T12:49:45.42Z" }, { url = "https://files.pythonhosted.org/packages/ee/f8/5d977f09cf82c1f22a864375f471db111530fc79c88efdf0659fe6d3d6bc/nh3-0.2.20-cp313-cp313t-win32.whl", hash = "sha256:d2a176fd4306b6f0f178a3f67fac91bd97a3a8d8fafb771c9b9ef675ba5c8886", size = 540482 },
{ url = "https://files.pythonhosted.org/packages/c5/f4/e34afe5fd8bed1920eac2974c9c853f548b4b65c139444285ffd2a68495d/nh3-0.2.20-cp313-cp313t-win_amd64.whl", hash = "sha256:6ed834c68452a600f517dd3e1534dbfaff1f67f98899fecf139a055a25d99150", size = 541302, upload-time = "2024-12-17T12:49:48.049Z" }, { url = "https://files.pythonhosted.org/packages/c5/f4/e34afe5fd8bed1920eac2974c9c853f548b4b65c139444285ffd2a68495d/nh3-0.2.20-cp313-cp313t-win_amd64.whl", hash = "sha256:6ed834c68452a600f517dd3e1534dbfaff1f67f98899fecf139a055a25d99150", size = 541302 },
{ url = "https://files.pythonhosted.org/packages/92/08/5e3b61eed1bc0efeb330ddc5cf5194f28a0b7be7943aa20bd44cfe14650b/nh3-0.2.20-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:76e2f603b30c02ff6456b233a83fc377dedab6a50947b04e960a6b905637b776", size = 1202141, upload-time = "2024-12-17T12:49:50.601Z" }, { url = "https://files.pythonhosted.org/packages/92/08/5e3b61eed1bc0efeb330ddc5cf5194f28a0b7be7943aa20bd44cfe14650b/nh3-0.2.20-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:76e2f603b30c02ff6456b233a83fc377dedab6a50947b04e960a6b905637b776", size = 1202141 },
{ url = "https://files.pythonhosted.org/packages/29/d2/3377f8006c71e95e007b07b5bfcac22c9de4744ca3efb23b396d3deb9581/nh3-0.2.20-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:181063c581defe683bd4bb78188ac9936d208aebbc74c7f7c16b6a32ae2ebb38", size = 760699, upload-time = "2024-12-17T12:49:52.833Z" }, { url = "https://files.pythonhosted.org/packages/29/d2/3377f8006c71e95e007b07b5bfcac22c9de4744ca3efb23b396d3deb9581/nh3-0.2.20-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:181063c581defe683bd4bb78188ac9936d208aebbc74c7f7c16b6a32ae2ebb38", size = 760699 },
{ url = "https://files.pythonhosted.org/packages/37/d7/7077f925d7d680d53dcb6e18a4af13d1a7da59761c06c193bfa249a7470a/nh3-0.2.20-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:231addb7643c952cd6d71f1c8702d703f8fe34afcb20becb3efb319a501a12d7", size = 747353, upload-time = "2024-12-17T12:49:54.23Z" }, { url = "https://files.pythonhosted.org/packages/37/d7/7077f925d7d680d53dcb6e18a4af13d1a7da59761c06c193bfa249a7470a/nh3-0.2.20-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:231addb7643c952cd6d71f1c8702d703f8fe34afcb20becb3efb319a501a12d7", size = 747353 },
{ url = "https://files.pythonhosted.org/packages/cb/59/6b2f32af477aae81f1454a7f6ef490ebc3c22dd9e1370e73fcfe243dc07a/nh3-0.2.20-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1b9a8340a0aab991c68a5ca938d35ef4a8a3f4bf1b455da8855a40bee1fa0ace", size = 854125, upload-time = "2024-12-17T12:49:55.481Z" }, { url = "https://files.pythonhosted.org/packages/cb/59/6b2f32af477aae81f1454a7f6ef490ebc3c22dd9e1370e73fcfe243dc07a/nh3-0.2.20-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1b9a8340a0aab991c68a5ca938d35ef4a8a3f4bf1b455da8855a40bee1fa0ace", size = 854125 },
{ url = "https://files.pythonhosted.org/packages/5b/f2/c3d2f7b801477b8b387b51fbefd16dc7ade888aeac547f18ba0558fd6f48/nh3-0.2.20-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10317cd96fe4bbd4eb6b95f3920b71c902157ad44fed103fdcde43e3b8ee8be6", size = 817453, upload-time = "2024-12-17T12:49:58.101Z" }, { url = "https://files.pythonhosted.org/packages/5b/f2/c3d2f7b801477b8b387b51fbefd16dc7ade888aeac547f18ba0558fd6f48/nh3-0.2.20-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10317cd96fe4bbd4eb6b95f3920b71c902157ad44fed103fdcde43e3b8ee8be6", size = 817453 },
{ url = "https://files.pythonhosted.org/packages/42/4d/f7e3a35506a0eba6eedafc21ad52773985511eb838812e9f96354831ad3c/nh3-0.2.20-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8698db4c04b140800d1a1cd3067fda399e36e1e2b8fc1fe04292a907350a3e9b", size = 891694, upload-time = "2024-12-17T12:49:59.91Z" }, { url = "https://files.pythonhosted.org/packages/42/4d/f7e3a35506a0eba6eedafc21ad52773985511eb838812e9f96354831ad3c/nh3-0.2.20-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8698db4c04b140800d1a1cd3067fda399e36e1e2b8fc1fe04292a907350a3e9b", size = 891694 },
{ url = "https://files.pythonhosted.org/packages/e6/0e/c499453c296fb40366e3069cd68fde77a10f0a30a17b9d3b491eb3ebc5bf/nh3-0.2.20-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eb04b9c3deb13c3a375ea39fd4a3c00d1f92e8fb2349f25f1e3e4506751774b", size = 744388, upload-time = "2024-12-17T12:50:02.656Z" }, { url = "https://files.pythonhosted.org/packages/e6/0e/c499453c296fb40366e3069cd68fde77a10f0a30a17b9d3b491eb3ebc5bf/nh3-0.2.20-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3eb04b9c3deb13c3a375ea39fd4a3c00d1f92e8fb2349f25f1e3e4506751774b", size = 744388 },
{ url = "https://files.pythonhosted.org/packages/18/67/c3de8022ba2719bdbbdd3704d1e32dbc7d3f8ac8646247711645fc90d051/nh3-0.2.20-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92f3f1c4f47a2c6f3ca7317b1d5ced05bd29556a75d3a4e2715652ae9d15c05d", size = 764831, upload-time = "2024-12-17T12:50:05.09Z" }, { url = "https://files.pythonhosted.org/packages/18/67/c3de8022ba2719bdbbdd3704d1e32dbc7d3f8ac8646247711645fc90d051/nh3-0.2.20-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:92f3f1c4f47a2c6f3ca7317b1d5ced05bd29556a75d3a4e2715652ae9d15c05d", size = 764831 },
{ url = "https://files.pythonhosted.org/packages/f0/14/a4ea40e2439717d11c3104fc2dc0ac412301b7aeb81d6a3d0e6505c77e7d/nh3-0.2.20-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddefa9fd6794a87e37d05827d299d4b53a3ec6f23258101907b96029bfef138a", size = 923334, upload-time = "2024-12-17T12:50:06.666Z" }, { url = "https://files.pythonhosted.org/packages/f0/14/a4ea40e2439717d11c3104fc2dc0ac412301b7aeb81d6a3d0e6505c77e7d/nh3-0.2.20-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ddefa9fd6794a87e37d05827d299d4b53a3ec6f23258101907b96029bfef138a", size = 923334 },
{ url = "https://files.pythonhosted.org/packages/ed/ae/e8ee8afaf67903dd304f390056d1ea620327524e2ad66127a331b14d5d98/nh3-0.2.20-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ce3731c8f217685d33d9268362e5b4f770914e922bba94d368ab244a59a6c397", size = 994873, upload-time = "2024-12-17T12:50:08.159Z" }, { url = "https://files.pythonhosted.org/packages/ed/ae/e8ee8afaf67903dd304f390056d1ea620327524e2ad66127a331b14d5d98/nh3-0.2.20-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:ce3731c8f217685d33d9268362e5b4f770914e922bba94d368ab244a59a6c397", size = 994873 },
{ url = "https://files.pythonhosted.org/packages/20/b5/02122cfe3b36cf0ba0fcd73a04fd462e1f7a9d91b456f6e0b70e46df21c7/nh3-0.2.20-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:09f037c02fc2c43b211ff1523de32801dcfb0918648d8e651c36ef890f1731ec", size = 915707, upload-time = "2024-12-17T12:50:12.178Z" }, { url = "https://files.pythonhosted.org/packages/20/b5/02122cfe3b36cf0ba0fcd73a04fd462e1f7a9d91b456f6e0b70e46df21c7/nh3-0.2.20-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:09f037c02fc2c43b211ff1523de32801dcfb0918648d8e651c36ef890f1731ec", size = 915707 },
{ url = "https://files.pythonhosted.org/packages/47/d3/5df43cc3570cdc9eb1dc79a39191f89fedf8bcefd8d30a161ff1dffb146c/nh3-0.2.20-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:813f1c8012dd64c990514b795508abb90789334f76a561fa0fd4ca32d2275330", size = 908539, upload-time = "2024-12-17T12:50:16.172Z" }, { url = "https://files.pythonhosted.org/packages/47/d3/5df43cc3570cdc9eb1dc79a39191f89fedf8bcefd8d30a161ff1dffb146c/nh3-0.2.20-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:813f1c8012dd64c990514b795508abb90789334f76a561fa0fd4ca32d2275330", size = 908539 },
{ url = "https://files.pythonhosted.org/packages/4f/fd/aa000f6c76a832c488eac26f20d2e8a221ba2b965efce692f14ebc4290bf/nh3-0.2.20-cp38-abi3-win32.whl", hash = "sha256:47b2946c0e13057855209daeffb45dc910bd0c55daf10190bb0b4b60e2999784", size = 540439, upload-time = "2024-12-17T12:50:18.694Z" }, { url = "https://files.pythonhosted.org/packages/4f/fd/aa000f6c76a832c488eac26f20d2e8a221ba2b965efce692f14ebc4290bf/nh3-0.2.20-cp38-abi3-win32.whl", hash = "sha256:47b2946c0e13057855209daeffb45dc910bd0c55daf10190bb0b4b60e2999784", size = 540439 },
{ url = "https://files.pythonhosted.org/packages/19/31/d65594efd3b42b1de2335d576eb77525691fc320dbf8617948ee05c008e5/nh3-0.2.20-cp38-abi3-win_amd64.whl", hash = "sha256:da87573f03084edae8eb87cfe811ec338606288f81d333c07d2a9a0b9b976c0b", size = 541249, upload-time = "2024-12-17T12:50:20.004Z" }, { url = "https://files.pythonhosted.org/packages/19/31/d65594efd3b42b1de2335d576eb77525691fc320dbf8617948ee05c008e5/nh3-0.2.20-cp38-abi3-win_amd64.whl", hash = "sha256:da87573f03084edae8eb87cfe811ec338606288f81d333c07d2a9a0b9b976c0b", size = 541249 },
] ]
[[package]] [[package]]
name = "odoorpc" name = "odoorpc"
version = "0.10.1" version = "0.10.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/cf/0a/9f907fbfefd2486bb4a3faab03f094f03b300b413004f348a3583ecc1898/OdooRPC-0.10.1.tar.gz", hash = "sha256:d0bc524c5b960781165575bad9c13d032d6f968c3c09276271045ddbbb483aa5", size = 58086, upload-time = "2023-08-16T09:13:42.346Z" } sdist = { url = "https://files.pythonhosted.org/packages/cf/0a/9f907fbfefd2486bb4a3faab03f094f03b300b413004f348a3583ecc1898/OdooRPC-0.10.1.tar.gz", hash = "sha256:d0bc524c5b960781165575bad9c13d032d6f968c3c09276271045ddbbb483aa5", size = 58086 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/20/60/8c5ea2a63151d6c1215e127909eeee3c16e792bbae92ab596dd921d6669d/OdooRPC-0.10.1-py2.py3-none-any.whl", hash = "sha256:a0900bdd5c989c414b1ef40dafccd9363f179312d9166d9486cf70c7c2f0dd44", size = 38482, upload-time = "2023-08-16T09:13:40.8Z" }, { url = "https://files.pythonhosted.org/packages/20/60/8c5ea2a63151d6c1215e127909eeee3c16e792bbae92ab596dd921d6669d/OdooRPC-0.10.1-py2.py3-none-any.whl", hash = "sha256:a0900bdd5c989c414b1ef40dafccd9363f179312d9166d9486cf70c7c2f0dd44", size = 38482 },
] ]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "24.2" version = "24.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 },
] ]
[[package]] [[package]]
name = "pillow" name = "pillow"
version = "11.1.0" version = "11.1.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715, upload-time = "2025-01-02T08:13:58.407Z" } sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640, upload-time = "2025-01-02T08:11:58.329Z" }, { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 },
{ url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437, upload-time = "2025-01-02T08:12:01.797Z" }, { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 },
{ url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605, upload-time = "2025-01-02T08:12:05.224Z" }, { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 },
{ url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173, upload-time = "2025-01-02T08:12:08.281Z" }, { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 },
{ url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145, upload-time = "2025-01-02T08:12:11.411Z" }, { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 },
{ url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340, upload-time = "2025-01-02T08:12:15.29Z" }, { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 },
{ url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906, upload-time = "2025-01-02T08:12:17.485Z" }, { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 },
{ url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759, upload-time = "2025-01-02T08:12:20.382Z" }, { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 },
{ url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657, upload-time = "2025-01-02T08:12:23.922Z" }, { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 },
{ url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304, upload-time = "2025-01-02T08:12:28.069Z" }, { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 },
{ url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117, upload-time = "2025-01-02T08:12:30.064Z" }, { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 },
{ url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060, upload-time = "2025-01-02T08:12:32.362Z" }, { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 },
{ url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192, upload-time = "2025-01-02T08:12:34.361Z" }, { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 },
{ url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805, upload-time = "2025-01-02T08:12:36.99Z" }, { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 },
{ url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623, upload-time = "2025-01-02T08:12:41.912Z" }, { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 },
{ url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191, upload-time = "2025-01-02T08:12:45.186Z" }, { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 },
{ url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494, upload-time = "2025-01-02T08:12:47.098Z" }, { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 },
{ url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595, upload-time = "2025-01-02T08:12:50.47Z" }, { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 },
{ url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651, upload-time = "2025-01-02T08:12:53.356Z" }, { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 },
] ]
[[package]] [[package]]
name = "python-dotenv" name = "python-dotenv"
version = "1.0.1" version = "1.0.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload-time = "2024-01-23T06:33:00.505Z" } sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload-time = "2024-01-23T06:32:58.246Z" }, { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 },
] ]
[[package]] [[package]]
name = "python-monkey-business" name = "python-monkey-business"
version = "1.1.0" version = "1.1.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/21/bc/a6182bb30701d0df25ad336f2dd74343447032e0995025ba82079a94f745/python-monkey-business-1.1.0.tar.gz", hash = "sha256:8393839cc741415ed5ddc2bd58e2d4ce07f966a7d26b7aebff19dcec64818edc", size = 4270, upload-time = "2024-07-11T16:35:00.117Z" } sdist = { url = "https://files.pythonhosted.org/packages/21/bc/a6182bb30701d0df25ad336f2dd74343447032e0995025ba82079a94f745/python-monkey-business-1.1.0.tar.gz", hash = "sha256:8393839cc741415ed5ddc2bd58e2d4ce07f966a7d26b7aebff19dcec64818edc", size = 4270 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/43/a2/b6a5cbd5822b4d049adfedf496ce0908480e5a41722fda7b7ffaacb086d6/python_monkey_business-1.1.0-py2.py3-none-any.whl", hash = "sha256:15b4f603c749ba9a7b4f1acd36af023a6c5ba0f7e591c945f8253f0ef44bf389", size = 4670, upload-time = "2024-07-11T16:34:58.565Z" }, { url = "https://files.pythonhosted.org/packages/43/a2/b6a5cbd5822b4d049adfedf496ce0908480e5a41722fda7b7ffaacb086d6/python_monkey_business-1.1.0-py2.py3-none-any.whl", hash = "sha256:15b4f603c749ba9a7b4f1acd36af023a6c5ba0f7e591c945f8253f0ef44bf389", size = 4670 },
] ]
[[package]] [[package]]
@ -309,7 +309,7 @@ dev = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "django", specifier = ">=5.2" }, { name = "django", specifier = ">=5.1.5" },
{ name = "django-admin-sortable2", specifier = ">=2.2.4" }, { name = "django-admin-sortable2", specifier = ">=2.2.4" },
{ name = "django-browser-reload", marker = "extra == 'dev'", specifier = "~=1.13" }, { name = "django-browser-reload", marker = "extra == 'dev'", specifier = "~=1.13" },
{ name = "django-jazzmin", specifier = ">=3.0.1" }, { name = "django-jazzmin", specifier = ">=3.0.1" },
@ -327,25 +327,25 @@ provides-extras = ["dev"]
name = "sqlparse" name = "sqlparse"
version = "0.5.3" version = "0.5.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999, upload-time = "2024-12-10T12:05:30.728Z" } sdist = { url = "https://files.pythonhosted.org/packages/e5/40/edede8dd6977b0d3da179a342c198ed100dd2aba4be081861ee5911e4da4/sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272", size = 84999 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415, upload-time = "2024-12-10T12:05:27.824Z" }, { url = "https://files.pythonhosted.org/packages/a9/5c/bfd6bd0bf979426d405cc6e71eceb8701b148b16c21d2dc3c261efc61c7b/sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca", size = 44415 },
] ]
[[package]] [[package]]
name = "typing-extensions" name = "typing-extensions"
version = "4.12.2" version = "4.12.2"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 },
] ]
[[package]] [[package]]
name = "tzdata" name = "tzdata"
version = "2025.1" version = "2025.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950, upload-time = "2025-01-21T19:49:38.686Z" } sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762, upload-time = "2025-01-21T19:49:37.187Z" }, { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 },
] ]