Compare commits

...

23 Commits

Author SHA1 Message Date
Dominic R
4518727ace Merge branch 'main' into sdko/source-icon-invert-fix
# Conflicts:
#	web/src/components/ak-page-navbar.ts
2026-04-29 20:12:25 -04:00
Dominic R
7c865de8b1 pffff 2026-04-15 22:07:45 -04:00
Dominic R
b6d6cc2959 fiiiixx 2026-04-15 22:03:44 -04:00
Dominic R
eb4296ea95 regen packages 2026-04-15 21:59:38 -04:00
Dominic R
7cf5b23b02 sigh 2026-04-15 21:57:49 -04:00
Dominic R
ab5c874381 oopsie 2026-04-15 21:57:49 -04:00
Dominic R
e053f934e1 doc 2026-04-15 21:57:49 -04:00
Dominic R
b103cc6738 web: improve source icon and Font Awesome support
Extend fa:// family handling, load Font Awesome Free styles in shadow roots, and document the file picker syntax and supported families.

Co-authored-by: Codex <codex@openai.com>
2026-04-15 21:57:49 -04:00
Dominic R
580641a3f5 web: format icon helpers 2026-04-15 21:57:49 -04:00
Dominic R
50a8c33296 api: restore client makefiles 2026-04-15 21:57:46 -04:00
Dominic R
ee1fabbd91 core: use dynamic icon urls 2026-04-15 21:57:39 -04:00
Dominic R
99110b7403 web: use themed image for icon helpers 2026-04-15 21:57:35 -04:00
Dominic R
a057c37e38 web: share icon rendering helpers 2026-04-15 21:57:35 -04:00
Dominic R
407de7eb93 web: reuse themed icon resolution 2026-04-15 21:57:35 -04:00
Dominic R
2502b4aca4 api: regenerate schema and clients 2026-04-15 21:57:35 -04:00
Dominic R
69c83027a4 web: format type create wizard 2026-04-15 21:57:35 -04:00
Dominic R
a930f82e87 web: stop inverting source icons 2026-04-15 21:57:35 -04:00
Dominic R
fe0f9efddb sources: preserve default icon urls 2026-04-15 21:57:35 -04:00
Dominic R
7c6393a023 sources: convert themed source icons to svg 2026-04-15 21:57:35 -04:00
Dominic R
fecbfef5d1 progress on icons 2026-04-15 21:57:35 -04:00
Dominic R
6bea88f7fd sources: regenerate clients for themed icons 2026-04-15 21:57:32 -04:00
Dominic R
7ba7dc338d sources: add themed source icons 2026-04-15 21:57:23 -04:00
Dominic R
9a85dc459f start working on new implementation 2026-04-15 21:57:23 -04:00
107 changed files with 2274 additions and 474 deletions

View File

@@ -3,7 +3,7 @@ from pathlib import Path
from django.http.request import HttpRequest
from authentik.admin.files.backends.base import Backend
from authentik.admin.files.backends.base import THEME_VARIABLE, Backend
from authentik.admin.files.usage import FileUsage
from authentik.lib.config import CONFIG
@@ -35,6 +35,20 @@ class StaticBackend(Backend):
for file_path in STATIC_ASSETS_SOURCES_DIR.iterdir():
if file_path.is_file() and (file_path.suffix in STATIC_FILE_EXTENSIONS):
yield f"{STATIC_PATH_PREFIX}/authentik/sources/{file_path.name}"
continue
if not file_path.is_dir():
continue
for extension in STATIC_FILE_EXTENSIONS:
light_variant = file_path / f"light{extension}"
dark_variant = file_path / f"dark{extension}"
if light_variant.exists() and dark_variant.exists():
yield (
f"{STATIC_PATH_PREFIX}/authentik/sources/"
f"{file_path.name}/{THEME_VARIABLE}{extension}"
)
break
# List other static assets
for dir in STATIC_ASSETS_DIRS:

View File

@@ -37,6 +37,7 @@ class TestStaticBackend(TestCase):
"""Test list_files includes expected files"""
files = list(self.backend.list_files())
self.assertIn("/static/authentik/sources/github/%(theme)s.svg", files)
self.assertIn("/static/authentik/sources/ldap.png", files)
self.assertIn("/static/authentik/sources/openidconnect.svg", files)
self.assertIn("/static/authentik/sources/saml.png", files)

View File

@@ -219,6 +219,31 @@ class TestFileAPI(FileTestFileBackendMixin, TestCase):
manager.delete_file(file_name)
def test_list_files_includes_themed_urls_for_static_themed_icons(self):
"""Test listing static themed icons exposes a %(theme)s placeholder entry."""
response = self.client.get(
reverse(
"authentik_api:files",
query={
"search": "github/%(theme)s.svg",
},
)
)
self.assertEqual(response.status_code, 200)
self.assertIn(
{
"name": "/static/authentik/sources/github/%(theme)s.svg",
"url": "http://testserver/static/authentik/sources/github/%(theme)s.svg",
"mime_type": "image/svg+xml",
"themed_urls": {
"light": "http://testserver/static/authentik/sources/github/light.svg",
"dark": "http://testserver/static/authentik/sources/github/dark.svg",
},
},
response.data,
)
def test_list_files_includes_themed_urls_dict(self):
"""Test listing files includes themed_urls as dict for themed files"""
manager = FileManager(FileUsage.MEDIA)

View File

@@ -9,7 +9,7 @@ from rest_framework.fields import (
from rest_framework.request import Request
from rest_framework.response import Response
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import DynamicURLSerializer, PassiveSerializer
from authentik.lib.models import DeprecatedMixin
from authentik.lib.utils.reflection import all_subclasses
@@ -22,7 +22,7 @@ class TypeCreateSerializer(PassiveSerializer):
component = CharField(required=True)
model_name = CharField(required=True)
icon_url = CharField(required=False)
icon_url = DynamicURLSerializer(required=False, allow_null=True)
requires_enterprise = BooleanField(default=False)
deprecated = BooleanField(default=False)
@@ -51,7 +51,7 @@ class TypesMixin:
continue
# Circumvent the django protection for not being able to instantiate
# abstract models. We need a model instance to access .component
# and further down .icon_url
# and further down .icon_dynamic_url
instance = subclass.__new__(subclass)
# Django re-sets abstract = False so we need to override that
instance.Meta.abstract = True
@@ -65,7 +65,7 @@ class TypesMixin:
"description": subclass.__doc__,
"component": instance.component,
"model_name": subclass._meta.model_name,
"icon_url": getattr(instance, "icon_url", None),
"icon_url": getattr(instance, "icon_dynamic_url", None),
"requires_enterprise": False,
"deprecated": isinstance(instance, DeprecatedMixin),
}

View File

@@ -14,7 +14,7 @@ from structlog.stdlib import get_logger
from authentik.core.api.object_types import TypesMixin
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import MetaNameSerializer, ModelSerializer, ThemedUrlsSerializer
from authentik.core.api.utils import DynamicURLSerializer, MetaNameSerializer, ModelSerializer
from authentik.core.models import GroupSourceConnection, Source, UserSourceConnection
from authentik.core.types import UserSettingSerializer
from authentik.policies.engine import PolicyEngine
@@ -27,8 +27,7 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer):
managed = ReadOnlyField()
component = SerializerMethodField()
icon_url = ReadOnlyField()
icon_themed_urls = ThemedUrlsSerializer(read_only=True, allow_null=True)
icon_url = DynamicURLSerializer(source="icon_dynamic_url", read_only=True, allow_null=True)
def get_component(self, obj: Source) -> str:
"""Get object component so that we know how to edit the object"""
@@ -58,7 +57,6 @@ class SourceSerializer(ModelSerializer, MetaNameSerializer):
"user_path_template",
"icon",
"icon_url",
"icon_themed_urls",
]

View File

