Refactored dashboard icons and menu registration
15
TODO.md
|
@ -376,3 +376,18 @@ TODO mount the filesystem with "nosuid" option
|
||||||
# orchestrate async stdout stderr (inspired on pangea managemengt commands)
|
# orchestrate async stdout stderr (inspired on pangea managemengt commands)
|
||||||
|
|
||||||
# orchestra-beat support for uwsgi cron
|
# orchestra-beat support for uwsgi cron
|
||||||
|
|
||||||
|
# message.log if 1: return changeform
|
||||||
|
|
||||||
|
# generate nginx certs on project dir rather than nginx
|
||||||
|
|
||||||
|
# Register icons
|
||||||
|
|
||||||
|
# send_message doesn't log task
|
||||||
|
|
||||||
|
make django admin taskstate uncollapse fucking traceback, ( if exists ?)
|
||||||
|
|
||||||
|
# receive tass stuck at RECEIVED
|
||||||
|
# monitor tasks in started and backend already in success?
|
||||||
|
|
||||||
|
# custom message on admin save
|
||||||
|
|
|
@ -1,32 +1,25 @@
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from fluent_dashboard import dashboard
|
from fluent_dashboard import dashboard
|
||||||
from fluent_dashboard.modules import CmsAppIconList
|
from fluent_dashboard.modules import CmsAppIconList
|
||||||
|
|
||||||
from orchestra.core import services
|
from orchestra.core import services, accounts, administration
|
||||||
|
|
||||||
|
|
||||||
|
class AppDefaultIconList(CmsAppIconList):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.icons = kwargs.pop('icons')
|
||||||
|
super(AppDefaultIconList, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def get_icon_for_model(self, app_name, model_name, default=None):
|
||||||
|
icon = self.icons.get('.'.join((app_name, model_name)))
|
||||||
|
return super(AppDefaultIconList, self).get_icon_for_model(app_name, model_name, default=icon)
|
||||||
|
|
||||||
|
|
||||||
class OrchestraIndexDashboard(dashboard.FluentIndexDashboard):
|
class OrchestraIndexDashboard(dashboard.FluentIndexDashboard):
|
||||||
_registry = {}
|
def process_registered_view(self, module, view_name, options):
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def register_link(cls, module, view_name, title):
|
|
||||||
registered = cls._registry.get(module, [])
|
|
||||||
registered.append((view_name, title))
|
|
||||||
cls._registry[module] = registered
|
|
||||||
|
|
||||||
def get_application_modules(self):
|
|
||||||
modules = super(OrchestraIndexDashboard, self).get_application_modules()
|
|
||||||
models = []
|
|
||||||
for model, options in services.get().items():
|
|
||||||
if options.get('menu', True):
|
|
||||||
models.append("%s.%s" % (model.__module__, model._meta.object_name))
|
|
||||||
|
|
||||||
for module in modules:
|
|
||||||
registered = self._registry.get(module.title, None)
|
|
||||||
if registered:
|
|
||||||
for view_name, title in registered:
|
|
||||||
# This values are shit, but it is how fluent dashboard will look for the icon
|
|
||||||
app_name, name = view_name.split('_')[:-1]
|
app_name, name = view_name.split('_')[:-1]
|
||||||
|
module.icons['.'.join((app_name, name))] = options.get('icon')
|
||||||
url = reverse('admin:' + view_name)
|
url = reverse('admin:' + view_name)
|
||||||
add_url = '/'.join(url.split('/')[:-2])
|
add_url = '/'.join(url.split('/')[:-2])
|
||||||
module.children.append({
|
module.children.append({
|
||||||
|
@ -35,11 +28,34 @@ class OrchestraIndexDashboard(dashboard.FluentIndexDashboard):
|
||||||
'app_name': app_name,
|
'app_name': app_name,
|
||||||
'change_url': url,
|
'change_url': url,
|
||||||
'name': name,
|
'name': name,
|
||||||
'title': title }],
|
'title': options.get('verbose_name')}],
|
||||||
'name': app_name,
|
'name': app_name,
|
||||||
'title': title,
|
'title': options.get('verbose_name'),
|
||||||
'url': add_url,
|
'url': add_url,
|
||||||
})
|
})
|
||||||
service_icon_list = CmsAppIconList('Services', models=models, collapsible=True)
|
|
||||||
modules.append(service_icon_list)
|
def get_application_modules(self):
|
||||||
|
from fluent_dashboard import appsettings
|
||||||
|
modules = []
|
||||||
|
# Honor settings override, hacky. I Know
|
||||||
|
if appsettings.FLUENT_DASHBOARD_APP_GROUPS[0][0] != _('CMS'):
|
||||||
|
modules = super(OrchestraIndexDashboard, self).get_application_modules()
|
||||||
|
for register in (accounts, administration, services):
|
||||||
|
title = register.verbose_name
|
||||||
|
models = []
|
||||||
|
icons = {}
|
||||||
|
views = []
|
||||||
|
for model, options in register.get().items():
|
||||||
|
if isinstance(model, str):
|
||||||
|
views.append((model, options))
|
||||||
|
elif options.get('dashboard', True):
|
||||||
|
opts = model._meta
|
||||||
|
label = "%s.%s" % (model.__module__, opts.object_name)
|
||||||
|
models.append(label)
|
||||||
|
label = '.'.join((opts.app_label, opts.model_name))
|
||||||
|
icons[label] = options.get('icon')
|
||||||
|
module = AppDefaultIconList(title, models=models, icons=icons, collapsible=True)
|
||||||
|
for view_name, options in views:
|
||||||
|
self.process_registered_view(module, view_name, options)
|
||||||
|
modules.append(module)
|
||||||
return modules
|
return modules
|
||||||
|
|
|
@ -27,80 +27,37 @@ def api_link(context):
|
||||||
return reverse('api-root')
|
return reverse('api-root')
|
||||||
|
|
||||||
|
|
||||||
def process_registered_models(register):
|
from copy import copy
|
||||||
childrens = []
|
def process_registry(register):
|
||||||
for model, options in register.get().items():
|
def get_item(model, options):
|
||||||
if options.get('menu', True):
|
if isinstance(model, str):
|
||||||
|
url = reverse('admin:'+model)
|
||||||
|
else:
|
||||||
opts = model._meta
|
opts = model._meta
|
||||||
url = reverse('admin:{}_{}_changelist'.format(
|
url = reverse('admin:{}_{}_changelist'.format(
|
||||||
opts.app_label, opts.model_name))
|
opts.app_label, opts.model_name))
|
||||||
name = capfirst(options.get('verbose_name_plural'))
|
name = capfirst(options.get('verbose_name_plural'))
|
||||||
childrens.append(items.MenuItem(name, url))
|
return items.MenuItem(name, url)
|
||||||
return childrens
|
|
||||||
|
|
||||||
|
childrens = {}
|
||||||
def get_services():
|
for model, options in register.get().items():
|
||||||
childrens = process_registered_models(services)
|
if options.get('menu', True):
|
||||||
return sorted(childrens, key=lambda i: i.title)
|
parent = options.get('parent')
|
||||||
|
if parent:
|
||||||
|
parent_item = childrens.get(parent)
|
||||||
def get_accounts():
|
if parent_item:
|
||||||
childrens=[]
|
if not parent_item.children:
|
||||||
if isinstalled('orchestra.contrib.payments'):
|
parent_item.children.append(copy(parent_item))
|
||||||
url = reverse('admin:payments_transactionprocess_changelist')
|
else:
|
||||||
childrens.append(items.MenuItem(_("Transaction processes"), url))
|
parent_item = get_item(parent, register[parent])
|
||||||
if isinstalled('orchestra.contrib.issues'):
|
parent_item.children = []
|
||||||
url = reverse('admin:issues_ticket_changelist')
|
parent_item.children.append(get_item(model, options))
|
||||||
childrens.append(items.MenuItem(_("Tickets"), url))
|
childrens[parent] = parent_item
|
||||||
childrens.extend(process_registered_models(accounts))
|
elif model not in childrens:
|
||||||
return sorted(childrens, key=lambda i: i.title)
|
childrens[model] = get_item(model, options)
|
||||||
|
else:
|
||||||
|
childrens[model].children.insert(0, get_item(model, options))
|
||||||
def get_administration_items():
|
return sorted(childrens.values(), key=lambda i: i.title)
|
||||||
childrens = []
|
|
||||||
if isinstalled('orchestra.contrib.settings'):
|
|
||||||
url = reverse('admin:settings_setting_change')
|
|
||||||
childrens.append(items.MenuItem(_("Settings"), url))
|
|
||||||
if isinstalled('orchestra.contrib.services'):
|
|
||||||
url = reverse('admin:services_service_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Services"), url))
|
|
||||||
url = reverse('admin:plans_plan_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Plans"), url))
|
|
||||||
if isinstalled('orchestra.contrib.orchestration'):
|
|
||||||
route = reverse('admin:orchestration_route_changelist')
|
|
||||||
backendlog = reverse('admin:orchestration_backendlog_changelist')
|
|
||||||
server = reverse('admin:orchestration_server_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Orchestration"), route, children=[
|
|
||||||
items.MenuItem(_("Routes"), route),
|
|
||||||
items.MenuItem(_("Backend logs"), backendlog),
|
|
||||||
items.MenuItem(_("Servers"), server),
|
|
||||||
]))
|
|
||||||
if isinstalled('orchestra.contrib.resources'):
|
|
||||||
resource = reverse('admin:resources_resource_changelist')
|
|
||||||
data = reverse('admin:resources_resourcedata_changelist')
|
|
||||||
monitor = reverse('admin:resources_monitordata_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Resources"), resource, children=[
|
|
||||||
items.MenuItem(_("Resources"), resource),
|
|
||||||
items.MenuItem(_("Data"), data),
|
|
||||||
items.MenuItem(_("Monitoring"), monitor),
|
|
||||||
]))
|
|
||||||
if isinstalled('orchestra.contrib.miscellaneous'):
|
|
||||||
url = reverse('admin:miscellaneous_miscservice_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Miscellaneous"), url))
|
|
||||||
if isinstalled('orchestra.contrib.issues'):
|
|
||||||
url = reverse('admin:issues_queue_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Ticket queues"), url))
|
|
||||||
if isinstalled('djcelery'):
|
|
||||||
task = reverse('admin:djcelery_taskstate_changelist')
|
|
||||||
periodic = reverse('admin:djcelery_periodictask_changelist')
|
|
||||||
worker = reverse('admin:djcelery_workerstate_changelist')
|
|
||||||
childrens.append(items.MenuItem(_("Tasks"), task, children=[
|
|
||||||
items.MenuItem(_("Logs"), task),
|
|
||||||
items.MenuItem(_("Periodic tasks"), periodic),
|
|
||||||
items.MenuItem(_("Workers"), worker),
|
|
||||||
]))
|
|
||||||
childrens.extend(process_registered_models(administration))
|
|
||||||
return childrens
|
|
||||||
|
|
||||||
|
|
||||||
class OrchestraMenu(Menu):
|
class OrchestraMenu(Menu):
|
||||||
|
@ -122,16 +79,16 @@ class OrchestraMenu(Menu):
|
||||||
# items.Bookmarks(),
|
# items.Bookmarks(),
|
||||||
items.MenuItem(
|
items.MenuItem(
|
||||||
_("Services"),
|
_("Services"),
|
||||||
children=get_services()
|
children=process_registry(services)
|
||||||
),
|
),
|
||||||
items.MenuItem(
|
items.MenuItem(
|
||||||
_("Accounts"),
|
_("Accounts"),
|
||||||
reverse('admin:accounts_account_changelist'),
|
reverse('admin:accounts_account_changelist'),
|
||||||
children=get_accounts()
|
children=process_registry(accounts)
|
||||||
),
|
),
|
||||||
items.MenuItem(
|
items.MenuItem(
|
||||||
_("Administration"),
|
_("Administration"),
|
||||||
children=get_administration_items()
|
children=process_registry(administration)
|
||||||
),
|
),
|
||||||
items.MenuItem("API", api_link(context)),
|
items.MenuItem("API", api_link(context)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -233,75 +233,6 @@ ADMIN_TOOLS_MENU = 'orchestra.admin.menu.OrchestraMenu'
|
||||||
# Fluent dashboard
|
# Fluent dashboard
|
||||||
ADMIN_TOOLS_INDEX_DASHBOARD = 'orchestra.admin.dashboard.OrchestraIndexDashboard'
|
ADMIN_TOOLS_INDEX_DASHBOARD = 'orchestra.admin.dashboard.OrchestraIndexDashboard'
|
||||||
FLUENT_DASHBOARD_ICON_THEME = '../orchestra/icons'
|
FLUENT_DASHBOARD_ICON_THEME = '../orchestra/icons'
|
||||||
FLUENT_DASHBOARD_APP_GROUPS = (
|
|
||||||
# Services group is generated by orchestra.admin.dashboard
|
|
||||||
('Accounts', {
|
|
||||||
'models': (
|
|
||||||
'orchestra.contrib.accounts.models.Account',
|
|
||||||
'orchestra.contrib.contacts.models.Contact',
|
|
||||||
'orchestra.contrib.orders.models.Order',
|
|
||||||
'orchestra.contrib.plans.models.ContractedPlan',
|
|
||||||
'orchestra.contrib.bills.models.Bill',
|
|
||||||
'orchestra.contrib.payments.models.Transaction',
|
|
||||||
'orchestra.contrib.issues.models.Ticket',
|
|
||||||
),
|
|
||||||
'collapsible': True,
|
|
||||||
}),
|
|
||||||
('Administration', {
|
|
||||||
'models': (
|
|
||||||
'djcelery.models.TaskState',
|
|
||||||
'orchestra.contrib.orchestration.models.Route',
|
|
||||||
'orchestra.contrib.orchestration.models.BackendLog',
|
|
||||||
'orchestra.contrib.orchestration.models.Server',
|
|
||||||
'orchestra.contrib.resources.models.Resource',
|
|
||||||
'orchestra.contrib.resources.models.ResourceData',
|
|
||||||
'orchestra.contrib.services.models.Service',
|
|
||||||
'orchestra.contrib.plans.models.Plan',
|
|
||||||
'orchestra.contrib.miscellaneous.models.MiscService',
|
|
||||||
),
|
|
||||||
'collapsible': True,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
FLUENT_DASHBOARD_APP_ICONS = {
|
|
||||||
# Services
|
|
||||||
'webs/web': 'web.png',
|
|
||||||
'mail/address': 'X-office-address-book.png',
|
|
||||||
'mailboxes/mailbox': 'email.png',
|
|
||||||
'mailboxes/address': 'X-office-address-book.png',
|
|
||||||
'lists/list': 'email-alter.png',
|
|
||||||
'domains/domain': 'domain.png',
|
|
||||||
'multitenance/tenant': 'apps.png',
|
|
||||||
'webapps/webapp': 'Applications-other.png',
|
|
||||||
'websites/website': 'Applications-internet.png',
|
|
||||||
'databases/database': 'database.png',
|
|
||||||
'databases/databaseuser': 'postgresql.png',
|
|
||||||
'vps/vps': 'TuxBox.png',
|
|
||||||
'miscellaneous/miscellaneous': 'applications-other.png',
|
|
||||||
'saas/saas': 'saas.png',
|
|
||||||
'systemusers/systemuser': 'roleplaying.png',
|
|
||||||
# Accounts
|
|
||||||
'accounts/account': 'Face-monkey.png',
|
|
||||||
'contacts/contact': 'contact_book.png',
|
|
||||||
'orders/order': 'basket.png',
|
|
||||||
'plans/contractedplan': 'ContractedPack.png',
|
|
||||||
'services/service': 'price.png',
|
|
||||||
'bills/bill': 'invoice.png',
|
|
||||||
'payments/paymentsource': 'card_in_use.png',
|
|
||||||
'payments/transaction': 'transaction.png',
|
|
||||||
'payments/transactionprocess': 'transactionprocess.png',
|
|
||||||
'issues/ticket': 'Ticket_star.png',
|
|
||||||
'miscellaneous/miscservice': 'Misc-Misc-Box-icon.png',
|
|
||||||
# Administration
|
|
||||||
'settings/setting': 'preferences.png',
|
|
||||||
'djcelery/taskstate': 'taskstate.png',
|
|
||||||
'orchestration/server': 'vps.png',
|
|
||||||
'orchestration/route': 'hal.png',
|
|
||||||
'orchestration/backendlog': 'scriptlog.png',
|
|
||||||
'resources/resource': "gauge.png",
|
|
||||||
'resources/resourcedata': "monitor.png",
|
|
||||||
'plans/plan': 'Pack.png',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Django-celery
|
# Django-celery
|
||||||
|
|
|
@ -12,7 +12,7 @@ class AccountConfig(AppConfig):
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from .management import create_initial_superuser
|
from .management import create_initial_superuser
|
||||||
from .models import Account
|
from .models import Account
|
||||||
services.register(Account, menu=False)
|
services.register(Account, menu=False, dashboard=False)
|
||||||
accounts.register(Account)
|
accounts.register(Account, icon='Face-monkey.png')
|
||||||
post_migrate.connect(create_initial_superuser,
|
post_migrate.connect(create_initial_superuser,
|
||||||
dispatch_uid="orchestra.contrib.accounts.management.createsuperuser")
|
dispatch_uid="orchestra.contrib.accounts.management.createsuperuser")
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.bills.apps.BillsConfig'
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import accounts
|
||||||
|
|
||||||
|
|
||||||
|
class BillsConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.bills'
|
||||||
|
verbose_name = 'Bills'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Bill
|
||||||
|
accounts.register(Bill, icon='invoice.png')
|
|
@ -13,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.contrib.accounts.models import Account
|
from orchestra.contrib.accounts.models import Account
|
||||||
from orchestra.contrib.contacts.models import Contact
|
from orchestra.contrib.contacts.models import Contact
|
||||||
from orchestra.core import accounts, validators
|
from orchestra.core import validators
|
||||||
from orchestra.utils.html import html_to_pdf
|
from orchestra.utils.html import html_to_pdf
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -351,6 +351,3 @@ class BillSubline(models.Model):
|
||||||
# if self.line.bill.is_open:
|
# if self.line.bill.is_open:
|
||||||
# self.line.bill.total = self.line.bill.get_total()
|
# self.line.bill.total = self.line.bill.get_total()
|
||||||
# self.line.bill.save(update_fields=['total'])
|
# self.line.bill.save(update_fields=['total'])
|
||||||
|
|
||||||
|
|
||||||
accounts.register(Bill)
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.contacts.apps.ContactsConfig'
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import accounts
|
||||||
|
|
||||||
|
|
||||||
|
class ContactsConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.contacts'
|
||||||
|
verbose_name = 'Contacts'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Contact
|
||||||
|
accounts.register(Contact, icon='contact_book.png')
|
|
@ -3,7 +3,7 @@ from django.core.validators import RegexValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import accounts, validators
|
from orchestra.core import validators
|
||||||
from orchestra.models.fields import MultiSelectField
|
from orchestra.models.fields import MultiSelectField
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -78,6 +78,3 @@ class Contact(models.Model):
|
||||||
errors['zipcode'] = error
|
errors['zipcode'] = error
|
||||||
if errors:
|
if errors:
|
||||||
raise ValidationError(errors)
|
raise ValidationError(errors)
|
||||||
|
|
||||||
|
|
||||||
accounts.register(Contact)
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.databases.apps.DatabasesConfig'
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
|
|
||||||
|
|
||||||
|
class DatabasesConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.databases'
|
||||||
|
verbose_name = 'Databases'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Database, DatabaseUser
|
||||||
|
services.register(Database, icon='database.png')
|
||||||
|
services.register(DatabaseUser, icon='postgresql.png', verbose_name_plural=_("Database users"))
|
|
@ -3,7 +3,7 @@ import hashlib
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import validators, services
|
from orchestra.core import validators
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
|
||||||
|
@ -76,7 +76,3 @@ class DatabaseUser(models.Model):
|
||||||
self.password = '*%s' % hexdigest.upper()
|
self.password = '*%s' % hexdigest.upper()
|
||||||
else:
|
else:
|
||||||
raise TypeError("Database type '%s' not supported" % self.type)
|
raise TypeError("Database type '%s' not supported" % self.type)
|
||||||
|
|
||||||
|
|
||||||
services.register(Database)
|
|
||||||
services.register(DatabaseUser, verbose_name_plural=_("Database users"))
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.domains.apps.DomainsConfig'
|
|
@ -11,8 +11,8 @@ from orchestra.contrib.accounts.admin import AccountAdminMixin
|
||||||
from orchestra.utils import apps
|
from orchestra.utils import apps
|
||||||
|
|
||||||
from .actions import view_zone
|
from .actions import view_zone
|
||||||
from .forms import RecordInlineFormSet, BatchDomainCreationAdminForm
|
|
||||||
from .filters import TopDomainListFilter
|
from .filters import TopDomainListFilter
|
||||||
|
from .forms import RecordInlineFormSet, BatchDomainCreationAdminForm
|
||||||
from .models import Domain, Record
|
from .models import Domain, Record
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,11 +21,6 @@ class RecordInline(admin.TabularInline):
|
||||||
formset = RecordInlineFormSet
|
formset = RecordInlineFormSet
|
||||||
verbose_name_plural = _("Extra records")
|
verbose_name_plural = _("Extra records")
|
||||||
|
|
||||||
# class Media:
|
|
||||||
# css = {
|
|
||||||
# 'all': ('orchestra/css/hide-inline-id.css',)
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
def formfield_for_dbfield(self, db_field, **kwargs):
|
def formfield_for_dbfield(self, db_field, **kwargs):
|
||||||
""" Make value input widget bigger """
|
""" Make value input widget bigger """
|
||||||
if db_field.name == 'value':
|
if db_field.name == 'value':
|
||||||
|
@ -73,9 +68,9 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||||
change_view_actions = [view_zone]
|
change_view_actions = [view_zone]
|
||||||
|
|
||||||
def structured_name(self, domain):
|
def structured_name(self, domain):
|
||||||
if not domain.is_top:
|
if domain.is_top:
|
||||||
return ' '*4 + domain.name
|
|
||||||
return domain.name
|
return domain.name
|
||||||
|
return ' '*4 + domain.name
|
||||||
structured_name.short_description = _("name")
|
structured_name.short_description = _("name")
|
||||||
structured_name.allow_tags = True
|
structured_name.allow_tags = True
|
||||||
structured_name.admin_order_field = 'structured_name'
|
structured_name.admin_order_field = 'structured_name'
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
|
|
||||||
|
|
||||||
|
class DomainsConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.domains'
|
||||||
|
verbose_name = 'Domains'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Domain
|
||||||
|
services.register(Domain, icon='domain.png')
|
|
@ -2,7 +2,6 @@ from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ungettext, ugettext_lazy as _
|
from django.utils.translation import ungettext, ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import services
|
|
||||||
from orchestra.core.validators import validate_ipv4_address, validate_ipv6_address, validate_ascii
|
from orchestra.core.validators import validate_ipv4_address, validate_ipv6_address, validate_ascii
|
||||||
from orchestra.utils.python import AttrDict
|
from orchestra.utils.python import AttrDict
|
||||||
|
|
||||||
|
@ -271,6 +270,3 @@ class Record(models.Model):
|
||||||
|
|
||||||
def get_ttl(self):
|
def get_ttl(self):
|
||||||
return self.ttl or settings.DOMAINS_DEFAULT_TTL
|
return self.ttl or settings.DOMAINS_DEFAULT_TTL
|
||||||
|
|
||||||
|
|
||||||
services.register(Domain)
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
REQUIRED_APPS = ['slices']
|
default_app_config = 'orchestra.contrib.issues.apps.IssuesConfig'
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import accounts, administration
|
||||||
|
|
||||||
|
|
||||||
|
class IssuesConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.issues'
|
||||||
|
verbose_name = "Issues"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Queue, Ticket
|
||||||
|
accounts.register(Ticket, icon='Ticket_star.png')
|
||||||
|
administration.register(Queue, dashboard=False)
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.lists.apps.ListsConfig'
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
|
|
||||||
|
|
||||||
|
class ListsConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.lists'
|
||||||
|
verbose_name = 'Lists'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import List
|
||||||
|
services.register(List, icon='email-alter.png')
|
|
@ -2,7 +2,6 @@ from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import services
|
|
||||||
from orchestra.core.validators import validate_name
|
from orchestra.core.validators import validate_name
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -70,6 +69,3 @@ class List(models.Model):
|
||||||
'name': self.name
|
'name': self.name
|
||||||
}
|
}
|
||||||
return settings.LISTS_LIST_URL % context
|
return settings.LISTS_LIST_URL % context
|
||||||
|
|
||||||
|
|
||||||
services.register(List)
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.mailboxes.apps.MailboxesConfig'
|
|
@ -0,0 +1,13 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
|
|
||||||
|
|
||||||
|
class MailboxesConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.mailboxes'
|
||||||
|
verbose_name = 'Mailboxes'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Mailbox, Address
|
||||||
|
services.register(Mailbox, icon='email.png')
|
||||||
|
services.register(Address, icon='X-office-address-book.png')
|
|
@ -6,8 +6,6 @@ from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import services
|
|
||||||
|
|
||||||
from . import validators, settings
|
from . import validators, settings
|
||||||
|
|
||||||
|
|
||||||
|
@ -152,7 +150,3 @@ class Autoresponse(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.address
|
return self.address
|
||||||
|
|
||||||
|
|
||||||
services.register(Mailbox)
|
|
||||||
services.register(Address)
|
|
||||||
|
|
|
@ -9,4 +9,4 @@ class MailerConfig(AppConfig):
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from .models import Message
|
from .models import Message
|
||||||
administration.register(Message)
|
administration.register(Message, icon='Mail-send.png')
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Message(models.Model):
|
||||||
# Max tries
|
# Max tries
|
||||||
if self.retries >= len(settings.MAILER_DEFERE_SECONDS):
|
if self.retries >= len(settings.MAILER_DEFERE_SECONDS):
|
||||||
self.state = self.FAILED
|
self.state = self.FAILED
|
||||||
self.save(update_fields=('state', 'retries'))
|
self.save(update_fields=('state', 'retries', 'last_retry'))
|
||||||
|
|
||||||
def sent(self):
|
def sent(self):
|
||||||
self.state = self.SENT
|
self.state = self.SENT
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.miscellaneous.apps.MiscellaneousConfig'
|
|
@ -0,0 +1,15 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import services, administration
|
||||||
|
from orchestra.core.translations import ModelTranslation
|
||||||
|
|
||||||
|
|
||||||
|
class MiscellaneousConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.miscellaneous'
|
||||||
|
verbose_name = 'Miscellaneous'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import MiscService, Miscellaneous
|
||||||
|
services.register(Miscellaneous, icon='applications-other.png')
|
||||||
|
administration.register(MiscService, icon='Misc-Misc-Box-icon.png')
|
||||||
|
ModelTranslation.register(MiscService, ('verbose_name',))
|
|
@ -2,8 +2,6 @@ from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import services
|
|
||||||
from orchestra.core.translations import ModelTranslation
|
|
||||||
from orchestra.core.validators import validate_name
|
from orchestra.core.validators import validate_name
|
||||||
from orchestra.models.fields import NullableCharField
|
from orchestra.models.fields import NullableCharField
|
||||||
|
|
||||||
|
@ -69,8 +67,3 @@ class Miscellaneous(models.Model):
|
||||||
if self.identifier:
|
if self.identifier:
|
||||||
self.identifier = self.identifier.strip()
|
self.identifier = self.identifier.strip()
|
||||||
self.description = self.description.strip()
|
self.description = self.description.strip()
|
||||||
|
|
||||||
|
|
||||||
services.register(Miscellaneous)
|
|
||||||
|
|
||||||
ModelTranslation.register(MiscService, ('verbose_name',))
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ import copy
|
||||||
from .backends import ServiceBackend, ServiceController, replace
|
from .backends import ServiceBackend, ServiceController, replace
|
||||||
|
|
||||||
|
|
||||||
|
default_app_config = 'orchestra.contrib.orchestration.apps.OrchestrationConfig'
|
||||||
|
|
||||||
|
|
||||||
class Operation():
|
class Operation():
|
||||||
DELETE = 'delete'
|
DELETE = 'delete'
|
||||||
SAVE = 'save'
|
SAVE = 'save'
|
||||||
|
@ -30,10 +33,10 @@ class Operation():
|
||||||
self.routes = routes
|
self.routes = routes
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute(cls, operations, async=False):
|
def execute(cls, operations, serialize=False, async=False):
|
||||||
from . import manager
|
from . import manager
|
||||||
scripts, block = manager.generate(operations)
|
scripts, oserialize = manager.generate(operations)
|
||||||
return manager.execute(scripts, block=block, async=async)
|
return manager.execute(scripts, serialize=(serialize or oserialize), async=async)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def execute_action(cls, instance, action):
|
def execute_action(cls, instance, action):
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import administration
|
||||||
|
|
||||||
|
|
||||||
|
class OrchestrationConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.orchestration'
|
||||||
|
verbose_name = "Orchestration"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Server, Route, BackendLog
|
||||||
|
administration.register(BackendLog, icon='scriptlog.png')
|
||||||
|
administration.register(Server, parent=BackendLog, icon='vps.png')
|
||||||
|
administration.register(Route, parent=BackendLog, icon='hal.png')
|
|
@ -45,7 +45,7 @@ class ServiceBackend(plugins.Plugin, metaclass=ServiceMount):
|
||||||
actions = []
|
actions = []
|
||||||
default_route_match = 'True'
|
default_route_match = 'True'
|
||||||
# Force the backend manager to block in multiple backend executions executing them synchronously
|
# Force the backend manager to block in multiple backend executions executing them synchronously
|
||||||
block = False
|
serialize = False
|
||||||
doc_settings = None
|
doc_settings = None
|
||||||
# By default backend will not run if actions do not generate insctructions,
|
# By default backend will not run if actions do not generate insctructions,
|
||||||
# If your backend uses prepare() or commit() only then you should set force_empty_action_execution = True
|
# If your backend uses prepare() or commit() only then you should set force_empty_action_execution = True
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Command(BaseCommand):
|
||||||
else:
|
else:
|
||||||
for instance in queryset:
|
for instance in queryset:
|
||||||
manager.collect(instance, action, operations=operations, route_cache=route_cache)
|
manager.collect(instance, action, operations=operations, route_cache=route_cache)
|
||||||
scripts, block = manager.generate(operations)
|
scripts, serialize = manager.generate(operations)
|
||||||
servers = []
|
servers = []
|
||||||
# Print scripts
|
# Print scripts
|
||||||
for key, value in scripts.items():
|
for key, value in scripts.items():
|
||||||
|
@ -96,7 +96,7 @@ class Command(BaseCommand):
|
||||||
return
|
return
|
||||||
break
|
break
|
||||||
if not dry:
|
if not dry:
|
||||||
logs = manager.execute(scripts, block=block)
|
logs = manager.execute(scripts, serialize=serialize)
|
||||||
for log in logs:
|
for log in logs:
|
||||||
self.stdout.write(log.stdout)
|
self.stdout.write(log.stdout)
|
||||||
self.stderr.write(log.stderr)
|
self.stderr.write(log.stderr)
|
||||||
|
|
|
@ -20,7 +20,7 @@ logger = logging.getLogger(__name__)
|
||||||
router = import_class(settings.ORCHESTRATION_ROUTER)
|
router = import_class(settings.ORCHESTRATION_ROUTER)
|
||||||
|
|
||||||
|
|
||||||
def as_task(execute, log, operations):
|
def keep_log(execute, log, operations):
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
""" send report """
|
""" send report """
|
||||||
# Remember that threads have their oun connection poll
|
# Remember that threads have their oun connection poll
|
||||||
|
@ -30,14 +30,14 @@ def as_task(execute, log, operations):
|
||||||
if log.state != log.SUCCESS:
|
if log.state != log.SUCCESS:
|
||||||
send_report(execute, args, log)
|
send_report(execute, args, log)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
subject = 'EXCEPTION executing backend(s) %s %s' % (str(args), str(kwargs))
|
trace = traceback.format_exc()
|
||||||
message = traceback.format_exc()
|
|
||||||
logger.error(subject)
|
|
||||||
logger.error(message)
|
|
||||||
mail_admins(subject, message)
|
|
||||||
log.state = BackendLog.EXCEPTION
|
log.state = BackendLog.EXCEPTION
|
||||||
log.stderr = traceback.format_exc()
|
log.stderr = trace
|
||||||
log.save(update_fields=('state', 'stderr'))
|
log.save()
|
||||||
|
subject = 'EXCEPTION executing backend(s) %s %s' % (str(args), str(kwargs))
|
||||||
|
logger.error(subject)
|
||||||
|
logger.error(trace)
|
||||||
|
mail_admins(subject, trace)
|
||||||
# We don't propagate the exception further to avoid transaction rollback
|
# We don't propagate the exception further to avoid transaction rollback
|
||||||
finally:
|
finally:
|
||||||
# Store and log the operation
|
# Store and log the operation
|
||||||
|
@ -56,7 +56,7 @@ def as_task(execute, log, operations):
|
||||||
def generate(operations):
|
def generate(operations):
|
||||||
scripts = OrderedDict()
|
scripts = OrderedDict()
|
||||||
cache = {}
|
cache = {}
|
||||||
block = False
|
serialize = False
|
||||||
# Generate scripts per route+backend
|
# Generate scripts per route+backend
|
||||||
for operation in operations:
|
for operation in operations:
|
||||||
logger.debug("Queued %s" % str(operation))
|
logger.debug("Queued %s" % str(operation))
|
||||||
|
@ -86,18 +86,18 @@ def generate(operations):
|
||||||
pre_action.send(**kwargs)
|
pre_action.send(**kwargs)
|
||||||
method(operation.instance)
|
method(operation.instance)
|
||||||
post_action.send(**kwargs)
|
post_action.send(**kwargs)
|
||||||
if backend.block:
|
if backend.serialize:
|
||||||
block = True
|
serialize = True
|
||||||
for value in scripts.values():
|
for value in scripts.values():
|
||||||
backend, operations = value
|
backend, operations = value
|
||||||
backend.set_tail()
|
backend.set_tail()
|
||||||
pre_commit.send(sender=backend.__class__, backend=backend)
|
pre_commit.send(sender=backend.__class__, backend=backend)
|
||||||
backend.commit()
|
backend.commit()
|
||||||
post_commit.send(sender=backend.__class__, backend=backend)
|
post_commit.send(sender=backend.__class__, backend=backend)
|
||||||
return scripts, block
|
return scripts, serialize
|
||||||
|
|
||||||
|
|
||||||
def execute(scripts, block=False, async=False):
|
def execute(scripts, serialize=False, async=False):
|
||||||
""" executes the operations on the servers """
|
""" executes the operations on the servers """
|
||||||
if settings.ORCHESTRATION_DISABLE_EXECUTION:
|
if settings.ORCHESTRATION_DISABLE_EXECUTION:
|
||||||
logger.info('Orchestration execution is dissabled by ORCHESTRATION_DISABLE_EXECUTION settings.')
|
logger.info('Orchestration execution is dissabled by ORCHESTRATION_DISABLE_EXECUTION settings.')
|
||||||
|
@ -110,21 +110,22 @@ def execute(scripts, block=False, async=False):
|
||||||
route, __ = key
|
route, __ = key
|
||||||
backend, operations = value
|
backend, operations = value
|
||||||
args = (route.host,)
|
args = (route.host,)
|
||||||
|
async = not serialize and (async or route.async)
|
||||||
kwargs = {
|
kwargs = {
|
||||||
'async': async or route.async
|
'async': async,
|
||||||
}
|
}
|
||||||
log = backend.create_log(*args, **kwargs)
|
log = backend.create_log(*args, **kwargs)
|
||||||
kwargs['log'] = log
|
kwargs['log'] = log
|
||||||
task = as_task(backend.execute, log, operations)
|
task = keep_log(backend.execute, log, operations)
|
||||||
logger.debug('%s is going to be executed on %s' % (backend, route.host))
|
logger.debug('%s is going to be executed on %s' % (backend, route.host))
|
||||||
if block:
|
if serialize:
|
||||||
# Execute one backend at a time, no need for threads
|
# Execute one backend at a time, no need for threads
|
||||||
task(*args, **kwargs)
|
task(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
task = close_connection(task)
|
task = close_connection(task)
|
||||||
thread = threading.Thread(target=task, args=args, kwargs=kwargs)
|
thread = threading.Thread(target=task, args=args, kwargs=kwargs)
|
||||||
thread.start()
|
thread.start()
|
||||||
if not route.async:
|
if not async:
|
||||||
threads_to_join.append(thread)
|
threads_to_join.append(thread)
|
||||||
logs.append(log)
|
logs.append(log)
|
||||||
[ thread.join() for thread in threads_to_join ]
|
[ thread.join() for thread in threads_to_join ]
|
||||||
|
|
|
@ -97,14 +97,14 @@ class OperationsMiddleware(object):
|
||||||
operations = self.get_pending_operations()
|
operations = self.get_pending_operations()
|
||||||
if operations:
|
if operations:
|
||||||
try:
|
try:
|
||||||
scripts, block = manager.generate(operations)
|
scripts, serialize = manager.generate(operations)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
self.leave_transaction_management(exception)
|
self.leave_transaction_management(exception)
|
||||||
raise
|
raise
|
||||||
# We commit transaction just before executing operations
|
# We commit transaction just before executing operations
|
||||||
# because here is when IntegrityError show up
|
# because here is when IntegrityError show up
|
||||||
self.leave_transaction_management()
|
self.leave_transaction_management()
|
||||||
logs = manager.execute(scripts, block=block)
|
logs = manager.execute(scripts, serialize=serialize)
|
||||||
if logs and resolve(request.path).app_name == 'admin':
|
if logs and resolve(request.path).app_name == 'admin':
|
||||||
message_user(request, logs)
|
message_user(request, logs)
|
||||||
return response
|
return response
|
||||||
|
|
|
@ -10,6 +10,6 @@ class OrdersConfig(AppConfig):
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from .models import Order
|
from .models import Order
|
||||||
accounts.register(Order)
|
accounts.register(Order, icon='basket.png')
|
||||||
if database_ready():
|
if database_ready():
|
||||||
from . import signals
|
from . import signals
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.payments.apps.PaymentsConfig'
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import accounts
|
||||||
|
|
||||||
|
|
||||||
|
class PaymentsConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.payments'
|
||||||
|
verbose_name = "Payments"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import PaymentSource, Transaction, TransactionProcess
|
||||||
|
accounts.register(PaymentSource, dashboard=False)
|
||||||
|
accounts.register(Transaction, icon='transaction.png')
|
||||||
|
accounts.register(TransactionProcess, icon='transactionprocess.png', dashboard=False)
|
|
@ -4,7 +4,6 @@ from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from jsonfield import JSONField
|
from jsonfield import JSONField
|
||||||
|
|
||||||
from orchestra.core import accounts
|
|
||||||
from orchestra.models.queryset import group_by
|
from orchestra.models.queryset import group_by
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -200,7 +199,3 @@ class TransactionProcess(models.Model):
|
||||||
for transaction in self.transactions.processing():
|
for transaction in self.transactions.processing():
|
||||||
transaction.mark_as_secured()
|
transaction.mark_as_secured()
|
||||||
self.save(update_fields=['state'])
|
self.save(update_fields=['state'])
|
||||||
|
|
||||||
|
|
||||||
accounts.register(PaymentSource)
|
|
||||||
accounts.register(Transaction)
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.plans.apps.PlansConfig'
|
|
@ -0,0 +1,15 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import administration, accounts
|
||||||
|
from orchestra.core.translations import ModelTranslation
|
||||||
|
|
||||||
|
|
||||||
|
class PlansConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.plans'
|
||||||
|
verbose_name = 'Plans'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Plan, ContractedPlan
|
||||||
|
accounts.register(ContractedPlan, icon='ContractedPack.png')
|
||||||
|
administration.register(Plan, icon='Pack.png')
|
||||||
|
ModelTranslation.register(Plan, ('verbose_name',))
|
|
@ -5,7 +5,6 @@ from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import services, accounts
|
from orchestra.core import services, accounts
|
||||||
from orchestra.core.translations import ModelTranslation
|
|
||||||
from orchestra.core.validators import validate_name
|
from orchestra.core.validators import validate_name
|
||||||
from orchestra.models import queryset
|
from orchestra.models import queryset
|
||||||
|
|
||||||
|
@ -100,9 +99,3 @@ class Rate(models.Model):
|
||||||
for name, method in cls.RATE_METHODS.items():
|
for name, method in cls.RATE_METHODS.items():
|
||||||
choices.append((name, method.verbose_name))
|
choices.append((name, method.verbose_name))
|
||||||
return choices
|
return choices
|
||||||
|
|
||||||
|
|
||||||
accounts.register(ContractedPlan)
|
|
||||||
services.register(ContractedPlan, menu=False)
|
|
||||||
|
|
||||||
ModelTranslation.register(Plan, ('verbose_name',))
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from django import db
|
from django import db
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import administration
|
||||||
from orchestra.utils.db import database_ready
|
from orchestra.utils.db import database_ready
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +17,10 @@ class ResourcesConfig(AppConfig):
|
||||||
except db.utils.OperationalError:
|
except db.utils.OperationalError:
|
||||||
# Not ready afterall
|
# Not ready afterall
|
||||||
pass
|
pass
|
||||||
|
from .models import Resource, ResourceData, MonitorData
|
||||||
|
administration.register(Resource, icon='gauge.png')
|
||||||
|
administration.register(ResourceData, parent=Resource, icon='monitor.png')
|
||||||
|
administration.register(MonitorData, parent=Resource, dashboard=False)
|
||||||
|
|
||||||
def reload_relations(self):
|
def reload_relations(self):
|
||||||
from .admin import insert_resource_inlines
|
from .admin import insert_resource_inlines
|
||||||
|
|
|
@ -72,7 +72,7 @@ class ServiceMonitor(ServiceBackend):
|
||||||
MonitorData.objects.create(monitor=name, object_id=object_id,
|
MonitorData.objects.create(monitor=name, object_id=object_id,
|
||||||
content_type=ct, value=value, created_at=self.current_date)
|
content_type=ct, value=value, created_at=self.current_date)
|
||||||
|
|
||||||
def execute(self, server, async=False):
|
def execute(self, *args, **kwargs):
|
||||||
log = super(ServiceMonitor, self).execute(server, async=async)
|
log = super(ServiceMonitor, self).execute(*args, **kwargs)
|
||||||
self.store(log)
|
self.store(log)
|
||||||
return log
|
return log
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('resources', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CrontabSchedule',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(serialize=False, primary_key=True, auto_created=True, verbose_name='ID')),
|
||||||
|
('minute', models.CharField(max_length=64, verbose_name='minute', default='*')),
|
||||||
|
('hour', models.CharField(max_length=64, verbose_name='hour', default='*')),
|
||||||
|
('day_of_week', models.CharField(max_length=64, verbose_name='day of week', default='*')),
|
||||||
|
('day_of_month', models.CharField(max_length=64, verbose_name='day of month', default='*')),
|
||||||
|
('month_of_year', models.CharField(max_length=64, verbose_name='month of year', default='*')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'crontab',
|
||||||
|
'ordering': ('month_of_year', 'day_of_month', 'day_of_week', 'hour', 'minute'),
|
||||||
|
'verbose_name_plural': 'crontabs',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('resources', '0002_auto_20150502_1429'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
|
@ -0,0 +1,14 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('resources', '0003_auto_20150502_1433'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
]
|
|
@ -148,9 +148,8 @@ class Resource(models.Model):
|
||||||
|
|
||||||
def monitor(self, async=True):
|
def monitor(self, async=True):
|
||||||
if async:
|
if async:
|
||||||
print(tasks.monitor.delay)
|
return tasks.monitor.apply_async(self.pk)
|
||||||
return tasks.monitor.delay(self.pk, async=async)
|
return tasks.monitor(self.pk)
|
||||||
return tasks.monitor(self.pk, async=async)
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceData(models.Model):
|
class ResourceData(models.Model):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from .backends import ServiceMonitor
|
||||||
|
|
||||||
|
|
||||||
@task(name='resources.Monitor')
|
@task(name='resources.Monitor')
|
||||||
def monitor(resource_id, ids=None, async=True):
|
def monitor(resource_id, ids=None):
|
||||||
with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60):
|
with LockFile('/dev/shm/resources.monitor-%i.lock' % resource_id, expire=60*60):
|
||||||
from .models import ResourceData, Resource
|
from .models import ResourceData, Resource
|
||||||
resource = Resource.objects.get(pk=resource_id)
|
resource = Resource.objects.get(pk=resource_id)
|
||||||
|
@ -29,9 +29,7 @@ def monitor(resource_id, ids=None, async=True):
|
||||||
for obj in model.objects.filter(**kwargs):
|
for obj in model.objects.filter(**kwargs):
|
||||||
op = Operation(backend, obj, Operation.MONITOR)
|
op = Operation(backend, obj, Operation.MONITOR)
|
||||||
monitorings.append(op)
|
monitorings.append(op)
|
||||||
# TODO async=True only when running with celery
|
logs += Operation.execute(monitorings, async=False)
|
||||||
# monitor.request.id
|
|
||||||
logs += Operation.execute(monitorings, async=async)
|
|
||||||
|
|
||||||
kwargs = {'id__in': ids} if ids else {}
|
kwargs = {'id__in': ids} if ids else {}
|
||||||
# Update used resources and trigger resource exceeded and revovery
|
# Update used resources and trigger resource exceeded and revovery
|
||||||
|
|
|
@ -10,6 +10,4 @@ class SaaSConfig(AppConfig):
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from . import signals
|
from . import signals
|
||||||
from .models import SaaS
|
from .models import SaaS
|
||||||
services.register(SaaS)
|
services.register(SaaS, icon='saas.png')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ class GitLabSaaSBackend(ServiceController):
|
||||||
verbose_name = _("GitLab SaaS")
|
verbose_name = _("GitLab SaaS")
|
||||||
model = 'saas.SaaS'
|
model = 'saas.SaaS'
|
||||||
default_route_match = "saas.service == 'gitlab'"
|
default_route_match = "saas.service == 'gitlab'"
|
||||||
block = True
|
serialize = True
|
||||||
actions = ('save', 'delete', 'validate_creation')
|
actions = ('save', 'delete', 'validate_creation')
|
||||||
doc_settings = (settings,
|
doc_settings = (settings,
|
||||||
('SAAS_GITLAB_DOMAIN', 'SAAS_GITLAB_ROOT_PASSWORD'),
|
('SAAS_GITLAB_DOMAIN', 'SAAS_GITLAB_ROOT_PASSWORD'),
|
||||||
|
|
|
@ -18,7 +18,7 @@ class PhpListSaaSBackend(ServiceController):
|
||||||
verbose_name = _("phpList SaaS")
|
verbose_name = _("phpList SaaS")
|
||||||
model = 'saas.SaaS'
|
model = 'saas.SaaS'
|
||||||
default_route_match = "saas.service == 'phplist'"
|
default_route_match = "saas.service == 'phplist'"
|
||||||
block = True
|
serialize = True
|
||||||
|
|
||||||
def _save(self, saas, server):
|
def _save(self, saas, server):
|
||||||
admin_link = 'http://%s/admin/' % saas.get_site_domain()
|
admin_link = 'http://%s/admin/' % saas.get_site_domain()
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import administration, accounts
|
||||||
|
from orchestra.core.translations import ModelTranslation
|
||||||
|
|
||||||
|
|
||||||
class ServicesConfig(AppConfig):
|
class ServicesConfig(AppConfig):
|
||||||
name = 'orchestra.contrib.services'
|
name = 'orchestra.contrib.services'
|
||||||
verbose_name = 'Services'
|
verbose_name = 'Services'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import Service
|
||||||
|
administration.register(Service, icon='price.png')
|
||||||
|
ModelTranslation.register(Service, ('description',))
|
||||||
|
|
|
@ -8,7 +8,6 @@ from django.utils.module_loading import autodiscover_modules
|
||||||
from django.utils.translation import string_concat, ugettext_lazy as _
|
from django.utils.translation import string_concat, ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import caches, validators
|
from orchestra.core import caches, validators
|
||||||
from orchestra.core.translations import ModelTranslation
|
|
||||||
from orchestra.utils.python import import_class
|
from orchestra.utils.python import import_class
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -244,6 +243,3 @@ class Service(models.Model):
|
||||||
for instance in queryset:
|
for instance in queryset:
|
||||||
updates += order_model.update_orders(instance, service=self, commit=commit)
|
updates += order_model.update_orders(instance, service=self, commit=commit)
|
||||||
return updates
|
return updates
|
||||||
|
|
||||||
|
|
||||||
ModelTranslation.register(Service, ('description',))
|
|
||||||
|
|
|
@ -103,7 +103,5 @@ class SettingFileView(generic.TemplateView):
|
||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register_url(r'^settings/setting/view/$', SettingFileView.as_view(), 'settings_setting_view')
|
admin.site.register_url(r'^settings/setting/view/$', SettingFileView.as_view(), 'settings_setting_view')
|
||||||
admin.site.register_url(r'^settings/setting/$', SettingView.as_view(), 'settings_setting_change')
|
admin.site.register_url(r'^settings/setting/$', SettingView.as_view(), 'settings_setting_change')
|
||||||
OrchestraIndexDashboard.register_link('Administration', 'settings_setting_change', _("Settings"))
|
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.core.checks import register, Error
|
from django.core.checks import register, Error
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.utils.translation import ngettext, ugettext_lazy as _
|
||||||
|
|
||||||
|
from orchestra.core import administration
|
||||||
|
|
||||||
from . import Setting
|
from . import Setting
|
||||||
|
|
||||||
|
|
||||||
class SettingsConfig(AppConfig):
|
class SettingsConfig(AppConfig):
|
||||||
name = 'orchestra.contrib.settings'
|
name = 'orchestra.contrib.settings'
|
||||||
verbose_name = 'Settings'
|
verbose_name = 'Settings'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
administration.register_view('settings_setting_change', verbose_name=_("Settings"),
|
||||||
|
icon='Multimedia-volume-control.png')
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def check_settings(app_configs, **kwargs):
|
def check_settings(app_configs, **kwargs):
|
||||||
""" perfroms all the validation """
|
""" perfroms all the validation """
|
||||||
|
|
|
@ -12,7 +12,7 @@ class SystemUsersConfig(AppConfig):
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from .models import SystemUser
|
from .models import SystemUser
|
||||||
services.register(SystemUser)
|
services.register(SystemUser, icon='roleplaying.png')
|
||||||
if 'migrate' in sys.argv and 'accounts' not in sys.argv:
|
if 'migrate' in sys.argv and 'accounts' not in sys.argv:
|
||||||
post_migrate.connect(self.create_initial_systemuser,
|
post_migrate.connect(self.create_initial_systemuser,
|
||||||
dispatch_uid="orchestra.contrib.systemusers.apps.create_initial_systemuser")
|
dispatch_uid="orchestra.contrib.systemusers.apps.create_initial_systemuser")
|
||||||
|
|
|
@ -2,3 +2,6 @@ import sys
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
from .decorators import task, periodic_task, keep_state, apply_async
|
from .decorators import task, periodic_task, keep_state, apply_async
|
||||||
|
|
||||||
|
|
||||||
|
default_app_config = 'orchestra.contrib.tasks.apps.TasksConfig'
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import administration
|
||||||
|
|
||||||
|
|
||||||
|
class TasksConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.tasks'
|
||||||
|
verbose_name = "Tasks"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from djcelery.models import PeriodicTask, TaskState, WorkerState
|
||||||
|
administration.register(TaskState, icon='Edit-check-sheet.png')
|
||||||
|
administration.register(PeriodicTask, parent=TaskState, icon='Appointment.png')
|
||||||
|
administration.register(WorkerState, parent=TaskState, dashboard=False)
|
|
@ -6,6 +6,7 @@ from threading import Thread
|
||||||
from celery import shared_task as celery_shared_task
|
from celery import shared_task as celery_shared_task
|
||||||
from celery import states
|
from celery import states
|
||||||
from celery.decorators import periodic_task as celery_periodic_task
|
from celery.decorators import periodic_task as celery_periodic_task
|
||||||
|
from django.core.mail import mail_admins
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from orchestra.utils.db import close_connection
|
from orchestra.utils.db import close_connection
|
||||||
|
@ -26,11 +27,15 @@ def keep_state(fn):
|
||||||
result = fn(*args, **kwargs)
|
result = fn(*args, **kwargs)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
state.state = states.FAILURE
|
state.state = states.FAILURE
|
||||||
state.traceback = traceback.format_exc()
|
state.traceback = trace
|
||||||
state.runtime = (timezone.now()-now).total_seconds()
|
state.runtime = (timezone.now()-now).total_seconds()
|
||||||
state.save()
|
state.save()
|
||||||
|
subject = 'EXCEPTION executing task %s(args=%s, kwargs=%s)' % (name, str(args), str(kwargs))
|
||||||
|
trace = traceback.format_exc()
|
||||||
|
logger.error(subject)
|
||||||
|
logger.error(trace)
|
||||||
|
mail_admins(subject, trace)
|
||||||
return
|
return
|
||||||
# TODO send email
|
|
||||||
else:
|
else:
|
||||||
state.state = states.SUCCESS
|
state.state = states.SUCCESS
|
||||||
state.result = str(result)
|
state.result = str(result)
|
||||||
|
|
|
@ -1,2 +1,15 @@
|
||||||
# create crontab entries for defines periodic tasks
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
|
from djcelery.app import app
|
||||||
|
from djcelery.schedulers import DatabaseScheduler
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = 'Runs Orchestra method.'
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
dbschedule = DatabaseScheduler(app=app)
|
||||||
|
self.stdout.write('\033[1m%i periodic tasks have been syncronized:\033[0m' % len(dbschedule.schedule))
|
||||||
|
size = max([len(name) for name in dbschedule.schedule])+1
|
||||||
|
for name, task in dbschedule.schedule.items():
|
||||||
|
spaces = ' '*(size-len(name))
|
||||||
|
self.stdout.write(' %s%s%s' % (name, spaces, task.schedule))
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.vps.apps.VPSConfig'
|
|
@ -0,0 +1,12 @@
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
|
|
||||||
|
|
||||||
|
class VPSConfig(AppConfig):
|
||||||
|
name = 'orchestra.contrib.vps'
|
||||||
|
verbose_name = 'VPS'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from .models import VPS
|
||||||
|
services.register(VPS, icon='TuxBox.png')
|
|
@ -1,8 +1,7 @@
|
||||||
|
from django.contrib.auth.hashers import make_password
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.contrib.auth.hashers import make_password
|
|
||||||
|
|
||||||
from orchestra.core import services
|
|
||||||
from orchestra.core.validators import validate_hostname
|
from orchestra.core.validators import validate_hostname
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -32,6 +31,3 @@ class VPS(models.Model):
|
||||||
|
|
||||||
def get_username(self):
|
def get_username(self):
|
||||||
return self.hostname
|
return self.hostname
|
||||||
|
|
||||||
|
|
||||||
services.register(VPS)
|
|
||||||
|
|
|
@ -10,4 +10,4 @@ class WebAppsConfig(AppConfig):
|
||||||
def ready(self):
|
def ready(self):
|
||||||
from . import signals
|
from . import signals
|
||||||
from .models import WebApp
|
from .models import WebApp
|
||||||
services.register(WebApp)
|
services.register(WebApp, icon='Applications-other.png')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
default_app_config = 'orchestra.contrib.websites.apps.WebsitesConfig'
|
|
@ -1,17 +1,20 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.contrib.contenttypes.fields import GenericRelation
|
from django.contrib.contenttypes.fields import GenericRelation
|
||||||
|
|
||||||
|
from orchestra.core import services
|
||||||
from orchestra.utils.db import database_ready
|
from orchestra.utils.db import database_ready
|
||||||
|
|
||||||
|
|
||||||
class WebsiteConfig(AppConfig):
|
class WebsitesConfig(AppConfig):
|
||||||
name = 'orchestra.contrib.websites'
|
name = 'orchestra.contrib.websites'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
if database_ready():
|
if database_ready():
|
||||||
from django.contrib.contenttypes.models import ContentType
|
# from django.contrib.contenttypes.models import ContentType
|
||||||
from .models import Content
|
# from .models import Content, Website
|
||||||
qset = Content.content_type.field.get_limit_choices_to()
|
# qset = Content.content_type.field.get_limit_choices_to()
|
||||||
for ct in ContentType.objects.filter(qset):
|
# for ct in ContentType.objects.filter(qset):
|
||||||
relation = GenericRelation('websites.Content')
|
# relation = GenericRelation('websites.Content')
|
||||||
ct.model_class().add_to_class('content_set', relation)
|
# ct.model_class().add_to_class('content_set', relation)
|
||||||
|
from .models import Website
|
||||||
|
services.register(Website, icon='Applications-internet.png')
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.db import models
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from orchestra.core import validators, services
|
from orchestra.core import validators
|
||||||
from orchestra.utils.functional import cached
|
from orchestra.utils.functional import cached
|
||||||
|
|
||||||
from . import settings
|
from . import settings
|
||||||
|
@ -152,6 +152,3 @@ class Content(models.Model):
|
||||||
domain = self.website.domains.first()
|
domain = self.website.domains.first()
|
||||||
if domain:
|
if domain:
|
||||||
return '%s://%s%s' % (self.website.get_protocol(), domain, self.path)
|
return '%s://%s%s' % (self.website.get_protocol(), domain, self.path)
|
||||||
|
|
||||||
|
|
||||||
services.register(Website)
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
from django.utils.translation import string_concat
|
||||||
|
|
||||||
from ..utils.python import AttrDict
|
from ..utils.python import AttrDict
|
||||||
|
|
||||||
|
|
||||||
class Register(object):
|
class Register(object):
|
||||||
def __init__(self):
|
def __init__(self, verbose_name=None):
|
||||||
self._registry = {}
|
self._registry = {}
|
||||||
|
self.verbose_name = verbose_name
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
return key in self._registry
|
return key in self._registry
|
||||||
|
@ -13,13 +16,21 @@ class Register(object):
|
||||||
|
|
||||||
def register(self, model, **kwargs):
|
def register(self, model, **kwargs):
|
||||||
if model in self._registry:
|
if model in self._registry:
|
||||||
raise KeyError("%s already registered" % str(model))
|
raise KeyError("%s already registered" % model)
|
||||||
plural = kwargs.get('verbose_name_plural', model._meta.verbose_name_plural)
|
if 'verbose_name' not in kwargs:
|
||||||
self._registry[model] = AttrDict(**{
|
kwargs['verbose_name'] = model._meta.verbose_name
|
||||||
'verbose_name': kwargs.get('verbose_name', model._meta.verbose_name),
|
if 'verbose_name_plural' not in kwargs:
|
||||||
'verbose_name_plural': plural,
|
kwargs['verbose_name_plural'] = model._meta.verbose_name_plural
|
||||||
'menu': kwargs.get('menu', True),
|
self._registry[model] = AttrDict(**kwargs)
|
||||||
})
|
|
||||||
|
def register_view(self, view_name, **kwargs):
|
||||||
|
if view_name in self._registry:
|
||||||
|
raise KeyError("%s already registered" % view_name)
|
||||||
|
if 'verbose_name' not in kwargs:
|
||||||
|
raise KeyError("%s verbose_name is required for views" % view_name)
|
||||||
|
if 'verbose_name_plural' not in kwargs:
|
||||||
|
kwargs['verbose_name_plural'] = string_concat(kwargs['verbose_name'], 's')
|
||||||
|
self._registry[view_name] = AttrDict(**kwargs)
|
||||||
|
|
||||||
def get(self, *args):
|
def get(self, *args):
|
||||||
if args:
|
if args:
|
||||||
|
@ -27,7 +38,7 @@ class Register(object):
|
||||||
return self._registry
|
return self._registry
|
||||||
|
|
||||||
|
|
||||||
services = Register()
|
services = Register(verbose_name='Services')
|
||||||
# TODO rename to something else
|
# TODO rename to something else
|
||||||
accounts = Register()
|
accounts = Register(verbose_name='Accounts')
|
||||||
administration = Register()
|
administration = Register(verbose_name='Administration')
|
||||||
|
|
After Width: | Height: | Size: 4.1 KiB |
|
@ -0,0 +1,413 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<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:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
inkscape:export-ydpi="90.000000"
|
||||||
|
inkscape:export-xdpi="90.000000"
|
||||||
|
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Appointment.png"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg11300"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="Appointment.svg"
|
||||||
|
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||||
|
version="1.1">
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient5204">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#c4a000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5206" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#c4a000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop5208" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient5196">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#c4a000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5198" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#c4a000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop5200" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient12512">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop12513" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#fff520;stop-opacity:0.89108908;"
|
||||||
|
offset="0.50000000"
|
||||||
|
id="stop12517" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#fff300;stop-opacity:0.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop12514" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient12512"
|
||||||
|
id="radialGradient278"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
cx="55.000000"
|
||||||
|
cy="125.00000"
|
||||||
|
fx="55.000000"
|
||||||
|
fy="125.00000"
|
||||||
|
r="14.375000" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient10653">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#f3f4ff;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop10655" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#9193af;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop10657" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient42174">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#a0a0a0;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop42176" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop42178" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2145">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#fffffd;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop2147" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#cbcbc9;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop2149" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient37935">
|
||||||
|
<stop
|
||||||
|
id="stop37937"
|
||||||
|
offset="0.0000000"
|
||||||
|
style="stop-color:#9497b3;stop-opacity:1.0000000;" />
|
||||||
|
<stop
|
||||||
|
id="stop37939"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#4c4059;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2152">
|
||||||
|
<stop
|
||||||
|
id="stop2154"
|
||||||
|
offset="0.0000000"
|
||||||
|
style="stop-color:#9aa29a;stop-opacity:1.0000000;" />
|
||||||
|
<stop
|
||||||
|
id="stop2156"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3816">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3818" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3820" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3816"
|
||||||
|
id="radialGradient3822"
|
||||||
|
cx="31.112698"
|
||||||
|
cy="19.008621"
|
||||||
|
fx="31.112698"
|
||||||
|
fy="19.008621"
|
||||||
|
r="8.6620579"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2152"
|
||||||
|
id="linearGradient4307"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(3.123841,0.000000,0.000000,0.969691,-31.88758,-19.59492)"
|
||||||
|
x1="8.9156475"
|
||||||
|
y1="37.197018"
|
||||||
|
x2="9.8855033"
|
||||||
|
y2="52.090678" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient10653"
|
||||||
|
id="radialGradient4309"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
cx="11.329200"
|
||||||
|
cy="10.583970"
|
||||||
|
fx="11.329200"
|
||||||
|
fy="10.583970"
|
||||||
|
r="15.532059" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2145"
|
||||||
|
id="radialGradient4311"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
cx="11.901996"
|
||||||
|
cy="10.045444"
|
||||||
|
fx="11.901996"
|
||||||
|
fy="10.045444"
|
||||||
|
r="29.292715" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient42174"
|
||||||
|
id="linearGradient4313"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="6.3422160"
|
||||||
|
y1="7.7893324"
|
||||||
|
x2="22.218424"
|
||||||
|
y2="25.884274" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5196"
|
||||||
|
id="radialGradient5202"
|
||||||
|
cx="23.375"
|
||||||
|
cy="10.972863"
|
||||||
|
fx="23.375"
|
||||||
|
fy="10.972863"
|
||||||
|
r="3.3478092"
|
||||||
|
gradientTransform="matrix(3.630420,1.654030e-15,-1.608743e-15,3.742066,-61.48607,-29.18618)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5204"
|
||||||
|
id="linearGradient5210"
|
||||||
|
x1="19.667364"
|
||||||
|
y1="4.2570662"
|
||||||
|
x2="20.329933"
|
||||||
|
y2="5.2845874"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient37935"
|
||||||
|
id="radialGradient5212"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
cx="8.7468252"
|
||||||
|
cy="6.8283234"
|
||||||
|
fx="8.7468252"
|
||||||
|
fy="6.8283234"
|
||||||
|
r="29.889715" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
stroke="#c4a000"
|
||||||
|
fill="#babdb6"
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="0.25490196"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="11.313708"
|
||||||
|
inkscape:cx="27.543713"
|
||||||
|
inkscape:cy="25.106052"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:window-width="833"
|
||||||
|
inkscape:window-height="772"
|
||||||
|
inkscape:window-x="1266"
|
||||||
|
inkscape:window-y="144"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata4">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Steiner</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:source>http://jimmac.musichall.cz</dc:source>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
|
||||||
|
<dc:title>New Appointment</dc:title>
|
||||||
|
<dc:subject>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>appointment</rdf:li>
|
||||||
|
<rdf:li>new</rdf:li>
|
||||||
|
<rdf:li>meeting</rdf:li>
|
||||||
|
<rdf:li>rvsp</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:subject>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Attribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
d="M 39.774755 19.008621 A 8.6620579 8.6620579 0 1 1 22.45064,19.008621 A 8.6620579 8.6620579 0 1 1 39.774755 19.008621 z"
|
||||||
|
sodipodi:ry="8.6620579"
|
||||||
|
sodipodi:rx="8.6620579"
|
||||||
|
sodipodi:cy="19.008621"
|
||||||
|
sodipodi:cx="31.112698"
|
||||||
|
id="path4318"
|
||||||
|
style="opacity:1;color:#000000;fill:url(#radialGradient3822);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
sodipodi:type="arc"
|
||||||
|
transform="matrix(2.563158,0.000000,0.000000,1.219602,-55.98414,14.04144)" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
id="path14341"
|
||||||
|
d="M 18.587591,1.403729 L 4.226755,18.096665 L 5.4854717,19.339844 L 18.587591,1.403729 z "
|
||||||
|
style="color:#000000;fill:url(#linearGradient4307);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccc"
|
||||||
|
id="path18921"
|
||||||
|
d="M 18.467176,1.3138035 L 5.6605716,19.072612 L 7.4900985,20.687913 L 18.467176,1.3138035 z "
|
||||||
|
style="fill:#fefefe;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" />
|
||||||
|
<path
|
||||||
|
transform="matrix(1.431529,0.000000,0.000000,1.431529,0.569459,-1.654618)"
|
||||||
|
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
|
||||||
|
sodipodi:ry="14.910714"
|
||||||
|
sodipodi:rx="14.910714"
|
||||||
|
sodipodi:cy="16.910715"
|
||||||
|
sodipodi:cx="16.25"
|
||||||
|
id="path27786"
|
||||||
|
style="fill:url(#radialGradient5212);fill-opacity:1;fill-rule:evenodd;stroke:#605773;stroke-width:0.69855404;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(1.163838,0.000000,0.000000,1.163838,4.824801,2.777556)"
|
||||||
|
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
|
||||||
|
sodipodi:ry="14.910714"
|
||||||
|
sodipodi:rx="14.910714"
|
||||||
|
sodipodi:cy="16.910715"
|
||||||
|
sodipodi:cx="16.25"
|
||||||
|
id="path35549"
|
||||||
|
style="fill:url(#radialGradient4311);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4313);stroke-width:0.71139598;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:1;color:#000000;fill:url(#radialGradient5202);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient5210);stroke-width:0.56498736;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
id="path4120"
|
||||||
|
sodipodi:cx="23.375"
|
||||||
|
sodipodi:cy="11.875"
|
||||||
|
sodipodi:rx="8.5"
|
||||||
|
sodipodi:ry="8.5"
|
||||||
|
d="M 16.679382,6.6387137 A 8.5,8.5 0 0 1 23.332691,3.3751053 L 23.375,11.875 z"
|
||||||
|
transform="matrix(1.769951,0.000000,0.000000,1.769951,-17.02424,1.610741)"
|
||||||
|
sodipodi:start="3.8052902"
|
||||||
|
sodipodi:end="4.7074114" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.073295,0.000000,0.000000,2.073295,-7.310224,-13.13682)"
|
||||||
|
d="M 16.40625 17.28125 A 1.21875 1.21875 0 1 1 13.96875,17.28125 A 1.21875 1.21875 0 1 1 16.40625 17.28125 z"
|
||||||
|
sodipodi:ry="1.21875"
|
||||||
|
sodipodi:rx="1.21875"
|
||||||
|
sodipodi:cy="17.28125"
|
||||||
|
sodipodi:cx="15.1875"
|
||||||
|
id="path34778"
|
||||||
|
style="fill:#f3f3f3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.48232403;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
id="path35559"
|
||||||
|
d="M 22.176614,20.718014 L 13.155702,13.140282"
|
||||||
|
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
|
||||||
|
<path
|
||||||
|
id="path35561"
|
||||||
|
d="M 19.408614,29.776506 L 22.368655,25.283228"
|
||||||
|
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
sodipodi:nodetypes="cc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,-12.40939)"
|
||||||
|
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
|
||||||
|
sodipodi:ry="0.61871845"
|
||||||
|
sodipodi:rx="0.61871845"
|
||||||
|
sodipodi:cy="7.6932044"
|
||||||
|
sodipodi:cx="16.705399"
|
||||||
|
id="path35563"
|
||||||
|
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.749493,0.000000,0.000000,2.749493,-22.30073,14.80922)"
|
||||||
|
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
|
||||||
|
sodipodi:ry="0.61871845"
|
||||||
|
sodipodi:rx="0.61871845"
|
||||||
|
sodipodi:cy="7.6932044"
|
||||||
|
sodipodi:cx="16.705399"
|
||||||
|
id="path35565"
|
||||||
|
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.749493,0.000000,0.000000,2.749493,-35.91004,1.199890)"
|
||||||
|
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
|
||||||
|
sodipodi:ry="0.61871845"
|
||||||
|
sodipodi:rx="0.61871845"
|
||||||
|
sodipodi:cy="7.6932044"
|
||||||
|
sodipodi:cx="16.705399"
|
||||||
|
id="path35567"
|
||||||
|
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
transform="matrix(2.749493,0.000000,0.000000,2.749493,-8.691448,1.199890)"
|
||||||
|
d="M 17.324117 7.6932044 A 0.61871845 0.61871845 0 1 1 16.08668,7.6932044 A 0.61871845 0.61871845 0 1 1 17.324117 7.6932044 z"
|
||||||
|
sodipodi:ry="0.61871845"
|
||||||
|
sodipodi:rx="0.61871845"
|
||||||
|
sodipodi:cy="7.6932044"
|
||||||
|
sodipodi:cx="16.705399"
|
||||||
|
id="path35569"
|
||||||
|
style="fill:#b6b9b1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.36871839;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;opacity:1"
|
||||||
|
sodipodi:type="arc" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#radialGradient4309);stroke-width:0.73656511;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
|
||||||
|
id="path10651"
|
||||||
|
sodipodi:cx="16.25"
|
||||||
|
sodipodi:cy="16.910715"
|
||||||
|
sodipodi:rx="14.910714"
|
||||||
|
sodipodi:ry="14.910714"
|
||||||
|
d="M 31.160714 16.910715 A 14.910714 14.910714 0 1 1 1.3392859,16.910715 A 14.910714 14.910714 0 1 1 31.160714 16.910715 z"
|
||||||
|
transform="matrix(1.357654,0.000000,0.000000,1.357654,1.769896,-0.493735)" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,390 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<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:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
height="48px"
|
||||||
|
width="48px"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="Edit-check-sheet.svg"
|
||||||
|
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Edit-check-sheet.png"
|
||||||
|
inkscape:export-xdpi="503.74228"
|
||||||
|
inkscape:export-ydpi="503.74228">
|
||||||
|
<metadata
|
||||||
|
id="metadata112">
|
||||||
|
<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:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="640"
|
||||||
|
inkscape:window-height="480"
|
||||||
|
id="namedview110"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="4.9166667"
|
||||||
|
inkscape:cx="24"
|
||||||
|
inkscape:cy="24"
|
||||||
|
inkscape:window-x="945"
|
||||||
|
inkscape:window-y="165"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<defs
|
||||||
|
id="defs4">
|
||||||
|
<linearGradient
|
||||||
|
id="i"
|
||||||
|
y2="-.2"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="12.17"
|
||||||
|
x2="25.69"
|
||||||
|
x1="25.68">
|
||||||
|
<stop
|
||||||
|
stop-color="#fff"
|
||||||
|
offset="0"
|
||||||
|
id="stop7" />
|
||||||
|
<stop
|
||||||
|
stop-opacity="0"
|
||||||
|
stop-color="#fff"
|
||||||
|
offset="1"
|
||||||
|
id="stop9" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="e"
|
||||||
|
x1="25.4"
|
||||||
|
xlink:href="#b"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="3.82"
|
||||||
|
gradientTransform="matrix(1 0 0 .884-.63.84)"
|
||||||
|
x2="25.46"
|
||||||
|
y2="9.32" />
|
||||||
|
<linearGradient
|
||||||
|
id="h"
|
||||||
|
x1="33.4"
|
||||||
|
xlink:href="#i"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x2="34.2"
|
||||||
|
y1="36.92"
|
||||||
|
y2="38.1" />
|
||||||
|
<linearGradient
|
||||||
|
id="f"
|
||||||
|
xlink:href="#b"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="3.82"
|
||||||
|
gradientTransform="matrix(.539 0 0 .512 10.8-.58)"
|
||||||
|
x2="0"
|
||||||
|
y2="6.48" />
|
||||||
|
<linearGradient
|
||||||
|
id="g"
|
||||||
|
x1="26.1"
|
||||||
|
xlink:href="#i"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x2="30.81"
|
||||||
|
y1="26.7"
|
||||||
|
y2="42" />
|
||||||
|
<linearGradient
|
||||||
|
id="j"
|
||||||
|
y2="37.77"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="40.46"
|
||||||
|
x2="33.66"
|
||||||
|
x1="36">
|
||||||
|
<stop
|
||||||
|
stop-color="#7c7c7c"
|
||||||
|
offset="0"
|
||||||
|
id="stop16" />
|
||||||
|
<stop
|
||||||
|
stop-color="#b8b8b8"
|
||||||
|
offset="1"
|
||||||
|
id="stop18" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="b">
|
||||||
|
<stop
|
||||||
|
stop-color="#97978a"
|
||||||
|
offset="0"
|
||||||
|
id="stop21" />
|
||||||
|
<stop
|
||||||
|
stop-color="#c2c2b9"
|
||||||
|
offset=".5"
|
||||||
|
id="stop23" />
|
||||||
|
<stop
|
||||||
|
stop-color="#7d7d6f"
|
||||||
|
offset="1"
|
||||||
|
id="stop25" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="n"
|
||||||
|
y2="37.88"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="10.45"
|
||||||
|
x2="33.86"
|
||||||
|
x1="6.11">
|
||||||
|
<stop
|
||||||
|
stop-color="#c68827"
|
||||||
|
offset="0"
|
||||||
|
id="stop28" />
|
||||||
|
<stop
|
||||||
|
stop-color="#89601f"
|
||||||
|
offset="1"
|
||||||
|
id="stop30" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="k"
|
||||||
|
y2="42.1"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="39.2"
|
||||||
|
x2="39.1"
|
||||||
|
x1="36.81">
|
||||||
|
<stop
|
||||||
|
offset="0"
|
||||||
|
id="stop33" />
|
||||||
|
<stop
|
||||||
|
stop-opacity="0"
|
||||||
|
offset="1"
|
||||||
|
id="stop35" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="m"
|
||||||
|
y2="39.5"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="18.99"
|
||||||
|
gradientTransform="matrix(1.066 0 0 .988-1.56.07)"
|
||||||
|
x2="35.79"
|
||||||
|
x1="22.31">
|
||||||
|
<stop
|
||||||
|
stop-color="#f0f0ef"
|
||||||
|
offset="0"
|
||||||
|
id="stop38" />
|
||||||
|
<stop
|
||||||
|
stop-color="#e8e8e8"
|
||||||
|
offset=".6"
|
||||||
|
id="stop40" />
|
||||||
|
<stop
|
||||||
|
stop-color="#fff"
|
||||||
|
offset=".83"
|
||||||
|
id="stop42" />
|
||||||
|
<stop
|
||||||
|
stop-color="#d8d8d3"
|
||||||
|
offset="1"
|
||||||
|
id="stop44" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="l"
|
||||||
|
x1="25.4"
|
||||||
|
xlink:href="#b"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y1="3.82"
|
||||||
|
gradientTransform="matrix(1.053 0 0 1-1.79 0)"
|
||||||
|
x2="25.46"
|
||||||
|
y2="9.32" />
|
||||||
|
<radialGradient
|
||||||
|
id="d"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
cy="45.3"
|
||||||
|
cx="24.65"
|
||||||
|
gradientTransform="matrix(1 0 0 .111 0 40.3)"
|
||||||
|
r="21">
|
||||||
|
<stop
|
||||||
|
stop-color="#646459"
|
||||||
|
offset="0"
|
||||||
|
id="stop48" />
|
||||||
|
<stop
|
||||||
|
stop-opacity="0"
|
||||||
|
stop-color="#646459"
|
||||||
|
offset="1"
|
||||||
|
id="stop50" />
|
||||||
|
</radialGradient>
|
||||||
|
</defs>
|
||||||
|
<path
|
||||||
|
fill="url(#d)"
|
||||||
|
d="m45.66 45.27a21.01 2.323 0 1 1 -42.02 0 21.01 2.323 0 1 1 42.02 0"
|
||||||
|
transform="matrix(.913 0 0 1.179 1.92-8.11)"
|
||||||
|
id="path52" />
|
||||||
|
<rect
|
||||||
|
rx="1.39"
|
||||||
|
height="41"
|
||||||
|
width="39"
|
||||||
|
stroke="#714c16"
|
||||||
|
y="4.5"
|
||||||
|
x="4.46"
|
||||||
|
fill="url(#n)"
|
||||||
|
id="rect54" />
|
||||||
|
<rect
|
||||||
|
rx=".57"
|
||||||
|
height="35.98"
|
||||||
|
width="30.95"
|
||||||
|
stroke="#888a85"
|
||||||
|
y="6.53"
|
||||||
|
x="8.53"
|
||||||
|
fill="url(#m)"
|
||||||
|
id="rect56" />
|
||||||
|
<rect
|
||||||
|
rx="1"
|
||||||
|
height="4"
|
||||||
|
width="12"
|
||||||
|
x="18"
|
||||||
|
fill="#5c5c5c"
|
||||||
|
id="rect58" />
|
||||||
|
<rect
|
||||||
|
id="a"
|
||||||
|
opacity=".4"
|
||||||
|
rx="1"
|
||||||
|
height="3.7"
|
||||||
|
width="3.7"
|
||||||
|
stroke="#2e3436"
|
||||||
|
y="14.4"
|
||||||
|
x="11.7"
|
||||||
|
stroke-width=".8"
|
||||||
|
fill="none" />
|
||||||
|
<use
|
||||||
|
y="6.48"
|
||||||
|
xlink:href="#a"
|
||||||
|
id="use61" />
|
||||||
|
<rect
|
||||||
|
opacity=".5"
|
||||||
|
rx="1"
|
||||||
|
height="5"
|
||||||
|
width="5"
|
||||||
|
stroke="#2e3436"
|
||||||
|
y="34.37"
|
||||||
|
x="11.64"
|
||||||
|
stroke-width=".8"
|
||||||
|
fill="none"
|
||||||
|
id="rect63" />
|
||||||
|
<use
|
||||||
|
y="12.96"
|
||||||
|
xlink:href="#a"
|
||||||
|
id="use65" />
|
||||||
|
<g
|
||||||
|
fill="none"
|
||||||
|
id="g67">
|
||||||
|
<path
|
||||||
|
stroke="url(#g)"
|
||||||
|
d="m9.52 7.47h29v34h-29z"
|
||||||
|
id="path69" />
|
||||||
|
<rect
|
||||||
|
rx=".5"
|
||||||
|
height="39.1"
|
||||||
|
width="37.1"
|
||||||
|
stroke="#c68827"
|
||||||
|
y="5.43"
|
||||||
|
x="5.44"
|
||||||
|
id="rect71" />
|
||||||
|
</g>
|
||||||
|
<rect
|
||||||
|
opacity=".11"
|
||||||
|
rx="1.39"
|
||||||
|
height="7"
|
||||||
|
width="18.95"
|
||||||
|
stroke="#000"
|
||||||
|
y="4.47"
|
||||||
|
x="14.79"
|
||||||
|
id="rect73" />
|
||||||
|
<rect
|
||||||
|
rx="1.39"
|
||||||
|
height="7"
|
||||||
|
width="18.95"
|
||||||
|
stroke="#5c5c5c"
|
||||||
|
y="3.5"
|
||||||
|
x="14.53"
|
||||||
|
fill="url(#l)"
|
||||||
|
id="rect75" />
|
||||||
|
<rect
|
||||||
|
rx=".33"
|
||||||
|
height="3.58"
|
||||||
|
width="9.7"
|
||||||
|
y="1.21"
|
||||||
|
x="19.1"
|
||||||
|
fill="url(#f)"
|
||||||
|
id="rect77" />
|
||||||
|
<rect
|
||||||
|
rx="1"
|
||||||
|
height="6.19"
|
||||||
|
width="18.1"
|
||||||
|
y="3.94"
|
||||||
|
x="14.95"
|
||||||
|
fill="url(#e)"
|
||||||
|
id="rect79" />
|
||||||
|
<path
|
||||||
|
opacity=".5"
|
||||||
|
d="m39 36.3l0.04 5.81-8.5-0.04 8.46-5.77"
|
||||||
|
fill="url(#k)"
|
||||||
|
id="path81" />
|
||||||
|
<path
|
||||||
|
stroke="#868a84"
|
||||||
|
d="m30.1 42.1c1.79 0.16 8.99-4.37 9.48-8.39-1.56 2.42-4.96 1.97-9.1 2.13 0 0 0.39 5.76-0.42 6.26z"
|
||||||
|
fill="url(#j)"
|
||||||
|
id="path83" />
|
||||||
|
<g
|
||||||
|
fill="none"
|
||||||
|
id="g85">
|
||||||
|
<path
|
||||||
|
opacity=".32"
|
||||||
|
stroke="url(#i)"
|
||||||
|
d="m19.47 1.47v0.03h-0.03v2.88c0 0.001 0.03 0.03 0.03 0.03v0.03h-3.59c-0.04 0-0.1 0.02-0.13 0.03-0.14 0.06-0.27 0.2-0.31 0.34-0.001 0.04 0 0.11 0 0.16v4.22c0 0.03 0.02 0.09 0.03 0.12 0.001 0.02 0.02 0.07 0.03 0.09 0 0.001 0.03 0.03 0.03 0.03 0.02 0.03 0.07 0.07 0.09 0.09 0.02 0.001 0.05 0.02 0.07 0.03 0.001 0.001 0.04 0.03 0.06 0.03 0.03 0.001 0.09 0.03 0.13 0.03h16.22c0.04-0.001 0.1-0.02 0.13-0.03 0.02-0.001 0.05-0.02 0.06-0.03 0.02-0.001 0.05-0.02 0.07-0.03l0.09-0.09c0-0.001 0.03-0.03 0.03-0.03 0.001-0.02 0.02-0.07 0.03-0.09 0.001-0.03 0.03-0.09 0.03-0.12v-4.22c0-0.04 0.001-0.12 0-0.16-0.04-0.14-0.17-0.29-0.31-0.34-0.03-0.001-0.09-0.03-0.13-0.03h-3.59v-0.03l0.03-0.03v-2.88h-0.03v-0.03h-9.03s-0.03 0-0.03 0z"
|
||||||
|
id="path87" />
|
||||||
|
<path
|
||||||
|
opacity=".37"
|
||||||
|
stroke="url(#h)"
|
||||||
|
d="m31.51 40.69c1.37-0.69 4.53-2.6 5.83-4.48-1.79 0.37-2.99 0.58-5.73 0.69 0 0 0.09 3-0.1 3.79z"
|
||||||
|
id="path89" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
opacity=".17"
|
||||||
|
id="g91">
|
||||||
|
<path
|
||||||
|
d="m19.76 15h16.34v2h-16.34z"
|
||||||
|
id="path93" />
|
||||||
|
<path
|
||||||
|
d="m19.76 19h15.56v2h-15.56z"
|
||||||
|
id="path95" />
|
||||||
|
<path
|
||||||
|
d="m19.76 23h14v2h-14z"
|
||||||
|
id="path97" />
|
||||||
|
<path
|
||||||
|
d="m19.76 27h16.34v2h-16.34z"
|
||||||
|
id="path99" />
|
||||||
|
<path
|
||||||
|
d="m19.76 31h10.12v2h-10.12z"
|
||||||
|
id="path101" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
id="c"
|
||||||
|
d="m18.57 28.81c3.909-6.26 4.744-6.495 9.012-11.93 1.32-1.47 5.119-5.149 6.888-4.447 1.351 0.537-0.8798 2.34-1.53 3.17-5.72 7.3-9.097 12.28-14.4 19.89-0.817 1.172-2.128 1.514-3.407 1.241-1.3-0.28-2.07-2.68-2.5-3.82-0.6404-1.7-2.255-3.821-2.254-5.641 0.0004468-1.47 0.7726-2.205 2.074-2.305 1.675-0.1285 2.298 2.19 2.789 3.557 0.93 2.58 1.13 3.81 3.33 0.29z"
|
||||||
|
transform="matrix(.292 0 0 .293 8.7 7.4)"
|
||||||
|
fill="#4e9a06" />
|
||||||
|
<use
|
||||||
|
y="6.46"
|
||||||
|
xlink:href="#c"
|
||||||
|
id="use104" />
|
||||||
|
<use
|
||||||
|
y="12.92"
|
||||||
|
xlink:href="#c"
|
||||||
|
id="use106" />
|
||||||
|
<use
|
||||||
|
xlink:href="#c"
|
||||||
|
transform="matrix(2.076 0 0 2.076 -13.72 1.792)"
|
||||||
|
stroke="#555753"
|
||||||
|
stroke-width=".3"
|
||||||
|
id="use108" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,999 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<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:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
sodipodi:docname="Mail-send.svg"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
id="svg5816"
|
||||||
|
height="48px"
|
||||||
|
width="48px"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:export-filename="/home/glic3rinu/orchestra/django-orchestra/orchestra/static/orchestra/icons/Mail-send.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<defs
|
||||||
|
id="defs3">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient5476">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5478" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop5480" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient5464">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#729fcf;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop5466" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#afc9e4;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop5468" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2624">
|
||||||
|
<stop
|
||||||
|
id="stop2626"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#dfe0df;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#a6b0a6;stop-opacity:1;"
|
||||||
|
offset="0.23809524"
|
||||||
|
id="stop2630" />
|
||||||
|
<stop
|
||||||
|
id="stop2628"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#b5beb5;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2573">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2575" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2577" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient2274">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.12871288;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop2276" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop2278" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient9749">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop9751" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ededed;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop9753" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient15107">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop15109" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e2e2e2;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop15111" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient10691"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop10693"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop10695"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4274">
|
||||||
|
<stop
|
||||||
|
id="stop4276"
|
||||||
|
offset="0.0000000"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0.25490198;" />
|
||||||
|
<stop
|
||||||
|
id="stop4278"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2187">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2189" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2191" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient6901"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop6903"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#3465a4;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop6905"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#3465a4;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient6925"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop6927"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#204a87;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop6929"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#204a87;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient6901"
|
||||||
|
id="linearGradient2562"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
|
||||||
|
x1="15.193591"
|
||||||
|
y1="15.028743"
|
||||||
|
x2="12.252101"
|
||||||
|
y2="30.55784" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient6925"
|
||||||
|
id="linearGradient2564"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
|
||||||
|
x1="10.791593"
|
||||||
|
y1="23.332331"
|
||||||
|
x2="10.112462"
|
||||||
|
y2="27.145725" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2187"
|
||||||
|
id="linearGradient2566"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-1.412791e-16,0.914114,-0.914114,-1.412791e-16,39.78243,-9.748047)"
|
||||||
|
x1="41.093174"
|
||||||
|
y1="16.612858"
|
||||||
|
x2="16.588747"
|
||||||
|
y2="29.698416" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4274"
|
||||||
|
id="linearGradient2365"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0,1,-1,0,37.07553,-5.879343)"
|
||||||
|
x1="26.577936"
|
||||||
|
y1="7.7850504"
|
||||||
|
x2="38.129341"
|
||||||
|
y2="12.765438" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient10691"
|
||||||
|
id="radialGradient1481"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="scale(1.902215,0.525703)"
|
||||||
|
cx="6.7027131"
|
||||||
|
cy="73.615714"
|
||||||
|
fx="6.7027131"
|
||||||
|
fy="73.615714"
|
||||||
|
r="7.2284161" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient1483"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.357669,0,0,1.505846,2.84291,-2.266018)"
|
||||||
|
x1="11.572842"
|
||||||
|
y1="4.7461626"
|
||||||
|
x2="18.475286"
|
||||||
|
y2="26.022910" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2624"
|
||||||
|
id="linearGradient1487"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(2.454781,0,0,0.762004,2.88175,0.337386)"
|
||||||
|
x1="9.1643066"
|
||||||
|
y1="38.070892"
|
||||||
|
x2="9.8855038"
|
||||||
|
y2="52.090679" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2274"
|
||||||
|
id="radialGradient1491"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.629929,0.459373,-0.147675,0.248512,16.51724,9.053737)"
|
||||||
|
cx="27.741131"
|
||||||
|
cy="38.711506"
|
||||||
|
fx="27.741131"
|
||||||
|
fy="38.711506"
|
||||||
|
r="17.977943" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient1493"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.276531,0,0,-1.406115,24.24763,33.3374)"
|
||||||
|
x1="11.74217"
|
||||||
|
y1="11.48487"
|
||||||
|
x2="13.846983"
|
||||||
|
y2="11.981981" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient1497"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.296015,0,0,-1.43692,3.746576,33.20516)"
|
||||||
|
x1="11.74217"
|
||||||
|
y1="11.48487"
|
||||||
|
x2="13.846983"
|
||||||
|
y2="11.981981" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient1501"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.570607,0,0,-1.231511,2.973436,33.33485)"
|
||||||
|
x1="10.027"
|
||||||
|
y1="20.219761"
|
||||||
|
x2="17.178024"
|
||||||
|
y2="-7.5274644" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient9749"
|
||||||
|
id="linearGradient1503"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.370928,0,0,-1.46456,2.525057,33.71269)"
|
||||||
|
x1="11.841544"
|
||||||
|
y1="4.2507305"
|
||||||
|
x2="40.024059"
|
||||||
|
y2="7.4121075" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2573"
|
||||||
|
id="linearGradient1505"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="17.397203"
|
||||||
|
y1="33.357376"
|
||||||
|
x2="22.17771"
|
||||||
|
y2="31.026741" />
|
||||||
|
<radialGradient
|
||||||
|
r="13.565360"
|
||||||
|
fy="19.836468"
|
||||||
|
fx="16.214741"
|
||||||
|
cy="19.836468"
|
||||||
|
cx="16.214741"
|
||||||
|
gradientTransform="matrix(1,0,0,0.681917,-1.105561e-15,8.233773)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient1381"
|
||||||
|
xlink:href="#linearGradient4344"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="35.803486"
|
||||||
|
x2="30.935921"
|
||||||
|
y1="29.553486"
|
||||||
|
x1="30.935921"
|
||||||
|
gradientTransform="translate(-12.41789,-7)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1372"
|
||||||
|
xlink:href="#linearGradient3824"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="36.217758"
|
||||||
|
x2="22.626925"
|
||||||
|
y1="35.817974"
|
||||||
|
x1="20.661695"
|
||||||
|
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,-7.07212,-9.82492)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1369"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="35.739632"
|
||||||
|
x2="21.408455"
|
||||||
|
y1="36.390400"
|
||||||
|
x1="22.686766"
|
||||||
|
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,41.80576,-11.11866)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient1366"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="35.739632"
|
||||||
|
x2="21.408455"
|
||||||
|
y1="36.390400"
|
||||||
|
x1="22.686766"
|
||||||
|
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,41.80576,-11.11866)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4374"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="36.217758"
|
||||||
|
x2="22.626925"
|
||||||
|
y1="35.817974"
|
||||||
|
x1="20.661695"
|
||||||
|
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,-7.072120,-9.824920)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4372"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
gradientTransform="matrix(-0.977685,0.210075,0.210075,0.977685,55.1096,-3.945209)"
|
||||||
|
y2="35.739632"
|
||||||
|
x2="21.408455"
|
||||||
|
y1="36.390400"
|
||||||
|
x1="22.686766"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4366"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
gradientTransform="matrix(0.983375,0.181588,-0.181588,0.983375,6.231716,-2.651466)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y2="36.217758"
|
||||||
|
x2="22.626925"
|
||||||
|
y1="35.817974"
|
||||||
|
x1="20.661695"
|
||||||
|
id="linearGradient4362"
|
||||||
|
xlink:href="#linearGradient4356"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.000000,0.000000,0.000000,0.681917,0.000000,8.233773)"
|
||||||
|
r="13.565360"
|
||||||
|
fy="19.836468"
|
||||||
|
fx="16.214741"
|
||||||
|
cy="19.836468"
|
||||||
|
cx="16.214741"
|
||||||
|
id="radialGradient4350"
|
||||||
|
xlink:href="#linearGradient4344"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
r="8.6620579"
|
||||||
|
fy="19.008621"
|
||||||
|
fx="31.112698"
|
||||||
|
cy="19.008621"
|
||||||
|
cx="31.112698"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient4336"
|
||||||
|
xlink:href="#linearGradient3816"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
gradientTransform="translate(-13.12500,-7.000000)"
|
||||||
|
y2="35.803486"
|
||||||
|
x2="30.935921"
|
||||||
|
y1="29.553486"
|
||||||
|
x1="30.935921"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4332"
|
||||||
|
xlink:href="#linearGradient3824"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
r="8.6620579"
|
||||||
|
fy="19.008621"
|
||||||
|
fx="31.112698"
|
||||||
|
cy="19.008621"
|
||||||
|
cx="31.112698"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient4330"
|
||||||
|
xlink:href="#linearGradient3816"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
r="9.1620579"
|
||||||
|
fy="17.064077"
|
||||||
|
fx="29.344931"
|
||||||
|
cy="17.064077"
|
||||||
|
cx="29.344931"
|
||||||
|
gradientTransform="matrix(0.787998,3.877637e-16,-3.877637e-16,0.787998,6.221198,3.617627)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient4328"
|
||||||
|
xlink:href="#linearGradient4338"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
y2="35.803486"
|
||||||
|
x2="30.935921"
|
||||||
|
y1="29.553486"
|
||||||
|
x1="30.935921"
|
||||||
|
gradientTransform="translate(-12.41789,-7.000000)"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4326"
|
||||||
|
xlink:href="#linearGradient3824"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
r="8.6620579"
|
||||||
|
fy="19.008621"
|
||||||
|
fx="31.112698"
|
||||||
|
cy="19.008621"
|
||||||
|
cx="31.112698"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient4179"
|
||||||
|
xlink:href="#linearGradient3816"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
gradientTransform="translate(0.707108,0.000000)"
|
||||||
|
y2="35.803486"
|
||||||
|
x2="30.935921"
|
||||||
|
y1="29.553486"
|
||||||
|
x1="30.935921"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="linearGradient4175"
|
||||||
|
xlink:href="#linearGradient3824"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientTransform="matrix(0.787998,3.877637e-16,-3.877637e-16,0.787998,6.221198,3.617627)"
|
||||||
|
r="9.1620579"
|
||||||
|
fy="17.064077"
|
||||||
|
fx="29.344931"
|
||||||
|
cy="17.064077"
|
||||||
|
cx="29.344931"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
id="radialGradient4171"
|
||||||
|
xlink:href="#linearGradient3800"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.297564,2.881172e-16,-1.96472e-16,0.884831,-8.358505,4.940469)"
|
||||||
|
r="13.565360"
|
||||||
|
fy="27.203083"
|
||||||
|
fx="28.089741"
|
||||||
|
cy="27.203083"
|
||||||
|
cx="28.089741"
|
||||||
|
id="radialGradient4169"
|
||||||
|
xlink:href="#linearGradient4163"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
y2="35.803486"
|
||||||
|
x2="30.935921"
|
||||||
|
y1="29.553486"
|
||||||
|
x1="30.935921"
|
||||||
|
id="linearGradient3830"
|
||||||
|
xlink:href="#linearGradient3824"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
r="8.6620579"
|
||||||
|
fy="19.008621"
|
||||||
|
fx="31.112698"
|
||||||
|
cy="19.008621"
|
||||||
|
cx="31.112698"
|
||||||
|
id="radialGradient3822"
|
||||||
|
xlink:href="#linearGradient3816"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<radialGradient
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
r="9.1620579"
|
||||||
|
fy="17.064077"
|
||||||
|
fx="29.344931"
|
||||||
|
cy="17.064077"
|
||||||
|
cx="29.344931"
|
||||||
|
id="radialGradient3806"
|
||||||
|
xlink:href="#linearGradient3800"
|
||||||
|
inkscape:collect="always" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3800">
|
||||||
|
<stop
|
||||||
|
id="stop3802"
|
||||||
|
offset="0.0000000"
|
||||||
|
style="stop-color:#f4d9b1;stop-opacity:1.0000000;" />
|
||||||
|
<stop
|
||||||
|
id="stop3804"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#df9725;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3816"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop3818"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop3820"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3824">
|
||||||
|
<stop
|
||||||
|
id="stop3826"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop3828"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#c9c9c9;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4163">
|
||||||
|
<stop
|
||||||
|
id="stop4165"
|
||||||
|
offset="0.0000000"
|
||||||
|
style="stop-color:#3b74bc;stop-opacity:1.0000000;" />
|
||||||
|
<stop
|
||||||
|
id="stop4167"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#2d5990;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4338">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e9b15e;stop-opacity:1.0000000;"
|
||||||
|
offset="0.0000000"
|
||||||
|
id="stop4340" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#966416;stop-opacity:1.0000000;"
|
||||||
|
offset="1.0000000"
|
||||||
|
id="stop4342" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4344">
|
||||||
|
<stop
|
||||||
|
id="stop4346"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#727e0a;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4348"
|
||||||
|
offset="1.0000000"
|
||||||
|
style="stop-color:#5b6508;stop-opacity:1.0000000;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4356"
|
||||||
|
inkscape:collect="always">
|
||||||
|
<stop
|
||||||
|
id="stop4358"
|
||||||
|
offset="0"
|
||||||
|
style="stop-color:#000000;stop-opacity:1;" />
|
||||||
|
<stop
|
||||||
|
id="stop4360"
|
||||||
|
offset="1"
|
||||||
|
style="stop-color:#000000;stop-opacity:0;" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5464"
|
||||||
|
id="linearGradient5472"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="21.587093"
|
||||||
|
y1="23.499001"
|
||||||
|
x2="21.587093"
|
||||||
|
y2="2.8163671"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5476"
|
||||||
|
id="linearGradient5482"
|
||||||
|
x1="25.950134"
|
||||||
|
y1="2.8703361"
|
||||||
|
x2="29.477814"
|
||||||
|
y2="46.06208"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5476"
|
||||||
|
id="linearGradient5486"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="25.950134"
|
||||||
|
y1="2.8703361"
|
||||||
|
x2="29.477814"
|
||||||
|
y2="46.06208"
|
||||||
|
gradientTransform="matrix(-0.901805,0.210818,-0.211618,-0.898788,63.54132,37.87423)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient5506"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.357669,0,0,1.505846,2.84291,-2.266018)"
|
||||||
|
x1="11.572842"
|
||||||
|
y1="4.7461626"
|
||||||
|
x2="18.475286"
|
||||||
|
y2="26.022910" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2624"
|
||||||
|
id="linearGradient5508"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(2.454781,0,0,0.762004,2.88175,0.337386)"
|
||||||
|
x1="9.1643066"
|
||||||
|
y1="38.070892"
|
||||||
|
x2="9.8855038"
|
||||||
|
y2="52.090679" />
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2274"
|
||||||
|
id="radialGradient5510"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.629929,0.459373,-0.147675,0.248512,16.51724,9.053737)"
|
||||||
|
cx="27.741131"
|
||||||
|
cy="38.711506"
|
||||||
|
fx="27.741131"
|
||||||
|
fy="38.711506"
|
||||||
|
r="17.977943" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient5512"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.296015,0,0,-1.43692,3.746576,33.20516)"
|
||||||
|
x1="11.74217"
|
||||||
|
y1="11.48487"
|
||||||
|
x2="13.846983"
|
||||||
|
y2="11.981981" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient15107"
|
||||||
|
id="linearGradient5514"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.570607,0,0,-1.231511,2.973436,33.33485)"
|
||||||
|
x1="10.027"
|
||||||
|
y1="20.219761"
|
||||||
|
x2="17.178024"
|
||||||
|
y2="-7.5274644" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient9749"
|
||||||
|
id="linearGradient5516"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.370928,0,0,-1.46456,2.525057,33.71269)"
|
||||||
|
x1="11.841544"
|
||||||
|
y1="4.2507305"
|
||||||
|
x2="40.024059"
|
||||||
|
y2="7.4121075" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2573"
|
||||||
|
id="linearGradient5518"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="17.397203"
|
||||||
|
y1="33.357376"
|
||||||
|
x2="22.17771"
|
||||||
|
y2="31.026741" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5476"
|
||||||
|
id="linearGradient5528"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(-0.901805,0.210818,-0.211618,-0.898788,63.54132,37.87423)"
|
||||||
|
x1="25.950134"
|
||||||
|
y1="2.8703361"
|
||||||
|
x2="29.477814"
|
||||||
|
y2="46.06208" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5464"
|
||||||
|
id="linearGradient5530"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
|
||||||
|
x1="21.587093"
|
||||||
|
y1="23.499001"
|
||||||
|
x2="21.587093"
|
||||||
|
y2="2.8163671" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5476"
|
||||||
|
id="linearGradient5532"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
|
||||||
|
x1="25.950134"
|
||||||
|
y1="2.8703361"
|
||||||
|
x2="29.477814"
|
||||||
|
y2="46.06208" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5464"
|
||||||
|
id="linearGradient3297"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
|
||||||
|
x1="21.587093"
|
||||||
|
y1="23.499001"
|
||||||
|
x2="21.587093"
|
||||||
|
y2="2.8163671" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient5476"
|
||||||
|
id="linearGradient3299"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.106909,-0.258404,0.259748,1.101665,-19.66697,12.19788)"
|
||||||
|
x1="25.950134"
|
||||||
|
y1="2.8703361"
|
||||||
|
x2="29.477814"
|
||||||
|
y2="46.06208" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
inkscape:window-y="27"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-height="1024"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
inkscape:cy="-14.347029"
|
||||||
|
inkscape:cx="38.533427"
|
||||||
|
inkscape:zoom="1.4142136"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
borderopacity="0.16862745"
|
||||||
|
bordercolor="#666666"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
id="base"
|
||||||
|
inkscape:grid-points="true"
|
||||||
|
gridtolerance="2"
|
||||||
|
inkscape:object-bbox="false"
|
||||||
|
inkscape:object-points="false"
|
||||||
|
objecttolerance="2.8"
|
||||||
|
guidetolerance="2"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
inkscape:object-paths="false"
|
||||||
|
inkscape:has_abs_tolerance="false"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
id="GridFromPre046Settings"
|
||||||
|
type="xygrid"
|
||||||
|
originx="0px"
|
||||||
|
originy="0px"
|
||||||
|
spacingx="1px"
|
||||||
|
spacingy="1px"
|
||||||
|
color="#3f3fff"
|
||||||
|
empcolor="#3f3fff"
|
||||||
|
opacity="0.15"
|
||||||
|
empopacity="0.38"
|
||||||
|
empspacing="2" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata4">
|
||||||
|
<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>Send and Receive Mail</dc:title>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Steiner</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:contributor>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Andreas Nilsson, Garrett LeSage</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:contributor>
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
|
||||||
|
<dc:subject>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>mail</rdf:li>
|
||||||
|
<rdf:li>e-mail</rdf:li>
|
||||||
|
<rdf:li>send</rdf:li>
|
||||||
|
<rdf:li>receive</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:subject>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Attribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.3;color:#000000;fill:url(#radialGradient1481);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.80000001;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
id="path10699"
|
||||||
|
sodipodi:cx="12.75"
|
||||||
|
sodipodi:cy="38.700001"
|
||||||
|
sodipodi:rx="13.75"
|
||||||
|
sodipodi:ry="3.8"
|
||||||
|
d="m 26.5,38.700001 a 13.75,3.8 0 1 1 -27.5,0 13.75,3.8 0 1 1 27.5,0 z"
|
||||||
|
transform="matrix(1.66707,0,0,1.5930485,5.3581929,-22.843871)"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true" />
|
||||||
|
<g
|
||||||
|
id="g2570"
|
||||||
|
transform="matrix(0.7571799,0,0,0.75599508,14.45706,-1.0815005)"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true">
|
||||||
|
<path
|
||||||
|
id="path12723"
|
||||||
|
d="m 6.3437483,15.454879 0,25.987281 37.3593247,0 -0.06316,-25.887713 c -1.3e-5,-0.0057 3.78e-4,-0.02709 0,-0.03319 -7.39e-4,-0.0065 0.0011,-0.02633 0,-0.03319 -0.0015,-0.0072 -0.02977,-0.02558 -0.03158,-0.03319 l -37.2645847,0 z"
|
||||||
|
style="fill:url(#linearGradient1483);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.37973988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
id="path1634"
|
||||||
|
d="M 20.490674,29.058712 7.09471,40.0307 l 13.908842,-9.604306 9.018158,0 12.419047,9.482193 -11.863425,-10.849875 -10.086658,0 z"
|
||||||
|
style="fill:url(#linearGradient1487);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path15103"
|
||||||
|
d="m 7.5310575,16.733861 c -0.00667,0.01319 0.00537,0.01943 0,0.03125 -0.00236,0.0056 -0.029093,0.02604 -0.031121,0.03125 -0.0017,0.0049 0.00136,0.02674 0,0.03125 -0.00102,0.0041 6.829e-4,0.02747 0,0.03125 l 0.031121,23.217159 34.7933665,0 -0.06224,-23.092168 c -6.84e-4,-0.0037 0.001,-0.02721 0,-0.03125 -0.0146,-0.04755 -0.04166,-0.130713 -0.09336,-0.218735 l -34.6377615,0 z"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.37974012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path2563"
|
||||||
|
d="M 23.329298,32.996721 C 20.937189,32.550375 7.9003872,18.771125 6.5966059,16.372022 6.5816495,16.343448 6.5559705,16.288608 6.5446896,16.2636 l 34.5131134,0 c -0.277079,2.502804 -7.524227,16.505746 -9.561279,16.733121 -0.0082,4.68e-4 -0.02128,0 -0.02927,0 l -8.020859,0 c -0.03363,0 -0.07755,0.0074 -0.117094,0 z"
|
||||||
|
style="fill:url(#radialGradient1491);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path1613"
|
||||||
|
d="M 20.77475,31.085394 C 18.407309,30.694257 7.945269,18.619435 7.1185841,16.517089 7.109327,16.49205 7.094677,16.443993 7.088438,16.422079 l 35.542207,0 c -0.823616,2.19322 -11.29845,14.464065 -13.445143,14.663315 -0.0085,4.09e-4 -0.02191,0 -0.03015,0 l -8.260021,0 c -0.03463,0 -0.08145,0.0065 -0.120584,0 z"
|
||||||
|
style="fill:url(#linearGradient1497);fill-opacity:1;fill-rule:evenodd;stroke:#989898;stroke-width:1.18189096;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path18153"
|
||||||
|
d="M 20.625174,30.490479 C 18.519211,29.999928 7.7224803,17.987711 7.0314243,16.466377 c -0.00254,-0.006 0.00218,-0.02669 0,-0.03231 -0.00545,-0.01576 -0.029096,-0.0523 -0.03125,-0.06463 2.87e-5,-0.0033 -4.061e-4,-0.02938 0,-0.03231 0.00117,-0.0021 0.029695,0.0017 0.03125,0 l 0.09375,-0.09694 35.4687497,0 c -0.0027,0.02433 -0.02268,0.06687 -0.03125,0.09694 -0.0075,0.0236 -0.02057,0.07023 -0.03125,0.09694 -0.922098,2.180937 -11.507988,13.766449 -13.34375,14.056416 -0.01493,0.0016 -0.04885,0 -0.0625,0 l -8.375,0 c -0.03029,-0.0017 -0.08975,0.0082 -0.125,0 z"
|
||||||
|
style="fill:url(#linearGradient1501);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
id="path1616"
|
||||||
|
d="M 20.875174,30.051141 C 18.427215,29.501671 8.7040003,18.433898 7.5314243,16.451725 l 34.5937497,0 c -1.490188,2.333171 -11.046672,13.411791 -13.15625,13.599416 -0.0087,4.02e-4 -0.02278,0 -0.03125,0 l -7.90625,0 c -0.02639,0 -0.06488,0.0036 -0.09375,0 -0.01979,-0.0031 -0.04165,0.0047 -0.0625,0 z"
|
||||||
|
style="fill:none;stroke:url(#linearGradient1503);stroke-width:1.18189073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccc"
|
||||||
|
id="path1636"
|
||||||
|
d="m 20.959511,30.447113 -11.941499,8.270856 2.219433,0.0061 9.998125,-6.86894 8.821908,-1.422838 -9.097967,0.01482 z"
|
||||||
|
style="fill:url(#linearGradient1505);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
transform="matrix(0.7571799,0,0,0.75599508,4.1230464,8.5143759)"
|
||||||
|
id="g5488">
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#linearGradient5506);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:1.37973988;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 6.3437483,15.454879 0,25.987281 37.3593247,0 -0.06316,-25.887713 c -1.3e-5,-0.0057 3.78e-4,-0.02709 0,-0.03319 -7.39e-4,-0.0065 0.0011,-0.02633 0,-0.03319 -0.0015,-0.0072 -0.02977,-0.02558 -0.03158,-0.03319 l -37.2645847,0 z"
|
||||||
|
id="path5490"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#linearGradient5508);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
d="M 20.490674,29.058712 7.09471,40.0307 l 13.908842,-9.604306 9.018158,0 12.419047,9.482193 -11.863425,-10.849875 -10.086658,0 z"
|
||||||
|
id="path5492"
|
||||||
|
sodipodi:nodetypes="ccccccc"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:none;stroke:#ffffff;stroke-width:1.37974012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||||
|
d="m 7.5310575,16.733861 c -0.00667,0.01319 0.00537,0.01943 0,0.03125 -0.00236,0.0056 -0.029093,0.02604 -0.031121,0.03125 -0.0017,0.0049 0.00136,0.02674 0,0.03125 -0.00102,0.0041 6.829e-4,0.02747 0,0.03125 l 0.031121,23.217159 34.7933665,0 -0.06224,-23.092168 c -6.84e-4,-0.0037 0.001,-0.02721 0,-0.03125 -0.0146,-0.04755 -0.04166,-0.130713 -0.09336,-0.218735 l -34.6377615,0 z"
|
||||||
|
id="path5494"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#radialGradient5510);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
d="M 23.329298,32.996721 C 20.937189,32.550375 7.9003872,18.771125 6.5966059,16.372022 6.5816495,16.343448 6.5559705,16.288608 6.5446896,16.2636 l 34.5131134,0 c -0.277079,2.502804 -7.524227,16.505746 -9.561279,16.733121 -0.0082,4.68e-4 -0.02128,0 -0.02927,0 l -8.020859,0 c -0.03363,0 -0.07755,0.0074 -0.117094,0 z"
|
||||||
|
id="path5496"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#linearGradient5512);fill-opacity:1;fill-rule:evenodd;stroke:#989898;stroke-width:1.18189096;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
|
||||||
|
d="M 20.77475,31.085394 C 18.407309,30.694257 7.945269,18.619435 7.1185841,16.517089 7.109327,16.49205 7.094677,16.443993 7.088438,16.422079 l 35.542207,0 c -0.823616,2.19322 -11.29845,14.464065 -13.445143,14.663315 -0.0085,4.09e-4 -0.02191,0 -0.03015,0 l -8.260021,0 c -0.03463,0 -0.08145,0.0065 -0.120584,0 z"
|
||||||
|
id="path5498"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#linearGradient5514);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
d="M 20.625174,30.490479 C 18.519211,29.999928 7.7224803,17.987711 7.0314243,16.466377 c -0.00254,-0.006 0.00218,-0.02669 0,-0.03231 -0.00545,-0.01576 -0.029096,-0.0523 -0.03125,-0.06463 2.87e-5,-0.0033 -4.061e-4,-0.02938 0,-0.03231 0.00117,-0.0021 0.029695,0.0017 0.03125,0 l 0.09375,-0.09694 35.4687497,0 c -0.0027,0.02433 -0.02268,0.06687 -0.03125,0.09694 -0.0075,0.0236 -0.02057,0.07023 -0.03125,0.09694 -0.922098,2.180937 -11.507988,13.766449 -13.34375,14.056416 -0.01493,0.0016 -0.04885,0 -0.0625,0 l -8.375,0 c -0.03029,-0.0017 -0.08975,0.0082 -0.125,0 z"
|
||||||
|
id="path5500"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:none;stroke:url(#linearGradient5516);stroke-width:1.18189073;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
|
||||||
|
d="M 20.875174,30.051141 C 18.427215,29.501671 8.7040003,18.433898 7.5314243,16.451725 l 34.5937497,0 c -1.490188,2.333171 -11.046672,13.411791 -13.15625,13.599416 -0.0087,4.02e-4 -0.02278,0 -0.03125,0 l -7.90625,0 c -0.02639,0 -0.06488,0.0036 -0.09375,0 -0.01979,-0.0031 -0.04165,0.0047 -0.0625,0 z"
|
||||||
|
id="path5502"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
style="fill:url(#linearGradient5518);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
||||||
|
d="m 20.959511,30.447113 -11.941499,8.270856 2.219433,0.0061 9.998125,-6.86894 8.821908,-1.422838 -9.097967,0.01482 z"
|
||||||
|
id="path5504"
|
||||||
|
sodipodi:nodetypes="cccccc"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g5524"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
transform="matrix(1.0358731,0.12915398,-0.12915398,1.0358731,3.4793879,-8.4319748)">
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
id="path4587"
|
||||||
|
d="M 1.349542,35.242012 7.245074,40.036876 20.092052,24.392047 24.022407,27.588624 30.349935,5.1150928 10.266168,16.400607 14.19652,19.597183 z"
|
||||||
|
style="color:#000000;fill:url(#linearGradient3297);fill-opacity:1;fill-rule:nonzero;stroke:#3465a4;stroke-width:0.99999911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="opacity:0.57142861;color:#000000;fill:none;stroke:url(#linearGradient3299);stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="m 2.982173,35.037884 4.072772,3.399631 12.855565,-15.699276 3.510841,2.868302 4.811841,-17.6344247 -16.088989,8.4894697 3.680552,2.931418 z"
|
||||||
|
id="path5474"
|
||||||
|
inkscape:r_cx="true"
|
||||||
|
inkscape:r_cy="true"
|
||||||
|
sodipodi:nodetypes="cccccccc"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 37 KiB |
After Width: | Height: | Size: 2.7 KiB |
|
@ -0,0 +1,242 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<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:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="48px"
|
||||||
|
height="48px"
|
||||||
|
id="svg1717"
|
||||||
|
sodipodi:version="0.32"
|
||||||
|
inkscape:version="0.48.3.1 r9886"
|
||||||
|
sodipodi:docname="Multimedia-volume-control.svg"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:export-filename="/home/glic3/orchestra/django-orchestra/orchestra/static/orchestra/icons/Multimedia-volume-control.png"
|
||||||
|
inkscape:export-xdpi="90"
|
||||||
|
inkscape:export-ydpi="90">
|
||||||
|
<defs
|
||||||
|
id="defs1719">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2335">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2337" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2339" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient2327">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop2329" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffffff;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop2331" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3574">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3465a4;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3576" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#3465a4;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3578" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient3566">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#d3d7cf;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3568" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#a6ae9d;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3570" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient3558">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop3560" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#000000;stop-opacity:0;"
|
||||||
|
offset="1"
|
||||||
|
id="stop3562" />
|
||||||
|
</linearGradient>
|
||||||
|
<radialGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3558"
|
||||||
|
id="radialGradient3564"
|
||||||
|
cx="22.571428"
|
||||||
|
cy="30.857143"
|
||||||
|
fx="22.571428"
|
||||||
|
fy="30.857143"
|
||||||
|
r="15.571428"
|
||||||
|
gradientTransform="matrix(1.000000,0.000000,0.000000,0.651376,3.763482e-15,10.75754)"
|
||||||
|
gradientUnits="userSpaceOnUse" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3566"
|
||||||
|
id="linearGradient3572"
|
||||||
|
x1="19.544102"
|
||||||
|
y1="22.640625"
|
||||||
|
x2="36.0625"
|
||||||
|
y2="22.640625"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-5.052390)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient3574"
|
||||||
|
id="linearGradient3580"
|
||||||
|
x1="22.031542"
|
||||||
|
y1="22.78162"
|
||||||
|
x2="20.71196"
|
||||||
|
y2="4.7503953"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-5.052390)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2327"
|
||||||
|
id="linearGradient2333"
|
||||||
|
x1="17.525631"
|
||||||
|
y1="20.396902"
|
||||||
|
x2="33.474358"
|
||||||
|
y2="15.271904"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-4.319792)" />
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient2335"
|
||||||
|
id="linearGradient2341"
|
||||||
|
x1="23.9375"
|
||||||
|
y1="18.725033"
|
||||||
|
x2="23.9375"
|
||||||
|
y2="16.847691"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(1.184060,0.000000,0.000000,1.184060,-5.942398,-4.319792)" />
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="0.12156863"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="4"
|
||||||
|
inkscape:cx="35.22146"
|
||||||
|
inkscape:cy="15.407751"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:grid-bbox="true"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:showpageshadow="false"
|
||||||
|
fill="#3465a4"
|
||||||
|
stroke="#888a85"
|
||||||
|
inkscape:window-width="737"
|
||||||
|
inkscape:window-height="669"
|
||||||
|
inkscape:window-x="697"
|
||||||
|
inkscape:window-y="181"
|
||||||
|
inkscape:window-maximized="0" />
|
||||||
|
<metadata
|
||||||
|
id="metadata1722">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<cc:license
|
||||||
|
rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
|
||||||
|
<dc:title>Volume Control</dc:title>
|
||||||
|
<dc:subject>
|
||||||
|
<rdf:Bag>
|
||||||
|
<rdf:li>multimedia</rdf:li>
|
||||||
|
<rdf:li>sound</rdf:li>
|
||||||
|
<rdf:li>volume</rdf:li>
|
||||||
|
<rdf:li>knob</rdf:li>
|
||||||
|
<rdf:li>control</rdf:li>
|
||||||
|
<rdf:li>mixer</rdf:li>
|
||||||
|
</rdf:Bag>
|
||||||
|
</dc:subject>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Jakub Steiner</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:source>http://jimmac.musichall.cz</dc:source>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License
|
||||||
|
rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/Attribution" />
|
||||||
|
<cc:permits
|
||||||
|
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||||
|
<cc:requires
|
||||||
|
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
id="layer1"
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer">
|
||||||
|
<path
|
||||||
|
style="opacity:1;color:#000000;fill:url(#linearGradient3580);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:1 1 ;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 3.5532403,33.393643 C -5.5596849,21.573975 6.9131063,9.4946328 20.952673,9.8329353 C 34.99224,10.171238 45.099036,15.118916 47.467155,27.805271 C 47.467155,27.805271 39.728479,27.086378 39.728479,27.086378 C 39.728479,19.305413 32.804297,15.24578 21.121824,15.24578 C 9.107311,15.24578 -2.6269476,18.34756 3.5532403,33.393643 z "
|
||||||
|
id="path2664"
|
||||||
|
sodipodi:nodetypes="cscczc" />
|
||||||
|
<path
|
||||||
|
sodipodi:type="arc"
|
||||||
|
style="opacity:0.47368421;color:#000000;fill:url(#radialGradient3564);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
id="path3556"
|
||||||
|
sodipodi:cx="22.571428"
|
||||||
|
sodipodi:cy="30.857143"
|
||||||
|
sodipodi:rx="15.571428"
|
||||||
|
sodipodi:ry="10.142858"
|
||||||
|
d="M 38.142857 30.857143 A 15.571428 10.142858 0 1 1 7,30.857143 A 15.571428 10.142858 0 1 1 38.142857 30.857143 z"
|
||||||
|
transform="matrix(1.408115,0.000000,0.000000,1.408115,-10.54085,-16.32385)" />
|
||||||
|
<path
|
||||||
|
style="opacity:1;color:#000000;fill:#cc0000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:1 1 ;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 39.390175,28.439589 C 39.390175,28.439589 38.882722,30.638557 38.290692,31.399738 L 46.832838,37.235461 C 47.847746,34.021585 47.509443,29.7928 47.509443,29.7928 L 39.390175,28.439589 z "
|
||||||
|
id="path3539"
|
||||||
|
sodipodi:nodetypes="ccccc" />
|
||||||
|
<path
|
||||||
|
style="opacity:1;color:#000000;fill:url(#linearGradient3572);fill-opacity:1;fill-rule:nonzero;stroke:#888a85;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 20.883958,6.1221749 C 13.55429,6.1221749 7.6002852,10.219577 7.6002852,15.261641 C 7.6002852,16.855622 5.2321652,23.956925 5.2321652,26.732222 C 5.2321652,32.609278 12.155451,37.388761 20.698949,37.388762 C 29.242446,37.388762 36.165734,32.609276 36.165733,26.732222 C 36.165733,24.022217 34.13063,15.261641 34.13063,15.261641 L 33.982622,8.1572805 L 29.690405,8.5272993 C 27.34265,7.0620706 24.305772,6.1221749 20.883958,6.1221749 z "
|
||||||
|
id="path3541"
|
||||||
|
sodipodi:nodetypes="csssssccc" />
|
||||||
|
<path
|
||||||
|
style="opacity:0.73684208;color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2341);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||||
|
d="M 20.698949,6.6031993 C 14.047951,6.6031993 8.636338,10.051187 8.636338,14.299592 C 8.636338,18.547995 14.047951,21.995982 20.698949,21.995982 C 27.349947,21.995982 32.761559,18.547995 32.76156,14.299592 C 32.76156,13.51384 32.401598,12.793721 32.058525,12.079479 L 33.316588,8.8233143 L 29.653403,9.3043386 C 27.444179,7.6893945 24.31762,6.6031994 20.698949,6.6031993 z "
|
||||||
|
id="path3545" />
|
||||||
|
<path
|
||||||
|
sodipodi:nodetypes="csssssccc"
|
||||||
|
id="path1452"
|
||||||
|
d="M 20.87031,7.2748571 C 14.081079,7.2748571 8.5660815,11.070145 8.5660815,15.740442 C 8.5660815,17.216895 6.3725701,23.794597 6.3725701,26.365264 C 6.3725701,31.808986 12.785381,36.236064 20.698941,36.236065 C 28.6125,36.236065 35.025314,31.808986 35.025312,26.365264 C 35.025312,23.855076 33.140264,15.740442 33.140264,15.740442 L 33.003169,9.1599082 L 29.02743,9.5026438 C 26.852782,8.1454517 24.039823,7.2748571 20.87031,7.2748571 z "
|
||||||
|
style="opacity:0.47368421;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient2333);stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |