@rmdes/indiekit-endpoint-funkwhale 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +6 -15
- package/lib/controllers/dashboard.js +18 -11
- package/lib/sync.js +19 -0
- package/locales/en.json +2 -2
- package/package.json +1 -2
- package/views/funkwhale.njk +25 -15
- package/assets/styles.css +0 -453
- package/views/favorites.njk +0 -124
- package/views/listenings.njk +0 -129
- package/views/partials/stats-summary.njk +0 -18
- package/views/partials/top-albums.njk +0 -20
- package/views/partials/top-artists.njk +0 -13
- package/views/stats.njk +0 -432
package/views/stats.njk
DELETED
|
@@ -1,432 +0,0 @@
|
|
|
1
|
-
{% extends "document.njk" %}
|
|
2
|
-
|
|
3
|
-
{% block content %}
|
|
4
|
-
<style>
|
|
5
|
-
.fw-section { margin-bottom: 2rem; }
|
|
6
|
-
|
|
7
|
-
/* Stats grid */
|
|
8
|
-
.fw-stats-grid {
|
|
9
|
-
display: grid;
|
|
10
|
-
grid-template-columns: repeat(4, 1fr);
|
|
11
|
-
gap: 1rem;
|
|
12
|
-
margin-bottom: 1.5rem;
|
|
13
|
-
}
|
|
14
|
-
@media (max-width: 600px) {
|
|
15
|
-
.fw-stats-grid { grid-template-columns: repeat(2, 1fr); }
|
|
16
|
-
}
|
|
17
|
-
.fw-stat {
|
|
18
|
-
display: flex;
|
|
19
|
-
flex-direction: column;
|
|
20
|
-
align-items: center;
|
|
21
|
-
padding: 1rem;
|
|
22
|
-
background: var(--color-offset, #f5f5f5);
|
|
23
|
-
border-radius: 0.5rem;
|
|
24
|
-
text-align: center;
|
|
25
|
-
}
|
|
26
|
-
.fw-stat-value {
|
|
27
|
-
font-size: 1.5rem;
|
|
28
|
-
font-weight: 700;
|
|
29
|
-
color: var(--color-accent, #3b82f6);
|
|
30
|
-
}
|
|
31
|
-
.fw-stat-label {
|
|
32
|
-
font-size: 0.75rem;
|
|
33
|
-
color: var(--color-text-secondary, #666);
|
|
34
|
-
text-transform: uppercase;
|
|
35
|
-
letter-spacing: 0.05em;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/* Tabs */
|
|
39
|
-
.fw-tabs {
|
|
40
|
-
display: flex;
|
|
41
|
-
gap: 0.25rem;
|
|
42
|
-
margin-bottom: 1.5rem;
|
|
43
|
-
border-bottom: 1px solid var(--color-border, #ddd);
|
|
44
|
-
}
|
|
45
|
-
.fw-tab {
|
|
46
|
-
padding: 0.75rem 1rem;
|
|
47
|
-
border: none;
|
|
48
|
-
background: none;
|
|
49
|
-
color: var(--color-text-secondary, #666);
|
|
50
|
-
cursor: pointer;
|
|
51
|
-
border-bottom: 2px solid transparent;
|
|
52
|
-
margin-bottom: -1px;
|
|
53
|
-
font-size: 0.875rem;
|
|
54
|
-
font-weight: 500;
|
|
55
|
-
}
|
|
56
|
-
.fw-tab:hover { color: inherit; }
|
|
57
|
-
.fw-tab--active {
|
|
58
|
-
color: var(--color-accent, #3b82f6);
|
|
59
|
-
border-bottom-color: var(--color-accent, #3b82f6);
|
|
60
|
-
}
|
|
61
|
-
.fw-tab-content { display: none; }
|
|
62
|
-
.fw-tab-content--active { display: block; }
|
|
63
|
-
|
|
64
|
-
/* Top list */
|
|
65
|
-
.fw-top-list {
|
|
66
|
-
list-style: none;
|
|
67
|
-
padding: 0;
|
|
68
|
-
margin: 0 0 1.5rem 0;
|
|
69
|
-
}
|
|
70
|
-
.fw-top-list li {
|
|
71
|
-
display: flex;
|
|
72
|
-
align-items: center;
|
|
73
|
-
gap: 0.75rem;
|
|
74
|
-
padding: 0.5rem 0;
|
|
75
|
-
border-bottom: 1px solid var(--color-border, #eee);
|
|
76
|
-
}
|
|
77
|
-
.fw-top-list li:last-child { border-bottom: none; }
|
|
78
|
-
.fw-rank {
|
|
79
|
-
width: 1.5rem;
|
|
80
|
-
height: 1.5rem;
|
|
81
|
-
display: flex;
|
|
82
|
-
align-items: center;
|
|
83
|
-
justify-content: center;
|
|
84
|
-
font-size: 0.75rem;
|
|
85
|
-
font-weight: 600;
|
|
86
|
-
background: var(--color-offset, #f5f5f5);
|
|
87
|
-
border-radius: 50%;
|
|
88
|
-
color: var(--color-text-secondary, #666);
|
|
89
|
-
flex-shrink: 0;
|
|
90
|
-
}
|
|
91
|
-
.fw-name { flex: 1; font-weight: 500; }
|
|
92
|
-
.fw-count {
|
|
93
|
-
font-size: 0.875rem;
|
|
94
|
-
color: var(--color-text-secondary, #666);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* Album grid */
|
|
98
|
-
.fw-album-grid {
|
|
99
|
-
display: grid;
|
|
100
|
-
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
|
|
101
|
-
gap: 1rem;
|
|
102
|
-
list-style: none;
|
|
103
|
-
padding: 0;
|
|
104
|
-
margin: 0 0 1.5rem 0;
|
|
105
|
-
}
|
|
106
|
-
.fw-album {
|
|
107
|
-
display: flex;
|
|
108
|
-
flex-direction: column;
|
|
109
|
-
gap: 0.5rem;
|
|
110
|
-
}
|
|
111
|
-
.fw-album img {
|
|
112
|
-
width: 100%;
|
|
113
|
-
aspect-ratio: 1;
|
|
114
|
-
object-fit: cover;
|
|
115
|
-
border-radius: 0.25rem;
|
|
116
|
-
}
|
|
117
|
-
.fw-album-placeholder {
|
|
118
|
-
width: 100%;
|
|
119
|
-
aspect-ratio: 1;
|
|
120
|
-
background: var(--color-border, #ddd);
|
|
121
|
-
border-radius: 0.25rem;
|
|
122
|
-
}
|
|
123
|
-
.fw-album-title {
|
|
124
|
-
font-weight: 500;
|
|
125
|
-
font-size: 0.875rem;
|
|
126
|
-
white-space: nowrap;
|
|
127
|
-
overflow: hidden;
|
|
128
|
-
text-overflow: ellipsis;
|
|
129
|
-
}
|
|
130
|
-
.fw-album-artist {
|
|
131
|
-
font-size: 0.75rem;
|
|
132
|
-
color: var(--color-text-secondary, #666);
|
|
133
|
-
white-space: nowrap;
|
|
134
|
-
overflow: hidden;
|
|
135
|
-
text-overflow: ellipsis;
|
|
136
|
-
}
|
|
137
|
-
.fw-album-plays {
|
|
138
|
-
font-size: 0.75rem;
|
|
139
|
-
color: var(--color-text-secondary, #666);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/* Chart */
|
|
143
|
-
.fw-chart { margin: 1rem 0 1.5rem 0; }
|
|
144
|
-
.fw-chart-bars {
|
|
145
|
-
display: flex;
|
|
146
|
-
align-items: flex-end;
|
|
147
|
-
gap: 2px;
|
|
148
|
-
height: 120px;
|
|
149
|
-
padding: 0.5rem 0;
|
|
150
|
-
}
|
|
151
|
-
.fw-chart-bar-wrapper {
|
|
152
|
-
flex: 1;
|
|
153
|
-
height: 100%;
|
|
154
|
-
display: flex;
|
|
155
|
-
align-items: flex-end;
|
|
156
|
-
}
|
|
157
|
-
.fw-chart-bar {
|
|
158
|
-
width: 100%;
|
|
159
|
-
background: var(--color-accent, #3b82f6);
|
|
160
|
-
border-radius: 2px 2px 0 0;
|
|
161
|
-
min-height: 2px;
|
|
162
|
-
transition: height 0.3s ease;
|
|
163
|
-
}
|
|
164
|
-
.fw-chart-bar-wrapper:hover .fw-chart-bar {
|
|
165
|
-
background: var(--color-accent-hover, #2563eb);
|
|
166
|
-
}
|
|
167
|
-
.fw-chart-labels {
|
|
168
|
-
display: flex;
|
|
169
|
-
justify-content: space-between;
|
|
170
|
-
font-size: 0.75rem;
|
|
171
|
-
color: var(--color-text-secondary, #666);
|
|
172
|
-
margin-top: 0.5rem;
|
|
173
|
-
}
|
|
174
|
-
</style>
|
|
175
|
-
|
|
176
|
-
{% if error %}
|
|
177
|
-
{{ prose({ text: error.message }) }}
|
|
178
|
-
{% else %}
|
|
179
|
-
<section class="fw-section">
|
|
180
|
-
{# Tabs #}
|
|
181
|
-
<div class="fw-tabs" role="tablist">
|
|
182
|
-
<button class="fw-tab fw-tab--active" role="tab" data-tab="all" aria-selected="true">
|
|
183
|
-
{{ __("funkwhale.allTime") }}
|
|
184
|
-
</button>
|
|
185
|
-
<button class="fw-tab" role="tab" data-tab="month" aria-selected="false">
|
|
186
|
-
{{ __("funkwhale.thisMonth") }}
|
|
187
|
-
</button>
|
|
188
|
-
<button class="fw-tab" role="tab" data-tab="week" aria-selected="false">
|
|
189
|
-
{{ __("funkwhale.thisWeek") }}
|
|
190
|
-
</button>
|
|
191
|
-
<button class="fw-tab" role="tab" data-tab="trends" aria-selected="false">
|
|
192
|
-
{{ __("funkwhale.trends") }}
|
|
193
|
-
</button>
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
{# All Time Tab #}
|
|
197
|
-
<div class="fw-tab-content fw-tab-content--active" id="tab-all" role="tabpanel">
|
|
198
|
-
{% set s = stats.summary.all %}
|
|
199
|
-
<div class="fw-stats-grid">
|
|
200
|
-
<div class="fw-stat">
|
|
201
|
-
<span class="fw-stat-value">{{ s.totalPlays | default(0) }}</span>
|
|
202
|
-
<span class="fw-stat-label">{{ __("funkwhale.plays") }}</span>
|
|
203
|
-
</div>
|
|
204
|
-
<div class="fw-stat">
|
|
205
|
-
<span class="fw-stat-value">{{ s.uniqueTracks | default(0) }}</span>
|
|
206
|
-
<span class="fw-stat-label">{{ __("funkwhale.tracks") }}</span>
|
|
207
|
-
</div>
|
|
208
|
-
<div class="fw-stat">
|
|
209
|
-
<span class="fw-stat-value">{{ s.uniqueArtists | default(0) }}</span>
|
|
210
|
-
<span class="fw-stat-label">{{ __("funkwhale.artists") }}</span>
|
|
211
|
-
</div>
|
|
212
|
-
<div class="fw-stat">
|
|
213
|
-
<span class="fw-stat-value">{{ s.totalDurationFormatted | default("0m") }}</span>
|
|
214
|
-
<span class="fw-stat-label">{{ __("funkwhale.listeningTime") }}</span>
|
|
215
|
-
</div>
|
|
216
|
-
</div>
|
|
217
|
-
|
|
218
|
-
<h3>{{ __("funkwhale.topArtists") }}</h3>
|
|
219
|
-
{% if stats.topArtists.all and stats.topArtists.all.length > 0 %}
|
|
220
|
-
<ol class="fw-top-list">
|
|
221
|
-
{% for artist in stats.topArtists.all %}
|
|
222
|
-
<li>
|
|
223
|
-
<span class="fw-rank">{{ loop.index }}</span>
|
|
224
|
-
<span class="fw-name">{{ artist.name }}</span>
|
|
225
|
-
<span class="fw-count">{{ artist.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
226
|
-
</li>
|
|
227
|
-
{% endfor %}
|
|
228
|
-
</ol>
|
|
229
|
-
{% else %}
|
|
230
|
-
{{ prose({ text: "No data yet" }) }}
|
|
231
|
-
{% endif %}
|
|
232
|
-
|
|
233
|
-
<h3>{{ __("funkwhale.topAlbums") }}</h3>
|
|
234
|
-
{% if stats.topAlbums.all and stats.topAlbums.all.length > 0 %}
|
|
235
|
-
<ul class="fw-album-grid">
|
|
236
|
-
{% for album in stats.topAlbums.all %}
|
|
237
|
-
<li class="fw-album">
|
|
238
|
-
{% if album.coverUrl %}
|
|
239
|
-
<img src="{{ album.coverUrl }}" alt="" loading="lazy">
|
|
240
|
-
{% else %}
|
|
241
|
-
<div class="fw-album-placeholder"></div>
|
|
242
|
-
{% endif %}
|
|
243
|
-
<span class="fw-album-title">{{ album.title }}</span>
|
|
244
|
-
<span class="fw-album-artist">{{ album.artist }}</span>
|
|
245
|
-
<span class="fw-album-plays">{{ album.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
246
|
-
</li>
|
|
247
|
-
{% endfor %}
|
|
248
|
-
</ul>
|
|
249
|
-
{% else %}
|
|
250
|
-
{{ prose({ text: "No data yet" }) }}
|
|
251
|
-
{% endif %}
|
|
252
|
-
</div>
|
|
253
|
-
|
|
254
|
-
{# This Month Tab #}
|
|
255
|
-
<div class="fw-tab-content" id="tab-month" role="tabpanel" hidden>
|
|
256
|
-
{% set s = stats.summary.month %}
|
|
257
|
-
<div class="fw-stats-grid">
|
|
258
|
-
<div class="fw-stat">
|
|
259
|
-
<span class="fw-stat-value">{{ s.totalPlays | default(0) }}</span>
|
|
260
|
-
<span class="fw-stat-label">{{ __("funkwhale.plays") }}</span>
|
|
261
|
-
</div>
|
|
262
|
-
<div class="fw-stat">
|
|
263
|
-
<span class="fw-stat-value">{{ s.uniqueTracks | default(0) }}</span>
|
|
264
|
-
<span class="fw-stat-label">{{ __("funkwhale.tracks") }}</span>
|
|
265
|
-
</div>
|
|
266
|
-
<div class="fw-stat">
|
|
267
|
-
<span class="fw-stat-value">{{ s.uniqueArtists | default(0) }}</span>
|
|
268
|
-
<span class="fw-stat-label">{{ __("funkwhale.artists") }}</span>
|
|
269
|
-
</div>
|
|
270
|
-
<div class="fw-stat">
|
|
271
|
-
<span class="fw-stat-value">{{ s.totalDurationFormatted | default("0m") }}</span>
|
|
272
|
-
<span class="fw-stat-label">{{ __("funkwhale.listeningTime") }}</span>
|
|
273
|
-
</div>
|
|
274
|
-
</div>
|
|
275
|
-
|
|
276
|
-
<h3>{{ __("funkwhale.topArtists") }}</h3>
|
|
277
|
-
{% if stats.topArtists.month and stats.topArtists.month.length > 0 %}
|
|
278
|
-
<ol class="fw-top-list">
|
|
279
|
-
{% for artist in stats.topArtists.month %}
|
|
280
|
-
<li>
|
|
281
|
-
<span class="fw-rank">{{ loop.index }}</span>
|
|
282
|
-
<span class="fw-name">{{ artist.name }}</span>
|
|
283
|
-
<span class="fw-count">{{ artist.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
284
|
-
</li>
|
|
285
|
-
{% endfor %}
|
|
286
|
-
</ol>
|
|
287
|
-
{% else %}
|
|
288
|
-
{{ prose({ text: "No data yet" }) }}
|
|
289
|
-
{% endif %}
|
|
290
|
-
|
|
291
|
-
<h3>{{ __("funkwhale.topAlbums") }}</h3>
|
|
292
|
-
{% if stats.topAlbums.month and stats.topAlbums.month.length > 0 %}
|
|
293
|
-
<ul class="fw-album-grid">
|
|
294
|
-
{% for album in stats.topAlbums.month %}
|
|
295
|
-
<li class="fw-album">
|
|
296
|
-
{% if album.coverUrl %}
|
|
297
|
-
<img src="{{ album.coverUrl }}" alt="" loading="lazy">
|
|
298
|
-
{% else %}
|
|
299
|
-
<div class="fw-album-placeholder"></div>
|
|
300
|
-
{% endif %}
|
|
301
|
-
<span class="fw-album-title">{{ album.title }}</span>
|
|
302
|
-
<span class="fw-album-artist">{{ album.artist }}</span>
|
|
303
|
-
<span class="fw-album-plays">{{ album.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
304
|
-
</li>
|
|
305
|
-
{% endfor %}
|
|
306
|
-
</ul>
|
|
307
|
-
{% else %}
|
|
308
|
-
{{ prose({ text: "No data yet" }) }}
|
|
309
|
-
{% endif %}
|
|
310
|
-
</div>
|
|
311
|
-
|
|
312
|
-
{# This Week Tab #}
|
|
313
|
-
<div class="fw-tab-content" id="tab-week" role="tabpanel" hidden>
|
|
314
|
-
{% set s = stats.summary.week %}
|
|
315
|
-
<div class="fw-stats-grid">
|
|
316
|
-
<div class="fw-stat">
|
|
317
|
-
<span class="fw-stat-value">{{ s.totalPlays | default(0) }}</span>
|
|
318
|
-
<span class="fw-stat-label">{{ __("funkwhale.plays") }}</span>
|
|
319
|
-
</div>
|
|
320
|
-
<div class="fw-stat">
|
|
321
|
-
<span class="fw-stat-value">{{ s.uniqueTracks | default(0) }}</span>
|
|
322
|
-
<span class="fw-stat-label">{{ __("funkwhale.tracks") }}</span>
|
|
323
|
-
</div>
|
|
324
|
-
<div class="fw-stat">
|
|
325
|
-
<span class="fw-stat-value">{{ s.uniqueArtists | default(0) }}</span>
|
|
326
|
-
<span class="fw-stat-label">{{ __("funkwhale.artists") }}</span>
|
|
327
|
-
</div>
|
|
328
|
-
<div class="fw-stat">
|
|
329
|
-
<span class="fw-stat-value">{{ s.totalDurationFormatted | default("0m") }}</span>
|
|
330
|
-
<span class="fw-stat-label">{{ __("funkwhale.listeningTime") }}</span>
|
|
331
|
-
</div>
|
|
332
|
-
</div>
|
|
333
|
-
|
|
334
|
-
<h3>{{ __("funkwhale.topArtists") }}</h3>
|
|
335
|
-
{% if stats.topArtists.week and stats.topArtists.week.length > 0 %}
|
|
336
|
-
<ol class="fw-top-list">
|
|
337
|
-
{% for artist in stats.topArtists.week %}
|
|
338
|
-
<li>
|
|
339
|
-
<span class="fw-rank">{{ loop.index }}</span>
|
|
340
|
-
<span class="fw-name">{{ artist.name }}</span>
|
|
341
|
-
<span class="fw-count">{{ artist.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
342
|
-
</li>
|
|
343
|
-
{% endfor %}
|
|
344
|
-
</ol>
|
|
345
|
-
{% else %}
|
|
346
|
-
{{ prose({ text: "No data yet" }) }}
|
|
347
|
-
{% endif %}
|
|
348
|
-
|
|
349
|
-
<h3>{{ __("funkwhale.topAlbums") }}</h3>
|
|
350
|
-
{% if stats.topAlbums.week and stats.topAlbums.week.length > 0 %}
|
|
351
|
-
<ul class="fw-album-grid">
|
|
352
|
-
{% for album in stats.topAlbums.week %}
|
|
353
|
-
<li class="fw-album">
|
|
354
|
-
{% if album.coverUrl %}
|
|
355
|
-
<img src="{{ album.coverUrl }}" alt="" loading="lazy">
|
|
356
|
-
{% else %}
|
|
357
|
-
<div class="fw-album-placeholder"></div>
|
|
358
|
-
{% endif %}
|
|
359
|
-
<span class="fw-album-title">{{ album.title }}</span>
|
|
360
|
-
<span class="fw-album-artist">{{ album.artist }}</span>
|
|
361
|
-
<span class="fw-album-plays">{{ album.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
362
|
-
</li>
|
|
363
|
-
{% endfor %}
|
|
364
|
-
</ul>
|
|
365
|
-
{% else %}
|
|
366
|
-
{{ prose({ text: "No data yet" }) }}
|
|
367
|
-
{% endif %}
|
|
368
|
-
</div>
|
|
369
|
-
|
|
370
|
-
{# Trends Tab #}
|
|
371
|
-
<div class="fw-tab-content" id="tab-trends" role="tabpanel" hidden>
|
|
372
|
-
<h3>{{ __("funkwhale.listeningTrend") }}</h3>
|
|
373
|
-
{% if stats.trends and stats.trends.length > 0 %}
|
|
374
|
-
<div class="fw-chart">
|
|
375
|
-
{% set maxCount = 0 %}
|
|
376
|
-
{% for day in stats.trends %}
|
|
377
|
-
{% if day.count > maxCount %}
|
|
378
|
-
{% set maxCount = day.count %}
|
|
379
|
-
{% endif %}
|
|
380
|
-
{% endfor %}
|
|
381
|
-
<div class="fw-chart-bars">
|
|
382
|
-
{% for day in stats.trends %}
|
|
383
|
-
<div class="fw-chart-bar-wrapper" title="{{ day.date }}: {{ day.count }} plays">
|
|
384
|
-
<div class="fw-chart-bar" style="height: {{ (day.count / maxCount * 100) if maxCount > 0 else 0 }}%"></div>
|
|
385
|
-
</div>
|
|
386
|
-
{% endfor %}
|
|
387
|
-
</div>
|
|
388
|
-
<div class="fw-chart-labels">
|
|
389
|
-
<span>{{ stats.trends[0].date }}</span>
|
|
390
|
-
<span>{{ stats.trends[stats.trends.length - 1].date }}</span>
|
|
391
|
-
</div>
|
|
392
|
-
</div>
|
|
393
|
-
{% else %}
|
|
394
|
-
{{ prose({ text: "No trend data available yet" }) }}
|
|
395
|
-
{% endif %}
|
|
396
|
-
</div>
|
|
397
|
-
</section>
|
|
398
|
-
|
|
399
|
-
{{ button({
|
|
400
|
-
classes: "button--secondary",
|
|
401
|
-
href: mountPath,
|
|
402
|
-
text: "Back to Dashboard"
|
|
403
|
-
}) }}
|
|
404
|
-
|
|
405
|
-
<script>
|
|
406
|
-
// Simple tab switching
|
|
407
|
-
document.querySelectorAll('.fw-tab').forEach(tab => {
|
|
408
|
-
tab.addEventListener('click', () => {
|
|
409
|
-
// Update tabs
|
|
410
|
-
document.querySelectorAll('.fw-tab').forEach(t => {
|
|
411
|
-
t.classList.remove('fw-tab--active');
|
|
412
|
-
t.setAttribute('aria-selected', 'false');
|
|
413
|
-
});
|
|
414
|
-
tab.classList.add('fw-tab--active');
|
|
415
|
-
tab.setAttribute('aria-selected', 'true');
|
|
416
|
-
|
|
417
|
-
// Update content
|
|
418
|
-
document.querySelectorAll('.fw-tab-content').forEach(content => {
|
|
419
|
-
content.classList.remove('fw-tab-content--active');
|
|
420
|
-
content.hidden = true;
|
|
421
|
-
});
|
|
422
|
-
const targetId = 'tab-' + tab.dataset.tab;
|
|
423
|
-
const target = document.getElementById(targetId);
|
|
424
|
-
if (target) {
|
|
425
|
-
target.classList.add('fw-tab-content--active');
|
|
426
|
-
target.hidden = false;
|
|
427
|
-
}
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
</script>
|
|
431
|
-
{% endif %}
|
|
432
|
-
{% endblock %}
|