Build image / build (push) Successful in 3m18s
- Dockerfile bakes the app and every CSV in data/ into an nginx image - UI discovers data/*.csv via nginx JSON autoindex and offers a dropdown when there is more than one dataset - docker-entrypoint.d/40-basic-auth.sh creates .htpasswd from BASIC_AUTH_USER / BASIC_AUTH_PASSWORD(_FILE) and refuses to start without credentials; replaces set-password.sh - Gitea Actions workflow builds and pushes registry.traberph.de/public/interval_viz (latest, sha-*, semver) - Escape resets the chart zoom Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
88 lines
3.2 KiB
JavaScript
88 lines
3.2 KiB
JavaScript
'use strict';
|
||
|
||
// UI strings. Keys used in index.html via data-i18n and in app.js via t().
|
||
const I18N = {
|
||
en: {
|
||
locale: 'en-GB',
|
||
title: 'Heatpump compressor cycles',
|
||
loading: 'loading…',
|
||
dataHeading: 'Data',
|
||
rangeHeading: 'Selected range',
|
||
all: 'All',
|
||
loadCsv: 'Load CSV…',
|
||
phaseList: 'On-phases in selected range',
|
||
start: 'Start',
|
||
end: 'End',
|
||
duration: 'Duration',
|
||
gapBefore: 'Gap before',
|
||
from: 'From',
|
||
to: 'To',
|
||
span: 'Span',
|
||
events: 'Events',
|
||
onPhases: 'On-phases',
|
||
phases: 'Phases',
|
||
min: 'Min',
|
||
max: 'Max',
|
||
mean: 'Mean',
|
||
median: 'Median',
|
||
totalOn: 'Total on',
|
||
dutyCycle: 'Duty cycle',
|
||
meanGap: 'Mean off-gap',
|
||
on: 'on',
|
||
off: 'off',
|
||
units: { d: 'd', h: 'h', m: 'm', s: 's' },
|
||
errColumns: 'CSV needs the columns "state" and "last_changed".',
|
||
errEmpty: 'CSV contains no valid rows.',
|
||
dataset: 'Dataset',
|
||
localFile: 'Local file',
|
||
errFetch: 'Could not load {file} ({status}) – use “Load CSV…”.',
|
||
errNoData: 'No CSV files found in data/ – use “Load CSV…”.',
|
||
note: 'Hover a phase to see its duration. Drag to zoom, shift+drag or the pan tool to pan, ' +
|
||
'mouse wheel to zoom, double-click or Esc to reset. Statistics use the on-phases that <em>start</em> ' +
|
||
'within the visible range; total on-time and duty cycle are clipped to the range. ' +
|
||
'A phase ends at the first state that is not "on" (off, unknown, unavailable); ' +
|
||
'a phase still running at the end of the data is excluded. Times are shown in your local time zone.',
|
||
},
|
||
de: {
|
||
locale: 'de-DE',
|
||
title: 'Wärmepumpe – Verdichterzyklen',
|
||
loading: 'lädt…',
|
||
dataHeading: 'Daten',
|
||
rangeHeading: 'Ausgewählter Zeitraum',
|
||
all: 'Alles',
|
||
loadCsv: 'CSV laden…',
|
||
phaseList: 'Laufphasen im ausgewählten Zeitraum',
|
||
start: 'Start',
|
||
end: 'Ende',
|
||
duration: 'Dauer',
|
||
gapBefore: 'Pause davor',
|
||
from: 'Von',
|
||
to: 'Bis',
|
||
span: 'Zeitraum',
|
||
events: 'Ereignisse',
|
||
onPhases: 'Laufphasen',
|
||
phases: 'Phasen',
|
||
min: 'Min',
|
||
max: 'Max',
|
||
mean: 'Mittelwert',
|
||
median: 'Median',
|
||
totalOn: 'Laufzeit gesamt',
|
||
dutyCycle: 'Einschaltanteil',
|
||
meanGap: 'Ø Pause',
|
||
on: 'an',
|
||
off: 'aus',
|
||
units: { d: 'T', h: 'h', m: 'min', s: 's' },
|
||
errColumns: 'Die CSV benötigt die Spalten "state" und "last_changed".',
|
||
errEmpty: 'Die CSV enthält keine gültigen Zeilen.',
|
||
dataset: 'Datensatz',
|
||
localFile: 'Lokale Datei',
|
||
errFetch: '{file} konnte nicht geladen werden ({status}) – bitte „CSV laden…“ verwenden.',
|
||
errNoData: 'Keine CSV-Dateien in data/ gefunden – bitte „CSV laden…“ verwenden.',
|
||
note: 'Für die Dauer über eine Phase fahren. Ziehen zum Zoomen, Umschalt+Ziehen oder das Verschieben-Werkzeug ' +
|
||
'zum Verschieben, Mausrad zum Zoomen, Doppelklick oder Esc zum Zurücksetzen. Die Statistik berücksichtigt Laufphasen, ' +
|
||
'die im sichtbaren Zeitraum <em>beginnen</em>; Laufzeit gesamt und Einschaltanteil werden auf den Zeitraum begrenzt. ' +
|
||
'Eine Phase endet beim ersten Zustand ungleich „on“ (off, unknown, unavailable); ' +
|
||
'eine am Datenende noch laufende Phase wird nicht gezählt. Zeiten in lokaler Zeitzone.',
|
||
},
|
||
};
|