forked from rc/aircox
continue migration: make website working
This commit is contained in:
parent
432467ec8d
commit
324cf2ef0f
|
@ -1,28 +1,7 @@
|
||||||
from django.contrib import admin
|
|
||||||
|
|
||||||
|
|
||||||
from .episode import DiffusionAdmin, EpisodeAdmin
|
from .episode import DiffusionAdmin, EpisodeAdmin
|
||||||
|
from .log import LogAdmin
|
||||||
# from .playlist import PlaylistAdmin
|
# from .playlist import PlaylistAdmin
|
||||||
from .program import ProgramAdmin, ScheduleAdmin, StreamAdmin
|
from .program import ProgramAdmin, ScheduleAdmin, StreamAdmin
|
||||||
from .sound import SoundAdmin
|
from .sound import SoundAdmin
|
||||||
|
from .station import StationAdmin
|
||||||
from aircox.models import Log, Port, Station
|
|
||||||
|
|
||||||
|
|
||||||
class PortInline(admin.StackedInline):
|
|
||||||
model = Port
|
|
||||||
extra = 0
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Station)
|
|
||||||
class StationAdmin(admin.ModelAdmin):
|
|
||||||
prepopulated_fields = {'slug': ('name',)}
|
|
||||||
inlines = [PortInline]
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Log)
|
|
||||||
class LogAdmin(admin.ModelAdmin):
|
|
||||||
list_display = ['id', 'date', 'station', 'source', 'type', 'comment']
|
|
||||||
list_filter = ['date', 'source', 'station']
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,6 +7,7 @@ from aircox.models import Episode, Diffusion, Sound, Track
|
||||||
|
|
||||||
from .page import PageAdmin
|
from .page import PageAdmin
|
||||||
from .playlist import TracksInline
|
from .playlist import TracksInline
|
||||||
|
from .sound import SoundInline
|
||||||
|
|
||||||
|
|
||||||
class DiffusionBaseAdmin:
|
class DiffusionBaseAdmin:
|
||||||
|
@ -46,14 +47,6 @@ class DiffusionInline(DiffusionBaseAdmin, admin.TabularInline):
|
||||||
return request.user.has_perm('aircox_program.scheduling')
|
return request.user.has_perm('aircox_program.scheduling')
|
||||||
|
|
||||||
|
|
||||||
class SoundInline(admin.TabularInline):
|
|
||||||
model = Sound
|
|
||||||
fk_name = 'episode'
|
|
||||||
fields = ['type', 'path', 'duration', 'is_public']
|
|
||||||
readonly_fields = ['type']
|
|
||||||
extra = 0
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Episode)
|
@admin.register(Episode)
|
||||||
class EpisodeAdmin(PageAdmin):
|
class EpisodeAdmin(PageAdmin):
|
||||||
list_display = PageAdmin.list_display + ('program',)
|
list_display = PageAdmin.list_display + ('program',)
|
||||||
|
|
13
aircox/admin/log.py
Normal file
13
aircox/admin/log.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from ..models import Log
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['LogAdmin']
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Log)
|
||||||
|
class LogAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['id', 'date', 'station', 'source', 'type', 'comment']
|
||||||
|
list_filter = ['date', 'source', 'station']
|
||||||
|
|
|
@ -2,6 +2,10 @@ from django.contrib import admin
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from adminsortable2.admin import SortableInlineAdminMixin
|
||||||
|
|
||||||
|
from ..models import NavItem
|
||||||
|
|
||||||
|
|
||||||
class PageAdmin(admin.ModelAdmin):
|
class PageAdmin(admin.ModelAdmin):
|
||||||
list_display = ('cover_thumb', 'title', 'status')
|
list_display = ('cover_thumb', 'title', 'status')
|
||||||
|
@ -24,5 +28,6 @@ class PageAdmin(admin.ModelAdmin):
|
||||||
if obj.cover else ''
|
if obj.cover else ''
|
||||||
|
|
||||||
|
|
||||||
|
class NavItemInline(SortableInlineAdminMixin, admin.TabularInline):
|
||||||
|
model = NavItem
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,13 @@ from aircox.models import Sound
|
||||||
from .playlist import TracksInline
|
from .playlist import TracksInline
|
||||||
|
|
||||||
|
|
||||||
|
class SoundInline(admin.TabularInline):
|
||||||
|
model = Sound
|
||||||
|
fields = ['type', 'path', 'duration', 'is_public']
|
||||||
|
readonly_fields = ['type']
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Sound)
|
@admin.register(Sound)
|
||||||
class SoundAdmin(admin.ModelAdmin):
|
class SoundAdmin(admin.ModelAdmin):
|
||||||
def filename(self, obj):
|
def filename(self, obj):
|
||||||
|
@ -24,3 +31,4 @@ class SoundAdmin(admin.ModelAdmin):
|
||||||
inlines = [TracksInline]
|
inlines = [TracksInline]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
20
aircox/admin/station.py
Normal file
20
aircox/admin/station.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from ..models import Port, Station
|
||||||
|
from .page import NavItemInline
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['PortInline', 'StationAdmin']
|
||||||
|
|
||||||
|
|
||||||
|
class PortInline(admin.StackedInline):
|
||||||
|
model = Port
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Station)
|
||||||
|
class StationAdmin(admin.ModelAdmin):
|
||||||
|
prepopulated_fields = {'slug': ('name',)}
|
||||||
|
inlines = [PortInline, NavItemInline]
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ from django.utils import timezone as tz
|
||||||
from . import settings
|
from . import settings
|
||||||
from .models import Port, Station, Sound
|
from .models import Port, Station, Sound
|
||||||
from .connector import Connector
|
from .connector import Connector
|
||||||
|
from .utils import to_seconds
|
||||||
|
|
||||||
|
|
||||||
# FIXME liquidsoap does not manage timezones -- we have to convert
|
# FIXME liquidsoap does not manage timezones -- we have to convert
|
||||||
|
@ -297,9 +298,6 @@ class PlaylistSource(Source):
|
||||||
if not stream or (not stream.begin and not stream.delay):
|
if not stream or (not stream.begin and not stream.delay):
|
||||||
return
|
return
|
||||||
|
|
||||||
def to_seconds(time):
|
|
||||||
return 3600 * time.hour + 60 * time.minute + time.second
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'begin': stream.begin.strftime('%Hh%M') if stream.begin else None,
|
'begin': stream.begin.strftime('%Hh%M') if stream.begin else None,
|
||||||
'end': stream.end.strftime('%Hh%M') if stream.end else None,
|
'end': stream.end.strftime('%Hh%M') if stream.end else None,
|
||||||
|
|
|
@ -12,7 +12,6 @@ used to:
|
||||||
# x cancel
|
# x cancel
|
||||||
# x when liquidsoap fails to start/exists: exit
|
# x when liquidsoap fails to start/exists: exit
|
||||||
# - handle restart after failure
|
# - handle restart after failure
|
||||||
# - file in queue without sound not logged?
|
|
||||||
# - is stream restart after live ok?
|
# - is stream restart after live ok?
|
||||||
from argparse import RawTextHelpFormatter
|
from argparse import RawTextHelpFormatter
|
||||||
import time
|
import time
|
||||||
|
|
|
@ -1,25 +1,13 @@
|
||||||
import pytz
|
import pytz
|
||||||
import django.utils.timezone as tz
|
from django import shortcuts
|
||||||
|
from django.db.models import Q, Case, Value, When
|
||||||
|
from django.utils import timezone as tz
|
||||||
|
|
||||||
import aircox.models as models
|
from .models import Station
|
||||||
|
from .utils import Redirect
|
||||||
|
|
||||||
|
|
||||||
class AircoxInfo:
|
__all__ = ['AircoxMiddleware']
|
||||||
"""
|
|
||||||
Used to store informations about Aircox on a request. Some of theses
|
|
||||||
information are None when user is anonymous.
|
|
||||||
"""
|
|
||||||
station = None
|
|
||||||
"""
|
|
||||||
Current station
|
|
||||||
"""
|
|
||||||
default_station = False
|
|
||||||
"""
|
|
||||||
Default station is used as the current station
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
self.__dict__.update(kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class AircoxMiddleware(object):
|
class AircoxMiddleware(object):
|
||||||
|
@ -31,37 +19,19 @@ class AircoxMiddleware(object):
|
||||||
def __init__(self, get_response):
|
def __init__(self, get_response):
|
||||||
self.get_response = get_response
|
self.get_response = get_response
|
||||||
|
|
||||||
|
def get_station(self, request):
|
||||||
def update_station(self, request):
|
""" Return station for the provided request """
|
||||||
station = request.GET.get('aircox.station')
|
expr = Q(default=True) | Q(hosts__contains=request.get_host())
|
||||||
pk = None
|
#case = Case(When(hosts__contains=request.get_host(), then=Value(0)),
|
||||||
try:
|
# When(default=True, then=Value(32)))
|
||||||
if station is not None:
|
return Station.objects.filter(expr).order_by('default').first()
|
||||||
pk = request.GET['aircox.station']
|
# .annotate(resolve_priority=case) \
|
||||||
if station:
|
#.order_by('resolve_priority').first()
|
||||||
pk = int(pk)
|
|
||||||
if models.Station.objects.filter(pk = station).exists():
|
|
||||||
request.session['aircox.station'] = pk
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def init_station(self, request, aircox):
|
|
||||||
self.update_station(request)
|
|
||||||
|
|
||||||
try:
|
|
||||||
pk = request.session.get('aircox.station')
|
|
||||||
pk = int(pk) if pk else None
|
|
||||||
except:
|
|
||||||
pk = None
|
|
||||||
|
|
||||||
aircox.station = models.Station.objects.default(pk)
|
|
||||||
aircox.default_station = (pk is None)
|
|
||||||
|
|
||||||
|
|
||||||
def init_timezone(self, request, aircox):
|
def init_timezone(self, request):
|
||||||
# note: later we can use http://freegeoip.net/ on user side if
|
# note: later we can use http://freegeoip.net/ on user side if
|
||||||
# required
|
# required
|
||||||
# TODO: add to request's session
|
|
||||||
timezone = None
|
timezone = None
|
||||||
try:
|
try:
|
||||||
timezone = request.session.get('aircox.timezone')
|
timezone = request.session.get('aircox.timezone')
|
||||||
|
@ -76,14 +46,11 @@ class AircoxMiddleware(object):
|
||||||
|
|
||||||
|
|
||||||
def __call__(self, request):
|
def __call__(self, request):
|
||||||
tz.activate(pytz.timezone('Europe/Brussels'))
|
self.init_timezone(request)
|
||||||
aircox = AircoxInfo()
|
request.station = self.get_station(request)
|
||||||
|
try:
|
||||||
if request.user.is_authenticated:
|
return self.get_response(request)
|
||||||
self.init_station(request, aircox)
|
except Redirect as redirect:
|
||||||
self.init_timezone(request, aircox)
|
return
|
||||||
|
|
||||||
request.aircox = aircox
|
|
||||||
return self.get_response(request)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from .page import Page
|
from .page import Page, NavItem
|
||||||
from .program import Program, Stream, Schedule
|
from .program import Program, Stream, Schedule
|
||||||
from .episode import Episode, Diffusion
|
from .episode import Episode, Diffusion
|
||||||
from .log import Log
|
from .log import Log
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -25,6 +25,7 @@ class Episode(Page):
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = InProgramQuerySet.as_manager()
|
objects = InProgramQuerySet.as_manager()
|
||||||
|
detail_url_name = 'episode-detail'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('Episode')
|
verbose_name = _('Episode')
|
||||||
|
@ -36,12 +37,18 @@ class Episode(Page):
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_date(cls, program, date):
|
def get_default_title(cls, program, date):
|
||||||
title = settings.AIRCOX_EPISODE_TITLE.format(
|
""" Get default Episode's title """
|
||||||
|
return settings.AIRCOX_EPISODE_TITLE.format(
|
||||||
program=program,
|
program=program,
|
||||||
date=date.strftime(settings.AIRCOX_EPISODE_TITLE_DATE_FORMAT),
|
date=date.strftime(settings.AIRCOX_EPISODE_TITLE_DATE_FORMAT),
|
||||||
)
|
)
|
||||||
return cls(program=program, title=title)
|
|
||||||
|
@classmethod
|
||||||
|
def from_date(cls, program, date):
|
||||||
|
title = cls.get_default_title(program, date)
|
||||||
|
return cls(program=program, title=title, cover=program.cover)
|
||||||
|
|
||||||
|
|
||||||
class DiffusionQuerySet(BaseRerunQuerySet):
|
class DiffusionQuerySet(BaseRerunQuerySet):
|
||||||
def episode(self, episode=None, id=None):
|
def episode(self, episode=None, id=None):
|
||||||
|
|
|
@ -3,14 +3,20 @@ from enum import IntEnum
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
|
from django.utils.html import format_html
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from ckeditor.fields import RichTextField
|
||||||
from filer.fields.image import FilerImageField
|
from filer.fields.image import FilerImageField
|
||||||
from model_utils.managers import InheritanceQuerySet
|
from model_utils.managers import InheritanceQuerySet
|
||||||
|
|
||||||
|
from .station import Station
|
||||||
|
|
||||||
__all__ = ['Page', 'PageQuerySet']
|
|
||||||
|
__all__ = ['PageQuerySet', 'Page', 'NavItem']
|
||||||
|
|
||||||
|
|
||||||
class PageQuerySet(InheritanceQuerySet):
|
class PageQuerySet(InheritanceQuerySet):
|
||||||
|
@ -48,8 +54,10 @@ class Page(models.Model):
|
||||||
|
|
||||||
objects = PageQuerySet.as_manager()
|
objects = PageQuerySet.as_manager()
|
||||||
|
|
||||||
|
detail_url_name = None
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract=True
|
abstract = True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{}: {}'.format(self._meta.verbose_name,
|
return '{}: {}'.format(self._meta.verbose_name,
|
||||||
|
@ -64,10 +72,53 @@ class Page(models.Model):
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse(self.detail_url_name, kwargs={'slug': self.slug}) \
|
return reverse(self.detail_url_name, kwargs={'slug': self.slug}) \
|
||||||
if self.is_published else ''
|
if self.is_published else '#'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_draft(self):
|
||||||
|
return self.status == self.STATUS.draft
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_published(self):
|
def is_published(self):
|
||||||
return self.status == self.STATUS.published
|
return self.status == self.STATUS.published
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_trash(self):
|
||||||
|
return self.status == self.STATUS.trash
|
||||||
|
|
||||||
|
|
||||||
|
class NavItem(models.Model):
|
||||||
|
""" Navigation menu items """
|
||||||
|
station = models.ForeignKey(
|
||||||
|
Station, models.CASCADE, verbose_name=_('station'))
|
||||||
|
menu = models.SlugField(_('menu'), max_length=24)
|
||||||
|
order = models.PositiveSmallIntegerField(_('order'))
|
||||||
|
text = models.CharField(_('title'), max_length=64)
|
||||||
|
url = models.CharField(_('url'), max_length=256, blank=True, null=True)
|
||||||
|
#target_type = models.ForeignKey(
|
||||||
|
# ContentType, models.CASCADE, blank=True, null=True)
|
||||||
|
#target_id = models.PositiveSmallIntegerField(blank=True, null=True)
|
||||||
|
#target = GenericForeignKey('target_type', 'target_id')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = _('Menu item')
|
||||||
|
ordering = ('order', 'pk')
|
||||||
|
|
||||||
|
is_active = False
|
||||||
|
|
||||||
|
def get_is_active(self, url):
|
||||||
|
""" Return True if navigation item is active for this url. """
|
||||||
|
return self.url and url.startswith(self.url)
|
||||||
|
|
||||||
|
def render(self, request, css_class='', active_class=''):
|
||||||
|
if active_class and request.path.startswith(self.url):
|
||||||
|
css_class += ' ' + active_class
|
||||||
|
|
||||||
|
if not self.url:
|
||||||
|
return self.text
|
||||||
|
elif not css_class:
|
||||||
|
return format_html('<a href="{}">{}</a>', self.url, self.text)
|
||||||
|
else:
|
||||||
|
return format_html('<a href="{}" class="{}">{}</a>', self.url,
|
||||||
|
css_class, self.text)
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ class Program(Page):
|
||||||
)
|
)
|
||||||
|
|
||||||
objects = ProgramQuerySet.as_manager()
|
objects = ProgramQuerySet.as_manager()
|
||||||
|
detail_url_name = 'program-detail'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
|
|
|
@ -5,7 +5,9 @@ from django.db import models
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
import aircox.settings as settings
|
from filer.fields.image import FilerImageField
|
||||||
|
|
||||||
|
from .. import settings
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Station', 'StationQuerySet', 'Port']
|
__all__ = ['Station', 'StationQuerySet', 'Port']
|
||||||
|
@ -45,6 +47,14 @@ class Station(models.Model):
|
||||||
default=True,
|
default=True,
|
||||||
help_text=_('if checked, this station is used as the main one')
|
help_text=_('if checked, this station is used as the main one')
|
||||||
)
|
)
|
||||||
|
logo = FilerImageField(
|
||||||
|
on_delete=models.SET_NULL, null=True, blank=True,
|
||||||
|
verbose_name=_('Logo'),
|
||||||
|
)
|
||||||
|
hosts = models.TextField(
|
||||||
|
_("website's urls"), max_length=512, null=True, blank=True,
|
||||||
|
help_text=_('specify one url per line')
|
||||||
|
)
|
||||||
|
|
||||||
objects = StationQuerySet.as_manager()
|
objects = StationQuerySet.as_manager()
|
||||||
|
|
||||||
|
@ -58,15 +68,14 @@ class Station(models.Model):
|
||||||
|
|
||||||
if self.default:
|
if self.default:
|
||||||
qs = Station.objects.filter(default=True)
|
qs = Station.objects.filter(default=True)
|
||||||
|
if self.pk is not None:
|
||||||
if self.pk:
|
|
||||||
qs = qs.exclude(pk=self.pk)
|
qs = qs.exclude(pk=self.pk)
|
||||||
qs.update(default=False)
|
qs.update(default=False)
|
||||||
|
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Port (models.Model):
|
class Port(models.Model):
|
||||||
"""
|
"""
|
||||||
Represent an audio input/output for the audio stream
|
Represent an audio input/output for the audio stream
|
||||||
generation.
|
generation.
|
||||||
|
@ -147,4 +156,3 @@ class Port (models.Model):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
7201
aircox/static/aircox/main.css
Normal file
7201
aircox/static/aircox/main.css
Normal file
File diff suppressed because it is too large
Load Diff
347
aircox/static/aircox/main.js
Normal file
347
aircox/static/aircox/main.js
Normal file
|
@ -0,0 +1,347 @@
|
||||||
|
/******/ (function(modules) { // webpackBootstrap
|
||||||
|
/******/ // install a JSONP callback for chunk loading
|
||||||
|
/******/ function webpackJsonpCallback(data) {
|
||||||
|
/******/ var chunkIds = data[0];
|
||||||
|
/******/ var moreModules = data[1];
|
||||||
|
/******/ var executeModules = data[2];
|
||||||
|
/******/
|
||||||
|
/******/ // add "moreModules" to the modules object,
|
||||||
|
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||||
|
/******/ var moduleId, chunkId, i = 0, resolves = [];
|
||||||
|
/******/ for(;i < chunkIds.length; i++) {
|
||||||
|
/******/ chunkId = chunkIds[i];
|
||||||
|
/******/ if(installedChunks[chunkId]) {
|
||||||
|
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||||
|
/******/ }
|
||||||
|
/******/ installedChunks[chunkId] = 0;
|
||||||
|
/******/ }
|
||||||
|
/******/ for(moduleId in moreModules) {
|
||||||
|
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||||
|
/******/ modules[moduleId] = moreModules[moduleId];
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
|
||||||
|
/******/
|
||||||
|
/******/ while(resolves.length) {
|
||||||
|
/******/ resolves.shift()();
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/ // add entry modules from loaded chunk to deferred list
|
||||||
|
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
|
||||||
|
/******/
|
||||||
|
/******/ // run deferred modules when all chunks ready
|
||||||
|
/******/ return checkDeferredModules();
|
||||||
|
/******/ };
|
||||||
|
/******/ function checkDeferredModules() {
|
||||||
|
/******/ var result;
|
||||||
|
/******/ for(var i = 0; i < deferredModules.length; i++) {
|
||||||
|
/******/ var deferredModule = deferredModules[i];
|
||||||
|
/******/ var fulfilled = true;
|
||||||
|
/******/ for(var j = 1; j < deferredModule.length; j++) {
|
||||||
|
/******/ var depId = deferredModule[j];
|
||||||
|
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
|
||||||
|
/******/ }
|
||||||
|
/******/ if(fulfilled) {
|
||||||
|
/******/ deferredModules.splice(i--, 1);
|
||||||
|
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
|
||||||
|
/******/ }
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/ return result;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var installedModules = {};
|
||||||
|
/******/
|
||||||
|
/******/ // object to store loaded and loading chunks
|
||||||
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||||
|
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||||
|
/******/ var installedChunks = {
|
||||||
|
/******/ "main": 0
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ var deferredModules = [];
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ if(installedModules[moduleId]) {
|
||||||
|
/******/ return installedModules[moduleId].exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = installedModules[moduleId] = {
|
||||||
|
/******/ i: moduleId,
|
||||||
|
/******/ l: false,
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Flag the module as loaded
|
||||||
|
/******/ module.l = true;
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/******/
|
||||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||||
|
/******/ __webpack_require__.m = modules;
|
||||||
|
/******/
|
||||||
|
/******/ // expose the module cache
|
||||||
|
/******/ __webpack_require__.c = installedModules;
|
||||||
|
/******/
|
||||||
|
/******/ // define getter function for harmony exports
|
||||||
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||||
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||||
|
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
||||||
|
/******/ }
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // define __esModule on exports
|
||||||
|
/******/ __webpack_require__.r = function(exports) {
|
||||||
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||||
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||||
|
/******/ }
|
||||||
|
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // create a fake namespace object
|
||||||
|
/******/ // mode & 1: value is a module id, require it
|
||||||
|
/******/ // mode & 2: merge all properties of value into the ns
|
||||||
|
/******/ // mode & 4: return value when already ns object
|
||||||
|
/******/ // mode & 8|1: behave like require
|
||||||
|
/******/ __webpack_require__.t = function(value, mode) {
|
||||||
|
/******/ if(mode & 1) value = __webpack_require__(value);
|
||||||
|
/******/ if(mode & 8) return value;
|
||||||
|
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
||||||
|
/******/ var ns = Object.create(null);
|
||||||
|
/******/ __webpack_require__.r(ns);
|
||||||
|
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
||||||
|
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
||||||
|
/******/ return ns;
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||||
|
/******/ __webpack_require__.n = function(module) {
|
||||||
|
/******/ var getter = module && module.__esModule ?
|
||||||
|
/******/ function getDefault() { return module['default']; } :
|
||||||
|
/******/ function getModuleExports() { return module; };
|
||||||
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||||
|
/******/ return getter;
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Object.prototype.hasOwnProperty.call
|
||||||
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||||
|
/******/
|
||||||
|
/******/ // __webpack_public_path__
|
||||||
|
/******/ __webpack_require__.p = "";
|
||||||
|
/******/
|
||||||
|
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
|
||||||
|
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
|
||||||
|
/******/ jsonpArray.push = webpackJsonpCallback;
|
||||||
|
/******/ jsonpArray = jsonpArray.slice();
|
||||||
|
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
|
||||||
|
/******/ var parentJsonpFunction = oldJsonpFunction;
|
||||||
|
/******/
|
||||||
|
/******/
|
||||||
|
/******/ // add entry module to deferred list
|
||||||
|
/******/ deferredModules.push(["./assets/index.js","vendor"]);
|
||||||
|
/******/ // run deferred modules when ready
|
||||||
|
/******/ return checkDeferredModules();
|
||||||
|
/******/ })
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ ({
|
||||||
|
|
||||||
|
/***/ "./assets/index.js":
|
||||||
|
/*!*************************!*\
|
||||||
|
!*** ./assets/index.js ***!
|
||||||
|
\*************************/
|
||||||
|
/*! no exports provided */
|
||||||
|
/*! all exports used */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./js */ \"./assets/js/index.js\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./styles.scss */ \"./assets/styles.scss\");\n/* harmony import */ var _styles_scss__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_styles_scss__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _noscript_scss__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./noscript.scss */ \"./assets/noscript.scss\");\n/* harmony import */ var _noscript_scss__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_noscript_scss__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vue */ \"./assets/vue/index.js\");\n\n\n\n\n\n\n\n//# sourceURL=webpack:///./assets/index.js?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/js/index.js":
|
||||||
|
/*!****************************!*\
|
||||||
|
!*** ./assets/js/index.js ***!
|
||||||
|
\****************************/
|
||||||
|
/*! no exports provided */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var buefy__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! buefy */ \"./node_modules/buefy/dist/buefy.js\");\n/* harmony import */ var buefy__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(buefy__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].use(buefy__WEBPACK_IMPORTED_MODULE_1___default.a);\n\nwindow.addEventListener('load', () => {\n var app = new vue__WEBPACK_IMPORTED_MODULE_0__[\"default\"]({\n el: '#app',\n delimiters: [ '[[', ']]' ],\n })\n});\n\n\n\n\n\n//# sourceURL=webpack:///./assets/js/index.js?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/noscript.scss":
|
||||||
|
/*!******************************!*\
|
||||||
|
!*** ./assets/noscript.scss ***!
|
||||||
|
\******************************/
|
||||||
|
/*! no static exports found */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./assets/noscript.scss?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/styles.scss":
|
||||||
|
/*!****************************!*\
|
||||||
|
!*** ./assets/styles.scss ***!
|
||||||
|
\****************************/
|
||||||
|
/*! no static exports found */
|
||||||
|
/***/ (function(module, exports, __webpack_require__) {
|
||||||
|
|
||||||
|
eval("// extracted by mini-css-extract-plugin\n\n//# sourceURL=webpack:///./assets/styles.scss?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/index.js":
|
||||||
|
/*!*****************************!*\
|
||||||
|
!*** ./assets/vue/index.js ***!
|
||||||
|
\*****************************/
|
||||||
|
/*! exports provided: Tab, Tabs */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ \"./node_modules/vue/dist/vue.esm.browser.js\");\n/* harmony import */ var _tab_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tab.vue */ \"./assets/vue/tab.vue\");\n/* harmony import */ var _tabs_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./tabs.vue */ \"./assets/vue/tabs.vue\");\n\n\n\n\n\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-tab', _tab_vue__WEBPACK_IMPORTED_MODULE_1__[/* default */ \"a\"]);\nvue__WEBPACK_IMPORTED_MODULE_0__[\"default\"].component('a-tabs', _tabs_vue__WEBPACK_IMPORTED_MODULE_2__[/* default */ \"a\"]);\n\n\n\n\n\n\n//# sourceURL=webpack:///./assets/vue/index.js?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tab.vue":
|
||||||
|
/*!****************************!*\
|
||||||
|
!*** ./assets/vue/tab.vue ***!
|
||||||
|
\****************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tab.vue?vue&type=template&id=65401e0e& */ \"./assets/vue/tab.vue?vue&type=template&id=65401e0e&\");\n/* harmony import */ var _tab_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tab.vue?vue&type=script&lang=js& */ \"./assets/vue/tab.vue?vue&type=script&lang=js&\");\n/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n\n\n/* normalize component */\n\nvar component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ \"a\"])(\n _tab_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[/* default */ \"a\"],\n _tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__[/* render */ \"a\"],\n _tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__[/* staticRenderFns */ \"b\"],\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"assets/vue/tab.vue\"\n/* harmony default export */ __webpack_exports__[\"a\"] = (component.exports);\n\n//# sourceURL=webpack:///./assets/vue/tab.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tab.vue?vue&type=script&lang=js&":
|
||||||
|
/*!*****************************************************!*\
|
||||||
|
!*** ./assets/vue/tab.vue?vue&type=script&lang=js& ***!
|
||||||
|
\*****************************************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _node_modules_vue_loader_lib_index_js_vue_loader_options_tab_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib??vue-loader-options!./tab.vue?vue&type=script&lang=js& */ \"./node_modules/vue-loader/lib/index.js?!./assets/vue/tab.vue?vue&type=script&lang=js&\");\n /* harmony default export */ __webpack_exports__[\"a\"] = (_node_modules_vue_loader_lib_index_js_vue_loader_options_tab_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[/* default */ \"a\"]); \n\n//# sourceURL=webpack:///./assets/vue/tab.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tab.vue?vue&type=template&id=65401e0e&":
|
||||||
|
/*!***********************************************************!*\
|
||||||
|
!*** ./assets/vue/tab.vue?vue&type=template&id=65401e0e& ***!
|
||||||
|
\***********************************************************/
|
||||||
|
/*! exports provided: render, staticRenderFns */
|
||||||
|
/*! exports used: render, staticRenderFns */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../node_modules/vue-loader/lib??vue-loader-options!./tab.vue?vue&type=template&id=65401e0e& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/vue/tab.vue?vue&type=template&id=65401e0e&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__[\"a\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tab_vue_vue_type_template_id_65401e0e___WEBPACK_IMPORTED_MODULE_0__[\"b\"]; });\n\n\n\n//# sourceURL=webpack:///./assets/vue/tab.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tabs.vue":
|
||||||
|
/*!*****************************!*\
|
||||||
|
!*** ./assets/vue/tabs.vue ***!
|
||||||
|
\*****************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./tabs.vue?vue&type=template&id=466f44d5& */ \"./assets/vue/tabs.vue?vue&type=template&id=466f44d5&\");\n/* harmony import */ var _tabs_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./tabs.vue?vue&type=script&lang=js& */ \"./assets/vue/tabs.vue?vue&type=script&lang=js&\");\n/* harmony import */ var _node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../node_modules/vue-loader/lib/runtime/componentNormalizer.js */ \"./node_modules/vue-loader/lib/runtime/componentNormalizer.js\");\n\n\n\n\n\n/* normalize component */\n\nvar component = Object(_node_modules_vue_loader_lib_runtime_componentNormalizer_js__WEBPACK_IMPORTED_MODULE_2__[/* default */ \"a\"])(\n _tabs_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_1__[/* default */ \"a\"],\n _tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__[/* render */ \"a\"],\n _tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__[/* staticRenderFns */ \"b\"],\n false,\n null,\n null,\n null\n \n)\n\n/* hot reload */\nif (false) { var api; }\ncomponent.options.__file = \"assets/vue/tabs.vue\"\n/* harmony default export */ __webpack_exports__[\"a\"] = (component.exports);\n\n//# sourceURL=webpack:///./assets/vue/tabs.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tabs.vue?vue&type=script&lang=js&":
|
||||||
|
/*!******************************************************!*\
|
||||||
|
!*** ./assets/vue/tabs.vue?vue&type=script&lang=js& ***!
|
||||||
|
\******************************************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _node_modules_vue_loader_lib_index_js_vue_loader_options_tabs_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib??vue-loader-options!./tabs.vue?vue&type=script&lang=js& */ \"./node_modules/vue-loader/lib/index.js?!./assets/vue/tabs.vue?vue&type=script&lang=js&\");\n /* harmony default export */ __webpack_exports__[\"a\"] = (_node_modules_vue_loader_lib_index_js_vue_loader_options_tabs_vue_vue_type_script_lang_js___WEBPACK_IMPORTED_MODULE_0__[/* default */ \"a\"]); \n\n//# sourceURL=webpack:///./assets/vue/tabs.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./assets/vue/tabs.vue?vue&type=template&id=466f44d5&":
|
||||||
|
/*!************************************************************!*\
|
||||||
|
!*** ./assets/vue/tabs.vue?vue&type=template&id=466f44d5& ***!
|
||||||
|
\************************************************************/
|
||||||
|
/*! exports provided: render, staticRenderFns */
|
||||||
|
/*! exports used: render, staticRenderFns */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony import */ var _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! -!../../node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!../../node_modules/vue-loader/lib??vue-loader-options!./tabs.vue?vue&type=template&id=466f44d5& */ \"./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/vue/tabs.vue?vue&type=template&id=466f44d5&\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__[\"a\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return _node_modules_vue_loader_lib_loaders_templateLoader_js_vue_loader_options_node_modules_vue_loader_lib_index_js_vue_loader_options_tabs_vue_vue_type_template_id_466f44d5___WEBPACK_IMPORTED_MODULE_0__[\"b\"]; });\n\n\n\n//# sourceURL=webpack:///./assets/vue/tabs.vue?");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/vue/tab.vue?vue&type=script&lang=js&":
|
||||||
|
/*!*******************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/vue/tab.vue?vue&type=script&lang=js& ***!
|
||||||
|
\*******************************************************************************************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n props: {\n value: { default: undefined },\n },\n\n methods: {\n select() {\n this.$parent.selectTab(this);\n },\n\n onclick(event) {\n this.select();\n /*if(event.target.href != document.location)\n window.history.pushState(\n { url: event.target.href },\n event.target.innerText + ' - ' + document.title,\n event.target.href\n ) */\n }\n }\n});\n\n\n//# sourceURL=webpack:///./assets/vue/tab.vue?./node_modules/vue-loader/lib??vue-loader-options");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./node_modules/vue-loader/lib/index.js?!./assets/vue/tabs.vue?vue&type=script&lang=js&":
|
||||||
|
/*!********************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/vue-loader/lib??vue-loader-options!./assets/vue/tabs.vue?vue&type=script&lang=js& ***!
|
||||||
|
\********************************************************************************************************/
|
||||||
|
/*! exports provided: default */
|
||||||
|
/*! exports used: default */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("//\n//\n//\n//\n//\n//\n//\n//\n//\n//\n\n/* harmony default export */ __webpack_exports__[\"a\"] = ({\n props: {\n default: { default: null },\n },\n\n data() {\n return {\n value: this.default,\n }\n },\n\n computed: {\n tab() {\n const vnode = this.$slots.default && this.$slots.default.find(\n elm => elm.child && elm.child.value == this.value\n );\n return vnode && vnode.child;\n }\n },\n\n methods: {\n selectTab(tab) {\n const value = tab.value;\n if(this.value === value)\n return;\n\n this.value = value;\n this.$emit('select', {target: this, value: value, tab: tab});\n },\n },\n});\n\n\n//# sourceURL=webpack:///./assets/vue/tabs.vue?./node_modules/vue-loader/lib??vue-loader-options");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/vue/tab.vue?vue&type=template&id=65401e0e&":
|
||||||
|
/*!*****************************************************************************************************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/vue/tab.vue?vue&type=template&id=65401e0e& ***!
|
||||||
|
\*****************************************************************************************************************************************************************************************/
|
||||||
|
/*! exports provided: render, staticRenderFns */
|
||||||
|
/*! exports used: render, staticRenderFns */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"li\",\n {\n class: { \"is-active\": _vm.$parent.value == _vm.value },\n on: {\n click: function($event) {\n $event.preventDefault()\n return _vm.onclick($event)\n }\n }\n },\n [_vm._t(\"default\")],\n 2\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./assets/vue/tab.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options");
|
||||||
|
|
||||||
|
/***/ }),
|
||||||
|
|
||||||
|
/***/ "./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/vue-loader/lib/index.js?!./assets/vue/tabs.vue?vue&type=template&id=466f44d5&":
|
||||||
|
/*!******************************************************************************************************************************************************************************************!*\
|
||||||
|
!*** ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./assets/vue/tabs.vue?vue&type=template&id=466f44d5& ***!
|
||||||
|
\******************************************************************************************************************************************************************************************/
|
||||||
|
/*! exports provided: render, staticRenderFns */
|
||||||
|
/*! exports used: render, staticRenderFns */
|
||||||
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
eval("/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return render; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return staticRenderFns; });\nvar render = function() {\n var _vm = this\n var _h = _vm.$createElement\n var _c = _vm._self._c || _h\n return _c(\n \"div\",\n [\n _c(\"div\", { staticClass: \"tabs is-centered\" }, [\n _c(\"ul\", [_vm._t(\"tabs\", null, { value: _vm.value })], 2)\n ]),\n _vm._v(\" \"),\n _vm._t(\"default\", null, { value: _vm.value })\n ],\n 2\n )\n}\nvar staticRenderFns = []\nrender._withStripped = true\n\n\n\n//# sourceURL=webpack:///./assets/vue/tabs.vue?./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options");
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
/******/ });
|
89
aircox/static/aircox/vendor.js
Normal file
89
aircox/static/aircox/vendor.js
Normal file
File diff suppressed because one or more lines are too long
84
aircox/templates/aircox/base.html
Normal file
84
aircox/templates/aircox/base.html
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
{% load static i18n thumbnail aircox %}
|
||||||
|
{% comment %}
|
||||||
|
Context:
|
||||||
|
- site: current website
|
||||||
|
{% endcomment %}
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="application-name" content="aircox">
|
||||||
|
<meta name="description" content="{{ site.description }}">
|
||||||
|
<meta name="keywords" content="{{ site.tags }}">
|
||||||
|
<link rel="icon" href="{% thumbnail site.favicon 32x32 crop %}" />
|
||||||
|
|
||||||
|
{% block assets %}
|
||||||
|
<link rel="stylesheet" type="text/css" href="{% static "aircox/main.css" %}"/>
|
||||||
|
<script src="{% static "aircox/main.js" %}"></script>
|
||||||
|
<script src="{% static "aircox/vendor.js" %}"></script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<title>
|
||||||
|
{% block head_title %}{{ site.title }}{% endblock %}
|
||||||
|
</title>
|
||||||
|
|
||||||
|
{% block head_extra %}{% endblock %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<nav class="navbar has-shadow" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a href="/" title="{% trans "Home" %}" class="navbar-item">
|
||||||
|
<img src="{{ station.logo.url }}" class="logo"/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-menu">
|
||||||
|
<div class="navbar-start">
|
||||||
|
{% block top-nav %}
|
||||||
|
{% nav_items "top" css_class="navbar-item" active_class="is-active" as items %}
|
||||||
|
{% for item, render in items %}
|
||||||
|
{{ render }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="columns is-desktop">
|
||||||
|
<main class="column page">
|
||||||
|
<header class="header">
|
||||||
|
{% block header %}
|
||||||
|
<h1 class="title is-1">{% block title %}{% endblock %}</h1>
|
||||||
|
|
||||||
|
{% if parent %}
|
||||||
|
<h4 class="subtitle is-size-3">
|
||||||
|
<a href="{{ parent.get_absolute_url }}">
|
||||||
|
❬ {{ parent.title }}</a></li>
|
||||||
|
</h4>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
</header>
|
||||||
|
|
||||||
|
{% block main %}{% endblock main %}
|
||||||
|
</main>
|
||||||
|
{% if show_side_nav %}
|
||||||
|
<aside class="column is-one-third-desktop">
|
||||||
|
{% block cover %}
|
||||||
|
{% if cover is not None %}
|
||||||
|
<img class="cover" src="{{ cover.url }}" class="cover"/>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block side_nav %}
|
||||||
|
{% endblock %}
|
||||||
|
</aside>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
|
59
aircox/templates/aircox/diffusion_item.html
Normal file
59
aircox/templates/aircox/diffusion_item.html
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
{% load i18n easy_thumbnails_tags aircox %}
|
||||||
|
{% comment %}
|
||||||
|
Context variables:
|
||||||
|
- object: the actual diffusion
|
||||||
|
- page: current parent page in which item is rendered
|
||||||
|
- hide_schedule: if True, do not display start time
|
||||||
|
- hide_headline: if True, do not display headline
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% with object.episode as episode %}
|
||||||
|
{% with episode.program as program %}
|
||||||
|
<article class="media">
|
||||||
|
<div class="media-left">
|
||||||
|
<img src="{% thumbnail episode.cover 128x128 crop=scale %}"
|
||||||
|
class="small-cover">
|
||||||
|
</div>
|
||||||
|
<div class="media-content">
|
||||||
|
<h5 class="subtitle is-size-5">
|
||||||
|
{% if episode.is_published %}
|
||||||
|
<a href="{{ episode.get_absolute_url }}">{{ episode.title }}</a>
|
||||||
|
{% endif %}
|
||||||
|
</h5>
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
{% if not page or program != page %}
|
||||||
|
{% if program.is_published %}
|
||||||
|
<a href="{{ program.get_absolute_url }}" class="has-text-grey-dark">
|
||||||
|
{{ program.title }}</a>
|
||||||
|
{% else %}{{ program.title }}
|
||||||
|
{% endif %}
|
||||||
|
{% if not hide_schedule %} — {% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not hide_schedule %}
|
||||||
|
<time datetime="{{ object.start|date:"c" }}" title="{{ object.start }}"
|
||||||
|
class="has-text-weight-light is-size-6">
|
||||||
|
{{ object.start|date:"d M, H:i" }}
|
||||||
|
</time>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if object.initial %}
|
||||||
|
{% with object.initial.date as date %}
|
||||||
|
<span class="tag is-info" title="{% blocktrans %}Rerun of {{ date }}{% endblocktrans %}">
|
||||||
|
{% trans "rerun" %}
|
||||||
|
</span>
|
||||||
|
{% endwith %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% if not hide_headline %}
|
||||||
|
<div class="content">
|
||||||
|
{{ episode.headline }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
|
51
aircox/templates/aircox/diffusion_list.html
Normal file
51
aircox/templates/aircox/diffusion_list.html
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{% extends "aircox/page.html" %}
|
||||||
|
{% load i18n aircox %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% if program %}
|
||||||
|
{% with program.name as program %}
|
||||||
|
{% blocktrans %}Diffusions of {{ program }}{% endblocktrans %}
|
||||||
|
{% endwith %}
|
||||||
|
{% else %}
|
||||||
|
{% trans "All diffusions" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<section>
|
||||||
|
{% for object in object_list %}
|
||||||
|
{% include "aircox/diffusion_item.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
{% if is_paginated %}
|
||||||
|
<nav class="pagination is-centered" role="pagination" aria-label="{% trans "pagination" %}">
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<a href="?page={{ page_obj.previous_page_number }}" class="pagination-previous">
|
||||||
|
{% else %}
|
||||||
|
<a class="pagination-previous" disabled>
|
||||||
|
{% endif %}
|
||||||
|
{% trans "Previous" %}</a>
|
||||||
|
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<a href="?page={{ page_obj.next_page_number }}" class="pagination-next">
|
||||||
|
{% else %}
|
||||||
|
<a class="pagination-next" disabled>
|
||||||
|
{% endif %}
|
||||||
|
{% trans "Next" %}</a>
|
||||||
|
|
||||||
|
<ul class="pagination-list">
|
||||||
|
{% for i in paginator.page_range %}
|
||||||
|
<li>
|
||||||
|
<a class="pagination-link {% if page_obj.number == i %}is-current{% endif %}"
|
||||||
|
href="?page={{ i }}">{{ i }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
56
aircox/templates/aircox/diffusion_timetable.html
Normal file
56
aircox/templates/aircox/diffusion_timetable.html
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
{% extends "aircox/page.html" %}
|
||||||
|
{% load i18n aircox %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Timetable" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
<h3 class="subtitle size-3">
|
||||||
|
{% blocktrans %}From <b>{{ start }}</b> to <b>{{ end }}</b>{% endblocktrans %}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
{% unique_id "timetable" as timetable_id %}
|
||||||
|
<a-tabs default="{{ date }}">
|
||||||
|
<template v-slot:tabs="scope" noscript="hidden">
|
||||||
|
<li><a href="{% url "timetable" date=prev_date %}"><</a></li>
|
||||||
|
|
||||||
|
{% for day in by_date.keys %}
|
||||||
|
<a-tab value="{{ day }}">
|
||||||
|
<a href="{% url "timetable" date=day %}">
|
||||||
|
{{ day|date:"D. d" }}
|
||||||
|
</a>
|
||||||
|
</a-tab>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="{% url "timetable" date=next_date %}">></a>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
{% with True as hide_schedule %}
|
||||||
|
<template v-slot:default="{value}">
|
||||||
|
{% for day, diffusions in by_date.items %}
|
||||||
|
<noscript><h4 class="subtitle is-4">{{ day|date:"l d F Y" }}</h4></noscript>
|
||||||
|
<div id="{{timetable_id}}-{{ day|date:"Y-m-d" }}" v-if="value == '{{ day }}'">
|
||||||
|
{% for object in diffusions %}
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column is-one-fifth has-text-right">
|
||||||
|
<time datetime="{{ object.start|date:"c" }}">
|
||||||
|
{{ object.start|date:"H:i" }} - {{ object.end|date:"H:i" }}
|
||||||
|
</time>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
{% include "aircox/diffusion_item.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</template>
|
||||||
|
{% endwith %}
|
||||||
|
</a-tabs>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
14
aircox/templates/aircox/episode_detail.html
Normal file
14
aircox/templates/aircox/episode_detail.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{% extends "aircox/program_base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
{% if podcasts %}
|
||||||
|
{% for object in podcasts %}
|
||||||
|
{% include "aircox/podcast_item.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
19
aircox/templates/aircox/log_item.html
Normal file
19
aircox/templates/aircox/log_item.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% with object.track as track %}
|
||||||
|
<span class="has-text-info is-size-5">♬</span>
|
||||||
|
<span>{{ track.title }}</span>
|
||||||
|
{% with track.artist as artist %}
|
||||||
|
{% with track.info as info %}
|
||||||
|
<span class="has-text-grey-dark has-text-weight-light">
|
||||||
|
{% blocktrans %}
|
||||||
|
by {{ artist }}
|
||||||
|
{% endblocktrans %}
|
||||||
|
{% if info %}
|
||||||
|
({% blocktrans %}<i>{{ info }}</i>{% endblocktrans %})
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
|
57
aircox/templates/aircox/log_list.html
Normal file
57
aircox/templates/aircox/log_list.html
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{% extends "aircox/page.html" %}
|
||||||
|
{% load i18n aircox %}
|
||||||
|
|
||||||
|
{% block title %}
|
||||||
|
{% trans "Logs" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<section class="section">
|
||||||
|
{% if dates %}
|
||||||
|
<nav class="tabs is-centered" aria-label="{% trans "Other days' logs" %}">
|
||||||
|
<ul>
|
||||||
|
{% for day in dates %}
|
||||||
|
<li {% if day == date %}class="is-active"{% endif %}>
|
||||||
|
<a href="{% url "logs" date=day %}">
|
||||||
|
{{ day|date:"d b" }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
{% if forloop.last and day > min_date %}
|
||||||
|
<li>...</li>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# <h4 class="subtitle size-4">{{ date }}</h4> #}
|
||||||
|
{% with True as hide_schedule %}
|
||||||
|
<table class="table is-striped is-hoverable is-fullwidth">
|
||||||
|
{% for object in object_list reversed %}
|
||||||
|
<tr>
|
||||||
|
{% if object|is_diffusion %}
|
||||||
|
<td>
|
||||||
|
<time datetime="{{ object.start }}" title="{{ object.start }}">
|
||||||
|
{{ object.start|date:"H:i" }} - {{ object.end|date:"H:i" }}
|
||||||
|
</time>
|
||||||
|
</td>
|
||||||
|
<td>{% include "aircox/diffusion_item.html" %}</td>
|
||||||
|
{% else %}
|
||||||
|
<td>
|
||||||
|
<time datetime="{{ object.date }}" title="{{ object.date }}">
|
||||||
|
{{ object.date|date:"H:i" }}
|
||||||
|
</time>
|
||||||
|
</td>
|
||||||
|
<td>{% include "aircox/log_item.html" %}</td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
{% endwith %}
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
||||||
|
|
30
aircox/templates/aircox/page.html
Normal file
30
aircox/templates/aircox/page.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
{% extends "aircox/base.html" %}
|
||||||
|
{% load static i18n thumbnail %}
|
||||||
|
{% comment %}
|
||||||
|
Context:
|
||||||
|
- cover: cover image
|
||||||
|
- title: title
|
||||||
|
- page: page
|
||||||
|
{% endcomment %}
|
||||||
|
|
||||||
|
{% block head_title %}
|
||||||
|
{% block title %}{{ title }}{% endblock %}
|
||||||
|
{% if title %} — {% endif %}
|
||||||
|
{{ site.title }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block main %}
|
||||||
|
{% block headline %}
|
||||||
|
{% if page and page.headline %}
|
||||||
|
<p class="headline">{{ page.headline }}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ page.content|default_if_none:''|safe }}
|
||||||
|
{% endblock %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
|
8
aircox/templates/aircox/podcast_item.html
Normal file
8
aircox/templates/aircox/podcast_item.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<div class="podcast">
|
||||||
|
{% if object.embed %}
|
||||||
|
{{ object.embed }}
|
||||||
|
{% else %}
|
||||||
|
<audio src="{{ object.url }}" controls>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
29
aircox/templates/aircox/program_base.html
Normal file
29
aircox/templates/aircox/program_base.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{% extends "aircox/page.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block side_nav %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
{% if diffusions %}
|
||||||
|
<section>
|
||||||
|
<h4 class="subtitle is-size-4">{% trans "Last shows" %}</h4>
|
||||||
|
|
||||||
|
{% for object in diffusions %}
|
||||||
|
{% include "aircox/diffusion_item.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<br>
|
||||||
|
<nav class="pagination is-centered">
|
||||||
|
<ul class="pagination-list">
|
||||||
|
<li>
|
||||||
|
<a href="{% url "diffusion-list" program_slug=page.slug %}"
|
||||||
|
class="pagination-link"
|
||||||
|
aria-label="{% trans "Show all diffusions" %}">
|
||||||
|
{% trans "All diffusions" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
8
aircox/templates/aircox/program_detail.html
Normal file
8
aircox/templates/aircox/program_detail.html
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{% extends "aircox/program_base.html" %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block header %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% include "aircox/program_header.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
25
aircox/templates/aircox/program_header.html
Normal file
25
aircox/templates/aircox/program_header.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{% load i18n %}
|
||||||
|
<section class="is-size-5">
|
||||||
|
{% for schedule in program.schedule_set.all %}
|
||||||
|
<p>
|
||||||
|
{{ schedule.get_frequency_verbose }}
|
||||||
|
{% with schedule.start|date:"H:i" as start %}
|
||||||
|
{% with schedule.end|date:"H:i" as end %}
|
||||||
|
<time datetime="{{ start }}">{{ start }}</time>
|
||||||
|
—
|
||||||
|
<time datetime="{{ end }}">{{ end }}</time>
|
||||||
|
{% endwith %}
|
||||||
|
{% endwith %}
|
||||||
|
<small>
|
||||||
|
{% if schedule.initial %}
|
||||||
|
{% with schedule.initial.date as date %}
|
||||||
|
<span title="{% blocktrans %}Rerun of {{ date }}{% endblocktrans %}">
|
||||||
|
({% trans "rerun" %})
|
||||||
|
</span>
|
||||||
|
{% endwith %}
|
||||||
|
{% endif %}
|
||||||
|
</small>
|
||||||
|
</p>
|
||||||
|
{% endfor %}
|
||||||
|
</section>
|
||||||
|
|
28
aircox/templatetags/aircox.py
Normal file
28
aircox/templatetags/aircox.py
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import random
|
||||||
|
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
from aircox.models import Page, Diffusion
|
||||||
|
|
||||||
|
random.seed()
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(name='unique_id')
|
||||||
|
def do_unique_id(prefix=''):
|
||||||
|
value = str(random.random()).replace('.', '')
|
||||||
|
return prefix + '_' + value if prefix else value
|
||||||
|
|
||||||
|
|
||||||
|
@register.filter(name='is_diffusion')
|
||||||
|
def do_is_diffusion(obj):
|
||||||
|
return isinstance(obj, Diffusion)
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag(name='nav_items', takes_context=True)
|
||||||
|
def do_nav_items(context, menu, **kwargs):
|
||||||
|
station, request = context['station'], context['request']
|
||||||
|
return [(item, item.render(request, **kwargs))
|
||||||
|
for item in station.navitem_set.filter(menu=menu)]
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,40 @@
|
||||||
from django.urls import path
|
from django.urls import path, register_converter
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
from .converters import PagePathConverter, DateConverter, WeekConverter
|
||||||
|
|
||||||
|
|
||||||
|
register_converter(PagePathConverter, 'page_path')
|
||||||
|
register_converter(DateConverter, 'date')
|
||||||
|
register_converter(WeekConverter, 'week')
|
||||||
|
|
||||||
|
|
||||||
|
#urls = [
|
||||||
|
# path('on_air', views.on_air, name='aircox.on_air'),
|
||||||
|
# path('monitor', views.Monitor.as_view(), name='aircox.monitor'),
|
||||||
|
# path('stats', views.StatisticsView.as_view(), name='aircox.stats'),
|
||||||
|
#]
|
||||||
|
|
||||||
import aircox.views as views
|
|
||||||
|
|
||||||
urls = [
|
urls = [
|
||||||
path('on_air', views.on_air, name='aircox.on_air'),
|
path(_('programs/<slug:slug>/'),
|
||||||
path('monitor', views.Monitor.as_view(), name='aircox.monitor'),
|
views.ProgramDetailView.as_view(), name='program-detail'),
|
||||||
path('stats', views.StatisticsView.as_view(), name='aircox.stats'),
|
path(_('programs/<slug:program_slug>/episodes/'),
|
||||||
|
views.DiffusionListView.as_view(), name='diffusion-list'),
|
||||||
|
|
||||||
|
path(_('episodes/'),
|
||||||
|
views.DiffusionListView.as_view(), name='diffusion-list'),
|
||||||
|
path(_('episodes/week/'),
|
||||||
|
views.TimetableView.as_view(), name='timetable'),
|
||||||
|
path(_('episodes/week/<week:date>/'),
|
||||||
|
views.TimetableView.as_view(), name='timetable'),
|
||||||
|
path(_('episodes/<slug:slug>/'),
|
||||||
|
views.EpisodeDetailView.as_view(), name='episode-detail'),
|
||||||
|
|
||||||
|
path(_('logs/'), views.LogListView.as_view(), name='logs'),
|
||||||
|
path(_('logs/<date:date>/'), views.LogListView.as_view(), name='logs'),
|
||||||
|
# path('<page_path:path>', views.route_page, name='page'),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,23 @@ import datetime
|
||||||
import django.utils.timezone as tz
|
import django.utils.timezone as tz
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ['Redirect', 'redirect', 'date_range', 'cast_date',
|
||||||
|
'date_or_default', 'to_timedelta', 'seconds_to_time']
|
||||||
|
|
||||||
|
|
||||||
|
class Redirect(Exception):
|
||||||
|
""" Redirect exception -- see `redirect()`. """
|
||||||
|
def __init__(self, url):
|
||||||
|
self.url = url
|
||||||
|
|
||||||
|
|
||||||
|
def redirect(url):
|
||||||
|
"""
|
||||||
|
Raise a Redirect exception in order to response a redirection to client.
|
||||||
|
AircoxMiddleware must be enabled. """
|
||||||
|
raise Redirect(url)
|
||||||
|
|
||||||
|
|
||||||
def date_range(date, delta=None, **delta_kwargs):
|
def date_range(date, delta=None, **delta_kwargs):
|
||||||
"""
|
"""
|
||||||
Return a range of provided date such as `[date-delta, date+delta]`.
|
Return a range of provided date such as `[date-delta, date+delta]`.
|
||||||
|
@ -53,6 +70,11 @@ def to_timedelta(time):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_seconds(time):
|
||||||
|
""" Return total seconds for provided time """
|
||||||
|
return 3600 * time.hour + 60 * time.minute + time.second
|
||||||
|
|
||||||
|
|
||||||
def seconds_to_time(seconds):
|
def seconds_to_time(seconds):
|
||||||
"""
|
"""
|
||||||
Seconds to datetime.time
|
Seconds to datetime.time
|
||||||
|
|
|
@ -2,7 +2,7 @@ import random
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
|
|
||||||
from aircox import models as aircox
|
from aircox.models import Page,
|
||||||
from aircox_web.models import Page
|
from aircox_web.models import Page
|
||||||
|
|
||||||
random.seed()
|
random.seed()
|
||||||
|
@ -12,11 +12,11 @@ register = template.Library()
|
||||||
@register.simple_tag(name='diffusion_page')
|
@register.simple_tag(name='diffusion_page')
|
||||||
def do_diffusion_page(diffusion):
|
def do_diffusion_page(diffusion):
|
||||||
""" Return page for diffusion. """
|
""" Return page for diffusion. """
|
||||||
diff = diffusion.initial if diffusion.initial is not None else diffusion
|
episode = diffusion.episode
|
||||||
for obj in (diff, diffusion.program):
|
if episode.is_publihed:
|
||||||
page = getattr(obj, 'page', None)
|
return diff.episode
|
||||||
if page is not None and page.status == Page.STATUS.published:
|
program = episode.program
|
||||||
return page
|
return program if program.is_published else None
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(name='unique_id')
|
@register.simple_tag(name='unique_id')
|
||||||
|
|
5
assets/index.js
Normal file
5
assets/index.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import './js';
|
||||||
|
import './styles.scss';
|
||||||
|
import './noscript.scss';
|
||||||
|
import './vue';
|
||||||
|
|
14
assets/js/index.js
Normal file
14
assets/js/index.js
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Buefy from 'buefy';
|
||||||
|
|
||||||
|
Vue.use(Buefy);
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
var app = new Vue({
|
||||||
|
el: '#app',
|
||||||
|
delimiters: [ '[[', ']]' ],
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
6
assets/noscript.scss
Normal file
6
assets/noscript.scss
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
/**[noscript="hidden"] {
|
||||||
|
display: none;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
75
assets/styles.scss
Normal file
75
assets/styles.scss
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
@charset "utf-8";
|
||||||
|
@import "~bulma/sass/utilities/_all.sass";
|
||||||
|
|
||||||
|
$body-background-color: $light;
|
||||||
|
|
||||||
|
@import "~bulma/bulma";
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar.has-shadow {
|
||||||
|
box-shadow: 0em 0.05em 0.5em rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
.navbar-brand img {
|
||||||
|
min-height: 6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-menu .navbar-item:not(:last-child) {
|
||||||
|
border-right: 1px $grey solid;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** page **/
|
||||||
|
.page {
|
||||||
|
& > .cover {
|
||||||
|
float: right;
|
||||||
|
max-width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .header {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headline {
|
||||||
|
font-size: 1.4em;
|
||||||
|
padding: 0.2em 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
padding: 0.4em 0em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.cover {
|
||||||
|
margin: 1em 0em;
|
||||||
|
border: 0.2em black solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.small-cover {
|
||||||
|
width: 10em;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
.small-cover {
|
||||||
|
width: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media .subtitle {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.media .content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
28
assets/vue/deck.vue
Normal file
28
assets/vue/deck.vue
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-tabs class="tabs" @select="value = $event.value;">
|
||||||
|
<template v-slot:default><slot name="tabs" :value="value"/></template>
|
||||||
|
</a-tabs>
|
||||||
|
|
||||||
|
<slot :value="value"></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Tabs from './tabs.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: ['default'],
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: this.default,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
'a-tabs': Tabs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
11
assets/vue/index.js
Normal file
11
assets/vue/index.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import Tab from './tab.vue';
|
||||||
|
import Tabs from './tabs.vue';
|
||||||
|
|
||||||
|
Vue.component('a-tab', Tab);
|
||||||
|
Vue.component('a-tabs', Tabs);
|
||||||
|
|
||||||
|
export {Tab, Tabs};
|
||||||
|
|
||||||
|
|
31
assets/vue/tab.vue
Normal file
31
assets/vue/tab.vue
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<template>
|
||||||
|
<li @click.prevent="onclick"
|
||||||
|
:class="{'is-active': $parent.value == value}">
|
||||||
|
<slot></slot>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: { default: undefined },
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
select() {
|
||||||
|
this.$parent.selectTab(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
onclick(event) {
|
||||||
|
this.select();
|
||||||
|
/*if(event.target.href != document.location)
|
||||||
|
window.history.pushState(
|
||||||
|
{ url: event.target.href },
|
||||||
|
event.target.innerText + ' - ' + document.title,
|
||||||
|
event.target.href
|
||||||
|
) */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
45
assets/vue/tabs.vue
Normal file
45
assets/vue/tabs.vue
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="tabs is-centered">
|
||||||
|
<ul><slot name="tabs" :value="value" /></ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<slot :value="value"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
default: { default: null },
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: this.default,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
tab() {
|
||||||
|
const vnode = this.$slots.default && this.$slots.default.find(
|
||||||
|
elm => elm.child && elm.child.value == this.value
|
||||||
|
);
|
||||||
|
return vnode && vnode.child;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
selectTab(tab) {
|
||||||
|
const value = tab.value;
|
||||||
|
if(this.value === value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.value = value;
|
||||||
|
this.$emit('select', {target: this, value: value, tab: tab});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,13 @@ Including another URLconf
|
||||||
1. Add an import: from blog import urls as blog_urls
|
1. Add an import: from blog import urls as blog_urls
|
||||||
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
|
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
|
||||||
"""
|
"""
|
||||||
|
# from django.conf.urls.i18n import i18n_patterns
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.urls import include, path, re_path
|
from django.urls import include, path, re_path
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
import aircox.urls
|
import aircox.urls
|
||||||
# import aircox_web.urls
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
@ -35,7 +36,6 @@ try:
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns.append(path('filer/', include('filer.urls')))
|
urlpatterns.append(path('filer/', include('filer.urls')))
|
||||||
# urlpatterns += aircox_web.urls.urlpatterns
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
import traceback
|
import traceback
|
||||||
|
|
29
package.json
Normal file
29
package.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "aircox-web-assets",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "Assets for Aircox Web",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "bkfox",
|
||||||
|
"license": "AGPL",
|
||||||
|
"devDependencies": {
|
||||||
|
"@fortawesome/fontawesome-free": "^5.8.2",
|
||||||
|
"bulma": "^0.7.5",
|
||||||
|
"css-loader": "^2.1.1",
|
||||||
|
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||||
|
"file-loader": "^3.0.1",
|
||||||
|
"mini-css-extract-plugin": "^0.5.0",
|
||||||
|
"node-sass": "^4.12.0",
|
||||||
|
"sass-loader": "^7.1.0",
|
||||||
|
"style-loader": "^0.23.1",
|
||||||
|
"ttf-loader": "^1.0.2",
|
||||||
|
"vue-loader": "^15.7.0",
|
||||||
|
"vue-style-loader": "^4.1.2",
|
||||||
|
"vue-template-compiler": "^2.6.10",
|
||||||
|
"webpack": "^4.32.2",
|
||||||
|
"webpack-cli": "^3.3.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"buefy": "^0.7.8",
|
||||||
|
"vue": "^2.6.10"
|
||||||
|
}
|
||||||
|
}
|
93
webpack.config.js
Normal file
93
webpack.config.js
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
const path = require('path');
|
||||||
|
const webpack = require('webpack');
|
||||||
|
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
// const { createLodashAliases } = require('lodash-loader');
|
||||||
|
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = (env, argv) => Object({
|
||||||
|
context: __dirname,
|
||||||
|
entry: './assets/index',
|
||||||
|
|
||||||
|
output: {
|
||||||
|
path: path.resolve('aircox/static/aircox'),
|
||||||
|
filename: '[name].js',
|
||||||
|
chunkFilename: '[name].js',
|
||||||
|
},
|
||||||
|
|
||||||
|
optimization: {
|
||||||
|
usedExports: true,
|
||||||
|
concatenateModules: argv.mode == 'production' ? true : false,
|
||||||
|
|
||||||
|
splitChunks: {
|
||||||
|
cacheGroups: {
|
||||||
|
vendor: {
|
||||||
|
name: 'vendor',
|
||||||
|
chunks: 'initial',
|
||||||
|
enforce: true,
|
||||||
|
|
||||||
|
test: /[\\/]node_modules[\\/]/,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*noscript: {
|
||||||
|
name: 'noscript',
|
||||||
|
chunks: 'initial',
|
||||||
|
enforce: true,
|
||||||
|
test: /noscript/,
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "[name].css",
|
||||||
|
chunkFilename: "[id].css"
|
||||||
|
}),
|
||||||
|
new VueLoaderPlugin(),
|
||||||
|
],
|
||||||
|
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{ test: /\.vue$/, loader: 'vue-loader' },
|
||||||
|
{
|
||||||
|
test: /\/node_modules\//,
|
||||||
|
sideEffects: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: [ { loader: MiniCssExtractPlugin.loader },
|
||||||
|
{ loader: 'css-loader' },
|
||||||
|
{ loader: 'sass-loader' , options: { sourceMap: true }} ],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// TODO: remove ttf eot svg
|
||||||
|
test: /\.(ttf|eot|svg|woff2?)$/,
|
||||||
|
use: [{
|
||||||
|
loader: 'file-loader',
|
||||||
|
options: {
|
||||||
|
name: '[name].[ext]',
|
||||||
|
outputPath: 'fonts/',
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
js: path.resolve(__dirname, 'assets/js'),
|
||||||
|
vue: 'vue/dist/vue.esm.browser.js',
|
||||||
|
// buefy: 'buefy/dist/buefy.js',
|
||||||
|
},
|
||||||
|
modules: [
|
||||||
|
'assets/css',
|
||||||
|
'assets/js',
|
||||||
|
'assets/vue',
|
||||||
|
'./node_modules',
|
||||||
|
],
|
||||||
|
extensions: ['.js', '.vue', '.css', '.styl', '.ttf']
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user