mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
Merge branch 'master' of gitlab.com:allianceauth/allianceauth into v5.x
This commit is contained in:
commit
15fc38ccfd
@ -3,6 +3,25 @@
|
|||||||
# Update this file:
|
# Update this file:
|
||||||
# pre-commit autoupdate
|
# pre-commit autoupdate
|
||||||
|
|
||||||
|
# Set the default language versions for the hooks
|
||||||
|
default_language_version:
|
||||||
|
python: python3 # Force all Python hooks to use Python 3
|
||||||
|
node: 22.12.0 # Force all Node hooks to use Node 22.12.0
|
||||||
|
|
||||||
|
# Globally exclude files
|
||||||
|
# https://pre-commit.com/#top_level-exclude
|
||||||
|
exclude: |
|
||||||
|
(?x)(
|
||||||
|
LICENSE|
|
||||||
|
allianceauth\/static\/allianceauth\/css\/themes\/bootstrap-locals.less|
|
||||||
|
\.min\.css|
|
||||||
|
\.min\.js|
|
||||||
|
\.po|
|
||||||
|
\.mo|
|
||||||
|
swagger\.json|
|
||||||
|
static/(.*)/libs/
|
||||||
|
)
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.8.1
|
rev: v0.8.1
|
||||||
@ -33,9 +52,9 @@ repos:
|
|||||||
- id: detect-private-key
|
- id: detect-private-key
|
||||||
- id: check-case-conflict
|
- id: check-case-conflict
|
||||||
# Python checks
|
# Python checks
|
||||||
# - id: check-docstring-first
|
# - id: check-docstring-first
|
||||||
- id: debug-statements
|
- id: debug-statements
|
||||||
# - id: requirements-txt-fixer
|
# - id: requirements-txt-fixer
|
||||||
- id: fix-encoding-pragma
|
- id: fix-encoding-pragma
|
||||||
args: [--remove]
|
args: [--remove]
|
||||||
- id: fix-byte-order-marker
|
- id: fix-byte-order-marker
|
||||||
@ -44,40 +63,17 @@ repos:
|
|||||||
args: [--fix=lf]
|
args: [--fix=lf]
|
||||||
- id: trailing-whitespace
|
- id: trailing-whitespace
|
||||||
args: [--markdown-linebreak-ext=md]
|
args: [--markdown-linebreak-ext=md]
|
||||||
exclude: |
|
|
||||||
(?x)(
|
|
||||||
\.min\.css|
|
|
||||||
\.min\.js|
|
|
||||||
\.po|
|
|
||||||
\.mo|
|
|
||||||
swagger\.json
|
|
||||||
)
|
|
||||||
- id: check-executables-have-shebangs
|
- id: check-executables-have-shebangs
|
||||||
- id: end-of-file-fixer
|
- id: end-of-file-fixer
|
||||||
exclude: |
|
|
||||||
(?x)(
|
|
||||||
\.min\.css|
|
|
||||||
\.min\.js|
|
|
||||||
\.po|
|
|
||||||
\.mo|
|
|
||||||
swagger\.json
|
|
||||||
)
|
|
||||||
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
|
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
|
||||||
rev: 3.0.3
|
rev: 3.2.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: editorconfig-checker
|
- id: editorconfig-checker
|
||||||
exclude: |
|
|
||||||
(?x)(
|
|
||||||
LICENSE|
|
|
||||||
allianceauth\/static\/allianceauth\/css\/themes\/bootstrap-locals.less|
|
|
||||||
\.po|
|
|
||||||
\.mo|
|
|
||||||
swagger\.json
|
|
||||||
)
|
|
||||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||||
rev: v0.43.0
|
rev: v0.44.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: markdownlint
|
- id: markdownlint
|
||||||
|
language: node
|
||||||
args:
|
args:
|
||||||
- --disable=MD013
|
- --disable=MD013
|
||||||
# Infrastructure
|
# Infrastructure
|
||||||
@ -90,7 +86,7 @@ repos:
|
|||||||
args:
|
args:
|
||||||
- --indent=4
|
- --indent=4
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- tox==4.18.1 # https://github.com/tox-dev/tox/releases/latest
|
- tox==4.24.1 # https://github.com/tox-dev/tox/releases/latest
|
||||||
- repo: https://github.com/abravalheri/validate-pyproject
|
- repo: https://github.com/abravalheri/validate-pyproject
|
||||||
rev: v0.23
|
rev: v0.23
|
||||||
hooks:
|
hooks:
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
[](https://pypi.org/project/allianceauth/)
|
[](https://pypi.org/project/allianceauth/)
|
||||||
[](https://pypi.org/project/allianceauth/)
|
[](https://pypi.org/project/allianceauth/)
|
||||||
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
||||||
[](http://allianceauth.readthedocs.io/?badge=latest)
|
[](https://allianceauth.readthedocs.io/?badge=latest)
|
||||||
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
[](https://gitlab.com/allianceauth/allianceauth/commits/master)
|
||||||
[](https://discord.gg/fjnHAmk)
|
[](https://discord.gg/fjnHAmk)
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ An auth system for EVE Online to help in-game organizations manage online servic
|
|||||||
## Content
|
## Content
|
||||||
|
|
||||||
- [Overview](#overview)
|
- [Overview](#overview)
|
||||||
- [Documentation](http://allianceauth.rtfd.io)
|
- [Documentation](https://allianceauth.rtfd.io)
|
||||||
- [Support](#support)
|
- [Support](#support)
|
||||||
- [Release Notes](https://gitlab.com/allianceauth/allianceauth/-/releases)
|
- [Release Notes](https://gitlab.com/allianceauth/allianceauth/-/releases)
|
||||||
- [Developer Team](#development-team)
|
- [Developer Team](#development-team)
|
||||||
@ -38,7 +38,7 @@ Main features:
|
|||||||
|
|
||||||
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr:, Russian :flag_ru:, Italian :flag_it:, French :flag_fr:, Japanese :flag_jp: and Ukrainian :flag_ua: Localization
|
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr:, Russian :flag_ru:, Italian :flag_it:, French :flag_fr:, Japanese :flag_jp: and Ukrainian :flag_ua: Localization
|
||||||
|
|
||||||
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](http://allianceauth.rtfd.io).
|
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](https://allianceauth.rtfd.io).
|
||||||
|
|
||||||
## Screenshot
|
## Screenshot
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ manage online service access.
|
|||||||
# This will make sure the app is always imported when
|
# This will make sure the app is always imported when
|
||||||
# Django starts so that shared_task will use this app.
|
# Django starts so that shared_task will use this app.
|
||||||
|
|
||||||
__version__ = '4.3.1'
|
__version__ = '4.6.4'
|
||||||
__title__ = 'Alliance Auth'
|
__title__ = 'Alliance Auth'
|
||||||
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
|
||||||
NAME = f'{__title__} v{__version__}'
|
NAME = f'{__title__} v{__version__}'
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
|
from solo.admin import SingletonModelAdmin
|
||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import AnalyticsIdentifier, AnalyticsTokens
|
from .models import AnalyticsIdentifier, AnalyticsTokens
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AnalyticsIdentifier)
|
@admin.register(AnalyticsIdentifier)
|
||||||
class AnalyticsIdentifierAdmin(admin.ModelAdmin):
|
class AnalyticsIdentifierAdmin(SingletonModelAdmin):
|
||||||
search_fields = ['identifier', ]
|
search_fields = ['identifier', ]
|
||||||
list_display = ('identifier',)
|
list_display = ['identifier', ]
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AnalyticsTokens)
|
@admin.register(AnalyticsTokens)
|
||||||
class AnalyticsTokensAdmin(admin.ModelAdmin):
|
class AnalyticsTokensAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['name', ]
|
search_fields = ['name', ]
|
||||||
list_display = ('name', 'type',)
|
list_display = ['name', 'type', ]
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-12-11 02:17
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('analytics', '0009_remove_analyticstokens_ignore_paths_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='analyticsidentifier',
|
||||||
|
options={'verbose_name': 'Analytics Identifier'},
|
||||||
|
),
|
||||||
|
]
|
@ -1,27 +1,21 @@
|
|||||||
|
from typing import Literal
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from solo.models import SingletonModel
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class AnalyticsIdentifier(models.Model):
|
class AnalyticsIdentifier(SingletonModel):
|
||||||
|
|
||||||
identifier = models.UUIDField(
|
identifier = models.UUIDField(default=uuid4, editable=False)
|
||||||
default=uuid4,
|
|
||||||
editable=False)
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> Literal['Analytics Identifier']:
|
||||||
return f"{self.identifier}"
|
return "Analytics Identifier"
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if not self.pk and AnalyticsIdentifier.objects.exists():
|
|
||||||
# Force a single object
|
|
||||||
raise ValidationError('There is can be only one \
|
|
||||||
AnalyticsIdentifier instance')
|
|
||||||
self.pk = self.id = 1 # If this happens to be deleted and recreated, force it to be 1
|
|
||||||
return super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Analytics Identifier"
|
||||||
|
|
||||||
class AnalyticsTokens(models.Model):
|
class AnalyticsTokens(models.Model):
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from django.conf import settings
|
|||||||
from allianceauth import __version__
|
from allianceauth import __version__
|
||||||
|
|
||||||
from .models import AnalyticsIdentifier, AnalyticsTokens
|
from .models import AnalyticsIdentifier, AnalyticsTokens
|
||||||
from .utils import install_stat_addons, install_stat_tokens, install_stat_users
|
from .utils import existence_baremetal_or_docker, install_stat_addons, install_stat_tokens, install_stat_users
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -67,8 +67,8 @@ def analytics_event(namespace: str,
|
|||||||
value=value).apply_async(priority=9)
|
value=value).apply_async(priority=9)
|
||||||
|
|
||||||
|
|
||||||
@shared_task()
|
@shared_task
|
||||||
def analytics_daily_stats():
|
def analytics_daily_stats() -> None:
|
||||||
"""Celery Task: Do not call directly
|
"""Celery Task: Do not call directly
|
||||||
|
|
||||||
Gathers a series of daily statistics
|
Gathers a series of daily statistics
|
||||||
@ -77,6 +77,7 @@ def analytics_daily_stats():
|
|||||||
users = install_stat_users()
|
users = install_stat_users()
|
||||||
tokens = install_stat_tokens()
|
tokens = install_stat_tokens()
|
||||||
addons = install_stat_addons()
|
addons = install_stat_addons()
|
||||||
|
existence_type = existence_baremetal_or_docker()
|
||||||
logger.debug("Running Daily Analytics Upload")
|
logger.debug("Running Daily Analytics Upload")
|
||||||
|
|
||||||
analytics_event(namespace='allianceauth.analytics',
|
analytics_event(namespace='allianceauth.analytics',
|
||||||
@ -84,6 +85,11 @@ def analytics_daily_stats():
|
|||||||
label='existence',
|
label='existence',
|
||||||
value=1,
|
value=1,
|
||||||
event_type='Stats')
|
event_type='Stats')
|
||||||
|
analytics_event(namespace='allianceauth.analytics',
|
||||||
|
task='send_install_stats',
|
||||||
|
label=existence_type,
|
||||||
|
value=1,
|
||||||
|
event_type='Stats')
|
||||||
analytics_event(namespace='allianceauth.analytics',
|
analytics_event(namespace='allianceauth.analytics',
|
||||||
task='send_install_stats',
|
task='send_install_stats',
|
||||||
label='users',
|
label='users',
|
||||||
@ -99,7 +105,6 @@ def analytics_daily_stats():
|
|||||||
label='addons',
|
label='addons',
|
||||||
value=addons,
|
value=addons,
|
||||||
event_type='Stats')
|
event_type='Stats')
|
||||||
|
|
||||||
for appconfig in apps.get_app_configs():
|
for appconfig in apps.get_app_configs():
|
||||||
if appconfig.label in [
|
if appconfig.label in [
|
||||||
"django_celery_beat",
|
"django_celery_beat",
|
||||||
@ -135,7 +140,7 @@ def analytics_daily_stats():
|
|||||||
event_type='Stats')
|
event_type='Stats')
|
||||||
|
|
||||||
|
|
||||||
@shared_task()
|
@shared_task
|
||||||
def send_ga_tracking_celery_event(
|
def send_ga_tracking_celery_event(
|
||||||
measurement_id: str,
|
measurement_id: str,
|
||||||
secret: str,
|
secret: str,
|
||||||
@ -165,7 +170,7 @@ def send_ga_tracking_celery_event(
|
|||||||
}
|
}
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
'client_id': AnalyticsIdentifier.objects.get(id=1).identifier.hex,
|
'client_id': AnalyticsIdentifier.get_solo().identifier.hex,
|
||||||
"user_properties": {
|
"user_properties": {
|
||||||
"allianceauth_version": {
|
"allianceauth_version": {
|
||||||
"value": __version__
|
"value": __version__
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from uuid import UUID, uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.test.testcases import TestCase
|
from django.test.testcases import TestCase
|
||||||
|
|
||||||
from allianceauth.analytics.models import AnalyticsIdentifier
|
from allianceauth.analytics.models import AnalyticsIdentifier
|
||||||
@ -13,14 +12,4 @@ uuid_2 = "7aa6bd70701f44729af5e3095ff4b55c"
|
|||||||
class TestAnalyticsIdentifier(TestCase):
|
class TestAnalyticsIdentifier(TestCase):
|
||||||
|
|
||||||
def test_identifier_random(self):
|
def test_identifier_random(self):
|
||||||
self.assertNotEqual(AnalyticsIdentifier.objects.get(), uuid4)
|
self.assertNotEqual(AnalyticsIdentifier.get_solo(), uuid4)
|
||||||
|
|
||||||
def test_identifier_singular(self):
|
|
||||||
AnalyticsIdentifier.objects.all().delete()
|
|
||||||
AnalyticsIdentifier.objects.create(identifier=uuid_1)
|
|
||||||
# Yeah i have multiple asserts here, they all do the same thing
|
|
||||||
with self.assertRaises(ValidationError):
|
|
||||||
AnalyticsIdentifier.objects.create(identifier=uuid_2)
|
|
||||||
self.assertEqual(AnalyticsIdentifier.objects.count(), 1)
|
|
||||||
self.assertEqual(AnalyticsIdentifier.objects.get(
|
|
||||||
pk=1).identifier, UUID(uuid_1))
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
|
||||||
from esi.models import Token
|
from esi.models import Token
|
||||||
@ -36,3 +38,16 @@ def install_stat_addons() -> int:
|
|||||||
The Number of Installed Apps"""
|
The Number of Installed Apps"""
|
||||||
addons = len(list(apps.get_app_configs()))
|
addons = len(list(apps.get_app_configs()))
|
||||||
return addons
|
return addons
|
||||||
|
|
||||||
|
|
||||||
|
def existence_baremetal_or_docker() -> str:
|
||||||
|
"""Checks the Installation Type of an install
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
str
|
||||||
|
existence_baremetal or existence_docker"""
|
||||||
|
docker_tag = os.getenv('AA_DOCKER_TAG')
|
||||||
|
if docker_tag:
|
||||||
|
return "existence_docker"
|
||||||
|
return "existence_baremetal"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
@ -13,7 +14,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div>
|
<div>
|
||||||
<p class="mb-3">
|
<p class="mb-3">
|
||||||
{% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://community.eveonline.com/support/third-party-applications/ where possible."|urlize %}
|
{% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://developers.eveonline.com/authorized-apps where possible."|urlize %}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<table class="table w-100" id="table_tokens">
|
<table class="table w-100" id="table_tokens">
|
||||||
@ -50,20 +51,23 @@
|
|||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include "bundles/datatables-js-bs5.html" %}
|
{% include "bundles/datatables-js-bs5.html" %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
let grp = 2;
|
let grp = 2;
|
||||||
|
|
||||||
const table = $('#table_tokens').DataTable({
|
$('#table_tokens').DataTable({
|
||||||
|
"language": {"url": '{{ DT_LANG_PATH }}'},
|
||||||
'columnDefs': [{orderable: false, targets: [0, 1]}, {
|
'columnDefs': [{orderable: false, targets: [0, 1]}, {
|
||||||
'visible': false,
|
'visible': false,
|
||||||
'targets': grp
|
'targets': grp
|
||||||
}],
|
}],
|
||||||
'order': [[grp, 'asc']],
|
'order': [[grp, 'asc']],
|
||||||
'drawCallback': function (settings) {
|
'drawCallback': function (settings) {
|
||||||
var api = this.api();
|
const api = this.api();
|
||||||
var rows = api.rows({page: 'current'}).nodes();
|
const rows = api.rows({page: 'current'}).nodes();
|
||||||
var last = null;
|
let last = null;
|
||||||
api.column(grp, {page: 'current'})
|
api.column(grp, {page: 'current'})
|
||||||
.data()
|
.data()
|
||||||
.each((group, i) => {
|
.each((group, i) => {
|
||||||
|
@ -5,11 +5,11 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<select class="form-select" onchange="this.form.submit()" class="form-control" id="lang-select" name="language">
|
<select class="form-select" onchange="this.form.submit()" class="form-control" id="lang-select" name="language">
|
||||||
{% get_language_info_list for LANGUAGES as languages %}
|
{% get_available_languages as LANGUAGES %}
|
||||||
|
|
||||||
{% for language in languages %}
|
{% for lang_code, lang_name in LANGUAGES %}
|
||||||
<option lang="{{ language.code }}" value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
|
<option lang="{{ lang_code }}" value="{{ lang_code }}"{% if lang_code == LANGUAGE_CODE %} selected{% endif %}>
|
||||||
{{ language.name_local|capfirst }} ({{ language.code }})
|
{{ lang_code|language_name_local|capfirst }} ({{ lang_code }})
|
||||||
</option>
|
</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<a class="text-reset" href="https://community.eveonline.com/support/third-party-applications/" target="_blank" rel="noopener noreferrer">
|
<a class="text-reset" href="https://developers.eveonline.com/authorized-apps" target="_blank" rel="noopener noreferrer">
|
||||||
{% translate "Manage ESI Applications" %}
|
{% translate "Manage ESI Applications" %}
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
import datetime
|
"""
|
||||||
|
Django system checks for Alliance Auth
|
||||||
|
"""
|
||||||
|
|
||||||
from sqlite3.dbapi2 import sqlite_version_info
|
from sqlite3.dbapi2 import sqlite_version_info
|
||||||
|
|
||||||
from celery import current_app
|
from celery import current_app
|
||||||
@ -19,131 +22,415 @@ B = Configuration
|
|||||||
|
|
||||||
@register()
|
@register()
|
||||||
def django_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
def django_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
errors: list[CheckMessage] = []
|
"""
|
||||||
if hasattr(settings, "SITE_URL"):
|
Check that Django settings are correctly configured
|
||||||
if settings.SITE_URL[-1] == "/":
|
|
||||||
errors.append(Warning("'SITE_URL' Has a trailing slash. This may lead to incorrect links being generated by Auth.", hint="", id="allianceauth.checks.B005"))
|
|
||||||
else:
|
|
||||||
errors.append(Error("No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules.", hint="", id="allianceauth.checks.B006"))
|
|
||||||
|
|
||||||
if hasattr(settings, "CSRF_TRUSTED_ORIGINS") and hasattr(settings, "SITE_URL"):
|
:param app_configs:
|
||||||
if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS:
|
:type app_configs:
|
||||||
errors.append(Warning("'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified.", hint="", id="allianceauth.checks.B007"))
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
|
# Check for SITE_URL
|
||||||
|
if hasattr(settings, "SITE_URL"):
|
||||||
|
# Check if SITE_URL is empty
|
||||||
|
if settings.SITE_URL == "":
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="'SITE_URL' is empty.",
|
||||||
|
hint="Make sure to set 'SITE_URL' to the URL of your Auth instance. (Without trailing slash)",
|
||||||
|
id="allianceauth.checks.B011",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Check if SITE_URL has a trailing slash
|
||||||
|
elif settings.SITE_URL[-1] == "/":
|
||||||
|
errors.append(
|
||||||
|
Warning(
|
||||||
|
msg="'SITE_URL' has a trailing slash. This may lead to incorrect links being generated by Auth.",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B005",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# SITE_URL not found
|
||||||
else:
|
else:
|
||||||
errors.append(Error("No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified", hint="", id="allianceauth.checks.B008"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="No 'SITE_URL' found is settings. This may lead to incorrect links being generated by Auth or Errors in 3rd party modules.",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B006",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check for CSRF_TRUSTED_ORIGINS
|
||||||
|
if hasattr(settings, "CSRF_TRUSTED_ORIGINS") and hasattr(settings, "SITE_URL"):
|
||||||
|
# Check if SITE_URL is not in CSRF_TRUSTED_ORIGINS
|
||||||
|
if settings.SITE_URL not in settings.CSRF_TRUSTED_ORIGINS:
|
||||||
|
errors.append(
|
||||||
|
Warning(
|
||||||
|
msg="'SITE_URL' not found in 'CSRF_TRUSTED_ORIGINS'. Auth may not load pages correctly until this is rectified.",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B007",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# CSRF_TRUSTED_ORIGINS not found
|
||||||
|
else:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="No 'CSRF_TRUSTED_ORIGINS' found is settings, Auth may not load pages correctly until this is rectified",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B008",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check for ESI_USER_CONTACT_EMAIL
|
||||||
|
if hasattr(settings, "ESI_USER_CONTACT_EMAIL"):
|
||||||
|
# Check if ESI_USER_CONTACT_EMAIL is empty
|
||||||
|
if settings.ESI_USER_CONTACT_EMAIL == "":
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="'ESI_USER_CONTACT_EMAIL' is empty. A valid email is required as maintainer contact for CCP.",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B009",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# ESI_USER_CONTACT_EMAIL not found
|
||||||
|
else:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="No 'ESI_USER_CONTACT_EMAIL' found is settings. A valid email is required as maintainer contact for CCP.",
|
||||||
|
hint="",
|
||||||
|
id="allianceauth.checks.B010",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def system_package_redis(app_configs, **kwargs) -> list[CheckMessage]:
|
def system_package_redis(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
|
"""
|
||||||
|
Check that Redis is a supported version
|
||||||
|
|
||||||
|
:param app_configs:
|
||||||
|
:type app_configs:
|
||||||
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
|
allianceauth_redis_install_link = "https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools"
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
redis_version = Pep440Version(get_redis_client().info()['redis_version'])
|
redis_version = Pep440Version(get_redis_client().info()["redis_version"])
|
||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
errors.append(Warning("Unable to confirm Redis Version"))
|
errors.append(Warning("Unable to confirm Redis Version"))
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
if redis_version.major == 7 and redis_version.minor == 4 and timezone.now() > timezone.datetime(year=2025, month=8, day=31, tzinfo=datetime.timezone.utc):
|
|
||||||
errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A001"))
|
if (
|
||||||
elif redis_version.major == 7 and redis_version.minor == 2:
|
redis_version.major == 7
|
||||||
errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A021"))
|
and redis_version.minor == 2
|
||||||
|
and timezone.now()
|
||||||
|
> timezone.datetime(year=2025, month=8, day=31, tzinfo=timezone.utc)
|
||||||
|
):
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
||||||
|
hint=allianceauth_redis_install_link,
|
||||||
|
id="allianceauth.checks.A001",
|
||||||
|
)
|
||||||
|
)
|
||||||
elif redis_version.major == 7 and redis_version.minor == 0:
|
elif redis_version.major == 7 and redis_version.minor == 0:
|
||||||
errors.append(Error(f"Redis {redis_version.public} EOL", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A019"))
|
errors.append(
|
||||||
|
Warning(
|
||||||
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
||||||
|
hint=allianceauth_redis_install_link,
|
||||||
|
id="allianceauth.checks.A002",
|
||||||
|
)
|
||||||
|
)
|
||||||
elif redis_version.major == 6 and redis_version.minor == 2:
|
elif redis_version.major == 6 and redis_version.minor == 2:
|
||||||
errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A018"))
|
errors.append(
|
||||||
|
Warning(
|
||||||
|
msg=f"Redis {redis_version.public} in Security Support only, Updating Suggested",
|
||||||
|
hint=allianceauth_redis_install_link,
|
||||||
|
id="allianceauth.checks.A018",
|
||||||
|
)
|
||||||
|
)
|
||||||
elif redis_version.major in [6, 5]:
|
elif redis_version.major in [6, 5]:
|
||||||
errors.append(Error(f"Redis {redis_version.public} EOL", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A003"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"Redis {redis_version.public} EOL",
|
||||||
|
hint=allianceauth_redis_install_link,
|
||||||
|
id="allianceauth.checks.A003",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def system_package_mysql(app_configs, **kwargs) -> list[CheckMessage]:
|
def system_package_mysql(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
|
"""
|
||||||
|
Check that MySQL is a supported version
|
||||||
|
|
||||||
|
:param app_configs:
|
||||||
|
:type app_configs:
|
||||||
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
|
mysql_quick_guide_link = "https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/"
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
for connection in db.connections.all():
|
for connection in db.connections.all():
|
||||||
if connection.vendor == "mysql":
|
if connection.vendor == "mysql":
|
||||||
try:
|
try:
|
||||||
mysql_version = Pep440Version(".".join(str(i) for i in connection.mysql_version))
|
mysql_version = Pep440Version(
|
||||||
|
".".join(str(i) for i in connection.mysql_version)
|
||||||
|
)
|
||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
errors.append(Warning("Unable to confirm MySQL Version"))
|
errors.append(Warning("Unable to confirm MySQL Version"))
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
# MySQL 8
|
# MySQL 8
|
||||||
if mysql_version.major == 8 and mysql_version.minor == 4 and timezone.now() > timezone.datetime(year=2032, month=4, day=30, tzinfo=datetime.timezone.utc):
|
if mysql_version.major == 8:
|
||||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A004"))
|
if mysql_version.minor == 4 and timezone.now() > timezone.datetime(
|
||||||
elif mysql_version.major == 8 and mysql_version.minor in [1, 2, 3]:
|
year=2032, month=4, day=30, tzinfo=timezone.utc
|
||||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A007"))
|
):
|
||||||
elif mysql_version.major == 8 and mysql_version.minor == 0 and timezone.now() > timezone.datetime(year=2026, month=4, day=30, tzinfo=datetime.timezone.utc):
|
errors.append(
|
||||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A008"))
|
Error(
|
||||||
elif mysql_version.major < 8: # This will also catch Mariadb 5.x
|
msg=f"MySQL {mysql_version.public} EOL",
|
||||||
errors.append(Error(f"MySQL or MariaDB {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A009"))
|
hint=mysql_quick_guide_link,
|
||||||
|
id="allianceauth.checks.A004",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Demote versions down here once EOL
|
||||||
|
elif mysql_version.minor in [1, 2, 3]:
|
||||||
|
errors.append(
|
||||||
|
Warning(
|
||||||
|
msg=f"MySQL {mysql_version.public} Non LTS",
|
||||||
|
hint=mysql_quick_guide_link,
|
||||||
|
id="allianceauth.checks.A005",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif mysql_version.minor == 0 and timezone.now() > timezone.datetime(
|
||||||
|
year=2026, month=4, day=30, tzinfo=timezone.utc
|
||||||
|
):
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MySQL {mysql_version.public} EOL",
|
||||||
|
hint=mysql_quick_guide_link,
|
||||||
|
id="allianceauth.checks.A008",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# MySQL below 8
|
||||||
|
# This will also catch Mariadb 5.x
|
||||||
|
elif mysql_version.major < 8:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MySQL or MariaDB {mysql_version.public} EOL",
|
||||||
|
hint=mysql_quick_guide_link,
|
||||||
|
id="allianceauth.checks.A009",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def system_package_mariadb(app_configs, **kwargs) -> list[CheckMessage]:
|
def system_package_mariadb(app_configs, **kwargs) -> list[CheckMessage]: # noqa: C901
|
||||||
|
"""
|
||||||
|
Check that MariaDB is a supported version
|
||||||
|
"""
|
||||||
|
|
||||||
|
mariadb_download_link = "https://mariadb.org/download/?t=repo-config"
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
for connection in db.connections.all():
|
for connection in db.connections.all():
|
||||||
if connection.vendor == "mysql": # Still to find a way to determine MySQL vs MariaDB
|
# TODO: Find a way to determine MySQL vs. MariaDB
|
||||||
|
if connection.vendor == "mysql":
|
||||||
try:
|
try:
|
||||||
mariadb_version = Pep440Version(".".join(str(i) for i in connection.mysql_version))
|
mariadb_version = Pep440Version(
|
||||||
|
".".join(str(i) for i in connection.mysql_version)
|
||||||
|
)
|
||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
errors.append(Warning("Unable to confirm MariaDB Version"))
|
errors.append(Warning("Unable to confirm MariaDB Version"))
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
# MariaDB 11
|
# MariaDB 11
|
||||||
if mariadb_version.major == 11 and mariadb_version.minor == 4 and timezone.now() > timezone.datetime(year=2029, month=5, day=19, tzinfo=datetime.timezone.utc):
|
if mariadb_version.major == 11:
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A010"))
|
if mariadb_version.minor == 4 and timezone.now() > timezone.datetime(
|
||||||
elif mariadb_version.major == 11 and mariadb_version.minor in [0, 1, 2, 3, 5]: # Demote versions down here once EOL
|
year=2029, month=5, day=19, tzinfo=timezone.utc
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config.", id="allianceauth.checks.A013"))
|
):
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A010",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Demote versions down here once EOL
|
||||||
|
elif mariadb_version.minor in [0, 1, 2, 3, 5, 6]:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A013",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# MariaDB 10
|
# MariaDB 10
|
||||||
elif mariadb_version.major == 10 and mariadb_version.minor == 11 and timezone.now() > timezone.datetime(year=2028, month=2, day=10, tzinfo=datetime.timezone.utc):
|
elif mariadb_version.major == 10:
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config.", id="allianceauth.checks.A014"))
|
if mariadb_version.minor == 11 and timezone.now() > timezone.datetime(
|
||||||
elif mariadb_version.major == 10 and mariadb_version.minor == 6 and timezone.now() > timezone.datetime(year=2026, month=7, day=6, tzinfo=datetime.timezone.utc):
|
year=2028, month=2, day=10, tzinfo=timezone.utc
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A0015"))
|
):
|
||||||
elif mariadb_version.major == 10 and mariadb_version.minor == 5 and timezone.now() > timezone.datetime(year=2025, month=6, day=24, tzinfo=datetime.timezone.utc):
|
errors.append(
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A016"))
|
Error(
|
||||||
elif mariadb_version.major == 10 and mariadb_version.minor in [0, 1, 2, 3, 4, 7, 9, 10]: # Demote versions down here once EOL
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A017"))
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A014",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif mariadb_version.minor == 6 and timezone.now() > timezone.datetime(
|
||||||
|
year=2026, month=7, day=6, tzinfo=timezone.utc
|
||||||
|
):
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A0015",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
elif mariadb_version.minor == 5 and timezone.now() > timezone.datetime(
|
||||||
|
year=2025, month=6, day=24, tzinfo=timezone.utc
|
||||||
|
):
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A016",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
# Demote versions down here once EOL
|
||||||
|
elif mariadb_version.minor in [0, 1, 2, 3, 4, 7, 9, 10]:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"MariaDB {mariadb_version.public} EOL",
|
||||||
|
hint=mariadb_download_link,
|
||||||
|
id="allianceauth.checks.A017",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def system_package_sqlite(app_configs, **kwargs) -> list[CheckMessage]:
|
def system_package_sqlite(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
|
"""
|
||||||
|
Check that SQLite is a supported version
|
||||||
|
|
||||||
|
:param app_configs:
|
||||||
|
:type app_configs:
|
||||||
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
for connection in db.connections.all():
|
for connection in db.connections.all():
|
||||||
if connection.vendor == "sqlite":
|
if connection.vendor == "sqlite":
|
||||||
try:
|
try:
|
||||||
sqlite_version = Pep440Version(".".join(str(i) for i in sqlite_version_info))
|
sqlite_version = Pep440Version(
|
||||||
|
".".join(str(i) for i in sqlite_version_info)
|
||||||
|
)
|
||||||
except InvalidVersion:
|
except InvalidVersion:
|
||||||
errors.append(Warning("Unable to confirm SQLite Version"))
|
errors.append(Warning("Unable to confirm SQLite Version"))
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
if sqlite_version.major == 3 and sqlite_version.minor < 27:
|
if sqlite_version.major == 3 and sqlite_version.minor < 27:
|
||||||
errors.append(Error(f"SQLite {sqlite_version.public} Unsupported by Django", hint="https://pkgs.org/download/sqlite3", id="allianceauth.checks.A020"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"SQLite {sqlite_version.public} Unsupported by Django",
|
||||||
|
hint="https://pkgs.org/download/sqlite3",
|
||||||
|
id="allianceauth.checks.A020",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
@register()
|
@register()
|
||||||
def sql_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
def sql_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
|
"""
|
||||||
|
Check that SQL settings are correctly configured
|
||||||
|
|
||||||
|
:param app_configs:
|
||||||
|
:type app_configs:
|
||||||
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
for connection in db.connections.all():
|
for connection in db.connections.all():
|
||||||
if connection.vendor == "mysql":
|
if connection.vendor == "mysql":
|
||||||
try:
|
try:
|
||||||
if connection.settings_dict["OPTIONS"]["charset"] != "utf8mb4":
|
if connection.settings_dict["OPTIONS"]["charset"] != "utf8mb4":
|
||||||
errors.append(Error(f"SQL Charset is not set to utf8mb4 DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"SQL Charset is not set to utf8mb4 DB: {connection.alias}",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
||||||
|
id="allianceauth.checks.B001",
|
||||||
|
)
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
errors.append(Error(f"SQL Charset is not set to utf8mb4 DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg=f"SQL Charset is not set to utf8mb4 DB: {connection.alias}",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
||||||
|
id="allianceauth.checks.B001",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# This hasn't actually been set on AA yet
|
# This hasn't actually been set on AA yet
|
||||||
# try:
|
# try:
|
||||||
# if connection.settings_dict["OPTIONS"]["collation"] != "utf8mb4_unicode_ci":
|
# if (
|
||||||
# errors.append(Error(f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001"))
|
# connection.settings_dict["OPTIONS"]["collation"]
|
||||||
|
# != "utf8mb4_unicode_ci"
|
||||||
|
# ):
|
||||||
|
# errors.append(
|
||||||
|
# Error(
|
||||||
|
# msg=f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}",
|
||||||
|
# hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
||||||
|
# id="allianceauth.checks.B001",
|
||||||
|
# )
|
||||||
|
# )
|
||||||
# except KeyError:
|
# except KeyError:
|
||||||
# errors.append(Error(f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8", id="allianceauth.checks.B001"))
|
# errors.append(
|
||||||
|
# Error(
|
||||||
|
# msg=f"SQL Collation is not set to utf8mb4_unicode_ci DB:{connection.alias}",
|
||||||
|
# hint="https://gitlab.com/allianceauth/allianceauth/-/commit/89be2456fb2d741b86417e889da9b6129525bec8",
|
||||||
|
# id="allianceauth.checks.B001",
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
|
||||||
# if connection.vendor == "sqlite":
|
# if connection.vendor == "sqlite":
|
||||||
|
|
||||||
@ -152,19 +439,57 @@ def sql_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
|||||||
|
|
||||||
@register()
|
@register()
|
||||||
def celery_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
def celery_settings(app_configs, **kwargs) -> list[CheckMessage]:
|
||||||
|
"""
|
||||||
|
Check that Celery settings are correctly configured
|
||||||
|
|
||||||
|
:param app_configs:
|
||||||
|
:type app_configs:
|
||||||
|
:param kwargs:
|
||||||
|
:type kwargs:
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
|
||||||
errors: list[CheckMessage] = []
|
errors: list[CheckMessage] = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if current_app.conf.broker_transport_options != {'priority_steps': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 'queue_order_strategy': 'priority'}:
|
if current_app.conf.broker_transport_options != {
|
||||||
errors.append(Error("Celery Priorities are not set correctly", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc", id="allianceauth.checks.B003"))
|
"priority_steps": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
"queue_order_strategy": "priority",
|
||||||
|
}:
|
||||||
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="Celery Priorities are not set correctly",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc",
|
||||||
|
id="allianceauth.checks.B003",
|
||||||
|
)
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
errors.append(Error("Celery Priorities are not set", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc", id="allianceauth.checks.B003"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="Celery Priorities are not set",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/8861ec0a61790eca0261f1adc1cc04ca5f243cbc",
|
||||||
|
id="allianceauth.checks.B003",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if current_app.conf.broker_connection_retry_on_startup is not True:
|
if not current_app.conf.broker_connection_retry_on_startup:
|
||||||
errors.append(Error("Celery broker_connection_retry_on_startup not set correctly", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280", id="allianceauth.checks.B004"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="Celery broker_connection_retry_on_startup not set correctly",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280",
|
||||||
|
id="allianceauth.checks.B004",
|
||||||
|
)
|
||||||
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
errors.append(Error("Celery broker_connection_retry_on_startup not set", hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280", id="allianceauth.checks.B004"))
|
errors.append(
|
||||||
|
Error(
|
||||||
|
msg="Celery broker_connection_retry_on_startup not set",
|
||||||
|
hint="https://gitlab.com/allianceauth/allianceauth/-/commit/380c41400b535447839e5552df2410af35a75280",
|
||||||
|
id="allianceauth.checks.B004",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends 'corputils/base.html' %}
|
{% extends 'corputils/base.html' %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load humanize %}
|
{% load humanize %}
|
||||||
|
|
||||||
@ -238,9 +239,12 @@
|
|||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js-bs5.html' %}
|
{% include 'bundles/datatables-js-bs5.html' %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
$('#table-mains').DataTable({
|
$('#table-mains').DataTable({
|
||||||
|
"language": {"url": '{{ DT_LANG_PATH }}'},
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{ "sortable": false, "targets": [1] },
|
{ "sortable": false, "targets": [1] },
|
||||||
],
|
],
|
||||||
@ -249,6 +253,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#table-members').DataTable({
|
$('#table-members').DataTable({
|
||||||
|
"language": {"url": '{{ DT_LANG_PATH }}'},
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{ "searchable": false, "targets": [0, 2] },
|
{ "searchable": false, "targets": [0, 2] },
|
||||||
{ "sortable": false, "targets": [0, 2] },
|
{ "sortable": false, "targets": [0, 2] },
|
||||||
@ -259,6 +264,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$('#table-unregistered').DataTable({
|
$('#table-unregistered').DataTable({
|
||||||
|
"language": {"url": '{{ DT_LANG_PATH }}'},
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
{ "searchable": false, "targets": [0, 2] },
|
{ "searchable": false, "targets": [0, 2] },
|
||||||
{ "sortable": false, "targets": [0, 2] },
|
{ "sortable": false, "targets": [0, 2] },
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends "corputils/base.html" %}
|
{% extends "corputils/base.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block member_data %}
|
{% block member_data %}
|
||||||
@ -42,9 +43,12 @@
|
|||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js-bs5.html' %}
|
{% include 'bundles/datatables-js-bs5.html' %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
$('#table-search').DataTable({
|
$('#table-search').DataTable({
|
||||||
|
"language": {"url": '{{ DT_LANG_PATH }}'},
|
||||||
"stateSave": true,
|
"stateSave": true,
|
||||||
"stateDuration": 0
|
"stateDuration": 0
|
||||||
});
|
});
|
||||||
|
3
allianceauth/crontab/__init__.py
Normal file
3
allianceauth/crontab/__init__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
"""
|
||||||
|
Alliance Auth Crontab Utilities
|
||||||
|
"""
|
14
allianceauth/crontab/apps.py
Normal file
14
allianceauth/crontab/apps.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
"""
|
||||||
|
Crontab App Config
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class CrontabConfig(AppConfig):
|
||||||
|
"""
|
||||||
|
Crontab App Config
|
||||||
|
"""
|
||||||
|
|
||||||
|
name = "allianceauth.crontab"
|
||||||
|
label = "crontab"
|
30
allianceauth/crontab/migrations/0001_initial.py
Normal file
30
allianceauth/crontab/migrations/0001_initial.py
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2025-01-20 06:16
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
import allianceauth.crontab.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CronOffset',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('minute', models.FloatField(default=allianceauth.crontab.models.random_default, verbose_name='Minute Offset')),
|
||||||
|
('hour', models.FloatField(default=allianceauth.crontab.models.random_default, verbose_name='Hour Offset')),
|
||||||
|
('day_of_month', models.FloatField(default=allianceauth.crontab.models.random_default, verbose_name='Day of Month Offset')),
|
||||||
|
('month_of_year', models.FloatField(default=allianceauth.crontab.models.random_default, verbose_name='Month of Year Offset')),
|
||||||
|
('day_of_week', models.FloatField(default=allianceauth.crontab.models.random_default, verbose_name='Day of Week Offset')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'Cron Offsets',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
0
allianceauth/crontab/migrations/__init__.py
Normal file
0
allianceauth/crontab/migrations/__init__.py
Normal file
25
allianceauth/crontab/models.py
Normal file
25
allianceauth/crontab/models.py
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
from random import random
|
||||||
|
|
||||||
|
from solo.models import SingletonModel
|
||||||
|
|
||||||
|
from django.db import models
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
def random_default() -> float:
|
||||||
|
return random()
|
||||||
|
|
||||||
|
|
||||||
|
class CronOffset(SingletonModel):
|
||||||
|
|
||||||
|
minute = models.FloatField(_("Minute Offset"), default=random_default)
|
||||||
|
hour = models.FloatField(_("Hour Offset"), default=random_default)
|
||||||
|
day_of_month = models.FloatField(_("Day of Month Offset"), default=random_default)
|
||||||
|
month_of_year = models.FloatField(_("Month of Year Offset"), default=random_default)
|
||||||
|
day_of_week = models.FloatField(_("Day of Week Offset"), default=random_default)
|
||||||
|
|
||||||
|
def __str__(self) -> str:
|
||||||
|
return "Cron Offsets"
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "Cron Offsets"
|
68
allianceauth/crontab/schedulers.py
Normal file
68
allianceauth/crontab/schedulers.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
from celery import schedules
|
||||||
|
from celery.utils.log import get_logger
|
||||||
|
from django_celery_beat.models import CrontabSchedule
|
||||||
|
from django_celery_beat.schedulers import DatabaseScheduler
|
||||||
|
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
from django.db.utils import OperationalError, ProgrammingError
|
||||||
|
|
||||||
|
from allianceauth.crontab.models import CronOffset
|
||||||
|
from allianceauth.crontab.utils import offset_cron
|
||||||
|
|
||||||
|
logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class OffsetDatabaseScheduler(DatabaseScheduler):
|
||||||
|
"""
|
||||||
|
Customization of Django Celery Beat, Database Scheduler
|
||||||
|
Takes the Celery Schedule from local.py and applies our AA Framework Cron Offset, if apply_offset is true
|
||||||
|
Otherwise it passes it through as normal
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs) -> None:
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def update_from_dict(self, mapping):
|
||||||
|
s = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
cron_offset = CronOffset.get_solo() # noqa: F841
|
||||||
|
except (OperationalError, ProgrammingError, ObjectDoesNotExist) as exc:
|
||||||
|
# This is just incase we haven't migrated yet or something
|
||||||
|
logger.warning(
|
||||||
|
"OffsetDatabaseScheduler: Could not fetch CronOffset (%r). "
|
||||||
|
"Defering to DatabaseScheduler",
|
||||||
|
exc
|
||||||
|
)
|
||||||
|
return super().update_from_dict(mapping)
|
||||||
|
|
||||||
|
for name, entry_fields in mapping.items():
|
||||||
|
try:
|
||||||
|
apply_offset = entry_fields.pop("apply_offset", False) # Ensure this pops before django tries to save to ORM
|
||||||
|
entry = self.Entry.from_entry(name, app=self.app, **entry_fields)
|
||||||
|
|
||||||
|
if apply_offset:
|
||||||
|
entry_fields.update({"apply_offset": apply_offset}) # Reapply this as its gets pulled from config inconsistently.
|
||||||
|
schedule_obj = entry.schedule
|
||||||
|
if isinstance(schedule_obj, schedules.crontab):
|
||||||
|
offset_cs = CrontabSchedule.from_schedule(offset_cron(schedule_obj))
|
||||||
|
offset_cs, created = CrontabSchedule.objects.get_or_create(
|
||||||
|
minute=offset_cs.minute,
|
||||||
|
hour=offset_cs.hour,
|
||||||
|
day_of_month=offset_cs.day_of_month,
|
||||||
|
month_of_year=offset_cs.month_of_year,
|
||||||
|
day_of_week=offset_cs.day_of_week,
|
||||||
|
timezone=offset_cs.timezone,
|
||||||
|
)
|
||||||
|
entry.schedule = offset_cron(schedule_obj) # This gets passed into Celery Beats Memory, important to keep it in sync with the model/DB
|
||||||
|
entry.model.crontab = offset_cs
|
||||||
|
entry.model.save()
|
||||||
|
logger.debug(f"Offset applied for '{name}' due to 'apply_offset' = True.")
|
||||||
|
|
||||||
|
if entry.model.enabled:
|
||||||
|
s[name] = entry
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception("Error updating schedule for %s: %r", name, e)
|
||||||
|
|
||||||
|
self.schedule.update(s)
|
0
allianceauth/crontab/tests/__init__.py
Normal file
0
allianceauth/crontab/tests/__init__.py
Normal file
64
allianceauth/crontab/tests/test_models.py
Normal file
64
allianceauth/crontab/tests/test_models.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from allianceauth.crontab.models import CronOffset
|
||||||
|
|
||||||
|
|
||||||
|
class CronOffsetModelTest(TestCase):
|
||||||
|
def test_cron_offset_is_singleton(self):
|
||||||
|
"""
|
||||||
|
Test that CronOffset is indeed a singleton and that
|
||||||
|
multiple calls to get_solo() return the same instance.
|
||||||
|
"""
|
||||||
|
offset1 = CronOffset.get_solo()
|
||||||
|
offset2 = CronOffset.get_solo()
|
||||||
|
|
||||||
|
# They should be the exact same object in memory
|
||||||
|
self.assertEqual(offset1.pk, offset2.pk)
|
||||||
|
|
||||||
|
def test_default_values_random(self):
|
||||||
|
"""
|
||||||
|
Test that the default values are set via random_default() when
|
||||||
|
no explicit value is provided. We'll patch 'random.random' to
|
||||||
|
produce predictable output.
|
||||||
|
"""
|
||||||
|
with patch('allianceauth.crontab.models.random', return_value=0.1234):
|
||||||
|
# Force creation of a new CronOffset by clearing the existing one
|
||||||
|
CronOffset.objects.all().delete()
|
||||||
|
|
||||||
|
offset = CronOffset.get_solo() # This triggers creation
|
||||||
|
|
||||||
|
# All fields should be 0.1234, because we patched random()
|
||||||
|
self.assertAlmostEqual(offset.minute, 0.1234)
|
||||||
|
self.assertAlmostEqual(offset.hour, 0.1234)
|
||||||
|
self.assertAlmostEqual(offset.day_of_month, 0.1234)
|
||||||
|
self.assertAlmostEqual(offset.month_of_year, 0.1234)
|
||||||
|
self.assertAlmostEqual(offset.day_of_week, 0.1234)
|
||||||
|
|
||||||
|
def test_update_offset_values(self):
|
||||||
|
"""
|
||||||
|
Test that we can update the offsets and retrieve them.
|
||||||
|
"""
|
||||||
|
offset = CronOffset.get_solo()
|
||||||
|
offset.minute = 0.5
|
||||||
|
offset.hour = 0.25
|
||||||
|
offset.day_of_month = 0.75
|
||||||
|
offset.month_of_year = 0.99
|
||||||
|
offset.day_of_week = 0.33
|
||||||
|
offset.save()
|
||||||
|
|
||||||
|
# Retrieve again to ensure changes persist
|
||||||
|
saved_offset = CronOffset.get_solo()
|
||||||
|
self.assertEqual(saved_offset.minute, 0.5)
|
||||||
|
self.assertEqual(saved_offset.hour, 0.25)
|
||||||
|
self.assertEqual(saved_offset.day_of_month, 0.75)
|
||||||
|
self.assertEqual(saved_offset.month_of_year, 0.99)
|
||||||
|
self.assertEqual(saved_offset.day_of_week, 0.33)
|
||||||
|
|
||||||
|
def test_str_representation(self):
|
||||||
|
"""
|
||||||
|
Verify the __str__ method returns 'Cron Offsets'.
|
||||||
|
"""
|
||||||
|
offset = CronOffset.get_solo()
|
||||||
|
self.assertEqual(str(offset), "Cron Offsets")
|
82
allianceauth/crontab/tests/test_utils.py
Normal file
82
allianceauth/crontab/tests/test_utils.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
# myapp/tests/test_tasks.py
|
||||||
|
|
||||||
|
import logging
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from celery.schedules import crontab
|
||||||
|
|
||||||
|
from django.db import ProgrammingError
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from allianceauth.crontab.models import CronOffset
|
||||||
|
from allianceauth.crontab.utils import offset_cron
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class TestOffsetCron(TestCase):
|
||||||
|
|
||||||
|
def test_offset_cron_normal(self):
|
||||||
|
"""
|
||||||
|
Test that offset_cron modifies the minute/hour fields
|
||||||
|
based on the CronOffset values when everything is normal.
|
||||||
|
"""
|
||||||
|
# We'll create a mock CronOffset instance
|
||||||
|
mock_offset = CronOffset(minute=0.5, hour=0.5)
|
||||||
|
|
||||||
|
# Our initial crontab schedule
|
||||||
|
original_schedule = crontab(
|
||||||
|
minute=[0, 5, 55],
|
||||||
|
hour=[0, 3, 23],
|
||||||
|
day_of_month='*',
|
||||||
|
month_of_year='*',
|
||||||
|
day_of_week='*'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Patch CronOffset.get_solo to return our mock offset
|
||||||
|
with patch('allianceauth.crontab.models.CronOffset.get_solo', return_value=mock_offset):
|
||||||
|
new_schedule = offset_cron(original_schedule)
|
||||||
|
|
||||||
|
# Check the new minute/hour
|
||||||
|
# minute 0 -> 0 + round(60 * 0.5) = 30 % 60 = 30
|
||||||
|
# minute 5 -> 5 + 30 = 35 % 60 = 35
|
||||||
|
# minute 55 -> 55 + 30 = 85 % 60 = 25 --> sorted => 25,30,35
|
||||||
|
self.assertEqual(new_schedule._orig_minute, '25,30,35')
|
||||||
|
|
||||||
|
# hour 0 -> 0 + round(24 * 0.5) = 12 % 24 = 12
|
||||||
|
# hour 3 -> 3 + 12 = 15 % 24 = 15
|
||||||
|
# hour 23 -> 23 + 12 = 35 % 24 = 11 --> sorted => 11,12,15
|
||||||
|
self.assertEqual(new_schedule._orig_hour, '11,12,15')
|
||||||
|
|
||||||
|
# Check that other fields are unchanged
|
||||||
|
self.assertEqual(new_schedule._orig_day_of_month, '*')
|
||||||
|
self.assertEqual(new_schedule._orig_month_of_year, '*')
|
||||||
|
self.assertEqual(new_schedule._orig_day_of_week, '*')
|
||||||
|
|
||||||
|
def test_offset_cron_programming_error(self):
|
||||||
|
"""
|
||||||
|
Test that if a ProgrammingError is raised (e.g. before migrations),
|
||||||
|
offset_cron just returns the original schedule.
|
||||||
|
"""
|
||||||
|
original_schedule = crontab(minute=[0, 15, 30], hour=[1, 2, 3])
|
||||||
|
|
||||||
|
# Force get_solo to raise ProgrammingError
|
||||||
|
with patch('allianceauth.crontab.models.CronOffset.get_solo', side_effect=ProgrammingError()):
|
||||||
|
new_schedule = offset_cron(original_schedule)
|
||||||
|
|
||||||
|
# Should return the original schedule unchanged
|
||||||
|
self.assertEqual(new_schedule, original_schedule)
|
||||||
|
|
||||||
|
def test_offset_cron_unexpected_exception(self):
|
||||||
|
"""
|
||||||
|
Test that if any other exception is raised, offset_cron
|
||||||
|
also returns the original schedule, and logs the error.
|
||||||
|
"""
|
||||||
|
original_schedule = crontab(minute='0', hour='0')
|
||||||
|
|
||||||
|
# Force get_solo to raise a generic Exception
|
||||||
|
with patch('allianceauth.crontab.models.CronOffset.get_solo', side_effect=Exception("Something bad")):
|
||||||
|
new_schedule = offset_cron(original_schedule)
|
||||||
|
|
||||||
|
# Should return the original schedule unchanged
|
||||||
|
self.assertEqual(new_schedule, original_schedule)
|
52
allianceauth/crontab/utils.py
Normal file
52
allianceauth/crontab/utils.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import logging
|
||||||
|
|
||||||
|
from celery.schedules import crontab
|
||||||
|
|
||||||
|
from django.db import ProgrammingError
|
||||||
|
|
||||||
|
from allianceauth.crontab.models import CronOffset
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def offset_cron(schedule: crontab) -> crontab:
|
||||||
|
"""Take a crontab and apply a series of precalculated offsets to spread out tasks execution on remote resources
|
||||||
|
|
||||||
|
Args:
|
||||||
|
schedule (crontab): celery.schedules.crontab()
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
crontab: A crontab with offsetted Minute and Hour fields
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
cron_offset = CronOffset.get_solo()
|
||||||
|
|
||||||
|
# Stops this shit from happening 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23
|
||||||
|
# It is only cosmetic, but still annoying
|
||||||
|
if schedule._orig_minute == '*':
|
||||||
|
new_minute = '*'
|
||||||
|
else:
|
||||||
|
new_minute = [(m + (round(60 * cron_offset.minute))) % 60 for m in schedule.minute]
|
||||||
|
if schedule._orig_hour == '*':
|
||||||
|
new_hour = '*'
|
||||||
|
else:
|
||||||
|
new_hour = [(m + (round(24 * cron_offset.hour))) % 24 for m in schedule.hour]
|
||||||
|
|
||||||
|
return crontab(
|
||||||
|
minute=",".join(str(m) for m in sorted(new_minute)),
|
||||||
|
hour=",".join(str(h) for h in sorted(new_hour)),
|
||||||
|
day_of_month=schedule._orig_day_of_month,
|
||||||
|
month_of_year=schedule._orig_month_of_year,
|
||||||
|
day_of_week=schedule._orig_day_of_week)
|
||||||
|
|
||||||
|
except ProgrammingError as e:
|
||||||
|
# If this is called before migrations are run hand back the default schedule
|
||||||
|
# These offsets are stored in a Singleton Model,
|
||||||
|
logger.error(e)
|
||||||
|
return schedule
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# We absolutely cant fail to hand back a schedule
|
||||||
|
logger.error(e)
|
||||||
|
return schedule
|
@ -4,7 +4,7 @@ from urllib.parse import quote, urljoin
|
|||||||
|
|
||||||
from . import _ESI_CATEGORY_ALLIANCE, _ESI_CATEGORY_CORPORATION, _ESI_CATEGORY_REGION, _ESI_CATEGORY_SOLARSYSTEM
|
from . import _ESI_CATEGORY_ALLIANCE, _ESI_CATEGORY_CORPORATION, _ESI_CATEGORY_REGION, _ESI_CATEGORY_SOLARSYSTEM
|
||||||
|
|
||||||
_BASE_URL = 'http://evemaps.dotlan.net'
|
_BASE_URL = 'https://evemaps.dotlan.net'
|
||||||
|
|
||||||
|
|
||||||
def _build_url(category: str, name: str) -> str:
|
def _build_url(category: str, name: str) -> str:
|
||||||
|
@ -29,29 +29,29 @@ class TestDotlan(TestCase):
|
|||||||
def test_alliance_url(self):
|
def test_alliance_url(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
dotlan.alliance_url('Wayne Enterprices'),
|
dotlan.alliance_url('Wayne Enterprices'),
|
||||||
'http://evemaps.dotlan.net/alliance/Wayne_Enterprices'
|
'https://evemaps.dotlan.net/alliance/Wayne_Enterprices'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_corporation_url(self):
|
def test_corporation_url(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
dotlan.corporation_url('Wayne Technology'),
|
dotlan.corporation_url('Wayne Technology'),
|
||||||
'http://evemaps.dotlan.net/corp/Wayne_Technology'
|
'https://evemaps.dotlan.net/corp/Wayne_Technology'
|
||||||
)
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
dotlan.corporation_url('Crédit Agricole'),
|
dotlan.corporation_url('Crédit Agricole'),
|
||||||
'http://evemaps.dotlan.net/corp/Cr%C3%A9dit_Agricole'
|
'https://evemaps.dotlan.net/corp/Cr%C3%A9dit_Agricole'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_region_url(self):
|
def test_region_url(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
dotlan.region_url('Black Rise'),
|
dotlan.region_url('Black Rise'),
|
||||||
'http://evemaps.dotlan.net/map/Black_Rise'
|
'https://evemaps.dotlan.net/map/Black_Rise'
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_solar_system_url(self):
|
def test_solar_system_url(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
dotlan.solar_system_url('Jita'),
|
dotlan.solar_system_url('Jita'),
|
||||||
'http://evemaps.dotlan.net/system/Jita'
|
'https://evemaps.dotlan.net/system/Jita'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from random import randint
|
||||||
|
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
|
|
||||||
@ -8,7 +9,8 @@ from .models import EveAllianceInfo, EveCharacter, EveCorporationInfo
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
TASK_PRIORITY = 7
|
TASK_PRIORITY = 7
|
||||||
CHUNK_SIZE = 500
|
CHARACTER_AFFILIATION_CHUNK_SIZE = 500
|
||||||
|
EVEONLINE_TASK_JITTER = 600
|
||||||
|
|
||||||
|
|
||||||
def chunks(lst, n):
|
def chunks(lst, n):
|
||||||
@ -18,13 +20,13 @@ def chunks(lst, n):
|
|||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def update_corp(corp_id):
|
def update_corp(corp_id: int) -> None:
|
||||||
"""Update given corporation from ESI"""
|
"""Update given corporation from ESI"""
|
||||||
EveCorporationInfo.objects.update_corporation(corp_id)
|
EveCorporationInfo.objects.update_corporation(corp_id)
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def update_alliance(alliance_id):
|
def update_alliance(alliance_id: int) -> None:
|
||||||
"""Update given alliance from ESI"""
|
"""Update given alliance from ESI"""
|
||||||
EveAllianceInfo.objects.update_alliance(alliance_id).populate_alliance()
|
EveAllianceInfo.objects.update_alliance(alliance_id).populate_alliance()
|
||||||
|
|
||||||
@ -36,23 +38,30 @@ def update_character(character_id: int) -> None:
|
|||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
def run_model_update():
|
def run_model_update() -> None:
|
||||||
"""Update all alliances, corporations and characters from ESI"""
|
"""Update all alliances, corporations and characters from ESI"""
|
||||||
|
|
||||||
#update existing corp models
|
# Queue update tasks for Known Corporation Models
|
||||||
for corp in EveCorporationInfo.objects.all().values('corporation_id'):
|
for corp in EveCorporationInfo.objects.all().values('corporation_id'):
|
||||||
update_corp.apply_async(args=[corp['corporation_id']], priority=TASK_PRIORITY)
|
update_corp.apply_async(
|
||||||
|
args=[corp['corporation_id']],
|
||||||
|
priority=TASK_PRIORITY,
|
||||||
|
countdown=randint(1, EVEONLINE_TASK_JITTER))
|
||||||
|
|
||||||
# update existing alliance models
|
# Queue update tasks for Known Alliance Models
|
||||||
for alliance in EveAllianceInfo.objects.all().values('alliance_id'):
|
for alliance in EveAllianceInfo.objects.all().values('alliance_id'):
|
||||||
update_alliance.apply_async(args=[alliance['alliance_id']], priority=TASK_PRIORITY)
|
update_alliance.apply_async(
|
||||||
|
args=[alliance['alliance_id']],
|
||||||
|
priority=TASK_PRIORITY,
|
||||||
|
countdown=randint(1, EVEONLINE_TASK_JITTER))
|
||||||
|
|
||||||
# update existing character models
|
# Queue update tasks for Known Character Models
|
||||||
character_ids = EveCharacter.objects.all().values_list('character_id', flat=True)
|
character_ids = EveCharacter.objects.all().values_list('character_id', flat=True)
|
||||||
for character_ids_chunk in chunks(character_ids, CHUNK_SIZE):
|
for character_ids_chunk in chunks(character_ids, CHARACTER_AFFILIATION_CHUNK_SIZE):
|
||||||
update_character_chunk.apply_async(
|
update_character_chunk.apply_async(
|
||||||
args=[character_ids_chunk], priority=TASK_PRIORITY
|
args=[character_ids_chunk],
|
||||||
)
|
priority=TASK_PRIORITY,
|
||||||
|
countdown=randint(1, EVEONLINE_TASK_JITTER))
|
||||||
|
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
@ -67,8 +76,9 @@ def update_character_chunk(character_ids_chunk: list):
|
|||||||
logger.info("Failed to bulk update characters. Attempting single updates")
|
logger.info("Failed to bulk update characters. Attempting single updates")
|
||||||
for character_id in character_ids_chunk:
|
for character_id in character_ids_chunk:
|
||||||
update_character.apply_async(
|
update_character.apply_async(
|
||||||
args=[character_id], priority=TASK_PRIORITY
|
args=[character_id],
|
||||||
)
|
priority=TASK_PRIORITY,
|
||||||
|
countdown=randint(1, EVEONLINE_TASK_JITTER))
|
||||||
return
|
return
|
||||||
|
|
||||||
affiliations = {
|
affiliations = {
|
||||||
@ -106,5 +116,5 @@ def update_character_chunk(character_ids_chunk: list):
|
|||||||
|
|
||||||
if corp_changed or alliance_changed or name_changed:
|
if corp_changed or alliance_changed or name_changed:
|
||||||
update_character.apply_async(
|
update_character.apply_async(
|
||||||
args=[character.get('character_id')], priority=TASK_PRIORITY
|
args=[character.get('character_id')],
|
||||||
)
|
priority=TASK_PRIORITY)
|
||||||
|
@ -723,5 +723,5 @@ class TestEveSwaggerProvider(TestCase):
|
|||||||
my_client = my_provider.client
|
my_client = my_provider.client
|
||||||
operation = my_client.Universe.get_universe_factions()
|
operation = my_client.Universe.get_universe_factions()
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
operation.future.request.headers['User-Agent'], 'allianceauth v1.0.0'
|
operation.future.request.headers['User-Agent'], 'allianceauth v1.0.0 dummy@example.net'
|
||||||
)
|
)
|
||||||
|
@ -84,7 +84,7 @@ class TestUpdateTasks(TestCase):
|
|||||||
@override_settings(CELERY_ALWAYS_EAGER=True)
|
@override_settings(CELERY_ALWAYS_EAGER=True)
|
||||||
@patch('allianceauth.eveonline.providers.esi_client_factory')
|
@patch('allianceauth.eveonline.providers.esi_client_factory')
|
||||||
@patch('allianceauth.eveonline.tasks.providers')
|
@patch('allianceauth.eveonline.tasks.providers')
|
||||||
@patch('allianceauth.eveonline.tasks.CHUNK_SIZE', 2)
|
@patch('allianceauth.eveonline.tasks.CHARACTER_AFFILIATION_CHUNK_SIZE', 2)
|
||||||
class TestRunModelUpdate(TransactionTestCase):
|
class TestRunModelUpdate(TransactionTestCase):
|
||||||
def test_should_run_updates(self, mock_providers, mock_esi_client_factory):
|
def test_should_run_updates(self, mock_providers, mock_esi_client_factory):
|
||||||
# given
|
# given
|
||||||
@ -139,7 +139,7 @@ class TestRunModelUpdate(TransactionTestCase):
|
|||||||
@patch('allianceauth.eveonline.tasks.update_character', wraps=update_character)
|
@patch('allianceauth.eveonline.tasks.update_character', wraps=update_character)
|
||||||
@patch('allianceauth.eveonline.providers.esi_client_factory')
|
@patch('allianceauth.eveonline.providers.esi_client_factory')
|
||||||
@patch('allianceauth.eveonline.tasks.providers')
|
@patch('allianceauth.eveonline.tasks.providers')
|
||||||
@patch('allianceauth.eveonline.tasks.CHUNK_SIZE', 2)
|
@patch('allianceauth.eveonline.tasks.CHARACTER_AFFILIATION_CHUNK_SIZE', 2)
|
||||||
class TestUpdateCharacterChunk(TestCase):
|
class TestUpdateCharacterChunk(TestCase):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _updated_character_ids(spy_update_character) -> set:
|
def _updated_character_ids(spy_update_character) -> set:
|
||||||
|
@ -13,6 +13,15 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Image overflow fix
|
||||||
|
------------------------------------------------------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Side Navigation
|
/* Side Navigation
|
||||||
------------------------------------------------------------------------------------- */
|
------------------------------------------------------------------------------------- */
|
||||||
@media all {
|
@media all {
|
||||||
@ -40,14 +49,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Chevron icons */
|
/* Chevron icons */
|
||||||
#sidebar-menu [data-bs-toggle="collapse"] > i.fa-chevron-down,
|
#sidebar-menu span[data-bs-toggle="collapse"][aria-expanded="true"] > i.fa-chevron-down,
|
||||||
#sidebar-menu [data-bs-toggle="collapse"].collapsed > i.fa-chevron-right {
|
#sidebar-menu span[data-bs-toggle="collapse"][aria-expanded="false"] > i.fa-chevron-right {
|
||||||
display: block;
|
display: block;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar-menu [data-bs-toggle="collapse"] > i.fa-chevron-right,
|
#sidebar-menu span[data-bs-toggle="collapse"][aria-expanded="true"] > i.fa-chevron-right,
|
||||||
#sidebar-menu [data-bs-toggle="collapse"].collapsed > i.fa-chevron-down {
|
#sidebar-menu span[data-bs-toggle="collapse"][aria-expanded="false"] > i.fa-chevron-down {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ class GroupsMenuItem(MenuItemHook):
|
|||||||
MenuItemHook.__init__(
|
MenuItemHook.__init__(
|
||||||
self,
|
self,
|
||||||
text=_("Groups"),
|
text=_("Groups"),
|
||||||
classes="fa-solid fa-user",
|
classes="fa-solid fa-users",
|
||||||
url_name="groupmanagement:groups",
|
url_name="groupmanagement:groups",
|
||||||
order=25,
|
order=25,
|
||||||
navactive=[
|
navactive=[
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load navactive %}
|
{% load navactive %}
|
||||||
@ -73,6 +74,8 @@
|
|||||||
{% include 'bundles/moment-js.html' with locale=True %}
|
{% include 'bundles/moment-js.html' with locale=True %}
|
||||||
{% include 'bundles/filterdropdown-js.html' %}
|
{% include 'bundles/filterdropdown-js.html' %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$.fn.dataTable.moment = (format, locale) => {
|
$.fn.dataTable.moment = (format, locale) => {
|
||||||
const types = $.fn.dataTable.ext.type;
|
const types = $.fn.dataTable.ext.type;
|
||||||
@ -94,6 +97,7 @@
|
|||||||
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
$.fn.dataTable.moment('YYYY-MMM-D, HH:mm');
|
||||||
|
|
||||||
$('#log-entries').DataTable({
|
$('#log-entries').DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
order: [[0, 'desc'], [1, 'asc']],
|
order: [[0, 'desc'], [1, 'asc']],
|
||||||
filterDropDown:
|
filterDropDown:
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load evelinks %}
|
{% load evelinks %}
|
||||||
{% load navactive %}
|
{% load navactive %}
|
||||||
@ -86,9 +87,12 @@
|
|||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js-bs5.html' %}
|
{% include 'bundles/datatables-js-bs5.html' %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
$('#tab_group_members').DataTable({
|
$('#tab_group_members').DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
order: [[0, "asc"]],
|
order: [[0, "asc"]],
|
||||||
columnDefs: [
|
columnDefs: [
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
@ -56,7 +57,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if g.group.authgroup.group_leaders.all.count %}
|
{% if g.group.authgroup.group_leader_groups.all.count %}
|
||||||
{% for group in g.group.authgroup.group_leader_groups.all %}
|
{% for group in g.group.authgroup.group_leader_groups.all %}
|
||||||
<span class="my-1 me-1 badge bg-secondary">{{group.name}}</span>
|
<span class="my-1 me-1 badge bg-secondary">{{group.name}}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -103,9 +104,13 @@
|
|||||||
{% block extra_javascript %}
|
{% block extra_javascript %}
|
||||||
{% include 'bundles/datatables-js-bs5.html' %}
|
{% include 'bundles/datatables-js-bs5.html' %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
$('#groupsTable').DataTable();
|
$('#groupsTable').DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -11,8 +11,8 @@
|
|||||||
data-bs-target="#{{ item.html_id }}"
|
data-bs-target="#{{ item.html_id }}"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-controls=""
|
aria-controls=""
|
||||||
{% endif %}>
|
{% endif %}
|
||||||
</i>
|
></i>
|
||||||
<a
|
<a
|
||||||
class="nav-link flex-fill align-self-center me-auto {% if item.navactive %}{% navactive request item.navactive|join:' ' %}{% endif %}"
|
class="nav-link flex-fill align-self-center me-auto {% if item.navactive %}{% navactive request item.navactive|join:' ' %}{% endif %}"
|
||||||
{% if item.is_folder %}
|
{% if item.is_folder %}
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
{% if item.is_folder %}
|
{% if item.is_folder %}
|
||||||
<span
|
<span
|
||||||
class="pill m-2 align-self-center collapsed"
|
class="pill m-2 align-self-center"
|
||||||
type="button"
|
type="button"
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#{{ item.html_id }}"
|
data-bs-target="#{{ item.html_id }}"
|
||||||
|
@ -1 +1,21 @@
|
|||||||
|
"""
|
||||||
|
Example
|
||||||
|
-------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from allianceauth.notifications.models import Notification
|
||||||
|
|
||||||
|
|
||||||
|
def notify_user_view(request):
|
||||||
|
'''Simple view sending a notification to the user'''
|
||||||
|
|
||||||
|
Notification.objects.notify_user(
|
||||||
|
user=request.user,
|
||||||
|
title="Some title",
|
||||||
|
message="Some message",
|
||||||
|
level=Notification.Level.INFO,
|
||||||
|
)
|
||||||
|
|
||||||
|
"""
|
||||||
from .core import notify # noqa: F401
|
from .core import notify # noqa: F401
|
||||||
|
@ -15,7 +15,7 @@ class OpForm(forms.Form):
|
|||||||
operation_name = forms.CharField(max_length=254, required=True, label=_("Operation Name"))
|
operation_name = forms.CharField(max_length=254, required=True, label=_("Operation Name"))
|
||||||
type = forms.CharField(required=False, label=_("Operation Type"))
|
type = forms.CharField(required=False, label=_("Operation Type"))
|
||||||
fc = forms.CharField(max_length=254, required=True, label=_("Fleet Commander"))
|
fc = forms.CharField(max_length=254, required=True, label=_("Fleet Commander"))
|
||||||
duration = forms.CharField(max_length=254, required=True, label=_("Duration"))
|
duration = forms.CharField(max_length=25, required=True, label=_("Duration"))
|
||||||
description = forms.CharField(
|
description = forms.CharField(
|
||||||
widget=forms.Textarea(attrs={"rows": 10, "cols": 20, "input_type": "textarea"}),
|
widget=forms.Textarea(attrs={"rows": 10, "cols": 20, "input_type": "textarea"}),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
@ -57,11 +58,14 @@
|
|||||||
{% include "bundles/datatables-js-bs5.html" %}
|
{% include "bundles/datatables-js-bs5.html" %}
|
||||||
{% include "bundles/filterdropdown-js.html" %}
|
{% include "bundles/filterdropdown-js.html" %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
const groupColumn = 0;
|
const groupColumn = 0;
|
||||||
|
|
||||||
$('#tab_permissions_audit').DataTable({
|
$('#tab_permissions_audit').DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
columnDefs: [{
|
columnDefs: [{
|
||||||
"visible": false,
|
"visible": false,
|
||||||
"targets": groupColumn
|
"targets": groupColumn
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
@ -62,11 +63,14 @@
|
|||||||
{% include "bundles/datatables-js-bs5.html" %}
|
{% include "bundles/datatables-js-bs5.html" %}
|
||||||
{% include "bundles/filterdropdown-js.html" %}
|
{% include "bundles/filterdropdown-js.html" %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(() => {
|
$(document).ready(() => {
|
||||||
const groupColumn = 0;
|
const groupColumn = 0;
|
||||||
|
|
||||||
$('#tab_permissions_overview').DataTable({
|
$('#tab_permissions_overview').DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
columnDefs: [{
|
columnDefs: [{
|
||||||
"visible": false,
|
"visible": false,
|
||||||
"targets": groupColumn
|
"targets": groupColumn
|
||||||
|
@ -42,13 +42,16 @@ INSTALLED_APPS = [
|
|||||||
'allianceauth.theme.flatly',
|
'allianceauth.theme.flatly',
|
||||||
'allianceauth.theme.materia',
|
'allianceauth.theme.materia',
|
||||||
"allianceauth.custom_css",
|
"allianceauth.custom_css",
|
||||||
|
'allianceauth.crontab',
|
||||||
|
'sri',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
SRI_ALGORITHM = "sha512"
|
||||||
SECRET_KEY = "wow I'm a really bad default secret key"
|
SECRET_KEY = "wow I'm a really bad default secret key"
|
||||||
|
|
||||||
# Celery configuration
|
# Celery configuration
|
||||||
BROKER_URL = 'redis://localhost:6379/0'
|
BROKER_URL = 'redis://localhost:6379/0'
|
||||||
CELERYBEAT_SCHEDULER = "django_celery_beat.schedulers.DatabaseScheduler"
|
CELERYBEAT_SCHEDULER = "allianceauth.crontab.schedulers.OffsetDatabaseScheduler"
|
||||||
CELERYBEAT_SCHEDULE = {
|
CELERYBEAT_SCHEDULE = {
|
||||||
'esi_cleanup_callbackredirect': {
|
'esi_cleanup_callbackredirect': {
|
||||||
'task': 'esi.tasks.cleanup_callbackredirect',
|
'task': 'esi.tasks.cleanup_callbackredirect',
|
||||||
@ -61,10 +64,12 @@ CELERYBEAT_SCHEDULE = {
|
|||||||
'run_model_update': {
|
'run_model_update': {
|
||||||
'task': 'allianceauth.eveonline.tasks.run_model_update',
|
'task': 'allianceauth.eveonline.tasks.run_model_update',
|
||||||
'schedule': crontab(minute='0', hour="*/6"),
|
'schedule': crontab(minute='0', hour="*/6"),
|
||||||
|
'apply_offset': True
|
||||||
},
|
},
|
||||||
'check_all_character_ownership': {
|
'check_all_character_ownership': {
|
||||||
'task': 'allianceauth.authentication.tasks.check_all_character_ownership',
|
'task': 'allianceauth.authentication.tasks.check_all_character_ownership',
|
||||||
'schedule': crontab(minute='0', hour='*/4'),
|
'schedule': crontab(minute='0', hour='*/4'),
|
||||||
|
'apply_offset': True
|
||||||
},
|
},
|
||||||
'analytics_daily_stats': {
|
'analytics_daily_stats': {
|
||||||
'task': 'allianceauth.analytics.tasks.analytics_daily_stats',
|
'task': 'allianceauth.analytics.tasks.analytics_daily_stats',
|
||||||
@ -72,6 +77,7 @@ CELERYBEAT_SCHEDULE = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
BASE_DIR = os.path.dirname(PROJECT_DIR)
|
BASE_DIR = os.path.dirname(PROJECT_DIR)
|
||||||
@ -110,6 +116,46 @@ LANGUAGES = ( # Sorted by Language Code alphabetical order + English at top
|
|||||||
("zh-hans", _("Simplified Chinese")),
|
("zh-hans", _("Simplified Chinese")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Django's language codes are different from some of the libraries we use,
|
||||||
|
# so we need to map them.
|
||||||
|
# When adding a new language, please remember to add it to the mapping
|
||||||
|
# and add the language files to their respective directories under `allianceauth/static/allianceauth/libs/`.
|
||||||
|
LANGUAGE_MAPPING = {
|
||||||
|
# See https://github.com/DataTables/Plugins/tree/master/i18n for available languages
|
||||||
|
# (We use the JSON files)
|
||||||
|
# `allianceauth/static/allianceauth/libs/DataTables/Plugins/{version}/i18n/` for the files
|
||||||
|
"DataTables": {
|
||||||
|
"cs-cz": "cs",
|
||||||
|
"de": "de-DE",
|
||||||
|
"es": "es-ES",
|
||||||
|
"fr-fr": "fr-FR",
|
||||||
|
"it-it": "it-IT",
|
||||||
|
"ja": "ja",
|
||||||
|
"ko-kr": "ko",
|
||||||
|
"nl-nl": "nl-NL",
|
||||||
|
"pl-pl": "pl",
|
||||||
|
"ru": "ru",
|
||||||
|
"uk": "uk",
|
||||||
|
"zh-hans": "zh-HANT",
|
||||||
|
},
|
||||||
|
# See https://github.com/moment/moment/tree/master/locale for available languages
|
||||||
|
# `allianceauth/static/allianceauth/libs/moment.js/{version}/locale/` for the files
|
||||||
|
"MomentJS": {
|
||||||
|
"cs-cz": "cs",
|
||||||
|
"de": "de",
|
||||||
|
"es": "es",
|
||||||
|
"fr-fr": "fr",
|
||||||
|
"it-it": "it",
|
||||||
|
"ja": "ja",
|
||||||
|
"ko-kr": "ko",
|
||||||
|
"nl-nl": "nl",
|
||||||
|
"pl-pl": "pl",
|
||||||
|
"ru": "ru",
|
||||||
|
"uk": "uk",
|
||||||
|
"zh-hans": "zh-cn",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
of the current Alliance Auth instance.
|
of the current Alliance Auth instance.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
=======
|
-------
|
||||||
|
|
||||||
Here is an example for using the api to fetch the current roles from the configured Discord server.
|
Here is an example for using the api to fetch the current roles from the configured Discord server.
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
# Generated by Django 4.2.16 on 2024-10-07 13:39
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("mumble", "0012_mumble_client_info"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name="mumbleuser",
|
||||||
|
options={
|
||||||
|
"permissions": (
|
||||||
|
("access_mumble", "Can access the Mumble service"),
|
||||||
|
(
|
||||||
|
"view_connection_history",
|
||||||
|
"Can access the connection history of the Mumble service",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="mumbleuser",
|
||||||
|
name="release",
|
||||||
|
field=models.TextField(
|
||||||
|
blank=True,
|
||||||
|
editable=False,
|
||||||
|
help_text="Client release. For official releases, this equals the version. For snapshots and git compiles, this will be something else.",
|
||||||
|
max_length=254,
|
||||||
|
null=True,
|
||||||
|
verbose_name="Mumble Release",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -89,7 +89,7 @@ class MumbleUser(AbstractServiceModel):
|
|||||||
max_length=254,
|
max_length=254,
|
||||||
blank=True,
|
blank=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
help_text="The Mumble Release the user last authenticated with"
|
help_text="Client release. For official releases, this equals the version. For snapshots and git compiles, this will be something else."
|
||||||
)
|
)
|
||||||
version = models.IntegerField(
|
version = models.IntegerField(
|
||||||
verbose_name="Mumble Version",
|
verbose_name="Mumble Version",
|
||||||
@ -157,4 +157,5 @@ class MumbleUser(AbstractServiceModel):
|
|||||||
class Meta:
|
class Meta:
|
||||||
permissions = (
|
permissions = (
|
||||||
("access_mumble", "Can access the Mumble service"),
|
("access_mumble", "Can access the Mumble service"),
|
||||||
|
("view_connection_history", "Can access the connection history of the Mumble service"),
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,232 @@
|
|||||||
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
|
||||||
|
{% load aa_i18n %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block page_title %}
|
||||||
|
{% translate "Mumble" %}
|
||||||
|
{% endblock page_title %}
|
||||||
|
|
||||||
|
{% block header_nav_brand %}
|
||||||
|
{% trans "Mumble History" %} - {{ mumble_url }}
|
||||||
|
{% endblock header_nav_brand %}
|
||||||
|
|
||||||
|
{% block header_nav_collapse_left %}
|
||||||
|
{% endblock header_nav_collapse_left %}
|
||||||
|
|
||||||
|
{% block header_nav_collapse_right %}
|
||||||
|
{% endblock header_nav_collapse_right %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="card col-lg-12 mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection History" %}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table w-100" id="table-mumble-connection-history">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-start">{% translate "User" %}</th>
|
||||||
|
<th class="text-start">{% translate "Displayed Name" %}</th>
|
||||||
|
<th class="text-start">{% translate "Release" %}</th>
|
||||||
|
<th class="text-start">{% translate "Version" %}</th>
|
||||||
|
<th class="text-end">{% translate "Last Connect" %}</th>
|
||||||
|
<th class="text-end">{% translate "Last Disconnect" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<canvas id="pieChart"></canvas> <!-- Canvas element for the pie chart -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-lg-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="card-title">{% translate "Server Connection Breakdown" %}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table class="table w-100" id="table-mumble-connection-stats">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-start">{% translate "Version" %}</th>
|
||||||
|
<th class="text-end">{% translate "Number" %}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block extra_javascript %}
|
||||||
|
{% include "bundles/datatables-js-bs5.html" %}
|
||||||
|
{% include "bundles/filterdropdown-js.html" %}
|
||||||
|
{% include "bundles/chart-js.html" %}
|
||||||
|
{% include "bundles/moment-js.html" with locale=True %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$(document).ready(function () {
|
||||||
|
const MUMBLESTATS_DATETIME_FORMAT = 'LLL';
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
$("#table-mumble-connection-history").DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
|
ajax: {
|
||||||
|
url: '{% url "mumble:connection_history_data" %}',
|
||||||
|
dataSrc: 'connection_history_data',
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: 'user' },
|
||||||
|
{ data: 'display_name' },
|
||||||
|
{ data: 'release' },
|
||||||
|
{ data: 'version' },
|
||||||
|
{
|
||||||
|
data: 'last_connect',
|
||||||
|
render: {
|
||||||
|
_: (data) => {
|
||||||
|
return data === null
|
||||||
|
? ''
|
||||||
|
: moment(data)
|
||||||
|
.utc()
|
||||||
|
.format(MUMBLESTATS_DATETIME_FORMAT);
|
||||||
|
},
|
||||||
|
sort: (data) => {
|
||||||
|
return data === null ? '' : data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: 'text-end',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: 'last_disconnect',
|
||||||
|
render: {
|
||||||
|
_: (data) => {
|
||||||
|
return data === null
|
||||||
|
? ''
|
||||||
|
: moment(data)
|
||||||
|
.utc()
|
||||||
|
.format(MUMBLESTATS_DATETIME_FORMAT);
|
||||||
|
},
|
||||||
|
sort: (data) => {
|
||||||
|
return data === null ? '' : data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
className: 'text-end',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
order: [[4, 'desc']],
|
||||||
|
processing: true,
|
||||||
|
stateSave: true,
|
||||||
|
stateDuration: 0,
|
||||||
|
filterDropDown: {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
idx: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
idx: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
bootstrap: true,
|
||||||
|
bootstrap_version: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#table-mumble-connection-stats").DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
|
ajax: {
|
||||||
|
url: '{% url "mumble:release_counts_data" %}',
|
||||||
|
dataSrc: 'release_counts_data',
|
||||||
|
},
|
||||||
|
columns: [
|
||||||
|
{ data: 'release' },
|
||||||
|
{ data: 'user_count', className: 'text-end' },
|
||||||
|
],
|
||||||
|
order: [[1, 'desc']],
|
||||||
|
processing: true,
|
||||||
|
stateSave: true,
|
||||||
|
stateDuration: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize empty Pie chart
|
||||||
|
const elementBody = document.querySelector('body');
|
||||||
|
const elementBodyCss = getComputedStyle(elementBody);
|
||||||
|
const ctx = document.getElementById('pieChart').getContext('2d');
|
||||||
|
const pieChart = new Chart(ctx, {
|
||||||
|
type: 'pie',
|
||||||
|
data: {
|
||||||
|
labels: [], // Initially empty
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: 'Server Connection Breakdown',
|
||||||
|
data: [], // Initially empty
|
||||||
|
backgroundColor: [
|
||||||
|
'rgba(255, 99, 132, 0.2)',
|
||||||
|
'rgba(54, 162, 235, 0.2)',
|
||||||
|
'rgba(255, 206, 86, 0.2)'
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
'rgba(255, 99, 132, 1)',
|
||||||
|
'rgba(54, 162, 235, 1)',
|
||||||
|
'rgba(255, 206, 86, 1)'
|
||||||
|
],
|
||||||
|
borderWidth: 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
responsive: true,
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
position: 'top'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Chart.defaults.color = elementBodyCss.color;
|
||||||
|
|
||||||
|
// AJAX call to dynamically update the chart
|
||||||
|
$.ajax({
|
||||||
|
url: '{% url "mumble:release_pie_chart_data" %}', // Your Django view URL that returns chart data
|
||||||
|
method: "GET",
|
||||||
|
success: (data) => {
|
||||||
|
// Replace chart data with the data from the AJAX response
|
||||||
|
pieChart.data.labels = data.labels; // Set the new labels
|
||||||
|
pieChart.data.datasets[0].data = data.values; // Set the new values
|
||||||
|
|
||||||
|
// Update the chart to reflect the new data
|
||||||
|
pieChart.update();
|
||||||
|
},
|
||||||
|
error: (xhr, status, error) => {
|
||||||
|
console.error('Error fetching pie chart data:', status, error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock extra_javascript %}
|
||||||
|
|
||||||
|
{% block extra_css %}
|
||||||
|
{% include "bundles/datatables-css-bs5.html" %}
|
||||||
|
{% endblock extra_css %}
|
@ -48,4 +48,9 @@
|
|||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if request.user.is_superuser %}
|
||||||
|
<a class="btn btn-primary" type="button" id="btnMumbleConnectionHistory" href="{% url 'mumble:connection_history' %}" title="{% translate 'Mumble Connection History' %}">
|
||||||
|
<i class="fa-solid fa-clock-rotate-left"></i> History
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -10,6 +10,10 @@ module_urls = [
|
|||||||
path('deactivate/', views.DeleteMumbleView.as_view(), name='deactivate'),
|
path('deactivate/', views.DeleteMumbleView.as_view(), name='deactivate'),
|
||||||
path('reset_password/', views.ResetPasswordMumbleView.as_view(), name='reset_password'),
|
path('reset_password/', views.ResetPasswordMumbleView.as_view(), name='reset_password'),
|
||||||
path('set_password/', views.SetPasswordMumbleView.as_view(), name='set_password'),
|
path('set_password/', views.SetPasswordMumbleView.as_view(), name='set_password'),
|
||||||
|
path('connection_history/', views.connection_history, name="connection_history"),
|
||||||
|
path('ajax/connection_history_data', views.connection_history_data, name="connection_history_data"),
|
||||||
|
path('ajax/release_counts_data', views.release_counts_data, name="release_counts_data"),
|
||||||
|
path('ajax/release_pie_chart_data', views.release_pie_chart_data, name="release_pie_chart_data"),
|
||||||
]
|
]
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
|
from django.db.models import Count
|
||||||
|
from django.http import HttpResponse, JsonResponse
|
||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
from allianceauth.services.abstract import (
|
from allianceauth.services.abstract import (
|
||||||
BaseCreatePasswordServiceAccountView,
|
BaseCreatePasswordServiceAccountView,
|
||||||
BaseDeactivateServiceAccountView,
|
BaseDeactivateServiceAccountView,
|
||||||
@ -39,3 +45,51 @@ class ResetPasswordMumbleView(MumbleViewMixin, BaseResetPasswordServiceAccountVi
|
|||||||
|
|
||||||
class SetPasswordMumbleView(MumbleViewMixin, BaseSetPasswordServiceAccountView):
|
class SetPasswordMumbleView(MumbleViewMixin, BaseSetPasswordServiceAccountView):
|
||||||
form_class = MumblePasswordForm
|
form_class = MumblePasswordForm
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required('mumble.view_connection_history')
|
||||||
|
def connection_history(request) -> HttpResponse:
|
||||||
|
|
||||||
|
context = {
|
||||||
|
"mumble_url": settings.MUMBLE_URL,
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'services/mumble/mumble_connection_history.html', context)
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def connection_history_data(request) -> JsonResponse:
|
||||||
|
connection_history_data = MumbleUser.objects.all(
|
||||||
|
).values(
|
||||||
|
'user',
|
||||||
|
'display_name',
|
||||||
|
'release',
|
||||||
|
'version',
|
||||||
|
'last_connect',
|
||||||
|
'last_disconnect',
|
||||||
|
)
|
||||||
|
|
||||||
|
return JsonResponse({"connection_history_data": list(connection_history_data)})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def release_counts_data(request) -> JsonResponse:
|
||||||
|
release_counts_data = MumbleUser.objects.values('release').annotate(user_count=Count('user_id')).order_by('release')
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
"release_counts_data": list(release_counts_data),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
@permission_required("mumble.view_connection_history")
|
||||||
|
def release_pie_chart_data(request) -> JsonResponse:
|
||||||
|
release_counts = MumbleUser.objects.values('release').annotate(user_count=Count('user_id')).order_by('release')
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
"labels": list(release_counts.values_list("release", flat=True)),
|
||||||
|
"values": list(release_counts.values_list("user_count", flat=True)),
|
||||||
|
})
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
{% extends "allianceauth/base-bs5.html" %}
|
{% extends "allianceauth/base-bs5.html" %}
|
||||||
|
{% load aa_i18n %}
|
||||||
|
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load humanize %}
|
{% load humanize %}
|
||||||
@ -168,6 +169,8 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
|
|||||||
{% include "bundles/moment-js.html" %}
|
{% include "bundles/moment-js.html" %}
|
||||||
{% include "bundles/clipboard-js.html" %}
|
{% include "bundles/clipboard-js.html" %}
|
||||||
|
|
||||||
|
{% get_datatables_language_static LANGUAGE_CODE as DT_LANG_PATH %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const clipboard = new ClipboardJS('.copy-text-fa-icon');
|
const clipboard = new ClipboardJS('.copy-text-fa-icon');
|
||||||
|
|
||||||
@ -237,6 +240,7 @@ ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
|
|||||||
});
|
});
|
||||||
|
|
||||||
elementTableSrpList.DataTable({
|
elementTableSrpList.DataTable({
|
||||||
|
language: {url: '{{ DT_LANG_PATH }}'},
|
||||||
"order": [[ 6, "asc" ]],
|
"order": [[ 6, "asc" ]],
|
||||||
"paging": false,
|
"paging": false,
|
||||||
"columnDefs": [
|
"columnDefs": [
|
||||||
|
@ -0,0 +1,247 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "Tabulka neobsahuje žádná data",
|
||||||
|
"info": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
|
||||||
|
"infoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
|
||||||
|
"infoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
|
||||||
|
"loadingRecords": "Načítám...",
|
||||||
|
"zeroRecords": "Žádné záznamy nebyly nalezeny",
|
||||||
|
"paginate": {
|
||||||
|
"first": "První",
|
||||||
|
"last": "Poslední",
|
||||||
|
"next": "Další",
|
||||||
|
"previous": "Předchozí"
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Přidat podmínku",
|
||||||
|
"clearAll": "Smazat vše",
|
||||||
|
"condition": "Podmínka",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "po",
|
||||||
|
"before": "před",
|
||||||
|
"between": "mezi",
|
||||||
|
"empty": "prázdné",
|
||||||
|
"equals": "rovno",
|
||||||
|
"not": "není",
|
||||||
|
"notBetween": "není mezi",
|
||||||
|
"notEmpty": "není prázdné"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "mezi",
|
||||||
|
"empty": "prázdné",
|
||||||
|
"equals": "rovno",
|
||||||
|
"gt": "větší",
|
||||||
|
"gte": "rovno a větší",
|
||||||
|
"lt": "menší",
|
||||||
|
"lte": "rovno a menší",
|
||||||
|
"not": "není",
|
||||||
|
"notBetween": "není mezi",
|
||||||
|
"notEmpty": "není prázdné"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "obsahuje",
|
||||||
|
"empty": "prázdné",
|
||||||
|
"endsWith": "končí na",
|
||||||
|
"equals": "rovno",
|
||||||
|
"not": "není",
|
||||||
|
"notEmpty": "není prázdné",
|
||||||
|
"startsWith": "začíná na",
|
||||||
|
"notContains": "Podmínka",
|
||||||
|
"notStartsWith": "Nezačíná",
|
||||||
|
"notEndsWith": "Nekončí"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "rovno",
|
||||||
|
"empty": "prázdné",
|
||||||
|
"contains": "obsahuje",
|
||||||
|
"not": "není",
|
||||||
|
"notEmpty": "není prázdné",
|
||||||
|
"without": "neobsahuje"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Sloupec",
|
||||||
|
"logicAnd": "A",
|
||||||
|
"logicOr": "NEBO",
|
||||||
|
"title": {
|
||||||
|
"0": "Rozšířený filtr",
|
||||||
|
"_": "Rozšířený filtr (%d)"
|
||||||
|
},
|
||||||
|
"value": "Hodnota",
|
||||||
|
"button": {
|
||||||
|
"0": "Rozšířený filtr",
|
||||||
|
"_": "Rozšířený filtr (%d)"
|
||||||
|
},
|
||||||
|
"deleteTitle": "Smazat filtrovací pravidlo",
|
||||||
|
"leftTitle": "Zrušení odsazení podmínky",
|
||||||
|
"rightTitle": "Odsazení podmínky"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Zrušit",
|
||||||
|
"fill": "Vyplň všechny buňky textem <i>%d<i><\/i><\/i>",
|
||||||
|
"fillHorizontal": "Vyplň všechny buňky horizontálně",
|
||||||
|
"fillVertical": "Vyplň všechny buňky vertikálně",
|
||||||
|
"info": "Příklad automatického vyplňování"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Kolekce <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"copy": "Kopírovat",
|
||||||
|
"copyTitle": "Kopírovat do schránky",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Zobrazit všechny řádky",
|
||||||
|
"_": "Zobrazit %d řádků",
|
||||||
|
"1": "Zobraz 1 řádek"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Tisknout",
|
||||||
|
"colvis": "Viditelnost sloupců",
|
||||||
|
"colvisRestore": "Resetovat sloupce",
|
||||||
|
"copyKeys": "Zmáčkněte ctrl or u2318 + C pro zkopírování dat. Pro zrušení klikněte na tuto zprávu nebo zmáčkněte esc..",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Zkopírován 1 řádek do schránky",
|
||||||
|
"_": "Zkopírováno %d řádků do schránky"
|
||||||
|
},
|
||||||
|
"createState": "Vytvořit Stav",
|
||||||
|
"removeAllStates": "Vymazat všechny Stavy",
|
||||||
|
"removeState": "Odstranit",
|
||||||
|
"renameState": "Odstranit",
|
||||||
|
"savedStates": "Uložit Stavy",
|
||||||
|
"stateRestore": "Stav %d",
|
||||||
|
"updateState": "Aktualizovat"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Smazat vše",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Vyhledávací Panely",
|
||||||
|
"_": "Vyhledávací Panely (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Žádné Vyhledávací Panely",
|
||||||
|
"loadMessage": "Načítám Vyhledávací Panely",
|
||||||
|
"title": "Aktivních filtrů - %d",
|
||||||
|
"showMessage": "Zobrazit Vše",
|
||||||
|
"collapseMessage": "Sbalit Vše"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"1": "Vybrán 1 záznam",
|
||||||
|
"_": "Vybráno %d záznamů"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "Vybrán 1 sloupec",
|
||||||
|
"_": "Vybráno %d sloupců"
|
||||||
|
},
|
||||||
|
"rows": {
|
||||||
|
"1": "Vybrán 1 řádek",
|
||||||
|
"_": "Vybráno %d řádků"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": "Aktivujte pro seřazení vzestupně",
|
||||||
|
"sortDescending": "Aktivujte pro seřazení sestupně"
|
||||||
|
},
|
||||||
|
"lengthMenu": "Zobrazit _MENU_ výsledků",
|
||||||
|
"processing": "Zpracovávání...",
|
||||||
|
"search": "Vyhledávání:",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Předchozí",
|
||||||
|
"next": "Další",
|
||||||
|
"hours": "Hodiny",
|
||||||
|
"minutes": "Minuty",
|
||||||
|
"seconds": "Vteřiny",
|
||||||
|
"unknown": "-",
|
||||||
|
"amPm": [
|
||||||
|
"Dopoledne",
|
||||||
|
"Odpoledne"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"Leden",
|
||||||
|
"Únor",
|
||||||
|
"Březen",
|
||||||
|
"Duben",
|
||||||
|
"Květen",
|
||||||
|
"Červen",
|
||||||
|
"Červenec",
|
||||||
|
"Srpen",
|
||||||
|
"Září",
|
||||||
|
"Říjen",
|
||||||
|
"Listopad",
|
||||||
|
"Prosinec"
|
||||||
|
],
|
||||||
|
"weekdays": [
|
||||||
|
"Ne",
|
||||||
|
"Po",
|
||||||
|
"Út",
|
||||||
|
"St",
|
||||||
|
"Čt",
|
||||||
|
"Pá",
|
||||||
|
"So"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Zavřít",
|
||||||
|
"create": {
|
||||||
|
"button": "Nový",
|
||||||
|
"title": "Nový záznam",
|
||||||
|
"submit": "Vytvořit"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Změnit",
|
||||||
|
"title": "Změnit záznam",
|
||||||
|
"submit": "Aktualizovat"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Vymazat",
|
||||||
|
"title": "Smazání",
|
||||||
|
"submit": "Vymazat",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Opravdu chcete smazat tyto %d řádky?",
|
||||||
|
"1": "Opravdu chcete smazat tento 1 řádek?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Mnohočetný výběr",
|
||||||
|
"restore": "Vrátit změny",
|
||||||
|
"noMulti": "Toto pole může být editováno individuálně, ale ne jako soušást skupiny.",
|
||||||
|
"info": "Vybrané položky obsahují různé hodnoty pro tento vstup. Chcete-li upravit a nastavit všechny položky tohoto vstupu na stejnou hodnotu, klikněte nebo klepněte sem, jinak si zachovají své individuální hodnoty."
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Došlo k systémové chybě (<a target=\"\\\" rel=\"nofollow\" href=\"\\\">Více informací<\/a>)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"infoThousands": " ",
|
||||||
|
"decimal": ",",
|
||||||
|
"thousands": " ",
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Vytvořit",
|
||||||
|
"columns": {
|
||||||
|
"search": "Vyhledávání v buňce",
|
||||||
|
"visible": "Viditelnost buňky"
|
||||||
|
},
|
||||||
|
"name": "Název:",
|
||||||
|
"order": "Řazení",
|
||||||
|
"paging": "Stránkování",
|
||||||
|
"scroller": "Pozice skrolování",
|
||||||
|
"select": "Výběr",
|
||||||
|
"title": "Vytvořit nový Stav",
|
||||||
|
"toggleLabel": "Zahrnout",
|
||||||
|
"search": "Filtrování",
|
||||||
|
"searchBuilder": "Rozšířené filtrování"
|
||||||
|
},
|
||||||
|
"duplicateError": "Stav s tímto názvem ji existuje.",
|
||||||
|
"emptyError": "Název nemůže být prázný.",
|
||||||
|
"emptyStates": "Žádné uložené stavy",
|
||||||
|
"removeConfirm": "Opravdu chcete odstranbit %s?",
|
||||||
|
"removeError": "Chyba při odstraňování stavu.",
|
||||||
|
"removeJoiner": "a",
|
||||||
|
"removeSubmit": "Odstranit",
|
||||||
|
"removeTitle": "Odstranit Stav",
|
||||||
|
"renameButton": "Vymazat",
|
||||||
|
"renameLabel": "Nové jméno pro %s:",
|
||||||
|
"renameTitle": "Přejmenování Stavu"
|
||||||
|
},
|
||||||
|
"searchPlaceholder": "Příklad zástupného prvku"
|
||||||
|
}
|
@ -0,0 +1,243 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "Keine Daten in der Tabelle vorhanden",
|
||||||
|
"info": "_START_ bis _END_ von _TOTAL_ Einträgen",
|
||||||
|
"infoEmpty": "Keine Daten vorhanden",
|
||||||
|
"infoFiltered": "(gefiltert von _MAX_ Einträgen)",
|
||||||
|
"infoThousands": ".",
|
||||||
|
"loadingRecords": "Wird geladen ..",
|
||||||
|
"processing": "Bitte warten ..",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Erste",
|
||||||
|
"next": "Nächste",
|
||||||
|
"last": "Letzte",
|
||||||
|
"previous": "Vorherige"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren",
|
||||||
|
"sortDescending": ": aktivieren, um Spalte absteigend zu sortieren"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"rows": {
|
||||||
|
"_": "%d Zeilen ausgewählt",
|
||||||
|
"1": "1 Zeile ausgewählt"
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"1": "1 Zelle ausgewählt",
|
||||||
|
"_": "%d Zellen ausgewählt"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 Spalte ausgewählt",
|
||||||
|
"_": "%d Spalten ausgewählt"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"print": "Drucken",
|
||||||
|
"copy": "Kopieren",
|
||||||
|
"copyTitle": "In Zwischenablage kopieren",
|
||||||
|
"copySuccess": {
|
||||||
|
"_": "%d Zeilen kopiert",
|
||||||
|
"1": "1 Zeile kopiert"
|
||||||
|
},
|
||||||
|
"collection": "Aktionen <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "Spaltensichtbarkeit",
|
||||||
|
"colvisRestore": "Sichtbarkeit wiederherstellen",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Alle Zeilen anzeigen",
|
||||||
|
"1": "Zeige 1 Zeile",
|
||||||
|
"_": "Zeige %d Zeilen"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"createState": "Ansicht erstellen",
|
||||||
|
"removeAllStates": "Alle Ansichten entfernen",
|
||||||
|
"removeState": "Entfernen",
|
||||||
|
"renameState": "Umbenennen",
|
||||||
|
"savedStates": "Gespeicherte Ansicht",
|
||||||
|
"stateRestore": "Ansicht %d",
|
||||||
|
"updateState": "Aktualisieren",
|
||||||
|
"copyKeys": "Taste <i>STRG<\\\/i> oder <i>⌘<\\\/i> + <i>C<\\\/i> drücken um die Tabelle<br \/>in den Zwischenspeicher zu kopieren.<br \/><br \/>Um den Vorgang abzubrechen, Nachricht anklicken oder Escape-Taste drücken.<\/i><\/i><\/i>"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Abbrechen",
|
||||||
|
"fill": "Alle Zellen mit <i>%d<i> füllen<\/i><\/i>",
|
||||||
|
"fillHorizontal": "Alle horizontalen Zellen füllen",
|
||||||
|
"fillVertical": "Alle vertikalen Zellen füllen",
|
||||||
|
"info": "Automatische Vervollständigung"
|
||||||
|
},
|
||||||
|
"decimal": ",",
|
||||||
|
"search": "Suche:",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Bedingung hinzufügen",
|
||||||
|
"button": {
|
||||||
|
"0": "Such-Baukasten",
|
||||||
|
"_": "Such-Baukasten (%d)"
|
||||||
|
},
|
||||||
|
"condition": "Bedingung",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Nach",
|
||||||
|
"before": "Vor",
|
||||||
|
"between": "Zwischen",
|
||||||
|
"empty": "Leer",
|
||||||
|
"not": "Nicht",
|
||||||
|
"notBetween": "Nicht zwischen",
|
||||||
|
"notEmpty": "Nicht leer",
|
||||||
|
"equals": "Gleich"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Zwischen",
|
||||||
|
"empty": "Leer",
|
||||||
|
"equals": "Entspricht",
|
||||||
|
"gt": "Größer als",
|
||||||
|
"gte": "Größer als oder gleich",
|
||||||
|
"lt": "Kleiner als",
|
||||||
|
"lte": "Kleiner als oder gleich",
|
||||||
|
"not": "Nicht",
|
||||||
|
"notBetween": "Nicht zwischen",
|
||||||
|
"notEmpty": "Nicht leer"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Beinhaltet",
|
||||||
|
"empty": "Leer",
|
||||||
|
"endsWith": "Endet mit",
|
||||||
|
"equals": "Entspricht",
|
||||||
|
"not": "Nicht",
|
||||||
|
"notEmpty": "Nicht leer",
|
||||||
|
"startsWith": "Startet mit",
|
||||||
|
"notContains": "enthält nicht",
|
||||||
|
"notStartsWith": "startet nicht mit",
|
||||||
|
"notEndsWith": "endet nicht mit"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "ist gleich",
|
||||||
|
"empty": "ist leer",
|
||||||
|
"contains": "enthält",
|
||||||
|
"not": "ist ungleich",
|
||||||
|
"notEmpty": "ist nicht leer",
|
||||||
|
"without": "aber nicht"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Daten",
|
||||||
|
"deleteTitle": "Filterregel entfernen",
|
||||||
|
"leftTitle": "Äußere Kriterien",
|
||||||
|
"rightTitle": "Innere Kriterien",
|
||||||
|
"title": {
|
||||||
|
"0": "Such-Baukasten",
|
||||||
|
"_": "Such-Baukasten (%d)"
|
||||||
|
},
|
||||||
|
"value": "Wert",
|
||||||
|
"clearAll": "Alle entfernen",
|
||||||
|
"logicAnd": "Und",
|
||||||
|
"logicOr": "Oder"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Leeren",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Suchmasken",
|
||||||
|
"_": "Suchmasken (%d)"
|
||||||
|
},
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Keine Suchmasken",
|
||||||
|
"title": "Aktive Filter: %d",
|
||||||
|
"showMessage": "zeige Alle",
|
||||||
|
"collapseMessage": "Alle einklappen",
|
||||||
|
"count": "{total}",
|
||||||
|
"loadMessage": "Lade Suchmasken .."
|
||||||
|
},
|
||||||
|
"thousands": ".",
|
||||||
|
"zeroRecords": "Keine passenden Einträge gefunden",
|
||||||
|
"lengthMenu": "_MENU_ Zeilen anzeigen",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Vorher",
|
||||||
|
"next": "Nachher",
|
||||||
|
"hours": "Stunden",
|
||||||
|
"minutes": "Minuten",
|
||||||
|
"seconds": "Sekunden",
|
||||||
|
"unknown": "Unbekannt",
|
||||||
|
"weekdays": [
|
||||||
|
"Sonntag",
|
||||||
|
"Montag",
|
||||||
|
"Dienstag",
|
||||||
|
"Mittwoch",
|
||||||
|
"Donnerstag",
|
||||||
|
"Freitag",
|
||||||
|
"Samstag"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"Januar",
|
||||||
|
"Februar",
|
||||||
|
"März",
|
||||||
|
"April",
|
||||||
|
"Mai",
|
||||||
|
"Juni",
|
||||||
|
"Juli",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"Oktober",
|
||||||
|
"November",
|
||||||
|
"Dezember"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Schließen",
|
||||||
|
"create": {
|
||||||
|
"button": "Neu",
|
||||||
|
"title": "Neuen Eintrag erstellen",
|
||||||
|
"submit": "Erstellen"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"confirm": {
|
||||||
|
"_": "Sollen %d Zeilen gelöscht werden?",
|
||||||
|
"1": "Soll diese Zeile gelöscht werden?"
|
||||||
|
},
|
||||||
|
"button": "Entfernen",
|
||||||
|
"title": "Entfernen",
|
||||||
|
"submit": "Entfernen"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Ein Systemfehler ist aufgetreten"
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Mehrere Werte",
|
||||||
|
"restore": "Änderungen zurücksetzen",
|
||||||
|
"noMulti": "Dieses Feld kann nur einzeln bearbeitet werden, nicht als Teil einer Mengen-Änderung.",
|
||||||
|
"info": "Die ausgewählten Elemente enthalten mehrere Werte für dieses Feld. Um alle Elemente für dieses Feld zu bearbeiten und auf denselben Wert zu setzen, hier klicken oder tippen, andernfalls behalten diese ihre individuellen Werte bei."
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Bearbeiten",
|
||||||
|
"title": "Eintrag bearbeiten",
|
||||||
|
"submit": "Bearbeiten"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"searchPlaceholder": "Suchen...",
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Erstellen",
|
||||||
|
"columns": {
|
||||||
|
"search": "Spalten Suche",
|
||||||
|
"visible": "Spalten Sichtbarkeit"
|
||||||
|
},
|
||||||
|
"name": "Name:",
|
||||||
|
"order": "Sortieren",
|
||||||
|
"paging": "Seiten",
|
||||||
|
"scroller": "Scroll Position",
|
||||||
|
"search": "Suche",
|
||||||
|
"searchBuilder": "Such-Baukasten",
|
||||||
|
"select": "Auswahl",
|
||||||
|
"title": "Neue Ansicht erstellen",
|
||||||
|
"toggleLabel": "Inkludiert:"
|
||||||
|
},
|
||||||
|
"duplicateError": "Eine Ansicht mit diesem Namen existiert bereits.",
|
||||||
|
"emptyError": "Name darf nicht leer sein.",
|
||||||
|
"emptyStates": "Keine gespeicherten Ansichten",
|
||||||
|
"removeError": "Entfernen der Ansicht fehlgeschlagen.",
|
||||||
|
"removeJoiner": " und ",
|
||||||
|
"removeSubmit": "Entfernen",
|
||||||
|
"removeTitle": "Ansicht entfernen",
|
||||||
|
"renameButton": "Umbenennen",
|
||||||
|
"renameLabel": "Neuer Name für %s:",
|
||||||
|
"renameTitle": "Ansicht umbenennen",
|
||||||
|
"removeConfirm": "Sicher dass %s entfernt werden soll?"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,244 @@
|
|||||||
|
{
|
||||||
|
"processing": "Procesando...",
|
||||||
|
"lengthMenu": "Mostrar _MENU_ registros",
|
||||||
|
"zeroRecords": "No se encontraron resultados",
|
||||||
|
"emptyTable": "Ningún dato disponible en esta tabla",
|
||||||
|
"infoEmpty": "Mostrando registros del 0 al 0 de un total de 0 registros",
|
||||||
|
"infoFiltered": "(filtrado de un total de _MAX_ registros)",
|
||||||
|
"search": "Buscar:",
|
||||||
|
"loadingRecords": "Cargando...",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Primero",
|
||||||
|
"last": "Último",
|
||||||
|
"next": "Siguiente",
|
||||||
|
"previous": "Anterior"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": Activar para ordenar la columna de manera ascendente",
|
||||||
|
"sortDescending": ": Activar para ordenar la columna de manera descendente"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"copy": "Copiar",
|
||||||
|
"colvis": "Visibilidad",
|
||||||
|
"collection": "Colección",
|
||||||
|
"colvisRestore": "Restaurar visibilidad",
|
||||||
|
"copyKeys": "Presione ctrl o u2318 + C para copiar los datos de la tabla al portapapeles del sistema. <br \/> <br \/> Para cancelar, haga clic en este mensaje o presione escape.",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Copiada 1 fila al portapapeles",
|
||||||
|
"_": "Copiadas %ds fila al portapapeles"
|
||||||
|
},
|
||||||
|
"copyTitle": "Copiar al portapapeles",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Mostrar todas las filas",
|
||||||
|
"_": "Mostrar %d filas"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Imprimir",
|
||||||
|
"renameState": "Cambiar nombre",
|
||||||
|
"updateState": "Actualizar",
|
||||||
|
"createState": "Crear Estado",
|
||||||
|
"removeAllStates": "Remover Estados",
|
||||||
|
"removeState": "Remover",
|
||||||
|
"savedStates": "Estados Guardados",
|
||||||
|
"stateRestore": "Estado %d"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Cancelar",
|
||||||
|
"fill": "Rellene todas las celdas con <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Rellenar celdas horizontalmente",
|
||||||
|
"fillVertical": "Rellenar celdas verticalmente"
|
||||||
|
},
|
||||||
|
"decimal": ",",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Añadir condición",
|
||||||
|
"button": {
|
||||||
|
"0": "Constructor de búsqueda",
|
||||||
|
"_": "Constructor de búsqueda (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Borrar todo",
|
||||||
|
"condition": "Condición",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"before": "Antes",
|
||||||
|
"between": "Entre",
|
||||||
|
"empty": "Vacío",
|
||||||
|
"equals": "Igual a",
|
||||||
|
"notBetween": "No entre",
|
||||||
|
"not": "Diferente de",
|
||||||
|
"after": "Después",
|
||||||
|
"notEmpty": "No Vacío"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Entre",
|
||||||
|
"equals": "Igual a",
|
||||||
|
"gt": "Mayor a",
|
||||||
|
"gte": "Mayor o igual a",
|
||||||
|
"lt": "Menor que",
|
||||||
|
"lte": "Menor o igual que",
|
||||||
|
"notBetween": "No entre",
|
||||||
|
"notEmpty": "No vacío",
|
||||||
|
"not": "Diferente de",
|
||||||
|
"empty": "Vacío"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Contiene",
|
||||||
|
"empty": "Vacío",
|
||||||
|
"endsWith": "Termina en",
|
||||||
|
"equals": "Igual a",
|
||||||
|
"startsWith": "Empieza con",
|
||||||
|
"not": "Diferente de",
|
||||||
|
"notContains": "No Contiene",
|
||||||
|
"notStartsWith": "No empieza con",
|
||||||
|
"notEndsWith": "No termina con",
|
||||||
|
"notEmpty": "No Vacío"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"not": "Diferente de",
|
||||||
|
"equals": "Igual",
|
||||||
|
"empty": "Vacío",
|
||||||
|
"contains": "Contiene",
|
||||||
|
"notEmpty": "No Vacío",
|
||||||
|
"without": "Sin"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Data",
|
||||||
|
"deleteTitle": "Eliminar regla de filtrado",
|
||||||
|
"leftTitle": "Criterios anulados",
|
||||||
|
"logicAnd": "Y",
|
||||||
|
"logicOr": "O",
|
||||||
|
"rightTitle": "Criterios de sangría",
|
||||||
|
"title": {
|
||||||
|
"0": "Constructor de búsqueda",
|
||||||
|
"_": "Constructor de búsqueda (%d)"
|
||||||
|
},
|
||||||
|
"value": "Valor"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Borrar todo",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Paneles de búsqueda",
|
||||||
|
"_": "Paneles de búsqueda (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Sin paneles de búsqueda",
|
||||||
|
"loadMessage": "Cargando paneles de búsqueda",
|
||||||
|
"title": "Filtros Activos - %d",
|
||||||
|
"showMessage": "Mostrar Todo",
|
||||||
|
"collapseMessage": "Colapsar Todo"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"1": "1 celda seleccionada",
|
||||||
|
"_": "%d celdas seleccionadas"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 columna seleccionada",
|
||||||
|
"_": "%d columnas seleccionadas"
|
||||||
|
},
|
||||||
|
"rows": {
|
||||||
|
"1": "1 fila seleccionada",
|
||||||
|
"_": "%d filas seleccionadas"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thousands": ".",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Anterior",
|
||||||
|
"hours": "Horas",
|
||||||
|
"minutes": "Minutos",
|
||||||
|
"seconds": "Segundos",
|
||||||
|
"unknown": "-",
|
||||||
|
"amPm": [
|
||||||
|
"AM",
|
||||||
|
"PM"
|
||||||
|
],
|
||||||
|
"months": {
|
||||||
|
"0": "Enero",
|
||||||
|
"1": "Febrero",
|
||||||
|
"10": "Noviembre",
|
||||||
|
"11": "Diciembre",
|
||||||
|
"2": "Marzo",
|
||||||
|
"3": "Abril",
|
||||||
|
"4": "Mayo",
|
||||||
|
"5": "Junio",
|
||||||
|
"6": "Julio",
|
||||||
|
"7": "Agosto",
|
||||||
|
"8": "Septiembre",
|
||||||
|
"9": "Octubre"
|
||||||
|
},
|
||||||
|
"weekdays": {
|
||||||
|
"0": "Dom",
|
||||||
|
"1": "Lun",
|
||||||
|
"2": "Mar",
|
||||||
|
"4": "Jue",
|
||||||
|
"5": "Vie",
|
||||||
|
"3": "Mié",
|
||||||
|
"6": "Sáb"
|
||||||
|
},
|
||||||
|
"next": "Próximo"
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Cerrar",
|
||||||
|
"create": {
|
||||||
|
"button": "Nuevo",
|
||||||
|
"title": "Crear Nuevo Registro",
|
||||||
|
"submit": "Crear"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Editar",
|
||||||
|
"title": "Editar Registro",
|
||||||
|
"submit": "Actualizar"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Eliminar",
|
||||||
|
"title": "Eliminar Registro",
|
||||||
|
"submit": "Eliminar",
|
||||||
|
"confirm": {
|
||||||
|
"_": "¿Está seguro de que desea eliminar %d filas?",
|
||||||
|
"1": "¿Está seguro de que desea eliminar 1 fila?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Ha ocurrido un error en el sistema (<a target=\"\\\" rel=\"\\ nofollow\" href=\"\\\">Más información<\\\/a>).<\/a>"
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Múltiples Valores",
|
||||||
|
"restore": "Deshacer Cambios",
|
||||||
|
"noMulti": "Este registro puede ser editado individualmente, pero no como parte de un grupo.",
|
||||||
|
"info": "Los elementos seleccionados contienen diferentes valores para este registro. Para editar y establecer todos los elementos de este registro con el mismo valor, haga clic o pulse aquí, de lo contrario conservarán sus valores individuales."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"info": "Mostrando _START_ a _END_ de _TOTAL_ registros",
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Crear",
|
||||||
|
"name": "Nombre:",
|
||||||
|
"order": "Clasificación",
|
||||||
|
"paging": "Paginación",
|
||||||
|
"select": "Seleccionar",
|
||||||
|
"columns": {
|
||||||
|
"search": "Búsqueda de Columna",
|
||||||
|
"visible": "Visibilidad de Columna"
|
||||||
|
},
|
||||||
|
"title": "Crear Nuevo Estado",
|
||||||
|
"toggleLabel": "Incluir:",
|
||||||
|
"scroller": "Posición de desplazamiento",
|
||||||
|
"search": "Búsqueda",
|
||||||
|
"searchBuilder": "Búsqueda avanzada"
|
||||||
|
},
|
||||||
|
"removeJoiner": "y",
|
||||||
|
"removeSubmit": "Eliminar",
|
||||||
|
"renameButton": "Cambiar Nombre",
|
||||||
|
"duplicateError": "Ya existe un Estado con este nombre.",
|
||||||
|
"emptyStates": "No hay Estados guardados",
|
||||||
|
"removeTitle": "Remover Estado",
|
||||||
|
"renameTitle": "Cambiar Nombre Estado",
|
||||||
|
"emptyError": "El nombre no puede estar vacío.",
|
||||||
|
"removeConfirm": "¿Seguro que quiere eliminar %s?",
|
||||||
|
"removeError": "Error al eliminar el Estado",
|
||||||
|
"renameLabel": "Nuevo nombre para %s:"
|
||||||
|
},
|
||||||
|
"infoThousands": "."
|
||||||
|
}
|
@ -0,0 +1,245 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "Aucune donnée disponible dans le tableau",
|
||||||
|
"loadingRecords": "Chargement...",
|
||||||
|
"processing": "Traitement...",
|
||||||
|
"select": {
|
||||||
|
"rows": {
|
||||||
|
"_": "%d lignes sélectionnées",
|
||||||
|
"1": "1 ligne sélectionnée"
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"1": "1 cellule sélectionnée",
|
||||||
|
"_": "%d cellules sélectionnées"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 colonne sélectionnée",
|
||||||
|
"_": "%d colonnes sélectionnées"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Annuler",
|
||||||
|
"fill": "Remplir toutes les cellules avec <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Remplir les cellules horizontalement",
|
||||||
|
"fillVertical": "Remplir les cellules verticalement"
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Après le",
|
||||||
|
"before": "Avant le",
|
||||||
|
"between": "Entre",
|
||||||
|
"empty": "Vide",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notBetween": "Pas entre",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"equals": "Égal à"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Entre",
|
||||||
|
"empty": "Vide",
|
||||||
|
"gt": "Supérieur à",
|
||||||
|
"gte": "Supérieur ou égal à",
|
||||||
|
"lt": "Inférieur à",
|
||||||
|
"lte": "Inférieur ou égal à",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notBetween": "Pas entre",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"equals": "Égal à"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Contient",
|
||||||
|
"empty": "Vide",
|
||||||
|
"endsWith": "Se termine par",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"startsWith": "Commence par",
|
||||||
|
"equals": "Égal à",
|
||||||
|
"notContains": "Ne contient pas",
|
||||||
|
"notEndsWith": "Ne termine pas par",
|
||||||
|
"notStartsWith": "Ne commence pas par"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"empty": "Vide",
|
||||||
|
"contains": "Contient",
|
||||||
|
"not": "Différent de",
|
||||||
|
"notEmpty": "Non vide",
|
||||||
|
"without": "Sans",
|
||||||
|
"equals": "Égal à"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"add": "Ajouter une condition",
|
||||||
|
"button": {
|
||||||
|
"0": "Recherche avancée",
|
||||||
|
"_": "Recherche avancée (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Effacer tout",
|
||||||
|
"condition": "Condition",
|
||||||
|
"data": "Donnée",
|
||||||
|
"deleteTitle": "Supprimer la règle de filtrage",
|
||||||
|
"logicAnd": "Et",
|
||||||
|
"logicOr": "Ou",
|
||||||
|
"title": {
|
||||||
|
"0": "Recherche avancée",
|
||||||
|
"_": "Recherche avancée (%d)"
|
||||||
|
},
|
||||||
|
"value": "Valeur",
|
||||||
|
"leftTitle": "Désindenter le critère",
|
||||||
|
"rightTitle": "Indenter le critère"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Effacer tout",
|
||||||
|
"count": "{total}",
|
||||||
|
"title": "Filtres actifs - %d",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Volet de recherche",
|
||||||
|
"_": "Volet de recherche (%d)"
|
||||||
|
},
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Pas de volet de recherche",
|
||||||
|
"loadMessage": "Chargement du volet de recherche...",
|
||||||
|
"collapseMessage": "Réduire tout",
|
||||||
|
"showMessage": "Montrer tout"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Collection",
|
||||||
|
"colvis": "Visibilité colonnes",
|
||||||
|
"colvisRestore": "Rétablir visibilité",
|
||||||
|
"copy": "Copier",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "1 ligne copiée dans le presse-papier",
|
||||||
|
"_": "%d lignes copiées dans le presse-papier"
|
||||||
|
},
|
||||||
|
"copyTitle": "Copier dans le presse-papier",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Afficher toutes les lignes",
|
||||||
|
"_": "Afficher %d lignes",
|
||||||
|
"1": "Afficher 1 ligne"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Imprimer",
|
||||||
|
"copyKeys": "Appuyez sur ctrl ou u2318 + C pour copier les données du tableau dans votre presse-papier.",
|
||||||
|
"createState": "Créer un état",
|
||||||
|
"removeAllStates": "Supprimer tous les états",
|
||||||
|
"removeState": "Supprimer",
|
||||||
|
"renameState": "Renommer",
|
||||||
|
"savedStates": "États sauvegardés",
|
||||||
|
"stateRestore": "État %d",
|
||||||
|
"updateState": "Mettre à jour"
|
||||||
|
},
|
||||||
|
"decimal": ",",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Précédent",
|
||||||
|
"next": "Suivant",
|
||||||
|
"hours": "Heures",
|
||||||
|
"minutes": "Minutes",
|
||||||
|
"seconds": "Secondes",
|
||||||
|
"unknown": "-",
|
||||||
|
"amPm": [
|
||||||
|
"am",
|
||||||
|
"pm"
|
||||||
|
],
|
||||||
|
"months": {
|
||||||
|
"0": "Janvier",
|
||||||
|
"2": "Mars",
|
||||||
|
"3": "Avril",
|
||||||
|
"4": "Mai",
|
||||||
|
"5": "Juin",
|
||||||
|
"6": "Juillet",
|
||||||
|
"8": "Septembre",
|
||||||
|
"9": "Octobre",
|
||||||
|
"10": "Novembre",
|
||||||
|
"1": "Février",
|
||||||
|
"11": "Décembre",
|
||||||
|
"7": "Août"
|
||||||
|
},
|
||||||
|
"weekdays": [
|
||||||
|
"Dim",
|
||||||
|
"Lun",
|
||||||
|
"Mar",
|
||||||
|
"Mer",
|
||||||
|
"Jeu",
|
||||||
|
"Ven",
|
||||||
|
"Sam"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Fermer",
|
||||||
|
"create": {
|
||||||
|
"title": "Créer une nouvelle entrée",
|
||||||
|
"button": "Nouveau",
|
||||||
|
"submit": "Créer"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Editer",
|
||||||
|
"title": "Editer Entrée",
|
||||||
|
"submit": "Mettre à jour"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Supprimer",
|
||||||
|
"title": "Supprimer",
|
||||||
|
"submit": "Supprimer",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Êtes-vous sûr de vouloir supprimer %d lignes ?",
|
||||||
|
"1": "Êtes-vous sûr de vouloir supprimer 1 ligne ?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Valeurs multiples",
|
||||||
|
"info": "Les éléments sélectionnés contiennent différentes valeurs pour cette entrée. Pour modifier et définir tous les éléments de cette entrée à la même valeur, cliquez ou tapez ici, sinon ils conserveront leurs valeurs individuelles.",
|
||||||
|
"restore": "Annuler les modifications",
|
||||||
|
"noMulti": "Ce champ peut être modifié individuellement, mais ne fait pas partie d'un groupe. "
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Une erreur système s'est produite (<a target=\"\\\" rel=\"nofollow\" href=\"\\\">Plus d'information<\/a>)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stateRestore": {
|
||||||
|
"removeSubmit": "Supprimer",
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Créer",
|
||||||
|
"order": "Tri",
|
||||||
|
"paging": "Pagination",
|
||||||
|
"scroller": "Position du défilement",
|
||||||
|
"search": "Recherche",
|
||||||
|
"select": "Sélection",
|
||||||
|
"columns": {
|
||||||
|
"search": "Recherche par colonne",
|
||||||
|
"visible": "Visibilité des colonnes"
|
||||||
|
},
|
||||||
|
"name": "Nom :",
|
||||||
|
"searchBuilder": "Recherche avancée",
|
||||||
|
"title": "Créer un nouvel état",
|
||||||
|
"toggleLabel": "Inclus :"
|
||||||
|
},
|
||||||
|
"renameButton": "Renommer",
|
||||||
|
"duplicateError": "Il existe déjà un état avec ce nom.",
|
||||||
|
"emptyError": "Le nom ne peut pas être vide.",
|
||||||
|
"emptyStates": "Aucun état sauvegardé",
|
||||||
|
"removeConfirm": "Voulez vous vraiment supprimer %s ?",
|
||||||
|
"removeError": "Échec de la suppression de l'état.",
|
||||||
|
"removeJoiner": "et",
|
||||||
|
"removeTitle": "Supprimer l'état",
|
||||||
|
"renameLabel": "Nouveau nom pour %s :",
|
||||||
|
"renameTitle": "Renommer l'état"
|
||||||
|
},
|
||||||
|
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrées",
|
||||||
|
"infoEmpty": "Affichage de 0 à 0 sur 0 entrées",
|
||||||
|
"infoFiltered": "(filtrées depuis un total de _MAX_ entrées)",
|
||||||
|
"lengthMenu": "Afficher _MENU_ entrées",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Première",
|
||||||
|
"last": "Dernière",
|
||||||
|
"next": "Suivante",
|
||||||
|
"previous": "Précédente"
|
||||||
|
},
|
||||||
|
"zeroRecords": "Aucune entrée correspondante trouvée",
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": " : activer pour trier la colonne par ordre croissant",
|
||||||
|
"sortDescending": " : activer pour trier la colonne par ordre décroissant"
|
||||||
|
},
|
||||||
|
"infoThousands": " ",
|
||||||
|
"search": "Rechercher :",
|
||||||
|
"thousands": " "
|
||||||
|
}
|
@ -0,0 +1,244 @@
|
|||||||
|
{
|
||||||
|
"infoFiltered": "(filtrati da _MAX_ elementi totali)",
|
||||||
|
"infoThousands": ".",
|
||||||
|
"loadingRecords": "Caricamento...",
|
||||||
|
"processing": "Elaborazione...",
|
||||||
|
"search": "Cerca:",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Inizio",
|
||||||
|
"previous": "Precedente",
|
||||||
|
"next": "Successivo",
|
||||||
|
"last": "Fine"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": attiva per ordinare la colonna in ordine crescente",
|
||||||
|
"sortDescending": ": attiva per ordinare la colonna in ordine decrescente"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Annulla",
|
||||||
|
"fill": "Riempi tutte le celle con <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Riempi celle orizzontalmente",
|
||||||
|
"fillVertical": "Riempi celle verticalmente"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Collezione <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "Visibilità Colonna",
|
||||||
|
"colvisRestore": "Ripristina visibilità",
|
||||||
|
"copy": "Copia",
|
||||||
|
"copyKeys": "Premi ctrl o u2318 + C per copiare i dati della tabella nella tua clipboard di sistema.<br \/><br \/>Per annullare, clicca questo messaggio o premi ESC.",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Copiata 1 riga nella clipboard",
|
||||||
|
"_": "Copiate %d righe nella clipboard"
|
||||||
|
},
|
||||||
|
"copyTitle": "Copia nella Clipboard",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Mostra tutte le righe",
|
||||||
|
"_": "Mostra %d righe"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Stampa",
|
||||||
|
"createState": "Crea stato",
|
||||||
|
"removeAllStates": "Rimuovi tutti gli stati",
|
||||||
|
"removeState": "Rimuovi",
|
||||||
|
"renameState": "Rinomina",
|
||||||
|
"savedStates": "Salva stato",
|
||||||
|
"stateRestore": "Ripristina stato",
|
||||||
|
"updateState": "Aggiorna"
|
||||||
|
},
|
||||||
|
"emptyTable": "Nessun dato disponibile nella tabella",
|
||||||
|
"info": "Risultati da _START_ a _END_ di _TOTAL_ elementi",
|
||||||
|
"infoEmpty": "Risultati da 0 a 0 di 0 elementi",
|
||||||
|
"lengthMenu": "Mostra _MENU_ elementi",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Aggiungi Condizione",
|
||||||
|
"button": {
|
||||||
|
"0": "Generatore di Ricerca",
|
||||||
|
"_": "Generatori di Ricerca (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Pulisci Tutto",
|
||||||
|
"condition": "Condizione",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Dopo",
|
||||||
|
"before": "Prima",
|
||||||
|
"between": "Tra",
|
||||||
|
"empty": "Vuoto",
|
||||||
|
"equals": "Uguale A",
|
||||||
|
"not": "Non",
|
||||||
|
"notBetween": "Non Tra",
|
||||||
|
"notEmpty": "Non Vuoto"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Tra",
|
||||||
|
"empty": "Vuoto",
|
||||||
|
"equals": "Uguale A",
|
||||||
|
"gt": "Maggiore Di",
|
||||||
|
"gte": "Maggiore O Uguale A",
|
||||||
|
"lt": "Minore Di",
|
||||||
|
"lte": "Minore O Uguale A",
|
||||||
|
"not": "Non",
|
||||||
|
"notBetween": "Non Tra",
|
||||||
|
"notEmpty": "Non Vuoto"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Contiene",
|
||||||
|
"empty": "Vuoto",
|
||||||
|
"endsWith": "Finisce Con",
|
||||||
|
"equals": "Uguale A",
|
||||||
|
"not": "Non",
|
||||||
|
"notEmpty": "Non Vuoto",
|
||||||
|
"startsWith": "Inizia Con",
|
||||||
|
"notContains": "Non Contiene",
|
||||||
|
"notStartsWith": "Non Inizia Con",
|
||||||
|
"notEndsWith": "Non Finisce Con"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "Uguale A",
|
||||||
|
"empty": "Vuoto",
|
||||||
|
"contains": "Contiene",
|
||||||
|
"not": "Non",
|
||||||
|
"notEmpty": "Non Vuoto",
|
||||||
|
"without": "Senza"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Dati",
|
||||||
|
"deleteTitle": "Elimina regola filtro",
|
||||||
|
"leftTitle": "Criterio di Riduzione Rientro",
|
||||||
|
"logicAnd": "E",
|
||||||
|
"logicOr": "O",
|
||||||
|
"rightTitle": "Criterio di Aumento Rientro",
|
||||||
|
"title": {
|
||||||
|
"0": "Generatore di Ricerca",
|
||||||
|
"_": "Generatori di Ricerca (%d)"
|
||||||
|
},
|
||||||
|
"value": "Valore"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Pulisci Tutto",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Pannello di Ricerca",
|
||||||
|
"_": "Pannelli di Ricerca (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Nessun Pannello di Ricerca",
|
||||||
|
"loadMessage": "Caricamento Pannello di Ricerca",
|
||||||
|
"title": "Filtri Attivi - %d",
|
||||||
|
"showMessage": "Mostra tutto",
|
||||||
|
"collapseMessage": "Espandi tutto"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"1": "1 cella selezionata",
|
||||||
|
"_": "%d celle selezionate"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 colonna selezionata",
|
||||||
|
"_": "%d colonne selezionate"
|
||||||
|
},
|
||||||
|
"rows": {
|
||||||
|
"1": "1 riga selezionata",
|
||||||
|
"_": "%d righe selezionate"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zeroRecords": "Nessun elemento corrispondente trovato",
|
||||||
|
"datetime": {
|
||||||
|
"amPm": [
|
||||||
|
"am",
|
||||||
|
"pm"
|
||||||
|
],
|
||||||
|
"hours": "ore",
|
||||||
|
"minutes": "minuti",
|
||||||
|
"next": "successivo",
|
||||||
|
"previous": "precedente",
|
||||||
|
"seconds": "secondi",
|
||||||
|
"unknown": "sconosciuto",
|
||||||
|
"weekdays": [
|
||||||
|
"Dom",
|
||||||
|
"Lun",
|
||||||
|
"Mar",
|
||||||
|
"Mer",
|
||||||
|
"Gio",
|
||||||
|
"Ven",
|
||||||
|
"Sab"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"Gennaio",
|
||||||
|
"Febbraio",
|
||||||
|
"Marzo",
|
||||||
|
"Aprile",
|
||||||
|
"Maggio",
|
||||||
|
"Giugno",
|
||||||
|
"Luglio",
|
||||||
|
"Agosto",
|
||||||
|
"Settembre",
|
||||||
|
"Ottobre",
|
||||||
|
"Novembre",
|
||||||
|
"Dicembre"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Chiudi",
|
||||||
|
"create": {
|
||||||
|
"button": "Nuovo",
|
||||||
|
"submit": "Aggiungi",
|
||||||
|
"title": "Aggiungi nuovo elemento"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Modifica",
|
||||||
|
"submit": "Modifica",
|
||||||
|
"title": "Modifica elemento"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Errore del sistema."
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"info": "Gli elementi selezionati contengono valori diversi. Per modificare e impostare tutti gli elementi per questa selezione allo stesso valore, premi o clicca qui, altrimenti ogni cella manterrà il suo valore attuale.",
|
||||||
|
"noMulti": "Questa selezione può essere modificata individualmente, ma non se fa parte di un gruppo.",
|
||||||
|
"restore": "Annulla le modifiche",
|
||||||
|
"title": "Valori multipli"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Rimuovi",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Sei sicuro di voler cancellare %d righe?",
|
||||||
|
"1": "Sei sicuro di voler cancellare 1 riga?"
|
||||||
|
},
|
||||||
|
"submit": "Rimuovi",
|
||||||
|
"title": "Rimuovi"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thousands": ".",
|
||||||
|
"decimal": ",",
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Crea",
|
||||||
|
"columns": {
|
||||||
|
"search": "Colonna Cerca",
|
||||||
|
"visible": "Colonna Visibilità"
|
||||||
|
},
|
||||||
|
"name": "Nome:",
|
||||||
|
"order": "Ordinamento",
|
||||||
|
"paging": "Paginazione",
|
||||||
|
"scroller": "Scorri posizione",
|
||||||
|
"search": "Ricerca",
|
||||||
|
"searchBuilder": "Form di Ricerca",
|
||||||
|
"select": "Seleziona",
|
||||||
|
"title": "Crea nuovo Stato",
|
||||||
|
"toggleLabel": "Includi:"
|
||||||
|
},
|
||||||
|
"duplicateError": "Nome stato già presente",
|
||||||
|
"emptyError": "Il nome è obbligatorio",
|
||||||
|
"emptyStates": "Non ci sono stati salvati",
|
||||||
|
"removeConfirm": "Sei sicuro di eliminare lo Stato %s?",
|
||||||
|
"removeError": "Errore durante l'eliminazione dello Stato",
|
||||||
|
"removeJoiner": "e",
|
||||||
|
"removeSubmit": "Elimina",
|
||||||
|
"removeTitle": "Elimina Stato",
|
||||||
|
"renameButton": "Rinomina",
|
||||||
|
"renameLabel": "Nuovo nome per %s:",
|
||||||
|
"renameTitle": "Rinomina Stato"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "テーブルにデータがありません",
|
||||||
|
"info": " _TOTAL_ 件中 _START_ から _END_ まで表示",
|
||||||
|
"infoEmpty": " 0 件中 0 から 0 まで表示",
|
||||||
|
"infoFiltered": "(全 _MAX_ 件より抽出)",
|
||||||
|
"infoThousands": ",",
|
||||||
|
"lengthMenu": "_MENU_ 件表示",
|
||||||
|
"loadingRecords": "読み込み中...",
|
||||||
|
"processing": "処理中...",
|
||||||
|
"search": "検索:",
|
||||||
|
"zeroRecords": "一致するレコードがありません",
|
||||||
|
"paginate": {
|
||||||
|
"first": "先頭",
|
||||||
|
"last": "最終",
|
||||||
|
"next": "次",
|
||||||
|
"previous": "前"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": 列を昇順に並べ替えるにはアクティブにする",
|
||||||
|
"sortDescending": ": 列を降順に並べ替えるにはアクティブにする"
|
||||||
|
},
|
||||||
|
"thousands": ",",
|
||||||
|
"buttons": {
|
||||||
|
"colvis": "項目の表示\/非表示",
|
||||||
|
"csv": "CSVをダウンロード",
|
||||||
|
"collection": "コレクション"
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "条件を追加",
|
||||||
|
"button": {
|
||||||
|
"0": "カスタムサーチ",
|
||||||
|
"_": "カスタムサーチ (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "すべての条件をクリア",
|
||||||
|
"condition": "条件",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "次の日付以降",
|
||||||
|
"before": "次の日付以前",
|
||||||
|
"between": "次の期間に含まれる",
|
||||||
|
"empty": "空白",
|
||||||
|
"equals": "次の日付と等しい",
|
||||||
|
"not": "次の日付と等しくない",
|
||||||
|
"notBetween": "次の期間に含まれない",
|
||||||
|
"notEmpty": "空白ではない"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "次の値の間に含まれる",
|
||||||
|
"empty": "空白",
|
||||||
|
"equals": "次の値と等しい",
|
||||||
|
"gt": "次の値よりも大きい",
|
||||||
|
"gte": "次の値以上",
|
||||||
|
"lt": "次の値未満",
|
||||||
|
"lte": "次の値以下",
|
||||||
|
"not": "次の値と等しくない",
|
||||||
|
"notBetween": "次の値の間に含まれない",
|
||||||
|
"notEmpty": "空白ではない"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "次の文字を含む",
|
||||||
|
"empty": "空白",
|
||||||
|
"endsWith": "次の文字で終わる",
|
||||||
|
"equals": "次の文字と等しい",
|
||||||
|
"not": "次の文字と等しくない",
|
||||||
|
"notEmpty": "空白ではない",
|
||||||
|
"startsWith": "次の文字から始まる",
|
||||||
|
"notContains": "次の文字を含まない",
|
||||||
|
"notStartsWith": "次の文字で始まらない",
|
||||||
|
"notEndsWith": "次の文字で終わらない"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "項目",
|
||||||
|
"title": {
|
||||||
|
"0": "カスタムサーチ",
|
||||||
|
"_": "カスタムサーチ (%d)"
|
||||||
|
},
|
||||||
|
"value": "値"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "キャンセル",
|
||||||
|
"fillHorizontal": "横でセルを書き込む",
|
||||||
|
"fillVertical": "縦でセルを書き込む"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"emptyTable": "데이터가 없습니다",
|
||||||
|
"info": "_START_ - _END_ \/ _TOTAL_",
|
||||||
|
"infoEmpty": "0 - 0 \/ 0",
|
||||||
|
"infoFiltered": "(총 _MAX_ 개)",
|
||||||
|
"infoThousands": ",",
|
||||||
|
"lengthMenu": "페이지당 줄수 _MENU_",
|
||||||
|
"loadingRecords": "읽는중...",
|
||||||
|
"processing": "처리중...",
|
||||||
|
"search": "검색:",
|
||||||
|
"zeroRecords": "검색 결과가 없습니다",
|
||||||
|
"paginate": {
|
||||||
|
"first": "처음",
|
||||||
|
"last": "마지막",
|
||||||
|
"next": "다음",
|
||||||
|
"previous": "이전"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": 오름차순 정렬",
|
||||||
|
"sortDescending": ": 내림차순 정렬"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"copyKeys": "ctrl키 나 u2318 + C키로 테이블 데이터를 시스텝 복사판에서 복사하고 취소하려면 이 메시지를 클릭하거나 ESC키를 누르면됩니다. to copy the table data to your system clipboard. To cancel, click this message or press escape.",
|
||||||
|
"copySuccess": {
|
||||||
|
"_": "%d행을 복사판에서 복사됨",
|
||||||
|
"1": "1행을 복사판에서 복사됨"
|
||||||
|
},
|
||||||
|
"copyTitle": "복사판에서 복사",
|
||||||
|
"csv": "CSV",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "모든 행 보기",
|
||||||
|
"_": "%d행 보기"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "인쇄",
|
||||||
|
"collection": "집합 <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "컬럼 보기",
|
||||||
|
"colvisRestore": "보기 복원",
|
||||||
|
"copy": "복사",
|
||||||
|
"excel": "엑셀"
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "조건 추가",
|
||||||
|
"button": {
|
||||||
|
"0": "빌더 조회",
|
||||||
|
"_": "빌더 조회(%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "모두 지우기",
|
||||||
|
"condition": "조건",
|
||||||
|
"data": "데이터",
|
||||||
|
"deleteTitle": "필터 규칙을 삭제",
|
||||||
|
"logicAnd": "And",
|
||||||
|
"logicOr": "Or",
|
||||||
|
"title": {
|
||||||
|
"0": "빌더 조회",
|
||||||
|
"_": "빌더 조회(%d)"
|
||||||
|
},
|
||||||
|
"value": "값"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "취소",
|
||||||
|
"fill": "모든 셀에서 <i>%d<i>을(를) 삽입<\/i><\/i>",
|
||||||
|
"fillHorizontal": "수평 셀에서 값을 삽입",
|
||||||
|
"fillVertical": "수직 설에서 값을 삽입"
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"previous": "이전",
|
||||||
|
"next": "다음",
|
||||||
|
"hours": "시",
|
||||||
|
"minutes": "분",
|
||||||
|
"seconds": "초",
|
||||||
|
"unknown": "-",
|
||||||
|
"amPm": [
|
||||||
|
"오전",
|
||||||
|
"오후"
|
||||||
|
],
|
||||||
|
"weekdays": [
|
||||||
|
"일",
|
||||||
|
"월",
|
||||||
|
"화",
|
||||||
|
"수",
|
||||||
|
"목",
|
||||||
|
"금",
|
||||||
|
"토"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"1월",
|
||||||
|
"2월",
|
||||||
|
"3월",
|
||||||
|
"4월",
|
||||||
|
"5월",
|
||||||
|
"6월",
|
||||||
|
"7월",
|
||||||
|
"8월",
|
||||||
|
"9월",
|
||||||
|
"10월",
|
||||||
|
"11월",
|
||||||
|
"12월"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "닫기",
|
||||||
|
"create": {
|
||||||
|
"button": "추가",
|
||||||
|
"title": "항목 추가",
|
||||||
|
"submit": "완료"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "수정",
|
||||||
|
"title": "항목 수정",
|
||||||
|
"submit": "완료"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "삭제",
|
||||||
|
"title": "항목 삭제",
|
||||||
|
"submit": "완료"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "에러가 발생하였습니다 (<a target=\"\\\" rel=\"nofollow\" href=\"\\\">자세한 정보<\/a>)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,246 @@
|
|||||||
|
{
|
||||||
|
"lengthMenu": "_MENU_ resultaten weergeven",
|
||||||
|
"zeroRecords": "Geen resultaten gevonden",
|
||||||
|
"infoEmpty": "Geen resultaten om weer te geven",
|
||||||
|
"search": "Zoeken:",
|
||||||
|
"emptyTable": "Geen resultaten aanwezig in de tabel",
|
||||||
|
"infoThousands": ".",
|
||||||
|
"loadingRecords": "Een moment geduld aub - bezig met laden...",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Eerste",
|
||||||
|
"last": "Laatste",
|
||||||
|
"next": "Volgende",
|
||||||
|
"previous": "Vorige"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": activeer om kolom oplopend te sorteren",
|
||||||
|
"sortDescending": ": activeer om kolom aflopend te sorteren"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"fill": "Vul alle cellen met <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Vul cellen horizontaal",
|
||||||
|
"fillVertical": "Vul cellen verticaal",
|
||||||
|
"cancel": "Annuleren",
|
||||||
|
"info": "Voorbeeld automatisch aanvullen info"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"colvis": "Kolom zichtbaarheid",
|
||||||
|
"colvisRestore": "Herstel zichtbaarheid",
|
||||||
|
"copy": "Kopieer",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "1 regel naar klembord gekopieerd",
|
||||||
|
"_": "%ds regels naar klembord gekopieerd"
|
||||||
|
},
|
||||||
|
"copyTitle": "Kopieer naar klembord",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Toon alle regels",
|
||||||
|
"_": "Toon %d regels",
|
||||||
|
"1": "Toon 1 rij"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Print",
|
||||||
|
"copyKeys": "Klik ctrl of u2318 + C om de tabeldata to kopiëren naar je klembord. Om te annuleren klik hier of klik op escape.",
|
||||||
|
"collection": "Verzameling",
|
||||||
|
"createState": "Maak staat",
|
||||||
|
"removeAllStates": "Verwijder alle",
|
||||||
|
"removeState": "Verwijder",
|
||||||
|
"renameState": "Hernoem",
|
||||||
|
"savedStates": "Opgeslagen",
|
||||||
|
"updateState": "Bijwerken",
|
||||||
|
"stateRestore": "Preset %d"
|
||||||
|
},
|
||||||
|
"processing": "Verwerken...",
|
||||||
|
"decimal": ",",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Toevoegen",
|
||||||
|
"clearAll": "Verwijder alles",
|
||||||
|
"condition": "Conditie",
|
||||||
|
"data": "Data",
|
||||||
|
"deleteTitle": "Verwijder",
|
||||||
|
"value": "Waarde",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Na",
|
||||||
|
"before": "Voor",
|
||||||
|
"between": "Tussen",
|
||||||
|
"empty": "Leeg",
|
||||||
|
"equals": "Gelijk aan",
|
||||||
|
"not": "Niet",
|
||||||
|
"notBetween": "Niet tussen",
|
||||||
|
"notEmpty": "Niet leeg"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Tussen",
|
||||||
|
"empty": "Leeg",
|
||||||
|
"equals": "Gelijk aan",
|
||||||
|
"gt": "Groter dan",
|
||||||
|
"gte": "Groter dan of gelijk aan",
|
||||||
|
"lt": "Kleiner dan",
|
||||||
|
"lte": "kleiner dan of gelijk aan",
|
||||||
|
"not": "Niet",
|
||||||
|
"notBetween": "Niet tussen",
|
||||||
|
"notEmpty": "Niet leeg"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Bevat",
|
||||||
|
"empty": "Leeg",
|
||||||
|
"endsWith": "Eindigt met",
|
||||||
|
"equals": "Gelijk aan",
|
||||||
|
"not": "Niet",
|
||||||
|
"notEmpty": "Niet leeg",
|
||||||
|
"startsWith": "Start met",
|
||||||
|
"notContains": "Zonder",
|
||||||
|
"notEndsWith": "Eindigt niet met",
|
||||||
|
"notStartsWith": "Begint niet met"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "Gelijk aan",
|
||||||
|
"empty": "Leeg",
|
||||||
|
"contains": "Bevat",
|
||||||
|
"not": "Niet",
|
||||||
|
"notEmpty": "Niet leeg",
|
||||||
|
"without": "Zonder"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"logicAnd": "En",
|
||||||
|
"logicOr": "Of",
|
||||||
|
"button": {
|
||||||
|
"0": "Zoekwizard",
|
||||||
|
"_": "Zoekwizard (%d)"
|
||||||
|
},
|
||||||
|
"leftTitle": "Afwijkende criteria",
|
||||||
|
"rightTitle": "Criteria inspringen",
|
||||||
|
"title": {
|
||||||
|
"0": "Zoekwizard",
|
||||||
|
"_": "Zoekwizard (%d) "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Alles leegmaken",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Zoekpanelen",
|
||||||
|
"_": "Zoekpanelen (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Geen zoekpanelen",
|
||||||
|
"loadMessage": "Zoekpanelen laden...",
|
||||||
|
"title": "%d filters actief",
|
||||||
|
"showMessage": "Alles weergeven",
|
||||||
|
"collapseMessage": "Instorten"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"1": "1 cel geselecteerd",
|
||||||
|
"_": "%d cellen geselecteerd"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 kolom geselecteerd",
|
||||||
|
"_": "%d kolommen geselecteerd"
|
||||||
|
},
|
||||||
|
"rows": {
|
||||||
|
"1": "1 rij geselecteerd",
|
||||||
|
"_": "%d rijen geselecteerd"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thousands": ".",
|
||||||
|
"info": "_START_ tot _END_ van _TOTAL_ resultaten",
|
||||||
|
"infoFiltered": " (gefilterd uit _MAX_ resultaten)",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Vorige",
|
||||||
|
"next": "Volgende",
|
||||||
|
"hours": "Uur",
|
||||||
|
"minutes": "Minuut",
|
||||||
|
"seconds": "Seconde",
|
||||||
|
"unknown": "Onbekend",
|
||||||
|
"amPm": [
|
||||||
|
"vm",
|
||||||
|
"nm"
|
||||||
|
],
|
||||||
|
"weekdays": [
|
||||||
|
"Zo",
|
||||||
|
"Ma",
|
||||||
|
"Di",
|
||||||
|
"Wo",
|
||||||
|
"Do",
|
||||||
|
"Vr",
|
||||||
|
"Za"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"Januari",
|
||||||
|
"Februari",
|
||||||
|
"Maart",
|
||||||
|
"April",
|
||||||
|
"Mei",
|
||||||
|
"Juni",
|
||||||
|
"Juli",
|
||||||
|
"Augustus",
|
||||||
|
"September",
|
||||||
|
"Oktober",
|
||||||
|
"November",
|
||||||
|
"December"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Sluiten",
|
||||||
|
"create": {
|
||||||
|
"button": "Nieuw",
|
||||||
|
"title": "Voeg nieuwe gegevens toe",
|
||||||
|
"submit": "Toevoegen"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Wijzigen",
|
||||||
|
"title": "Wijzig gegevens",
|
||||||
|
"submit": "Wijzigen"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Verwijderen",
|
||||||
|
"title": "Verwijder",
|
||||||
|
"submit": "Verwijder",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Bent u zeker dat u %d rijen wil verwijderen?",
|
||||||
|
"1": "Bent u zeker dat u 1 rij wil verwijderen?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Er is een fout gebeurd"
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "Meerdere waarden",
|
||||||
|
"info": "De geselecteerde items bevatten verschillende waarden voor deze invoer. Om alle items voor deze invoer op dezelfde waarde te zetten, klik of tik hier, zoniet zullen de individuele waarden behouden blijven.",
|
||||||
|
"restore": "Wijzigingen ongedaan maken",
|
||||||
|
"noMulti": "Deze invoer kan individueel gewijzigd worden, maar niet als deel van een groep."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Aanmaken",
|
||||||
|
"columns": {
|
||||||
|
"search": "Zoeken in kolom",
|
||||||
|
"visible": "Kolom tonen"
|
||||||
|
},
|
||||||
|
"name": "Naam",
|
||||||
|
"order": "Sorteervolgorde",
|
||||||
|
"paging": "Paginering",
|
||||||
|
"scroller": "Meescrollen",
|
||||||
|
"search": "Zoeken",
|
||||||
|
"searchBuilder": "SearchBuilder",
|
||||||
|
"select": "Selecteer",
|
||||||
|
"title": "Nieuwe staat aanmaken",
|
||||||
|
"toggleLabel": "Bevat"
|
||||||
|
},
|
||||||
|
"duplicateError": "Staat bestaat al",
|
||||||
|
"emptyError": "Naam kan niet leeg zijn",
|
||||||
|
"emptyStates": "Geen beschikbare staten",
|
||||||
|
"removeConfirm": "Weet u zeker dat u deze wil verwijderen:",
|
||||||
|
"removeError": "De verwijdering is mislukt",
|
||||||
|
"removeJoiner": "en",
|
||||||
|
"removeSubmit": "Verwijder",
|
||||||
|
"removeTitle": "Verwijder staat",
|
||||||
|
"renameButton": "Hernoem",
|
||||||
|
"renameLabel": "Nieuwe naam voor staat",
|
||||||
|
"renameTitle": "Hernoem staat"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,240 @@
|
|||||||
|
{
|
||||||
|
"processing": "Przetwarzanie...",
|
||||||
|
"search": "Szukaj:",
|
||||||
|
"lengthMenu": "Pokaż _MENU_ pozycji",
|
||||||
|
"info": "Pozycje od _START_ do _END_ z _TOTAL_ łącznie",
|
||||||
|
"infoEmpty": "Pozycji 0 z 0 dostępnych",
|
||||||
|
"infoFiltered": "(filtrowanie spośród _MAX_ dostępnych pozycji)",
|
||||||
|
"loadingRecords": "Wczytywanie...",
|
||||||
|
"zeroRecords": "Nie znaleziono pasujących pozycji",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Pierwsza",
|
||||||
|
"previous": "Poprzednia",
|
||||||
|
"next": "Następna",
|
||||||
|
"last": "Ostatnia"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": aktywuj, by posortować kolumnę rosnąco",
|
||||||
|
"sortDescending": ": aktywuj, by posortować kolumnę malejąco"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Anuluj",
|
||||||
|
"fill": "Wypełnij wszystkie komórki <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Wypełnij komórki w poziomie",
|
||||||
|
"fillVertical": "Wypełnij komórki w pionie"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Zbiór <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "Widoczność kolumny",
|
||||||
|
"colvisRestore": "Przywróć widoczność",
|
||||||
|
"copy": "Kopiuj",
|
||||||
|
"copyKeys": "Naciśnij Ctrl lub u2318 + C, aby skopiować dane tabeli do schowka systemowego. <br \/> <br \/> Aby anulować, kliknij tę wiadomość lub naciśnij Esc.",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Skopiowano 1 wiersz do schowka",
|
||||||
|
"_": "Skopiowano %d wierszy do schowka"
|
||||||
|
},
|
||||||
|
"copyTitle": "Skopiuj do schowka",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Pokaż wszystkie wiersze",
|
||||||
|
"_": "Pokaż %d wierszy"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Drukuj",
|
||||||
|
"createState": "Utwórz stan",
|
||||||
|
"removeAllStates": "Usuń wszystkie stany",
|
||||||
|
"removeState": "Usuń",
|
||||||
|
"renameState": "Zmień nazwę",
|
||||||
|
"savedStates": "Zapisane stany",
|
||||||
|
"stateRestore": "Stan %d",
|
||||||
|
"updateState": "Aktualizuj"
|
||||||
|
},
|
||||||
|
"emptyTable": "Brak danych w tabeli",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Dodaj warunek",
|
||||||
|
"clearAll": "Wyczyść wszystko",
|
||||||
|
"condition": "Warunek",
|
||||||
|
"data": "Dane",
|
||||||
|
"button": {
|
||||||
|
"_": "Aktywne zapytania",
|
||||||
|
"0": "Budowanie zapytania"
|
||||||
|
},
|
||||||
|
"conditions": {
|
||||||
|
"array": {
|
||||||
|
"contains": "Zawiera",
|
||||||
|
"empty": "Pusta",
|
||||||
|
"equals": "Równa się",
|
||||||
|
"not": "Nie",
|
||||||
|
"notEmpty": "Nie pusta",
|
||||||
|
"without": "Bez"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"after": "Po",
|
||||||
|
"before": "Przed",
|
||||||
|
"between": "Pomiędzy",
|
||||||
|
"empty": "Pusto",
|
||||||
|
"equals": "Równa",
|
||||||
|
"not": "Nie",
|
||||||
|
"notBetween": "Nie pomiędzy",
|
||||||
|
"notEmpty": "Nie pusta"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Pomiędzy",
|
||||||
|
"empty": "Pusty",
|
||||||
|
"equals": "Równy",
|
||||||
|
"gt": "Większy niż",
|
||||||
|
"gte": "Równy lub większy niż",
|
||||||
|
"lt": "Mniejszy niż",
|
||||||
|
"lte": "Równy lub mniejszy niż",
|
||||||
|
"not": "Nie",
|
||||||
|
"notBetween": "Nie pomiędzy",
|
||||||
|
"notEmpty": "Nie pusty"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Zawiera",
|
||||||
|
"empty": "Pusty",
|
||||||
|
"endsWith": "Kończy się na",
|
||||||
|
"equals": "Równa się",
|
||||||
|
"not": "Nie",
|
||||||
|
"notEmpty": "Nie pusty",
|
||||||
|
"startsWith": "Zaczyna się od",
|
||||||
|
"notContains": "Nie zawiera",
|
||||||
|
"notStartsWith": "Nie zaczyna się od",
|
||||||
|
"notEndsWith": "Nie kończy się na"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deleteTitle": "Czyszczenie",
|
||||||
|
"leftTitle": "Lewy",
|
||||||
|
"logicAnd": "I",
|
||||||
|
"logicOr": "Lub",
|
||||||
|
"rightTitle": "Prawy",
|
||||||
|
"title": {
|
||||||
|
"_": "Aktywne zapytania",
|
||||||
|
"0": "Budowanie zapytania"
|
||||||
|
},
|
||||||
|
"value": "Wartość"
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"amPm": [
|
||||||
|
"am",
|
||||||
|
"pm"
|
||||||
|
],
|
||||||
|
"hours": "Godzina",
|
||||||
|
"minutes": "Minuta",
|
||||||
|
"next": "Następne",
|
||||||
|
"previous": "Poprzednie",
|
||||||
|
"seconds": "Sekunda",
|
||||||
|
"unknown": "nieznana",
|
||||||
|
"months": {
|
||||||
|
"0": "Styczeń",
|
||||||
|
"1": "Luty",
|
||||||
|
"10": "Listopad",
|
||||||
|
"11": "Grudzień",
|
||||||
|
"2": "Marzec",
|
||||||
|
"3": "Kwiecień",
|
||||||
|
"4": "Maj",
|
||||||
|
"5": "Czerwiec",
|
||||||
|
"6": "Lipiec",
|
||||||
|
"7": "Sierpień",
|
||||||
|
"8": "Wrzesień",
|
||||||
|
"9": "Październik"
|
||||||
|
},
|
||||||
|
"weekdays": [
|
||||||
|
"Nd",
|
||||||
|
"Pn",
|
||||||
|
"Wt",
|
||||||
|
"Śr",
|
||||||
|
"Czw",
|
||||||
|
"Pt",
|
||||||
|
"So"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Zamknij",
|
||||||
|
"create": {
|
||||||
|
"button": "Dodaj",
|
||||||
|
"submit": "Dodaj",
|
||||||
|
"title": "Dodawanie nowego wpisu"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Edytuj",
|
||||||
|
"submit": "Aktualizuj",
|
||||||
|
"title": "Aktualizacja wpisu"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Nastąpił błąd systemu (<a target=\"\\\" rel=\"\\ nofollow\" href=\"\\\">Więcej informacji<\\\/a>).<\/a>"
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"info": "Wybrane pole zawiera wiele elementów z różnymi wartościami. Aby zmienić ich wartość kliknij w nie, inaczej zachowane zostaną ich wartości domyślne.",
|
||||||
|
"noMulti": "Ta wartość może być edytowana oddzielnie - niezależnie od grupy.",
|
||||||
|
"restore": "Cofnij zmiany",
|
||||||
|
"title": "Pole z wieloma wartościami"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Usuń",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Czy na pewno chcesz usunąć %d rzędów?",
|
||||||
|
"1": "Czy na pewno chcesz usunąć 1 rząd?"
|
||||||
|
},
|
||||||
|
"submit": "Usuń",
|
||||||
|
"title": "Usuwanie"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Wyczyść wszystkie",
|
||||||
|
"collapse": {
|
||||||
|
"_": "Aktywne grupowania (%d)",
|
||||||
|
"0": "Grupowanie"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Brak paneli wyszukań",
|
||||||
|
"loadMessage": "Ładuję panele wyszukań",
|
||||||
|
"title": "Aktywne filtry",
|
||||||
|
"showMessage": "Pokaż wszystko",
|
||||||
|
"collapseMessage": "Rozwiń wszystko"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"_": "zaznaczono %d komórek",
|
||||||
|
"1": "zaznaczono %d komórkę"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"_": "zaznaczono %d kolumn",
|
||||||
|
"1": "zaznaczono %d kolumnę"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Utwórz",
|
||||||
|
"columns": {
|
||||||
|
"search": "Wyszukiwanie kolumny",
|
||||||
|
"visible": "Widoczność kolumny"
|
||||||
|
},
|
||||||
|
"name": "Nazwa:",
|
||||||
|
"order": "Sortowanie",
|
||||||
|
"paging": "Stronicowanie",
|
||||||
|
"scroller": "Przewijanie",
|
||||||
|
"search": "Szukanie",
|
||||||
|
"searchBuilder": "Tworzenie zapytań",
|
||||||
|
"select": "Wybieranie",
|
||||||
|
"title": "Utwórz nowy stan",
|
||||||
|
"toggleLabel": "Zawiera:"
|
||||||
|
},
|
||||||
|
"duplicateError": "Stan o tej nazwie już istnieje.",
|
||||||
|
"emptyError": "Nazwa nie może być pusta.",
|
||||||
|
"emptyStates": "Brak zapisanych stanów",
|
||||||
|
"removeConfirm": "Czy na pewno chcesz usunąć %s?",
|
||||||
|
"removeError": "Nie udało się usunąć stanu.",
|
||||||
|
"removeJoiner": "oraz",
|
||||||
|
"removeSubmit": "Usuń",
|
||||||
|
"removeTitle": "Usuń stan",
|
||||||
|
"renameButton": "Zmień nazwę",
|
||||||
|
"renameLabel": "Nowa nazwa dla %s:",
|
||||||
|
"renameTitle": "Zmień nazwę stanu"
|
||||||
|
},
|
||||||
|
"decimal": ",",
|
||||||
|
"infoThousands": " ",
|
||||||
|
"thousands": " "
|
||||||
|
}
|
@ -0,0 +1,247 @@
|
|||||||
|
{
|
||||||
|
"processing": "Подождите...",
|
||||||
|
"search": "Поиск:",
|
||||||
|
"lengthMenu": "Показать _MENU_ записей",
|
||||||
|
"info": "Записи с _START_ до _END_ из _TOTAL_ записей",
|
||||||
|
"infoEmpty": "Записи с 0 до 0 из 0 записей",
|
||||||
|
"infoFiltered": "(отфильтровано из _MAX_ записей)",
|
||||||
|
"loadingRecords": "Загрузка записей...",
|
||||||
|
"zeroRecords": "Записи отсутствуют.",
|
||||||
|
"emptyTable": "В таблице отсутствуют данные",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Первая",
|
||||||
|
"previous": "Предыдущая",
|
||||||
|
"next": "Следующая",
|
||||||
|
"last": "Последняя"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": активировать для сортировки столбца по возрастанию",
|
||||||
|
"sortDescending": ": активировать для сортировки столбца по убыванию"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"rows": {
|
||||||
|
"_": "Выбрано записей: %d",
|
||||||
|
"1": "Выбрана одна запись"
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"_": "Выбрано %d ячеек",
|
||||||
|
"1": "Выбрана 1 ячейка "
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "Выбран 1 столбец ",
|
||||||
|
"_": "Выбрано %d столбцов "
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"conditions": {
|
||||||
|
"string": {
|
||||||
|
"startsWith": "Начинается с",
|
||||||
|
"contains": "Содержит",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"endsWith": "Заканчивается на",
|
||||||
|
"equals": "Равно",
|
||||||
|
"not": "Не",
|
||||||
|
"notEmpty": "Не пусто",
|
||||||
|
"notContains": "Не содержит",
|
||||||
|
"notStartsWith": "Не начинается на",
|
||||||
|
"notEndsWith": "Не заканчивается на"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"after": "После",
|
||||||
|
"before": "До",
|
||||||
|
"between": "Между",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"equals": "Равно",
|
||||||
|
"not": "Не",
|
||||||
|
"notBetween": "Не между",
|
||||||
|
"notEmpty": "Не пусто"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"empty": "Пусто",
|
||||||
|
"equals": "Равно",
|
||||||
|
"gt": "Больше чем",
|
||||||
|
"gte": "Больше, чем равно",
|
||||||
|
"lt": "Меньше чем",
|
||||||
|
"lte": "Меньше, чем равно",
|
||||||
|
"not": "Не",
|
||||||
|
"notEmpty": "Не пусто",
|
||||||
|
"between": "Между",
|
||||||
|
"notBetween": "Не между ними"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "Равно",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"contains": "Содержит",
|
||||||
|
"not": "Не равно",
|
||||||
|
"notEmpty": "Не пусто",
|
||||||
|
"without": "Без"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Данные",
|
||||||
|
"deleteTitle": "Удалить условие фильтрации",
|
||||||
|
"logicAnd": "И",
|
||||||
|
"logicOr": "Или",
|
||||||
|
"title": {
|
||||||
|
"0": "Конструктор поиска",
|
||||||
|
"_": "Конструктор поиска (%d)"
|
||||||
|
},
|
||||||
|
"value": "Значение",
|
||||||
|
"add": "Добавить условие",
|
||||||
|
"button": {
|
||||||
|
"0": "Конструктор поиска",
|
||||||
|
"_": "Конструктор поиска (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Очистить всё",
|
||||||
|
"condition": "Условие",
|
||||||
|
"leftTitle": "Превосходные критерии",
|
||||||
|
"rightTitle": "Критерии отступа"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Очистить всё",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Панели поиска",
|
||||||
|
"_": "Панели поиска (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Нет панелей поиска",
|
||||||
|
"loadMessage": "Загрузка панелей поиска",
|
||||||
|
"title": "Фильтры активны - %d",
|
||||||
|
"showMessage": "Показать все",
|
||||||
|
"collapseMessage": "Скрыть все"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Печать",
|
||||||
|
"collection": "Коллекция <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "Видимость столбцов",
|
||||||
|
"colvisRestore": "Восстановить видимость",
|
||||||
|
"copy": "Копировать",
|
||||||
|
"copyTitle": "Скопировать в буфер обмена",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Показать все строки",
|
||||||
|
"_": "Показать %d строк",
|
||||||
|
"1": "Показать 1 строку"
|
||||||
|
},
|
||||||
|
"removeState": "Удалить",
|
||||||
|
"renameState": "Переименовать",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Строка скопирована в буфер обмена",
|
||||||
|
"_": "Скопировано %d строк в буфер обмена"
|
||||||
|
},
|
||||||
|
"createState": "Создать состояние",
|
||||||
|
"removeAllStates": "Удалить все состояния",
|
||||||
|
"savedStates": "Сохраненные состояния",
|
||||||
|
"stateRestore": "Состояние %d",
|
||||||
|
"updateState": "Обновить",
|
||||||
|
"copyKeys": "Нажмите ctrl или u2318 + C, чтобы скопировать данные таблицы в буфер обмена. Для отмены, щелкните по сообщению или нажмите escape."
|
||||||
|
},
|
||||||
|
"decimal": ".",
|
||||||
|
"infoThousands": ",",
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Отменить",
|
||||||
|
"fill": "Заполнить все ячейки <i>%d<i><\/i><\/i>",
|
||||||
|
"fillHorizontal": "Заполнить ячейки по горизонтали",
|
||||||
|
"fillVertical": "Заполнить ячейки по вертикали",
|
||||||
|
"info": "Информация"
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"previous": "Предыдущий",
|
||||||
|
"next": "Следующий",
|
||||||
|
"hours": "Часы",
|
||||||
|
"minutes": "Минуты",
|
||||||
|
"seconds": "Секунды",
|
||||||
|
"unknown": "Неизвестный",
|
||||||
|
"amPm": [
|
||||||
|
"AM",
|
||||||
|
"PM"
|
||||||
|
],
|
||||||
|
"months": {
|
||||||
|
"0": "Январь",
|
||||||
|
"1": "Февраль",
|
||||||
|
"10": "Ноябрь",
|
||||||
|
"11": "Декабрь",
|
||||||
|
"2": "Март",
|
||||||
|
"3": "Апрель",
|
||||||
|
"4": "Май",
|
||||||
|
"5": "Июнь",
|
||||||
|
"6": "Июль",
|
||||||
|
"7": "Август",
|
||||||
|
"8": "Сентябрь",
|
||||||
|
"9": "Октябрь"
|
||||||
|
},
|
||||||
|
"weekdays": [
|
||||||
|
"Вс",
|
||||||
|
"Пн",
|
||||||
|
"Вт",
|
||||||
|
"Ср",
|
||||||
|
"Чт",
|
||||||
|
"Пт",
|
||||||
|
"Сб"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "Закрыть",
|
||||||
|
"create": {
|
||||||
|
"button": "Новый",
|
||||||
|
"title": "Создать новую запись",
|
||||||
|
"submit": "Создать"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Изменить",
|
||||||
|
"title": "Изменить запись",
|
||||||
|
"submit": "Изменить"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Удалить",
|
||||||
|
"title": "Удалить",
|
||||||
|
"submit": "Удалить",
|
||||||
|
"confirm": {
|
||||||
|
"_": "Вы точно хотите удалить %d строк?",
|
||||||
|
"1": "Вы точно хотите удалить 1 строку?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"restore": "Отменить изменения",
|
||||||
|
"title": "Несколько значений",
|
||||||
|
"info": "Выбранные элементы содержат разные значения для этого входа. Чтобы отредактировать и установить для всех элементов этого ввода одинаковое значение, нажмите или коснитесь здесь, в противном случае они сохранят свои индивидуальные значения.",
|
||||||
|
"noMulti": "Это поле должно редактироваться отдельно, а не как часть группы"
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "Возникла системная ошибка (<a target=\"\\\" rel=\"nofollow\" href=\"\\\">Подробнее<\/a>)."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"searchPlaceholder": "Что ищете?",
|
||||||
|
"stateRestore": {
|
||||||
|
"creationModal": {
|
||||||
|
"button": "Создать",
|
||||||
|
"search": "Поиск",
|
||||||
|
"columns": {
|
||||||
|
"search": "Поиск по столбцам",
|
||||||
|
"visible": "Видимость столбцов"
|
||||||
|
},
|
||||||
|
"name": "Имя:",
|
||||||
|
"order": "Сортировка",
|
||||||
|
"paging": "Страницы",
|
||||||
|
"scroller": "Позиция прокрутки",
|
||||||
|
"searchBuilder": "Редактор поиска",
|
||||||
|
"select": "Выделение",
|
||||||
|
"title": "Создать новое состояние",
|
||||||
|
"toggleLabel": "Включает:"
|
||||||
|
},
|
||||||
|
"removeJoiner": "и",
|
||||||
|
"removeSubmit": "Удалить",
|
||||||
|
"renameButton": "Переименовать",
|
||||||
|
"duplicateError": "Состояние с таким именем уже существует.",
|
||||||
|
"emptyError": "Имя не может быть пустым.",
|
||||||
|
"emptyStates": "Нет сохраненных состояний",
|
||||||
|
"removeConfirm": "Вы уверены, что хотите удалить %s?",
|
||||||
|
"removeError": "Не удалось удалить состояние.",
|
||||||
|
"removeTitle": "Удалить состояние",
|
||||||
|
"renameLabel": "Новое имя для %s:",
|
||||||
|
"renameTitle": "Переименовать состояние"
|
||||||
|
},
|
||||||
|
"thousands": " "
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
{
|
||||||
|
"lengthMenu": "Показати _MENU_ записів",
|
||||||
|
"infoFiltered": "(відфільтровано з _MAX_ записів)",
|
||||||
|
"search": "Пошук:",
|
||||||
|
"paginate": {
|
||||||
|
"first": "Перша",
|
||||||
|
"previous": "Попередня",
|
||||||
|
"next": "Наступна",
|
||||||
|
"last": "Остання"
|
||||||
|
},
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ": активуйте, щоб сортувати колонку за зростанням",
|
||||||
|
"sortDescending": ": активуйте, щоб сортувати колонку за спаданням"
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "Відміна",
|
||||||
|
"fill": "Заповнити всі клітинки з <i>%d<\/i>",
|
||||||
|
"fillHorizontal": "Заповнити клітинки горизонтально",
|
||||||
|
"fillVertical": "Заповнити клітинки вертикально"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"collection": "Список <span class=\"ui-button-icon-primary ui-icon ui-icon-triangle-1-s\"><\/span>",
|
||||||
|
"colvis": "Видимість колонки",
|
||||||
|
"colvisRestore": "Відновити видимість",
|
||||||
|
"copy": "Копіювати",
|
||||||
|
"copyKeys": "Нажміть ctrl або u2318 + C щоб копіювати інформацію з таблиці до вашого буферу обміну.<br \/><br \/>Щоб відмінити нажміть на це повідомлення або Esc",
|
||||||
|
"copySuccess": {
|
||||||
|
"1": "Скопійовано 1 рядок в буфер обміну",
|
||||||
|
"_": "Скопійовано %d рядків в буфер обміну"
|
||||||
|
},
|
||||||
|
"copyTitle": "Копіювати в буфер обміну",
|
||||||
|
"csv": "CSV",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "Показати усі рядки",
|
||||||
|
"_": "Показати %d рядки"
|
||||||
|
},
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "Друкувати"
|
||||||
|
},
|
||||||
|
"emptyTable": "Ця таблиця не містить даних",
|
||||||
|
"info": "Показано від _START_ по _END_ з _TOTAL_ записів",
|
||||||
|
"infoEmpty": "Показано від 0 по 0 з 0 записів",
|
||||||
|
"infoThousands": ",",
|
||||||
|
"loadingRecords": "Завантаження",
|
||||||
|
"processing": "Опрацювання...",
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "Додати умову",
|
||||||
|
"button": {
|
||||||
|
"0": "Розширений пошук",
|
||||||
|
"_": "Розширений пошук (%d)"
|
||||||
|
},
|
||||||
|
"clearAll": "Очистити все",
|
||||||
|
"condition": "Умова",
|
||||||
|
"conditions": {
|
||||||
|
"date": {
|
||||||
|
"after": "Після",
|
||||||
|
"before": "До",
|
||||||
|
"between": "Між",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"equals": "Дорівнює",
|
||||||
|
"not": "Не",
|
||||||
|
"notBetween": "Не між",
|
||||||
|
"notEmpty": "Не пусто"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "Між",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"equals": "Дорівнює",
|
||||||
|
"gt": "Більше ніж",
|
||||||
|
"gte": "Більше або дорівнює",
|
||||||
|
"lt": "Менше ніж",
|
||||||
|
"lte": "Менше або дорівнює",
|
||||||
|
"not": "Не",
|
||||||
|
"notBetween": "Не між",
|
||||||
|
"notEmpty": "Не пусто"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "Містить",
|
||||||
|
"empty": "Пусто",
|
||||||
|
"endsWith": "Закінчується з",
|
||||||
|
"equals": "Дорівнює",
|
||||||
|
"not": "Не",
|
||||||
|
"notEmpty": "Не пусто",
|
||||||
|
"startsWith": "Починається з",
|
||||||
|
"notContains": "Не містить",
|
||||||
|
"notStartsWith": "Не починається з",
|
||||||
|
"notEndsWith": "Не закінчується на"
|
||||||
|
},
|
||||||
|
"array": {
|
||||||
|
"equals": "Дорівнює",
|
||||||
|
"empty": "Пустий",
|
||||||
|
"contains": "Містить",
|
||||||
|
"not": "Не",
|
||||||
|
"notEmpty": "Не пустий",
|
||||||
|
"without": "Без"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "Дата",
|
||||||
|
"deleteTitle": "Видалити правило фільтрування",
|
||||||
|
"leftTitle": "Відступні критерії",
|
||||||
|
"logicAnd": "I",
|
||||||
|
"logicOr": "Або",
|
||||||
|
"rightTitle": "Відступні критерії",
|
||||||
|
"title": {
|
||||||
|
"0": "Розширений пошук",
|
||||||
|
"_": "Розширений пошук (%d)"
|
||||||
|
},
|
||||||
|
"value": "Значення"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"clearMessage": "Очистити все",
|
||||||
|
"collapse": {
|
||||||
|
"0": "Пошукові Панелі",
|
||||||
|
"_": "Пошукові Панелі (%d)"
|
||||||
|
},
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"emptyPanes": "Немає Пошукових Панелей",
|
||||||
|
"loadMessage": "Завантаження Пошукових Панелей",
|
||||||
|
"title": "Активній фільтри - %d",
|
||||||
|
"showMessage": "Показати всі",
|
||||||
|
"collapseMessage": "Приховати всі"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"cells": {
|
||||||
|
"1": "1 клітинку вибрано",
|
||||||
|
"_": "%d клітинок вибрано"
|
||||||
|
},
|
||||||
|
"columns": {
|
||||||
|
"1": "1 колонку вибрано",
|
||||||
|
"_": "%d колонок вибрано"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"thousands": ",",
|
||||||
|
"zeroRecords": "Не знайдено жодних записів",
|
||||||
|
"editor": {
|
||||||
|
"close": "Закрити",
|
||||||
|
"create": {
|
||||||
|
"button": "Cтворити нову",
|
||||||
|
"title": "Cтворити новий запис",
|
||||||
|
"submit": "Cтворити"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "Редагувати",
|
||||||
|
"title": "Редагувати запис",
|
||||||
|
"submit": "Оновити"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "Видалити",
|
||||||
|
"title": "Видалити",
|
||||||
|
"submit": "Видалити"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"datetime": {
|
||||||
|
"minutes": "Хвилина",
|
||||||
|
"months": {
|
||||||
|
"0": "Січень",
|
||||||
|
"1": "Лютий",
|
||||||
|
"10": "Листопад",
|
||||||
|
"11": "Грудень",
|
||||||
|
"2": "Березень",
|
||||||
|
"3": "Квітень",
|
||||||
|
"4": "Травень",
|
||||||
|
"5": "Червень",
|
||||||
|
"6": "Липень",
|
||||||
|
"7": "Серпень",
|
||||||
|
"8": "Вересень",
|
||||||
|
"9": "Жовтень"
|
||||||
|
},
|
||||||
|
"next": "Наступні",
|
||||||
|
"previous": "Попередні",
|
||||||
|
"seconds": "Секунда",
|
||||||
|
"unknown": "-",
|
||||||
|
"weekdays": [
|
||||||
|
"Неділя",
|
||||||
|
"Понеділок",
|
||||||
|
"Вівторок",
|
||||||
|
"Середа",
|
||||||
|
"Четверг",
|
||||||
|
"П'ятниця",
|
||||||
|
"Субота"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"searchPlaceholder": "Пошук"
|
||||||
|
}
|
@ -0,0 +1,240 @@
|
|||||||
|
{
|
||||||
|
"processing": "處理中...",
|
||||||
|
"loadingRecords": "載入中...",
|
||||||
|
"paginate": {
|
||||||
|
"first": "第一頁",
|
||||||
|
"previous": "上一頁",
|
||||||
|
"next": "下一頁",
|
||||||
|
"last": "最後一頁"
|
||||||
|
},
|
||||||
|
"emptyTable": "目前沒有資料",
|
||||||
|
"datetime": {
|
||||||
|
"previous": "上一頁",
|
||||||
|
"next": "下一頁",
|
||||||
|
"hours": "時",
|
||||||
|
"minutes": "分",
|
||||||
|
"seconds": "秒",
|
||||||
|
"amPm": [
|
||||||
|
"上午",
|
||||||
|
"下午"
|
||||||
|
],
|
||||||
|
"unknown": "未知",
|
||||||
|
"weekdays": [
|
||||||
|
"週日",
|
||||||
|
"週一",
|
||||||
|
"週二",
|
||||||
|
"週三",
|
||||||
|
"週四",
|
||||||
|
"週五",
|
||||||
|
"週六"
|
||||||
|
],
|
||||||
|
"months": [
|
||||||
|
"一月",
|
||||||
|
"二月",
|
||||||
|
"三月",
|
||||||
|
"四月",
|
||||||
|
"五月",
|
||||||
|
"六月",
|
||||||
|
"七月",
|
||||||
|
"八月",
|
||||||
|
"九月",
|
||||||
|
"十月",
|
||||||
|
"十一月",
|
||||||
|
"十二月"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"searchBuilder": {
|
||||||
|
"add": "新增條件",
|
||||||
|
"condition": "條件",
|
||||||
|
"button": {
|
||||||
|
"_": "複合查詢 (%d)",
|
||||||
|
"0": "複合查詢"
|
||||||
|
},
|
||||||
|
"clearAll": "清空",
|
||||||
|
"conditions": {
|
||||||
|
"array": {
|
||||||
|
"contains": "含有",
|
||||||
|
"equals": "等於",
|
||||||
|
"empty": "空值",
|
||||||
|
"not": "不等於",
|
||||||
|
"notEmpty": "非空值",
|
||||||
|
"without": "不含"
|
||||||
|
},
|
||||||
|
"date": {
|
||||||
|
"after": "大於",
|
||||||
|
"before": "小於",
|
||||||
|
"between": "在其中",
|
||||||
|
"empty": "為空",
|
||||||
|
"equals": "等於",
|
||||||
|
"not": "不為",
|
||||||
|
"notBetween": "不在其中",
|
||||||
|
"notEmpty": "不為空"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"between": "在其中",
|
||||||
|
"empty": "為空",
|
||||||
|
"equals": "等於",
|
||||||
|
"gt": "大於",
|
||||||
|
"gte": "大於等於",
|
||||||
|
"lt": "小於",
|
||||||
|
"lte": "小於等於",
|
||||||
|
"not": "不為",
|
||||||
|
"notBetween": "不在其中",
|
||||||
|
"notEmpty": "不為空"
|
||||||
|
},
|
||||||
|
"string": {
|
||||||
|
"contains": "含有",
|
||||||
|
"empty": "為空",
|
||||||
|
"endsWith": "字尾為",
|
||||||
|
"equals": "等於",
|
||||||
|
"not": "不為",
|
||||||
|
"notEmpty": "不為空",
|
||||||
|
"startsWith": "字首為",
|
||||||
|
"notContains": "不含",
|
||||||
|
"notStartsWith": "開頭不是",
|
||||||
|
"notEndsWith": "結尾不是"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"data": "欄位",
|
||||||
|
"leftTitle": "群組條件",
|
||||||
|
"logicAnd": "且",
|
||||||
|
"logicOr": "或",
|
||||||
|
"rightTitle": "取消群組",
|
||||||
|
"title": {
|
||||||
|
"_": "複合查詢 (%d)",
|
||||||
|
"0": "複合查詢"
|
||||||
|
},
|
||||||
|
"value": "內容",
|
||||||
|
"deleteTitle": "刪除篩選條件"
|
||||||
|
},
|
||||||
|
"editor": {
|
||||||
|
"close": "關閉",
|
||||||
|
"create": {
|
||||||
|
"button": "新增",
|
||||||
|
"title": "新增資料",
|
||||||
|
"submit": "送出新增"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"button": "刪除",
|
||||||
|
"title": "刪除資料",
|
||||||
|
"submit": "送出刪除",
|
||||||
|
"confirm": {
|
||||||
|
"_": "您確定要刪除您所選取的 %d 筆資料嗎?",
|
||||||
|
"1": "您確定要刪除您所選取的 1 筆資料嗎?"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"system": "系統發生錯誤(更多資訊)"
|
||||||
|
},
|
||||||
|
"edit": {
|
||||||
|
"button": "修改",
|
||||||
|
"title": "修改資料",
|
||||||
|
"submit": "送出修改"
|
||||||
|
},
|
||||||
|
"multi": {
|
||||||
|
"title": "多重值",
|
||||||
|
"info": "您所選擇的多筆資料中,此欄位包含了不同的值。若您想要將它們都改為同一個值,可以在此輸入,要不然它們會保留各自原本的值。",
|
||||||
|
"restore": "復原",
|
||||||
|
"noMulti": "此輸入欄需單獨輸入,不容許多筆資料一起修改"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoFill": {
|
||||||
|
"cancel": "取消"
|
||||||
|
},
|
||||||
|
"buttons": {
|
||||||
|
"copySuccess": {
|
||||||
|
"_": "複製了 %d 筆資料",
|
||||||
|
"1": "複製了 1 筆資料"
|
||||||
|
},
|
||||||
|
"copyTitle": "已經複製到剪貼簿",
|
||||||
|
"excel": "Excel",
|
||||||
|
"pdf": "PDF",
|
||||||
|
"print": "列印",
|
||||||
|
"copy": "複製",
|
||||||
|
"colvis": "欄位顯示",
|
||||||
|
"colvisRestore": "重置欄位顯示",
|
||||||
|
"csv": "CSV",
|
||||||
|
"pageLength": {
|
||||||
|
"-1": "顯示全部",
|
||||||
|
"_": "顯示 %d 筆"
|
||||||
|
},
|
||||||
|
"createState": "建立狀態",
|
||||||
|
"removeAllStates": "移除所有狀態",
|
||||||
|
"removeState": "移除",
|
||||||
|
"renameState": "重新命名",
|
||||||
|
"savedStates": "儲存狀態",
|
||||||
|
"stateRestore": "狀態 %d",
|
||||||
|
"updateState": "更新",
|
||||||
|
"collection": "更多"
|
||||||
|
},
|
||||||
|
"searchPanes": {
|
||||||
|
"collapse": {
|
||||||
|
"_": "搜尋面版 (%d)",
|
||||||
|
"0": "搜尋面版"
|
||||||
|
},
|
||||||
|
"emptyPanes": "沒搜尋面版",
|
||||||
|
"loadMessage": "載入搜尋面版中...",
|
||||||
|
"clearMessage": "清空",
|
||||||
|
"count": "{total}",
|
||||||
|
"countFiltered": "{shown} ({total})",
|
||||||
|
"showMessage": "顯示全部",
|
||||||
|
"collapseMessage": "摺疊全部",
|
||||||
|
"title": "篩選條件 - %d"
|
||||||
|
},
|
||||||
|
"stateRestore": {
|
||||||
|
"emptyError": "名稱不能空白。",
|
||||||
|
"creationModal": {
|
||||||
|
"button": "建立",
|
||||||
|
"columns": {
|
||||||
|
"search": "欄位搜尋",
|
||||||
|
"visible": "欄位顯示"
|
||||||
|
},
|
||||||
|
"name": "名稱:",
|
||||||
|
"order": "排序",
|
||||||
|
"paging": "分頁",
|
||||||
|
"scroller": "卷軸位置",
|
||||||
|
"search": "搜尋",
|
||||||
|
"searchBuilder": "複合查詢",
|
||||||
|
"select": "選擇",
|
||||||
|
"title": "建立新狀態",
|
||||||
|
"toggleLabel": "包含:"
|
||||||
|
},
|
||||||
|
"duplicateError": "此狀態名稱已經存在。",
|
||||||
|
"emptyStates": "名稱不可空白。",
|
||||||
|
"removeConfirm": "確定要移除 %s 嗎?",
|
||||||
|
"removeError": "移除狀態失敗。",
|
||||||
|
"removeJoiner": "和",
|
||||||
|
"removeSubmit": "移除",
|
||||||
|
"removeTitle": "移除狀態",
|
||||||
|
"renameButton": "重新命名",
|
||||||
|
"renameLabel": "%s 的新名稱:",
|
||||||
|
"renameTitle": "重新命名狀態"
|
||||||
|
},
|
||||||
|
"select": {
|
||||||
|
"columns": {
|
||||||
|
"_": "選擇了 %d 欄資料",
|
||||||
|
"1": "選擇了 1 欄資料"
|
||||||
|
},
|
||||||
|
"rows": {
|
||||||
|
"1": "選擇了 1 筆資料",
|
||||||
|
"_": "選擇了 %d 筆資料"
|
||||||
|
},
|
||||||
|
"cells": {
|
||||||
|
"1": "選擇了 1 格資料",
|
||||||
|
"_": "選擇了 %d 格資料"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zeroRecords": "沒有符合的資料",
|
||||||
|
"aria": {
|
||||||
|
"sortAscending": ":升冪排列",
|
||||||
|
"sortDescending": ":降冪排列"
|
||||||
|
},
|
||||||
|
"info": "顯示第 _START_ 至 _END_ 筆結果,共 _TOTAL_ 筆",
|
||||||
|
"infoEmpty": "顯示第 0 至 0 筆結果,共 0 筆",
|
||||||
|
"infoThousands": ",",
|
||||||
|
"lengthMenu": "顯示 _MENU_ 筆結果",
|
||||||
|
"search": "搜尋:",
|
||||||
|
"searchPlaceholder": "請輸入關鍵字",
|
||||||
|
"thousands": ",",
|
||||||
|
"infoFiltered": "(從 _MAX_ 筆結果中篩選)"
|
||||||
|
}
|
@ -0,0 +1,191 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Czech [cs]
|
||||||
|
//! author : petrbela : https://github.com/petrbela
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var months = {
|
||||||
|
format: 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
standalone:
|
||||||
|
'ledna_února_března_dubna_května_června_července_srpna_září_října_listopadu_prosince'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_'),
|
||||||
|
monthsParse = [
|
||||||
|
/^led/i,
|
||||||
|
/^úno/i,
|
||||||
|
/^bře/i,
|
||||||
|
/^dub/i,
|
||||||
|
/^kvě/i,
|
||||||
|
/^(čvn|červen$|června)/i,
|
||||||
|
/^(čvc|červenec|července)/i,
|
||||||
|
/^srp/i,
|
||||||
|
/^zář/i,
|
||||||
|
/^říj/i,
|
||||||
|
/^lis/i,
|
||||||
|
/^pro/i,
|
||||||
|
],
|
||||||
|
// NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
|
||||||
|
// Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
|
||||||
|
monthsRegex =
|
||||||
|
/^(leden|únor|březen|duben|květen|červenec|července|červen|června|srpen|září|říjen|listopad|prosinec|led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i;
|
||||||
|
|
||||||
|
function plural(n) {
|
||||||
|
return n > 1 && n < 5 && ~~(n / 10) !== 1;
|
||||||
|
}
|
||||||
|
function translate(number, withoutSuffix, key, isFuture) {
|
||||||
|
var result = number + ' ';
|
||||||
|
switch (key) {
|
||||||
|
case 's': // a few seconds / in a few seconds / a few seconds ago
|
||||||
|
return withoutSuffix || isFuture ? 'pár sekund' : 'pár sekundami';
|
||||||
|
case 'ss': // 9 seconds / in 9 seconds / 9 seconds ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'sekundy' : 'sekund');
|
||||||
|
} else {
|
||||||
|
return result + 'sekundami';
|
||||||
|
}
|
||||||
|
case 'm': // a minute / in a minute / a minute ago
|
||||||
|
return withoutSuffix ? 'minuta' : isFuture ? 'minutu' : 'minutou';
|
||||||
|
case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'minuty' : 'minut');
|
||||||
|
} else {
|
||||||
|
return result + 'minutami';
|
||||||
|
}
|
||||||
|
case 'h': // an hour / in an hour / an hour ago
|
||||||
|
return withoutSuffix ? 'hodina' : isFuture ? 'hodinu' : 'hodinou';
|
||||||
|
case 'hh': // 9 hours / in 9 hours / 9 hours ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'hodiny' : 'hodin');
|
||||||
|
} else {
|
||||||
|
return result + 'hodinami';
|
||||||
|
}
|
||||||
|
case 'd': // a day / in a day / a day ago
|
||||||
|
return withoutSuffix || isFuture ? 'den' : 'dnem';
|
||||||
|
case 'dd': // 9 days / in 9 days / 9 days ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'dny' : 'dní');
|
||||||
|
} else {
|
||||||
|
return result + 'dny';
|
||||||
|
}
|
||||||
|
case 'M': // a month / in a month / a month ago
|
||||||
|
return withoutSuffix || isFuture ? 'měsíc' : 'měsícem';
|
||||||
|
case 'MM': // 9 months / in 9 months / 9 months ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'měsíce' : 'měsíců');
|
||||||
|
} else {
|
||||||
|
return result + 'měsíci';
|
||||||
|
}
|
||||||
|
case 'y': // a year / in a year / a year ago
|
||||||
|
return withoutSuffix || isFuture ? 'rok' : 'rokem';
|
||||||
|
case 'yy': // 9 years / in 9 years / 9 years ago
|
||||||
|
if (withoutSuffix || isFuture) {
|
||||||
|
return result + (plural(number) ? 'roky' : 'let');
|
||||||
|
} else {
|
||||||
|
return result + 'lety';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var cs = moment.defineLocale('cs', {
|
||||||
|
months: months,
|
||||||
|
monthsShort: monthsShort,
|
||||||
|
monthsRegex: monthsRegex,
|
||||||
|
monthsShortRegex: monthsRegex,
|
||||||
|
// NOTE: 'červen' is substring of 'červenec'; therefore 'červenec' must precede 'červen' in the regex to be fully matched.
|
||||||
|
// Otherwise parser matches '1. červenec' as '1. červen' + 'ec'.
|
||||||
|
monthsStrictRegex:
|
||||||
|
/^(leden|ledna|února|únor|březen|března|duben|dubna|květen|května|červenec|července|červen|června|srpen|srpna|září|říjen|října|listopadu|listopad|prosinec|prosince)/i,
|
||||||
|
monthsShortStrictRegex:
|
||||||
|
/^(led|úno|bře|dub|kvě|čvn|čvc|srp|zář|říj|lis|pro)/i,
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
weekdays: 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),
|
||||||
|
weekdaysShort: 'ne_po_út_st_čt_pá_so'.split('_'),
|
||||||
|
weekdaysMin: 'ne_po_út_st_čt_pá_so'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'H:mm',
|
||||||
|
LTS: 'H:mm:ss',
|
||||||
|
L: 'DD.MM.YYYY',
|
||||||
|
LL: 'D. MMMM YYYY',
|
||||||
|
LLL: 'D. MMMM YYYY H:mm',
|
||||||
|
LLLL: 'dddd D. MMMM YYYY H:mm',
|
||||||
|
l: 'D. M. YYYY',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[dnes v] LT',
|
||||||
|
nextDay: '[zítra v] LT',
|
||||||
|
nextWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[v neděli v] LT';
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
return '[v] dddd [v] LT';
|
||||||
|
case 3:
|
||||||
|
return '[ve středu v] LT';
|
||||||
|
case 4:
|
||||||
|
return '[ve čtvrtek v] LT';
|
||||||
|
case 5:
|
||||||
|
return '[v pátek v] LT';
|
||||||
|
case 6:
|
||||||
|
return '[v sobotu v] LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastDay: '[včera v] LT',
|
||||||
|
lastWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[minulou neděli v] LT';
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
return '[minulé] dddd [v] LT';
|
||||||
|
case 3:
|
||||||
|
return '[minulou středu v] LT';
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
return '[minulý] dddd [v] LT';
|
||||||
|
case 6:
|
||||||
|
return '[minulou sobotu v] LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'za %s',
|
||||||
|
past: 'před %s',
|
||||||
|
s: translate,
|
||||||
|
ss: translate,
|
||||||
|
m: translate,
|
||||||
|
mm: translate,
|
||||||
|
h: translate,
|
||||||
|
hh: translate,
|
||||||
|
d: translate,
|
||||||
|
dd: translate,
|
||||||
|
M: translate,
|
||||||
|
MM: translate,
|
||||||
|
y: translate,
|
||||||
|
yy: translate,
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}\./,
|
||||||
|
ordinal: '%d.',
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,89 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : German [de]
|
||||||
|
//! author : lluchs : https://github.com/lluchs
|
||||||
|
//! author: Menelion Elensúle: https://github.com/Oire
|
||||||
|
//! author : Mikolaj Dadela : https://github.com/mik01aj
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
function processRelativeTime(number, withoutSuffix, key, isFuture) {
|
||||||
|
var format = {
|
||||||
|
m: ['eine Minute', 'einer Minute'],
|
||||||
|
h: ['eine Stunde', 'einer Stunde'],
|
||||||
|
d: ['ein Tag', 'einem Tag'],
|
||||||
|
dd: [number + ' Tage', number + ' Tagen'],
|
||||||
|
w: ['eine Woche', 'einer Woche'],
|
||||||
|
M: ['ein Monat', 'einem Monat'],
|
||||||
|
MM: [number + ' Monate', number + ' Monaten'],
|
||||||
|
y: ['ein Jahr', 'einem Jahr'],
|
||||||
|
yy: [number + ' Jahre', number + ' Jahren'],
|
||||||
|
};
|
||||||
|
return withoutSuffix ? format[key][0] : format[key][1];
|
||||||
|
}
|
||||||
|
|
||||||
|
var de = moment.defineLocale('de', {
|
||||||
|
months: 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort:
|
||||||
|
'Jan._Feb._März_Apr._Mai_Juni_Juli_Aug._Sep._Okt._Nov._Dez.'.split('_'),
|
||||||
|
monthsParseExact: true,
|
||||||
|
weekdays:
|
||||||
|
'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdaysShort: 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),
|
||||||
|
weekdaysMin: 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),
|
||||||
|
weekdaysParseExact: true,
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD.MM.YYYY',
|
||||||
|
LL: 'D. MMMM YYYY',
|
||||||
|
LLL: 'D. MMMM YYYY HH:mm',
|
||||||
|
LLLL: 'dddd, D. MMMM YYYY HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[heute um] LT [Uhr]',
|
||||||
|
sameElse: 'L',
|
||||||
|
nextDay: '[morgen um] LT [Uhr]',
|
||||||
|
nextWeek: 'dddd [um] LT [Uhr]',
|
||||||
|
lastDay: '[gestern um] LT [Uhr]',
|
||||||
|
lastWeek: '[letzten] dddd [um] LT [Uhr]',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'in %s',
|
||||||
|
past: 'vor %s',
|
||||||
|
s: 'ein paar Sekunden',
|
||||||
|
ss: '%d Sekunden',
|
||||||
|
m: processRelativeTime,
|
||||||
|
mm: '%d Minuten',
|
||||||
|
h: processRelativeTime,
|
||||||
|
hh: '%d Stunden',
|
||||||
|
d: processRelativeTime,
|
||||||
|
dd: processRelativeTime,
|
||||||
|
w: processRelativeTime,
|
||||||
|
ww: '%d Wochen',
|
||||||
|
M: processRelativeTime,
|
||||||
|
MM: processRelativeTime,
|
||||||
|
y: processRelativeTime,
|
||||||
|
yy: processRelativeTime,
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}\./,
|
||||||
|
ordinal: '%d.',
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return de;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,121 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Spanish [es]
|
||||||
|
//! author : Julio Napurí : https://github.com/julionc
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var monthsShortDot =
|
||||||
|
'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_'),
|
||||||
|
monthsParse = [
|
||||||
|
/^ene/i,
|
||||||
|
/^feb/i,
|
||||||
|
/^mar/i,
|
||||||
|
/^abr/i,
|
||||||
|
/^may/i,
|
||||||
|
/^jun/i,
|
||||||
|
/^jul/i,
|
||||||
|
/^ago/i,
|
||||||
|
/^sep/i,
|
||||||
|
/^oct/i,
|
||||||
|
/^nov/i,
|
||||||
|
/^dic/i,
|
||||||
|
],
|
||||||
|
monthsRegex =
|
||||||
|
/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre|ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i;
|
||||||
|
|
||||||
|
var es = moment.defineLocale('es', {
|
||||||
|
months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort: function (m, format) {
|
||||||
|
if (!m) {
|
||||||
|
return monthsShortDot;
|
||||||
|
} else if (/-MMM-/.test(format)) {
|
||||||
|
return monthsShort[m.month()];
|
||||||
|
} else {
|
||||||
|
return monthsShortDot[m.month()];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
monthsRegex: monthsRegex,
|
||||||
|
monthsShortRegex: monthsRegex,
|
||||||
|
monthsStrictRegex:
|
||||||
|
/^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i,
|
||||||
|
monthsShortStrictRegex:
|
||||||
|
/^(ene\.?|feb\.?|mar\.?|abr\.?|may\.?|jun\.?|jul\.?|ago\.?|sep\.?|oct\.?|nov\.?|dic\.?)/i,
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
weekdays: 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),
|
||||||
|
weekdaysShort: 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),
|
||||||
|
weekdaysMin: 'do_lu_ma_mi_ju_vi_sá'.split('_'),
|
||||||
|
weekdaysParseExact: true,
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'H:mm',
|
||||||
|
LTS: 'H:mm:ss',
|
||||||
|
L: 'DD/MM/YYYY',
|
||||||
|
LL: 'D [de] MMMM [de] YYYY',
|
||||||
|
LLL: 'D [de] MMMM [de] YYYY H:mm',
|
||||||
|
LLLL: 'dddd, D [de] MMMM [de] YYYY H:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: function () {
|
||||||
|
return '[hoy a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
|
||||||
|
},
|
||||||
|
nextDay: function () {
|
||||||
|
return '[mañana a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
|
||||||
|
},
|
||||||
|
nextWeek: function () {
|
||||||
|
return 'dddd [a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
|
||||||
|
},
|
||||||
|
lastDay: function () {
|
||||||
|
return '[ayer a la' + (this.hours() !== 1 ? 's' : '') + '] LT';
|
||||||
|
},
|
||||||
|
lastWeek: function () {
|
||||||
|
return (
|
||||||
|
'[el] dddd [pasado a la' +
|
||||||
|
(this.hours() !== 1 ? 's' : '') +
|
||||||
|
'] LT'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'en %s',
|
||||||
|
past: 'hace %s',
|
||||||
|
s: 'unos segundos',
|
||||||
|
ss: '%d segundos',
|
||||||
|
m: 'un minuto',
|
||||||
|
mm: '%d minutos',
|
||||||
|
h: 'una hora',
|
||||||
|
hh: '%d horas',
|
||||||
|
d: 'un día',
|
||||||
|
dd: '%d días',
|
||||||
|
w: 'una semana',
|
||||||
|
ww: '%d semanas',
|
||||||
|
M: 'un mes',
|
||||||
|
MM: '%d meses',
|
||||||
|
y: 'un año',
|
||||||
|
yy: '%d años',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}º/,
|
||||||
|
ordinal: '%dº',
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
invalidDate: 'Fecha inválida',
|
||||||
|
});
|
||||||
|
|
||||||
|
return es;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,119 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : French [fr]
|
||||||
|
//! author : John Fischer : https://github.com/jfroffice
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var monthsStrictRegex =
|
||||||
|
/^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
|
||||||
|
monthsShortStrictRegex =
|
||||||
|
/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?)/i,
|
||||||
|
monthsRegex =
|
||||||
|
/(janv\.?|févr\.?|mars|avr\.?|mai|juin|juil\.?|août|sept\.?|oct\.?|nov\.?|déc\.?|janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,
|
||||||
|
monthsParse = [
|
||||||
|
/^janv/i,
|
||||||
|
/^févr/i,
|
||||||
|
/^mars/i,
|
||||||
|
/^avr/i,
|
||||||
|
/^mai/i,
|
||||||
|
/^juin/i,
|
||||||
|
/^juil/i,
|
||||||
|
/^août/i,
|
||||||
|
/^sept/i,
|
||||||
|
/^oct/i,
|
||||||
|
/^nov/i,
|
||||||
|
/^déc/i,
|
||||||
|
];
|
||||||
|
|
||||||
|
var fr = moment.defineLocale('fr', {
|
||||||
|
months: 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort:
|
||||||
|
'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsRegex: monthsRegex,
|
||||||
|
monthsShortRegex: monthsRegex,
|
||||||
|
monthsStrictRegex: monthsStrictRegex,
|
||||||
|
monthsShortStrictRegex: monthsShortStrictRegex,
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
weekdays: 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),
|
||||||
|
weekdaysShort: 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),
|
||||||
|
weekdaysMin: 'di_lu_ma_me_je_ve_sa'.split('_'),
|
||||||
|
weekdaysParseExact: true,
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD/MM/YYYY',
|
||||||
|
LL: 'D MMMM YYYY',
|
||||||
|
LLL: 'D MMMM YYYY HH:mm',
|
||||||
|
LLLL: 'dddd D MMMM YYYY HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[Aujourd’hui à] LT',
|
||||||
|
nextDay: '[Demain à] LT',
|
||||||
|
nextWeek: 'dddd [à] LT',
|
||||||
|
lastDay: '[Hier à] LT',
|
||||||
|
lastWeek: 'dddd [dernier à] LT',
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'dans %s',
|
||||||
|
past: 'il y a %s',
|
||||||
|
s: 'quelques secondes',
|
||||||
|
ss: '%d secondes',
|
||||||
|
m: 'une minute',
|
||||||
|
mm: '%d minutes',
|
||||||
|
h: 'une heure',
|
||||||
|
hh: '%d heures',
|
||||||
|
d: 'un jour',
|
||||||
|
dd: '%d jours',
|
||||||
|
w: 'une semaine',
|
||||||
|
ww: '%d semaines',
|
||||||
|
M: 'un mois',
|
||||||
|
MM: '%d mois',
|
||||||
|
y: 'un an',
|
||||||
|
yy: '%d ans',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}(er|)/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
// TODO: Return 'e' when day of month > 1. Move this case inside
|
||||||
|
// block for masculine words below.
|
||||||
|
// See https://github.com/moment/moment/issues/3375
|
||||||
|
case 'D':
|
||||||
|
return number + (number === 1 ? 'er' : '');
|
||||||
|
|
||||||
|
// Words with masculine grammatical gender: mois, trimestre, jour
|
||||||
|
default:
|
||||||
|
case 'M':
|
||||||
|
case 'Q':
|
||||||
|
case 'DDD':
|
||||||
|
case 'd':
|
||||||
|
return number + (number === 1 ? 'er' : 'e');
|
||||||
|
|
||||||
|
// Words with feminine grammatical gender: semaine
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
return number + (number === 1 ? 're' : 'e');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return fr;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,117 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Italian [it]
|
||||||
|
//! author : Lorenzo : https://github.com/aliem
|
||||||
|
//! author: Mattia Larentis: https://github.com/nostalgiaz
|
||||||
|
//! author: Marco : https://github.com/Manfre98
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var it = moment.defineLocale('it', {
|
||||||
|
months: 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort: 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),
|
||||||
|
weekdays: 'domenica_lunedì_martedì_mercoledì_giovedì_venerdì_sabato'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdaysShort: 'dom_lun_mar_mer_gio_ven_sab'.split('_'),
|
||||||
|
weekdaysMin: 'do_lu_ma_me_gi_ve_sa'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD/MM/YYYY',
|
||||||
|
LL: 'D MMMM YYYY',
|
||||||
|
LLL: 'D MMMM YYYY HH:mm',
|
||||||
|
LLLL: 'dddd D MMMM YYYY HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: function () {
|
||||||
|
return (
|
||||||
|
'[Oggi a' +
|
||||||
|
(this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
nextDay: function () {
|
||||||
|
return (
|
||||||
|
'[Domani a' +
|
||||||
|
(this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
nextWeek: function () {
|
||||||
|
return (
|
||||||
|
'dddd [a' +
|
||||||
|
(this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
lastDay: function () {
|
||||||
|
return (
|
||||||
|
'[Ieri a' +
|
||||||
|
(this.hours() > 1 ? 'lle ' : this.hours() === 0 ? ' ' : "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
lastWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return (
|
||||||
|
'[La scorsa] dddd [a' +
|
||||||
|
(this.hours() > 1
|
||||||
|
? 'lle '
|
||||||
|
: this.hours() === 0
|
||||||
|
? ' '
|
||||||
|
: "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
'[Lo scorso] dddd [a' +
|
||||||
|
(this.hours() > 1
|
||||||
|
? 'lle '
|
||||||
|
: this.hours() === 0
|
||||||
|
? ' '
|
||||||
|
: "ll'") +
|
||||||
|
']LT'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'tra %s',
|
||||||
|
past: '%s fa',
|
||||||
|
s: 'alcuni secondi',
|
||||||
|
ss: '%d secondi',
|
||||||
|
m: 'un minuto',
|
||||||
|
mm: '%d minuti',
|
||||||
|
h: "un'ora",
|
||||||
|
hh: '%d ore',
|
||||||
|
d: 'un giorno',
|
||||||
|
dd: '%d giorni',
|
||||||
|
w: 'una settimana',
|
||||||
|
ww: '%d settimane',
|
||||||
|
M: 'un mese',
|
||||||
|
MM: '%d mesi',
|
||||||
|
y: 'un anno',
|
||||||
|
yy: '%d anni',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}º/,
|
||||||
|
ordinal: '%dº',
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return it;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,159 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Japanese [ja]
|
||||||
|
//! author : LI Long : https://github.com/baryon
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var ja = moment.defineLocale('ja', {
|
||||||
|
eras: [
|
||||||
|
{
|
||||||
|
since: '2019-05-01',
|
||||||
|
offset: 1,
|
||||||
|
name: '令和',
|
||||||
|
narrow: '㋿',
|
||||||
|
abbr: 'R',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '1989-01-08',
|
||||||
|
until: '2019-04-30',
|
||||||
|
offset: 1,
|
||||||
|
name: '平成',
|
||||||
|
narrow: '㍻',
|
||||||
|
abbr: 'H',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '1926-12-25',
|
||||||
|
until: '1989-01-07',
|
||||||
|
offset: 1,
|
||||||
|
name: '昭和',
|
||||||
|
narrow: '㍼',
|
||||||
|
abbr: 'S',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '1912-07-30',
|
||||||
|
until: '1926-12-24',
|
||||||
|
offset: 1,
|
||||||
|
name: '大正',
|
||||||
|
narrow: '㍽',
|
||||||
|
abbr: 'T',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '1873-01-01',
|
||||||
|
until: '1912-07-29',
|
||||||
|
offset: 6,
|
||||||
|
name: '明治',
|
||||||
|
narrow: '㍾',
|
||||||
|
abbr: 'M',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '0001-01-01',
|
||||||
|
until: '1873-12-31',
|
||||||
|
offset: 1,
|
||||||
|
name: '西暦',
|
||||||
|
narrow: 'AD',
|
||||||
|
abbr: 'AD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
since: '0000-12-31',
|
||||||
|
until: -Infinity,
|
||||||
|
offset: 1,
|
||||||
|
name: '紀元前',
|
||||||
|
narrow: 'BC',
|
||||||
|
abbr: 'BC',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
eraYearOrdinalRegex: /(元|\d+)年/,
|
||||||
|
eraYearOrdinalParse: function (input, match) {
|
||||||
|
return match[1] === '元' ? 1 : parseInt(match[1] || input, 10);
|
||||||
|
},
|
||||||
|
months: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),
|
||||||
|
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdays: '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),
|
||||||
|
weekdaysShort: '日_月_火_水_木_金_土'.split('_'),
|
||||||
|
weekdaysMin: '日_月_火_水_木_金_土'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'YYYY/MM/DD',
|
||||||
|
LL: 'YYYY年M月D日',
|
||||||
|
LLL: 'YYYY年M月D日 HH:mm',
|
||||||
|
LLLL: 'YYYY年M月D日 dddd HH:mm',
|
||||||
|
l: 'YYYY/MM/DD',
|
||||||
|
ll: 'YYYY年M月D日',
|
||||||
|
lll: 'YYYY年M月D日 HH:mm',
|
||||||
|
llll: 'YYYY年M月D日(ddd) HH:mm',
|
||||||
|
},
|
||||||
|
meridiemParse: /午前|午後/i,
|
||||||
|
isPM: function (input) {
|
||||||
|
return input === '午後';
|
||||||
|
},
|
||||||
|
meridiem: function (hour, minute, isLower) {
|
||||||
|
if (hour < 12) {
|
||||||
|
return '午前';
|
||||||
|
} else {
|
||||||
|
return '午後';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[今日] LT',
|
||||||
|
nextDay: '[明日] LT',
|
||||||
|
nextWeek: function (now) {
|
||||||
|
if (now.week() !== this.week()) {
|
||||||
|
return '[来週]dddd LT';
|
||||||
|
} else {
|
||||||
|
return 'dddd LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastDay: '[昨日] LT',
|
||||||
|
lastWeek: function (now) {
|
||||||
|
if (this.week() !== now.week()) {
|
||||||
|
return '[先週]dddd LT';
|
||||||
|
} else {
|
||||||
|
return 'dddd LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}日/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
case 'y':
|
||||||
|
return number === 1 ? '元年' : number + '年';
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'DDD':
|
||||||
|
return number + '日';
|
||||||
|
default:
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: '%s後',
|
||||||
|
past: '%s前',
|
||||||
|
s: '数秒',
|
||||||
|
ss: '%d秒',
|
||||||
|
m: '1分',
|
||||||
|
mm: '%d分',
|
||||||
|
h: '1時間',
|
||||||
|
hh: '%d時間',
|
||||||
|
d: '1日',
|
||||||
|
dd: '%d日',
|
||||||
|
M: '1ヶ月',
|
||||||
|
MM: '%dヶ月',
|
||||||
|
y: '1年',
|
||||||
|
yy: '%d年',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return ja;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,86 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Korean [ko]
|
||||||
|
//! author : Kyungwook, Park : https://github.com/kyungw00k
|
||||||
|
//! author : Jeeeyul Lee <jeeeyul@gmail.com>
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var ko = moment.defineLocale('ko', {
|
||||||
|
months: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),
|
||||||
|
monthsShort: '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdays: '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),
|
||||||
|
weekdaysShort: '일_월_화_수_목_금_토'.split('_'),
|
||||||
|
weekdaysMin: '일_월_화_수_목_금_토'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'A h:mm',
|
||||||
|
LTS: 'A h:mm:ss',
|
||||||
|
L: 'YYYY.MM.DD.',
|
||||||
|
LL: 'YYYY년 MMMM D일',
|
||||||
|
LLL: 'YYYY년 MMMM D일 A h:mm',
|
||||||
|
LLLL: 'YYYY년 MMMM D일 dddd A h:mm',
|
||||||
|
l: 'YYYY.MM.DD.',
|
||||||
|
ll: 'YYYY년 MMMM D일',
|
||||||
|
lll: 'YYYY년 MMMM D일 A h:mm',
|
||||||
|
llll: 'YYYY년 MMMM D일 dddd A h:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '오늘 LT',
|
||||||
|
nextDay: '내일 LT',
|
||||||
|
nextWeek: 'dddd LT',
|
||||||
|
lastDay: '어제 LT',
|
||||||
|
lastWeek: '지난주 dddd LT',
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: '%s 후',
|
||||||
|
past: '%s 전',
|
||||||
|
s: '몇 초',
|
||||||
|
ss: '%d초',
|
||||||
|
m: '1분',
|
||||||
|
mm: '%d분',
|
||||||
|
h: '한 시간',
|
||||||
|
hh: '%d시간',
|
||||||
|
d: '하루',
|
||||||
|
dd: '%d일',
|
||||||
|
M: '한 달',
|
||||||
|
MM: '%d달',
|
||||||
|
y: '일 년',
|
||||||
|
yy: '%d년',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}(일|월|주)/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'DDD':
|
||||||
|
return number + '일';
|
||||||
|
case 'M':
|
||||||
|
return number + '월';
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
return number + '주';
|
||||||
|
default:
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meridiemParse: /오전|오후/,
|
||||||
|
isPM: function (token) {
|
||||||
|
return token === '오후';
|
||||||
|
},
|
||||||
|
meridiem: function (hour, minute, isUpper) {
|
||||||
|
return hour < 12 ? '오전' : '오후';
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return ko;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,115 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Dutch [nl]
|
||||||
|
//! author : Joris Röling : https://github.com/jorisroling
|
||||||
|
//! author : Jacob Middag : https://github.com/middagj
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var monthsShortWithDots =
|
||||||
|
'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),
|
||||||
|
monthsShortWithoutDots =
|
||||||
|
'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_'),
|
||||||
|
monthsParse = [
|
||||||
|
/^jan/i,
|
||||||
|
/^feb/i,
|
||||||
|
/^maart|mrt.?$/i,
|
||||||
|
/^apr/i,
|
||||||
|
/^mei$/i,
|
||||||
|
/^jun[i.]?$/i,
|
||||||
|
/^jul[i.]?$/i,
|
||||||
|
/^aug/i,
|
||||||
|
/^sep/i,
|
||||||
|
/^okt/i,
|
||||||
|
/^nov/i,
|
||||||
|
/^dec/i,
|
||||||
|
],
|
||||||
|
monthsRegex =
|
||||||
|
/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december|jan\.?|feb\.?|mrt\.?|apr\.?|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i;
|
||||||
|
|
||||||
|
var nl = moment.defineLocale('nl', {
|
||||||
|
months: 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort: function (m, format) {
|
||||||
|
if (!m) {
|
||||||
|
return monthsShortWithDots;
|
||||||
|
} else if (/-MMM-/.test(format)) {
|
||||||
|
return monthsShortWithoutDots[m.month()];
|
||||||
|
} else {
|
||||||
|
return monthsShortWithDots[m.month()];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
monthsRegex: monthsRegex,
|
||||||
|
monthsShortRegex: monthsRegex,
|
||||||
|
monthsStrictRegex:
|
||||||
|
/^(januari|februari|maart|april|mei|ju[nl]i|augustus|september|oktober|november|december)/i,
|
||||||
|
monthsShortStrictRegex:
|
||||||
|
/^(jan\.?|feb\.?|mrt\.?|apr\.?|mei|ju[nl]\.?|aug\.?|sep\.?|okt\.?|nov\.?|dec\.?)/i,
|
||||||
|
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
|
||||||
|
weekdays:
|
||||||
|
'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),
|
||||||
|
weekdaysShort: 'zo._ma._di._wo._do._vr._za.'.split('_'),
|
||||||
|
weekdaysMin: 'zo_ma_di_wo_do_vr_za'.split('_'),
|
||||||
|
weekdaysParseExact: true,
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD-MM-YYYY',
|
||||||
|
LL: 'D MMMM YYYY',
|
||||||
|
LLL: 'D MMMM YYYY HH:mm',
|
||||||
|
LLLL: 'dddd D MMMM YYYY HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[vandaag om] LT',
|
||||||
|
nextDay: '[morgen om] LT',
|
||||||
|
nextWeek: 'dddd [om] LT',
|
||||||
|
lastDay: '[gisteren om] LT',
|
||||||
|
lastWeek: '[afgelopen] dddd [om] LT',
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'over %s',
|
||||||
|
past: '%s geleden',
|
||||||
|
s: 'een paar seconden',
|
||||||
|
ss: '%d seconden',
|
||||||
|
m: 'één minuut',
|
||||||
|
mm: '%d minuten',
|
||||||
|
h: 'één uur',
|
||||||
|
hh: '%d uur',
|
||||||
|
d: 'één dag',
|
||||||
|
dd: '%d dagen',
|
||||||
|
w: 'één week',
|
||||||
|
ww: '%d weken',
|
||||||
|
M: 'één maand',
|
||||||
|
MM: '%d maanden',
|
||||||
|
y: 'één jaar',
|
||||||
|
yy: '%d jaar',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}(ste|de)/,
|
||||||
|
ordinal: function (number) {
|
||||||
|
return (
|
||||||
|
number +
|
||||||
|
(number === 1 || number === 8 || number >= 20 ? 'ste' : 'de')
|
||||||
|
);
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return nl;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,151 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Polish [pl]
|
||||||
|
//! author : Rafal Hirsz : https://github.com/evoL
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var monthsNominative =
|
||||||
|
'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsSubjective =
|
||||||
|
'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsParse = [
|
||||||
|
/^sty/i,
|
||||||
|
/^lut/i,
|
||||||
|
/^mar/i,
|
||||||
|
/^kwi/i,
|
||||||
|
/^maj/i,
|
||||||
|
/^cze/i,
|
||||||
|
/^lip/i,
|
||||||
|
/^sie/i,
|
||||||
|
/^wrz/i,
|
||||||
|
/^paź/i,
|
||||||
|
/^lis/i,
|
||||||
|
/^gru/i,
|
||||||
|
];
|
||||||
|
function plural(n) {
|
||||||
|
return n % 10 < 5 && n % 10 > 1 && ~~(n / 10) % 10 !== 1;
|
||||||
|
}
|
||||||
|
function translate(number, withoutSuffix, key) {
|
||||||
|
var result = number + ' ';
|
||||||
|
switch (key) {
|
||||||
|
case 'ss':
|
||||||
|
return result + (plural(number) ? 'sekundy' : 'sekund');
|
||||||
|
case 'm':
|
||||||
|
return withoutSuffix ? 'minuta' : 'minutę';
|
||||||
|
case 'mm':
|
||||||
|
return result + (plural(number) ? 'minuty' : 'minut');
|
||||||
|
case 'h':
|
||||||
|
return withoutSuffix ? 'godzina' : 'godzinę';
|
||||||
|
case 'hh':
|
||||||
|
return result + (plural(number) ? 'godziny' : 'godzin');
|
||||||
|
case 'ww':
|
||||||
|
return result + (plural(number) ? 'tygodnie' : 'tygodni');
|
||||||
|
case 'MM':
|
||||||
|
return result + (plural(number) ? 'miesiące' : 'miesięcy');
|
||||||
|
case 'yy':
|
||||||
|
return result + (plural(number) ? 'lata' : 'lat');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var pl = moment.defineLocale('pl', {
|
||||||
|
months: function (momentToFormat, format) {
|
||||||
|
if (!momentToFormat) {
|
||||||
|
return monthsNominative;
|
||||||
|
} else if (/D MMMM/.test(format)) {
|
||||||
|
return monthsSubjective[momentToFormat.month()];
|
||||||
|
} else {
|
||||||
|
return monthsNominative[momentToFormat.month()];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
monthsShort: 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
weekdays:
|
||||||
|
'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),
|
||||||
|
weekdaysShort: 'ndz_pon_wt_śr_czw_pt_sob'.split('_'),
|
||||||
|
weekdaysMin: 'Nd_Pn_Wt_Śr_Cz_Pt_So'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD.MM.YYYY',
|
||||||
|
LL: 'D MMMM YYYY',
|
||||||
|
LLL: 'D MMMM YYYY HH:mm',
|
||||||
|
LLLL: 'dddd, D MMMM YYYY HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[Dziś o] LT',
|
||||||
|
nextDay: '[Jutro o] LT',
|
||||||
|
nextWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[W niedzielę o] LT';
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
return '[We wtorek o] LT';
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return '[W środę o] LT';
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
return '[W sobotę o] LT';
|
||||||
|
|
||||||
|
default:
|
||||||
|
return '[W] dddd [o] LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastDay: '[Wczoraj o] LT',
|
||||||
|
lastWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[W zeszłą niedzielę o] LT';
|
||||||
|
case 3:
|
||||||
|
return '[W zeszłą środę o] LT';
|
||||||
|
case 6:
|
||||||
|
return '[W zeszłą sobotę o] LT';
|
||||||
|
default:
|
||||||
|
return '[W zeszły] dddd [o] LT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'za %s',
|
||||||
|
past: '%s temu',
|
||||||
|
s: 'kilka sekund',
|
||||||
|
ss: translate,
|
||||||
|
m: translate,
|
||||||
|
mm: translate,
|
||||||
|
h: translate,
|
||||||
|
hh: translate,
|
||||||
|
d: '1 dzień',
|
||||||
|
dd: '%d dni',
|
||||||
|
w: 'tydzień',
|
||||||
|
ww: translate,
|
||||||
|
M: 'miesiąc',
|
||||||
|
MM: translate,
|
||||||
|
y: 'rok',
|
||||||
|
yy: translate,
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}\./,
|
||||||
|
ordinal: '%d.',
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return pl;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,224 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Russian [ru]
|
||||||
|
//! author : Viktorminator : https://github.com/Viktorminator
|
||||||
|
//! author : Menelion Elensúle : https://github.com/Oire
|
||||||
|
//! author : Коренберг Марк : https://github.com/socketpair
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
function plural(word, num) {
|
||||||
|
var forms = word.split('_');
|
||||||
|
return num % 10 === 1 && num % 100 !== 11
|
||||||
|
? forms[0]
|
||||||
|
: num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
|
||||||
|
? forms[1]
|
||||||
|
: forms[2];
|
||||||
|
}
|
||||||
|
function relativeTimeWithPlural(number, withoutSuffix, key) {
|
||||||
|
var format = {
|
||||||
|
ss: withoutSuffix ? 'секунда_секунды_секунд' : 'секунду_секунды_секунд',
|
||||||
|
mm: withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',
|
||||||
|
hh: 'час_часа_часов',
|
||||||
|
dd: 'день_дня_дней',
|
||||||
|
ww: 'неделя_недели_недель',
|
||||||
|
MM: 'месяц_месяца_месяцев',
|
||||||
|
yy: 'год_года_лет',
|
||||||
|
};
|
||||||
|
if (key === 'm') {
|
||||||
|
return withoutSuffix ? 'минута' : 'минуту';
|
||||||
|
} else {
|
||||||
|
return number + ' ' + plural(format[key], +number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var monthsParse = [
|
||||||
|
/^янв/i,
|
||||||
|
/^фев/i,
|
||||||
|
/^мар/i,
|
||||||
|
/^апр/i,
|
||||||
|
/^ма[йя]/i,
|
||||||
|
/^июн/i,
|
||||||
|
/^июл/i,
|
||||||
|
/^авг/i,
|
||||||
|
/^сен/i,
|
||||||
|
/^окт/i,
|
||||||
|
/^ноя/i,
|
||||||
|
/^дек/i,
|
||||||
|
];
|
||||||
|
|
||||||
|
// http://new.gramota.ru/spravka/rules/139-prop : § 103
|
||||||
|
// Сокращения месяцев: http://new.gramota.ru/spravka/buro/search-answer?s=242637
|
||||||
|
// CLDR data: http://www.unicode.org/cldr/charts/28/summary/ru.html#1753
|
||||||
|
var ru = moment.defineLocale('ru', {
|
||||||
|
months: {
|
||||||
|
format: 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
standalone:
|
||||||
|
'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
monthsShort: {
|
||||||
|
// по CLDR именно "июл." и "июн.", но какой смысл менять букву на точку?
|
||||||
|
format: 'янв._февр._мар._апр._мая_июня_июля_авг._сент._окт._нояб._дек.'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
standalone:
|
||||||
|
'янв._февр._март_апр._май_июнь_июль_авг._сент._окт._нояб._дек.'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
weekdays: {
|
||||||
|
standalone:
|
||||||
|
'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
format: 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
isFormat: /\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?] ?dddd/,
|
||||||
|
},
|
||||||
|
weekdaysShort: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
|
||||||
|
weekdaysMin: 'вс_пн_вт_ср_чт_пт_сб'.split('_'),
|
||||||
|
monthsParse: monthsParse,
|
||||||
|
longMonthsParse: monthsParse,
|
||||||
|
shortMonthsParse: monthsParse,
|
||||||
|
|
||||||
|
// полные названия с падежами, по три буквы, для некоторых, по 4 буквы, сокращения с точкой и без точки
|
||||||
|
monthsRegex:
|
||||||
|
/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
|
||||||
|
|
||||||
|
// копия предыдущего
|
||||||
|
monthsShortRegex:
|
||||||
|
/^(январ[ья]|янв\.?|феврал[ья]|февр?\.?|марта?|мар\.?|апрел[ья]|апр\.?|ма[йя]|июн[ья]|июн\.?|июл[ья]|июл\.?|августа?|авг\.?|сентябр[ья]|сент?\.?|октябр[ья]|окт\.?|ноябр[ья]|нояб?\.?|декабр[ья]|дек\.?)/i,
|
||||||
|
|
||||||
|
// полные названия с падежами
|
||||||
|
monthsStrictRegex:
|
||||||
|
/^(январ[яь]|феврал[яь]|марта?|апрел[яь]|ма[яй]|июн[яь]|июл[яь]|августа?|сентябр[яь]|октябр[яь]|ноябр[яь]|декабр[яь])/i,
|
||||||
|
|
||||||
|
// Выражение, которое соответствует только сокращённым формам
|
||||||
|
monthsShortStrictRegex:
|
||||||
|
/^(янв\.|февр?\.|мар[т.]|апр\.|ма[яй]|июн[ья.]|июл[ья.]|авг\.|сент?\.|окт\.|нояб?\.|дек\.)/i,
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'H:mm',
|
||||||
|
LTS: 'H:mm:ss',
|
||||||
|
L: 'DD.MM.YYYY',
|
||||||
|
LL: 'D MMMM YYYY г.',
|
||||||
|
LLL: 'D MMMM YYYY г., H:mm',
|
||||||
|
LLLL: 'dddd, D MMMM YYYY г., H:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[Сегодня, в] LT',
|
||||||
|
nextDay: '[Завтра, в] LT',
|
||||||
|
lastDay: '[Вчера, в] LT',
|
||||||
|
nextWeek: function (now) {
|
||||||
|
if (now.week() !== this.week()) {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[В следующее] dddd, [в] LT';
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
return '[В следующий] dddd, [в] LT';
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
return '[В следующую] dddd, [в] LT';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.day() === 2) {
|
||||||
|
return '[Во] dddd, [в] LT';
|
||||||
|
} else {
|
||||||
|
return '[В] dddd, [в] LT';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastWeek: function (now) {
|
||||||
|
if (now.week() !== this.week()) {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
return '[В прошлое] dddd, [в] LT';
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
return '[В прошлый] dddd, [в] LT';
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
return '[В прошлую] dddd, [в] LT';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.day() === 2) {
|
||||||
|
return '[Во] dddd, [в] LT';
|
||||||
|
} else {
|
||||||
|
return '[В] dddd, [в] LT';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'через %s',
|
||||||
|
past: '%s назад',
|
||||||
|
s: 'несколько секунд',
|
||||||
|
ss: relativeTimeWithPlural,
|
||||||
|
m: relativeTimeWithPlural,
|
||||||
|
mm: relativeTimeWithPlural,
|
||||||
|
h: 'час',
|
||||||
|
hh: relativeTimeWithPlural,
|
||||||
|
d: 'день',
|
||||||
|
dd: relativeTimeWithPlural,
|
||||||
|
w: 'неделя',
|
||||||
|
ww: relativeTimeWithPlural,
|
||||||
|
M: 'месяц',
|
||||||
|
MM: relativeTimeWithPlural,
|
||||||
|
y: 'год',
|
||||||
|
yy: relativeTimeWithPlural,
|
||||||
|
},
|
||||||
|
meridiemParse: /ночи|утра|дня|вечера/i,
|
||||||
|
isPM: function (input) {
|
||||||
|
return /^(дня|вечера)$/.test(input);
|
||||||
|
},
|
||||||
|
meridiem: function (hour, minute, isLower) {
|
||||||
|
if (hour < 4) {
|
||||||
|
return 'ночи';
|
||||||
|
} else if (hour < 12) {
|
||||||
|
return 'утра';
|
||||||
|
} else if (hour < 17) {
|
||||||
|
return 'дня';
|
||||||
|
} else {
|
||||||
|
return 'вечера';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}-(й|го|я)/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
case 'M':
|
||||||
|
case 'd':
|
||||||
|
case 'DDD':
|
||||||
|
return number + '-й';
|
||||||
|
case 'D':
|
||||||
|
return number + '-го';
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
return number + '-я';
|
||||||
|
default:
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return ru;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,178 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Ukrainian [uk]
|
||||||
|
//! author : zemlanin : https://github.com/zemlanin
|
||||||
|
//! Author : Menelion Elensúle : https://github.com/Oire
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
function plural(word, num) {
|
||||||
|
var forms = word.split('_');
|
||||||
|
return num % 10 === 1 && num % 100 !== 11
|
||||||
|
? forms[0]
|
||||||
|
: num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20)
|
||||||
|
? forms[1]
|
||||||
|
: forms[2];
|
||||||
|
}
|
||||||
|
function relativeTimeWithPlural(number, withoutSuffix, key) {
|
||||||
|
var format = {
|
||||||
|
ss: withoutSuffix ? 'секунда_секунди_секунд' : 'секунду_секунди_секунд',
|
||||||
|
mm: withoutSuffix ? 'хвилина_хвилини_хвилин' : 'хвилину_хвилини_хвилин',
|
||||||
|
hh: withoutSuffix ? 'година_години_годин' : 'годину_години_годин',
|
||||||
|
dd: 'день_дні_днів',
|
||||||
|
MM: 'місяць_місяці_місяців',
|
||||||
|
yy: 'рік_роки_років',
|
||||||
|
};
|
||||||
|
if (key === 'm') {
|
||||||
|
return withoutSuffix ? 'хвилина' : 'хвилину';
|
||||||
|
} else if (key === 'h') {
|
||||||
|
return withoutSuffix ? 'година' : 'годину';
|
||||||
|
} else {
|
||||||
|
return number + ' ' + plural(format[key], +number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function weekdaysCaseReplace(m, format) {
|
||||||
|
var weekdays = {
|
||||||
|
nominative:
|
||||||
|
'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
accusative:
|
||||||
|
'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
genitive:
|
||||||
|
'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nounCase;
|
||||||
|
|
||||||
|
if (m === true) {
|
||||||
|
return weekdays['nominative']
|
||||||
|
.slice(1, 7)
|
||||||
|
.concat(weekdays['nominative'].slice(0, 1));
|
||||||
|
}
|
||||||
|
if (!m) {
|
||||||
|
return weekdays['nominative'];
|
||||||
|
}
|
||||||
|
|
||||||
|
nounCase = /(\[[ВвУу]\]) ?dddd/.test(format)
|
||||||
|
? 'accusative'
|
||||||
|
: /\[?(?:минулої|наступної)? ?\] ?dddd/.test(format)
|
||||||
|
? 'genitive'
|
||||||
|
: 'nominative';
|
||||||
|
return weekdays[nounCase][m.day()];
|
||||||
|
}
|
||||||
|
function processHoursFunction(str) {
|
||||||
|
return function () {
|
||||||
|
return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var uk = moment.defineLocale('uk', {
|
||||||
|
months: {
|
||||||
|
format: 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
standalone:
|
||||||
|
'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
monthsShort: 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdays: weekdaysCaseReplace,
|
||||||
|
weekdaysShort: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
|
||||||
|
weekdaysMin: 'нд_пн_вт_ср_чт_пт_сб'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'DD.MM.YYYY',
|
||||||
|
LL: 'D MMMM YYYY р.',
|
||||||
|
LLL: 'D MMMM YYYY р., HH:mm',
|
||||||
|
LLLL: 'dddd, D MMMM YYYY р., HH:mm',
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: processHoursFunction('[Сьогодні '),
|
||||||
|
nextDay: processHoursFunction('[Завтра '),
|
||||||
|
lastDay: processHoursFunction('[Вчора '),
|
||||||
|
nextWeek: processHoursFunction('[У] dddd ['),
|
||||||
|
lastWeek: function () {
|
||||||
|
switch (this.day()) {
|
||||||
|
case 0:
|
||||||
|
case 3:
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
return processHoursFunction('[Минулої] dddd [').call(this);
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 4:
|
||||||
|
return processHoursFunction('[Минулого] dddd [').call(this);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: 'за %s',
|
||||||
|
past: '%s тому',
|
||||||
|
s: 'декілька секунд',
|
||||||
|
ss: relativeTimeWithPlural,
|
||||||
|
m: relativeTimeWithPlural,
|
||||||
|
mm: relativeTimeWithPlural,
|
||||||
|
h: 'годину',
|
||||||
|
hh: relativeTimeWithPlural,
|
||||||
|
d: 'день',
|
||||||
|
dd: relativeTimeWithPlural,
|
||||||
|
M: 'місяць',
|
||||||
|
MM: relativeTimeWithPlural,
|
||||||
|
y: 'рік',
|
||||||
|
yy: relativeTimeWithPlural,
|
||||||
|
},
|
||||||
|
// M. E.: those two are virtually unused but a user might want to implement them for his/her website for some reason
|
||||||
|
meridiemParse: /ночі|ранку|дня|вечора/,
|
||||||
|
isPM: function (input) {
|
||||||
|
return /^(дня|вечора)$/.test(input);
|
||||||
|
},
|
||||||
|
meridiem: function (hour, minute, isLower) {
|
||||||
|
if (hour < 4) {
|
||||||
|
return 'ночі';
|
||||||
|
} else if (hour < 12) {
|
||||||
|
return 'ранку';
|
||||||
|
} else if (hour < 17) {
|
||||||
|
return 'дня';
|
||||||
|
} else {
|
||||||
|
return 'вечора';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}-(й|го)/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
case 'M':
|
||||||
|
case 'd':
|
||||||
|
case 'DDD':
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
return number + '-й';
|
||||||
|
case 'D':
|
||||||
|
return number + '-го';
|
||||||
|
default:
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 7, // The week that contains Jan 7th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return uk;
|
||||||
|
|
||||||
|
})));
|
@ -0,0 +1,131 @@
|
|||||||
|
//! moment.js locale configuration
|
||||||
|
//! locale : Chinese (China) [zh-cn]
|
||||||
|
//! author : suupic : https://github.com/suupic
|
||||||
|
//! author : Zeno Zeng : https://github.com/zenozeng
|
||||||
|
//! author : uu109 : https://github.com/uu109
|
||||||
|
|
||||||
|
;(function (global, factory) {
|
||||||
|
typeof exports === 'object' && typeof module !== 'undefined'
|
||||||
|
&& typeof require === 'function' ? factory(require('../moment')) :
|
||||||
|
typeof define === 'function' && define.amd ? define(['../moment'], factory) :
|
||||||
|
factory(global.moment)
|
||||||
|
}(this, (function (moment) { 'use strict';
|
||||||
|
|
||||||
|
//! moment.js locale configuration
|
||||||
|
|
||||||
|
var zhCn = moment.defineLocale('zh-cn', {
|
||||||
|
months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
monthsShort: '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split(
|
||||||
|
'_'
|
||||||
|
),
|
||||||
|
weekdays: '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),
|
||||||
|
weekdaysShort: '周日_周一_周二_周三_周四_周五_周六'.split('_'),
|
||||||
|
weekdaysMin: '日_一_二_三_四_五_六'.split('_'),
|
||||||
|
longDateFormat: {
|
||||||
|
LT: 'HH:mm',
|
||||||
|
LTS: 'HH:mm:ss',
|
||||||
|
L: 'YYYY/MM/DD',
|
||||||
|
LL: 'YYYY年M月D日',
|
||||||
|
LLL: 'YYYY年M月D日Ah点mm分',
|
||||||
|
LLLL: 'YYYY年M月D日ddddAh点mm分',
|
||||||
|
l: 'YYYY/M/D',
|
||||||
|
ll: 'YYYY年M月D日',
|
||||||
|
lll: 'YYYY年M月D日 HH:mm',
|
||||||
|
llll: 'YYYY年M月D日dddd HH:mm',
|
||||||
|
},
|
||||||
|
meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,
|
||||||
|
meridiemHour: function (hour, meridiem) {
|
||||||
|
if (hour === 12) {
|
||||||
|
hour = 0;
|
||||||
|
}
|
||||||
|
if (meridiem === '凌晨' || meridiem === '早上' || meridiem === '上午') {
|
||||||
|
return hour;
|
||||||
|
} else if (meridiem === '下午' || meridiem === '晚上') {
|
||||||
|
return hour + 12;
|
||||||
|
} else {
|
||||||
|
// '中午'
|
||||||
|
return hour >= 11 ? hour : hour + 12;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
meridiem: function (hour, minute, isLower) {
|
||||||
|
var hm = hour * 100 + minute;
|
||||||
|
if (hm < 600) {
|
||||||
|
return '凌晨';
|
||||||
|
} else if (hm < 900) {
|
||||||
|
return '早上';
|
||||||
|
} else if (hm < 1130) {
|
||||||
|
return '上午';
|
||||||
|
} else if (hm < 1230) {
|
||||||
|
return '中午';
|
||||||
|
} else if (hm < 1800) {
|
||||||
|
return '下午';
|
||||||
|
} else {
|
||||||
|
return '晚上';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
sameDay: '[今天]LT',
|
||||||
|
nextDay: '[明天]LT',
|
||||||
|
nextWeek: function (now) {
|
||||||
|
if (now.week() !== this.week()) {
|
||||||
|
return '[下]dddLT';
|
||||||
|
} else {
|
||||||
|
return '[本]dddLT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lastDay: '[昨天]LT',
|
||||||
|
lastWeek: function (now) {
|
||||||
|
if (this.week() !== now.week()) {
|
||||||
|
return '[上]dddLT';
|
||||||
|
} else {
|
||||||
|
return '[本]dddLT';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sameElse: 'L',
|
||||||
|
},
|
||||||
|
dayOfMonthOrdinalParse: /\d{1,2}(日|月|周)/,
|
||||||
|
ordinal: function (number, period) {
|
||||||
|
switch (period) {
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case 'DDD':
|
||||||
|
return number + '日';
|
||||||
|
case 'M':
|
||||||
|
return number + '月';
|
||||||
|
case 'w':
|
||||||
|
case 'W':
|
||||||
|
return number + '周';
|
||||||
|
default:
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
relativeTime: {
|
||||||
|
future: '%s后',
|
||||||
|
past: '%s前',
|
||||||
|
s: '几秒',
|
||||||
|
ss: '%d 秒',
|
||||||
|
m: '1 分钟',
|
||||||
|
mm: '%d 分钟',
|
||||||
|
h: '1 小时',
|
||||||
|
hh: '%d 小时',
|
||||||
|
d: '1 天',
|
||||||
|
dd: '%d 天',
|
||||||
|
w: '1 周',
|
||||||
|
ww: '%d 周',
|
||||||
|
M: '1 个月',
|
||||||
|
MM: '%d 个月',
|
||||||
|
y: '1 年',
|
||||||
|
yy: '%d 年',
|
||||||
|
},
|
||||||
|
week: {
|
||||||
|
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
|
||||||
|
dow: 1, // Monday is the first day of the week.
|
||||||
|
doy: 4, // The week that contains Jan 4th is the first week of the year.
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return zhCn;
|
||||||
|
|
||||||
|
})));
|
@ -101,22 +101,30 @@
|
|||||||
const sidebar = document.getElementById('sidebar');
|
const sidebar = document.getElementById('sidebar');
|
||||||
|
|
||||||
sidebar.addEventListener('shown.bs.collapse', () => {
|
sidebar.addEventListener('shown.bs.collapse', () => {
|
||||||
localStorage.removeItem('sidebar_' + sidebar.id);
|
localStorage.removeItem(`sidebar_${sidebar.id}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
sidebar.addEventListener('hidden.bs.collapse', () => {
|
sidebar.addEventListener('hidden.bs.collapse', () => {
|
||||||
localStorage.setItem('sidebar_' + sidebar.id, 'closed');
|
localStorage.setItem(`sidebar_${sidebar.id}`, 'closed');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (localStorage.getItem('sidebar_' + sidebar.id) === 'closed') {
|
if (localStorage.getItem(`sidebar_${sidebar.id}`) === 'closed') {
|
||||||
sidebar.classList.remove('show')
|
sidebar.classList.remove('show')
|
||||||
} else {
|
} else {
|
||||||
sidebar.classList.add("show")
|
sidebar.classList.add("show")
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeChildMenuItem = document.querySelector('#sidebar-menu li ul li a.active');
|
const activeChildMenuItem = document.querySelector('#sidebar-menu li ul li a.active');
|
||||||
|
|
||||||
if (activeChildMenuItem) {
|
if (activeChildMenuItem) {
|
||||||
activeChildMenuItem.parentElement.parentElement.classList.add('show');
|
const activeChildMenuUl = activeChildMenuItem.parentElement.parentElement;
|
||||||
|
const elementsToToggle = document.querySelectorAll(`[data-bs-target^="#${activeChildMenuUl.id}"]`);
|
||||||
|
|
||||||
|
activeChildMenuUl.classList.add('show');
|
||||||
|
|
||||||
|
elementsToToggle.forEach((element) => {
|
||||||
|
element.setAttribute('aria-expanded', true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,11 +10,6 @@
|
|||||||
<i class="fa-solid fa-gauge-high fa-fw"></i> {% translate "Dashboard" %}
|
<i class="fa-solid fa-gauge-high fa-fw"></i> {% translate "Dashboard" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a class="{% navactive request 'groupmanagement:groups' %}" href="{% url 'groupmanagement:groups' %}">
|
|
||||||
<i class="fa-solid fa-users fa-fw"></i> {% translate "Groups" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{% menu_items %}
|
{% menu_items %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{% load static %}
|
{% load sri %}
|
||||||
|
|
||||||
<link href="{% static 'allianceauth/css/auth-base.css' %}" rel="stylesheet">
|
{% sri_static 'allianceauth/css/auth-base.css' %}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{% load static %}
|
{% load sri %}
|
||||||
|
|
||||||
<link href="{% static 'allianceauth/framework/css/auth-framework.css' %}" rel="stylesheet">
|
{% sri_static 'allianceauth/framework/css/auth-framework.css' %}
|
||||||
|
3
allianceauth/templates/bundles/chart-js.html
Normal file
3
allianceauth/templates/bundles/chart-js.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<!-- Start Chart.js js from cdnjs -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.min.js" integrity="sha512-CQBWl4fJHWbryGE+Pc7UAxWMUMNMWzWxF4SQo9CgkJIN1kx6djDQZjh3Y8SZ1d+6I+1zze6Z7kHXO7q3UyZAWw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||||
|
<!-- End Chart.js js from cdnjs -->
|
@ -1,3 +1,3 @@
|
|||||||
{% load static %}
|
{% load sri %}
|
||||||
|
|
||||||
<link href="{% static 'allianceauth/css/checkbox.css' %}" rel="stylesheet">
|
{% sri_static 'allianceauth/css/checkbox.css' %}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{% load static %}
|
{% load sri %}
|
||||||
|
|
||||||
<script src="{% static 'allianceauth/js/eve-time.js' %}"></script>
|
{% sri_static 'allianceauth/js/eve-time.js' %}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
{% load static %}
|
{% load sri %}
|
||||||
|
|
||||||
<script src="{% static 'allianceauth/js/filterDropDown/filterDropDown.min.js' %}"></script>
|
{% sri_static 'allianceauth/js/filterDropDown/filterDropDown.min.js' %}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
{% load static %}
|
|
||||||
<!-- Start jQuery UI CSS from Alliance Auth -->
|
<!-- Start jQuery UI CSS from Alliance Auth -->
|
||||||
<!-- CDNs all contain theme.css, which is not supposed to be in the base CSS, Which is why this is uniquely bundled in not using a CDN -->
|
<!-- CDNs all contain theme.css, which is not supposed to be in the base CSS, which is why this is uniquely bundled in not using a CDN -->
|
||||||
<link rel="stylesheet" href="{% static 'allianceauth/js/jquery-ui/1.14.0/css/jquery-ui.min.css' %}" integrity="OPZg3VlV71eauVMNlFS3+S1LKXDKPfUwZ6awg/HioerPqeAiO+1xletysrCqgJfEcGYbZlVHNwTA6dT9VKARag==" crossorigin="anonymous" referrerpolicy="no-referrer">
|
{% load sri %}
|
||||||
|
|
||||||
|
{% sri_static 'allianceauth/js/jquery-ui/1.13.2/css/jquery-ui.min.css' %}
|
||||||
<!-- End jQuery UI CSS from aa-gdpr -->
|
<!-- End jQuery UI CSS from aa-gdpr -->
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user