@@ -4,8 +4,8 @@ from typing import Any
from django.db import models
from django.db.models import Model
from drf_spectacular.extensions import OpenApiSerializerFieldExtension
from drf_spectacular.plumbing import build_basic_type
from drf_spectacular.extensions import OpenApiSerializerExtension, OpenApiSerializerFieldExtension
from drf_spectacular.plumbing import build_basic_type, build_object_type
from drf_spectacular.types import OpenApiTypes
from rest_framework.fields import (
CharField,
@@ -129,8 +129,69 @@ class LinkSerializer(PassiveSerializer):
link = CharField()
class ThemedUrlsSerializer(PassiveSerializer):
"""Themed URLs - maps theme names to URLs for light and dark themes"""
def _validate_dynamic_url_map(value: Any) -> dict[str, str | None]:
if not isinstance(value, dict):
raise ValidationError("Value must be a dictionary mapping variant names to URLs.")
light = CharField(required=False, allow_null=True)
dark = CharField(required=False, allow_null=True)
validated = {}
for key, variant_url in value.items():
if not isinstance(key, str):
raise ValidationError("Dynamic URL variant names must be strings.")
if variant_url is not None and not isinstance(variant_url, str):
raise ValidationError(f'Value for "{key}" must be a string or null.')
validated[key] = variant_url
return validated
def _build_dynamic_url_schema(description: str) -> dict[str, Any]:
url_schema = build_basic_type(OpenApiTypes.STR)
url_schema["nullable"] = True
return build_object_type(
description=description,
properties={
"fallback": url_schema.copy(),
},
additionalProperties=url_schema,
)
class DynamicURLSerializerExtension(OpenApiSerializerExtension):
target_class = "authentik.core.api.utils.DynamicURLSerializer"
def get_name(self, auto_schema, direction):
return "DynamicURL"
def map_serializer(self, auto_schema, direction):
return _build_dynamic_url_schema(
"Dynamic URL variants keyed by variant name. Includes a fallback URL."
)
class DynamicURLSerializer(PassiveSerializer):
"""Dynamic URLs keyed by variant name with a generic fallback URL."""
fallback = CharField(required=False, allow_null=True)
def to_internal_value(self, data: Any) -> dict[str, str | None]:
return _validate_dynamic_url_map(data)
def to_representation(self, instance: Any) -> dict[str, str | None] | None:
if instance is None:
return None
return _validate_dynamic_url_map(instance)
class ThemedUrlsSerializerExtension(OpenApiSerializerExtension):
target_class = "authentik.core.api.utils.ThemedUrlsSerializer"
def get_name(self, auto_schema, direction):
return "ThemedUrls"
def map_serializer(self, auto_schema, direction):
return _build_dynamic_url_schema(
"URL variants keyed by theme name. Includes a fallback URL."
)
class ThemedUrlsSerializer(DynamicURLSerializer):
"""Backward-compatible alias for themed URL variants."""

View File

@@ -14,10 +14,12 @@ from django.contrib.auth.hashers import check_password, identify_hasher
from django.contrib.auth.models import AbstractUser, Permission
from django.contrib.auth.models import UserManager as DjangoUserManager
from django.contrib.sessions.base_session import AbstractBaseSession
from django.contrib.staticfiles import finders
from django.core.validators import validate_slug
from django.db import models
from django.db.models import Manager, Q, QuerySet, options
from django.http import HttpRequest
from django.templatetags.static import static
from django.utils.functional import cached_property
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
@@ -29,6 +31,7 @@ from psqlextra.models import PostgresMaterializedViewModel
from rest_framework.serializers import Serializer
from structlog.stdlib import get_logger
from authentik.admin.files.backends.base import THEME_VARIABLE
from authentik.admin.files.fields import FileField
from authentik.admin.files.manager import get_file_manager
from authentik.admin.files.usage import FileUsage
@@ -58,6 +61,49 @@ USER_PATH_SYSTEM_PREFIX = "goauthentik.io"
_USER_ATTR_PREFIX = f"{USER_PATH_SYSTEM_PREFIX}/user"
USER_ATTRIBUTE_DEBUG = f"{_USER_ATTR_PREFIX}/debug"
USER_ATTRIBUTE_GENERATED = f"{_USER_ATTR_PREFIX}/generated"
def _get_default_source_icon_themed_urls(icon_name: str) -> dict[str, str] | None:
themed_paths = {
"light": f"authentik/sources/{icon_name}/light.svg",
"dark": f"authentik/sources/{icon_name}/dark.svg",
}
if all(finders.find(path) for path in themed_paths.values()):
return {theme: static(path) for theme, path in themed_paths.items()}
for extension in ("svg", "png"):
legacy_path = f"authentik/sources/{icon_name}.{extension}"
if finders.find(legacy_path):
legacy_url = static(legacy_path)
return {
"light": legacy_url,
"dark": legacy_url,
}
return None
def _build_dynamic_url_map(
fallback: str | None,
variants: dict[str, str] | None,
) -> dict[str, str] | None:
dynamic_url = dict(variants or {})
if fallback and THEME_VARIABLE in fallback:
fallback = None
resolved_fallback = fallback or dynamic_url.get("light")
if not resolved_fallback and dynamic_url:
resolved_fallback = next((url for url in dynamic_url.values() if url), None)
if resolved_fallback:
dynamic_url["fallback"] = resolved_fallback
return dynamic_url or None
def _get_default_source_icon_url(icon_name: str) -> str | None:
themed_urls = _get_default_source_icon_themed_urls(icon_name)
if themed_urls:
return themed_urls["light"]
return None
USER_ATTRIBUTE_EXPIRES = f"{_USER_ATTR_PREFIX}/expires"
USER_ATTRIBUTE_DELETE_ON_LOGOUT = f"{_USER_ATTR_PREFIX}/delete-on-logout"
USER_ATTRIBUTE_SOURCES = f"{_USER_ATTR_PREFIX}/sources"
@@ -793,6 +839,10 @@ class Application(SerializerModel, PolicyBindingModel):
return get_file_manager(FileUsage.MEDIA).themed_urls(self.meta_icon)
@property
def get_meta_icon_dynamic_url(self) -> dict[str, str] | None:
return _build_dynamic_url_map(self.get_meta_icon, self.get_meta_icon_themed_urls)
def get_launch_url(self, user: User | None = None, user_data: dict | None = None) -> str | None:
"""Get launch URL if set, otherwise attempt to get launch URL based on provider.
@@ -985,34 +1035,52 @@ class Source(ManagedModel, SerializerModel, PolicyBindingModel):
objects = InheritanceManager()
def get_icon_url(self, request=None, use_cache: bool = True) -> str | None:
"""Get the URL to the source icon."""
if not self.icon:
return None
return get_file_manager(FileUsage.MEDIA).file_url(self.icon, request, use_cache=use_cache)
default_icon_name: str | None = None
"""Source type name used to resolve built-in themed icons (e.g. "discord")."""
@property
def icon_url(self) -> str | None:
"""Get the URL to the source icon"""
return self.get_icon_url()
def get_icon_themed_urls(
def icon_url(
self,
request=None,
request: HttpRequest | None = None,
use_cache: bool = True,
) -> str | None:
"""Get the URL to the source icon."""
manager = get_file_manager(FileUsage.MEDIA)
custom_icon = None
try:
custom_icon = self.icon
except AttributeError:
# Abstract type instances (created via __new__) don't have field state.
custom_icon = None
if custom_icon:
return manager.file_url(custom_icon, request, use_cache=use_cache)
if self.default_icon_name:
return _get_default_source_icon_url(self.default_icon_name)
return None
def icon_themed_urls(
self,
request: HttpRequest | None = None,
use_cache: bool = True,
) -> dict[str, str] | None:
"""Get themed URLs for icon if it contains %(theme)s."""
if not self.icon:
return None
return get_file_manager(FileUsage.MEDIA).themed_urls(
self.icon,
request,
use_cache=use_cache,
)
"""Get themed URLs for source icon."""
manager = get_file_manager(FileUsage.MEDIA)
# If the user set a custom icon, check if it supports themes.
custom_icon = None
try:
custom_icon = self.icon
except AttributeError:
# Abstract type instances (created via __new__) don't have field state.
custom_icon = None
if custom_icon:
return manager.themed_urls(custom_icon, request, use_cache=use_cache)
# Fall back to built-in default icons.
if self.default_icon_name:
return _get_default_source_icon_themed_urls(self.default_icon_name)
return None
@property
def icon_themed_urls(self) -> dict[str, str] | None:
return self.get_icon_themed_urls()
def icon_dynamic_url(self) -> dict[str, str] | None:
return _build_dynamic_url_map(self.icon_url(), self.icon_themed_urls())
def get_user_path(self) -> str:
"""Get user path, fallback to default for formatting errors"""

View File

@@ -58,7 +58,7 @@ class TestModels(TestCase):
source = Source(icon="source-icons/icon.svg")
self.assertEqual(
source.get_icon_url(request, use_cache=False),
source.icon_url(request, use_cache=False),
"/files/media/public/source-icons/icon.svg?token=fresh",
)
manager.file_url.assert_called_once_with(
@@ -101,6 +101,17 @@ class TestModels(TestCase):
use_cache=False,
)
def test_source_icon_dynamic_url_uses_resolved_variant_fallback(self):
source = Source(icon="https://example.com/icon-%(theme)s.svg")
self.assertEqual(
source.icon_dynamic_url,
{
"fallback": "https://example.com/icon-light.svg",
"light": "https://example.com/icon-light.svg",
"dark": "https://example.com/icon-dark.svg",
},
)
def source_tester_factory(test_model: type[Source]) -> Callable:
"""Test source"""

View File

@@ -4,7 +4,7 @@ from dataclasses import dataclass
from rest_framework.fields import CharField
from authentik.core.api.utils import PassiveSerializer
from authentik.core.api.utils import DynamicURLSerializer, PassiveSerializer
from authentik.flows.challenge import Challenge
@@ -18,8 +18,8 @@ class UILoginButton:
# Challenge which is presented to the user when they click the button
challenge: Challenge
# Icon URL, used as-is
icon_url: str | None = None
# Pre-resolved icon URLs keyed by variant name, with a fallback URL.
icon_url: dict[str, str | None] | None = None
# Whether this source should be displayed as a prominent button
promoted: bool = False
@@ -32,4 +32,4 @@ class UserSettingSerializer(PassiveSerializer):
component = CharField()
title = CharField(required=True)
configure_url = CharField(required=False)
icon_url = CharField(required=False)
icon_url = DynamicURLSerializer(required=False, allow_null=True)

View File

@@ -11,7 +11,6 @@ import pglock
from django.db import connection, models
from django.http import HttpRequest
from django.shortcuts import reverse
from django.templatetags.static import static
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from kadmin import KAdm5Variant, KAdmin, KAdminApiVersion
@@ -129,12 +128,7 @@ class KerberosSource(IncomingSyncSource):
def property_mapping_type(self) -> type[PropertyMapping]:
return KerberosSourcePropertyMapping
@property
def icon_url(self) -> str:
icon = super().icon_url
if not icon:
return static("authentik/sources/kerberos.png")
return icon
default_icon_name = "kerberos"
@property
def schedule_specs(self) -> list[ScheduleSpec]:
@@ -168,7 +162,7 @@ class KerberosSource(IncomingSyncSource):
}
),
name=self.name,
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
icon_url=self.icon_dynamic_url,
promoted=self.promoted,
)
@@ -181,7 +175,7 @@ class KerberosSource(IncomingSyncSource):
"authentik_sources_kerberos:spnego-login",
kwargs={"source_slug": self.slug},
),
"icon_url": self.icon_url,
"icon_url": self.icon_dynamic_url,
}
)

View File

@@ -9,7 +9,6 @@ from typing import Any
import pglock
from django.db import connection, models
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from ldap3 import ALL, NONE, RANDOM, Connection, Server, ServerPool, Tls
from ldap3.core.exceptions import (
@@ -217,9 +216,7 @@ class LDAPSource(IncomingSyncSource):
**kwargs,
)
@property
def icon_url(self) -> str:
return static("authentik/sources/ldap.png")
default_icon_name = "ldap"
def server(self, **kwargs) -> ServerPool:
"""Get LDAP Server/ServerPool"""

View File

@@ -15,6 +15,8 @@ from authentik.core.models import (
PropertyMapping,
Source,
UserSourceConnection,
_get_default_source_icon_themed_urls,
_get_default_source_icon_url,
)
from authentik.core.types import UILoginButton, UserSettingSerializer
@@ -111,24 +113,46 @@ class OAuthSource(NonCreatableType, Source):
def get_base_group_properties(self, **kwargs):
return self.source_type().get_base_group_properties(source=self, **kwargs)
@property
def icon_url(self) -> str | None:
# When listing source types, this property might be retrieved from an abstract
# model. In that case we can't check self.provider_type or self.icon_url
# and as such we attempt to find the correct provider type based on the mode name
if self.Meta.abstract:
from authentik.sources.oauth.types.registry import registry
def icon_themed_urls(
self,
request: HttpRequest | None = None,
use_cache: bool = True,
) -> dict[str, str] | None:
"""Get themed URLs for source icon.
provider_type = registry.find_type(
self._meta.model_name.replace(OAuthSource._meta.model_name, "")
)
return provider_type().icon_url()
icon = super().icon_url
if not icon:
provider_type = self.source_type
provider = provider_type()
icon = provider.icon_url()
return icon
OAuth source types are abstract models so the DB always stores OAuthSource
instances. We resolve the built-in icon from the provider_type field instead
of the class-level default_icon_name (which only exists on the abstract
subclasses used by the TypeCreate wizard).
"""
urls = super().icon_themed_urls(request=request, use_cache=use_cache)
if urls:
return urls
try:
provider_type = self.provider_type
except AttributeError:
# Gracefully fall back when provider icon metadata is unavailable.
return None
if provider_type:
return _get_default_source_icon_themed_urls(provider_type)
return None
def icon_url(
self,
request: HttpRequest | None = None,
use_cache: bool = True,
) -> str | None:
icon = super().icon_url(request=request, use_cache=use_cache)
if icon:
return icon
try:
provider_type = self.provider_type
except AttributeError:
# Gracefully fall back when provider icon metadata is unavailable.
return None
if provider_type:
return _get_default_source_icon_url(provider_type)
return None
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
provider_type = self.source_type
@@ -136,7 +160,7 @@ class OAuthSource(NonCreatableType, Source):
return UILoginButton(
name=self.name,
challenge=provider.login_challenge(self, request),
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
icon_url=self.icon_dynamic_url,
promoted=self.promoted,
)
@@ -149,7 +173,7 @@ class OAuthSource(NonCreatableType, Source):
"authentik_sources_oauth:oauth-client-login",
kwargs={"source_slug": self.slug},
),
"icon_url": self.icon_url,
"icon_url": self.icon_dynamic_url,
}
)
@@ -164,6 +188,8 @@ class OAuthSource(NonCreatableType, Source):
class GitHubOAuthSource(CreatableType, OAuthSource):
"""Social Login using GitHub.com or a GitHub-Enterprise Instance."""
default_icon_name = "github"
class Meta:
abstract = True
verbose_name = _("GitHub OAuth Source")
@@ -173,6 +199,8 @@ class GitHubOAuthSource(CreatableType, OAuthSource):
class GitLabOAuthSource(CreatableType, OAuthSource):
"""Social Login using GitLab.com or a GitLab Instance."""
default_icon_name = "gitlab"
class Meta:
abstract = True
verbose_name = _("GitLab OAuth Source")
@@ -182,6 +210,8 @@ class GitLabOAuthSource(CreatableType, OAuthSource):
class TwitchOAuthSource(CreatableType, OAuthSource):
"""Social Login using Twitch."""
default_icon_name = "twitch"
class Meta:
abstract = True
verbose_name = _("Twitch OAuth Source")
@@ -191,6 +221,8 @@ class TwitchOAuthSource(CreatableType, OAuthSource):
class MailcowOAuthSource(CreatableType, OAuthSource):
"""Social Login using Mailcow."""
default_icon_name = "mailcow"
class Meta:
abstract = True
verbose_name = _("Mailcow OAuth Source")
@@ -200,6 +232,8 @@ class MailcowOAuthSource(CreatableType, OAuthSource):
class TwitterOAuthSource(CreatableType, OAuthSource):
"""Social Login using Twitter.com"""
default_icon_name = "twitter"
class Meta:
abstract = True
verbose_name = _("Twitter OAuth Source")
@@ -209,6 +243,8 @@ class TwitterOAuthSource(CreatableType, OAuthSource):
class FacebookOAuthSource(CreatableType, OAuthSource):
"""Social Login using Facebook.com."""
default_icon_name = "facebook"
class Meta:
abstract = True
verbose_name = _("Facebook OAuth Source")
@@ -218,6 +254,8 @@ class FacebookOAuthSource(CreatableType, OAuthSource):
class DiscordOAuthSource(CreatableType, OAuthSource):
"""Social Login using Discord."""
default_icon_name = "discord"
class Meta:
abstract = True
verbose_name = _("Discord OAuth Source")
@@ -227,6 +265,8 @@ class DiscordOAuthSource(CreatableType, OAuthSource):
class SlackOAuthSource(CreatableType, OAuthSource):
"""Social Login using Slack."""
default_icon_name = "slack"
class Meta:
abstract = True
verbose_name = _("Slack OAuth Source")
@@ -236,6 +276,8 @@ class SlackOAuthSource(CreatableType, OAuthSource):
class PatreonOAuthSource(CreatableType, OAuthSource):
"""Social Login using Patreon."""
default_icon_name = "patreon"
class Meta:
abstract = True
verbose_name = _("Patreon OAuth Source")
@@ -245,6 +287,8 @@ class PatreonOAuthSource(CreatableType, OAuthSource):
class GoogleOAuthSource(CreatableType, OAuthSource):
"""Social Login using Google or Google Workspace (GSuite)."""
default_icon_name = "google"
class Meta:
abstract = True
verbose_name = _("Google OAuth Source")
@@ -254,6 +298,8 @@ class GoogleOAuthSource(CreatableType, OAuthSource):
class AzureADOAuthSource(CreatableType, OAuthSource):
"""(Deprecated) Social Login using Azure AD."""
default_icon_name = "azuread"
class Meta:
abstract = True
verbose_name = _("Azure AD OAuth Source")
@@ -265,6 +311,8 @@ class AzureADOAuthSource(CreatableType, OAuthSource):
class EntraIDOAuthSource(CreatableType, OAuthSource):
"""Social Login using Entra ID."""
default_icon_name = "entraid"
class Meta:
abstract = True
verbose_name = _("Entra ID OAuth Source")
@@ -274,6 +322,8 @@ class EntraIDOAuthSource(CreatableType, OAuthSource):
class OpenIDConnectOAuthSource(CreatableType, OAuthSource):
"""Login using a Generic OpenID-Connect compliant provider."""
default_icon_name = "openidconnect"
class Meta:
abstract = True
verbose_name = _("OpenID OAuth Source")
@@ -283,6 +333,8 @@ class OpenIDConnectOAuthSource(CreatableType, OAuthSource):
class AppleOAuthSource(CreatableType, OAuthSource):
"""Social Login using Apple."""
default_icon_name = "apple"
class Meta:
abstract = True
verbose_name = _("Apple OAuth Source")
@@ -292,6 +344,8 @@ class AppleOAuthSource(CreatableType, OAuthSource):
class OktaOAuthSource(CreatableType, OAuthSource):
"""Social Login using Okta."""
default_icon_name = "okta"
class Meta:
abstract = True
verbose_name = _("Okta OAuth Source")
@@ -301,6 +355,8 @@ class OktaOAuthSource(CreatableType, OAuthSource):
class RedditOAuthSource(CreatableType, OAuthSource):
"""Social Login using reddit.com."""
default_icon_name = "reddit"
class Meta:
abstract = True
verbose_name = _("Reddit OAuth Source")
@@ -310,6 +366,8 @@ class RedditOAuthSource(CreatableType, OAuthSource):
class WeChatOAuthSource(CreatableType, OAuthSource):
"""Social Login using WeChat."""
default_icon_name = "wechat"
class Meta:
abstract = True
verbose_name = _("WeChat OAuth Source")

View File

@@ -5,7 +5,6 @@ from enum import Enum
from typing import Any
from django.http.request import HttpRequest
from django.templatetags.static import static
from django.urls.base import reverse
from structlog.stdlib import get_logger
@@ -46,10 +45,6 @@ class SourceType:
AuthorizationCodeAuthMethod.BASIC_AUTH
)
def icon_url(self) -> str:
"""Get Icon URL for login"""
return static(f"authentik/sources/{self.name}.svg")
def login_challenge(self, source: OAuthSource, request: HttpRequest) -> Challenge:
"""Allow types to return custom challenges"""
return RedirectChallenge(

View File

@@ -5,7 +5,6 @@ from typing import Any
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.http.request import HttpRequest
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from rest_framework.fields import CharField
from rest_framework.serializers import BaseSerializer, Serializer
@@ -100,12 +99,7 @@ class PlexSource(ScheduledModel, Source):
"name": group_id,
}
@property
def icon_url(self) -> str:
icon = super().icon_url
if not icon:
icon = static("authentik/sources/plex.svg")
return icon
default_icon_name = "plex"
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
return UILoginButton(
@@ -116,7 +110,7 @@ class PlexSource(ScheduledModel, Source):
"slug": self.slug,
}
),
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
icon_url=self.icon_dynamic_url,
name=self.name,
promoted=self.promoted,
)
@@ -127,7 +121,7 @@ class PlexSource(ScheduledModel, Source):
"title": self.name,
"component": "ak-user-settings-source-plex",
"configure_url": self.client_id,
"icon_url": self.icon_url,
"icon_url": self.icon_dynamic_url,
}
)

View File

@@ -4,7 +4,6 @@ from typing import Any
from django.db import models
from django.http import HttpRequest
from django.templatetags.static import static
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from lxml.etree import _Element # nosec
@@ -266,12 +265,7 @@ class SAMLSource(Source):
reverse(f"authentik_sources_saml:{view}", kwargs={"source_slug": self.slug})
)
@property
def icon_url(self) -> str:
icon = super().icon_url
if not icon:
return static("authentik/sources/saml.png")
return icon
default_icon_name = "saml"
def ui_login_button(self, request: HttpRequest) -> UILoginButton:
return UILoginButton(
@@ -284,7 +278,7 @@ class SAMLSource(Source):
}
),
name=self.name,
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
icon_url=self.icon_dynamic_url,
promoted=self.promoted,
)
@@ -297,7 +291,7 @@ class SAMLSource(Source):
"authentik_sources_saml:login",
kwargs={"source_slug": self.slug},
),
"icon_url": self.icon_url,
"icon_url": self.icon_dynamic_url,
}
)

View File

@@ -4,7 +4,6 @@ from typing import Any
from uuid import uuid4
from django.db import models
from django.templatetags.static import static
from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import BaseSerializer, Serializer
@@ -27,9 +26,7 @@ class SCIMSource(Source):
"""Return component used to edit this object"""
return "ak-source-scim-form"
@property
def icon_url(self) -> str:
return static("authentik/sources/scim.png")
default_icon_name = "scim"
@property
def serializer(self) -> BaseSerializer:

View File

@@ -5,7 +5,6 @@ from urllib.parse import urlencode
from django.db import models
from django.http import HttpRequest
from django.templatetags.static import static
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import BaseSerializer, Serializer
@@ -42,12 +41,7 @@ class TelegramSource(Source):
def component(self) -> str:
return "ak-source-telegram-form"
@property
def icon_url(self) -> str | None:
icon = super().icon_url
if not icon:
icon = static("authentik/sources/telegram.svg")
return icon
default_icon_name = "telegram"
@property
def serializer(self) -> type[BaseSerializer]:
@@ -66,7 +60,7 @@ class TelegramSource(Source):
}
),
name=self.name,
icon_url=self.get_icon_url(request, use_cache=False) or self.icon_url,
icon_url=self.icon_dynamic_url,
promoted=self.promoted,
)
@@ -75,7 +69,7 @@ class TelegramSource(Source):
data={
"title": self.name,
"component": "ak-user-settings-source-telegram",
"icon_url": self.icon_url,
"icon_url": self.icon_dynamic_url,
"configure_url": urlencode(
{
"bot_username": self.bot_username,

View File

@@ -14,7 +14,7 @@ from rest_framework.fields import BooleanField, CharField, ChoiceField, DictFiel
from rest_framework.serializers import ValidationError
from sentry_sdk import start_span
from authentik.core.api.utils import JSONDictField, PassiveSerializer
from authentik.core.api.utils import DynamicURLSerializer, JSONDictField, PassiveSerializer
from authentik.core.models import Application, Source, User
from authentik.endpoints.connectors.agent.stage import PLAN_CONTEXT_DEVICE_AUTH_TOKEN
from authentik.endpoints.models import Device
@@ -84,7 +84,7 @@ class LoginSourceSerializer(PassiveSerializer):
"""Serializer for Login buttons of sources"""
name = CharField()
icon_url = CharField(required=False, allow_null=True)
icon_url = DynamicURLSerializer(required=False, allow_null=True)
promoted = BooleanField(default=False)
challenge = ChallengeDictWrapper()

View File

@@ -206,7 +206,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -242,7 +242,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -317,7 +317,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -373,7 +373,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -436,7 +436,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -481,7 +481,7 @@ class TestIdentificationStage(FlowTestCase):
primary_action="Log in",
sources=[
{
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"challenge": {
"component": "xak-flow-redirect",
@@ -523,7 +523,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}
@@ -551,7 +551,7 @@ class TestIdentificationStage(FlowTestCase):
"component": "xak-flow-redirect",
"to": f"/source/oauth/login/{self.source.slug}/",
},
"icon_url": "/static/authentik/sources/default.svg",
"icon_url": None,
"name": self.source.name,
"promoted": False,
}

View File

@@ -5,6 +5,14 @@ asgi
azuread
Azuread
buildx
fass
fasdl
fasdr
fasds
fasdt
fasl
fasr
fast
goauthentik
lxml
pässwörd

165
packages/client-go/model_dynamic_url.go generated Normal file
View File

@@ -0,0 +1,165 @@
/*
authentik
Making authentication simple.
API version: 2026.5.0-rc1
Contact: hello@goauthentik.io
*/
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
package api
import (
"encoding/json"
)
// checks if the DynamicURL type satisfies the MappedNullable interface at compile time
var _ MappedNullable = &DynamicURL{}
// DynamicURL Dynamic URL variants keyed by variant name. Includes a fallback URL.
type DynamicURL struct {
Fallback NullableString `json:"fallback,omitempty"`
AdditionalProperties map[string]interface{}
}
type _DynamicURL DynamicURL
// NewDynamicURL instantiates a new DynamicURL object
// This constructor will assign default values to properties that have it defined,
// and makes sure properties required by API are set, but the set of arguments
// will change when the set of required properties is changed
func NewDynamicURL() *DynamicURL {
this := DynamicURL{}
return &this
}
// NewDynamicURLWithDefaults instantiates a new DynamicURL object
// This constructor will only assign default values to properties that have it defined,
// but it doesn't guarantee that properties required by API are set
func NewDynamicURLWithDefaults() *DynamicURL {
this := DynamicURL{}
return &this
}
// GetFallback returns the Fallback field value if set, zero value otherwise (both if not set or set to explicit null).
func (o *DynamicURL) GetFallback() string {
if o == nil || IsNil(o.Fallback.Get()) {
var ret string
return ret
}
return *o.Fallback.Get()
}
// GetFallbackOk returns a tuple with the Fallback field value if set, nil otherwise
// and a boolean to check if the value has been set.
// NOTE: If the value is an explicit nil, `nil, true` will be returned
func (o *DynamicURL) GetFallbackOk() (*string, bool) {
if o == nil {
return nil, false
}
return o.Fallback.Get(), o.Fallback.IsSet()
}
// HasFallback returns a boolean if a field has been set.
func (o *DynamicURL) HasFallback() bool {
if o != nil && o.Fallback.IsSet() {
return true
}
return false
}
// SetFallback gets a reference to the given NullableString and assigns it to the Fallback field.
func (o *DynamicURL) SetFallback(v string) {
o.Fallback.Set(&v)
}
// SetFallbackNil sets the value for Fallback to be an explicit nil
func (o *DynamicURL) SetFallbackNil() {
o.Fallback.Set(nil)
}
// UnsetFallback ensures that no value is present for Fallback, not even an explicit nil
func (o *DynamicURL) UnsetFallback() {
o.Fallback.Unset()
}
func (o DynamicURL) MarshalJSON() ([]byte, error) {
toSerialize, err := o.ToMap()
if err != nil {
return []byte{}, err
}
return json.Marshal(toSerialize)
}
func (o DynamicURL) ToMap() (map[string]interface{}, error) {
toSerialize := map[string]interface{}{}
if o.Fallback.IsSet() {
toSerialize["fallback"] = o.Fallback.Get()
}
for key, value := range o.AdditionalProperties {
toSerialize[key] = value
}
return toSerialize, nil
}
func (o *DynamicURL) UnmarshalJSON(data []byte) (err error) {
varDynamicURL := _DynamicURL{}
err = json.Unmarshal(data, &varDynamicURL)
if err != nil {
return err
}
*o = DynamicURL(varDynamicURL)
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(data, &additionalProperties); err == nil {
delete(additionalProperties, "fallback")
o.AdditionalProperties = additionalProperties
}
return err
}
type NullableDynamicURL struct {
value *DynamicURL
isSet bool
}
func (v NullableDynamicURL) Get() *DynamicURL {
return v.value
}
func (v *NullableDynamicURL) Set(val *DynamicURL) {
v.value = val
v.isSet = true
}
func (v NullableDynamicURL) IsSet() bool {
return v.isSet
}
func (v *NullableDynamicURL) Unset() {
v.value = nil
v.isSet = false
}
func NewNullableDynamicURL(val *DynamicURL) *NullableDynamicURL {
return &NullableDynamicURL{value: val, isSet: true}
}
func (v NullableDynamicURL) MarshalJSON() ([]byte, error) {
return json.Marshal(v.value)
}
func (v *NullableDynamicURL) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@@ -22,7 +22,7 @@ var _ MappedNullable = &LoginSource{}
// LoginSource Serializer for Login buttons of sources
type LoginSource struct {
Name string `json:"name"`
IconUrl NullableString `json:"icon_url,omitempty"`
IconUrl NullableDynamicURL `json:"icon_url,omitempty"`
Promoted *bool `json:"promoted,omitempty"`
Challenge LoginChallengeTypes `json:"challenge"`
AdditionalProperties map[string]interface{}
@@ -78,9 +78,9 @@ func (o *LoginSource) SetName(v string) {
}
// GetIconUrl returns the IconUrl field value if set, zero value otherwise (both if not set or set to explicit null).
func (o *LoginSource) GetIconUrl() string {
func (o *LoginSource) GetIconUrl() DynamicURL {
if o == nil || IsNil(o.IconUrl.Get()) {
var ret string
var ret DynamicURL
return ret
}
return *o.IconUrl.Get()
@@ -89,7 +89,7 @@ func (o *LoginSource) GetIconUrl() string {
// GetIconUrlOk returns a tuple with the IconUrl field value if set, nil otherwise
// and a boolean to check if the value has been set.
// NOTE: If the value is an explicit nil, `nil, true` will be returned
func (o *LoginSource) GetIconUrlOk() (*string, bool) {
func (o *LoginSource) GetIconUrlOk() (*DynamicURL, bool) {
if o == nil {
return nil, false
}
@@ -105,8 +105,8 @@ func (o *LoginSource) HasIconUrl() bool {
return false
}
// SetIconUrl gets a reference to the given NullableString and assigns it to the IconUrl field.
func (o *LoginSource) SetIconUrl(v string) {
// SetIconUrl gets a reference to the given NullableDynamicURL and assigns it to the IconUrl field.
func (o *LoginSource) SetIconUrl(v DynamicURL) {
o.IconUrl.Set(&v)
}

View File

@@ -18,10 +18,9 @@ import (
// checks if the ThemedUrls type satisfies the MappedNullable interface at compile time
var _ MappedNullable = &ThemedUrls{}
// ThemedUrls Themed URLs - maps theme names to URLs for light and dark themes
// ThemedUrls URL variants keyed by theme name. Includes a fallback URL.
type ThemedUrls struct {
Light NullableString `json:"light,omitempty"`
Dark NullableString `json:"dark,omitempty"`
Fallback NullableString `json:"fallback,omitempty"`
AdditionalProperties map[string]interface{}
}
@@ -44,90 +43,47 @@ func NewThemedUrlsWithDefaults() *ThemedUrls {
return &this
}
// GetLight returns the Light field value if set, zero value otherwise (both if not set or set to explicit null).
func (o *ThemedUrls) GetLight() string {
if o == nil || IsNil(o.Light.Get()) {
// GetFallback returns the Fallback field value if set, zero value otherwise (both if not set or set to explicit null).
func (o *ThemedUrls) GetFallback() string {
if o == nil || IsNil(o.Fallback.Get()) {
var ret string
return ret
}
return *o.Light.Get()
return *o.Fallback.Get()
}
// GetLightOk returns a tuple with the Light field value if set, nil otherwise
// GetFallbackOk returns a tuple with the Fallback field value if set, nil otherwise
// and a boolean to check if the value has been set.
// NOTE: If the value is an explicit nil, `nil, true` will be returned
func (o *ThemedUrls) GetLightOk() (*string, bool) {
func (o *ThemedUrls) GetFallbackOk() (*string, bool) {
if o == nil {
return nil, false
}
return o.Light.Get(), o.Light.IsSet()
return o.Fallback.Get(), o.Fallback.IsSet()
}
// HasLight returns a boolean if a field has been set.
func (o *ThemedUrls) HasLight() bool {
if o != nil && o.Light.IsSet() {
// HasFallback returns a boolean if a field has been set.
func (o *ThemedUrls) HasFallback() bool {
if o != nil && o.Fallback.IsSet() {
return true
}
return false
}
// SetLight gets a reference to the given NullableString and assigns it to the Light field.
func (o *ThemedUrls) SetLight(v string) {
o.Light.Set(&v)
// SetFallback gets a reference to the given NullableString and assigns it to the Fallback field.
func (o *ThemedUrls) SetFallback(v string) {
o.Fallback.Set(&v)
}
// SetLightNil sets the value for Light to be an explicit nil
func (o *ThemedUrls) SetLightNil() {
o.Light.Set(nil)
// SetFallbackNil sets the value for Fallback to be an explicit nil
func (o *ThemedUrls) SetFallbackNil() {
o.Fallback.Set(nil)
}
// UnsetLight ensures that no value is present for Light, not even an explicit nil
func (o *ThemedUrls) UnsetLight() {
o.Light.Unset()
}
// GetDark returns the Dark field value if set, zero value otherwise (both if not set or set to explicit null).
func (o *ThemedUrls) GetDark() string {
if o == nil || IsNil(o.Dark.Get()) {
var ret string
return ret
}
return *o.Dark.Get()
}
// GetDarkOk returns a tuple with the Dark field value if set, nil otherwise
// and a boolean to check if the value has been set.
// NOTE: If the value is an explicit nil, `nil, true` will be returned
func (o *ThemedUrls) GetDarkOk() (*string, bool) {
if o == nil {
return nil, false
}
return o.Dark.Get(), o.Dark.IsSet()
}
// HasDark returns a boolean if a field has been set.
func (o *ThemedUrls) HasDark() bool {
if o != nil && o.Dark.IsSet() {
return true
}
return false
}
// SetDark gets a reference to the given NullableString and assigns it to the Dark field.
func (o *ThemedUrls) SetDark(v string) {
o.Dark.Set(&v)
}
// SetDarkNil sets the value for Dark to be an explicit nil
func (o *ThemedUrls) SetDarkNil() {
o.Dark.Set(nil)
}
// UnsetDark ensures that no value is present for Dark, not even an explicit nil
func (o *ThemedUrls) UnsetDark() {
o.Dark.Unset()
// UnsetFallback ensures that no value is present for Fallback, not even an explicit nil
func (o *ThemedUrls) UnsetFallback() {
o.Fallback.Unset()
}
func (o ThemedUrls) MarshalJSON() ([]byte, error) {
@@ -140,11 +96,8 @@ func (o ThemedUrls) MarshalJSON() ([]byte, error) {
func (o ThemedUrls) ToMap() (map[string]interface{}, error) {
toSerialize := map[string]interface{}{}
if o.Light.IsSet() {
toSerialize["light"] = o.Light.Get()
}
if o.Dark.IsSet() {
toSerialize["dark"] = o.Dark.Get()
if o.Fallback.IsSet() {
toSerialize["fallback"] = o.Fallback.Get()
}
for key, value := range o.AdditionalProperties {
@@ -168,8 +121,7 @@ func (o *ThemedUrls) UnmarshalJSON(data []byte) (err error) {
additionalProperties := make(map[string]interface{})
if err = json.Unmarshal(data, &additionalProperties); err == nil {
delete(additionalProperties, "light")
delete(additionalProperties, "dark")
delete(additionalProperties, "fallback")
o.AdditionalProperties = additionalProperties
}

View File

@@ -0,0 +1,30 @@
// authentik
//
// Making authentication simple.
//
// The version of the OpenAPI document: 2026.5.0-rc1
// Contact: hello@goauthentik.io
// Generated by: https://openapi-generator.tech
use serde::{Deserialize, Serialize};
use crate::models;
/// DynamicUrl : Dynamic URL variants keyed by variant name. Includes a fallback URL.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct DynamicUrl {
#[serde(
rename = "fallback",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub fallback: Option<Option<String>>,
}
impl DynamicUrl {
/// Dynamic URL variants keyed by variant name. Includes a fallback URL.
pub fn new() -> DynamicUrl {
DynamicUrl { fallback: None }
}
}

View File

@@ -21,7 +21,7 @@ pub struct LoginSource {
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub icon_url: Option<Option<String>>,
pub icon_url: Option<Option<models::DynamicUrl>>,
#[serde(rename = "promoted", skip_serializing_if = "Option::is_none")]
pub promoted: Option<bool>,
#[serde(rename = "challenge")]

View File

@@ -74,6 +74,8 @@ pub mod dummy_challenge;
pub use self::dummy_challenge::DummyChallenge;
pub mod dummy_challenge_response_request;
pub use self::dummy_challenge_response_request::DummyChallengeResponseRequest;
pub mod dynamic_url;
pub use self::dynamic_url::DynamicUrl;
pub mod email_challenge;
pub use self::email_challenge::EmailChallenge;
pub mod email_challenge_response_request;

View File

@@ -10,31 +10,21 @@ use serde::{Deserialize, Serialize};
use crate::models;
/// ThemedUrls : Themed URLs - maps theme names to URLs for light and dark themes
/// ThemedUrls : URL variants keyed by theme name. Includes a fallback URL.
#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct ThemedUrls {
#[serde(
rename = "light",
rename = "fallback",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub light: Option<Option<String>>,
#[serde(
rename = "dark",
default,
with = "::serde_with::rust::double_option",
skip_serializing_if = "Option::is_none"
)]
pub dark: Option<Option<String>>,
pub fallback: Option<Option<String>>,
}
impl ThemedUrls {
/// Themed URLs - maps theme names to URLs for light and dark themes
/// URL variants keyed by theme name. Includes a fallback URL.
pub fn new() -> ThemedUrls {
ThemedUrls {
light: None,
dark: None,
}
ThemedUrls { fallback: None }
}
}

View File

@@ -0,0 +1,67 @@
/* tslint:disable */
/* eslint-disable */
/**
* authentik
* Making authentication simple.
*
* The version of the OpenAPI document: 2026.5.0-rc1
* Contact: hello@goauthentik.io
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/**
* Dynamic URL variants keyed by variant name. Includes a fallback URL.
* @export
* @interface DynamicURL
*/
export interface DynamicURL {
[key: string]: string | any;
/**
*
* @type {string}
* @memberof DynamicURL
*/
fallback?: string | null;
}
/**
* Check if a given object implements the DynamicURL interface.
*/
export function instanceOfDynamicURL(value: object): value is DynamicURL {
return true;
}
export function DynamicURLFromJSON(json: any): DynamicURL {
return DynamicURLFromJSONTyped(json, false);
}
export function DynamicURLFromJSONTyped(json: any, ignoreDiscriminator: boolean): DynamicURL {
if (json == null) {
return json;
}
return {
...json,
fallback: json["fallback"] == null ? undefined : json["fallback"],
};
}
export function DynamicURLToJSON(json: any): DynamicURL {
return DynamicURLToJSONTyped(json, false);
}
export function DynamicURLToJSONTyped(
value?: DynamicURL | null,
ignoreDiscriminator: boolean = false,
): any {
if (value == null) {
return value;
}
return {
...value,
fallback: value["fallback"],
};
}

View File

@@ -12,6 +12,8 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { GroupMatchingModeEnum } from "./GroupMatchingModeEnum";
import {
GroupMatchingModeEnumFromJSON,
@@ -26,8 +28,6 @@ import {
SyncOutgoingTriggerModeEnumFromJSON,
SyncOutgoingTriggerModeEnumToJSON,
} from "./SyncOutgoingTriggerModeEnum";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -147,16 +147,10 @@ export interface KerberosSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof KerberosSource
*/
readonly iconUrl: string;
/**
*
* @type {ThemedUrls}
* @memberof KerberosSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
* How the source determines if an existing group should be used or a new group created.
* @type {GroupMatchingModeEnum}
@@ -250,7 +244,6 @@ export function instanceOfKerberosSource(value: object): value is KerberosSource
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("realm" in value) || value["realm"] === undefined) return false;
if (!("connectivity" in value) || value["connectivity"] === undefined) return false;
return true;
@@ -296,8 +289,7 @@ export function KerberosSourceFromJSONTyped(
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
groupMatchingMode:
json["group_matching_mode"] == null
? undefined
@@ -340,7 +332,6 @@ export function KerberosSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
| "connectivity"
> | null,
ignoreDiscriminator: boolean = false,

View File

@@ -12,6 +12,8 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { PolicyEngineMode } from "./PolicyEngineMode";
import { PolicyEngineModeFromJSON, PolicyEngineModeToJSON } from "./PolicyEngineMode";
import type { SyncOutgoingTriggerModeEnum } from "./SyncOutgoingTriggerModeEnum";
@@ -19,8 +21,6 @@ import {
SyncOutgoingTriggerModeEnumFromJSON,
SyncOutgoingTriggerModeEnumToJSON,
} from "./SyncOutgoingTriggerModeEnum";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -140,16 +140,10 @@ export interface LDAPSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof LDAPSource
*/
readonly iconUrl: string;
/**
*
* @type {ThemedUrls}
* @memberof LDAPSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
*
* @type {string}
@@ -303,7 +297,6 @@ export function instanceOfLDAPSource(value: object): value is LDAPSource {
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("serverUri" in value) || value["serverUri"] === undefined) return false;
if (!("baseDn" in value) || value["baseDn"] === undefined) return false;
if (!("connectivity" in value) || value["connectivity"] === undefined) return false;
@@ -347,8 +340,7 @@ export function LDAPSourceFromJSONTyped(json: any, ignoreDiscriminator: boolean)
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
serverUri: json["server_uri"],
peerCertificate: json["peer_certificate"] == null ? undefined : json["peer_certificate"],
clientCertificate:
@@ -408,7 +400,6 @@ export function LDAPSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
| "connectivity"
> | null,
ignoreDiscriminator: boolean = false,

View File

@@ -12,6 +12,8 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON, DynamicURLToJSON } from "./DynamicURL";
import type { LoginChallengeTypes } from "./LoginChallengeTypes";
import { LoginChallengeTypesFromJSON, LoginChallengeTypesToJSON } from "./LoginChallengeTypes";
@@ -29,10 +31,10 @@ export interface LoginSource {
name: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof LoginSource
*/
iconUrl?: string | null;
iconUrl?: DynamicURL | null;
/**
*
* @type {boolean}
@@ -66,7 +68,7 @@ export function LoginSourceFromJSONTyped(json: any, ignoreDiscriminator: boolean
}
return {
name: json["name"],
iconUrl: json["icon_url"] == null ? undefined : json["icon_url"],
iconUrl: json["icon_url"] == null ? undefined : DynamicURLFromJSON(json["icon_url"]),
promoted: json["promoted"] == null ? undefined : json["promoted"],
challenge: LoginChallengeTypesFromJSON(json["challenge"]),
};
@@ -86,7 +88,7 @@ export function LoginSourceToJSONTyped(
return {
name: value["name"],
icon_url: value["iconUrl"],
icon_url: DynamicURLToJSON(value["iconUrl"]),
promoted: value["promoted"],
challenge: LoginChallengeTypesToJSON(value["challenge"]),
};

View File

@@ -17,6 +17,8 @@ import {
AuthorizationCodeAuthMethodEnumFromJSON,
AuthorizationCodeAuthMethodEnumToJSON,
} from "./AuthorizationCodeAuthMethodEnum";
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { GroupMatchingModeEnum } from "./GroupMatchingModeEnum";
import {
GroupMatchingModeEnumFromJSON,
@@ -30,8 +32,6 @@ import type { ProviderTypeEnum } from "./ProviderTypeEnum";
import { ProviderTypeEnumFromJSON, ProviderTypeEnumToJSON } from "./ProviderTypeEnum";
import type { SourceType } from "./SourceType";
import { SourceTypeFromJSON } from "./SourceType";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -151,16 +151,10 @@ export interface OAuthSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof OAuthSource
*/
readonly iconUrl: string | null;
/**
*
* @type {ThemedUrls}
* @memberof OAuthSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
* How the source determines if an existing group should be used or a new group created.
* @type {GroupMatchingModeEnum}
@@ -266,7 +260,6 @@ export function instanceOfOAuthSource(value: object): value is OAuthSource {
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("providerType" in value) || value["providerType"] === undefined) return false;
if (!("consumerKey" in value) || value["consumerKey"] === undefined) return false;
if (!("callbackUrl" in value) || value["callbackUrl"] === undefined) return false;
@@ -311,8 +304,7 @@ export function OAuthSourceFromJSONTyped(json: any, ignoreDiscriminator: boolean
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
groupMatchingMode:
json["group_matching_mode"] == null
? undefined
@@ -352,7 +344,6 @@ export function OAuthSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
| "callback_url"
| "type"
> | null,

View File

@@ -12,6 +12,8 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { GroupMatchingModeEnum } from "./GroupMatchingModeEnum";
import {
GroupMatchingModeEnumFromJSON,
@@ -19,8 +21,6 @@ import {
} from "./GroupMatchingModeEnum";
import type { PolicyEngineMode } from "./PolicyEngineMode";
import { PolicyEngineModeFromJSON, PolicyEngineModeToJSON } from "./PolicyEngineMode";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -140,16 +140,10 @@ export interface PlexSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof PlexSource
*/
readonly iconUrl: string;
/**
*
* @type {ThemedUrls}
* @memberof PlexSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
* How the source determines if an existing group should be used or a new group created.
* @type {GroupMatchingModeEnum}
@@ -195,7 +189,6 @@ export function instanceOfPlexSource(value: object): value is PlexSource {
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("plexToken" in value) || value["plexToken"] === undefined) return false;
return true;
}
@@ -237,8 +230,7 @@ export function PlexSourceFromJSONTyped(json: any, ignoreDiscriminator: boolean)
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
groupMatchingMode:
json["group_matching_mode"] == null
? undefined
@@ -264,7 +256,6 @@ export function PlexSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
> | null,
ignoreDiscriminator: boolean = false,
): any {

View File

@@ -16,6 +16,8 @@ import type { BindingTypeEnum } from "./BindingTypeEnum";
import { BindingTypeEnumFromJSON, BindingTypeEnumToJSON } from "./BindingTypeEnum";
import type { DigestAlgorithmEnum } from "./DigestAlgorithmEnum";
import { DigestAlgorithmEnumFromJSON, DigestAlgorithmEnumToJSON } from "./DigestAlgorithmEnum";
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { GroupMatchingModeEnum } from "./GroupMatchingModeEnum";
import {
GroupMatchingModeEnumFromJSON,
@@ -30,8 +32,6 @@ import {
SignatureAlgorithmEnumFromJSON,
SignatureAlgorithmEnumToJSON,
} from "./SignatureAlgorithmEnum";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -151,16 +151,10 @@ export interface SAMLSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof SAMLSource
*/
readonly iconUrl: string;
/**
*
* @type {ThemedUrls}
* @memberof SAMLSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
* How the source determines if an existing group should be used or a new group created.
* @type {GroupMatchingModeEnum}
@@ -278,7 +272,6 @@ export function instanceOfSAMLSource(value: object): value is SAMLSource {
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("preAuthenticationFlow" in value) || value["preAuthenticationFlow"] === undefined)
return false;
if (!("ssoUrl" in value) || value["ssoUrl"] === undefined) return false;
@@ -322,8 +315,7 @@ export function SAMLSourceFromJSONTyped(json: any, ignoreDiscriminator: boolean)
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
groupMatchingMode:
json["group_matching_mode"] == null
? undefined
@@ -377,7 +369,6 @@ export function SAMLSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
> | null,
ignoreDiscriminator: boolean = false,
): any {

View File

@@ -12,10 +12,10 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { PolicyEngineMode } from "./PolicyEngineMode";
import { PolicyEngineModeFromJSON, PolicyEngineModeToJSON } from "./PolicyEngineMode";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -133,18 +133,12 @@ export interface Source {
* @memberof Source
*/
icon?: string;
/**
* Get the URL to the source icon
* @type {string}
* @memberof Source
*/
readonly iconUrl: string | null;
/**
*
* @type {ThemedUrls}
* @type {DynamicURL}
* @memberof Source
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
}
/**
@@ -160,7 +154,6 @@ export function instanceOfSource(value: object): value is Source {
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
return true;
}
@@ -201,8 +194,7 @@ export function SourceFromJSONTyped(json: any, ignoreDiscriminator: boolean): So
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
};
}
@@ -220,7 +212,6 @@ export function SourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
> | null,
ignoreDiscriminator: boolean = false,
): any {

View File

@@ -12,10 +12,10 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON } from "./DynamicURL";
import type { PolicyEngineMode } from "./PolicyEngineMode";
import { PolicyEngineModeFromJSON, PolicyEngineModeToJSON } from "./PolicyEngineMode";
import type { ThemedUrls } from "./ThemedUrls";
import { ThemedUrlsFromJSON } from "./ThemedUrls";
import type { UserMatchingModeEnum } from "./UserMatchingModeEnum";
import { UserMatchingModeEnumFromJSON, UserMatchingModeEnumToJSON } from "./UserMatchingModeEnum";
@@ -135,16 +135,10 @@ export interface TelegramSource {
icon?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof TelegramSource
*/
readonly iconUrl: string | null;
/**
*
* @type {ThemedUrls}
* @memberof TelegramSource
*/
readonly iconThemedUrls: ThemedUrls | null;
readonly iconUrl: DynamicURL | null;
/**
* Telegram bot username
* @type {string}
@@ -178,7 +172,6 @@ export function instanceOfTelegramSource(value: object): value is TelegramSource
if (!("metaModelName" in value) || value["metaModelName"] === undefined) return false;
if (!("managed" in value) || value["managed"] === undefined) return false;
if (!("iconUrl" in value) || value["iconUrl"] === undefined) return false;
if (!("iconThemedUrls" in value) || value["iconThemedUrls"] === undefined) return false;
if (!("botUsername" in value) || value["botUsername"] === undefined) return false;
if (!("preAuthenticationFlow" in value) || value["preAuthenticationFlow"] === undefined)
return false;
@@ -225,8 +218,7 @@ export function TelegramSourceFromJSONTyped(
userPathTemplate:
json["user_path_template"] == null ? undefined : json["user_path_template"],
icon: json["icon"] == null ? undefined : json["icon"],
iconUrl: json["icon_url"],
iconThemedUrls: ThemedUrlsFromJSON(json["icon_themed_urls"]),
iconUrl: DynamicURLFromJSON(json["icon_url"]),
botUsername: json["bot_username"],
requestMessageAccess:
json["request_message_access"] == null ? undefined : json["request_message_access"],
@@ -248,7 +240,6 @@ export function TelegramSourceToJSONTyped(
| "meta_model_name"
| "managed"
| "icon_url"
| "icon_themed_urls"
> | null,
ignoreDiscriminator: boolean = false,
): any {

View File

@@ -13,23 +13,18 @@
*/
/**
* Themed URLs - maps theme names to URLs for light and dark themes
* URL variants keyed by theme name. Includes a fallback URL.
* @export
* @interface ThemedUrls
*/
export interface ThemedUrls {
[key: string]: string | any;
/**
*
* @type {string}
* @memberof ThemedUrls
*/
light?: string | null;
/**
*
* @type {string}
* @memberof ThemedUrls
*/
dark?: string | null;
fallback?: string | null;
}
/**
@@ -48,8 +43,8 @@ export function ThemedUrlsFromJSONTyped(json: any, ignoreDiscriminator: boolean)
return json;
}
return {
light: json["light"] == null ? undefined : json["light"],
dark: json["dark"] == null ? undefined : json["dark"],
...json,
fallback: json["fallback"] == null ? undefined : json["fallback"],
};
}
@@ -66,7 +61,7 @@ export function ThemedUrlsToJSONTyped(
}
return {
light: value["light"],
dark: value["dark"],
...value,
fallback: value["fallback"],
};
}

View File

@@ -12,6 +12,9 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON, DynamicURLToJSON } from "./DynamicURL";
/**
* Types of an object that can be created
* @export
@@ -44,10 +47,10 @@ export interface TypeCreate {
modelName: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof TypeCreate
*/
iconUrl?: string;
iconUrl?: DynamicURL | null;
/**
*
* @type {boolean}
@@ -86,7 +89,7 @@ export function TypeCreateFromJSONTyped(json: any, ignoreDiscriminator: boolean)
description: json["description"],
component: json["component"],
modelName: json["model_name"],
iconUrl: json["icon_url"] == null ? undefined : json["icon_url"],
iconUrl: json["icon_url"] == null ? undefined : DynamicURLFromJSON(json["icon_url"]),
requiresEnterprise:
json["requires_enterprise"] == null ? undefined : json["requires_enterprise"],
deprecated: json["deprecated"] == null ? undefined : json["deprecated"],
@@ -110,7 +113,7 @@ export function TypeCreateToJSONTyped(
description: value["description"],
component: value["component"],
model_name: value["modelName"],
icon_url: value["iconUrl"],
icon_url: DynamicURLToJSON(value["iconUrl"]),
requires_enterprise: value["requiresEnterprise"],
deprecated: value["deprecated"],
};

View File

@@ -12,6 +12,9 @@
* Do not edit the class manually.
*/
import type { DynamicURL } from "./DynamicURL";
import { DynamicURLFromJSON, DynamicURLToJSON } from "./DynamicURL";
/**
* Serializer for User settings for stages and sources
* @export
@@ -44,10 +47,10 @@ export interface UserSetting {
configureUrl?: string;
/**
*
* @type {string}
* @type {DynamicURL}
* @memberof UserSetting
*/
iconUrl?: string;
iconUrl?: DynamicURL | null;
}
/**
@@ -73,7 +76,7 @@ export function UserSettingFromJSONTyped(json: any, ignoreDiscriminator: boolean
component: json["component"],
title: json["title"],
configureUrl: json["configure_url"] == null ? undefined : json["configure_url"],
iconUrl: json["icon_url"] == null ? undefined : json["icon_url"],
iconUrl: json["icon_url"] == null ? undefined : DynamicURLFromJSON(json["icon_url"]),
};
}
@@ -94,6 +97,6 @@ export function UserSettingToJSONTyped(
component: value["component"],
title: value["title"],
configure_url: value["configureUrl"],
icon_url: value["iconUrl"],
icon_url: DynamicURLToJSON(value["iconUrl"]),
};
}

View File

@@ -149,6 +149,7 @@ export * from "./DuoDevice";
export * from "./DuoDeviceEnrollmentStatus";
export * from "./DuoDeviceRequest";
export * from "./DuoResponseEnum";
export * from "./DynamicURL";
export * from "./EmailChallenge";
export * from "./EmailChallengeResponseRequest";
export * from "./EmailDevice";

View File

@@ -37802,6 +37802,17 @@ components:
- waiting
- invalid
type: string
DynamicURL:
type: object
description: Dynamic URL variants keyed by variant name. Includes a fallback
URL.
properties:
fallback:
type: string
nullable: true
additionalProperties:
type: string
nullable: true
EmailChallenge:
type: object
description: Email challenge
@@ -41158,11 +41169,8 @@ components:
icon:
type: string
icon_url:
type: string
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
group_matching_mode:
@@ -41218,7 +41226,6 @@ components:
required:
- component
- connectivity
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -41848,11 +41855,8 @@ components:
icon:
type: string
icon_url:
type: string
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
server_uri:
@@ -41945,7 +41949,6 @@ components:
- base_dn
- component
- connectivity
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -42650,7 +42653,8 @@ components:
name:
type: string
icon_url:
type: string
allOf:
- $ref: '#/components/schemas/DynamicURL'
nullable: true
promoted:
type: boolean
@@ -44060,12 +44064,8 @@ components:
icon:
type: string
icon_url:
type: string
nullable: true
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
group_matching_mode:
@@ -44126,7 +44126,6 @@ components:
- callback_url
- component
- consumer_key
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -51458,11 +51457,8 @@ components:
icon:
type: string
icon_url:
type: string
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
group_matching_mode:
@@ -51487,7 +51483,6 @@ components:
description: Plex token used to check friends
required:
- component
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -54133,11 +54128,8 @@ components:
icon:
type: string
icon_url:
type: string
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
group_matching_mode:
@@ -54214,7 +54206,6 @@ components:
type: boolean
required:
- component
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -55787,18 +55778,12 @@ components:
icon:
type: string
icon_url:
type: string
nullable: true
description: Get the URL to the source icon
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
required:
- component
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -56469,12 +56454,8 @@ components:
icon:
type: string
icon_url:
type: string
nullable: true
readOnly: true
icon_themed_urls:
allOf:
- $ref: '#/components/schemas/ThemedUrls'
- $ref: '#/components/schemas/DynamicURL'
readOnly: true
nullable: true
bot_username:
@@ -56490,7 +56471,6 @@ components:
required:
- bot_username
- component
- icon_themed_urls
- icon_url
- managed
- meta_model_name
@@ -56710,14 +56690,14 @@ components:
- schema_name
ThemedUrls:
type: object
description: Themed URLs - maps theme names to URLs for light and dark themes
description: URL variants keyed by theme name. Includes a fallback URL.
properties:
light:
type: string
nullable: true
dark:
fallback:
type: string
nullable: true
additionalProperties:
type: string
nullable: true
Token:
type: object
description: Token Serializer
@@ -56932,7 +56912,9 @@ components:
model_name:
type: string
icon_url:
type: string
allOf:
- $ref: '#/components/schemas/DynamicURL'
nullable: true
requires_enterprise:
type: boolean
default: false
@@ -57970,7 +57952,9 @@ components:
configure_url:
type: string
icon_url:
type: string
allOf:
- $ref: '#/components/schemas/DynamicURL'
nullable: true
required:
- component
- object_uid

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282"/>
</svg>

After

Width:  |  Height:  |  Size: 756 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M11.182.008C11.148-.03 9.923.023 8.857 1.18c-1.066 1.156-.902 2.482-.878 2.516s1.52.087 2.475-1.258.762-2.391.728-2.43m3.314 11.733c-.048-.096-2.325-1.234-2.113-3.422s1.675-2.789 1.698-2.854-.597-.79-1.254-1.157a3.7 3.7 0 0 0-1.563-.434c-.108-.003-.483-.095-1.254.116-.508.139-1.653.589-1.968.607-.316.018-1.256-.522-2.267-.665-.647-.125-1.333.131-1.824.328-.49.196-1.422.754-2.074 2.237-.652 1.482-.311 3.83-.067 4.56s.625 1.924 1.273 2.796c.576.984 1.34 1.667 1.659 1.899s1.219.386 1.843.067c.502-.308 1.408-.485 1.766-.472.357.013 1.061.154 1.782.539.571.197 1.111.115 1.652-.105.541-.221 1.324-1.059 2.238-2.758q.52-1.185.473-1.282"/>
</svg>

After

Width:  |  Height:  |  Size: 761 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M13.545 2.907a13.2 13.2 0 0 0-3.257-1.011.05.05 0 0 0-.052.025c-.141.25-.297.577-.406.833a12.2 12.2 0 0 0-3.658 0 8 8 0 0 0-.412-.833.05.05 0 0 0-.052-.025c-1.125.194-2.22.534-3.257 1.011a.04.04 0 0 0-.021.018C.356 6.024-.213 9.047.066 12.032q.003.022.021.037a13.3 13.3 0 0 0 3.995 2.02.05.05 0 0 0 .056-.019q.463-.63.818-1.329a.05.05 0 0 0-.01-.059l-.018-.011a9 9 0 0 1-1.248-.595.05.05 0 0 1-.02-.066l.015-.019q.127-.095.248-.195a.05.05 0 0 1 .051-.007c2.619 1.196 5.454 1.196 8.041 0a.05.05 0 0 1 .053.007q.121.1.248.195a.05.05 0 0 1-.004.085 8 8 0 0 1-1.249.594.05.05 0 0 0-.03.03.05.05 0 0 0 .003.041c.24.465.515.909.817 1.329a.05.05 0 0 0 .056.019 13.2 13.2 0 0 0 4.001-2.02.05.05 0 0 0 .021-.037c.334-3.451-.559-6.449-2.366-9.106a.03.03 0 0 0-.02-.019m-8.198 7.307c-.789 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.45.73 1.438 1.613 0 .888-.637 1.612-1.438 1.612m5.316 0c-.788 0-1.438-.724-1.438-1.612s.637-1.613 1.438-1.613c.807 0 1.451.73 1.438 1.613 0 .888-.631 1.612-1.438 1.612"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M8.01 4.555 4.005 7.11 8.01 9.665 4.005 12.22 0 9.651l4.005-2.555L0 4.555 4.005 2zm-4.026 8.487 4.006-2.555 4.005 2.555-4.005 2.555zm4.026-3.39 4.005-2.556L8.01 4.555 11.995 2 16 4.555 11.995 7.11 16 9.665l-4.005 2.555z"/>
</svg>

After

Width:  |  Height:  |  Size: 340 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8.01 4.555 4.005 7.11 8.01 9.665 4.005 12.22 0 9.651l4.005-2.555L0 4.555 4.005 2zm-4.026 8.487 4.006-2.555 4.005 2.555-4.005 2.555zm4.026-3.39 4.005-2.556L8.01 4.555 11.995 2 16 4.555 11.995 7.11 16 9.665l-4.005 2.555z"/>
</svg>

After

Width:  |  Height:  |  Size: 345 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
</svg>

After

Width:  |  Height:  |  Size: 408 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8.049c0-4.446-3.582-8.05-8-8.05C3.58 0-.002 3.603-.002 8.05c0 4.017 2.926 7.347 6.75 7.951v-5.625h-2.03V8.05H6.75V6.275c0-2.017 1.195-3.131 3.022-3.131.876 0 1.791.157 1.791.157v1.98h-1.009c-.993 0-1.303.621-1.303 1.258v1.51h2.218l-.354 2.326H9.25V16c3.824-.604 6.75-3.934 6.75-7.951"/>
</svg>

After

Width:  |  Height:  |  Size: 413 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
</svg>

After

Width:  |  Height:  |  Size: 683 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27s1.36.09 2 .27c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8"/>
</svg>

After

Width:  |  Height:  |  Size: 688 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="m15.734 6.1-.022-.058L13.534.358a.57.57 0 0 0-.563-.356.6.6 0 0 0-.328.122.6.6 0 0 0-.193.294l-1.47 4.499H5.025l-1.47-4.5A.572.572 0 0 0 2.47.358L.289 6.04l-.022.057A4.044 4.044 0 0 0 1.61 10.77l.007.006.02.014 3.318 2.485 1.64 1.242 1 .755a.67.67 0 0 0 .814 0l1-.755 1.64-1.242 3.338-2.5.009-.007a4.05 4.05 0 0 0 1.34-4.668Z"/>
</svg>

After

Width:  |  Height:  |  Size: 446 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="m15.734 6.1-.022-.058L13.534.358a.57.57 0 0 0-.563-.356.6.6 0 0 0-.328.122.6.6 0 0 0-.193.294l-1.47 4.499H5.025l-1.47-4.5A.572.572 0 0 0 2.47.358L.289 6.04l-.022.057A4.044 4.044 0 0 0 1.61 10.77l.007.006.02.014 3.318 2.485 1.64 1.242 1 .755a.67.67 0 0 0 .814 0l1-.755 1.64-1.242 3.338-2.5.009-.007a4.05 4.05 0 0 0 1.34-4.668Z"/>
</svg>

After

Width:  |  Height:  |  Size: 451 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"/>
</svg>

After

Width:  |  Height:  |  Size: 465 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M15.545 6.558a9.4 9.4 0 0 1 .139 1.626c0 2.434-.87 4.492-2.384 5.885h.002C11.978 15.292 10.158 16 8 16A8 8 0 1 1 8 0a7.7 7.7 0 0 1 5.352 2.082l-2.284 2.284A4.35 4.35 0 0 0 8 3.166c-2.087 0-3.86 1.408-4.492 3.304a4.8 4.8 0 0 0 0 3.063h.003c.635 1.893 2.405 3.301 4.492 3.301 1.078 0 2.004-.276 2.722-.764h-.003a3.7 3.7 0 0 0 1.599-2.431H8v-3.08z"/>
</svg>

After

Width:  |  Height:  |  Size: 470 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 60 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="768" height="768" viewBox="0 0 768 768" fill="none">
<path fill="#cb2026" d="M 323 214 L 325 214 L 325 215.5 L 326 216.5 L 327 219.5 L 329 221.5 L 330 224.5 L 332 226.5 L 334 231.5 L 336 233.5 L 338 238.5 L 340 240.5 L 341 243.5 L 343 245.5 L 345 250.5 L 347 252.5 L 349 257.5 L 351 259.5 L 353 264.5 L 355 266.5 L 356 269.5 L 358 271.5 L 358 272.5 L 359 273.5 L 360 276.5 L 362 278.5 L 364 283.5 L 366 285.5 L 367 288.5 L 369 290.5 L 369 291.5 L 370 292.5 L 371 295.5 L 373 297.5 L 375 302.5 L 377 304.5 L 378 307.5 L 380 309.5 L 382 314.5 L 384 316.5 L 384 317.5 L 385 318.5 L 386 321.5 L 388 323.5 L 390 328.5 L 392 330.5 L 391 331.5 L 390 334.5 L 388 336.5 L 386 341.5 L 384 343.5 L 383 346.5 L 381 348.5 L 379 353.5 L 377 355.5 L 375 360.5 L 373 362.5 L 371 367.5 L 369 369.5 L 367 374.5 L 365 376.5 L 364 379.5 L 362 381.5 L 360 386.5 L 358 388.5 L 356 393.5 L 354 395.5 L 352 400.5 L 350 402.5 L 348 407.5 L 346 409.5 L 344 414.5 L 342 416.5 L 341 419.5 L 339 421.5 L 336.5 427 L 335 425.5 L 334 422.5 L 332 420.5 L 332 419.5 L 331 418.5 L 330 415.5 L 328 413.5 L 327 410.5 L 325 408.5 L 323 403.5 L 321 401.5 L 319 396.5 L 317 394.5 L 315 389.5 L 313 387.5 L 313 386.5 L 312 385.5 L 311 382.5 L 309 380.5 L 307 375.5 L 305 373.5 L 304 370.5 L 302 368.5 L 300 363.5 L 298 361.5 L 296 356.5 L 294 354.5 L 294 353.5 L 293 352.5 L 292 349.5 L 290 347.5 L 288 342.5 L 286 340.5 L 285 337.5 L 283 335.5 L 281 330.5 L 279 328.5 L 279 327.5 L 278 326.5 L 277 323.5 L 275 321.5 L 273 316.5 L 271 314.5 L 271 313.5 L 269 310.5 L 269 308.5 L 270 307.5 L 272 302.5 L 274 300.5 L 276 295.5 L 278 293.5 L 280 288.5 L 282 286.5 L 283 283.5 L 285 281.5 L 287 276.5 L 289 274.5 L 291 269.5 L 293 267.5 L 295 262.5 L 297 260.5 L 298 257.5 L 300 255.5 L 302 250.5 L 304 248.5 L 306 243.5 L 308 241.5 L 310 236.5 L 312 234.5 L 313 231.5 L 315 229.5 L 315 228.5 L 316 227.5 L 317 224.5 L 319 222.5 L 321 217.5 L 323 215.5 L 323 214 Z "/>
<path fill="#cb2026" d="M 221.5 266 L 223 267.5 L 224 270.5 L 226 272.5 L 228 277.5 L 230 279.5 L 232 284.5 L 234 286.5 L 236 291.5 L 238 293.5 L 239 296.5 L 241 298.5 L 243 303.5 L 245 305.5 L 247 310.5 L 249 312.5 L 249 313.5 L 250 314.5 L 251 317.5 L 253 319.5 L 255 324.5 L 257 326.5 L 258 329.5 L 260 331.5 L 262 336.5 L 264 338.5 L 266 343.5 L 268 345.5 L 270 350.5 L 272 352.5 L 272 353.5 L 273 354.5 L 274 357.5 L 276 359.5 L 278 364.5 L 280 366.5 L 281 369.5 L 283 371.5 L 285 376.5 L 287 378.5 L 289 383.5 L 291 385.5 L 291 386.5 L 292 387.5 L 293 390.5 L 295 392.5 L 297 397.5 L 299 399.5 L 300 402.5 L 302 404.5 L 304 409.5 L 306 411.5 L 308 416.5 L 310 418.5 L 312 423.5 L 314 425.5 L 314 426.5 L 315 427.5 L 316 430.5 L 318 432.5 L 320 437.5 L 322 439.5 L 323 442.5 L 325 444.5 L 325 447.5 L 323 449.5 L 322 452.5 L 320 454.5 L 318 459.5 L 316 461.5 L 314 466.5 L 312 468.5 L 310 473.5 L 308 475.5 L 308 476.5 L 307 477.5 L 306 480.5 L 304 482.5 L 302 487.5 L 300 489.5 L 299 492.5 L 297 494.5 L 295 499.5 L 293 501.5 L 291 506.5 L 289 508.5 L 287 513.5 L 285 515.5 L 284 519 L 283.5 519 L 76.5 519 L 76 518.5 L 77 517.5 L 78 514.5 L 80 512.5 L 82 507.5 L 84 505.5 L 86 500.5 L 88 498.5 L 90 493.5 L 92 491.5 L 94 486.5 L 96 484.5 L 97 481.5 L 99 479.5 L 101 474.5 L 103 472.5 L 105 467.5 L 107 465.5 L 109 460.5 L 111 458.5 L 112 455.5 L 114 453.5 L 116 448.5 L 118 446.5 L 118 445.5 L 119 444.5 L 120 441.5 L 122 439.5 L 124 434.5 L 126 432.5 L 127 429.5 L 129 427.5 L 131 422.5 L 133 420.5 L 135 415.5 L 137 413.5 L 137 412.5 L 138 411.5 L 139 408.5 L 141 406.5 L 143 401.5 L 145 399.5 L 146 396.5 L 148 394.5 L 150 389.5 L 152 387.5 L 152 386.5 L 153 385.5 L 154 382.5 L 156 380.5 L 158 375.5 L 160 373.5 L 161 370.5 L 163 368.5 L 165 363.5 L 167 361.5 L 167 360.5 L 168 359.5 L 169 356.5 L 171 354.5 L 173 349.5 L 175 347.5 L 176 344.5 L 178 342.5 L 180 337.5 L 182 335.5 L 182 334.5 L 183 333.5 L 184 330.5 L 186 328.5 L 188 323.5 L 190 321.5 L 191 318.5 L 193 316.5 L 195 311.5 L 197 309.5 L 199 304.5 L 201 302.5 L 203 297.5 L 205 295.5 L 207 290.5 L 209 288.5 L 210 285.5 L 212 283.5 L 214 278.5 L 216 276.5 L 218 271.5 L 220 269.5 L 221.5 266 Z "/>
<path fill="#cb2026" d="M 547.5 266 L 551 270.5 L 551 271.5 L 552 272.5 L 553 275.5 L 555 277.5 L 557 282.5 L 559 284.5 L 560 287.5 L 562 289.5 L 562 290.5 L 563 291.5 L 564 294.5 L 566 296.5 L 568 301.5 L 570 303.5 L 571 306.5 L 573 308.5 L 573 309.5 L 574 310.5 L 575 313.5 L 577 315.5 L 579 320.5 L 581 322.5 L 582 325.5 L 584 327.5 L 586 332.5 L 588 334.5 L 588 335.5 L 589 336.5 L 590 339.5 L 592 341.5 L 594 346.5 L 596 348.5 L 597 351.5 L 599 353.5 L 599 354.5 L 600 355.5 L 601 358.5 L 603 360.5 L 605 365.5 L 607 367.5 L 608 370.5 L 610 372.5 L 610 373.5 L 611 374.5 L 612 377.5 L 614 379.5 L 616 384.5 L 618 386.5 L 619 389.5 L 621 391.5 L 623 396.5 L 625 398.5 L 625 399.5 L 626 400.5 L 627 403.5 L 629 405.5 L 631 410.5 L 633 412.5 L 634 415.5 L 636 417.5 L 636 418.5 L 637 419.5 L 638 422.5 L 640 424.5 L 642 429.5 L 644 431.5 L 645 434.5 L 647 436.5 L 647 437.5 L 648 438.5 L 649 441.5 L 651 443.5 L 653 448.5 L 655 450.5 L 656 453.5 L 658 455.5 L 660 460.5 L 662 462.5 L 664 467.5 L 666 469.5 L 668 474.5 L 670 476.5 L 671 479.5 L 673 481.5 L 675 486.5 L 677 488.5 L 679 493.5 L 681 495.5 L 682 498.5 L 684 500.5 L 686 505.5 L 688 507.5 L 690 512.5 L 692 514.5 L 692 515.5 L 694 518.5 L 693.5 519 L 576.5 519 L 576 519 L 576 517.5 L 575 516.5 L 574 513.5 L 572 511.5 L 572 510.5 L 571 509.5 L 570 506.5 L 568 504.5 L 566 499.5 L 564 497.5 L 563 494.5 L 561 492.5 L 559 487.5 L 557 485.5 L 555 480.5 L 553 478.5 L 551 473.5 L 549 471.5 L 549 470.5 L 548 469.5 L 547 466.5 L 545 464.5 L 543 459.5 L 541 457.5 L 540 454.5 L 538 452.5 L 536 447.5 L 534 445.5 L 532 440.5 L 530 438.5 L 530 437.5 L 529 436.5 L 528 433.5 L 526 431.5 L 524 426.5 L 522 424.5 L 521 421.5 L 519 419.5 L 517 414.5 L 515 412.5 L 513 407.5 L 511 405.5 L 509 400.5 L 507 398.5 L 507 397.5 L 506 396.5 L 505 393.5 L 503 391.5 L 501 386.5 L 499 384.5 L 499 383.5 L 496 379.5 L 494 374.5 L 492 372.5 L 492 371.5 L 490 368.5 L 490 365.5 L 493 361.5 L 493 360.5 L 494 359.5 L 495 356.5 L 497 354.5 L 498 351.5 L 500 349.5 L 502 344.5 L 504 342.5 L 506 337.5 L 508 335.5 L 510 330.5 L 512 328.5 L 513 325.5 L 515 323.5 L 517 318.5 L 519 316.5 L 521 311.5 L 523 309.5 L 525 304.5 L 527 302.5 L 528 299.5 L 530 297.5 L 532 292.5 L 534 290.5 L 536 285.5 L 538 283.5 L 540 278.5 L 542 276.5 L 544 271.5 L 546 269.5 L 547.5 266 Z "/>
<path fill="#cb2026" d="M 429.5 303 Q 431.8 302.8 432 304.5 L 432 305.5 L 435 309.5 L 437 314.5 L 439 316.5 L 441 321.5 L 443 323.5 L 445 328.5 L 447 330.5 L 449 335.5 L 451 337.5 L 451 338.5 L 454 342.5 L 456 347.5 L 458 349.5 L 460 354.5 L 462 356.5 L 464 361.5 L 466 363.5 L 468 368.5 L 470 370.5 L 472 375.5 L 474 377.5 L 475 380.5 L 477 382.5 L 479 387.5 L 481 389.5 L 483 394.5 L 485 396.5 L 485 397.5 L 486 398.5 L 487 401.5 L 489 403.5 L 491 408.5 L 493 410.5 L 493 411.5 L 496 415.5 L 498 420.5 L 500 422.5 L 502 427.5 L 504 429.5 L 506 434.5 L 508 436.5 L 510 441.5 L 512 443.5 L 514 448.5 L 516 450.5 L 516 451.5 L 519 455.5 L 521 460.5 L 523 462.5 L 525 467.5 L 527 469.5 L 529 474.5 L 531 476.5 L 533 481.5 L 535 483.5 L 536 486.5 L 538 488.5 L 540 493.5 L 542 495.5 L 544 500.5 L 546 502.5 L 548 507.5 L 550 509.5 L 552 514.5 L 554 516.5 L 556 521.5 L 558 523.5 L 558 524.5 L 561 528.5 L 563 533.5 L 565 535.5 L 567 540.5 L 569 542.5 L 571 547.5 L 573 549.5 L 573 550.5 L 575 553.5 L 575 555 L 574.5 555 L 285.5 555 Q 284.5 555.4 285 553.5 L 288 549.5 L 290 544.5 L 292 542.5 L 294 537.5 L 296 535.5 L 296 534.5 L 297 533.5 L 298 530.5 L 300 528.5 L 302 523.5 L 304 521.5 L 305 518.5 L 307 516.5 L 309 511.5 L 311 509.5 L 313 504.5 L 315 502.5 L 315 501.5 L 316 500.5 L 317 497.5 L 319 495.5 L 321 490.5 L 323 488.5 L 324 485.5 L 326 483.5 L 328 478.5 L 330 476.5 L 332 471.5 L 334 469.5 L 336 464.5 L 338 462.5 L 338 461.5 L 339 460.5 L 340 457.5 L 342 455.5 L 344 450.5 L 346 448.5 L 347 445.5 L 349 443.5 L 351 438.5 L 353 436.5 L 355 431.5 L 357 429.5 L 357 428.5 L 358 427.5 L 359 424.5 L 361 422.5 L 363 417.5 L 365 415.5 L 366 412.5 L 368 410.5 L 370 405.5 L 372 403.5 L 374 398.5 L 376 396.5 L 378 391.5 L 380 389.5 L 380 388.5 L 381 387.5 L 382 384.5 L 384 382.5 L 386 377.5 L 388 375.5 L 389 372.5 L 391 370.5 L 393 365.5 L 395 363.5 L 397 358.5 L 399 356.5 L 401 351.5 L 403 349.5 L 405 344.5 L 407 342.5 L 408 339.5 L 410 337.5 L 412 332.5 L 414 330.5 L 416 325.5 L 418 323.5 L 420 318.5 L 422 316.5 L 424 311.5 L 426 309.5 L 428 304.5 L 429.5 303 Z "/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="768" height="768" viewBox="0 0 768 768" fill="none">
<path fill="#cb2026" d="M 323 214 L 325 214 L 325 215.5 L 326 216.5 L 327 219.5 L 329 221.5 L 330 224.5 L 332 226.5 L 334 231.5 L 336 233.5 L 338 238.5 L 340 240.5 L 341 243.5 L 343 245.5 L 345 250.5 L 347 252.5 L 349 257.5 L 351 259.5 L 353 264.5 L 355 266.5 L 356 269.5 L 358 271.5 L 358 272.5 L 359 273.5 L 360 276.5 L 362 278.5 L 364 283.5 L 366 285.5 L 367 288.5 L 369 290.5 L 369 291.5 L 370 292.5 L 371 295.5 L 373 297.5 L 375 302.5 L 377 304.5 L 378 307.5 L 380 309.5 L 382 314.5 L 384 316.5 L 384 317.5 L 385 318.5 L 386 321.5 L 388 323.5 L 390 328.5 L 392 330.5 L 391 331.5 L 390 334.5 L 388 336.5 L 386 341.5 L 384 343.5 L 383 346.5 L 381 348.5 L 379 353.5 L 377 355.5 L 375 360.5 L 373 362.5 L 371 367.5 L 369 369.5 L 367 374.5 L 365 376.5 L 364 379.5 L 362 381.5 L 360 386.5 L 358 388.5 L 356 393.5 L 354 395.5 L 352 400.5 L 350 402.5 L 348 407.5 L 346 409.5 L 344 414.5 L 342 416.5 L 341 419.5 L 339 421.5 L 336.5 427 L 335 425.5 L 334 422.5 L 332 420.5 L 332 419.5 L 331 418.5 L 330 415.5 L 328 413.5 L 327 410.5 L 325 408.5 L 323 403.5 L 321 401.5 L 319 396.5 L 317 394.5 L 315 389.5 L 313 387.5 L 313 386.5 L 312 385.5 L 311 382.5 L 309 380.5 L 307 375.5 L 305 373.5 L 304 370.5 L 302 368.5 L 300 363.5 L 298 361.5 L 296 356.5 L 294 354.5 L 294 353.5 L 293 352.5 L 292 349.5 L 290 347.5 L 288 342.5 L 286 340.5 L 285 337.5 L 283 335.5 L 281 330.5 L 279 328.5 L 279 327.5 L 278 326.5 L 277 323.5 L 275 321.5 L 273 316.5 L 271 314.5 L 271 313.5 L 269 310.5 L 269 308.5 L 270 307.5 L 272 302.5 L 274 300.5 L 276 295.5 L 278 293.5 L 280 288.5 L 282 286.5 L 283 283.5 L 285 281.5 L 287 276.5 L 289 274.5 L 291 269.5 L 293 267.5 L 295 262.5 L 297 260.5 L 298 257.5 L 300 255.5 L 302 250.5 L 304 248.5 L 306 243.5 L 308 241.5 L 310 236.5 L 312 234.5 L 313 231.5 L 315 229.5 L 315 228.5 L 316 227.5 L 317 224.5 L 319 222.5 L 321 217.5 L 323 215.5 L 323 214 Z "/>
<path fill="#cb2026" d="M 221.5 266 L 223 267.5 L 224 270.5 L 226 272.5 L 228 277.5 L 230 279.5 L 232 284.5 L 234 286.5 L 236 291.5 L 238 293.5 L 239 296.5 L 241 298.5 L 243 303.5 L 245 305.5 L 247 310.5 L 249 312.5 L 249 313.5 L 250 314.5 L 251 317.5 L 253 319.5 L 255 324.5 L 257 326.5 L 258 329.5 L 260 331.5 L 262 336.5 L 264 338.5 L 266 343.5 L 268 345.5 L 270 350.5 L 272 352.5 L 272 353.5 L 273 354.5 L 274 357.5 L 276 359.5 L 278 364.5 L 280 366.5 L 281 369.5 L 283 371.5 L 285 376.5 L 287 378.5 L 289 383.5 L 291 385.5 L 291 386.5 L 292 387.5 L 293 390.5 L 295 392.5 L 297 397.5 L 299 399.5 L 300 402.5 L 302 404.5 L 304 409.5 L 306 411.5 L 308 416.5 L 310 418.5 L 312 423.5 L 314 425.5 L 314 426.5 L 315 427.5 L 316 430.5 L 318 432.5 L 320 437.5 L 322 439.5 L 323 442.5 L 325 444.5 L 325 447.5 L 323 449.5 L 322 452.5 L 320 454.5 L 318 459.5 L 316 461.5 L 314 466.5 L 312 468.5 L 310 473.5 L 308 475.5 L 308 476.5 L 307 477.5 L 306 480.5 L 304 482.5 L 302 487.5 L 300 489.5 L 299 492.5 L 297 494.5 L 295 499.5 L 293 501.5 L 291 506.5 L 289 508.5 L 287 513.5 L 285 515.5 L 284 519 L 283.5 519 L 76.5 519 L 76 518.5 L 77 517.5 L 78 514.5 L 80 512.5 L 82 507.5 L 84 505.5 L 86 500.5 L 88 498.5 L 90 493.5 L 92 491.5 L 94 486.5 L 96 484.5 L 97 481.5 L 99 479.5 L 101 474.5 L 103 472.5 L 105 467.5 L 107 465.5 L 109 460.5 L 111 458.5 L 112 455.5 L 114 453.5 L 116 448.5 L 118 446.5 L 118 445.5 L 119 444.5 L 120 441.5 L 122 439.5 L 124 434.5 L 126 432.5 L 127 429.5 L 129 427.5 L 131 422.5 L 133 420.5 L 135 415.5 L 137 413.5 L 137 412.5 L 138 411.5 L 139 408.5 L 141 406.5 L 143 401.5 L 145 399.5 L 146 396.5 L 148 394.5 L 150 389.5 L 152 387.5 L 152 386.5 L 153 385.5 L 154 382.5 L 156 380.5 L 158 375.5 L 160 373.5 L 161 370.5 L 163 368.5 L 165 363.5 L 167 361.5 L 167 360.5 L 168 359.5 L 169 356.5 L 171 354.5 L 173 349.5 L 175 347.5 L 176 344.5 L 178 342.5 L 180 337.5 L 182 335.5 L 182 334.5 L 183 333.5 L 184 330.5 L 186 328.5 L 188 323.5 L 190 321.5 L 191 318.5 L 193 316.5 L 195 311.5 L 197 309.5 L 199 304.5 L 201 302.5 L 203 297.5 L 205 295.5 L 207 290.5 L 209 288.5 L 210 285.5 L 212 283.5 L 214 278.5 L 216 276.5 L 218 271.5 L 220 269.5 L 221.5 266 Z "/>
<path fill="#cb2026" d="M 547.5 266 L 551 270.5 L 551 271.5 L 552 272.5 L 553 275.5 L 555 277.5 L 557 282.5 L 559 284.5 L 560 287.5 L 562 289.5 L 562 290.5 L 563 291.5 L 564 294.5 L 566 296.5 L 568 301.5 L 570 303.5 L 571 306.5 L 573 308.5 L 573 309.5 L 574 310.5 L 575 313.5 L 577 315.5 L 579 320.5 L 581 322.5 L 582 325.5 L 584 327.5 L 586 332.5 L 588 334.5 L 588 335.5 L 589 336.5 L 590 339.5 L 592 341.5 L 594 346.5 L 596 348.5 L 597 351.5 L 599 353.5 L 599 354.5 L 600 355.5 L 601 358.5 L 603 360.5 L 605 365.5 L 607 367.5 L 608 370.5 L 610 372.5 L 610 373.5 L 611 374.5 L 612 377.5 L 614 379.5 L 616 384.5 L 618 386.5 L 619 389.5 L 621 391.5 L 623 396.5 L 625 398.5 L 625 399.5 L 626 400.5 L 627 403.5 L 629 405.5 L 631 410.5 L 633 412.5 L 634 415.5 L 636 417.5 L 636 418.5 L 637 419.5 L 638 422.5 L 640 424.5 L 642 429.5 L 644 431.5 L 645 434.5 L 647 436.5 L 647 437.5 L 648 438.5 L 649 441.5 L 651 443.5 L 653 448.5 L 655 450.5 L 656 453.5 L 658 455.5 L 660 460.5 L 662 462.5 L 664 467.5 L 666 469.5 L 668 474.5 L 670 476.5 L 671 479.5 L 673 481.5 L 675 486.5 L 677 488.5 L 679 493.5 L 681 495.5 L 682 498.5 L 684 500.5 L 686 505.5 L 688 507.5 L 690 512.5 L 692 514.5 L 692 515.5 L 694 518.5 L 693.5 519 L 576.5 519 L 576 519 L 576 517.5 L 575 516.5 L 574 513.5 L 572 511.5 L 572 510.5 L 571 509.5 L 570 506.5 L 568 504.5 L 566 499.5 L 564 497.5 L 563 494.5 L 561 492.5 L 559 487.5 L 557 485.5 L 555 480.5 L 553 478.5 L 551 473.5 L 549 471.5 L 549 470.5 L 548 469.5 L 547 466.5 L 545 464.5 L 543 459.5 L 541 457.5 L 540 454.5 L 538 452.5 L 536 447.5 L 534 445.5 L 532 440.5 L 530 438.5 L 530 437.5 L 529 436.5 L 528 433.5 L 526 431.5 L 524 426.5 L 522 424.5 L 521 421.5 L 519 419.5 L 517 414.5 L 515 412.5 L 513 407.5 L 511 405.5 L 509 400.5 L 507 398.5 L 507 397.5 L 506 396.5 L 505 393.5 L 503 391.5 L 501 386.5 L 499 384.5 L 499 383.5 L 496 379.5 L 494 374.5 L 492 372.5 L 492 371.5 L 490 368.5 L 490 365.5 L 493 361.5 L 493 360.5 L 494 359.5 L 495 356.5 L 497 354.5 L 498 351.5 L 500 349.5 L 502 344.5 L 504 342.5 L 506 337.5 L 508 335.5 L 510 330.5 L 512 328.5 L 513 325.5 L 515 323.5 L 517 318.5 L 519 316.5 L 521 311.5 L 523 309.5 L 525 304.5 L 527 302.5 L 528 299.5 L 530 297.5 L 532 292.5 L 534 290.5 L 536 285.5 L 538 283.5 L 540 278.5 L 542 276.5 L 544 271.5 L 546 269.5 L 547.5 266 Z "/>
<path fill="#cb2026" d="M 429.5 303 Q 431.8 302.8 432 304.5 L 432 305.5 L 435 309.5 L 437 314.5 L 439 316.5 L 441 321.5 L 443 323.5 L 445 328.5 L 447 330.5 L 449 335.5 L 451 337.5 L 451 338.5 L 454 342.5 L 456 347.5 L 458 349.5 L 460 354.5 L 462 356.5 L 464 361.5 L 466 363.5 L 468 368.5 L 470 370.5 L 472 375.5 L 474 377.5 L 475 380.5 L 477 382.5 L 479 387.5 L 481 389.5 L 483 394.5 L 485 396.5 L 485 397.5 L 486 398.5 L 487 401.5 L 489 403.5 L 491 408.5 L 493 410.5 L 493 411.5 L 496 415.5 L 498 420.5 L 500 422.5 L 502 427.5 L 504 429.5 L 506 434.5 L 508 436.5 L 510 441.5 L 512 443.5 L 514 448.5 L 516 450.5 L 516 451.5 L 519 455.5 L 521 460.5 L 523 462.5 L 525 467.5 L 527 469.5 L 529 474.5 L 531 476.5 L 533 481.5 L 535 483.5 L 536 486.5 L 538 488.5 L 540 493.5 L 542 495.5 L 544 500.5 L 546 502.5 L 548 507.5 L 550 509.5 L 552 514.5 L 554 516.5 L 556 521.5 L 558 523.5 L 558 524.5 L 561 528.5 L 563 533.5 L 565 535.5 L 567 540.5 L 569 542.5 L 571 547.5 L 573 549.5 L 573 550.5 L 575 553.5 L 575 555 L 574.5 555 L 285.5 555 Q 284.5 555.4 285 553.5 L 288 549.5 L 290 544.5 L 292 542.5 L 294 537.5 L 296 535.5 L 296 534.5 L 297 533.5 L 298 530.5 L 300 528.5 L 302 523.5 L 304 521.5 L 305 518.5 L 307 516.5 L 309 511.5 L 311 509.5 L 313 504.5 L 315 502.5 L 315 501.5 L 316 500.5 L 317 497.5 L 319 495.5 L 321 490.5 L 323 488.5 L 324 485.5 L 326 483.5 L 328 478.5 L 330 476.5 L 332 471.5 L 334 469.5 L 336 464.5 L 338 462.5 L 338 461.5 L 339 460.5 L 340 457.5 L 342 455.5 L 344 450.5 L 346 448.5 L 347 445.5 L 349 443.5 L 351 438.5 L 353 436.5 L 355 431.5 L 357 429.5 L 357 428.5 L 358 427.5 L 359 424.5 L 361 422.5 L 363 417.5 L 365 415.5 L 366 412.5 L 368 410.5 L 370 405.5 L 372 403.5 L 374 398.5 L 376 396.5 L 378 391.5 L 380 389.5 L 380 388.5 L 381 387.5 L 382 384.5 L 384 382.5 L 386 377.5 L 388 375.5 L 389 372.5 L 391 370.5 L 393 365.5 L 395 363.5 L 397 358.5 L 399 356.5 L 401 351.5 L 403 349.5 L 405 344.5 L 407 342.5 L 408 339.5 L 410 337.5 L 412 332.5 L 414 330.5 L 416 325.5 L 418 323.5 L 420 318.5 L 422 316.5 L 424 311.5 L 426 309.5 L 428 304.5 L 429.5 303 Z "/>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="layer1"
x="0px"
y="0px"
width="394.82101"
height="376.871"
viewBox="0 0 394.82101 376.871"
enable-background="new 0 0 374.82 356.871"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="cow_mailcow.svg"><metadata
id="metadata77"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title><cc:license
rdf:resource="" /></cc:Work></rdf:RDF></metadata><defs
id="defs75" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1721"
inkscape:window-height="1177"
id="namedview73"
showgrid="false"
inkscape:zoom="1.4142136"
inkscape:cx="179.01206"
inkscape:cy="236.74715"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
fit-margin-top="10"
fit-margin-left="10"
fit-margin-bottom="10"
fit-margin-right="10"
showguides="true" /><g
id="g3"
transform="translate(10,10)"><g
id="grey_5_"><path
d="m 55.948,213.25 c 0.07331,-20.26146 -0.716379,-17.26061 -3.655806,-39.26743 2.227824,-22.4392 -7.627923,-38.85857 -7.669233,-58.34044 0,-4.715 -5.805961,-6.78013 -4.760961,-11.13713 -6.292,13.037 -9.833,27.707 -9.833,43.222 0,25.946 9.89,49.533 26.027,67.059 -0.048,-0.511 -0.082,-1.023 -0.108,-1.536 z"
id="path6"
inkscape:connector-curvature="0"
style="fill:#3d5263"
sodipodi:nodetypes="ccccscc" /></g><g
id="yellow"><path
d="m 254.808,180.412 -0.567,0.455 c -10.49,39.88 -40.951,71.658 -80.048,83.996 l 10.952,9.206 53.296,44.799 31.601,26.563 c 0.783,-2.011 1.229,-4.19 1.231,-6.478 0,-0.007 10e-4,-0.013 10e-4,-0.02 l 0,-16.836 0,-10e-4 0,-28.141 0,-126.736 -16.466,13.193 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#f9e82d" /><path
d="m 23.027,185.52 -6.574,-5.225 -16.452,-13.076 0,90.407 0,81.307 c 0,2.295 0.447,4.481 1.233,6.499 l 58.39,-48.683 26.964,-22.481 12.38,-10.321 C 62.73,251.524 34.307,222.274 23.027,185.52 Z"
id="path11"
inkscape:connector-curvature="0"
style="fill:#f9e82d" /><path
d="m 238.441,318.868 -53.296,-44.799 -10.952,-9.206 c -11.431,3.607 -23.597,5.558 -36.22,5.558 -13.653,0 -26.772,-2.28 -39.004,-6.474 l -12.38,10.321 -26.965,22.482 -58.39,48.683 c 2.605,6.69 9.094,11.438 16.706,11.438 l 235.394,0 c 7.613,0 14.103,-4.749 16.707,-11.44 l -31.6,-26.563 z"
id="path13"
inkscape:connector-curvature="0"
style="fill:#edd514;fill-opacity:0.89499996" /></g><g
id="grey_4_"><path
enable-background="new "
d="M 238.441,318.868 C 196.984,322.876 123.368,324.434 59.625,296.75 38.082,287.394 17.666,274.7 0.002,257.627 l 0,81.307 c 0,2.295 0.447,4.481 1.233,6.499 2.605,6.69 9.094,11.438 16.706,11.438 l 235.394,0 c 7.613,0 14.103,-4.749 16.707,-11.44 0.783,-2.011 1.229,-4.19 1.231,-6.478 l 0,-24.584 c 0,0 -12.58,2.541 -32.832,4.499 z"
id="path16"
inkscape:connector-curvature="0"
style="opacity:0.1;fill:#3d5263" /><path
enable-background="new "
d="m 86.588,274.268 c 14.979,6.703 31.579,10.435 49.051,10.435 17.648,0 34.408,-3.803 49.505,-10.634 37.082,-16.777 64.125,-51.824 69.664,-93.657 l -0.567,0.455 c -10.49,39.88 -40.951,71.658 -80.048,83.996 -11.431,3.607 -23.597,5.558 -36.22,5.558 -13.653,0 -26.772,-2.28 -39.004,-6.474 C 62.731,251.524 34.308,222.274 23.028,185.52 l -6.574,-5.225 c 5.525,42.054 32.786,77.261 70.134,93.973 z"
id="path18"
inkscape:connector-curvature="0"
style="opacity:0.1;fill:#3d5263" /></g><g
id="white_1_"><path
d="m 54.293,63.875 c -1.799,1.745 -3.541,3.548 -5.229,5.402 -0.042,0.046 -0.085,0.092 -0.127,0.139 -0.234,0.258 -0.473,0.51 -0.705,0.77 0.055,-0.055 0.111,-0.108 0.166,-0.163 21.76,-21.782 51.828,-35.259 85.046,-35.259 66.396,0 120.222,53.826 120.222,120.223 0,30.718 -11.526,58.74 -30.482,79.991 21.633,-21.737 35.006,-51.7 35.01,-84.791 0,-0.004 0,-0.009 0,-0.013 0,-21.143 -5.465,-41.007 -15.049,-58.269 -1.449,-2.608 -2.991,-5.157 -4.624,-7.643 -5.377,-8.187 -11.727,-15.676 -18.885,-22.307 -5.903,-5.467 -12.351,-10.354 -19.26,-14.558 -4.278,-2.604 -8.734,-4.944 -13.341,-7.006 -10.627,-4.756 -22.07,-8.016 -34.062,-9.509 -4.915,-0.612 -9.921,-0.931 -15.001,-0.931 -5.747,0 -11.398,0.409 -16.93,1.189 -12.291,1.733 -23.981,5.329 -34.784,10.487 -4.742,2.264 -9.313,4.83 -13.688,7.672 -6.561,4.266 -12.682,9.149 -18.277,14.576 z"
id="path21"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 95.828,118.535 c 2.559,0 4.63,-2.071 4.63,-4.629 0,-2.553 -2.071,-4.626 -4.63,-4.626 -2.558,0 -4.634,2.074 -4.634,4.626 10e-4,2.557 2.076,4.629 4.634,4.629 z"
id="path23"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 186.85,118.535 c 2.556,0 4.629,-2.071 4.629,-4.629 0,-2.553 -2.074,-4.626 -4.629,-4.626 -2.559,0 -4.631,2.074 -4.631,4.626 0,2.557 2.073,4.629 4.631,4.629 z"
id="path25"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g><g
id="grey_3_"><g
id="g28"><path
d="m 223.701,234.394 c 18.648,-21.18 29.965,-48.971 29.965,-79.408 0,-66.396 -53.825,-120.223 -120.222,-120.223 -33.218,0 -63.286,13.477 -85.046,35.259 -4.591,5.125 -8.746,10.647 -12.413,16.507 -1.524,2.437 -2.963,4.931 -4.314,7.48 -7.067,13.341 -11.704,28.167 -13.301,43.893 -0.411,4.043 -0.622,8.146 -0.622,12.298 0,3.849 0.188,7.653 0.542,11.409 0.776,8.241 2.38,16.24 4.735,23.912 11.281,36.754 39.703,66.004 75.941,78.427 12.231,4.193 25.351,6.474 39.004,6.474 12.623,0 24.79,-1.95 36.22,-5.558 18.139,-5.725 34.412,-15.64 47.7,-28.603 0.536,-0.522 1.811,-1.867 1.811,-1.867 z m -5.788,-58.356 c -2.132,7.217 -5.052,14.085 -8.668,20.495 -16.571,29.372 -47.64,49.146 -83.233,49.146 -27.584,0 -52.447,-11.88 -69.956,-30.895 C 39.919,197.26 30.03,173.673 30.03,147.726 c 0,-15.515 3.54,-30.185 9.833,-43.222 15.648,-32.42 48.344,-54.73 86.15,-54.73 3.967,0 7.876,0.25 11.717,0.728 47.479,5.898 84.262,47.175 84.262,97.224 -0.002,9.846 -1.431,19.348 -4.079,28.312 z"
id="path30"
inkscape:connector-curvature="0"
style="fill:#f1f2f2" /></g><path
d="m 49.064,69.277 c -0.042,0.046 -0.085,0.092 -0.127,0.139 0.042,-0.047 0.085,-0.093 0.127,-0.139 z"
id="path32"
inkscape:connector-curvature="0"
style="fill:#f1f2f2" /></g><g
id="darkbrown_1_"><path
d="m 257.626,161.89 c -0.488,5.062 -1.29,10.032 -2.387,14.89 -0.31,1.371 -0.643,2.733 -0.999,4.086 l 0.567,-0.455 16.466,-13.193 0,-0.023 -13.647,-5.305 z"
id="path35"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 0.001,167.219 16.451,13.076 6.574,5.225 c -2.354,-7.672 -3.959,-15.671 -4.735,-23.912 l -2.85,0.871 L 0,167.196"
id="path37"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 87.491,192.337 c -6.21,0 -11.254,5.034 -11.254,11.257 0,6.216 5.043,11.257 11.254,11.257 6.221,0 11.261,-5.041 11.261,-11.257 0,-6.223 -5.041,-11.257 -11.261,-11.257 z"
id="path39"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 181.307,192.337 c -6.218,0 -11.259,5.034 -11.259,11.257 0,6.216 5.041,11.257 11.259,11.257 6.22,0 11.257,-5.041 11.257,-11.257 0,-6.223 -5.037,-11.257 -11.257,-11.257 z"
id="path41"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 182.997,102.25057 c -6.963,0 -15.44243,7.76632 -15.44243,14.73532 0,6.965 8.12588,17.2072 15.08888,17.2072 6.968,0 15.79898,-9.53609 15.79898,-16.50009 0.001,-6.97 -8.47743,-15.44243 -15.44543,-15.44243 z m 3.853,16.28443 c -2.558,0 -4.631,-2.072 -4.631,-4.629 0,-2.552 2.072,-4.626 4.631,-4.626 2.555,0 4.629,2.073 4.629,4.626 0,2.558 -2.073,4.629 -4.629,4.629 z"
id="path43"
inkscape:connector-curvature="0"
style="fill:#5a3620"
sodipodi:nodetypes="ssscssssss" /><path
d="m 89.709786,102.60413 c -6.971,0 -14.379767,8.11987 -14.379767,15.08887 0,6.965 8.824981,16.14653 15.793981,16.14653 6.963,0 15.79298,-9.18253 15.79298,-16.14653 0.001,-6.97 -10.243194,-15.08887 -17.207194,-15.08887 z M 95.828,118.535 c -2.559,0 -4.634,-2.072 -4.634,-4.629 0,-2.552 2.076,-4.626 4.634,-4.626 2.559,0 4.63,2.073 4.63,4.626 0,2.558 -2.071,4.629 -4.63,4.629 z"
id="path45"
inkscape:connector-curvature="0"
style="fill:#5a3620"
sodipodi:nodetypes="ssscssssss" /></g><g
id="cream"><path
d="m 336.302,256.425 c 3.59,-9.155 7.701,-11 9.346,-11.346 -40.757,3.757 -36.661,27.769 -34.026,35.96 0.55,1.712 1.037,2.733 1.037,2.733 0,0 2.031,4.787 7.536,8.748 4.149,2.986 10.27,5.503 18.995,5.144 27.063,0.461 35.631,-50.166 35.631,-50.166 -6.654,11.655 -26.404,9.876 -38.519,8.927 z"
id="path48"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 48.937,69.415 c 0.042,-0.046 0.085,-0.092 0.127,-0.139 1.688,-1.854 3.43,-3.657 5.229,-5.402 -8.915,-6.977 -24.344,-15.826 -41.744,-11.633 0,0 2.814,20.458 23.437,34.287 3.667,-5.86 7.822,-11.381 12.413,-16.507 -0.055,0.055 -0.111,0.108 -0.166,0.163 0.231,-0.258 0.47,-0.511 0.704,-0.769 z"
id="path50"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 258.812,52.242 c -15.831,-3.815 -30.029,3.169 -39.176,9.714 7.158,6.63 13.508,14.12 18.885,22.307 17.763,-13.689 20.291,-32.021 20.291,-32.021 z"
id="path52"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 134.269,160.225 c -43.299,0 -78.388,22.964 -78.388,51.289 0,0.582 0.038,1.157 0.067,1.735 0.026,0.514 0.06,1.025 0.108,1.535 17.508,19.015 42.371,30.895 69.956,30.895 35.594,0 66.662,-19.774 83.233,-49.146 -9.796,-21.016 -39.651,-36.308 -74.976,-36.308 z M 87.491,214.85 c -6.211,0 -11.254,-5.041 -11.254,-11.257 0,-6.223 5.044,-11.257 11.254,-11.257 6.22,0 11.261,5.034 11.261,11.257 0,6.216 -5.04,11.257 -11.261,11.257 z m 93.816,0 c -6.218,0 -11.259,-5.041 -11.259,-11.257 0,-6.223 5.041,-11.257 11.259,-11.257 6.22,0 11.257,5.034 11.257,11.257 0,6.216 -5.037,11.257 -11.257,11.257 z"
id="path54"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="M 86.265,0 C 68.102,16.373 86.113,41.427 86.258,41.628 97.061,36.47 108.751,32.874 121.042,31.141 97.629,27.686 86.265,0 86.265,0 Z"
id="path56"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 186.204,0 c 0,0 -10.863,26.476 -33.231,30.883 11.992,1.493 23.435,4.752 34.062,9.509 C 190.383,35.136 202.036,14.271 186.204,0 Z"
id="path58"
inkscape:connector-curvature="0"
style="fill:#fef3df" /></g><g
id="g60"><path
d="m 217.913,176.038 c 2.647,-8.964 6.55187,-25.89162 6.55187,-35.73662 C 224.46487,90.252379 185.208,56.4 137.728,50.502 c -2.157,28.03 3.629,87.043 80.185,125.536 z m -47.53,-58.345 c 0,-6.97 5.651,-12.614 12.614,-12.614 6.968,0 12.617,5.645 12.617,12.614 0,6.964 -5.649,12.611 -12.617,12.611 -6.963,0 -12.614,-5.646 -12.614,-12.611 z"
id="path62"
inkscape:connector-curvature="0"
style="fill:#87654a"
sodipodi:nodetypes="csccsssss" /></g><g
id="brown"><path
d="m 312.658,283.772 c 0,0 -0.487,-1.021 -1.037,-2.733 -3.758,3.317 -13.036,10.236 -27.03,12.416 l 0,-10e-4 c -0.009,0.002 -0.019,0.003 -0.027,0.005 -4.044,0.628 -8.479,0.863 -13.29,0.497 l 0,28.141 c 2.059,-0.801 4.607,-1.834 7.477,-3.083 5.462,-2.377 12.093,-5.542 18.771,-9.395 0.027,-0.016 0.054,-0.031 0.081,-0.047 8.158,-4.713 16.37,-10.452 22.593,-17.052 -5.506,-3.961 -7.538,-8.748 -7.538,-8.748 z"
id="path65"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 12.549,52.242 c 17.4,-4.193 32.83,4.656 41.744,11.633 C 59.888,58.449 66.009,53.565 72.57,49.301 48.272,18.498 2.169,37.201 2.169,37.201 -1.114,67.502 15.288,84.594 31.672,94.01 33.023,91.461 34.462,88.966 35.986,86.53 15.363,72.699 12.549,52.242 12.549,52.242 Z"
id="path67"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 200.376,47.398 c 6.909,4.205 13.356,9.091 19.26,14.558 9.146,-6.545 23.345,-13.529 39.176,-9.714 0,0 -2.527,18.332 -20.291,32.021 1.633,2.485 3.175,5.034 4.624,7.643 15.141,-9.784 29.097,-26.539 26.046,-54.704 0,-10e-4 -44.152,-17.909 -68.815,10.196 z"
id="path69"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 138.854,50.502 c -3.841,-0.478 -8.875,-0.728 -12.842,-0.728 -37.806,0 -70.502,22.31 -86.15,54.73 -1.045,4.357 -1.603,8.897 -1.603,13.612 0,1.454 0.085,2.787 0.121,4.175 0.127,3.935 0.448,7.585 0.855,11.135 4.291755,24.95762 7.959057,42.49186 13.464,66.758 0.056,0.407 0.164,0.804 0.224,1.211 0.617,4.028 1.642,7.992 3.025,11.854 -0.029,-0.578 -0.067,-1.153 -0.067,-1.735 0,-28.325 35.089,-51.289 78.388,-51.289 35.325,0 65.181,15.292 74.977,36.308 3.616,-6.409 6.536,-13.277 8.668,-20.495 C 179.98905,152.54886 163.9995,134.88987 153.25313,111.82124 142.50675,88.752624 137.775,64.517 138.854,50.502 Z m -47.73,79.802 c -6.97,0 -12.612,-5.646 -12.612,-12.611 0,-6.97 5.642,-12.614 12.612,-12.614 6.964,0 12.611,5.645 12.611,12.614 0.001,6.964 -5.648,12.611 -12.611,12.611 z"
id="path71"
inkscape:connector-curvature="0"
style="fill:#b58765"
sodipodi:nodetypes="cscscccccssccscssscs" /></g></g></svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="layer1"
x="0px"
y="0px"
width="394.82101"
height="376.871"
viewBox="0 0 394.82101 376.871"
enable-background="new 0 0 374.82 356.871"
xml:space="preserve"
inkscape:version="0.91 r13725"
sodipodi:docname="cow_mailcow.svg"><metadata
id="metadata77"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title><cc:license
rdf:resource="" /></cc:Work></rdf:RDF></metadata><defs
id="defs75" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1721"
inkscape:window-height="1177"
id="namedview73"
showgrid="false"
inkscape:zoom="1.4142136"
inkscape:cx="179.01206"
inkscape:cy="236.74715"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
fit-margin-top="10"
fit-margin-left="10"
fit-margin-bottom="10"
fit-margin-right="10"
showguides="true" /><g
id="g3"
transform="translate(10,10)"><g
id="grey_5_"><path
d="m 55.948,213.25 c 0.07331,-20.26146 -0.716379,-17.26061 -3.655806,-39.26743 2.227824,-22.4392 -7.627923,-38.85857 -7.669233,-58.34044 0,-4.715 -5.805961,-6.78013 -4.760961,-11.13713 -6.292,13.037 -9.833,27.707 -9.833,43.222 0,25.946 9.89,49.533 26.027,67.059 -0.048,-0.511 -0.082,-1.023 -0.108,-1.536 z"
id="path6"
inkscape:connector-curvature="0"
style="fill:#3d5263"
sodipodi:nodetypes="ccccscc" /></g><g
id="yellow"><path
d="m 254.808,180.412 -0.567,0.455 c -10.49,39.88 -40.951,71.658 -80.048,83.996 l 10.952,9.206 53.296,44.799 31.601,26.563 c 0.783,-2.011 1.229,-4.19 1.231,-6.478 0,-0.007 10e-4,-0.013 10e-4,-0.02 l 0,-16.836 0,-10e-4 0,-28.141 0,-126.736 -16.466,13.193 z"
id="path9"
inkscape:connector-curvature="0"
style="fill:#f9e82d" /><path
d="m 23.027,185.52 -6.574,-5.225 -16.452,-13.076 0,90.407 0,81.307 c 0,2.295 0.447,4.481 1.233,6.499 l 58.39,-48.683 26.964,-22.481 12.38,-10.321 C 62.73,251.524 34.307,222.274 23.027,185.52 Z"
id="path11"
inkscape:connector-curvature="0"
style="fill:#f9e82d" /><path
d="m 238.441,318.868 -53.296,-44.799 -10.952,-9.206 c -11.431,3.607 -23.597,5.558 -36.22,5.558 -13.653,0 -26.772,-2.28 -39.004,-6.474 l -12.38,10.321 -26.965,22.482 -58.39,48.683 c 2.605,6.69 9.094,11.438 16.706,11.438 l 235.394,0 c 7.613,0 14.103,-4.749 16.707,-11.44 l -31.6,-26.563 z"
id="path13"
inkscape:connector-curvature="0"
style="fill:#edd514;fill-opacity:0.89499996" /></g><g
id="grey_4_"><path
enable-background="new "
d="M 238.441,318.868 C 196.984,322.876 123.368,324.434 59.625,296.75 38.082,287.394 17.666,274.7 0.002,257.627 l 0,81.307 c 0,2.295 0.447,4.481 1.233,6.499 2.605,6.69 9.094,11.438 16.706,11.438 l 235.394,0 c 7.613,0 14.103,-4.749 16.707,-11.44 0.783,-2.011 1.229,-4.19 1.231,-6.478 l 0,-24.584 c 0,0 -12.58,2.541 -32.832,4.499 z"
id="path16"
inkscape:connector-curvature="0"
style="opacity:0.1;fill:#3d5263" /><path
enable-background="new "
d="m 86.588,274.268 c 14.979,6.703 31.579,10.435 49.051,10.435 17.648,0 34.408,-3.803 49.505,-10.634 37.082,-16.777 64.125,-51.824 69.664,-93.657 l -0.567,0.455 c -10.49,39.88 -40.951,71.658 -80.048,83.996 -11.431,3.607 -23.597,5.558 -36.22,5.558 -13.653,0 -26.772,-2.28 -39.004,-6.474 C 62.731,251.524 34.308,222.274 23.028,185.52 l -6.574,-5.225 c 5.525,42.054 32.786,77.261 70.134,93.973 z"
id="path18"
inkscape:connector-curvature="0"
style="opacity:0.1;fill:#3d5263" /></g><g
id="white_1_"><path
d="m 54.293,63.875 c -1.799,1.745 -3.541,3.548 -5.229,5.402 -0.042,0.046 -0.085,0.092 -0.127,0.139 -0.234,0.258 -0.473,0.51 -0.705,0.77 0.055,-0.055 0.111,-0.108 0.166,-0.163 21.76,-21.782 51.828,-35.259 85.046,-35.259 66.396,0 120.222,53.826 120.222,120.223 0,30.718 -11.526,58.74 -30.482,79.991 21.633,-21.737 35.006,-51.7 35.01,-84.791 0,-0.004 0,-0.009 0,-0.013 0,-21.143 -5.465,-41.007 -15.049,-58.269 -1.449,-2.608 -2.991,-5.157 -4.624,-7.643 -5.377,-8.187 -11.727,-15.676 -18.885,-22.307 -5.903,-5.467 -12.351,-10.354 -19.26,-14.558 -4.278,-2.604 -8.734,-4.944 -13.341,-7.006 -10.627,-4.756 -22.07,-8.016 -34.062,-9.509 -4.915,-0.612 -9.921,-0.931 -15.001,-0.931 -5.747,0 -11.398,0.409 -16.93,1.189 -12.291,1.733 -23.981,5.329 -34.784,10.487 -4.742,2.264 -9.313,4.83 -13.688,7.672 -6.561,4.266 -12.682,9.149 -18.277,14.576 z"
id="path21"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 95.828,118.535 c 2.559,0 4.63,-2.071 4.63,-4.629 0,-2.553 -2.071,-4.626 -4.63,-4.626 -2.558,0 -4.634,2.074 -4.634,4.626 10e-4,2.557 2.076,4.629 4.634,4.629 z"
id="path23"
inkscape:connector-curvature="0"
style="fill:#ffffff" /><path
d="m 186.85,118.535 c 2.556,0 4.629,-2.071 4.629,-4.629 0,-2.553 -2.074,-4.626 -4.629,-4.626 -2.559,0 -4.631,2.074 -4.631,4.626 0,2.557 2.073,4.629 4.631,4.629 z"
id="path25"
inkscape:connector-curvature="0"
style="fill:#ffffff" /></g><g
id="grey_3_"><g
id="g28"><path
d="m 223.701,234.394 c 18.648,-21.18 29.965,-48.971 29.965,-79.408 0,-66.396 -53.825,-120.223 -120.222,-120.223 -33.218,0 -63.286,13.477 -85.046,35.259 -4.591,5.125 -8.746,10.647 -12.413,16.507 -1.524,2.437 -2.963,4.931 -4.314,7.48 -7.067,13.341 -11.704,28.167 -13.301,43.893 -0.411,4.043 -0.622,8.146 -0.622,12.298 0,3.849 0.188,7.653 0.542,11.409 0.776,8.241 2.38,16.24 4.735,23.912 11.281,36.754 39.703,66.004 75.941,78.427 12.231,4.193 25.351,6.474 39.004,6.474 12.623,0 24.79,-1.95 36.22,-5.558 18.139,-5.725 34.412,-15.64 47.7,-28.603 0.536,-0.522 1.811,-1.867 1.811,-1.867 z m -5.788,-58.356 c -2.132,7.217 -5.052,14.085 -8.668,20.495 -16.571,29.372 -47.64,49.146 -83.233,49.146 -27.584,0 -52.447,-11.88 -69.956,-30.895 C 39.919,197.26 30.03,173.673 30.03,147.726 c 0,-15.515 3.54,-30.185 9.833,-43.222 15.648,-32.42 48.344,-54.73 86.15,-54.73 3.967,0 7.876,0.25 11.717,0.728 47.479,5.898 84.262,47.175 84.262,97.224 -0.002,9.846 -1.431,19.348 -4.079,28.312 z"
id="path30"
inkscape:connector-curvature="0"
style="fill:#f1f2f2" /></g><path
d="m 49.064,69.277 c -0.042,0.046 -0.085,0.092 -0.127,0.139 0.042,-0.047 0.085,-0.093 0.127,-0.139 z"
id="path32"
inkscape:connector-curvature="0"
style="fill:#f1f2f2" /></g><g
id="darkbrown_1_"><path
d="m 257.626,161.89 c -0.488,5.062 -1.29,10.032 -2.387,14.89 -0.31,1.371 -0.643,2.733 -0.999,4.086 l 0.567,-0.455 16.466,-13.193 0,-0.023 -13.647,-5.305 z"
id="path35"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 0.001,167.219 16.451,13.076 6.574,5.225 c -2.354,-7.672 -3.959,-15.671 -4.735,-23.912 l -2.85,0.871 L 0,167.196"
id="path37"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 87.491,192.337 c -6.21,0 -11.254,5.034 -11.254,11.257 0,6.216 5.043,11.257 11.254,11.257 6.221,0 11.261,-5.041 11.261,-11.257 0,-6.223 -5.041,-11.257 -11.261,-11.257 z"
id="path39"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 181.307,192.337 c -6.218,0 -11.259,5.034 -11.259,11.257 0,6.216 5.041,11.257 11.259,11.257 6.22,0 11.257,-5.041 11.257,-11.257 0,-6.223 -5.037,-11.257 -11.257,-11.257 z"
id="path41"
inkscape:connector-curvature="0"
style="fill:#5a3620" /><path
d="m 182.997,102.25057 c -6.963,0 -15.44243,7.76632 -15.44243,14.73532 0,6.965 8.12588,17.2072 15.08888,17.2072 6.968,0 15.79898,-9.53609 15.79898,-16.50009 0.001,-6.97 -8.47743,-15.44243 -15.44543,-15.44243 z m 3.853,16.28443 c -2.558,0 -4.631,-2.072 -4.631,-4.629 0,-2.552 2.072,-4.626 4.631,-4.626 2.555,0 4.629,2.073 4.629,4.626 0,2.558 -2.073,4.629 -4.629,4.629 z"
id="path43"
inkscape:connector-curvature="0"
style="fill:#5a3620"
sodipodi:nodetypes="ssscssssss" /><path
d="m 89.709786,102.60413 c -6.971,0 -14.379767,8.11987 -14.379767,15.08887 0,6.965 8.824981,16.14653 15.793981,16.14653 6.963,0 15.79298,-9.18253 15.79298,-16.14653 0.001,-6.97 -10.243194,-15.08887 -17.207194,-15.08887 z M 95.828,118.535 c -2.559,0 -4.634,-2.072 -4.634,-4.629 0,-2.552 2.076,-4.626 4.634,-4.626 2.559,0 4.63,2.073 4.63,4.626 0,2.558 -2.071,4.629 -4.63,4.629 z"
id="path45"
inkscape:connector-curvature="0"
style="fill:#5a3620"
sodipodi:nodetypes="ssscssssss" /></g><g
id="cream"><path
d="m 336.302,256.425 c 3.59,-9.155 7.701,-11 9.346,-11.346 -40.757,3.757 -36.661,27.769 -34.026,35.96 0.55,1.712 1.037,2.733 1.037,2.733 0,0 2.031,4.787 7.536,8.748 4.149,2.986 10.27,5.503 18.995,5.144 27.063,0.461 35.631,-50.166 35.631,-50.166 -6.654,11.655 -26.404,9.876 -38.519,8.927 z"
id="path48"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 48.937,69.415 c 0.042,-0.046 0.085,-0.092 0.127,-0.139 1.688,-1.854 3.43,-3.657 5.229,-5.402 -8.915,-6.977 -24.344,-15.826 -41.744,-11.633 0,0 2.814,20.458 23.437,34.287 3.667,-5.86 7.822,-11.381 12.413,-16.507 -0.055,0.055 -0.111,0.108 -0.166,0.163 0.231,-0.258 0.47,-0.511 0.704,-0.769 z"
id="path50"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 258.812,52.242 c -15.831,-3.815 -30.029,3.169 -39.176,9.714 7.158,6.63 13.508,14.12 18.885,22.307 17.763,-13.689 20.291,-32.021 20.291,-32.021 z"
id="path52"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 134.269,160.225 c -43.299,0 -78.388,22.964 -78.388,51.289 0,0.582 0.038,1.157 0.067,1.735 0.026,0.514 0.06,1.025 0.108,1.535 17.508,19.015 42.371,30.895 69.956,30.895 35.594,0 66.662,-19.774 83.233,-49.146 -9.796,-21.016 -39.651,-36.308 -74.976,-36.308 z M 87.491,214.85 c -6.211,0 -11.254,-5.041 -11.254,-11.257 0,-6.223 5.044,-11.257 11.254,-11.257 6.22,0 11.261,5.034 11.261,11.257 0,6.216 -5.04,11.257 -11.261,11.257 z m 93.816,0 c -6.218,0 -11.259,-5.041 -11.259,-11.257 0,-6.223 5.041,-11.257 11.259,-11.257 6.22,0 11.257,5.034 11.257,11.257 0,6.216 -5.037,11.257 -11.257,11.257 z"
id="path54"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="M 86.265,0 C 68.102,16.373 86.113,41.427 86.258,41.628 97.061,36.47 108.751,32.874 121.042,31.141 97.629,27.686 86.265,0 86.265,0 Z"
id="path56"
inkscape:connector-curvature="0"
style="fill:#fef3df" /><path
d="m 186.204,0 c 0,0 -10.863,26.476 -33.231,30.883 11.992,1.493 23.435,4.752 34.062,9.509 C 190.383,35.136 202.036,14.271 186.204,0 Z"
id="path58"
inkscape:connector-curvature="0"
style="fill:#fef3df" /></g><g
id="g60"><path
d="m 217.913,176.038 c 2.647,-8.964 6.55187,-25.89162 6.55187,-35.73662 C 224.46487,90.252379 185.208,56.4 137.728,50.502 c -2.157,28.03 3.629,87.043 80.185,125.536 z m -47.53,-58.345 c 0,-6.97 5.651,-12.614 12.614,-12.614 6.968,0 12.617,5.645 12.617,12.614 0,6.964 -5.649,12.611 -12.617,12.611 -6.963,0 -12.614,-5.646 -12.614,-12.611 z"
id="path62"
inkscape:connector-curvature="0"
style="fill:#87654a"
sodipodi:nodetypes="csccsssss" /></g><g
id="brown"><path
d="m 312.658,283.772 c 0,0 -0.487,-1.021 -1.037,-2.733 -3.758,3.317 -13.036,10.236 -27.03,12.416 l 0,-10e-4 c -0.009,0.002 -0.019,0.003 -0.027,0.005 -4.044,0.628 -8.479,0.863 -13.29,0.497 l 0,28.141 c 2.059,-0.801 4.607,-1.834 7.477,-3.083 5.462,-2.377 12.093,-5.542 18.771,-9.395 0.027,-0.016 0.054,-0.031 0.081,-0.047 8.158,-4.713 16.37,-10.452 22.593,-17.052 -5.506,-3.961 -7.538,-8.748 -7.538,-8.748 z"
id="path65"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 12.549,52.242 c 17.4,-4.193 32.83,4.656 41.744,11.633 C 59.888,58.449 66.009,53.565 72.57,49.301 48.272,18.498 2.169,37.201 2.169,37.201 -1.114,67.502 15.288,84.594 31.672,94.01 33.023,91.461 34.462,88.966 35.986,86.53 15.363,72.699 12.549,52.242 12.549,52.242 Z"
id="path67"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 200.376,47.398 c 6.909,4.205 13.356,9.091 19.26,14.558 9.146,-6.545 23.345,-13.529 39.176,-9.714 0,0 -2.527,18.332 -20.291,32.021 1.633,2.485 3.175,5.034 4.624,7.643 15.141,-9.784 29.097,-26.539 26.046,-54.704 0,-10e-4 -44.152,-17.909 -68.815,10.196 z"
id="path69"
inkscape:connector-curvature="0"
style="fill:#b58765" /><path
d="m 138.854,50.502 c -3.841,-0.478 -8.875,-0.728 -12.842,-0.728 -37.806,0 -70.502,22.31 -86.15,54.73 -1.045,4.357 -1.603,8.897 -1.603,13.612 0,1.454 0.085,2.787 0.121,4.175 0.127,3.935 0.448,7.585 0.855,11.135 4.291755,24.95762 7.959057,42.49186 13.464,66.758 0.056,0.407 0.164,0.804 0.224,1.211 0.617,4.028 1.642,7.992 3.025,11.854 -0.029,-0.578 -0.067,-1.153 -0.067,-1.735 0,-28.325 35.089,-51.289 78.388,-51.289 35.325,0 65.181,15.292 74.977,36.308 3.616,-6.409 6.536,-13.277 8.668,-20.495 C 179.98905,152.54886 163.9995,134.88987 153.25313,111.82124 142.50675,88.752624 137.775,64.517 138.854,50.502 Z m -47.73,79.802 c -6.97,0 -12.612,-5.646 -12.612,-12.611 0,-6.97 5.642,-12.614 12.612,-12.614 6.964,0 12.611,5.645 12.611,12.614 0.001,6.964 -5.648,12.611 -12.611,12.611 z"
id="path71"
inkscape:connector-curvature="0"
style="fill:#b58765"
sodipodi:nodetypes="cscscccccssccscssscs" /></g></g></svg>

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 400 134.7" style="enable-background:new 0 0 400 134.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:#007DC1;}
</style>
<g>
<g>
<g>
<path class="st0" d="M50.3,33.8C22.5,33.8,0,56.3,0,84.1s22.5,50.3,50.3,50.3s50.3-22.5,50.3-50.3S78.1,33.8,50.3,33.8z
M50.3,109.3c-13.9,0-25.2-11.3-25.2-25.2s11.3-25.2,25.2-25.2s25.2,11.3,25.2,25.2S64.2,109.3,50.3,109.3z"/>
</g>
<path class="st0" d="M138.7,101c0-4,4.8-5.9,7.6-3.1c12.6,12.8,33.4,34.8,33.5,34.9c0.3,0.3,0.6,0.8,1.8,1.2
c0.5,0.2,1.3,0.2,2.2,0.2l22.7,0c4.1,0,5.3-4.7,3.4-7.1l-37.6-38.5l-2-2c-4.3-5.1-3.8-7.1,1.1-12.3L201.2,41c1.9-2.4,0.7-7-3.5-7
h-20.6c-0.8,0-1.4,0-2,0.2c-1.2,0.4-1.7,0.8-2,1.2c-0.1,0.1-16.6,17.9-26.8,28.8c-2.8,3-7.8,1-7.8-3.1l0-57.1c0-2.9-2.4-4-4.3-4
h-16.8c-2.9,0-4.3,1.9-4.3,3.6v126.6c0,2.9,2.4,3.7,4.4,3.7h16.8c2.6,0,4.3-1.9,4.3-3.8v-1.3V101z"/>
<path class="st0" d="M275.9,129.6l-1.8-16.8c-0.2-2.3-2.4-3.9-4.7-3.5c-1.3,0.2-2.6,0.3-3.9,0.3c-13.4,0-24.3-10.5-25.1-23.8
c0-0.4,0-0.9,0-1.4V63.8c0-2.7,2-4.9,4.7-4.9l22.5,0c1.6,0,4-1.4,4-4.3V38.7c0-3.1-2-4.7-3.8-4.7h-22.7c-2.6,0-4.7-1.9-4.8-4.5
l0-25.5c0-1.6-1.2-4-4.3-4h-16.7c-2.1,0-4.1,1.3-4.1,3.9c0,0,0,81.5,0,81.9c0.7,27.2,23,48.9,50.3,48.9c2.3,0,4.5-0.2,6.7-0.5
C274.6,133.9,276.2,131.9,275.9,129.6z"/>
</g>
<g>
<path class="st0" d="M397.1,108.5c-14.2,0-16.4-5.1-16.4-24.2c0-0.1,0-0.1,0-0.2l0-45.9c0-1.6-1.2-4.3-4.4-4.3h-16.8
c-2.1,0-4.4,1.7-4.4,4.3l0,2.1c-7.3-4.2-15.8-6.6-24.8-6.6c-27.8,0-50.3,22.5-50.3,50.3c0,27.8,22.5,50.3,50.3,50.3
c12.5,0,23.9-4.6,32.7-12.1c4.7,7.2,12.3,12,24.2,12.1c2,0,12.8,0.4,12.8-4.7v-17.9C400,110.2,398.8,108.5,397.1,108.5z
M330.4,109.3c-13.9,0-25.2-11.3-25.2-25.2c0-13.9,11.3-25.2,25.2-25.2c13.9,0,25.2,11.3,25.2,25.2
C355.5,98,344.2,109.3,330.4,109.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 400 134.7" style="enable-background:new 0 0 400 134.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:#007DC1;}
</style>
<g>
<g>
<g>
<path class="st0" d="M50.3,33.8C22.5,33.8,0,56.3,0,84.1s22.5,50.3,50.3,50.3s50.3-22.5,50.3-50.3S78.1,33.8,50.3,33.8z
M50.3,109.3c-13.9,0-25.2-11.3-25.2-25.2s11.3-25.2,25.2-25.2s25.2,11.3,25.2,25.2S64.2,109.3,50.3,109.3z"/>
</g>
<path class="st0" d="M138.7,101c0-4,4.8-5.9,7.6-3.1c12.6,12.8,33.4,34.8,33.5,34.9c0.3,0.3,0.6,0.8,1.8,1.2
c0.5,0.2,1.3,0.2,2.2,0.2l22.7,0c4.1,0,5.3-4.7,3.4-7.1l-37.6-38.5l-2-2c-4.3-5.1-3.8-7.1,1.1-12.3L201.2,41c1.9-2.4,0.7-7-3.5-7
h-20.6c-0.8,0-1.4,0-2,0.2c-1.2,0.4-1.7,0.8-2,1.2c-0.1,0.1-16.6,17.9-26.8,28.8c-2.8,3-7.8,1-7.8-3.1l0-57.1c0-2.9-2.4-4-4.3-4
h-16.8c-2.9,0-4.3,1.9-4.3,3.6v126.6c0,2.9,2.4,3.7,4.4,3.7h16.8c2.6,0,4.3-1.9,4.3-3.8v-1.3V101z"/>
<path class="st0" d="M275.9,129.6l-1.8-16.8c-0.2-2.3-2.4-3.9-4.7-3.5c-1.3,0.2-2.6,0.3-3.9,0.3c-13.4,0-24.3-10.5-25.1-23.8
c0-0.4,0-0.9,0-1.4V63.8c0-2.7,2-4.9,4.7-4.9l22.5,0c1.6,0,4-1.4,4-4.3V38.7c0-3.1-2-4.7-3.8-4.7h-22.7c-2.6,0-4.7-1.9-4.8-4.5
l0-25.5c0-1.6-1.2-4-4.3-4h-16.7c-2.1,0-4.1,1.3-4.1,3.9c0,0,0,81.5,0,81.9c0.7,27.2,23,48.9,50.3,48.9c2.3,0,4.5-0.2,6.7-0.5
C274.6,133.9,276.2,131.9,275.9,129.6z"/>
</g>
<g>
<path class="st0" d="M397.1,108.5c-14.2,0-16.4-5.1-16.4-24.2c0-0.1,0-0.1,0-0.2l0-45.9c0-1.6-1.2-4.3-4.4-4.3h-16.8
c-2.1,0-4.4,1.7-4.4,4.3l0,2.1c-7.3-4.2-15.8-6.6-24.8-6.6c-27.8,0-50.3,22.5-50.3,50.3c0,27.8,22.5,50.3,50.3,50.3
c12.5,0,23.9-4.6,32.7-12.1c4.7,7.2,12.3,12,24.2,12.1c2,0,12.8,0.4,12.8-4.7v-17.9C400,110.2,398.8,108.5,397.1,108.5z
M330.4,109.3c-13.9,0-25.2-11.3-25.2-25.2c0-13.9,11.3-25.2,25.2-25.2c13.9,0,25.2,11.3,25.2,25.2
C355.5,98,344.2,109.3,330.4,109.3z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 24 24"
version="1.1"
>
<path
d="M14 3l-3 2v15c-4.059-.531-6-2.68-6-5 0-2.18 1.781-3.445 5-4.031V9c-4.95.629-8 2.754-8 6 0 3.383 3.102 6.512 9 7l3-2zm1 6v2a9.514 9.514 0 0 1 2.75 1.031l-1.656.938L22 14l-.313-4.156-1.625.875C18.684 9.883 16.945 9.289 15 9z"
fill="#ffffff"
/>
</svg>

After

Width:  |  Height:  |  Size: 456 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" version="1.1"><path d="M14 3l-3 2v15c-4.059-.531-6-2.68-6-5 0-2.18 1.781-3.445 5-4.031V9c-4.95.629-8 2.754-8 6 0 3.383 3.102 6.512 9 7l3-2zm1 6v2a9.514 9.514 0 0 1 2.75 1.031l-1.656.938L22 14l-.313-4.156-1.625.875C18.684 9.883 16.945 9.289 15 9z" id="surface1"/><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description about="https://iconscout.com/legal#licenses" dc:title="openid" dc:description="openid" dc:publisher="Iconscout" dc:date="2018-06-22" dc:format="image/svg+xml" dc:language="en"><dc:creator><rdf:Bag><rdf:li>Icons8</rdf:li></rdf:Bag></dc:creator></rdf:Description></rdf:RDF></metadata></svg>

After

Width:  |  Height:  |  Size: 878 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="256px" height="247px" viewBox="0 0 256 247" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M45.1355837,0 L45.1355837,246.35001 L0,246.35001 L0,0 L45.1355837,0 Z M163.657111,0 C214.65668,0 256,41.3433196 256,92.3428889 C256,143.342458 214.65668,184.685778 163.657111,184.685778 C112.657542,184.685778 71.3142222,143.342458 71.3142222,92.3428889 C71.3142222,41.3433196 112.657542,0 163.657111,0 Z" fill="#FF424D"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 587 B

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="256px" height="247px" viewBox="0 0 256 247" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path d="M45.1355837,0 L45.1355837,246.35001 L0,246.35001 L0,0 L45.1355837,0 Z M163.657111,0 C214.65668,0 256,41.3433196 256,92.3428889 C256,143.342458 214.65668,184.685778 163.657111,184.685778 C112.657542,184.685778 71.3142222,143.342458 71.3142222,92.3428889 C71.3142222,41.3433196 112.657542,0 163.657111,0 Z" fill="#FF424D"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 587 B

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path
d="M11.643 0H4.68l7.679 12L4.68 24h6.963l7.677-12-7.677-12"
fill="#ffffff"
/>
</svg>

After

Width:  |  Height:  |  Size: 226 B

View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title/><path d="M11.643 0H4.68l7.679 12L4.68 24h6.963l7.677-12-7.677-12"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"/>
</svg>

After

Width:  |  Height:  |  Size: 959 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M6.167 8a.83.83 0 0 0-.83.83c0 .459.372.84.83.831a.831.831 0 0 0 0-1.661m1.843 3.647c.315 0 1.403-.038 1.976-.611a.23.23 0 0 0 0-.306.213.213 0 0 0-.306 0c-.353.363-1.126.487-1.67.487-.545 0-1.308-.124-1.671-.487a.213.213 0 0 0-.306 0 .213.213 0 0 0 0 .306c.564.563 1.652.61 1.977.61zm.992-2.807c0 .458.373.83.831.83s.83-.381.83-.83a.831.831 0 0 0-1.66 0z"/>
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0m-3.828-1.165c-.315 0-.602.124-.812.325-.801-.573-1.9-.945-3.121-.993l.534-2.501 1.738.372a.83.83 0 1 0 .83-.869.83.83 0 0 0-.744.468l-1.938-.41a.2.2 0 0 0-.153.028.2.2 0 0 0-.086.134l-.592 2.788c-1.24.038-2.358.41-3.17.992-.21-.2-.496-.324-.81-.324a1.163 1.163 0 0 0-.478 2.224q-.03.17-.029.353c0 1.795 2.091 3.256 4.669 3.256s4.668-1.451 4.668-3.256c0-.114-.01-.238-.029-.353.401-.181.688-.592.688-1.069 0-.65-.525-1.165-1.165-1.165"/>
</svg>

After

Width:  |  Height:  |  Size: 964 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="#ffffff">
<path d="M7.754 2l.463.41c.343.304.687.607 1.026.915C11.44 5.32 13.3 7.565 14.7 10.149c.072.132.137.268.202.403l.098.203-.108.057-.081-.115-.21-.299-.147-.214c-1.019-1.479-2.04-2.96-3.442-4.145a6.563 6.563 0 00-1.393-.904c-1.014-.485-1.916-.291-2.69.505-.736.757-1.118 1.697-1.463 2.653-.045.123-.092.245-.139.367l-.082.215-.172-.055c.1-.348.192-.698.284-1.049.21-.795.42-1.59.712-2.356.31-.816.702-1.603 1.093-2.39.169-.341.338-.682.5-1.025h.092z"/>
<path d="M8.448 11.822c-1.626.77-5.56 1.564-7.426 1.36C.717 11.576 3.71 4.05 5.18 2.91l-.095.218a4.638 4.638 0 01-.138.303l-.066.129c-.76 1.462-1.519 2.926-1.908 4.53a7.482 7.482 0 00-.228 1.689c-.01 1.34.824 2.252 2.217 2.309.67.027 1.347-.043 2.023-.114.294-.03.587-.061.88-.084.108-.008.214-.021.352-.039l.231-.028z"/>
<path d="M3.825 14.781c-.445.034-.89.068-1.333.108 4.097.39 8.03-.277 11.91-1.644-1.265-2.23-2.97-3.991-4.952-5.522.026.098.084.169.141.239l.048.06c.17.226.348.448.527.67.409.509.818 1.018 1.126 1.578.778 1.42.356 2.648-1.168 3.296-1.002.427-2.097.718-3.18.892-1.03.164-2.075.243-3.119.323z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M7.754 2l.463.41c.343.304.687.607 1.026.915C11.44 5.32 13.3 7.565 14.7 10.149c.072.132.137.268.202.403l.098.203-.108.057-.081-.115-.21-.299-.147-.214c-1.019-1.479-2.04-2.96-3.442-4.145a6.563 6.563 0 00-1.393-.904c-1.014-.485-1.916-.291-2.69.505-.736.757-1.118 1.697-1.463 2.653-.045.123-.092.245-.139.367l-.082.215-.172-.055c.1-.348.192-.698.284-1.049.21-.795.42-1.59.712-2.356.31-.816.702-1.603 1.093-2.39.169-.341.338-.682.5-1.025h.092z"/>
<path d="M8.448 11.822c-1.626.77-5.56 1.564-7.426 1.36C.717 11.576 3.71 4.05 5.18 2.91l-.095.218a4.638 4.638 0 01-.138.303l-.066.129c-.76 1.462-1.519 2.926-1.908 4.53a7.482 7.482 0 00-.228 1.689c-.01 1.34.824 2.252 2.217 2.309.67.027 1.347-.043 2.023-.114.294-.03.587-.061.88-.084.108-.008.214-.021.352-.039l.231-.028z"/>
<path d="M3.825 14.781c-.445.034-.89.068-1.333.108 4.097.39 8.03-.277 11.91-1.644-1.265-2.23-2.97-3.991-4.952-5.522.026.098.084.169.141.239l.048.06c.17.226.348.448.527.67.409.509.818 1.018 1.126 1.578.778 1.42.356 2.648-1.168 3.296-1.002.427-2.097.718-3.18.892-1.03.164-2.075.243-3.119.323z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036 0 10.111.756 8.43 1.68 8.43h1.682zm.846 0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685 0 0 1-1.682-1.68zM5.89 3.362c-.926 0-1.682-.756-1.682-1.681S4.964 0 5.89 0s1.68.756 1.68 1.68v1.682zm0 .846c.924 0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57 0 6.814 0 5.89c0-.926.756-1.682 1.68-1.682zm6.749 1.682c0-.926.755-1.682 1.68-1.682S16 4.964 16 5.889s-.756 1.681-1.68 1.681h-1.681zm-.848 0c0 .924-.755 1.68-1.68 1.68A1.685 1.685 0 0 1 8.43 5.89V1.68C8.43.757 9.186 0 10.11 0c.926 0 1.681.756 1.681 1.68zm-1.681 6.748c.926 0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924 0-1.68-.755-1.68-1.68s.756-1.681 1.68-1.681h4.21c.924 0 1.68.756 1.68 1.68 0 .926-.756 1.681-1.68 1.681z"/>
</svg>

After

Width:  |  Height:  |  Size: 947 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3.362 10.11c0 .926-.756 1.681-1.681 1.681S0 11.036 0 10.111.756 8.43 1.68 8.43h1.682zm.846 0c0-.924.756-1.68 1.681-1.68s1.681.756 1.681 1.68v4.21c0 .924-.756 1.68-1.68 1.68a1.685 1.685 0 0 1-1.682-1.68zM5.89 3.362c-.926 0-1.682-.756-1.682-1.681S4.964 0 5.89 0s1.68.756 1.68 1.68v1.682zm0 .846c.924 0 1.68.756 1.68 1.681S6.814 7.57 5.89 7.57H1.68C.757 7.57 0 6.814 0 5.89c0-.926.756-1.682 1.68-1.682zm6.749 1.682c0-.926.755-1.682 1.68-1.682S16 4.964 16 5.889s-.756 1.681-1.68 1.681h-1.681zm-.848 0c0 .924-.755 1.68-1.68 1.68A1.685 1.685 0 0 1 8.43 5.89V1.68C8.43.757 9.186 0 10.11 0c.926 0 1.681.756 1.681 1.68zm-1.681 6.748c.926 0 1.682.756 1.682 1.681S11.036 16 10.11 16s-1.681-.756-1.681-1.68v-1.682h1.68zm0-.847c-.924 0-1.68-.755-1.68-1.68s.756-1.681 1.68-1.681h4.21c.924 0 1.68.756 1.68 1.68 0 .926-.756 1.681-1.68 1.681z"/>
</svg>

After

Width:  |  Height:  |  Size: 952 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
</svg>

After

Width:  |  Height:  |  Size: 684 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0M8.287 5.906q-1.168.486-4.666 2.01-.567.225-.595.442c-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294q.39.01.868-.32 3.269-2.206 3.374-2.23c.05-.012.12-.026.166.016s.042.12.037.141c-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8 8 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629q.14.092.27.187c.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.4 1.4 0 0 0-.013-.315.34.34 0 0 0-.114-.217.53.53 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09"/>
</svg>

After

Width:  |  Height:  |  Size: 689 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
</svg>

After

Width:  |  Height:  |  Size: 309 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M3.857 0 1 2.857v10.286h3.429V16l2.857-2.857H9.57L14.714 8V0zm9.714 7.429-2.285 2.285H9l-2 2v-2H4.429V1.143h9.142z"/>
<path d="M11.857 3.143h-1.143V6.57h1.143zm-3.143 0H7.571V6.57h1.143z"/>
</svg>

After

Width:  |  Height:  |  Size: 314 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
</svg>

After

Width:  |  Height:  |  Size: 273 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M12.6.75h2.454l-5.36 6.142L16 15.25h-4.937l-3.867-5.07-4.425 5.07H.316l5.733-6.57L0 .75h5.063l3.495 4.633L12.601.75Zm-.86 13.028h1.36L4.323 2.145H2.865z"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M11.176 14.429c-2.665 0-4.826-1.8-4.826-4.018 0-2.22 2.159-4.02 4.824-4.02S16 8.191 16 10.411c0 1.21-.65 2.301-1.666 3.036a.32.32 0 0 0-.12.366l.218.81a.6.6 0 0 1 .029.117.166.166 0 0 1-.162.162.2.2 0 0 1-.092-.03l-1.057-.61a.5.5 0 0 0-.256-.074.5.5 0 0 0-.142.021 5.7 5.7 0 0 1-1.576.22M9.064 9.542a.647.647 0 1 0 .557-1 .645.645 0 0 0-.646.647.6.6 0 0 0 .09.353Zm3.232.001a.646.646 0 1 0 .546-1 .645.645 0 0 0-.644.644.63.63 0 0 0 .098.356"/>
<path d="M0 6.826c0 1.455.781 2.765 2.001 3.656a.385.385 0 0 1 .143.439l-.161.6-.1.373a.5.5 0 0 0-.032.14.19.19 0 0 0 .193.193q.06 0 .111-.029l1.268-.733a.6.6 0 0 1 .308-.088q.088 0 .171.025a6.8 6.8 0 0 0 1.625.26 4.5 4.5 0 0 1-.177-1.251c0-2.936 2.785-5.02 5.824-5.02l.15.002C10.587 3.429 8.392 2 5.796 2 2.596 2 0 4.16 0 6.826m4.632-1.555a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0m3.875 0a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0"/>
</svg>

After

Width:  |  Height:  |  Size: 996 B

View File

@@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M11.176 14.429c-2.665 0-4.826-1.8-4.826-4.018 0-2.22 2.159-4.02 4.824-4.02S16 8.191 16 10.411c0 1.21-.65 2.301-1.666 3.036a.32.32 0 0 0-.12.366l.218.81a.6.6 0 0 1 .029.117.166.166 0 0 1-.162.162.2.2 0 0 1-.092-.03l-1.057-.61a.5.5 0 0 0-.256-.074.5.5 0 0 0-.142.021 5.7 5.7 0 0 1-1.576.22M9.064 9.542a.647.647 0 1 0 .557-1 .645.645 0 0 0-.646.647.6.6 0 0 0 .09.353Zm3.232.001a.646.646 0 1 0 .546-1 .645.645 0 0 0-.644.644.63.63 0 0 0 .098.356"/>
<path d="M0 6.826c0 1.455.781 2.765 2.001 3.656a.385.385 0 0 1 .143.439l-.161.6-.1.373a.5.5 0 0 0-.032.14.19.19 0 0 0 .193.193q.06 0 .111-.029l1.268-.733a.6.6 0 0 1 .308-.088q.088 0 .171.025a6.8 6.8 0 0 0 1.625.26 4.5 4.5 0 0 1-.177-1.251c0-2.936 2.785-5.02 5.824-5.02l.15.002C10.587 3.429 8.392 2 5.796 2 2.596 2 0 4.16 0 6.826m4.632-1.555a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0m3.875 0a.77.77 0 1 1-1.54 0 .77.77 0 0 1 1.54 0"/>
</svg>

After

Width:  |  Height:  |  Size: 1001 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="#ffffff" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 208 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16">
<path d="M7.462 0H0v7.19h7.462zM16 0H8.538v7.19H16zM7.462 8.211H0V16h7.462zm8.538 0H8.538V16H16z"/>
</svg>

After

Width:  |  Height:  |  Size: 213 B

View File

@@ -8,7 +8,7 @@ import { WithBrandConfig } from "#elements/mixins/branding";
import { WithSession } from "#elements/mixins/session";
import { isAdminRoute } from "#elements/router/utils";
import { SlottedTemplateResult } from "#elements/types";
import { ThemedImage } from "#elements/utils/images";
import { FontAwesomeProtocol, getFontAwesomeClasses, ThemedImage } from "#elements/utils/images";
import Styles from "#components/ak-page-navbar.css";
@@ -146,7 +146,7 @@ export class AKPageNavbar
protected renderIcon() {
return guard([this.icon, this.iconImage], () => {
if (this.icon) {
if (this.iconImage && !this.icon.startsWith("fa://")) {
if (this.iconImage && !this.icon.startsWith(FontAwesomeProtocol)) {
return html`<img
aria-hidden="true"
class="accent-icon pf-icon"
@@ -155,9 +155,10 @@ export class AKPageNavbar
/>`;
}
const icon = this.icon.replaceAll("fa://", "fa ");
return html`<i class="accent-icon ${icon}" aria-hidden="true"></i>`;
return html`<i
class=${`accent-icon ${getFontAwesomeClasses(this.icon)}`}
aria-hidden="true"
></i>`;
}
return nothing;

View File

@@ -2,7 +2,7 @@ import { PFSize } from "#common/enums";
import Styles from "#elements/AppIcon.css";
import { AKElement } from "#elements/Base";
import { FontAwesomeProtocol } from "#elements/utils/images";
import { FontAwesomeProtocol, resolveThemedUrl, ThemedImage } from "#elements/utils/images";
import type { ThemedUrls } from "@goauthentik/api";
@@ -10,8 +10,6 @@ import { msg, str } from "@lit/localize";
import { CSSResult, html, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFFontAwesomeIcons from "@patternfly/patternfly/base/patternfly-fa-icons.css";
export interface IAppIcon {
name?: string | null;
icon?: string | null;
@@ -23,7 +21,7 @@ export interface IAppIcon {
export class AppIcon extends AKElement implements IAppIcon {
public static readonly FontAwesomeProtocol = FontAwesomeProtocol;
static styles: CSSResult[] = [PFFontAwesomeIcons, Styles];
static styles: CSSResult[] = [Styles];
@property({ type: String })
public name: string | null = null;
@@ -38,47 +36,34 @@ export class AppIcon extends AKElement implements IAppIcon {
public size: PFSize = PFSize.Medium;
#wrap(icon: TemplateResult): TemplateResult {
// PatternFly's font awesome rules use descendant selectors (`* .fa-*`),
// so the icon needs at least one ancestor inside the shadow DOM to pick up those styles.
// Keep the icon wrapped so image and font-based variants share the same layout box.
return html`<span class="icon-wrapper">${icon}</span>`;
}
override render(): TemplateResult {
const applicationName = this.name ?? msg("Application");
const label = msg(str`${applicationName} Icon`);
const resolvedIcon = resolveThemedUrl(this.icon, this.iconThemedUrls, this.activeTheme);
const part = resolvedIcon?.startsWith(AppIcon.FontAwesomeProtocol)
? "icon font-awesome"
: "icon image";
// Check for Font Awesome icons (fa://fa-icon-name)
if (this.icon?.startsWith(AppIcon.FontAwesomeProtocol)) {
const iconClass = this.icon.slice(AppIcon.FontAwesomeProtocol.length);
if (resolvedIcon) {
return this.#wrap(
html`<i
part="icon font-awesome"
role="img"
aria-label=${label}
class="icon fas ${iconClass}"
></i>`,
html`${ThemedImage({
"aria-label": label,
"alt": this.name?.charAt(0).toUpperCase() ?? "<22>",
"className": "icon",
part,
"role": "img",
"src": resolvedIcon,
"theme": this.activeTheme,
})}`,
);
}
const insignia = this.name?.charAt(0).toUpperCase() ?? "<22>";
// Check for image URLs (http://, https://, or file paths)
// Use themed URL if available, otherwise fall back to icon
const resolvedIcon =
(this.iconThemedUrls as Record<string, string> | null)?.[this.activeTheme] ?? this.icon;
if (resolvedIcon) {
return this.#wrap(
html`<img
part="icon image"
role="img"
aria-label=${label}
class="icon"
src=${resolvedIcon}
alt=${insignia}
/>`,
);
}
// Fallback to first letter insignia
return this.#wrap(
html`<span part="icon insignia" role="img" aria-label=${label} class="icon"

View File

@@ -13,6 +13,11 @@ import PFBase from "#styles/patternfly/base.css" with { type: "bundled-text" };
import { CSSResult, CSSResultGroup, CSSResultOrNative, LitElement, PropertyValues } from "lit";
import { property } from "lit/decorators.js";
import FABrands from "@fortawesome/fontawesome-free/css/brands.min.css";
import FAFontAwesome from "@fortawesome/fontawesome-free/css/fontawesome.min.css";
import FARegular from "@fortawesome/fontawesome-free/css/regular.min.css";
import FASolid from "@fortawesome/fontawesome-free/css/solid.min.css";
/**
* Patternfly base styles, providing common variables and resets.
*
@@ -21,6 +26,10 @@ import { property } from "lit/decorators.js";
* This style sheet **must** be included before any other styles that depend on Patternfly variables.
*/
const $PFBase = createStyleSheetUnsafe(PFBase);
const $FAFontAwesome = createStyleSheetUnsafe(FAFontAwesome);
const $FASolid = createStyleSheetUnsafe(FASolid);
const $FARegular = createStyleSheetUnsafe(FARegular);
const $FABrands = createStyleSheetUnsafe(FABrands);
/**
* authentik base styles, providing overrides to Patternfly's initial definitions,
@@ -69,6 +78,10 @@ export class AKElement extends LitElement implements AKElementProps {
protected static override finalizeStyles(styles: CSSResultGroup = []): CSSResultOrNative[] {
const elementStyles = [
$PFBase,
$FAFontAwesome,
$FASolid,
$FARegular,
$FABrands,
// Route around TSC`s known-to-fail typechecking of `.flat(Infinity)`. Removes types.
...([styles] as Array<unknown>).flat(Infinity),
$AKBase,

View File

@@ -1,23 +1,32 @@
import { PolicyBindingCheckTarget } from "#common/policies/utils";
import { ResolvedUITheme } from "#common/theme";
import type { VariantUrls } from "#elements/utils/images";
import { renderDynamicIcon } from "#elements/utils/images";
import { msg } from "@lit/localize";
import { html, TemplateResult } from "lit";
import { html, nothing, TemplateResult } from "lit";
export function renderSourceIcon(name: string, iconUrl: string | undefined | null): TemplateResult {
const icon = html`<i
export function renderSourceIcon(
name: string,
iconUrl: VariantUrls | undefined | null,
theme?: ResolvedUITheme,
): TemplateResult {
const fallback = html`<i
part="source-icon"
role="img"
class="fas fa-share-square"
class="fa-solid fa-share-square"
title="${name}"
></i>`;
if (iconUrl) {
if (iconUrl.startsWith("fa://")) {
const url = iconUrl.replaceAll("fa://", "");
return html`<i part="source-icon" role="img" class="fas ${url}" title="${name}"></i>`;
}
return html`<img part="source-icon" src="${iconUrl}" alt="${name}" />`;
}
return icon;
const icon = renderDynamicIcon({
urls: iconUrl,
theme,
alt: name,
ariaLabel: name,
fallback,
part: "source-icon",
});
return icon === nothing ? fallback : icon;
}
export function sourceBindingTypeNotices() {

View File

@@ -24,10 +24,6 @@
padding-inline-start: 0;
border-top-color: var(--ak-dark-background-lighter);
.pf-c-data-list__cell img {
filter: invert(1);
}
.pf-c-data-list__item {
--pf-c-data-list__item--BackgroundColor: transparent;
--pf-c-data-list__item--BorderBottomColor: var(--ak-dark-background-lighter);

View File

@@ -142,7 +142,6 @@ export class UserSourceSettingsPage extends AKElement {
const connection = this.sourceToConnection.get(source);
const connectionPk = connection?.pk ?? -1;
const connectionUserPk = connection?.user ?? -1;
return html`<li
class="pf-c-data-list__item"
part="list-item"
@@ -159,7 +158,8 @@ export class UserSourceSettingsPage extends AKElement {
<div class="pf-c-data-list__item-row">
<div class="pf-c-data-list__item-content">
<div class="pf-c-data-list__cell">
${renderSourceIcon(source.title, source.iconUrl)} ${source.title}
${renderSourceIcon(source.title, source.iconUrl, this.activeTheme)}
${source.title}
</div>
<div class="pf-c-data-list__cell">${this.renderSourceSettings(source)}</div>
</div>

View File

@@ -8,9 +8,133 @@ import type { ThemedUrls } from "@goauthentik/api";
import { spread } from "@open-wc/lit-helpers";
import { ImgHTMLAttributes } from "react";
import { html, nothing } from "lit";
import { html, nothing, TemplateResult } from "lit";
export const FontAwesomeProtocol = "fa://";
export const FA_FAMILY_MAP: Record<string, string[]> = {
"brands": ["fa-brands"],
"fab": ["fa-brands"],
"fa-brands": ["fa-brands"],
"duotone": ["fa-duotone"],
"fad": ["fa-duotone"],
"fa-duotone": ["fa-duotone"],
"light": ["fa-light"],
"fal": ["fa-light"],
"fa-light": ["fa-light"],
"regular": ["fa-regular"],
"far": ["fa-regular"],
"fa-regular": ["fa-regular"],
"solid": ["fa-solid"],
"fas": ["fa-solid"],
"fa-solid": ["fa-solid"],
"thin": ["fa-thin"],
"fat": ["fa-thin"],
"fa-thin": ["fa-thin"],
"sharp-solid": ["fa-sharp", "fa-solid"],
"fass": ["fa-sharp", "fa-solid"],
"fa-sharp-solid": ["fa-sharp", "fa-solid"],
"sharp-regular": ["fa-sharp", "fa-regular"],
"fasr": ["fa-sharp", "fa-regular"],
"fa-sharp-regular": ["fa-sharp", "fa-regular"],
"sharp-light": ["fa-sharp", "fa-light"],
"fasl": ["fa-sharp", "fa-light"],
"fa-sharp-light": ["fa-sharp", "fa-light"],
"sharp-thin": ["fa-sharp", "fa-thin"],
"fast": ["fa-sharp", "fa-thin"],
"fa-sharp-thin": ["fa-sharp", "fa-thin"],
"sharp-duotone-solid": ["fa-sharp-duotone", "fa-solid"],
"fasds": ["fa-sharp-duotone", "fa-solid"],
"fa-sharp-duotone-solid": ["fa-sharp-duotone", "fa-solid"],
"sharp-duotone-regular": ["fa-sharp-duotone", "fa-regular"],
"fasdr": ["fa-sharp-duotone", "fa-regular"],
"fa-sharp-duotone-regular": ["fa-sharp-duotone", "fa-regular"],
"sharp-duotone-light": ["fa-sharp-duotone", "fa-light"],
"fasdl": ["fa-sharp-duotone", "fa-light"],
"fa-sharp-duotone-light": ["fa-sharp-duotone", "fa-light"],
"sharp-duotone-thin": ["fa-sharp-duotone", "fa-thin"],
"fasdt": ["fa-sharp-duotone", "fa-thin"],
"fa-sharp-duotone-thin": ["fa-sharp-duotone", "fa-thin"],
};
const FontAwesomeStyleClasses = new Set([
"fa",
"fab",
"fad",
"fal",
"far",
"fas",
"fat",
"fa-brands",
"fa-duotone",
"fa-light",
"fa-regular",
"fa-sharp",
"fa-sharp-duotone",
"fa-solid",
"fa-thin",
]);
export function getFontAwesomeClasses(src: string, className?: string): string {
const rawValue = src.slice(FontAwesomeProtocol.length).trim();
const [familyKey, iconFromFamily] = rawValue.split("/", 2);
const familyClasses = FA_FAMILY_MAP[familyKey] ?? [];
const rawClasses = (familyClasses.length ? iconFromFamily : rawValue)
.trim()
.split(/\s+/)
.filter(Boolean);
const iconClasses = rawClasses
.filter((token) => !FontAwesomeStyleClasses.has(token))
.map((token) => (token.startsWith("fa-") ? token : `fa-${token}`));
const styleClasses = rawClasses.filter((token) => FontAwesomeStyleClasses.has(token));
return [
className,
"font-awesome",
...(familyClasses.length
? familyClasses
: styleClasses.length
? styleClasses
: ["fa-solid"]),
...iconClasses,
]
.filter(Boolean)
.join(" ");
}
export interface VariantUrls {
fallback?: string | null;
[key: string]: string | null | undefined;
}
export function resolveVariantUrl(
variantUrls: VariantUrls | undefined | null,
theme: ResolvedUITheme | undefined,
): string | undefined | null {
if (!variantUrls) {
return undefined;
}
if (theme && variantUrls[theme]) {
return variantUrls[theme];
}
if (variantUrls.fallback) {
return variantUrls.fallback;
}
return Object.values(variantUrls).find((url) => !!url);
}
export function resolveThemedUrl(
src: string | undefined | null,
themedUrls: ThemedUrls | undefined | null,
theme: ResolvedUITheme | undefined,
): string | undefined | null {
const variantUrls = themedUrls ? { ...themedUrls } : {};
if (src !== undefined && src !== null) {
variantUrls.fallback = src;
}
return resolveVariantUrl(variantUrls, theme);
}
/**
* The default background image for flows, used when no specific background is set.
@@ -30,6 +154,22 @@ export interface ThemedImageProps extends ImgHTMLAttributes<HTMLImageElement> {
* When provided, these are used instead of src.
*/
themedUrls?: ThemedUrls | null;
part?: string;
role?: string;
}
export interface RenderIconOptions {
alt?: string;
ariaHidden?: boolean;
ariaLabel?: string;
className?: string;
fallback?: TemplateResult | typeof nothing;
part?: string;
}
export interface RenderDynamicIconOptions extends RenderIconOptions {
urls: VariantUrls | undefined | null;
theme: ResolvedUITheme | undefined;
}
export const ThemedImage: LitFC<ThemedImageProps> = ({
@@ -45,19 +185,59 @@ export const ThemedImage: LitFC<ThemedImageProps> = ({
// Handle Font Awesome icons
if (src.startsWith(FontAwesomeProtocol)) {
const classes = [className, "font-awesome", "fas", src.slice(FontAwesomeProtocol.length)]
.filter(Boolean)
.join(" ");
const classes = getFontAwesomeClasses(src, className);
return html`<i part="icon font-awesome" role="img" class=${classes} ${spread(props)}></i>`;
}
// Use themed URL if available, otherwise use src directly
const resolvedSrc = (themedUrls as Record<string, string> | null)?.[theme] ?? src;
const resolvedSrc = resolveThemedUrl(src, themedUrls, theme);
if (!resolvedSrc) {
return nothing;
}
return html`<img src=${resolvedSrc} class=${ifPresent(className)} ${spread(props)} />`;
};
export function renderIcon(
src: string | undefined | null,
themedUrls: ThemedUrls | undefined | null,
theme: ResolvedUITheme | undefined,
{
alt = "",
ariaHidden = false,
ariaLabel,
className,
fallback = nothing,
part,
}: RenderIconOptions = {},
): TemplateResult | typeof nothing {
const resolvedSrc = resolveThemedUrl(src, themedUrls, theme);
if (!resolvedSrc) {
return fallback;
}
return html`${ThemedImage({
"src": resolvedSrc,
alt,
"aria-hidden": ariaHidden,
"aria-label": ariaLabel,
className,
part,
"role": ariaHidden ? undefined : "img",
"theme": theme ?? "light",
})}`;
}
export function renderDynamicIcon({
urls,
theme,
...options
}: RenderDynamicIconOptions): TemplateResult | typeof nothing {
const resolvedSrc = resolveVariantUrl(urls, theme);
return renderIcon(resolvedSrc, null, theme, options);
}
export function isDefaultAvatar(path?: string | null): boolean {
return !!path?.endsWith("user_default.png");
}

View File

@@ -5,12 +5,13 @@ import "#elements/forms/FormGroup";
import { WithLicenseSummary } from "#elements/mixins/license";
import { SlottedTemplateResult } from "#elements/types";
import { ifPresent } from "#elements/utils/attributes";
import { renderDynamicIcon } from "#elements/utils/images";
import { WizardPage } from "#elements/wizard/WizardPage";
import { TypeCreate } from "@goauthentik/api";
import { msg, str } from "@lit/localize";
import { css, CSSResult, html } from "lit";
import { css, CSSResult, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { guard } from "lit/directives/guard.js";
@@ -64,8 +65,9 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
max-height: 2em;
min-height: 2em;
}
:host([theme="dark"]) .pf-c-card__header-main img {
filter: invert(1);
.pf-c-card__header-main .font-awesome {
font-size: 2em;
line-height: 1;
}
:host([theme="dark"]) .pf-c-card {
@@ -80,6 +82,10 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
[part*="type-create"]:not(:first-child) {
margin-block-start: var(--pf-global--spacer--md);
}
.pf-c-page__main-section {
margin-bottom: 2rem;
}
`,
];
@@ -121,9 +127,14 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
return this.types.map((type, idx) => {
const disabled = !!(type.requiresEnterprise && !this.hasEnterpriseLicense);
const selected = this.selectedType === type;
const inputID = `${type.component}-${type.modelName}`;
const icon = renderDynamicIcon({
urls: type.iconUrl,
theme: this.activeTheme,
alt: msg(str`${type.name} Icon`),
ariaHidden: true,
});
return html`<div
class=${classMap({
@@ -150,17 +161,11 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
this.#selectDispatch(type);
}}
>
${type.iconUrl
${icon !== nothing
? html`<div role="presentation" class="pf-c-card__header">
<div role="presentation" class="pf-c-card__header-main">
<img
aria-hidden="true"
src=${type.iconUrl}
alt=${msg(str`${type.name} Icon`)}
/>
</div>
<div role="presentation" class="pf-c-card__header-main">${icon}</div>
</div>`
: null}
: nothing}
<div role="heading" aria-level="2" class="pf-c-card__title">${type.name}</div>
<div class="pf-c-card__body" id=${`${inputID}-description`}>
${type.description}
@@ -169,7 +174,7 @@ export class TypeCreateWizardPage extends WithLicenseSummary(WizardPage) {
? html`<div class="pf-c-card__footer">
<ak-license-notice></ak-license-notice>
</div> `
: null}
: nothing}
</div>`;
});
}

View File

@@ -79,7 +79,11 @@ export const ChallengeEverything = flowFactory("ak-stage-identification", {
component: "xak-flow-redirect",
to: "foo",
},
iconUrl: "/static/authentik/sources/google.svg",
iconUrl: {
fallback: "/static/authentik/sources/google/light.svg",
light: "/static/authentik/sources/google/light.svg",
dark: "/static/authentik/sources/google/dark.svg",
},
},
],
recoveryUrl: "foo",

Some files were not shown because too many files have changed in this diff Show More